@aztec/p2p 0.0.1-commit.f2ce05ee → 0.0.1-commit.f5a9928
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/README.md +130 -3
- package/dest/bootstrap/bootstrap.d.ts +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +22 -6
- package/dest/client/factory.d.ts +11 -10
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +64 -17
- package/dest/client/interface.d.ts +86 -40
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +67 -64
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +251 -251
- package/dest/config.d.ts +173 -94
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +158 -44
- package/dest/errors/p2p-service.error.d.ts +9 -0
- package/dest/errors/p2p-service.error.d.ts.map +1 -0
- package/dest/errors/p2p-service.error.js +10 -0
- package/dest/errors/reqresp.error.d.ts +9 -16
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/errors/reqresp.error.js +10 -17
- 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 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +106 -55
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +302 -195
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- 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 +274 -115
- package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/index.js +1 -1
- 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 +7 -5
- package/dest/mem_pools/index.d.ts +2 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.d.ts +12 -5
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +38 -17
- package/dest/mem_pools/interface.d.ts +3 -3
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +10 -5
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +29 -20
- 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 +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +8 -4
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +15 -5
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +3 -2
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +2 -1
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +64 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +6 -5
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +9 -8
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +15 -6
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
- package/dest/mem_pools/tx_pool_v2/index.d.ts +3 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +2 -1
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +25 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.js +67 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +62 -16
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +6 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +81 -15
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +147 -19
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +26 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +79 -43
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +27 -7
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +94 -32
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +62 -9
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +537 -246
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +10 -3
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +38 -15
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -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 +4 -5
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +12 -5
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +11 -3
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +12 -5
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +23 -3
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +36 -9
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +130 -48
- 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 +11 -18
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +25 -21
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
- package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
- package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
- package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +36 -2
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
- package/dest/msg_validators/tx_validator/factory.d.ts +133 -7
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +261 -61
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +104 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +137 -53
- package/dest/msg_validators/tx_validator/index.d.ts +5 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +4 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
- 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 +22 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
- 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 -0
- package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
- package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
- 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 +5 -5
- package/dest/services/discv5/discV5_service.d.ts +13 -2
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +119 -23
- package/dest/services/discv5/persisted_enr_store.d.ts +38 -0
- package/dest/services/discv5/persisted_enr_store.d.ts.map +1 -0
- package/dest/services/discv5/persisted_enr_store.js +145 -0
- package/dest/services/dummy_service.d.ts +25 -19
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +28 -20
- package/dest/services/encoding.d.ts +24 -7
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +43 -26
- package/dest/services/gossipsub/topic_score_params.d.ts +23 -17
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +36 -24
- package/dest/services/libp2p/instrumentation.d.ts +6 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +21 -0
- package/dest/services/libp2p/libp2p_service.d.ts +71 -60
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +602 -407
- package/dest/services/peer-manager/metrics.d.ts +3 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +6 -0
- package/dest/services/peer-manager/peer_manager.d.ts +31 -3
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +127 -26
- package/dest/services/peer-manager/peer_scoring.d.ts +34 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +102 -13
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +5 -8
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +95 -127
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +11 -11
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
- package/dest/services/reqresp/config.d.ts +15 -3
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/config.js +11 -0
- package/dest/services/reqresp/interface.d.ts +25 -18
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +23 -19
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +0 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
- 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 +31 -28
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +18 -7
- 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 +57 -24
- package/dest/services/reqresp/protocols/index.d.ts +1 -2
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.js +0 -1
- 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 +21 -3
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.js +3 -13
- package/dest/services/reqresp/reqresp.d.ts +7 -29
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +85 -219
- package/dest/services/service.d.ts +63 -19
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +11 -14
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +26 -33
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +37 -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 +127 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts +38 -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 +100 -0
- package/dest/services/tx_collection/index.d.ts +3 -3
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +1 -1
- package/dest/services/tx_collection/instrumentation.js +1 -2
- package/dest/services/tx_collection/request_tracker.d.ts +53 -0
- package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/request_tracker.js +84 -0
- package/dest/services/tx_collection/tx_collection.d.ts +45 -51
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +296 -68
- package/dest/services/tx_collection/tx_collection_sink.d.ts +19 -9
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +28 -31
- package/dest/services/tx_collection/tx_source.d.ts +13 -7
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +29 -7
- package/dest/services/tx_file_store/config.d.ts +1 -3
- package/dest/services/tx_file_store/config.d.ts.map +1 -1
- package/dest/services/tx_file_store/config.js +0 -4
- package/dest/services/tx_file_store/tx_file_store.d.ts +4 -5
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
- package/dest/services/tx_file_store/tx_file_store.js +13 -20
- package/dest/services/tx_provider.d.ts +6 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +12 -8
- 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 +5 -3
- package/dest/test-helpers/mock-pubsub.d.ts +56 -6
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +128 -14
- package/dest/test-helpers/reqresp-nodes.d.ts +5 -7
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +17 -19
- package/dest/test-helpers/test_tx_provider.d.ts +3 -1
- package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
- package/dest/test-helpers/test_tx_provider.js +3 -0
- package/dest/test-helpers/testbench-utils.d.ts +49 -37
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +142 -50
- package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +112 -49
- package/dest/testbench/worker_client_manager.d.ts +12 -6
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +57 -11
- package/dest/util.d.ts +13 -8
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +35 -14
- package/dest/versioning.d.ts +3 -6
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +3 -24
- package/package.json +17 -17
- package/src/bootstrap/bootstrap.ts +17 -3
- package/src/client/factory.ts +129 -28
- package/src/client/interface.ts +88 -48
- package/src/client/p2p_client.ts +284 -317
- package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
- package/src/config.ts +280 -49
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/errors/reqresp.error.ts +13 -19
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +373 -236
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +298 -119
- package/src/mem_pools/attestation_pool/index.ts +3 -3
- package/src/mem_pools/attestation_pool/mocks.ts +14 -8
- package/src/mem_pools/index.ts +1 -1
- package/src/mem_pools/instrumentation.ts +27 -17
- package/src/mem_pools/interface.ts +2 -2
- package/src/mem_pools/tx_pool_v2/README.md +85 -11
- package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +30 -20
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +6 -4
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +21 -6
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +5 -0
- package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +67 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +4 -6
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +8 -10
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +14 -10
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
- package/src/mem_pools/tx_pool_v2/index.ts +2 -1
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +96 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +63 -16
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +215 -27
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +91 -43
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +122 -33
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +602 -242
- package/src/msg_validators/attestation_validator/README.md +49 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +46 -14
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +15 -7
- package/src/msg_validators/proposal_validator/README.md +123 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +26 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +43 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +155 -49
- package/src/msg_validators/tx_validator/README.md +129 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +8 -17
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
- package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
- package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
- package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +44 -1
- package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
- package/src/msg_validators/tx_validator/factory.ts +413 -80
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +195 -54
- package/src/msg_validators/tx_validator/index.ts +4 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
- package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
- package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
- package/src/services/data_store.ts +5 -13
- package/src/services/discv5/discV5_service.ts +126 -14
- package/src/services/discv5/persisted_enr_store.ts +158 -0
- package/src/services/dummy_service.ts +38 -46
- package/src/services/encoding.ts +42 -26
- package/src/services/gossipsub/README.md +59 -22
- package/src/services/gossipsub/topic_score_params.ts +58 -31
- package/src/services/libp2p/instrumentation.ts +22 -0
- package/src/services/libp2p/libp2p_service.ts +687 -466
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +140 -25
- package/src/services/peer-manager/peer_scoring.ts +102 -8
- package/src/services/reqresp/README.md +194 -0
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +92 -138
- package/src/services/reqresp/batch-tx-requester/interface.ts +14 -10
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
- package/src/services/reqresp/config.ts +19 -2
- package/src/services/reqresp/interface.ts +45 -46
- package/src/services/reqresp/metrics.ts +0 -1
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +36 -32
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +64 -20
- package/src/services/reqresp/protocols/index.ts +0 -1
- package/src/services/reqresp/protocols/tx.ts +23 -3
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
- package/src/services/reqresp/rate-limiter/rate_limits.ts +3 -13
- package/src/services/reqresp/reqresp.ts +100 -263
- package/src/services/service.ts +80 -35
- package/src/services/tx_collection/config.ts +40 -49
- package/src/services/tx_collection/file_store_tx_collection.ts +153 -0
- package/src/services/tx_collection/file_store_tx_source.ts +129 -0
- package/src/services/tx_collection/index.ts +2 -6
- package/src/services/tx_collection/instrumentation.ts +1 -1
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/tx_collection.ts +362 -110
- package/src/services/tx_collection/tx_collection_sink.ts +32 -36
- package/src/services/tx_collection/tx_source.ts +29 -8
- package/src/services/tx_file_store/config.ts +0 -6
- package/src/services/tx_file_store/tx_file_store.ts +15 -25
- package/src/services/tx_provider.ts +15 -9
- package/src/test-helpers/make-test-p2p-clients.ts +7 -6
- package/src/test-helpers/mock-pubsub.ts +152 -14
- package/src/test-helpers/reqresp-nodes.ts +15 -28
- package/src/test-helpers/test_tx_provider.ts +5 -0
- package/src/test-helpers/testbench-utils.ts +171 -68
- package/src/testbench/p2p_client_testbench_worker.ts +121 -64
- package/src/testbench/worker_client_manager.ts +72 -25
- package/src/util.ts +40 -19
- package/src/versioning.ts +3 -33
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -305
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
- package/dest/mem_pools/tx_pool/index.d.ts +0 -3
- package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/index.js +0 -2
- package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
- package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/priority.js +0 -15
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
- package/dest/msg_validators/clock_tolerance.d.ts +0 -21
- package/dest/msg_validators/clock_tolerance.d.ts.map +0 -1
- package/dest/msg_validators/clock_tolerance.js +0 -37
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
- package/dest/services/reqresp/protocols/block.d.ts +0 -9
- package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/block.js +0 -32
- package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -52
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
- package/dest/services/tx_collection/fast_tx_collection.js +0 -307
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -48
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +0 -49
- package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -53
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
- package/dest/services/tx_collection/slow_tx_collection.js +0 -177
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -336
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
- package/src/mem_pools/tx_pool/README.md +0 -270
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
- package/src/mem_pools/tx_pool/index.ts +0 -2
- package/src/mem_pools/tx_pool/priority.ts +0 -20
- package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
- package/src/msg_validators/clock_tolerance.ts +0 -51
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
- package/src/services/reqresp/protocols/block.ts +0 -37
- package/src/services/tx_collection/fast_tx_collection.ts +0 -354
- package/src/services/tx_collection/proposal_tx_collector.ts +0 -112
- package/src/services/tx_collection/slow_tx_collection.ts +0 -233
|
@@ -1,7 +1,9 @@
|
|
|
1
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
|
|
4
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
5
|
+
import type { BlockProposal, CheckpointProposalCore } from '@aztec/stdlib/p2p';
|
|
6
|
+
import { CheckpointAttestation } from '@aztec/stdlib/p2p';
|
|
5
7
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
6
8
|
import {
|
|
7
9
|
makeBlockHeader,
|
|
@@ -10,7 +12,11 @@ import {
|
|
|
10
12
|
makeCheckpointProposal,
|
|
11
13
|
} from '@aztec/stdlib/testing';
|
|
12
14
|
|
|
13
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
type AttestationPool,
|
|
17
|
+
MAX_BLOCK_PROPOSALS_PER_POSITION,
|
|
18
|
+
MAX_CHECKPOINT_PROPOSALS_PER_SLOT,
|
|
19
|
+
} from './attestation_pool.js';
|
|
14
20
|
import { mockCheckpointAttestation } from './mocks.js';
|
|
15
21
|
|
|
16
22
|
const NUMBER_OF_SIGNERS_PER_TEST = 4;
|
|
@@ -24,9 +30,16 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
24
30
|
signers = Array.from({ length: NUMBER_OF_SIGNERS_PER_TEST }, () => Secp256k1Signer.random());
|
|
25
31
|
});
|
|
26
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Build attestations from each signer over the *same* signed payload (same header,
|
|
35
|
+
* archive, feeAssetPriceModifier). Required by the new pool, which deduplicates by
|
|
36
|
+
* payload hash and treats attestations from different signers as distinct entries
|
|
37
|
+
* only when the payload itself matches.
|
|
38
|
+
*/
|
|
27
39
|
const createCheckpointAttestationsForSlot = (slotNumber: number, archive?: Fr) => {
|
|
28
40
|
const archiveToUse = archive ?? Fr.random();
|
|
29
|
-
|
|
41
|
+
const sharedHeader = CheckpointHeader.random({ slotNumber: SlotNumber(slotNumber) });
|
|
42
|
+
return signers.map(signer => mockCheckpointAttestation(signer, slotNumber, archiveToUse, sharedHeader));
|
|
30
43
|
};
|
|
31
44
|
|
|
32
45
|
const mockBlockProposalForPool = (
|
|
@@ -51,17 +64,58 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
51
64
|
expect(a1Buffer).toEqual(expect.arrayContaining(a2Buffer));
|
|
52
65
|
};
|
|
53
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Rewrites the attester signature into yParity form (27 -> 0, 28 -> 1), keeping (r, s). The recovery
|
|
69
|
+
* bit is unchanged so it still recovers to the same signer, mimicking a peer that gossips (or mutates
|
|
70
|
+
* in flight) a signature with a non-canonical recovery byte.
|
|
71
|
+
*/
|
|
72
|
+
const toYParityForm = (attestation: CheckpointAttestation): CheckpointAttestation => {
|
|
73
|
+
const sig = attestation.signature;
|
|
74
|
+
const yParityV = sig.v === 27 ? 0 : sig.v === 28 ? 1 : sig.v;
|
|
75
|
+
return new CheckpointAttestation(
|
|
76
|
+
attestation.payload,
|
|
77
|
+
new Signature(sig.r, sig.s, yParityV),
|
|
78
|
+
attestation.proposerSignature,
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
54
82
|
describe('CheckpointAttestation', () => {
|
|
83
|
+
it('normalizes yParity (v=0/v=1) attester signatures on ingress from both gossip and own keys', async () => {
|
|
84
|
+
const slotNumber = 421;
|
|
85
|
+
const canonical = createCheckpointAttestationsForSlot(slotNumber);
|
|
86
|
+
const payloadHash = canonical[0].getPayloadHash();
|
|
87
|
+
const expectedSenders = new Set([canonical[0].getSender()!.toString(), canonical[1].getSender()!.toString()]);
|
|
88
|
+
|
|
89
|
+
const gossiped = toYParityForm(canonical[0]);
|
|
90
|
+
expect([0, 1]).toContain(gossiped.signature.v);
|
|
91
|
+
await ap.tryAddCheckpointAttestation(gossiped);
|
|
92
|
+
|
|
93
|
+
const own = toYParityForm(canonical[1]);
|
|
94
|
+
expect([0, 1]).toContain(own.signature.v);
|
|
95
|
+
await ap.addOwnCheckpointAttestations([own]);
|
|
96
|
+
|
|
97
|
+
const retrieved = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
|
|
98
|
+
expect(retrieved.length).toBe(2);
|
|
99
|
+
for (const attestation of retrieved) {
|
|
100
|
+
expect([27, 28]).toContain(attestation.signature.v);
|
|
101
|
+
expect(expectedSenders.has(attestation.getSender()!.toString())).toBe(true);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
55
105
|
it('should add attestations to pool', async () => {
|
|
56
106
|
const slotNumber = 420;
|
|
57
107
|
const archive = Fr.random();
|
|
58
|
-
const
|
|
108
|
+
const sharedHeader = CheckpointHeader.random({ slotNumber: SlotNumber(slotNumber) });
|
|
109
|
+
const attestations = signers
|
|
110
|
+
.slice(0, -1)
|
|
111
|
+
.map(signer => mockCheckpointAttestation(signer, slotNumber, archive, sharedHeader));
|
|
112
|
+
const payloadHash = attestations[0].getPayloadHash();
|
|
59
113
|
|
|
60
114
|
await ap.addOwnCheckpointAttestations(attestations);
|
|
61
115
|
|
|
62
116
|
const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
63
117
|
SlotNumber(slotNumber),
|
|
64
|
-
|
|
118
|
+
payloadHash,
|
|
65
119
|
);
|
|
66
120
|
expect(retrievedAttestations.length).toBe(attestations.length);
|
|
67
121
|
compareCheckpointAttestations(retrievedAttestations, attestations);
|
|
@@ -71,11 +125,16 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
71
125
|
compareCheckpointAttestations(retrievedAttestationsForSlot, attestations);
|
|
72
126
|
|
|
73
127
|
// Add another one
|
|
74
|
-
const newAttestation = mockCheckpointAttestation(
|
|
128
|
+
const newAttestation = mockCheckpointAttestation(
|
|
129
|
+
signers[NUMBER_OF_SIGNERS_PER_TEST - 1],
|
|
130
|
+
slotNumber,
|
|
131
|
+
archive,
|
|
132
|
+
sharedHeader,
|
|
133
|
+
);
|
|
75
134
|
await ap.addOwnCheckpointAttestations([newAttestation]);
|
|
76
135
|
const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
77
136
|
SlotNumber(slotNumber),
|
|
78
|
-
|
|
137
|
+
payloadHash,
|
|
79
138
|
);
|
|
80
139
|
expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
|
|
81
140
|
compareCheckpointAttestations(retrievedAttestationsAfterAdd, [...attestations, newAttestation]);
|
|
@@ -88,7 +147,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
88
147
|
|
|
89
148
|
const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
90
149
|
SlotNumber(slotNumber),
|
|
91
|
-
|
|
150
|
+
payloadHash,
|
|
92
151
|
);
|
|
93
152
|
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
94
153
|
});
|
|
@@ -104,13 +163,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
104
163
|
for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) {
|
|
105
164
|
attestations.push(mockCheckpointAttestation(signer, slotNumber, archive, header));
|
|
106
165
|
}
|
|
166
|
+
const payloadHash = attestations[0].getPayloadHash();
|
|
107
167
|
|
|
108
168
|
// Add them to store and check we end up with only one
|
|
109
169
|
await ap.addOwnCheckpointAttestations(attestations);
|
|
110
170
|
|
|
111
171
|
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
112
172
|
SlotNumber(slotNumber),
|
|
113
|
-
|
|
173
|
+
payloadHash,
|
|
114
174
|
);
|
|
115
175
|
expect(retreivedAttestations.length).toBe(1);
|
|
116
176
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
|
|
@@ -118,9 +178,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
118
178
|
|
|
119
179
|
// Try adding them on another operation and check they are still not duplicated
|
|
120
180
|
await ap.addOwnCheckpointAttestations([attestations[0]]);
|
|
121
|
-
expect(
|
|
122
|
-
await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), archive.toString()),
|
|
123
|
-
).toHaveLength(1);
|
|
181
|
+
expect(await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash)).toHaveLength(1);
|
|
124
182
|
});
|
|
125
183
|
|
|
126
184
|
it('should store attestations by differing slot', async () => {
|
|
@@ -131,9 +189,9 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
131
189
|
|
|
132
190
|
for (const attestation of attestations) {
|
|
133
191
|
const slot = attestation.payload.header.slotNumber;
|
|
134
|
-
const
|
|
192
|
+
const payloadHash = attestation.getPayloadHash();
|
|
135
193
|
|
|
136
|
-
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot,
|
|
194
|
+
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, payloadHash);
|
|
137
195
|
expect(retreivedAttestations.length).toBe(1);
|
|
138
196
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
139
197
|
expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
|
|
@@ -149,9 +207,9 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
149
207
|
|
|
150
208
|
for (const attestation of attestations) {
|
|
151
209
|
const slot = attestation.payload.header.slotNumber;
|
|
152
|
-
const
|
|
210
|
+
const payloadHash = attestation.getPayloadHash();
|
|
153
211
|
|
|
154
|
-
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot,
|
|
212
|
+
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, payloadHash);
|
|
155
213
|
expect(retreivedAttestations.length).toBe(1);
|
|
156
214
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
157
215
|
expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
|
|
@@ -160,21 +218,25 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
160
218
|
|
|
161
219
|
it('should delete attestations older than a given slot', async () => {
|
|
162
220
|
const slotNumbers = [1, 2, 3, 69, 72, 74, 88, 420];
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
)
|
|
166
|
-
const
|
|
221
|
+
const attestationsPerSlot = await Promise.all(
|
|
222
|
+
slotNumbers.map(slotNumber => createCheckpointAttestationsForSlot(slotNumber)),
|
|
223
|
+
);
|
|
224
|
+
const attestations = attestationsPerSlot.flat();
|
|
225
|
+
const payloadHashForSlot1 = attestationsPerSlot[0][0].getPayloadHash();
|
|
167
226
|
|
|
168
227
|
await ap.addOwnCheckpointAttestations(attestations);
|
|
169
228
|
|
|
170
|
-
const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
229
|
+
const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
230
|
+
SlotNumber(1),
|
|
231
|
+
payloadHashForSlot1,
|
|
232
|
+
);
|
|
171
233
|
expect(attestationsForSlot1.length).toBe(signers.length);
|
|
172
234
|
|
|
173
235
|
await ap.deleteOlderThan(SlotNumber(73));
|
|
174
236
|
|
|
175
237
|
const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(
|
|
176
238
|
SlotNumber(1),
|
|
177
|
-
|
|
239
|
+
payloadHashForSlot1,
|
|
178
240
|
);
|
|
179
241
|
expect(attestationsForSlot1AfterDelete.length).toBe(0);
|
|
180
242
|
});
|
|
@@ -185,15 +247,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
185
247
|
const slotNumber = 420;
|
|
186
248
|
const archive = Fr.random();
|
|
187
249
|
const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
|
|
188
|
-
const proposalId = proposal.archive.toString();
|
|
189
250
|
|
|
190
251
|
const result = await ap.tryAddBlockProposal(proposal);
|
|
191
252
|
|
|
192
253
|
expect(result.added).toBe(true);
|
|
193
254
|
expect(result.alreadyExists).toBe(false);
|
|
194
|
-
expect(result.
|
|
255
|
+
expect(result.count).toBe(1);
|
|
195
256
|
|
|
196
|
-
const retrievedProposal = await ap.
|
|
257
|
+
const retrievedProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
|
|
197
258
|
|
|
198
259
|
expect(retrievedProposal).toBeDefined();
|
|
199
260
|
expect(retrievedProposal!).toEqual(proposal);
|
|
@@ -201,33 +262,68 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
201
262
|
|
|
202
263
|
it('should return undefined for non-existent block proposal', async () => {
|
|
203
264
|
const nonExistentId = Fr.random().toString();
|
|
204
|
-
const retrievedProposal = await ap.
|
|
265
|
+
const retrievedProposal = await ap.getBlockProposalByArchive(nonExistentId);
|
|
205
266
|
expect(retrievedProposal).toBeUndefined();
|
|
206
267
|
});
|
|
207
268
|
|
|
208
|
-
it('should return alreadyExists when adding
|
|
269
|
+
it('should return alreadyExists when re-adding the same signed payload', async () => {
|
|
209
270
|
const slotNumber = 420;
|
|
210
271
|
const archive = Fr.random();
|
|
211
|
-
const
|
|
212
|
-
const proposalId = proposal1.archive.toString();
|
|
272
|
+
const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
|
|
213
273
|
|
|
214
|
-
const result1 = await ap.tryAddBlockProposal(
|
|
274
|
+
const result1 = await ap.tryAddBlockProposal(proposal);
|
|
215
275
|
expect(result1.added).toBe(true);
|
|
216
276
|
expect(result1.alreadyExists).toBe(false);
|
|
217
277
|
|
|
218
|
-
//
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
const result2 = await ap.tryAddBlockProposal(proposal2);
|
|
278
|
+
// Re-broadcasting the exact same proposal yields alreadyExists.
|
|
279
|
+
const result2 = await ap.tryAddBlockProposal(proposal);
|
|
222
280
|
expect(result2.added).toBe(false);
|
|
223
281
|
expect(result2.alreadyExists).toBe(true);
|
|
224
282
|
|
|
225
|
-
|
|
226
|
-
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
283
|
+
const retrievedProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
|
|
227
284
|
expect(retrievedProposal).toBeDefined();
|
|
228
|
-
expect(retrievedProposal!.toBuffer()).toEqual(
|
|
285
|
+
expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer());
|
|
229
286
|
expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString());
|
|
230
287
|
});
|
|
288
|
+
|
|
289
|
+
it('should retain an exact duplicate block proposal only once', async () => {
|
|
290
|
+
const slotNumber = 420;
|
|
291
|
+
const proposal = await mockBlockProposalForPool(signers[0], slotNumber);
|
|
292
|
+
|
|
293
|
+
await ap.tryAddBlockProposal(proposal);
|
|
294
|
+
await ap.tryAddBlockProposal(proposal);
|
|
295
|
+
|
|
296
|
+
const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
|
|
297
|
+
expect(proposals.blockProposals.map(proposal => proposal.toBuffer())).toEqual([
|
|
298
|
+
proposal.withoutSignedTxs().toBuffer(),
|
|
299
|
+
]);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('should retain all accepted block proposals at a position', async () => {
|
|
303
|
+
const slotNumber = 420;
|
|
304
|
+
const blockHeader = makeBlockHeader(1, { slotNumber: SlotNumber(slotNumber) });
|
|
305
|
+
const proposal1 = await makeBlockProposal({
|
|
306
|
+
signer: signers[0],
|
|
307
|
+
blockHeader,
|
|
308
|
+
archiveRoot: Fr.random(),
|
|
309
|
+
indexWithinCheckpoint: IndexWithinCheckpoint(1),
|
|
310
|
+
});
|
|
311
|
+
const proposal2 = await makeBlockProposal({
|
|
312
|
+
signer: signers[0],
|
|
313
|
+
blockHeader,
|
|
314
|
+
archiveRoot: Fr.random(),
|
|
315
|
+
indexWithinCheckpoint: IndexWithinCheckpoint(1),
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
await ap.tryAddBlockProposal(proposal1);
|
|
319
|
+
await ap.tryAddBlockProposal(proposal2);
|
|
320
|
+
|
|
321
|
+
const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
|
|
322
|
+
expect(proposals.blockProposals.map(proposal => proposal.toBuffer())).toEqual(
|
|
323
|
+
expect.arrayContaining([proposal1.withoutSignedTxs().toBuffer(), proposal2.withoutSignedTxs().toBuffer()]),
|
|
324
|
+
);
|
|
325
|
+
expect(await ap.getBlockProposalByArchive(proposal2.archive.toString())).toBeDefined();
|
|
326
|
+
});
|
|
231
327
|
});
|
|
232
328
|
|
|
233
329
|
describe('CheckpointProposal in attestation pool', () => {
|
|
@@ -235,12 +331,13 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
235
331
|
signer: Secp256k1Signer,
|
|
236
332
|
slotNumber: number,
|
|
237
333
|
archive: Fr = Fr.random(),
|
|
334
|
+
checkpointHeader?: CheckpointHeader,
|
|
238
335
|
): Promise<CheckpointProposalCore> => {
|
|
239
|
-
const
|
|
336
|
+
const headerToUse = checkpointHeader ?? makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
|
|
240
337
|
const blockHeader = makeBlockHeader(1);
|
|
241
338
|
const proposal = await makeCheckpointProposal({
|
|
242
339
|
signer,
|
|
243
|
-
checkpointHeader,
|
|
340
|
+
checkpointHeader: headerToUse,
|
|
244
341
|
archiveRoot: archive,
|
|
245
342
|
lastBlock: { blockHeader },
|
|
246
343
|
});
|
|
@@ -252,15 +349,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
252
349
|
const slotNumber = 420;
|
|
253
350
|
const archive = Fr.random();
|
|
254
351
|
const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
|
|
255
|
-
const proposalId = proposal.archive.toString();
|
|
256
352
|
|
|
257
353
|
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
258
354
|
|
|
259
355
|
expect(result.added).toBe(true);
|
|
260
356
|
expect(result.alreadyExists).toBe(false);
|
|
261
|
-
expect(result.
|
|
357
|
+
expect(result.count).toBe(1);
|
|
262
358
|
|
|
263
|
-
const retrievedProposal = await ap.getCheckpointProposal(
|
|
359
|
+
const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
|
|
264
360
|
|
|
265
361
|
expect(retrievedProposal).toBeDefined();
|
|
266
362
|
expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer());
|
|
@@ -277,67 +373,149 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
277
373
|
archiveRoot: archive,
|
|
278
374
|
// No lastBlock
|
|
279
375
|
});
|
|
280
|
-
const proposalId = proposal.archive.toString();
|
|
281
376
|
|
|
282
377
|
// Add the checkpoint core - block extraction is now caller responsibility
|
|
283
378
|
await ap.tryAddCheckpointProposal(proposal.toCore());
|
|
284
379
|
|
|
285
380
|
// The checkpoint proposal should be stored
|
|
286
|
-
const retrievedCheckpointProposal = await ap.getCheckpointProposal(
|
|
381
|
+
const retrievedCheckpointProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
|
|
287
382
|
expect(retrievedCheckpointProposal).toBeDefined();
|
|
288
383
|
|
|
289
384
|
// No block proposal was extracted (it had none anyway)
|
|
290
|
-
const retrievedBlockProposal = await ap.
|
|
385
|
+
const retrievedBlockProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
|
|
291
386
|
expect(retrievedBlockProposal).toBeUndefined();
|
|
292
387
|
});
|
|
293
388
|
|
|
294
389
|
it('should return undefined for non-existent checkpoint proposal', async () => {
|
|
295
|
-
const
|
|
296
|
-
const retrievedProposal = await ap.getCheckpointProposal(nonExistentId);
|
|
390
|
+
const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(99999));
|
|
297
391
|
expect(retrievedProposal).toBeUndefined();
|
|
298
392
|
});
|
|
299
393
|
|
|
300
|
-
it('should return alreadyExists when adding
|
|
394
|
+
it('should return alreadyExists when re-adding the same signed payload', async () => {
|
|
301
395
|
const slotNumber = 420;
|
|
302
396
|
const archive = Fr.random();
|
|
303
|
-
const
|
|
304
|
-
const proposalId = proposal1.archive.toString();
|
|
397
|
+
const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
|
|
305
398
|
|
|
306
|
-
const result1 = await ap.tryAddCheckpointProposal(
|
|
399
|
+
const result1 = await ap.tryAddCheckpointProposal(proposal);
|
|
307
400
|
expect(result1.added).toBe(true);
|
|
308
401
|
expect(result1.alreadyExists).toBe(false);
|
|
309
402
|
|
|
310
|
-
//
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
403
|
+
// Re-broadcasting the exact same signed payload yields alreadyExists.
|
|
404
|
+
const result2 = await ap.tryAddCheckpointProposal(proposal);
|
|
314
405
|
expect(result2.added).toBe(false);
|
|
315
406
|
expect(result2.alreadyExists).toBe(true);
|
|
316
407
|
|
|
317
|
-
// Should still have the first proposal
|
|
318
|
-
const retrievedProposal = await ap.getCheckpointProposal(
|
|
408
|
+
// Should still have the first proposal stored at the slot
|
|
409
|
+
const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
|
|
319
410
|
expect(retrievedProposal).toBeDefined();
|
|
320
|
-
expect(retrievedProposal!.toBuffer()).toEqual(
|
|
411
|
+
expect(retrievedProposal!.toBuffer()).toEqual(proposal.toBuffer());
|
|
321
412
|
expect(retrievedProposal!.getSender()?.toString()).toBe(signers[0].address.toString());
|
|
322
413
|
});
|
|
323
414
|
|
|
415
|
+
it('should treat distinct payloads at the same slot as equivocations (count = 2)', async () => {
|
|
416
|
+
const slotNumber = 420;
|
|
417
|
+
// Two proposals at the same slot but with different headers (distinct payloads).
|
|
418
|
+
const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, Fr.random());
|
|
419
|
+
const proposal2 = await mockCheckpointProposalForPool(signers[0], slotNumber, Fr.random());
|
|
420
|
+
|
|
421
|
+
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
422
|
+
expect(result1.added).toBe(true);
|
|
423
|
+
expect(result1.count).toBe(1);
|
|
424
|
+
|
|
425
|
+
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
426
|
+
// The second distinct payload is tracked as an equivocation, count goes to 2,
|
|
427
|
+
// and both accepted payloads are retained by payload hash.
|
|
428
|
+
expect(result2.added).toBe(true);
|
|
429
|
+
expect(result2.alreadyExists).toBe(false);
|
|
430
|
+
expect(result2.count).toBe(2);
|
|
431
|
+
|
|
432
|
+
const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
|
|
433
|
+
const expectedProposal = [proposal1, proposal2].sort((a, b) =>
|
|
434
|
+
a.getPayloadHash().localeCompare(b.getPayloadHash()),
|
|
435
|
+
)[0];
|
|
436
|
+
expect(retrievedProposal!.toBuffer()).toEqual(expectedProposal.toBuffer());
|
|
437
|
+
|
|
438
|
+
const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
|
|
439
|
+
expect(proposals.checkpointProposals.map(proposal => proposal.toBuffer())).toEqual(
|
|
440
|
+
expect.arrayContaining([proposal1.toBuffer(), proposal2.toBuffer()]),
|
|
441
|
+
);
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it('should detect equivocation when only feeAssetPriceModifier differs', async () => {
|
|
445
|
+
const slotNumber = 420;
|
|
446
|
+
const archive = Fr.random();
|
|
447
|
+
// Same checkpoint header + archive, but two different feeAssetPriceModifier values.
|
|
448
|
+
// This is the audit-finding scenario: archive collides but the signed payload differs.
|
|
449
|
+
const sharedHeader = makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
|
|
450
|
+
const proposalA = await makeCheckpointProposal({
|
|
451
|
+
signer: signers[0],
|
|
452
|
+
checkpointHeader: sharedHeader,
|
|
453
|
+
archiveRoot: archive,
|
|
454
|
+
feeAssetPriceModifier: 50n,
|
|
455
|
+
});
|
|
456
|
+
const proposalB = await makeCheckpointProposal({
|
|
457
|
+
signer: signers[0],
|
|
458
|
+
checkpointHeader: sharedHeader,
|
|
459
|
+
archiveRoot: archive,
|
|
460
|
+
feeAssetPriceModifier: -50n,
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
const result1 = await ap.tryAddCheckpointProposal(proposalA.toCore());
|
|
464
|
+
expect(result1.count).toBe(1);
|
|
465
|
+
|
|
466
|
+
const result2 = await ap.tryAddCheckpointProposal(proposalB.toCore());
|
|
467
|
+
// The fix: archive collision no longer hides the equivocation; payload-hash dedup
|
|
468
|
+
// sees the distinct feeMod and bumps `count` to 2 so libp2p can fire the slash callback.
|
|
469
|
+
expect(result2.added).toBe(true);
|
|
470
|
+
expect(result2.alreadyExists).toBe(false);
|
|
471
|
+
expect(result2.count).toBe(2);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
it('should delete retained proposals older than a given slot', async () => {
|
|
475
|
+
const oldSlot = 100;
|
|
476
|
+
const newSlot = 200;
|
|
477
|
+
const oldBlock = await mockBlockProposalForPool(signers[0], oldSlot);
|
|
478
|
+
const newBlock = await mockBlockProposalForPool(signers[1], newSlot);
|
|
479
|
+
const oldCheckpoint = await mockCheckpointProposalForPool(signers[0], oldSlot);
|
|
480
|
+
const newCheckpoint = await mockCheckpointProposalForPool(signers[1], newSlot);
|
|
481
|
+
|
|
482
|
+
await ap.tryAddBlockProposal(oldBlock);
|
|
483
|
+
await ap.tryAddBlockProposal(newBlock);
|
|
484
|
+
await ap.tryAddCheckpointProposal(oldCheckpoint);
|
|
485
|
+
await ap.tryAddCheckpointProposal(newCheckpoint);
|
|
486
|
+
|
|
487
|
+
await ap.deleteOlderThan(SlotNumber(newSlot));
|
|
488
|
+
|
|
489
|
+
expect(await ap.getProposalsForSlot(SlotNumber(oldSlot))).toEqual({
|
|
490
|
+
blockProposals: [],
|
|
491
|
+
checkpointProposals: [],
|
|
492
|
+
});
|
|
493
|
+
const newProposals = await ap.getProposalsForSlot(SlotNumber(newSlot));
|
|
494
|
+
expect(newProposals.blockProposals.map(proposal => proposal.toBuffer())).toContainEqual(
|
|
495
|
+
newBlock.withoutSignedTxs().toBuffer(),
|
|
496
|
+
);
|
|
497
|
+
expect(newProposals.checkpointProposals.map(proposal => proposal.toBuffer())).toContainEqual(
|
|
498
|
+
newCheckpoint.toBuffer(),
|
|
499
|
+
);
|
|
500
|
+
});
|
|
501
|
+
|
|
324
502
|
it('should return added=false when exceeding capacity', async () => {
|
|
325
503
|
const slotNumber = 420;
|
|
326
504
|
|
|
327
|
-
// Add
|
|
328
|
-
for (let i = 0; i <
|
|
505
|
+
// Add MAX_CHECKPOINT_PROPOSALS_PER_SLOT distinct proposals.
|
|
506
|
+
for (let i = 0; i < MAX_CHECKPOINT_PROPOSALS_PER_SLOT; i++) {
|
|
329
507
|
const proposal = await mockCheckpointProposalForPool(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber);
|
|
330
508
|
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
331
509
|
expect(result.added).toBe(true);
|
|
332
|
-
expect(result.
|
|
510
|
+
expect(result.count).toBe(i + 1);
|
|
333
511
|
}
|
|
334
512
|
|
|
335
|
-
// The next proposal should not be added
|
|
513
|
+
// The next proposal should not be added.
|
|
336
514
|
const extraProposal = await mockCheckpointProposalForPool(signers[0], slotNumber);
|
|
337
515
|
const result = await ap.tryAddCheckpointProposal(extraProposal);
|
|
338
516
|
expect(result.added).toBe(false);
|
|
339
517
|
expect(result.alreadyExists).toBe(false);
|
|
340
|
-
expect(result.
|
|
518
|
+
expect(result.count).toBe(MAX_CHECKPOINT_PROPOSALS_PER_SLOT);
|
|
341
519
|
});
|
|
342
520
|
});
|
|
343
521
|
|
|
@@ -358,13 +536,13 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
358
536
|
};
|
|
359
537
|
|
|
360
538
|
describe('tryAddBlockProposal duplicate detection', () => {
|
|
361
|
-
it('should return
|
|
539
|
+
it('should return count=1 when pool is empty', async () => {
|
|
362
540
|
const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
|
|
363
541
|
const result = await ap.tryAddBlockProposal(proposal);
|
|
364
542
|
|
|
365
543
|
expect(result.added).toBe(true);
|
|
366
544
|
expect(result.alreadyExists).toBe(false);
|
|
367
|
-
expect(result.
|
|
545
|
+
expect(result.count).toBe(1);
|
|
368
546
|
});
|
|
369
547
|
|
|
370
548
|
it('should return alreadyExists when same proposal exists', async () => {
|
|
@@ -375,17 +553,17 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
375
553
|
|
|
376
554
|
expect(result.added).toBe(false);
|
|
377
555
|
expect(result.alreadyExists).toBe(true);
|
|
378
|
-
expect(result.
|
|
556
|
+
expect(result.count).toBe(1);
|
|
379
557
|
});
|
|
380
558
|
|
|
381
|
-
it('should detect duplicate via
|
|
559
|
+
it('should detect duplicate via count when different proposal exists at same position', async () => {
|
|
382
560
|
const slotNumber = 100;
|
|
383
561
|
const indexWithinCheckpoint = 2;
|
|
384
562
|
|
|
385
563
|
// Add first proposal
|
|
386
564
|
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
387
565
|
const result1 = await ap.tryAddBlockProposal(proposal1);
|
|
388
|
-
expect(result1.
|
|
566
|
+
expect(result1.count).toBe(1);
|
|
389
567
|
|
|
390
568
|
// Add a different proposal at same position - this is a duplicate (equivocation)
|
|
391
569
|
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
|
|
@@ -393,8 +571,8 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
393
571
|
|
|
394
572
|
expect(result2.added).toBe(true);
|
|
395
573
|
expect(result2.alreadyExists).toBe(false);
|
|
396
|
-
//
|
|
397
|
-
expect(result2.
|
|
574
|
+
// count >= 2 indicates duplicate detection
|
|
575
|
+
expect(result2.count).toBe(2);
|
|
398
576
|
});
|
|
399
577
|
|
|
400
578
|
it('should not detect duplicate for different positions in same slot', async () => {
|
|
@@ -409,8 +587,8 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
409
587
|
const result = await ap.tryAddBlockProposal(proposal2);
|
|
410
588
|
|
|
411
589
|
expect(result.added).toBe(true);
|
|
412
|
-
//
|
|
413
|
-
expect(result.
|
|
590
|
+
// count = 1 means no duplicate for this position
|
|
591
|
+
expect(result.count).toBe(1);
|
|
414
592
|
});
|
|
415
593
|
|
|
416
594
|
it('should not detect duplicate for same position in different slots', async () => {
|
|
@@ -425,37 +603,37 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
425
603
|
const result = await ap.tryAddBlockProposal(proposal2);
|
|
426
604
|
|
|
427
605
|
expect(result.added).toBe(true);
|
|
428
|
-
//
|
|
429
|
-
expect(result.
|
|
606
|
+
// count = 1 means no duplicate for this position
|
|
607
|
+
expect(result.count).toBe(1);
|
|
430
608
|
});
|
|
431
609
|
|
|
432
|
-
it('should track multiple duplicates correctly via
|
|
610
|
+
it('should track multiple duplicates correctly via count', async () => {
|
|
433
611
|
const slotNumber = 100;
|
|
434
612
|
const indexWithinCheckpoint = 0;
|
|
435
613
|
|
|
436
614
|
// Add multiple proposals for same position
|
|
437
615
|
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
438
616
|
const result1 = await ap.tryAddBlockProposal(proposal1);
|
|
439
|
-
expect(result1.
|
|
617
|
+
expect(result1.count).toBe(1);
|
|
440
618
|
|
|
441
619
|
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
|
|
442
620
|
const result2 = await ap.tryAddBlockProposal(proposal2);
|
|
443
|
-
expect(result2.
|
|
621
|
+
expect(result2.count).toBe(2);
|
|
444
622
|
|
|
445
|
-
//
|
|
623
|
+
// Third proposal for same position should be rejected (cap is 2)
|
|
446
624
|
const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
|
|
447
625
|
const result3 = await ap.tryAddBlockProposal(proposal3);
|
|
448
626
|
|
|
449
|
-
expect(result3.added).toBe(
|
|
450
|
-
expect(result3.
|
|
627
|
+
expect(result3.added).toBe(false);
|
|
628
|
+
expect(result3.count).toBe(2);
|
|
451
629
|
});
|
|
452
630
|
|
|
453
631
|
it('should return added=false when exceeding capacity', async () => {
|
|
454
632
|
const slotNumber = 100;
|
|
455
633
|
const indexWithinCheckpoint = 0;
|
|
456
634
|
|
|
457
|
-
// Add
|
|
458
|
-
for (let i = 0; i <
|
|
635
|
+
// Add MAX_BLOCK_PROPOSALS_PER_POSITION proposals
|
|
636
|
+
for (let i = 0; i < MAX_BLOCK_PROPOSALS_PER_POSITION; i++) {
|
|
459
637
|
const proposal = await mockBlockProposalWithIndex(
|
|
460
638
|
signers[i % NUMBER_OF_SIGNERS_PER_TEST],
|
|
461
639
|
slotNumber,
|
|
@@ -463,7 +641,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
463
641
|
);
|
|
464
642
|
const result = await ap.tryAddBlockProposal(proposal);
|
|
465
643
|
expect(result.added).toBe(true);
|
|
466
|
-
expect(result.
|
|
644
|
+
expect(result.count).toBe(i + 1);
|
|
467
645
|
}
|
|
468
646
|
|
|
469
647
|
// The next proposal should not be added
|
|
@@ -471,7 +649,7 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
471
649
|
const result = await ap.tryAddBlockProposal(extraProposal);
|
|
472
650
|
expect(result.added).toBe(false);
|
|
473
651
|
expect(result.alreadyExists).toBe(false);
|
|
474
|
-
expect(result.
|
|
652
|
+
expect(result.count).toBe(MAX_BLOCK_PROPOSALS_PER_POSITION);
|
|
475
653
|
});
|
|
476
654
|
|
|
477
655
|
it('should clean up block position index when deleting old data', async () => {
|
|
@@ -482,18 +660,18 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
482
660
|
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
483
661
|
await ap.tryAddBlockProposal(proposal1);
|
|
484
662
|
|
|
485
|
-
// Verify it's tracked (adding another should show
|
|
663
|
+
// Verify it's tracked (adding another should show count = 2)
|
|
486
664
|
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
|
|
487
665
|
let result = await ap.tryAddBlockProposal(proposal2);
|
|
488
|
-
expect(result.
|
|
666
|
+
expect(result.count).toBe(2);
|
|
489
667
|
|
|
490
668
|
// Delete old data
|
|
491
669
|
await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
|
|
492
670
|
|
|
493
|
-
// Verify position index is cleaned up (
|
|
671
|
+
// Verify position index is cleaned up (count should be 1 now)
|
|
494
672
|
const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
|
|
495
673
|
result = await ap.tryAddBlockProposal(proposal3);
|
|
496
|
-
expect(result.
|
|
674
|
+
expect(result.count).toBe(1);
|
|
497
675
|
});
|
|
498
676
|
|
|
499
677
|
it('should correctly delete block proposals at slot boundary', async () => {
|
|
@@ -514,16 +692,16 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
514
692
|
// Slot 99 proposals should have their index cleaned up
|
|
515
693
|
const newProposal99 = await mockBlockProposalWithIndex(signers[0], 99, 0);
|
|
516
694
|
const result99 = await ap.tryAddBlockProposal(newProposal99);
|
|
517
|
-
expect(result99.
|
|
695
|
+
expect(result99.count).toBe(1); // Index was cleaned up
|
|
518
696
|
|
|
519
697
|
// Slot 100 and 101 should still be tracked
|
|
520
698
|
const newProposal100 = await mockBlockProposalWithIndex(signers[1], 100, 0);
|
|
521
699
|
const result100 = await ap.tryAddBlockProposal(newProposal100);
|
|
522
|
-
expect(result100.
|
|
700
|
+
expect(result100.count).toBe(2); // Still has the original
|
|
523
701
|
|
|
524
702
|
const newProposal101 = await mockBlockProposalWithIndex(signers[2], 101, 0);
|
|
525
703
|
const result101 = await ap.tryAddBlockProposal(newProposal101);
|
|
526
|
-
expect(result101.
|
|
704
|
+
expect(result101.count).toBe(2); // Still has the original
|
|
527
705
|
});
|
|
528
706
|
|
|
529
707
|
it('should delete all indices for a given slot', async () => {
|
|
@@ -544,15 +722,15 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
544
722
|
// All indices should be cleaned up
|
|
545
723
|
const newProposal0 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
|
|
546
724
|
const result0 = await ap.tryAddBlockProposal(newProposal0);
|
|
547
|
-
expect(result0.
|
|
725
|
+
expect(result0.count).toBe(1);
|
|
548
726
|
|
|
549
727
|
const newProposal1 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
|
|
550
728
|
const result1 = await ap.tryAddBlockProposal(newProposal1);
|
|
551
|
-
expect(result1.
|
|
729
|
+
expect(result1.count).toBe(1);
|
|
552
730
|
|
|
553
731
|
const newProposal2 = await mockBlockProposalWithIndex(signers[2], slotNumber, 2);
|
|
554
732
|
const result2 = await ap.tryAddBlockProposal(newProposal2);
|
|
555
|
-
expect(result2.
|
|
733
|
+
expect(result2.count).toBe(1);
|
|
556
734
|
});
|
|
557
735
|
|
|
558
736
|
it('should delete block proposals from storage when deleting old data', async () => {
|
|
@@ -567,17 +745,17 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
567
745
|
await ap.tryAddBlockProposal(newProposal);
|
|
568
746
|
|
|
569
747
|
// Verify both proposals exist
|
|
570
|
-
expect(await ap.
|
|
571
|
-
expect(await ap.
|
|
748
|
+
expect(await ap.getBlockProposalByArchive(oldProposal.archive.toString())).toBeDefined();
|
|
749
|
+
expect(await ap.getBlockProposalByArchive(newProposal.archive.toString())).toBeDefined();
|
|
572
750
|
|
|
573
751
|
// Delete slots older than newSlot (should delete oldSlot)
|
|
574
752
|
await ap.deleteOlderThan(SlotNumber(newSlot));
|
|
575
753
|
|
|
576
754
|
// Old proposal should be deleted from storage
|
|
577
|
-
expect(await ap.
|
|
755
|
+
expect(await ap.getBlockProposalByArchive(oldProposal.archive.toString())).toBeUndefined();
|
|
578
756
|
|
|
579
757
|
// New proposal should still exist
|
|
580
|
-
expect(await ap.
|
|
758
|
+
expect(await ap.getBlockProposalByArchive(newProposal.archive.toString())).toBeDefined();
|
|
581
759
|
});
|
|
582
760
|
});
|
|
583
761
|
|
|
@@ -586,25 +764,26 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
586
764
|
signer: Secp256k1Signer,
|
|
587
765
|
slotNumber: number,
|
|
588
766
|
archive: Fr = Fr.random(),
|
|
767
|
+
checkpointHeader?: CheckpointHeader,
|
|
589
768
|
): Promise<CheckpointProposalCore> => {
|
|
590
|
-
const
|
|
769
|
+
const headerToUse = checkpointHeader ?? makeCheckpointHeader(1, { slotNumber: SlotNumber(slotNumber) });
|
|
591
770
|
const blockHeader = makeBlockHeader(1);
|
|
592
771
|
const proposal = await makeCheckpointProposal({
|
|
593
772
|
signer,
|
|
594
|
-
checkpointHeader,
|
|
773
|
+
checkpointHeader: headerToUse,
|
|
595
774
|
archiveRoot: archive,
|
|
596
775
|
lastBlock: { blockHeader },
|
|
597
776
|
});
|
|
598
777
|
return proposal.toCore();
|
|
599
778
|
};
|
|
600
779
|
|
|
601
|
-
it('should return
|
|
780
|
+
it('should return count=1 when pool is empty', async () => {
|
|
602
781
|
const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
|
|
603
782
|
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
604
783
|
|
|
605
784
|
expect(result.added).toBe(true);
|
|
606
785
|
expect(result.alreadyExists).toBe(false);
|
|
607
|
-
expect(result.
|
|
786
|
+
expect(result.count).toBe(1);
|
|
608
787
|
});
|
|
609
788
|
|
|
610
789
|
it('should return alreadyExists when same proposal exists', async () => {
|
|
@@ -615,16 +794,16 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
615
794
|
|
|
616
795
|
expect(result.added).toBe(false);
|
|
617
796
|
expect(result.alreadyExists).toBe(true);
|
|
618
|
-
expect(result.
|
|
797
|
+
expect(result.count).toBe(1);
|
|
619
798
|
});
|
|
620
799
|
|
|
621
|
-
it('should detect duplicate via
|
|
800
|
+
it('should detect duplicate via count when different proposal exists for same slot', async () => {
|
|
622
801
|
const slotNumber = 100;
|
|
623
802
|
|
|
624
803
|
// Add first proposal
|
|
625
804
|
const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
|
|
626
805
|
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
627
|
-
expect(result1.
|
|
806
|
+
expect(result1.count).toBe(1);
|
|
628
807
|
|
|
629
808
|
// Add a different proposal for same slot - this is a duplicate (equivocation)
|
|
630
809
|
const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
|
|
@@ -632,8 +811,8 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
632
811
|
|
|
633
812
|
expect(result2.added).toBe(true);
|
|
634
813
|
expect(result2.alreadyExists).toBe(false);
|
|
635
|
-
//
|
|
636
|
-
expect(result2.
|
|
814
|
+
// count >= 2 indicates duplicate detection
|
|
815
|
+
expect(result2.count).toBe(2);
|
|
637
816
|
});
|
|
638
817
|
|
|
639
818
|
it('should not detect duplicate for different slots', async () => {
|
|
@@ -646,28 +825,28 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
646
825
|
const result = await ap.tryAddCheckpointProposal(proposal2);
|
|
647
826
|
|
|
648
827
|
expect(result.added).toBe(true);
|
|
649
|
-
//
|
|
650
|
-
expect(result.
|
|
828
|
+
// count = 1 means no duplicate for this slot
|
|
829
|
+
expect(result.count).toBe(1);
|
|
651
830
|
});
|
|
652
831
|
|
|
653
|
-
it('should track multiple duplicates correctly via
|
|
832
|
+
it('should track multiple duplicates correctly via count', async () => {
|
|
654
833
|
const slotNumber = 100;
|
|
655
834
|
|
|
656
835
|
// Add multiple proposals for same slot
|
|
657
836
|
const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
|
|
658
837
|
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
659
|
-
expect(result1.
|
|
838
|
+
expect(result1.count).toBe(1);
|
|
660
839
|
|
|
661
840
|
const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
|
|
662
841
|
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
663
|
-
expect(result2.
|
|
842
|
+
expect(result2.count).toBe(2);
|
|
664
843
|
|
|
665
|
-
//
|
|
844
|
+
// Third proposal for same slot should be rejected (cap is 2)
|
|
666
845
|
const proposal3 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber);
|
|
667
846
|
const result3 = await ap.tryAddCheckpointProposal(proposal3);
|
|
668
847
|
|
|
669
|
-
expect(result3.added).toBe(
|
|
670
|
-
expect(result3.
|
|
848
|
+
expect(result3.added).toBe(false);
|
|
849
|
+
expect(result3.count).toBe(2);
|
|
671
850
|
});
|
|
672
851
|
|
|
673
852
|
it('should not count attestations as proposals for duplicate detection', async () => {
|
|
@@ -684,8 +863,8 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
684
863
|
|
|
685
864
|
expect(result.added).toBe(true);
|
|
686
865
|
expect(result.alreadyExists).toBe(false);
|
|
687
|
-
//
|
|
688
|
-
expect(result.
|
|
866
|
+
// count should be 1, NOT 2 - attestations should not count as proposals
|
|
867
|
+
expect(result.count).toBe(1);
|
|
689
868
|
});
|
|
690
869
|
|
|
691
870
|
it('should not count attestations for different proposals as duplicates', async () => {
|
|
@@ -703,14 +882,14 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
|
|
|
703
882
|
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
704
883
|
|
|
705
884
|
expect(result1.added).toBe(true);
|
|
706
|
-
expect(result1.
|
|
885
|
+
expect(result1.count).toBe(1);
|
|
707
886
|
|
|
708
887
|
// Add the second checkpoint proposal - this IS a duplicate (different archive, same slot)
|
|
709
888
|
const proposal2 = await mockCheckpointProposalCoreForPool(signers[3], slotNumber, archive2);
|
|
710
889
|
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
711
890
|
|
|
712
891
|
expect(result2.added).toBe(true);
|
|
713
|
-
expect(result2.
|
|
892
|
+
expect(result2.count).toBe(2);
|
|
714
893
|
});
|
|
715
894
|
});
|
|
716
895
|
});
|