@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,9 +1,11 @@
|
|
|
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 { Signature } from '@aztec/foundation/eth-signature';
|
|
5
|
+
import { CheckpointAttestation } from '@aztec/stdlib/p2p';
|
|
4
6
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
5
7
|
import { makeBlockHeader, makeBlockProposal, makeCheckpointHeader, makeCheckpointProposal } from '@aztec/stdlib/testing';
|
|
6
|
-
import {
|
|
8
|
+
import { MAX_BLOCK_PROPOSALS_PER_POSITION, MAX_CHECKPOINT_PROPOSALS_PER_SLOT } from './attestation_pool.js';
|
|
7
9
|
import { mockCheckpointAttestation } from './mocks.js';
|
|
8
10
|
const NUMBER_OF_SIGNERS_PER_TEST = 4;
|
|
9
11
|
export function describeAttestationPool(getAttestationPool) {
|
|
@@ -15,9 +17,17 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
15
17
|
length: NUMBER_OF_SIGNERS_PER_TEST
|
|
16
18
|
}, ()=>Secp256k1Signer.random());
|
|
17
19
|
});
|
|
18
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Build attestations from each signer over the *same* signed payload (same header,
|
|
22
|
+
* archive, feeAssetPriceModifier). Required by the new pool, which deduplicates by
|
|
23
|
+
* payload hash and treats attestations from different signers as distinct entries
|
|
24
|
+
* only when the payload itself matches.
|
|
25
|
+
*/ const createCheckpointAttestationsForSlot = (slotNumber, archive)=>{
|
|
19
26
|
const archiveToUse = archive ?? Fr.random();
|
|
20
|
-
|
|
27
|
+
const sharedHeader = CheckpointHeader.random({
|
|
28
|
+
slotNumber: SlotNumber(slotNumber)
|
|
29
|
+
});
|
|
30
|
+
return signers.map((signer)=>mockCheckpointAttestation(signer, slotNumber, archiveToUse, sharedHeader));
|
|
21
31
|
};
|
|
22
32
|
const mockBlockProposalForPool = (signer, slotNumber, archive = Fr.random())=>{
|
|
23
33
|
const header = makeBlockHeader(1, {
|
|
@@ -37,24 +47,69 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
37
47
|
expect(a1Buffer.length).toBe(a2Buffer.length);
|
|
38
48
|
expect(a1Buffer).toEqual(expect.arrayContaining(a2Buffer));
|
|
39
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Rewrites the attester signature into yParity form (27 -> 0, 28 -> 1), keeping (r, s). The recovery
|
|
52
|
+
* bit is unchanged so it still recovers to the same signer, mimicking a peer that gossips (or mutates
|
|
53
|
+
* in flight) a signature with a non-canonical recovery byte.
|
|
54
|
+
*/ const toYParityForm = (attestation)=>{
|
|
55
|
+
const sig = attestation.signature;
|
|
56
|
+
const yParityV = sig.v === 27 ? 0 : sig.v === 28 ? 1 : sig.v;
|
|
57
|
+
return new CheckpointAttestation(attestation.payload, new Signature(sig.r, sig.s, yParityV), attestation.proposerSignature);
|
|
58
|
+
};
|
|
40
59
|
describe('CheckpointAttestation', ()=>{
|
|
60
|
+
it('normalizes yParity (v=0/v=1) attester signatures on ingress from both gossip and own keys', async ()=>{
|
|
61
|
+
const slotNumber = 421;
|
|
62
|
+
const canonical = createCheckpointAttestationsForSlot(slotNumber);
|
|
63
|
+
const payloadHash = canonical[0].getPayloadHash();
|
|
64
|
+
const expectedSenders = new Set([
|
|
65
|
+
canonical[0].getSender().toString(),
|
|
66
|
+
canonical[1].getSender().toString()
|
|
67
|
+
]);
|
|
68
|
+
const gossiped = toYParityForm(canonical[0]);
|
|
69
|
+
expect([
|
|
70
|
+
0,
|
|
71
|
+
1
|
|
72
|
+
]).toContain(gossiped.signature.v);
|
|
73
|
+
await ap.tryAddCheckpointAttestation(gossiped);
|
|
74
|
+
const own = toYParityForm(canonical[1]);
|
|
75
|
+
expect([
|
|
76
|
+
0,
|
|
77
|
+
1
|
|
78
|
+
]).toContain(own.signature.v);
|
|
79
|
+
await ap.addOwnCheckpointAttestations([
|
|
80
|
+
own
|
|
81
|
+
]);
|
|
82
|
+
const retrieved = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
|
|
83
|
+
expect(retrieved.length).toBe(2);
|
|
84
|
+
for (const attestation of retrieved){
|
|
85
|
+
expect([
|
|
86
|
+
27,
|
|
87
|
+
28
|
|
88
|
+
]).toContain(attestation.signature.v);
|
|
89
|
+
expect(expectedSenders.has(attestation.getSender().toString())).toBe(true);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
41
92
|
it('should add attestations to pool', async ()=>{
|
|
42
93
|
const slotNumber = 420;
|
|
43
94
|
const archive = Fr.random();
|
|
44
|
-
const
|
|
95
|
+
const sharedHeader = CheckpointHeader.random({
|
|
96
|
+
slotNumber: SlotNumber(slotNumber)
|
|
97
|
+
});
|
|
98
|
+
const attestations = signers.slice(0, -1).map((signer)=>mockCheckpointAttestation(signer, slotNumber, archive, sharedHeader));
|
|
99
|
+
const payloadHash = attestations[0].getPayloadHash();
|
|
45
100
|
await ap.addOwnCheckpointAttestations(attestations);
|
|
46
|
-
const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber),
|
|
101
|
+
const retrievedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
|
|
47
102
|
expect(retrievedAttestations.length).toBe(attestations.length);
|
|
48
103
|
compareCheckpointAttestations(retrievedAttestations, attestations);
|
|
49
104
|
const retrievedAttestationsForSlot = await ap.getCheckpointAttestationsForSlot(SlotNumber(slotNumber));
|
|
50
105
|
expect(retrievedAttestationsForSlot.length).toBe(attestations.length);
|
|
51
106
|
compareCheckpointAttestations(retrievedAttestationsForSlot, attestations);
|
|
52
107
|
// Add another one
|
|
53
|
-
const newAttestation = mockCheckpointAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive);
|
|
108
|
+
const newAttestation = mockCheckpointAttestation(signers[NUMBER_OF_SIGNERS_PER_TEST - 1], slotNumber, archive, sharedHeader);
|
|
54
109
|
await ap.addOwnCheckpointAttestations([
|
|
55
110
|
newAttestation
|
|
56
111
|
]);
|
|
57
|
-
const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber),
|
|
112
|
+
const retrievedAttestationsAfterAdd = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
|
|
58
113
|
expect(retrievedAttestationsAfterAdd.length).toBe(attestations.length + 1);
|
|
59
114
|
compareCheckpointAttestations(retrievedAttestationsAfterAdd, [
|
|
60
115
|
...attestations,
|
|
@@ -68,7 +123,7 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
68
123
|
]);
|
|
69
124
|
// Delete by slot
|
|
70
125
|
await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
|
|
71
|
-
const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber),
|
|
126
|
+
const retreivedAttestationsAfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
|
|
72
127
|
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
73
128
|
});
|
|
74
129
|
it('should handle duplicate proposals in a slot', async ()=>{
|
|
@@ -83,9 +138,10 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
83
138
|
for(let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++){
|
|
84
139
|
attestations.push(mockCheckpointAttestation(signer, slotNumber, archive, header));
|
|
85
140
|
}
|
|
141
|
+
const payloadHash = attestations[0].getPayloadHash();
|
|
86
142
|
// Add them to store and check we end up with only one
|
|
87
143
|
await ap.addOwnCheckpointAttestations(attestations);
|
|
88
|
-
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber),
|
|
144
|
+
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash);
|
|
89
145
|
expect(retreivedAttestations.length).toBe(1);
|
|
90
146
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
|
|
91
147
|
expect(retreivedAttestations[0].getSender()?.toString()).toEqual(signer.address.toString());
|
|
@@ -93,7 +149,7 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
93
149
|
await ap.addOwnCheckpointAttestations([
|
|
94
150
|
attestations[0]
|
|
95
151
|
]);
|
|
96
|
-
expect(await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber),
|
|
152
|
+
expect(await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(slotNumber), payloadHash)).toHaveLength(1);
|
|
97
153
|
});
|
|
98
154
|
it('should store attestations by differing slot', async ()=>{
|
|
99
155
|
const slotNumbers = [
|
|
@@ -106,8 +162,8 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
106
162
|
await ap.addOwnCheckpointAttestations(attestations);
|
|
107
163
|
for (const attestation of attestations){
|
|
108
164
|
const slot = attestation.payload.header.slotNumber;
|
|
109
|
-
const
|
|
110
|
-
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot,
|
|
165
|
+
const payloadHash = attestation.getPayloadHash();
|
|
166
|
+
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, payloadHash);
|
|
111
167
|
expect(retreivedAttestations.length).toBe(1);
|
|
112
168
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
113
169
|
expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
|
|
@@ -130,8 +186,8 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
130
186
|
await ap.addOwnCheckpointAttestations(attestations);
|
|
131
187
|
for (const attestation of attestations){
|
|
132
188
|
const slot = attestation.payload.header.slotNumber;
|
|
133
|
-
const
|
|
134
|
-
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot,
|
|
189
|
+
const payloadHash = attestation.getPayloadHash();
|
|
190
|
+
const retreivedAttestations = await ap.getCheckpointAttestationsForSlotAndProposal(slot, payloadHash);
|
|
135
191
|
expect(retreivedAttestations.length).toBe(1);
|
|
136
192
|
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
137
193
|
expect(retreivedAttestations[0].payload.header.slotNumber).toEqual(slot);
|
|
@@ -148,13 +204,14 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
148
204
|
88,
|
|
149
205
|
420
|
|
150
206
|
];
|
|
151
|
-
const
|
|
152
|
-
const
|
|
207
|
+
const attestationsPerSlot = await Promise.all(slotNumbers.map((slotNumber)=>createCheckpointAttestationsForSlot(slotNumber)));
|
|
208
|
+
const attestations = attestationsPerSlot.flat();
|
|
209
|
+
const payloadHashForSlot1 = attestationsPerSlot[0][0].getPayloadHash();
|
|
153
210
|
await ap.addOwnCheckpointAttestations(attestations);
|
|
154
|
-
const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1),
|
|
211
|
+
const attestationsForSlot1 = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), payloadHashForSlot1);
|
|
155
212
|
expect(attestationsForSlot1.length).toBe(signers.length);
|
|
156
213
|
await ap.deleteOlderThan(SlotNumber(73));
|
|
157
|
-
const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1),
|
|
214
|
+
const attestationsForSlot1AfterDelete = await ap.getCheckpointAttestationsForSlotAndProposal(SlotNumber(1), payloadHashForSlot1);
|
|
158
215
|
expect(attestationsForSlot1AfterDelete.length).toBe(0);
|
|
159
216
|
});
|
|
160
217
|
});
|
|
@@ -163,49 +220,81 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
163
220
|
const slotNumber = 420;
|
|
164
221
|
const archive = Fr.random();
|
|
165
222
|
const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
|
|
166
|
-
const proposalId = proposal.archive.toString();
|
|
167
223
|
const result = await ap.tryAddBlockProposal(proposal);
|
|
168
224
|
expect(result.added).toBe(true);
|
|
169
225
|
expect(result.alreadyExists).toBe(false);
|
|
170
|
-
expect(result.
|
|
171
|
-
const retrievedProposal = await ap.
|
|
226
|
+
expect(result.count).toBe(1);
|
|
227
|
+
const retrievedProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
|
|
172
228
|
expect(retrievedProposal).toBeDefined();
|
|
173
229
|
expect(retrievedProposal).toEqual(proposal);
|
|
174
230
|
});
|
|
175
231
|
it('should return undefined for non-existent block proposal', async ()=>{
|
|
176
232
|
const nonExistentId = Fr.random().toString();
|
|
177
|
-
const retrievedProposal = await ap.
|
|
233
|
+
const retrievedProposal = await ap.getBlockProposalByArchive(nonExistentId);
|
|
178
234
|
expect(retrievedProposal).toBeUndefined();
|
|
179
235
|
});
|
|
180
|
-
it('should return alreadyExists when adding
|
|
236
|
+
it('should return alreadyExists when re-adding the same signed payload', async ()=>{
|
|
181
237
|
const slotNumber = 420;
|
|
182
238
|
const archive = Fr.random();
|
|
183
|
-
const
|
|
184
|
-
const
|
|
185
|
-
const result1 = await ap.tryAddBlockProposal(proposal1);
|
|
239
|
+
const proposal = await mockBlockProposalForPool(signers[0], slotNumber, archive);
|
|
240
|
+
const result1 = await ap.tryAddBlockProposal(proposal);
|
|
186
241
|
expect(result1.added).toBe(true);
|
|
187
242
|
expect(result1.alreadyExists).toBe(false);
|
|
188
|
-
//
|
|
189
|
-
const
|
|
190
|
-
const result2 = await ap.tryAddBlockProposal(proposal2);
|
|
243
|
+
// Re-broadcasting the exact same proposal yields alreadyExists.
|
|
244
|
+
const result2 = await ap.tryAddBlockProposal(proposal);
|
|
191
245
|
expect(result2.added).toBe(false);
|
|
192
246
|
expect(result2.alreadyExists).toBe(true);
|
|
193
|
-
|
|
194
|
-
const retrievedProposal = await ap.getBlockProposal(proposalId);
|
|
247
|
+
const retrievedProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
|
|
195
248
|
expect(retrievedProposal).toBeDefined();
|
|
196
|
-
expect(retrievedProposal.toBuffer()).toEqual(
|
|
249
|
+
expect(retrievedProposal.toBuffer()).toEqual(proposal.toBuffer());
|
|
197
250
|
expect(retrievedProposal.getSender()?.toString()).toBe(signers[0].address.toString());
|
|
198
251
|
});
|
|
252
|
+
it('should retain an exact duplicate block proposal only once', async ()=>{
|
|
253
|
+
const slotNumber = 420;
|
|
254
|
+
const proposal = await mockBlockProposalForPool(signers[0], slotNumber);
|
|
255
|
+
await ap.tryAddBlockProposal(proposal);
|
|
256
|
+
await ap.tryAddBlockProposal(proposal);
|
|
257
|
+
const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
|
|
258
|
+
expect(proposals.blockProposals.map((proposal)=>proposal.toBuffer())).toEqual([
|
|
259
|
+
proposal.withoutSignedTxs().toBuffer()
|
|
260
|
+
]);
|
|
261
|
+
});
|
|
262
|
+
it('should retain all accepted block proposals at a position', async ()=>{
|
|
263
|
+
const slotNumber = 420;
|
|
264
|
+
const blockHeader = makeBlockHeader(1, {
|
|
265
|
+
slotNumber: SlotNumber(slotNumber)
|
|
266
|
+
});
|
|
267
|
+
const proposal1 = await makeBlockProposal({
|
|
268
|
+
signer: signers[0],
|
|
269
|
+
blockHeader,
|
|
270
|
+
archiveRoot: Fr.random(),
|
|
271
|
+
indexWithinCheckpoint: IndexWithinCheckpoint(1)
|
|
272
|
+
});
|
|
273
|
+
const proposal2 = await makeBlockProposal({
|
|
274
|
+
signer: signers[0],
|
|
275
|
+
blockHeader,
|
|
276
|
+
archiveRoot: Fr.random(),
|
|
277
|
+
indexWithinCheckpoint: IndexWithinCheckpoint(1)
|
|
278
|
+
});
|
|
279
|
+
await ap.tryAddBlockProposal(proposal1);
|
|
280
|
+
await ap.tryAddBlockProposal(proposal2);
|
|
281
|
+
const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
|
|
282
|
+
expect(proposals.blockProposals.map((proposal)=>proposal.toBuffer())).toEqual(expect.arrayContaining([
|
|
283
|
+
proposal1.withoutSignedTxs().toBuffer(),
|
|
284
|
+
proposal2.withoutSignedTxs().toBuffer()
|
|
285
|
+
]));
|
|
286
|
+
expect(await ap.getBlockProposalByArchive(proposal2.archive.toString())).toBeDefined();
|
|
287
|
+
});
|
|
199
288
|
});
|
|
200
289
|
describe('CheckpointProposal in attestation pool', ()=>{
|
|
201
|
-
const mockCheckpointProposalForPool = async (signer, slotNumber, archive = Fr.random())=>{
|
|
202
|
-
const
|
|
290
|
+
const mockCheckpointProposalForPool = async (signer, slotNumber, archive = Fr.random(), checkpointHeader)=>{
|
|
291
|
+
const headerToUse = checkpointHeader ?? makeCheckpointHeader(1, {
|
|
203
292
|
slotNumber: SlotNumber(slotNumber)
|
|
204
293
|
});
|
|
205
294
|
const blockHeader = makeBlockHeader(1);
|
|
206
295
|
const proposal = await makeCheckpointProposal({
|
|
207
296
|
signer,
|
|
208
|
-
checkpointHeader,
|
|
297
|
+
checkpointHeader: headerToUse,
|
|
209
298
|
archiveRoot: archive,
|
|
210
299
|
lastBlock: {
|
|
211
300
|
blockHeader
|
|
@@ -218,12 +307,11 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
218
307
|
const slotNumber = 420;
|
|
219
308
|
const archive = Fr.random();
|
|
220
309
|
const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
|
|
221
|
-
const proposalId = proposal.archive.toString();
|
|
222
310
|
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
223
311
|
expect(result.added).toBe(true);
|
|
224
312
|
expect(result.alreadyExists).toBe(false);
|
|
225
|
-
expect(result.
|
|
226
|
-
const retrievedProposal = await ap.getCheckpointProposal(
|
|
313
|
+
expect(result.count).toBe(1);
|
|
314
|
+
const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
|
|
227
315
|
expect(retrievedProposal).toBeDefined();
|
|
228
316
|
expect(retrievedProposal.toBuffer()).toEqual(proposal.toBuffer());
|
|
229
317
|
});
|
|
@@ -239,55 +327,126 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
239
327
|
checkpointHeader,
|
|
240
328
|
archiveRoot: archive
|
|
241
329
|
});
|
|
242
|
-
const proposalId = proposal.archive.toString();
|
|
243
330
|
// Add the checkpoint core - block extraction is now caller responsibility
|
|
244
331
|
await ap.tryAddCheckpointProposal(proposal.toCore());
|
|
245
332
|
// The checkpoint proposal should be stored
|
|
246
|
-
const retrievedCheckpointProposal = await ap.getCheckpointProposal(
|
|
333
|
+
const retrievedCheckpointProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
|
|
247
334
|
expect(retrievedCheckpointProposal).toBeDefined();
|
|
248
335
|
// No block proposal was extracted (it had none anyway)
|
|
249
|
-
const retrievedBlockProposal = await ap.
|
|
336
|
+
const retrievedBlockProposal = await ap.getBlockProposalByArchive(proposal.archive.toString());
|
|
250
337
|
expect(retrievedBlockProposal).toBeUndefined();
|
|
251
338
|
});
|
|
252
339
|
it('should return undefined for non-existent checkpoint proposal', async ()=>{
|
|
253
|
-
const
|
|
254
|
-
const retrievedProposal = await ap.getCheckpointProposal(nonExistentId);
|
|
340
|
+
const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(99999));
|
|
255
341
|
expect(retrievedProposal).toBeUndefined();
|
|
256
342
|
});
|
|
257
|
-
it('should return alreadyExists when adding
|
|
343
|
+
it('should return alreadyExists when re-adding the same signed payload', async ()=>{
|
|
258
344
|
const slotNumber = 420;
|
|
259
345
|
const archive = Fr.random();
|
|
260
|
-
const
|
|
261
|
-
const
|
|
262
|
-
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
346
|
+
const proposal = await mockCheckpointProposalForPool(signers[0], slotNumber, archive);
|
|
347
|
+
const result1 = await ap.tryAddCheckpointProposal(proposal);
|
|
263
348
|
expect(result1.added).toBe(true);
|
|
264
349
|
expect(result1.alreadyExists).toBe(false);
|
|
265
|
-
//
|
|
266
|
-
const
|
|
267
|
-
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
350
|
+
// Re-broadcasting the exact same signed payload yields alreadyExists.
|
|
351
|
+
const result2 = await ap.tryAddCheckpointProposal(proposal);
|
|
268
352
|
expect(result2.added).toBe(false);
|
|
269
353
|
expect(result2.alreadyExists).toBe(true);
|
|
270
|
-
// Should still have the first proposal
|
|
271
|
-
const retrievedProposal = await ap.getCheckpointProposal(
|
|
354
|
+
// Should still have the first proposal stored at the slot
|
|
355
|
+
const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
|
|
272
356
|
expect(retrievedProposal).toBeDefined();
|
|
273
|
-
expect(retrievedProposal.toBuffer()).toEqual(
|
|
357
|
+
expect(retrievedProposal.toBuffer()).toEqual(proposal.toBuffer());
|
|
274
358
|
expect(retrievedProposal.getSender()?.toString()).toBe(signers[0].address.toString());
|
|
275
359
|
});
|
|
360
|
+
it('should treat distinct payloads at the same slot as equivocations (count = 2)', async ()=>{
|
|
361
|
+
const slotNumber = 420;
|
|
362
|
+
// Two proposals at the same slot but with different headers (distinct payloads).
|
|
363
|
+
const proposal1 = await mockCheckpointProposalForPool(signers[0], slotNumber, Fr.random());
|
|
364
|
+
const proposal2 = await mockCheckpointProposalForPool(signers[0], slotNumber, Fr.random());
|
|
365
|
+
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
366
|
+
expect(result1.added).toBe(true);
|
|
367
|
+
expect(result1.count).toBe(1);
|
|
368
|
+
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
369
|
+
// The second distinct payload is tracked as an equivocation, count goes to 2,
|
|
370
|
+
// and both accepted payloads are retained by payload hash.
|
|
371
|
+
expect(result2.added).toBe(true);
|
|
372
|
+
expect(result2.alreadyExists).toBe(false);
|
|
373
|
+
expect(result2.count).toBe(2);
|
|
374
|
+
const retrievedProposal = await ap.getCheckpointProposal(SlotNumber(slotNumber));
|
|
375
|
+
const expectedProposal = [
|
|
376
|
+
proposal1,
|
|
377
|
+
proposal2
|
|
378
|
+
].sort((a, b)=>a.getPayloadHash().localeCompare(b.getPayloadHash()))[0];
|
|
379
|
+
expect(retrievedProposal.toBuffer()).toEqual(expectedProposal.toBuffer());
|
|
380
|
+
const proposals = await ap.getProposalsForSlot(SlotNumber(slotNumber));
|
|
381
|
+
expect(proposals.checkpointProposals.map((proposal)=>proposal.toBuffer())).toEqual(expect.arrayContaining([
|
|
382
|
+
proposal1.toBuffer(),
|
|
383
|
+
proposal2.toBuffer()
|
|
384
|
+
]));
|
|
385
|
+
});
|
|
386
|
+
it('should detect equivocation when only feeAssetPriceModifier differs', async ()=>{
|
|
387
|
+
const slotNumber = 420;
|
|
388
|
+
const archive = Fr.random();
|
|
389
|
+
// Same checkpoint header + archive, but two different feeAssetPriceModifier values.
|
|
390
|
+
// This is the audit-finding scenario: archive collides but the signed payload differs.
|
|
391
|
+
const sharedHeader = makeCheckpointHeader(1, {
|
|
392
|
+
slotNumber: SlotNumber(slotNumber)
|
|
393
|
+
});
|
|
394
|
+
const proposalA = await makeCheckpointProposal({
|
|
395
|
+
signer: signers[0],
|
|
396
|
+
checkpointHeader: sharedHeader,
|
|
397
|
+
archiveRoot: archive,
|
|
398
|
+
feeAssetPriceModifier: 50n
|
|
399
|
+
});
|
|
400
|
+
const proposalB = await makeCheckpointProposal({
|
|
401
|
+
signer: signers[0],
|
|
402
|
+
checkpointHeader: sharedHeader,
|
|
403
|
+
archiveRoot: archive,
|
|
404
|
+
feeAssetPriceModifier: -50n
|
|
405
|
+
});
|
|
406
|
+
const result1 = await ap.tryAddCheckpointProposal(proposalA.toCore());
|
|
407
|
+
expect(result1.count).toBe(1);
|
|
408
|
+
const result2 = await ap.tryAddCheckpointProposal(proposalB.toCore());
|
|
409
|
+
// The fix: archive collision no longer hides the equivocation; payload-hash dedup
|
|
410
|
+
// sees the distinct feeMod and bumps `count` to 2 so libp2p can fire the slash callback.
|
|
411
|
+
expect(result2.added).toBe(true);
|
|
412
|
+
expect(result2.alreadyExists).toBe(false);
|
|
413
|
+
expect(result2.count).toBe(2);
|
|
414
|
+
});
|
|
415
|
+
it('should delete retained proposals older than a given slot', async ()=>{
|
|
416
|
+
const oldSlot = 100;
|
|
417
|
+
const newSlot = 200;
|
|
418
|
+
const oldBlock = await mockBlockProposalForPool(signers[0], oldSlot);
|
|
419
|
+
const newBlock = await mockBlockProposalForPool(signers[1], newSlot);
|
|
420
|
+
const oldCheckpoint = await mockCheckpointProposalForPool(signers[0], oldSlot);
|
|
421
|
+
const newCheckpoint = await mockCheckpointProposalForPool(signers[1], newSlot);
|
|
422
|
+
await ap.tryAddBlockProposal(oldBlock);
|
|
423
|
+
await ap.tryAddBlockProposal(newBlock);
|
|
424
|
+
await ap.tryAddCheckpointProposal(oldCheckpoint);
|
|
425
|
+
await ap.tryAddCheckpointProposal(newCheckpoint);
|
|
426
|
+
await ap.deleteOlderThan(SlotNumber(newSlot));
|
|
427
|
+
expect(await ap.getProposalsForSlot(SlotNumber(oldSlot))).toEqual({
|
|
428
|
+
blockProposals: [],
|
|
429
|
+
checkpointProposals: []
|
|
430
|
+
});
|
|
431
|
+
const newProposals = await ap.getProposalsForSlot(SlotNumber(newSlot));
|
|
432
|
+
expect(newProposals.blockProposals.map((proposal)=>proposal.toBuffer())).toContainEqual(newBlock.withoutSignedTxs().toBuffer());
|
|
433
|
+
expect(newProposals.checkpointProposals.map((proposal)=>proposal.toBuffer())).toContainEqual(newCheckpoint.toBuffer());
|
|
434
|
+
});
|
|
276
435
|
it('should return added=false when exceeding capacity', async ()=>{
|
|
277
436
|
const slotNumber = 420;
|
|
278
|
-
// Add
|
|
279
|
-
for(let i = 0; i <
|
|
437
|
+
// Add MAX_CHECKPOINT_PROPOSALS_PER_SLOT distinct proposals.
|
|
438
|
+
for(let i = 0; i < MAX_CHECKPOINT_PROPOSALS_PER_SLOT; i++){
|
|
280
439
|
const proposal = await mockCheckpointProposalForPool(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber);
|
|
281
440
|
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
282
441
|
expect(result.added).toBe(true);
|
|
283
|
-
expect(result.
|
|
442
|
+
expect(result.count).toBe(i + 1);
|
|
284
443
|
}
|
|
285
|
-
// The next proposal should not be added
|
|
444
|
+
// The next proposal should not be added.
|
|
286
445
|
const extraProposal = await mockCheckpointProposalForPool(signers[0], slotNumber);
|
|
287
446
|
const result = await ap.tryAddCheckpointProposal(extraProposal);
|
|
288
447
|
expect(result.added).toBe(false);
|
|
289
448
|
expect(result.alreadyExists).toBe(false);
|
|
290
|
-
expect(result.
|
|
449
|
+
expect(result.count).toBe(MAX_CHECKPOINT_PROPOSALS_PER_SLOT);
|
|
291
450
|
});
|
|
292
451
|
});
|
|
293
452
|
describe('Duplicate proposal detection', ()=>{
|
|
@@ -303,12 +462,12 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
303
462
|
});
|
|
304
463
|
};
|
|
305
464
|
describe('tryAddBlockProposal duplicate detection', ()=>{
|
|
306
|
-
it('should return
|
|
465
|
+
it('should return count=1 when pool is empty', async ()=>{
|
|
307
466
|
const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
|
|
308
467
|
const result = await ap.tryAddBlockProposal(proposal);
|
|
309
468
|
expect(result.added).toBe(true);
|
|
310
469
|
expect(result.alreadyExists).toBe(false);
|
|
311
|
-
expect(result.
|
|
470
|
+
expect(result.count).toBe(1);
|
|
312
471
|
});
|
|
313
472
|
it('should return alreadyExists when same proposal exists', async ()=>{
|
|
314
473
|
const proposal = await mockBlockProposalWithIndex(signers[0], 100, 0);
|
|
@@ -316,22 +475,22 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
316
475
|
const result = await ap.tryAddBlockProposal(proposal);
|
|
317
476
|
expect(result.added).toBe(false);
|
|
318
477
|
expect(result.alreadyExists).toBe(true);
|
|
319
|
-
expect(result.
|
|
478
|
+
expect(result.count).toBe(1);
|
|
320
479
|
});
|
|
321
|
-
it('should detect duplicate via
|
|
480
|
+
it('should detect duplicate via count when different proposal exists at same position', async ()=>{
|
|
322
481
|
const slotNumber = 100;
|
|
323
482
|
const indexWithinCheckpoint = 2;
|
|
324
483
|
// Add first proposal
|
|
325
484
|
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
326
485
|
const result1 = await ap.tryAddBlockProposal(proposal1);
|
|
327
|
-
expect(result1.
|
|
486
|
+
expect(result1.count).toBe(1);
|
|
328
487
|
// Add a different proposal at same position - this is a duplicate (equivocation)
|
|
329
488
|
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
|
|
330
489
|
const result2 = await ap.tryAddBlockProposal(proposal2);
|
|
331
490
|
expect(result2.added).toBe(true);
|
|
332
491
|
expect(result2.alreadyExists).toBe(false);
|
|
333
|
-
//
|
|
334
|
-
expect(result2.
|
|
492
|
+
// count >= 2 indicates duplicate detection
|
|
493
|
+
expect(result2.count).toBe(2);
|
|
335
494
|
});
|
|
336
495
|
it('should not detect duplicate for different positions in same slot', async ()=>{
|
|
337
496
|
const slotNumber = 100;
|
|
@@ -342,8 +501,8 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
342
501
|
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
|
|
343
502
|
const result = await ap.tryAddBlockProposal(proposal2);
|
|
344
503
|
expect(result.added).toBe(true);
|
|
345
|
-
//
|
|
346
|
-
expect(result.
|
|
504
|
+
// count = 1 means no duplicate for this position
|
|
505
|
+
expect(result.count).toBe(1);
|
|
347
506
|
});
|
|
348
507
|
it('should not detect duplicate for same position in different slots', async ()=>{
|
|
349
508
|
const indexWithinCheckpoint = 0;
|
|
@@ -354,41 +513,41 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
354
513
|
const proposal2 = await mockBlockProposalWithIndex(signers[1], 200, indexWithinCheckpoint);
|
|
355
514
|
const result = await ap.tryAddBlockProposal(proposal2);
|
|
356
515
|
expect(result.added).toBe(true);
|
|
357
|
-
//
|
|
358
|
-
expect(result.
|
|
516
|
+
// count = 1 means no duplicate for this position
|
|
517
|
+
expect(result.count).toBe(1);
|
|
359
518
|
});
|
|
360
|
-
it('should track multiple duplicates correctly via
|
|
519
|
+
it('should track multiple duplicates correctly via count', async ()=>{
|
|
361
520
|
const slotNumber = 100;
|
|
362
521
|
const indexWithinCheckpoint = 0;
|
|
363
522
|
// Add multiple proposals for same position
|
|
364
523
|
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
365
524
|
const result1 = await ap.tryAddBlockProposal(proposal1);
|
|
366
|
-
expect(result1.
|
|
525
|
+
expect(result1.count).toBe(1);
|
|
367
526
|
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
|
|
368
527
|
const result2 = await ap.tryAddBlockProposal(proposal2);
|
|
369
|
-
expect(result2.
|
|
370
|
-
//
|
|
528
|
+
expect(result2.count).toBe(2);
|
|
529
|
+
// Third proposal for same position should be rejected (cap is 2)
|
|
371
530
|
const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
|
|
372
531
|
const result3 = await ap.tryAddBlockProposal(proposal3);
|
|
373
|
-
expect(result3.added).toBe(
|
|
374
|
-
expect(result3.
|
|
532
|
+
expect(result3.added).toBe(false);
|
|
533
|
+
expect(result3.count).toBe(2);
|
|
375
534
|
});
|
|
376
535
|
it('should return added=false when exceeding capacity', async ()=>{
|
|
377
536
|
const slotNumber = 100;
|
|
378
537
|
const indexWithinCheckpoint = 0;
|
|
379
|
-
// Add
|
|
380
|
-
for(let i = 0; i <
|
|
538
|
+
// Add MAX_BLOCK_PROPOSALS_PER_POSITION proposals
|
|
539
|
+
for(let i = 0; i < MAX_BLOCK_PROPOSALS_PER_POSITION; i++){
|
|
381
540
|
const proposal = await mockBlockProposalWithIndex(signers[i % NUMBER_OF_SIGNERS_PER_TEST], slotNumber, indexWithinCheckpoint);
|
|
382
541
|
const result = await ap.tryAddBlockProposal(proposal);
|
|
383
542
|
expect(result.added).toBe(true);
|
|
384
|
-
expect(result.
|
|
543
|
+
expect(result.count).toBe(i + 1);
|
|
385
544
|
}
|
|
386
545
|
// The next proposal should not be added
|
|
387
546
|
const extraProposal = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
388
547
|
const result = await ap.tryAddBlockProposal(extraProposal);
|
|
389
548
|
expect(result.added).toBe(false);
|
|
390
549
|
expect(result.alreadyExists).toBe(false);
|
|
391
|
-
expect(result.
|
|
550
|
+
expect(result.count).toBe(MAX_BLOCK_PROPOSALS_PER_POSITION);
|
|
392
551
|
});
|
|
393
552
|
it('should clean up block position index when deleting old data', async ()=>{
|
|
394
553
|
const slotNumber = 100;
|
|
@@ -396,16 +555,16 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
396
555
|
// Add proposal
|
|
397
556
|
const proposal1 = await mockBlockProposalWithIndex(signers[0], slotNumber, indexWithinCheckpoint);
|
|
398
557
|
await ap.tryAddBlockProposal(proposal1);
|
|
399
|
-
// Verify it's tracked (adding another should show
|
|
558
|
+
// Verify it's tracked (adding another should show count = 2)
|
|
400
559
|
const proposal2 = await mockBlockProposalWithIndex(signers[1], slotNumber, indexWithinCheckpoint);
|
|
401
560
|
let result = await ap.tryAddBlockProposal(proposal2);
|
|
402
|
-
expect(result.
|
|
561
|
+
expect(result.count).toBe(2);
|
|
403
562
|
// Delete old data
|
|
404
563
|
await ap.deleteOlderThan(SlotNumber(slotNumber + 1));
|
|
405
|
-
// Verify position index is cleaned up (
|
|
564
|
+
// Verify position index is cleaned up (count should be 1 now)
|
|
406
565
|
const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
|
|
407
566
|
result = await ap.tryAddBlockProposal(proposal3);
|
|
408
|
-
expect(result.
|
|
567
|
+
expect(result.count).toBe(1);
|
|
409
568
|
});
|
|
410
569
|
it('should correctly delete block proposals at slot boundary', async ()=>{
|
|
411
570
|
// Add proposals at slots 99, 100, and 101 with various indices
|
|
@@ -422,14 +581,14 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
422
581
|
// Slot 99 proposals should have their index cleaned up
|
|
423
582
|
const newProposal99 = await mockBlockProposalWithIndex(signers[0], 99, 0);
|
|
424
583
|
const result99 = await ap.tryAddBlockProposal(newProposal99);
|
|
425
|
-
expect(result99.
|
|
584
|
+
expect(result99.count).toBe(1); // Index was cleaned up
|
|
426
585
|
// Slot 100 and 101 should still be tracked
|
|
427
586
|
const newProposal100 = await mockBlockProposalWithIndex(signers[1], 100, 0);
|
|
428
587
|
const result100 = await ap.tryAddBlockProposal(newProposal100);
|
|
429
|
-
expect(result100.
|
|
588
|
+
expect(result100.count).toBe(2); // Still has the original
|
|
430
589
|
const newProposal101 = await mockBlockProposalWithIndex(signers[2], 101, 0);
|
|
431
590
|
const result101 = await ap.tryAddBlockProposal(newProposal101);
|
|
432
|
-
expect(result101.
|
|
591
|
+
expect(result101.count).toBe(2); // Still has the original
|
|
433
592
|
});
|
|
434
593
|
it('should delete all indices for a given slot', async ()=>{
|
|
435
594
|
const slotNumber = 50;
|
|
@@ -445,13 +604,13 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
445
604
|
// All indices should be cleaned up
|
|
446
605
|
const newProposal0 = await mockBlockProposalWithIndex(signers[0], slotNumber, 0);
|
|
447
606
|
const result0 = await ap.tryAddBlockProposal(newProposal0);
|
|
448
|
-
expect(result0.
|
|
607
|
+
expect(result0.count).toBe(1);
|
|
449
608
|
const newProposal1 = await mockBlockProposalWithIndex(signers[1], slotNumber, 1);
|
|
450
609
|
const result1 = await ap.tryAddBlockProposal(newProposal1);
|
|
451
|
-
expect(result1.
|
|
610
|
+
expect(result1.count).toBe(1);
|
|
452
611
|
const newProposal2 = await mockBlockProposalWithIndex(signers[2], slotNumber, 2);
|
|
453
612
|
const result2 = await ap.tryAddBlockProposal(newProposal2);
|
|
454
|
-
expect(result2.
|
|
613
|
+
expect(result2.count).toBe(1);
|
|
455
614
|
});
|
|
456
615
|
it('should delete block proposals from storage when deleting old data', async ()=>{
|
|
457
616
|
const oldSlot = 50;
|
|
@@ -462,25 +621,25 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
462
621
|
await ap.tryAddBlockProposal(oldProposal);
|
|
463
622
|
await ap.tryAddBlockProposal(newProposal);
|
|
464
623
|
// Verify both proposals exist
|
|
465
|
-
expect(await ap.
|
|
466
|
-
expect(await ap.
|
|
624
|
+
expect(await ap.getBlockProposalByArchive(oldProposal.archive.toString())).toBeDefined();
|
|
625
|
+
expect(await ap.getBlockProposalByArchive(newProposal.archive.toString())).toBeDefined();
|
|
467
626
|
// Delete slots older than newSlot (should delete oldSlot)
|
|
468
627
|
await ap.deleteOlderThan(SlotNumber(newSlot));
|
|
469
628
|
// Old proposal should be deleted from storage
|
|
470
|
-
expect(await ap.
|
|
629
|
+
expect(await ap.getBlockProposalByArchive(oldProposal.archive.toString())).toBeUndefined();
|
|
471
630
|
// New proposal should still exist
|
|
472
|
-
expect(await ap.
|
|
631
|
+
expect(await ap.getBlockProposalByArchive(newProposal.archive.toString())).toBeDefined();
|
|
473
632
|
});
|
|
474
633
|
});
|
|
475
634
|
describe('tryAddCheckpointProposal duplicate detection', ()=>{
|
|
476
|
-
const mockCheckpointProposalCoreForPool = async (signer, slotNumber, archive = Fr.random())=>{
|
|
477
|
-
const
|
|
635
|
+
const mockCheckpointProposalCoreForPool = async (signer, slotNumber, archive = Fr.random(), checkpointHeader)=>{
|
|
636
|
+
const headerToUse = checkpointHeader ?? makeCheckpointHeader(1, {
|
|
478
637
|
slotNumber: SlotNumber(slotNumber)
|
|
479
638
|
});
|
|
480
639
|
const blockHeader = makeBlockHeader(1);
|
|
481
640
|
const proposal = await makeCheckpointProposal({
|
|
482
641
|
signer,
|
|
483
|
-
checkpointHeader,
|
|
642
|
+
checkpointHeader: headerToUse,
|
|
484
643
|
archiveRoot: archive,
|
|
485
644
|
lastBlock: {
|
|
486
645
|
blockHeader
|
|
@@ -488,12 +647,12 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
488
647
|
});
|
|
489
648
|
return proposal.toCore();
|
|
490
649
|
};
|
|
491
|
-
it('should return
|
|
650
|
+
it('should return count=1 when pool is empty', async ()=>{
|
|
492
651
|
const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
|
|
493
652
|
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
494
653
|
expect(result.added).toBe(true);
|
|
495
654
|
expect(result.alreadyExists).toBe(false);
|
|
496
|
-
expect(result.
|
|
655
|
+
expect(result.count).toBe(1);
|
|
497
656
|
});
|
|
498
657
|
it('should return alreadyExists when same proposal exists', async ()=>{
|
|
499
658
|
const proposal = await mockCheckpointProposalCoreForPool(signers[0], 100);
|
|
@@ -501,21 +660,21 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
501
660
|
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
502
661
|
expect(result.added).toBe(false);
|
|
503
662
|
expect(result.alreadyExists).toBe(true);
|
|
504
|
-
expect(result.
|
|
663
|
+
expect(result.count).toBe(1);
|
|
505
664
|
});
|
|
506
|
-
it('should detect duplicate via
|
|
665
|
+
it('should detect duplicate via count when different proposal exists for same slot', async ()=>{
|
|
507
666
|
const slotNumber = 100;
|
|
508
667
|
// Add first proposal
|
|
509
668
|
const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
|
|
510
669
|
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
511
|
-
expect(result1.
|
|
670
|
+
expect(result1.count).toBe(1);
|
|
512
671
|
// Add a different proposal for same slot - this is a duplicate (equivocation)
|
|
513
672
|
const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
|
|
514
673
|
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
515
674
|
expect(result2.added).toBe(true);
|
|
516
675
|
expect(result2.alreadyExists).toBe(false);
|
|
517
|
-
//
|
|
518
|
-
expect(result2.
|
|
676
|
+
// count >= 2 indicates duplicate detection
|
|
677
|
+
expect(result2.count).toBe(2);
|
|
519
678
|
});
|
|
520
679
|
it('should not detect duplicate for different slots', async ()=>{
|
|
521
680
|
// Add proposal at slot 100
|
|
@@ -525,23 +684,23 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
525
684
|
const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], 200);
|
|
526
685
|
const result = await ap.tryAddCheckpointProposal(proposal2);
|
|
527
686
|
expect(result.added).toBe(true);
|
|
528
|
-
//
|
|
529
|
-
expect(result.
|
|
687
|
+
// count = 1 means no duplicate for this slot
|
|
688
|
+
expect(result.count).toBe(1);
|
|
530
689
|
});
|
|
531
|
-
it('should track multiple duplicates correctly via
|
|
690
|
+
it('should track multiple duplicates correctly via count', async ()=>{
|
|
532
691
|
const slotNumber = 100;
|
|
533
692
|
// Add multiple proposals for same slot
|
|
534
693
|
const proposal1 = await mockCheckpointProposalCoreForPool(signers[0], slotNumber);
|
|
535
694
|
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
536
|
-
expect(result1.
|
|
695
|
+
expect(result1.count).toBe(1);
|
|
537
696
|
const proposal2 = await mockCheckpointProposalCoreForPool(signers[1], slotNumber);
|
|
538
697
|
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
539
|
-
expect(result2.
|
|
540
|
-
//
|
|
698
|
+
expect(result2.count).toBe(2);
|
|
699
|
+
// Third proposal for same slot should be rejected (cap is 2)
|
|
541
700
|
const proposal3 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber);
|
|
542
701
|
const result3 = await ap.tryAddCheckpointProposal(proposal3);
|
|
543
|
-
expect(result3.added).toBe(
|
|
544
|
-
expect(result3.
|
|
702
|
+
expect(result3.added).toBe(false);
|
|
703
|
+
expect(result3.count).toBe(2);
|
|
545
704
|
});
|
|
546
705
|
it('should not count attestations as proposals for duplicate detection', async ()=>{
|
|
547
706
|
const slotNumber = 100;
|
|
@@ -556,8 +715,8 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
556
715
|
const result = await ap.tryAddCheckpointProposal(proposal);
|
|
557
716
|
expect(result.added).toBe(true);
|
|
558
717
|
expect(result.alreadyExists).toBe(false);
|
|
559
|
-
//
|
|
560
|
-
expect(result.
|
|
718
|
+
// count should be 1, NOT 2 - attestations should not count as proposals
|
|
719
|
+
expect(result.count).toBe(1);
|
|
561
720
|
});
|
|
562
721
|
it('should not count attestations for different proposals as duplicates', async ()=>{
|
|
563
722
|
const slotNumber = 100;
|
|
@@ -574,12 +733,12 @@ export function describeAttestationPool(getAttestationPool) {
|
|
|
574
733
|
const proposal1 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber, archive1);
|
|
575
734
|
const result1 = await ap.tryAddCheckpointProposal(proposal1);
|
|
576
735
|
expect(result1.added).toBe(true);
|
|
577
|
-
expect(result1.
|
|
736
|
+
expect(result1.count).toBe(1);
|
|
578
737
|
// Add the second checkpoint proposal - this IS a duplicate (different archive, same slot)
|
|
579
738
|
const proposal2 = await mockCheckpointProposalCoreForPool(signers[3], slotNumber, archive2);
|
|
580
739
|
const result2 = await ap.tryAddCheckpointProposal(proposal2);
|
|
581
740
|
expect(result2.added).toBe(true);
|
|
582
|
-
expect(result2.
|
|
741
|
+
expect(result2.count).toBe(2);
|
|
583
742
|
});
|
|
584
743
|
});
|
|
585
744
|
});
|