@aztec/p2p 0.0.1-commit.e61ad554 → 0.0.1-commit.ec5f612
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bootstrap/bootstrap.d.ts +4 -3
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +4 -4
- package/dest/client/factory.d.ts +10 -10
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +45 -18
- package/dest/client/interface.d.ts +46 -33
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +41 -51
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +156 -200
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +2 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +1 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +304 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +73 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +1 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +8 -0
- package/dest/config.d.ts +35 -7
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +21 -7
- package/dest/errors/tx-pool.error.d.ts +8 -0
- package/dest/errors/tx-pool.error.d.ts.map +1 -0
- package/dest/errors/tx-pool.error.js +9 -0
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -88
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +441 -3
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +353 -87
- package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/index.js +1 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +2 -2
- package/dest/mem_pools/index.d.ts +3 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/index.js +1 -1
- package/dest/mem_pools/instrumentation.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +2 -2
- package/dest/mem_pools/interface.d.ts +5 -5
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
- package/dest/mem_pools/tx_pool_v2/archive/index.d.ts +2 -0
- package/dest/mem_pools/tx_pool_v2/archive/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/archive/index.js +1 -0
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +43 -0
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +103 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +47 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +128 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +93 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +97 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +10 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +11 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +174 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +25 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +65 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +93 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +78 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +20 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +73 -0
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +19 -0
- package/dest/mem_pools/tx_pool_v2/index.d.ts +6 -0
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/index.js +5 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +211 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.js +9 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +119 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +193 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts +26 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.js +70 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +108 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +354 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +60 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +161 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +77 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +905 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +3 -3
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +7 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.js +5 -5
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +3 -3
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +20 -6
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +5 -4
- package/dest/msg_validators/tx_validator/data_validator.d.ts +3 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +4 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +15 -4
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +7 -6
- package/dest/msg_validators/tx_validator/factory.d.ts +118 -5
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +228 -57
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +59 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +76 -38
- package/dest/msg_validators/tx_validator/index.d.ts +2 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +1 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +2 -2
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
- package/dest/msg_validators/tx_validator/size_validator.d.ts +3 -1
- package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/size_validator.js +4 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +22 -5
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +8 -8
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.js +2 -2
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -2
- package/dest/services/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/data_store.js +10 -6
- package/dest/services/discv5/discV5_service.js +1 -1
- package/dest/services/dummy_service.d.ts +24 -4
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +46 -1
- package/dest/services/encoding.d.ts +3 -3
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +11 -10
- package/dest/services/gossipsub/index.d.ts +3 -0
- package/dest/services/gossipsub/index.d.ts.map +1 -0
- package/dest/services/gossipsub/index.js +2 -0
- package/dest/services/gossipsub/scoring.d.ts +21 -3
- package/dest/services/gossipsub/scoring.d.ts.map +1 -1
- package/dest/services/gossipsub/scoring.js +24 -7
- package/dest/services/gossipsub/topic_score_params.d.ts +173 -0
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
- package/dest/services/gossipsub/topic_score_params.js +346 -0
- package/dest/services/index.d.ts +2 -1
- package/dest/services/index.d.ts.map +1 -1
- package/dest/services/index.js +1 -0
- package/dest/services/libp2p/instrumentation.d.ts +1 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +14 -3
- package/dest/services/libp2p/libp2p_service.d.ts +100 -42
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +451 -359
- package/dest/services/peer-manager/metrics.d.ts +2 -2
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +20 -5
- package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +33 -4
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +48 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +539 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts +17 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/config.js +27 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +46 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/interface.js +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +34 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +130 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +60 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +173 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +20 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +21 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +22 -3
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +63 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +12 -0
- package/dest/services/reqresp/interface.d.ts +12 -1
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +15 -1
- package/dest/services/reqresp/metrics.d.ts +6 -5
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +17 -5
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +5 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +5 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +7 -5
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +27 -9
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +29 -6
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +59 -13
- package/dest/services/reqresp/protocols/tx.d.ts +7 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +20 -0
- package/dest/services/reqresp/reqresp.d.ts +6 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +71 -27
- package/dest/services/service.d.ts +42 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +22 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +55 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +7 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +71 -44
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_source.js +90 -0
- package/dest/services/tx_collection/index.d.ts +3 -1
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +2 -0
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +10 -2
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +49 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -0
- package/dest/services/tx_collection/proposal_tx_collector.js +50 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +60 -26
- package/dest/services/tx_collection/tx_collection.d.ts +25 -12
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +79 -7
- package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +26 -29
- package/dest/services/tx_collection/tx_source.d.ts +8 -3
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +19 -2
- package/dest/services/tx_file_store/config.d.ts +16 -0
- package/dest/services/tx_file_store/config.d.ts.map +1 -0
- package/dest/services/tx_file_store/config.js +22 -0
- package/dest/services/tx_file_store/index.d.ts +4 -0
- package/dest/services/tx_file_store/index.d.ts.map +1 -0
- package/dest/services/tx_file_store/index.js +3 -0
- package/dest/services/tx_file_store/instrumentation.d.ts +15 -0
- package/dest/services/tx_file_store/instrumentation.d.ts.map +1 -0
- package/dest/services/tx_file_store/instrumentation.js +29 -0
- package/dest/services/tx_file_store/tx_file_store.d.ts +48 -0
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -0
- package/dest/services/tx_file_store/tx_file_store.js +152 -0
- package/dest/services/tx_provider.d.ts +4 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +9 -8
- package/dest/services/tx_provider_instrumentation.d.ts +1 -1
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +5 -5
- package/dest/test-helpers/index.d.ts +3 -1
- package/dest/test-helpers/index.d.ts.map +1 -1
- package/dest/test-helpers/index.js +2 -0
- package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +1 -2
- package/dest/test-helpers/mock-pubsub.d.ts +30 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +105 -4
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +4 -3
- package/dest/test-helpers/test_tx_provider.d.ts +40 -0
- package/dest/test-helpers/test_tx_provider.d.ts.map +1 -0
- package/dest/test-helpers/test_tx_provider.js +41 -0
- package/dest/test-helpers/testbench-utils.d.ts +163 -0
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
- package/dest/test-helpers/testbench-utils.js +366 -0
- package/dest/testbench/p2p_client_testbench_worker.d.ts +28 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +219 -138
- package/dest/testbench/worker_client_manager.d.ts +51 -6
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +226 -44
- package/dest/util.d.ts +2 -2
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/bootstrap/bootstrap.ts +7 -4
- package/src/client/factory.ts +83 -36
- package/src/client/interface.ts +56 -34
- package/src/client/p2p_client.ts +192 -247
- package/src/client/test/tx_proposal_collector/README.md +227 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +345 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
- package/src/config.ts +47 -11
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +496 -91
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +442 -102
- package/src/mem_pools/attestation_pool/index.ts +9 -2
- package/src/mem_pools/attestation_pool/mocks.ts +2 -1
- package/src/mem_pools/index.ts +4 -1
- package/src/mem_pools/instrumentation.ts +2 -1
- package/src/mem_pools/interface.ts +4 -4
- package/src/mem_pools/tx_pool/README.md +1 -1
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/README.md +275 -0
- package/src/mem_pools/tx_pool_v2/archive/index.ts +1 -0
- package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +120 -0
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +160 -0
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +121 -0
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +125 -0
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +27 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +209 -0
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +74 -0
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +101 -0
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +91 -0
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +90 -0
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +31 -0
- package/src/mem_pools/tx_pool_v2/index.ts +12 -0
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +242 -0
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +297 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_bench_metrics.ts +77 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +444 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +223 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1083 -0
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +10 -4
- package/src/msg_validators/proposal_validator/proposal_validator.ts +5 -5
- package/src/msg_validators/tx_validator/README.md +115 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
- package/src/msg_validators/tx_validator/archive_cache.ts +3 -3
- package/src/msg_validators/tx_validator/block_header_validator.ts +22 -11
- package/src/msg_validators/tx_validator/data_validator.ts +6 -2
- package/src/msg_validators/tx_validator/double_spend_validator.ts +15 -9
- package/src/msg_validators/tx_validator/factory.ts +372 -55
- package/src/msg_validators/tx_validator/gas_validator.ts +98 -29
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +6 -3
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +5 -3
- package/src/msg_validators/tx_validator/size_validator.ts +6 -2
- package/src/msg_validators/tx_validator/timestamp_validator.ts +29 -21
- package/src/msg_validators/tx_validator/tx_permitted_validator.ts +8 -3
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +8 -3
- package/src/services/data_store.ts +10 -7
- package/src/services/discv5/discV5_service.ts +1 -1
- package/src/services/dummy_service.ts +59 -2
- package/src/services/encoding.ts +9 -9
- package/src/services/gossipsub/README.md +641 -0
- package/src/services/gossipsub/index.ts +2 -0
- package/src/services/gossipsub/scoring.ts +29 -5
- package/src/services/gossipsub/topic_score_params.ts +487 -0
- package/src/services/index.ts +1 -0
- package/src/services/libp2p/instrumentation.ts +15 -2
- package/src/services/libp2p/libp2p_service.ts +496 -397
- package/src/services/peer-manager/metrics.ts +21 -4
- package/src/services/peer-manager/peer_scoring.ts +29 -1
- package/src/services/reqresp/batch-tx-requester/README.md +305 -0
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +678 -0
- package/src/services/reqresp/batch-tx-requester/config.ts +40 -0
- package/src/services/reqresp/batch-tx-requester/interface.ts +53 -0
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +161 -0
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +244 -0
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +37 -0
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +65 -4
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +16 -0
- package/src/services/reqresp/interface.ts +29 -1
- package/src/services/reqresp/metrics.ts +34 -9
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +7 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +35 -12
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +74 -9
- package/src/services/reqresp/protocols/tx.ts +22 -0
- package/src/services/reqresp/reqresp.ts +82 -23
- package/src/services/service.ts +55 -2
- package/src/services/tx_collection/config.ts +83 -1
- package/src/services/tx_collection/fast_tx_collection.ts +93 -47
- package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
- package/src/services/tx_collection/file_store_tx_source.ts +117 -0
- package/src/services/tx_collection/index.ts +6 -0
- package/src/services/tx_collection/instrumentation.ts +17 -2
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +113 -0
- package/src/services/tx_collection/slow_tx_collection.ts +66 -33
- package/src/services/tx_collection/tx_collection.ts +117 -20
- package/src/services/tx_collection/tx_collection_sink.ts +30 -34
- package/src/services/tx_collection/tx_source.ts +22 -3
- package/src/services/tx_file_store/config.ts +37 -0
- package/src/services/tx_file_store/index.ts +3 -0
- package/src/services/tx_file_store/instrumentation.ts +36 -0
- package/src/services/tx_file_store/tx_file_store.ts +175 -0
- package/src/services/tx_provider.ts +10 -9
- package/src/services/tx_provider_instrumentation.ts +11 -5
- package/src/test-helpers/index.ts +2 -0
- package/src/test-helpers/make-test-p2p-clients.ts +3 -5
- package/src/test-helpers/mock-pubsub.ts +146 -9
- package/src/test-helpers/reqresp-nodes.ts +4 -6
- package/src/test-helpers/test_tx_provider.ts +64 -0
- package/src/test-helpers/testbench-utils.ts +430 -0
- package/src/testbench/p2p_client_testbench_worker.ts +333 -131
- package/src/testbench/worker_client_manager.ts +304 -47
- package/src/util.ts +7 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
|
+
import { IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
|
|
3
3
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
|
-
import type { BlockProposal, CheckpointAttestation,
|
|
4
|
+
import type { BlockProposal, CheckpointAttestation, CheckpointProposalCore } from '@aztec/stdlib/p2p';
|
|
5
5
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
6
6
|
import {
|
|
7
7
|
makeBlockHeader,
|
|
@@ -10,8 +10,11 @@ import {
|
|
|
10
10
|
makeCheckpointProposal,
|
|
11
11
|
} from '@aztec/stdlib/testing';
|
|
12
12
|
|
|
13
|
-
import
|
|
14
|
-
|
|
13
|
+
import {
|
|
14
|
+
type AttestationPool,
|
|
15
|
+
MAX_BLOCK_PROPOSALS_PER_POSITION,
|
|
16
|
+
MAX_CHECKPOINT_PROPOSALS_PER_SLOT,
|
|
17
|
+
} from './attestation_pool.js';
|
|
15
18
|
import { mockCheckpointAttestation } from './mocks.js';
|
|
16
19
|
|
|
17
20
|
const NUMBER_OF_SIGNERS_PER_TEST = 4;
|
|
@@ -58,7 +61,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
58
61
|
const archive = Fr.random();
|
|
59
62
|
const attestations = signers.slice(0, -1).map(signer => mockCheckpointAttestation(signer, slotNumber, archive));
|
|
60
63
|
|
|
61
|
-
await ap.
|
|
64
|
+
await ap.addOwnCheckpointAttestations(attestations);
|
|
62
65
|
|
|
63
66
|
const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
64
67
|
SlotNumber(slotNumber),
|
|
@@ -67,42 +70,31 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
67
70
|
expect(retrievedAttestations.length).toBe(attestations.length);
|
|
68
71
|
compareCheckpointAttestations(retrievedAttestations, attestations);
|
|
69
72
|
|
|
70
|
-
// Check hasCheckpointAttestation for added attestations
|
|
71
|
-
for (const attestation of attestations) {
|
|
72
|
-
expect(await ap.hasCheckpointAttestation(attestation)).toBe(true);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
73
|
const retrievedAttestationsForSlot = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
|
|
76
74
|
expect(retrievedAttestationsForSlot.length).toBe(attestations.length);
|
|
77
75
|
compareCheckpointAttestations(retrievedAttestationsForSlot, attestations);
|
|
78
76
|
|
|
79
77
|
// Add another one
|
|
80
78
|
const newAttestation = mockCheckpointAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive);
|
|
81
|
-
await ap.
|
|
79
|
+
await ap.addOwnCheckpointAttestations([newAttestation]);
|
|
82
80
|
const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
83
81
|
SlotNumber(slotNumber),
|
|
84
82
|
archive.toString(),
|
|
85
83
|
);
|
|
86
84
|
expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
|
|
87
85
|
compareCheckpointAttestations(retrievedAttestationsAfterAdd, [...attestations, newAttestation]);
|
|
88
|
-
expect(await ap.hasCheckpointAttestation(newAttestation)).toBe(true);
|
|
89
86
|
const retrievedAttestationsForSlotAfterAdd = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
|
|
90
87
|
expect(retrievedAttestationsForSlotAfterAdd.length).toBe(attestations.length + 1);
|
|
91
88
|
compareCheckpointAttestations(retrievedAttestationsForSlotAfterAdd, [...attestations, newAttestation]);
|
|
92
89
|
|
|
93
90
|
// Delete by slot
|
|
94
|
-
await ap.
|
|
91
|
+
await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
|
|
95
92
|
|
|
96
93
|
const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
97
94
|
SlotNumber(slotNumber),
|
|
98
95
|
archive.toString(),
|
|
99
96
|
);
|
|
100
97
|
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
101
|
-
// Check hasCheckpointAttestation after deletion
|
|
102
|
-
for (const attestation of attestations) {
|
|
103
|
-
expect(await ap.hasCheckpointAttestation(attestation)).toBe(false);
|
|
104
|
-
}
|
|
105
|
-
expect(await ap.hasCheckpointAttestation(newAttestation)).toBe(false);
|
|
106
98
|
});
|
|
107
99
|
|
|
108
100
|
it('should handle duplicate proposals in a slot', async () => {
|
|
@@ -118,7 +110,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
118
110
|
}
|
|
119
111
|
|
|
120
112
|
// Add them to store and check we end up with only one
|
|
121
|
-
await ap.
|
|
113
|
+
await ap.addOwnCheckpointAttestations(attestations);
|
|
122
114
|
|
|
123
115
|
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
124
116
|
SlotNumber(slotNumber),
|
|
@@ -129,7 +121,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
129
121
|
expect(retreivedAttestations[0].getSender()?.toString()).toEqual(signer.address.toString());
|
|
130
122
|
|
|
131
123
|
// Try adding them on another operation and check they are still not duplicated
|
|
132
|
-
await ap.
|
|
124
|
+
await ap.addOwnCheckpointAttestations([attestations[0]]);
|
|
133
125
|
expect(
|
|
134
126
|
await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString()),
|
|
135
127
|
).toHaveLength(1);
|
|
@@ -139,7 +131,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
139
131
|
const slotNumbers = [1, 2, 3, 4];
|
|
140
132
|
const attestations = signers.map((signer, i) => mockCheckpointAttestation(signer, slotNumbers[i]));
|
|
141
133
|
|
|
142
|
-
await ap.
|
|
134
|
+
await ap.addOwnCheckpointAttestations(attestations);
|
|
143
135
|
|
|
144
136
|
for (const attestation of attestations) {
|
|
145
137
|
const slot = attestation.payload.header.slotNumber;
|
|
@@ -157,7 +149,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
157
149
|
const archives = [Fr.random(), Fr.random(), Fr.random(), Fr.random()];
|
|
158
150
|
const attestations = signers.map((signer, i) => mockCheckpointAttestation(signer, slotNumbers[i], archives[i]));
|
|
159
151
|
|
|
160
|
-
await ap.
|
|
152
|
+
await ap.addOwnCheckpointAttestations(attestations);
|
|
161
153
|
|
|
162
154
|
for (const attestation of attestations) {
|
|
163
155
|
const slot = attestation.payload.header.slotNumber;
|
|
@@ -177,12 +169,12 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
177
169
|
).flat();
|
|
178
170
|
const proposalId = attestations[0].archive.toString();
|
|
179
171
|
|
|
180
|
-
await ap.
|
|
172
|
+
await ap.addOwnCheckpointAttestations(attestations);
|
|
181
173
|
|
|
182
174
|
const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), proposalId);
|
|
183
175
|
expect(attestationsForSlot1.length).toBe(signers.length);
|
|
184
176
|
|
|
185
|
-
await ap.
|
|
177
|
+
await ap.deleteOlderThan(SlotNumber(73));
|
|
186
178
|
|
|
187
179
|
const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
188
180
|
SlotNumber(1),
|
|
@@ -199,119 +191,86 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
199
191
|
const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
|
|
200
192
|
const proposalId = proposal.archive.toString();
|
|
201
193
|
|
|
202
|
-
await ap.
|
|
194
|
+
const result = await ap.tryAddBlockProposal(proposal);
|
|
195
|
+
|
|
196
|
+
expect(result.added).toBe(true);
|
|
197
|
+
expect(result.alreadyExists).toBe(false);
|
|
198
|
+
expect(result.count).toBe(1);
|
|
203
199
|
|
|
204
200
|
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
205
201
|
|
|
206
202
|
expect(retrievedProposal).toBeDefined();
|
|
207
203
|
expect(retrievedProposal!).toEqual(proposal);
|
|
208
|
-
|
|
209
|
-
// Check hasBlockProposal with both id and object
|
|
210
|
-
expect(await ap.hasBlockProposal(proposalId)).toBe(true);
|
|
211
|
-
expect(await ap.hasBlockProposal(proposal)).toBe(true);
|
|
212
204
|
});
|
|
213
205
|
|
|
214
206
|
it('should return undefined for non-existent block proposal', async () => {
|
|
215
207
|
const nonExistentId = Fr.random().toString();
|
|
216
208
|
const retrievedProposal = await ap.getBlockProposal(nonExistentId);
|
|
217
209
|
expect(retrievedProposal).toBeUndefined();
|
|
218
|
-
|
|
219
|
-
// Check hasBlockProposal returns false for non-existent proposal
|
|
220
|
-
expect(await ap.hasBlockProposal(nonExistentId)).toBe(false);
|
|
221
210
|
});
|
|
222
211
|
|
|
223
|
-
it('should
|
|
212
|
+
it('should return alreadyExists when adding proposal with same id', async () => {
|
|
224
213
|
const slotNumber = 420;
|
|
225
214
|
const archive = Fr.random();
|
|
226
215
|
const proposal1 = await mockBlockProposalForPool(signers[0], slotNumber, archive);
|
|
227
216
|
const proposalId = proposal1.archive.toString();
|
|
228
217
|
|
|
229
|
-
await ap.
|
|
218
|
+
const result1 = await ap.tryAddBlockProposal(proposal1);
|
|
219
|
+
expect(result1.added).toBe(true);
|
|
220
|
+
expect(result1.alreadyExists).toBe(false);
|
|
230
221
|
|
|
231
222
|
// Create a new proposal with same archive but different signer
|
|
232
223
|
const proposal2 = await mockBlockProposalForPool(signers[1], slotNumber, archive);
|
|
233
224
|
|
|
234
|
-
await ap.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
expect(retrievedProposal).toBeDefined();
|
|
238
|
-
// Should have the second proposal
|
|
239
|
-
expect(retrievedProposal!.toBuffer()).toEqual(proposal2.toBuffer());
|
|
240
|
-
expect(retrievedProposal!.getSender()?.toString()).toBe(signers[1].address.toString());
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
it('should handle block proposals with different slots and same archive', async () => {
|
|
244
|
-
const archive = Fr.random();
|
|
245
|
-
const proposal1 = await mockBlockProposalForPool(signers[0], 100, archive);
|
|
246
|
-
const proposal2 = await mockBlockProposalForPool(signers[1], 200, archive);
|
|
247
|
-
const proposalId = archive.toString();
|
|
248
|
-
|
|
249
|
-
await ap.addBlockProposal(proposal1);
|
|
250
|
-
await ap.addBlockProposal(proposal2);
|
|
225
|
+
const result2 = await ap.tryAddBlockProposal(proposal2);
|
|
226
|
+
expect(result2.added).toBe(false);
|
|
227
|
+
expect(result2.alreadyExists).toBe(true);
|
|
251
228
|
|
|
252
|
-
// Should
|
|
229
|
+
// Should still have the first proposal
|
|
253
230
|
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
254
231
|
expect(retrievedProposal).toBeDefined();
|
|
255
|
-
expect(retrievedProposal!.toBuffer()).toEqual(
|
|
256
|
-
expect(retrievedProposal!.
|
|
232
|
+
expect(retrievedProposal!.toBuffer()).toEqual(proposal1.toBuffer());
|
|
233
|
+
expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString());
|
|
257
234
|
});
|
|
258
235
|
});
|
|
259
236
|
|
|
260
237
|
describe('CheckpointProposal in attestation pool', () => {
|
|
261
|
-
const mockCheckpointProposalForPool = (
|
|
238
|
+
const mockCheckpointProposalForPool = async (
|
|
262
239
|
signer: Secp256k1Signer,
|
|
263
240
|
slotNumber: number,
|
|
264
241
|
archive: Fr = Fr.random(),
|
|
265
|
-
): Promise<
|
|
242
|
+
): Promise<CheckpointProposalCore> => {
|
|
266
243
|
const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
|
|
267
244
|
const blockHeader = makeBlockHeader(1);
|
|
268
|
-
|
|
245
|
+
const proposal = await makeCheckpointProposal({
|
|
269
246
|
signer,
|
|
270
247
|
checkpointHeader,
|
|
271
248
|
archiveRoot: archive,
|
|
272
249
|
lastBlock: { blockHeader },
|
|
273
250
|
});
|
|
251
|
+
// Return the core version since tryAddCheckpointProposal now takes CheckpointProposalCore
|
|
252
|
+
return proposal.toCore();
|
|
274
253
|
};
|
|
275
254
|
|
|
276
|
-
it('should add and retrieve checkpoint proposal
|
|
255
|
+
it('should add and retrieve checkpoint proposal', async () => {
|
|
277
256
|
const slotNumber = 420;
|
|
278
257
|
const archive = Fr.random();
|
|
279
258
|
const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
|
|
280
259
|
const proposalId = proposal.archive.toString();
|
|
281
260
|
|
|
282
|
-
await ap.
|
|
261
|
+
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
262
|
+
|
|
263
|
+
expect(result.added).toBe(true);
|
|
264
|
+
expect(result.alreadyExists).toBe(false);
|
|
265
|
+
expect(result.count).toBe(1);
|
|
283
266
|
|
|
284
267
|
const retrievedProposal = await ap.getCheckpointProposal(proposalId);
|
|
285
268
|
|
|
286
269
|
expect(retrievedProposal).toBeDefined();
|
|
287
|
-
|
|
288
|
-
expect(retrievedProposal!.toBuffer()).toEqual(proposal.toCore().toBuffer());
|
|
289
|
-
|
|
290
|
-
// Check hasCheckpointProposal with both id and object
|
|
291
|
-
expect(await ap.hasCheckpointProposal(proposalId)).toBe(true);
|
|
292
|
-
expect(await ap.hasCheckpointProposal(proposal)).toBe(true);
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
it('should extract and store block proposal when adding checkpoint proposal with lastBlock', async () => {
|
|
296
|
-
const slotNumber = 420;
|
|
297
|
-
const archive = Fr.random();
|
|
298
|
-
const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
|
|
299
|
-
const proposalId = proposal.archive.toString();
|
|
300
|
-
|
|
301
|
-
// Verify the proposal has a lastBlock
|
|
302
|
-
const expectedBlockProposal = proposal.getBlockProposal();
|
|
303
|
-
expect(expectedBlockProposal).toBeDefined();
|
|
304
|
-
|
|
305
|
-
await ap.addCheckpointProposal(proposal);
|
|
306
|
-
|
|
307
|
-
// The block proposal should be stored separately and retrievable
|
|
308
|
-
const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
|
|
309
|
-
expect(retrievedBlockProposal).toBeDefined();
|
|
310
|
-
expect(retrievedBlockProposal!.archive.toString()).toBe(archive.toString());
|
|
311
|
-
expect(retrievedBlockProposal!.blockHeader.toBuffer()).toEqual(expectedBlockProposal!.blockHeader.toBuffer());
|
|
270
|
+
expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer());
|
|
312
271
|
});
|
|
313
272
|
|
|
314
|
-
it('should
|
|
273
|
+
it('should handle checkpoint proposal without lastBlock (caller extracts and adds block separately)', async () => {
|
|
315
274
|
const slotNumber = 420;
|
|
316
275
|
const archive = Fr.random();
|
|
317
276
|
const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
|
|
@@ -324,13 +283,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
324
283
|
});
|
|
325
284
|
const proposalId = proposal.archive.toString();
|
|
326
285
|
|
|
327
|
-
|
|
286
|
+
// Add the checkpoint core - block extraction is now caller responsibility
|
|
287
|
+
await ap.tryAddCheckpointProposal(proposal.toCore());
|
|
328
288
|
|
|
329
289
|
// The checkpoint proposal should be stored
|
|
330
290
|
const retrievedCheckpointProposal = await ap.getCheckpointProposal(proposalId);
|
|
331
291
|
expect(retrievedCheckpointProposal).toBeDefined();
|
|
332
292
|
|
|
333
|
-
//
|
|
293
|
+
// No block proposal was extracted (it had none anyway)
|
|
334
294
|
const retrievedBlockProposal = await ap.getBlockProposal(proposalId);
|
|
335
295
|
expect(retrievedBlockProposal).toBeUndefined();
|
|
336
296
|
});
|
|
@@ -339,43 +299,423 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
339
299
|
const nonExistentId = Fr.random().toString();
|
|
340
300
|
const retrievedProposal = await ap.getCheckpointProposal(nonExistentId);
|
|
341
301
|
expect(retrievedProposal).toBeUndefined();
|
|
342
|
-
|
|
343
|
-
// Check hasCheckpointProposal returns false for non-existent proposal
|
|
344
|
-
expect(await ap.hasCheckpointProposal(nonExistentId)).toBe(false);
|
|
345
302
|
});
|
|
346
303
|
|
|
347
|
-
it('should
|
|
304
|
+
it('should return alreadyExists when adding proposal with same id', async () => {
|
|
348
305
|
const slotNumber = 420;
|
|
349
306
|
const archive = Fr.random();
|
|
350
307
|
const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
|
|
351
308
|
const proposalId = proposal1.archive.toString();
|
|
352
309
|
|
|
353
|
-
await ap.
|
|
310
|
+
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
311
|
+
expect(result1.added).toBe(true);
|
|
312
|
+
expect(result1.alreadyExists).toBe(false);
|
|
354
313
|
|
|
355
314
|
// Create a new proposal with same archive but different signer
|
|
356
315
|
const proposal2 = await mockCheckpointProposalForPool(signers[1], slotNumber, archive);
|
|
357
316
|
|
|
358
|
-
await ap.
|
|
317
|
+
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
318
|
+
expect(result2.added).toBe(false);
|
|
319
|
+
expect(result2.alreadyExists).toBe(true);
|
|
359
320
|
|
|
321
|
+
// Should still have the first proposal
|
|
360
322
|
const retrievedProposal = await ap.getCheckpointProposal(proposalId);
|
|
361
323
|
expect(retrievedProposal).toBeDefined();
|
|
362
|
-
|
|
363
|
-
expect(retrievedProposal!.
|
|
364
|
-
expect(retrievedProposal!.getSender()?.toString()).toBe(signers[1].address.toString());
|
|
324
|
+
expect(retrievedProposal!.toBuffer()).toEqual(proposal1.toBuffer());
|
|
325
|
+
expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString());
|
|
365
326
|
});
|
|
366
327
|
|
|
367
|
-
it('should
|
|
328
|
+
it('should return added=false when exceeding capacity', async () => {
|
|
368
329
|
const slotNumber = 420;
|
|
369
330
|
|
|
370
|
-
// Add
|
|
371
|
-
for (let i = 0; i <
|
|
331
|
+
// Add MAX_CHECKPOINT_PROPOSALS_PER_SLOT proposals
|
|
332
|
+
for (let i = 0; i < MAX_CHECKPOINT_PROPOSALS_PER_SLOT; i++) {
|
|
372
333
|
const proposal = await mockCheckpointProposalForPool(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber);
|
|
373
|
-
await ap.
|
|
334
|
+
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
335
|
+
expect(result.added).toBe(true);
|
|
336
|
+
expect(result.count).toBe(i + 1);
|
|
374
337
|
}
|
|
375
338
|
|
|
376
|
-
// The next proposal should
|
|
339
|
+
// The next proposal should not be added
|
|
377
340
|
const extraProposal = await mockCheckpointProposalForPool(signers[0], slotNumber);
|
|
378
|
-
await
|
|
341
|
+
const result = await ap.tryAddCheckpointProposal(extraProposal);
|
|
342
|
+
expect(result.added).toBe(false);
|
|
343
|
+
expect(result.alreadyExists).toBe(false);
|
|
344
|
+
expect(result.count).toBe(MAX_CHECKPOINT_PROPOSALS_PER_SLOT);
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
describe('Duplicate proposal detection', () => {
|
|
349
|
+
const mockBlockProposalWithIndex = (
|
|
350
|
+
signer: Secp256k1Signer,
|
|
351
|
+
slotNumber: number,
|
|
352
|
+
indexWithinCheckpoint: number,
|
|
353
|
+
archive: Fr = Fr.random(),
|
|
354
|
+
): Promise<BlockProposal> => {
|
|
355
|
+
const header = makeBlockHeader(1, { slotNumber: SlotNumber(slotNumber) });
|
|
356
|
+
return makeBlockProposal({
|
|
357
|
+
signer,
|
|
358
|
+
blockHeader: header,
|
|
359
|
+
archiveRoot: archive,
|
|
360
|
+
indexWithinCheckpoint: IndexWithinCheckpoint(indexWithinCheckpoint),
|
|
361
|
+
});
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
describe('tryAddBlockProposal duplicate detection', () => {
|
|
365
|
+
it('should return count=1 when pool is empty', async () => {
|
|
366
|
+
const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
|
|
367
|
+
const result = await ap.tryAddBlockProposal(proposal);
|
|
368
|
+
|
|
369
|
+
expect(result.added).toBe(true);
|
|
370
|
+
expect(result.alreadyExists).toBe(false);
|
|
371
|
+
expect(result.count).toBe(1);
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it('should return alreadyExists when same proposal exists', async () => {
|
|
375
|
+
const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
|
|
376
|
+
await ap.tryAddBlockProposal(proposal);
|
|
377
|
+
|
|
378
|
+
const result = await ap.tryAddBlockProposal(proposal);
|
|
379
|
+
|
|
380
|
+
expect(result.added).toBe(false);
|
|
381
|
+
expect(result.alreadyExists).toBe(true);
|
|
382
|
+
expect(result.count).toBe(1);
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it('should detect duplicate via count when different proposal exists at same position', async () => {
|
|
386
|
+
const slotNumber = 100;
|
|
387
|
+
const indexWithinCheckpoint = 2;
|
|
388
|
+
|
|
389
|
+
// Add first proposal
|
|
390
|
+
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
391
|
+
const result1 = await ap.tryAddBlockProposal(proposal1);
|
|
392
|
+
expect(result1.count).toBe(1);
|
|
393
|
+
|
|
394
|
+
// Add a different proposal at same position - this is a duplicate (equivocation)
|
|
395
|
+
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
|
|
396
|
+
const result2 = await ap.tryAddBlockProposal(proposal2);
|
|
397
|
+
|
|
398
|
+
expect(result2.added).toBe(true);
|
|
399
|
+
expect(result2.alreadyExists).toBe(false);
|
|
400
|
+
// count >= 2 indicates duplicate detection
|
|
401
|
+
expect(result2.count).toBe(2);
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
it('should not detect duplicate for different positions in same slot', async () => {
|
|
405
|
+
const slotNumber = 100;
|
|
406
|
+
|
|
407
|
+
// Add proposal at index 0
|
|
408
|
+
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
|
|
409
|
+
await ap.tryAddBlockProposal(proposal1);
|
|
410
|
+
|
|
411
|
+
// Add proposal at index 1 (different position)
|
|
412
|
+
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
|
|
413
|
+
const result = await ap.tryAddBlockProposal(proposal2);
|
|
414
|
+
|
|
415
|
+
expect(result.added).toBe(true);
|
|
416
|
+
// count = 1 means no duplicate for this position
|
|
417
|
+
expect(result.count).toBe(1);
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
it('should not detect duplicate for same position in different slots', async () => {
|
|
421
|
+
const indexWithinCheckpoint = 0;
|
|
422
|
+
|
|
423
|
+
// Add proposal at slot 100
|
|
424
|
+
const proposal1 = await mockBlockProposalWithIndex(signers[0], 100, indexWithinCheckpoint);
|
|
425
|
+
await ap.tryAddBlockProposal(proposal1);
|
|
426
|
+
|
|
427
|
+
// Add proposal at slot 200 (different slot)
|
|
428
|
+
const proposal2 = await mockBlockProposalWithIndex(signers[1], 200, indexWithinCheckpoint);
|
|
429
|
+
const result = await ap.tryAddBlockProposal(proposal2);
|
|
430
|
+
|
|
431
|
+
expect(result.added).toBe(true);
|
|
432
|
+
// count = 1 means no duplicate for this position
|
|
433
|
+
expect(result.count).toBe(1);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('should track multiple duplicates correctly via count', async () => {
|
|
437
|
+
const slotNumber = 100;
|
|
438
|
+
const indexWithinCheckpoint = 0;
|
|
439
|
+
|
|
440
|
+
// Add multiple proposals for same position
|
|
441
|
+
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
442
|
+
const result1 = await ap.tryAddBlockProposal(proposal1);
|
|
443
|
+
expect(result1.count).toBe(1);
|
|
444
|
+
|
|
445
|
+
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
|
|
446
|
+
const result2 = await ap.tryAddBlockProposal(proposal2);
|
|
447
|
+
expect(result2.count).toBe(2);
|
|
448
|
+
|
|
449
|
+
// Add a third proposal for same position
|
|
450
|
+
const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
|
|
451
|
+
const result3 = await ap.tryAddBlockProposal(proposal3);
|
|
452
|
+
|
|
453
|
+
expect(result3.added).toBe(true);
|
|
454
|
+
expect(result3.count).toBe(3);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
it('should return added=false when exceeding capacity', async () => {
|
|
458
|
+
const slotNumber = 100;
|
|
459
|
+
const indexWithinCheckpoint = 0;
|
|
460
|
+
|
|
461
|
+
// Add MAX_BLOCK_PROPOSALS_PER_POSITION proposals
|
|
462
|
+
for (let i = 0; i < MAX_BLOCK_PROPOSALS_PER_POSITION; i++) {
|
|
463
|
+
const proposal = await mockBlockProposalWithIndex(
|
|
464
|
+
signers[i % NUMBER_OF_SIGNERS_PER_TEST],
|
|
465
|
+
slotNumber,
|
|
466
|
+
indexWithinCheckpoint,
|
|
467
|
+
);
|
|
468
|
+
const result = await ap.tryAddBlockProposal(proposal);
|
|
469
|
+
expect(result.added).toBe(true);
|
|
470
|
+
expect(result.count).toBe(i + 1);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// The next proposal should not be added
|
|
474
|
+
const extraProposal = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
475
|
+
const result = await ap.tryAddBlockProposal(extraProposal);
|
|
476
|
+
expect(result.added).toBe(false);
|
|
477
|
+
expect(result.alreadyExists).toBe(false);
|
|
478
|
+
expect(result.count).toBe(MAX_BLOCK_PROPOSALS_PER_POSITION);
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it('should clean up block position index when deleting old data', async () => {
|
|
482
|
+
const slotNumber = 100;
|
|
483
|
+
const indexWithinCheckpoint = 0;
|
|
484
|
+
|
|
485
|
+
// Add proposal
|
|
486
|
+
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
487
|
+
await ap.tryAddBlockProposal(proposal1);
|
|
488
|
+
|
|
489
|
+
// Verify it's tracked (adding another should show count = 2)
|
|
490
|
+
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
|
|
491
|
+
let result = await ap.tryAddBlockProposal(proposal2);
|
|
492
|
+
expect(result.count).toBe(2);
|
|
493
|
+
|
|
494
|
+
// Delete old data
|
|
495
|
+
await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
|
|
496
|
+
|
|
497
|
+
// Verify position index is cleaned up (count should be 1 now)
|
|
498
|
+
const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
|
|
499
|
+
result = await ap.tryAddBlockProposal(proposal3);
|
|
500
|
+
expect(result.count).toBe(1);
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
it('should correctly delete block proposals at slot boundary', async () => {
|
|
504
|
+
// Add proposals at slots 99, 100, and 101 with various indices
|
|
505
|
+
const proposalSlot99Idx0 = await mockBlockProposalWithIndex(signers[0], 99, 0);
|
|
506
|
+
const proposalSlot99Idx1 = await mockBlockProposalWithIndex(signers[1], 99, 1);
|
|
507
|
+
const proposalSlot100Idx0 = await mockBlockProposalWithIndex(signers[2], 100, 0);
|
|
508
|
+
const proposalSlot101Idx0 = await mockBlockProposalWithIndex(signers[3], 101, 0);
|
|
509
|
+
|
|
510
|
+
await ap.tryAddBlockProposal(proposalSlot99Idx0);
|
|
511
|
+
await ap.tryAddBlockProposal(proposalSlot99Idx1);
|
|
512
|
+
await ap.tryAddBlockProposal(proposalSlot100Idx0);
|
|
513
|
+
await ap.tryAddBlockProposal(proposalSlot101Idx0);
|
|
514
|
+
|
|
515
|
+
// Delete slots older than 100 (should delete slot 99 only)
|
|
516
|
+
await ap.deleteOlderThan(SlotNumber(100));
|
|
517
|
+
|
|
518
|
+
// Slot 99 proposals should have their index cleaned up
|
|
519
|
+
const newProposal99 = await mockBlockProposalWithIndex(signers[0], 99, 0);
|
|
520
|
+
const result99 = await ap.tryAddBlockProposal(newProposal99);
|
|
521
|
+
expect(result99.count).toBe(1); // Index was cleaned up
|
|
522
|
+
|
|
523
|
+
// Slot 100 and 101 should still be tracked
|
|
524
|
+
const newProposal100 = await mockBlockProposalWithIndex(signers[1], 100, 0);
|
|
525
|
+
const result100 = await ap.tryAddBlockProposal(newProposal100);
|
|
526
|
+
expect(result100.count).toBe(2); // Still has the original
|
|
527
|
+
|
|
528
|
+
const newProposal101 = await mockBlockProposalWithIndex(signers[2], 101, 0);
|
|
529
|
+
const result101 = await ap.tryAddBlockProposal(newProposal101);
|
|
530
|
+
expect(result101.count).toBe(2); // Still has the original
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
it('should delete all indices for a given slot', async () => {
|
|
534
|
+
const slotNumber = 50;
|
|
535
|
+
|
|
536
|
+
// Add proposals at multiple indices for the same slot
|
|
537
|
+
const proposal0 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
|
|
538
|
+
const proposal1 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
|
|
539
|
+
const proposal2 = await mockBlockProposalWithIndex(signers[2], slotNumber, 2);
|
|
540
|
+
|
|
541
|
+
await ap.tryAddBlockProposal(proposal0);
|
|
542
|
+
await ap.tryAddBlockProposal(proposal1);
|
|
543
|
+
await ap.tryAddBlockProposal(proposal2);
|
|
544
|
+
|
|
545
|
+
// Delete slots older than slotNumber + 1
|
|
546
|
+
await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
|
|
547
|
+
|
|
548
|
+
// All indices should be cleaned up
|
|
549
|
+
const newProposal0 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
|
|
550
|
+
const result0 = await ap.tryAddBlockProposal(newProposal0);
|
|
551
|
+
expect(result0.count).toBe(1);
|
|
552
|
+
|
|
553
|
+
const newProposal1 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
|
|
554
|
+
const result1 = await ap.tryAddBlockProposal(newProposal1);
|
|
555
|
+
expect(result1.count).toBe(1);
|
|
556
|
+
|
|
557
|
+
const newProposal2 = await mockBlockProposalWithIndex(signers[2], slotNumber, 2);
|
|
558
|
+
const result2 = await ap.tryAddBlockProposal(newProposal2);
|
|
559
|
+
expect(result2.count).toBe(1);
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
it('should delete block proposals from storage when deleting old data', async () => {
|
|
563
|
+
const oldSlot = 50;
|
|
564
|
+
const newSlot = 100;
|
|
565
|
+
|
|
566
|
+
// Add proposals at old and new slots
|
|
567
|
+
const oldProposal = await mockBlockProposalWithIndex(signers[0], oldSlot, 0);
|
|
568
|
+
const newProposal = await mockBlockProposalWithIndex(signers[1], newSlot, 0);
|
|
569
|
+
|
|
570
|
+
await ap.tryAddBlockProposal(oldProposal);
|
|
571
|
+
await ap.tryAddBlockProposal(newProposal);
|
|
572
|
+
|
|
573
|
+
// Verify both proposals exist
|
|
574
|
+
expect(await ap.getBlockProposal(oldProposal.archive.toString())).toBeDefined();
|
|
575
|
+
expect(await ap.getBlockProposal(newProposal.archive.toString())).toBeDefined();
|
|
576
|
+
|
|
577
|
+
// Delete slots older than newSlot (should delete oldSlot)
|
|
578
|
+
await ap.deleteOlderThan(SlotNumber(newSlot));
|
|
579
|
+
|
|
580
|
+
// Old proposal should be deleted from storage
|
|
581
|
+
expect(await ap.getBlockProposal(oldProposal.archive.toString())).toBeUndefined();
|
|
582
|
+
|
|
583
|
+
// New proposal should still exist
|
|
584
|
+
expect(await ap.getBlockProposal(newProposal.archive.toString())).toBeDefined();
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
describe('tryAddCheckpointProposal duplicate detection', () => {
|
|
589
|
+
const mockCheckpointProposalCoreForPool = async (
|
|
590
|
+
signer: Secp256k1Signer,
|
|
591
|
+
slotNumber: number,
|
|
592
|
+
archive: Fr = Fr.random(),
|
|
593
|
+
): Promise<CheckpointProposalCore> => {
|
|
594
|
+
const checkpointHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
|
|
595
|
+
const blockHeader = makeBlockHeader(1);
|
|
596
|
+
const proposal = await makeCheckpointProposal({
|
|
597
|
+
signer,
|
|
598
|
+
checkpointHeader,
|
|
599
|
+
archiveRoot: archive,
|
|
600
|
+
lastBlock: { blockHeader },
|
|
601
|
+
});
|
|
602
|
+
return proposal.toCore();
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
it('should return count=1 when pool is empty', async () => {
|
|
606
|
+
const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
|
|
607
|
+
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
608
|
+
|
|
609
|
+
expect(result.added).toBe(true);
|
|
610
|
+
expect(result.alreadyExists).toBe(false);
|
|
611
|
+
expect(result.count).toBe(1);
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
it('should return alreadyExists when same proposal exists', async () => {
|
|
615
|
+
const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
|
|
616
|
+
await ap.tryAddCheckpointProposal(proposal);
|
|
617
|
+
|
|
618
|
+
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
619
|
+
|
|
620
|
+
expect(result.added).toBe(false);
|
|
621
|
+
expect(result.alreadyExists).toBe(true);
|
|
622
|
+
expect(result.count).toBe(1);
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
it('should detect duplicate via count when different proposal exists for same slot', async () => {
|
|
626
|
+
const slotNumber = 100;
|
|
627
|
+
|
|
628
|
+
// Add first proposal
|
|
629
|
+
const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
|
|
630
|
+
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
631
|
+
expect(result1.count).toBe(1);
|
|
632
|
+
|
|
633
|
+
// Add a different proposal for same slot - this is a duplicate (equivocation)
|
|
634
|
+
const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
|
|
635
|
+
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
636
|
+
|
|
637
|
+
expect(result2.added).toBe(true);
|
|
638
|
+
expect(result2.alreadyExists).toBe(false);
|
|
639
|
+
// count >= 2 indicates duplicate detection
|
|
640
|
+
expect(result2.count).toBe(2);
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
it('should not detect duplicate for different slots', async () => {
|
|
644
|
+
// Add proposal at slot 100
|
|
645
|
+
const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], 100);
|
|
646
|
+
await ap.tryAddCheckpointProposal(proposal1);
|
|
647
|
+
|
|
648
|
+
// Add proposal at slot 200 (different slot)
|
|
649
|
+
const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], 200);
|
|
650
|
+
const result = await ap.tryAddCheckpointProposal(proposal2);
|
|
651
|
+
|
|
652
|
+
expect(result.added).toBe(true);
|
|
653
|
+
// count = 1 means no duplicate for this slot
|
|
654
|
+
expect(result.count).toBe(1);
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
it('should track multiple duplicates correctly via count', async () => {
|
|
658
|
+
const slotNumber = 100;
|
|
659
|
+
|
|
660
|
+
// Add multiple proposals for same slot
|
|
661
|
+
const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
|
|
662
|
+
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
663
|
+
expect(result1.count).toBe(1);
|
|
664
|
+
|
|
665
|
+
const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
|
|
666
|
+
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
667
|
+
expect(result2.count).toBe(2);
|
|
668
|
+
|
|
669
|
+
// Add a third proposal for same slot
|
|
670
|
+
const proposal3 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber);
|
|
671
|
+
const result3 = await ap.tryAddCheckpointProposal(proposal3);
|
|
672
|
+
|
|
673
|
+
expect(result3.added).toBe(true);
|
|
674
|
+
expect(result3.count).toBe(3);
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
it('should not count attestations as proposals for duplicate detection', async () => {
|
|
678
|
+
const slotNumber = 100;
|
|
679
|
+
const archive = Fr.random();
|
|
680
|
+
|
|
681
|
+
// Attestation arrives BEFORE the checkpoint proposal (race condition in p2p)
|
|
682
|
+
const attestation = mockCheckpointAttestation(signers[0], slotNumber, archive);
|
|
683
|
+
await ap.addOwnCheckpointAttestations([attestation]);
|
|
684
|
+
|
|
685
|
+
// Now the checkpoint proposal arrives - this should NOT be detected as a duplicate
|
|
686
|
+
const proposal = await mockCheckpointProposalCoreForPool(signers[1], slotNumber, archive);
|
|
687
|
+
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
688
|
+
|
|
689
|
+
expect(result.added).toBe(true);
|
|
690
|
+
expect(result.alreadyExists).toBe(false);
|
|
691
|
+
// count should be 1, NOT 2 - attestations should not count as proposals
|
|
692
|
+
expect(result.count).toBe(1);
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
it('should not count attestations for different proposals as duplicates', async () => {
|
|
696
|
+
const slotNumber = 100;
|
|
697
|
+
const archive1 = Fr.random();
|
|
698
|
+
const archive2 = Fr.random();
|
|
699
|
+
|
|
700
|
+
// Add attestations for two different proposals in the same slot
|
|
701
|
+
const attestation1 = mockCheckpointAttestation(signers[0], slotNumber, archive1);
|
|
702
|
+
const attestation2 = mockCheckpointAttestation(signers[1], slotNumber, archive2);
|
|
703
|
+
await ap.addOwnCheckpointAttestations([attestation1, attestation2]);
|
|
704
|
+
|
|
705
|
+
// Add the first checkpoint proposal - should not be affected by attestations
|
|
706
|
+
const proposal1 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber, archive1);
|
|
707
|
+
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
708
|
+
|
|
709
|
+
expect(result1.added).toBe(true);
|
|
710
|
+
expect(result1.count).toBe(1);
|
|
711
|
+
|
|
712
|
+
// Add the second checkpoint proposal - this IS a duplicate (different archive, same slot)
|
|
713
|
+
const proposal2 = await mockCheckpointProposalCoreForPool(signers[3], slotNumber, archive2);
|
|
714
|
+
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
715
|
+
|
|
716
|
+
expect(result2.added).toBe(true);
|
|
717
|
+
expect(result2.count).toBe(2);
|
|
718
|
+
});
|
|
379
719
|
});
|
|
380
720
|
});
|
|
381
721
|
}
|