@aztec/p2p 0.0.1-commit.96dac018d → 0.0.1-commit.993d240
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 +129 -3
- package/dest/bootstrap/bootstrap.d.ts +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +9 -1
- package/dest/client/factory.d.ts +7 -7
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +34 -16
- package/dest/client/interface.d.ts +17 -8
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +15 -11
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +93 -49
- package/dest/config.d.ts +153 -102
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +134 -35
- 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 +1 -20
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/errors/reqresp.error.js +0 -21
- package/dest/index.d.ts +1 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +0 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +99 -59
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +267 -197
- 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 +181 -65
- package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +6 -4
- package/dest/mem_pools/index.d.ts +1 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.d.ts +4 -2
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +33 -15
- 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 +2 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
- 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 +2 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
- 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 +62 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
- 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 +8 -6
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
- 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 +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +12 -5
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +44 -12
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +81 -22
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
- 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 +26 -44
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +4 -2
- 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 +6 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +2 -1
- 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 +133 -110
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +37 -12
- 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/clock_tolerance.d.ts +12 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +61 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +10 -4
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +10 -4
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +21 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +90 -44
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +8 -15
- 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/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/factory.d.ts +27 -7
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +47 -17
- 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 +48 -7
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +88 -41
- package/dest/msg_validators/tx_validator/index.d.ts +4 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +3 -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/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/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 +69 -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 +2 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +35 -8
- package/dest/services/dummy_service.d.ts +11 -15
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +12 -16
- package/dest/services/encoding.d.ts +6 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +14 -8
- package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +21 -4
- package/dest/services/libp2p/instrumentation.d.ts +3 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +14 -0
- package/dest/services/libp2p/libp2p_service.d.ts +39 -50
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +299 -250
- 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 +6 -2
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +40 -11
- package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +32 -10
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -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 +84 -71
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +10 -6
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +3 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +3 -0
- 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 +3 -3
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/interface.d.ts +16 -18
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +10 -20
- 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/block_txs_handler.d.ts +1 -1
- 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 +4 -2
- 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 +1 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +1 -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 +0 -10
- 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 +43 -215
- package/dest/services/service.d.ts +9 -12
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +2 -23
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +2 -55
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +12 -28
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.js +43 -83
- package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_source.js +39 -29
- package/dest/services/tx_collection/index.d.ts +2 -3
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +0 -1
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +0 -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 +36 -55
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +275 -119
- package/dest/services/tx_collection/tx_collection_sink.d.ts +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +2 -2
- package/dest/services/tx_collection/tx_source.d.ts +6 -5
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +9 -7
- package/dest/services/tx_file_store/tx_file_store.d.ts +1 -3
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
- package/dest/services/tx_file_store/tx_file_store.js +4 -14
- package/dest/services/tx_provider.d.ts +3 -1
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +3 -0
- package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
- 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 +24 -11
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +45 -45
- 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 +12 -14
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +42 -15
- 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 +88 -42
- 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 +12 -7
- 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 +15 -14
- package/src/bootstrap/bootstrap.ts +9 -1
- package/src/client/factory.ts +65 -21
- package/src/client/interface.ts +18 -20
- package/src/client/p2p_client.ts +108 -82
- package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
- package/src/config.ts +226 -36
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/errors/reqresp.error.ts +0 -25
- package/src/index.ts +0 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +318 -242
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +204 -68
- package/src/mem_pools/attestation_pool/mocks.ts +13 -8
- package/src/mem_pools/index.ts +0 -3
- package/src/mem_pools/instrumentation.ts +22 -14
- package/src/mem_pools/tx_pool_v2/README.md +9 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +2 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -0
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
- package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
- package/src/mem_pools/tx_pool_v2/index.ts +1 -1
- package/src/mem_pools/tx_pool_v2/interfaces.ts +12 -4
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +121 -27
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +16 -1
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +141 -114
- package/src/msg_validators/attestation_validator/README.md +49 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -9
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +14 -7
- package/src/msg_validators/clock_tolerance.ts +79 -3
- package/src/msg_validators/proposal_validator/README.md +123 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +24 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +35 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +114 -47
- package/src/msg_validators/tx_validator/README.md +15 -3
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -12
- 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/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/factory.ts +61 -10
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +121 -39
- package/src/msg_validators/tx_validator/index.ts +3 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
- package/src/msg_validators/tx_validator/tx_validation_cache.ts +102 -0
- package/src/services/data_store.ts +5 -13
- package/src/services/discv5/discV5_service.ts +38 -5
- package/src/services/dummy_service.ts +14 -39
- package/src/services/encoding.ts +14 -7
- package/src/services/gossipsub/topic_score_params.ts +36 -4
- package/src/services/libp2p/instrumentation.ts +14 -0
- package/src/services/libp2p/libp2p_service.ts +326 -287
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +46 -11
- package/src/services/peer-manager/peer_scoring.ts +27 -5
- package/src/services/reqresp/README.md +215 -0
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +83 -77
- package/src/services/reqresp/batch-tx-requester/interface.ts +13 -5
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +5 -0
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
- package/src/services/reqresp/config.ts +2 -2
- package/src/services/reqresp/interface.ts +21 -47
- package/src/services/reqresp/metrics.ts +0 -1
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +4 -2
- package/src/services/reqresp/protocols/index.ts +0 -1
- package/src/services/reqresp/protocols/tx.ts +1 -3
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
- package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
- package/src/services/reqresp/reqresp.ts +48 -261
- package/src/services/service.ts +12 -28
- package/src/services/tx_collection/config.ts +3 -80
- package/src/services/tx_collection/file_store_tx_collection.ts +54 -103
- package/src/services/tx_collection/file_store_tx_source.ts +43 -31
- package/src/services/tx_collection/index.ts +1 -6
- package/src/services/tx_collection/instrumentation.ts +1 -7
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/tx_collection.ts +331 -176
- package/src/services/tx_collection/tx_collection_sink.ts +2 -2
- package/src/services/tx_collection/tx_source.ts +8 -7
- package/src/services/tx_file_store/tx_file_store.ts +5 -17
- package/src/services/tx_provider.ts +5 -0
- package/src/test-helpers/make-test-p2p-clients.ts +4 -3
- package/src/test-helpers/mock-pubsub.ts +49 -66
- 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 +53 -28
- package/src/testbench/p2p_client_testbench_worker.ts +91 -61
- package/src/testbench/worker_client_manager.ts +72 -25
- package/src/util.ts +33 -18
- 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/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 -54
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
- package/dest/services/tx_collection/fast_tx_collection.js +0 -327
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
- package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -49
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +0 -50
- package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -57
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
- package/dest/services/tx_collection/slow_tx_collection.js +0 -211
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -346
- 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/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 -387
- package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
- package/src/services/tx_collection/proposal_tx_collector.ts +0 -113
- package/src/services/tx_collection/slow_tx_collection.ts +0 -266
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { insertIntoSortedArray, removeFromSortedArray } from '@aztec/foundation/array';
|
|
1
2
|
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
3
|
import type { L2BlockId } from '@aztec/stdlib/block';
|
|
3
4
|
|
|
4
|
-
import { type TxMetaData, type TxState,
|
|
5
|
+
import { type PriorityComparable, type TxMetaData, type TxState, comparePriority } from './tx_metadata.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Manages in-memory indices for the transaction pool.
|
|
@@ -22,8 +23,8 @@ export class TxPoolIndices {
|
|
|
22
23
|
#nullifierToTxHash: Map<string, string> = new Map();
|
|
23
24
|
/** Fee payer to txHashes index (pending txs only) */
|
|
24
25
|
#feePayerToTxHashes: Map<string, Set<string>> = new Map();
|
|
25
|
-
/** Pending
|
|
26
|
-
#pendingByPriority:
|
|
26
|
+
/** Pending transactions sorted ascending by priority fee, ties broken by txHash */
|
|
27
|
+
#pendingByPriority: PriorityComparable[] = [];
|
|
27
28
|
/** Protected transactions: txHash -> slotNumber */
|
|
28
29
|
#protectedTransactions: Map<string, SlotNumber> = new Map();
|
|
29
30
|
|
|
@@ -73,20 +74,14 @@ export class TxPoolIndices {
|
|
|
73
74
|
* @param order - 'desc' for highest priority first, 'asc' for lowest priority first
|
|
74
75
|
*/
|
|
75
76
|
*iteratePendingByPriority(order: 'asc' | 'desc', filter?: (hash: string) => boolean): Generator<string> {
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// Use compareTxHash from tx_metadata, swap args for descending order
|
|
85
|
-
const sortedHashes = [...hashesAtFee].sort(hashCompareFn);
|
|
86
|
-
for (const hash of sortedHashes) {
|
|
87
|
-
if (filter === undefined || filter(hash)) {
|
|
88
|
-
yield hash;
|
|
89
|
-
}
|
|
77
|
+
const arr = this.#pendingByPriority;
|
|
78
|
+
const start = order === 'asc' ? 0 : arr.length - 1;
|
|
79
|
+
const step = order === 'asc' ? 1 : -1;
|
|
80
|
+
const inBounds = order === 'asc' ? (i: number) => i < arr.length : (i: number) => i >= 0;
|
|
81
|
+
|
|
82
|
+
for (let i = start; inBounds(i); i += step) {
|
|
83
|
+
if (filter === undefined || filter(arr[i].txHash)) {
|
|
84
|
+
yield arr[i].txHash;
|
|
90
85
|
}
|
|
91
86
|
}
|
|
92
87
|
}
|
|
@@ -227,11 +222,7 @@ export class TxPoolIndices {
|
|
|
227
222
|
|
|
228
223
|
/** Gets the count of pending transactions */
|
|
229
224
|
getPendingTxCount(): number {
|
|
230
|
-
|
|
231
|
-
for (const hashes of this.#pendingByPriority.values()) {
|
|
232
|
-
count += hashes.size;
|
|
233
|
-
}
|
|
234
|
-
return count;
|
|
225
|
+
return this.#pendingByPriority.length;
|
|
235
226
|
}
|
|
236
227
|
|
|
237
228
|
/** Gets the lowest priority pending transaction hashes (up to limit) */
|
|
@@ -264,12 +255,10 @@ export class TxPoolIndices {
|
|
|
264
255
|
/** Gets all pending transactions */
|
|
265
256
|
getPendingTxs(): TxMetaData[] {
|
|
266
257
|
const result: TxMetaData[] = [];
|
|
267
|
-
for (const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
result.push(meta);
|
|
272
|
-
}
|
|
258
|
+
for (const entry of this.#pendingByPriority) {
|
|
259
|
+
const meta = this.#metadata.get(entry.txHash);
|
|
260
|
+
if (meta) {
|
|
261
|
+
result.push(meta);
|
|
273
262
|
}
|
|
274
263
|
}
|
|
275
264
|
return result;
|
|
@@ -408,13 +397,12 @@ export class TxPoolIndices {
|
|
|
408
397
|
}
|
|
409
398
|
feePayerSet.add(meta.txHash);
|
|
410
399
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
prioritySet.add(meta.txHash);
|
|
400
|
+
insertIntoSortedArray(
|
|
401
|
+
this.#pendingByPriority,
|
|
402
|
+
{ txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
|
|
403
|
+
comparePriority,
|
|
404
|
+
false,
|
|
405
|
+
);
|
|
418
406
|
}
|
|
419
407
|
|
|
420
408
|
#removeFromPendingIndices(meta: TxMetaData): void {
|
|
@@ -432,13 +420,11 @@ export class TxPoolIndices {
|
|
|
432
420
|
}
|
|
433
421
|
}
|
|
434
422
|
|
|
435
|
-
// Remove from priority
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
}
|
|
423
|
+
// Remove from priority array
|
|
424
|
+
removeFromSortedArray(
|
|
425
|
+
this.#pendingByPriority,
|
|
426
|
+
{ txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
|
|
427
|
+
comparePriority,
|
|
428
|
+
);
|
|
443
429
|
}
|
|
444
430
|
}
|
|
@@ -11,7 +11,14 @@ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-clien
|
|
|
11
11
|
import EventEmitter from 'node:events';
|
|
12
12
|
|
|
13
13
|
import { PoolInstrumentation, PoolName } from '../instrumentation.js';
|
|
14
|
-
import type {
|
|
14
|
+
import type {
|
|
15
|
+
AddTxsResult,
|
|
16
|
+
PoolReadAccess,
|
|
17
|
+
TxPoolV2,
|
|
18
|
+
TxPoolV2Config,
|
|
19
|
+
TxPoolV2Dependencies,
|
|
20
|
+
TxPoolV2Events,
|
|
21
|
+
} from './interfaces.js';
|
|
15
22
|
import type { TxState } from './tx_metadata.js';
|
|
16
23
|
import { TxPoolV2Impl } from './tx_pool_v2_impl.js';
|
|
17
24
|
|
|
@@ -58,6 +65,9 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
|
|
|
58
65
|
const hashes = txHashes.map(h => (typeof h === 'string' ? TxHash.fromString(h) : TxHash.fromBigInt(h)));
|
|
59
66
|
this.emit('txs-removed', { txHashes: hashes });
|
|
60
67
|
},
|
|
68
|
+
onTxsMined: (txHashes: string[]) => {
|
|
69
|
+
this.#metrics?.transactionsRemoved(txHashes);
|
|
70
|
+
},
|
|
61
71
|
};
|
|
62
72
|
|
|
63
73
|
// Create the implementation
|
|
@@ -162,6 +172,11 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
|
|
|
162
172
|
return this.#queue.put(() => Promise.resolve(this.#impl.getLowestPriorityPending(limit)));
|
|
163
173
|
}
|
|
164
174
|
|
|
175
|
+
/** Returns read-only access to the pool. Used for testing. */
|
|
176
|
+
getPoolReadAccess(): PoolReadAccess {
|
|
177
|
+
return this.#impl.getPoolReadAccess();
|
|
178
|
+
}
|
|
179
|
+
|
|
165
180
|
// === Configuration ===
|
|
166
181
|
|
|
167
182
|
updateConfig(config: Partial<TxPoolV2Config>): Promise<void> {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { FifoSet } from '@aztec/foundation/fifo-set';
|
|
2
3
|
import type { Logger } from '@aztec/foundation/log';
|
|
3
4
|
import type { DateProvider } from '@aztec/foundation/timer';
|
|
4
5
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
EvictionManager,
|
|
18
19
|
FeePayerBalanceEvictionRule,
|
|
19
20
|
FeePayerBalancePreAddRule,
|
|
21
|
+
InsufficientFeePerGasEvictionRule,
|
|
20
22
|
InvalidTxsAfterMiningRule,
|
|
21
23
|
InvalidTxsAfterReorgRule,
|
|
22
24
|
LowPriorityEvictionRule,
|
|
@@ -39,12 +41,20 @@ import {
|
|
|
39
41
|
import { type TxMetaData, type TxState, buildTxMetaData, checkNullifierConflict } from './tx_metadata.js';
|
|
40
42
|
import { TxPoolIndices } from './tx_pool_indices.js';
|
|
41
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Maximum number of full transactions to load into memory at once when finalizing a block.
|
|
46
|
+
* Bounds peak memory while archiving and hard-deleting mined txs (~23k txs/epoch at 10 TPS would
|
|
47
|
+
* otherwise OOM the node).
|
|
48
|
+
*/
|
|
49
|
+
const FINALIZE_BLOCK_CHUNK_SIZE = 100;
|
|
50
|
+
|
|
42
51
|
/**
|
|
43
52
|
* Callbacks for the implementation to notify the outer class about events and metrics.
|
|
44
53
|
*/
|
|
45
54
|
export interface TxPoolV2Callbacks {
|
|
46
55
|
onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
|
|
47
56
|
onTxsRemoved: (txHashes: string[] | bigint[]) => void;
|
|
57
|
+
onTxsMined: (txHashes: string[]) => void;
|
|
48
58
|
}
|
|
49
59
|
|
|
50
60
|
/**
|
|
@@ -61,6 +71,7 @@ export class TxPoolV2Impl {
|
|
|
61
71
|
#l2BlockSource: L2BlockSource;
|
|
62
72
|
#worldStateSynchronizer: WorldStateSynchronizer;
|
|
63
73
|
#createTxValidator: TxPoolV2Dependencies['createTxValidator'];
|
|
74
|
+
#checkAllowedSetupCalls: TxPoolV2Dependencies['checkAllowedSetupCalls'];
|
|
64
75
|
|
|
65
76
|
// === In-Memory Indices ===
|
|
66
77
|
#indices: TxPoolIndices = new TxPoolIndices();
|
|
@@ -72,7 +83,7 @@ export class TxPoolV2Impl {
|
|
|
72
83
|
#evictionManager: EvictionManager;
|
|
73
84
|
#dateProvider: DateProvider;
|
|
74
85
|
#instrumentation: TxPoolV2Instrumentation;
|
|
75
|
-
#evictedTxHashes:
|
|
86
|
+
#evictedTxHashes: FifoSet<string>;
|
|
76
87
|
#log: Logger;
|
|
77
88
|
#callbacks: TxPoolV2Callbacks;
|
|
78
89
|
|
|
@@ -92,8 +103,10 @@ export class TxPoolV2Impl {
|
|
|
92
103
|
this.#l2BlockSource = deps.l2BlockSource;
|
|
93
104
|
this.#worldStateSynchronizer = deps.worldStateSynchronizer;
|
|
94
105
|
this.#createTxValidator = deps.createTxValidator;
|
|
106
|
+
this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
|
|
95
107
|
|
|
96
108
|
this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
|
|
109
|
+
this.#evictedTxHashes = FifoSet.withLimit<string>(this.#config.evictedTxCacheSize);
|
|
97
110
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
98
111
|
this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
|
|
99
112
|
this.#dateProvider = dateProvider;
|
|
@@ -113,6 +126,7 @@ export class TxPoolV2Impl {
|
|
|
113
126
|
|
|
114
127
|
// Post-event eviction rules (run after events to check ALL pending txs)
|
|
115
128
|
this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
|
|
129
|
+
this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
|
|
116
130
|
this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
|
|
117
131
|
this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
|
|
118
132
|
// LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
|
|
@@ -135,39 +149,67 @@ export class TxPoolV2Impl {
|
|
|
135
149
|
// Step 0: Hydrate deleted pool state
|
|
136
150
|
await this.#deletedPool.hydrateFromDatabase();
|
|
137
151
|
|
|
138
|
-
// Step 1:
|
|
139
|
-
const
|
|
152
|
+
// Step 1: Stream txs from DB, building metadata and mined status one at a time.
|
|
153
|
+
const minedMetas: TxMetaData[] = [];
|
|
154
|
+
const pendingMetas: TxMetaData[] = [];
|
|
155
|
+
const deserializationErrors: string[] = [];
|
|
156
|
+
|
|
157
|
+
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
158
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
159
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let meta: TxMetaData;
|
|
164
|
+
let txEffect: Awaited<ReturnType<L2BlockSource['getTxEffect']>>;
|
|
165
|
+
try {
|
|
166
|
+
const tx = Tx.fromBuffer(buffer);
|
|
167
|
+
// Resolve allowed-setup-calls and the tx effect concurrently
|
|
168
|
+
// getTxEffect failures are non-fatal (we just treat the tx as not-yet-mined), so
|
|
169
|
+
// its rejection is swallowed before the Promise.all so it can't fail-fast the batch.
|
|
170
|
+
const txEffectPromise = this.#l2BlockSource.getTxEffect(tx.getTxHash()).catch(err => {
|
|
171
|
+
this.#log.warn(`Failed to check mined status for tx ${txHashStr}`, { err });
|
|
172
|
+
return undefined;
|
|
173
|
+
});
|
|
174
|
+
const [allowedSetupCalls, fetchedTxEffect] = await Promise.all([
|
|
175
|
+
this.#checkAllowedSetupCalls(tx),
|
|
176
|
+
txEffectPromise,
|
|
177
|
+
]);
|
|
178
|
+
meta = await buildTxMetaData(tx, allowedSetupCalls);
|
|
179
|
+
txEffect = fetchedTxEffect;
|
|
180
|
+
} catch (err) {
|
|
181
|
+
this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
|
|
182
|
+
deserializationErrors.push(txHashStr);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
140
185
|
|
|
141
|
-
|
|
142
|
-
|
|
186
|
+
if (txEffect) {
|
|
187
|
+
meta.minedL2BlockId = {
|
|
188
|
+
number: txEffect.l2BlockNumber,
|
|
189
|
+
hash: txEffect.l2BlockHash.toString(),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
143
192
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const nonMined: { tx: Tx; meta: TxMetaData }[] = [];
|
|
147
|
-
for (const entry of loaded) {
|
|
148
|
-
if (entry.meta.minedL2BlockId !== undefined) {
|
|
149
|
-
mined.push(entry.meta);
|
|
193
|
+
if (meta.minedL2BlockId !== undefined) {
|
|
194
|
+
minedMetas.push(meta);
|
|
150
195
|
} else {
|
|
151
|
-
|
|
196
|
+
pendingMetas.push(meta);
|
|
152
197
|
}
|
|
153
198
|
}
|
|
154
199
|
|
|
155
|
-
// Step
|
|
156
|
-
const { valid, invalid } = await this.#revalidateMetadata(
|
|
157
|
-
nonMined.map(e => e.meta),
|
|
158
|
-
'on startup',
|
|
159
|
-
);
|
|
200
|
+
// Step 2: Validate non-mined transactions
|
|
201
|
+
const { valid, invalid } = await this.#revalidateMetadata(pendingMetas, 'on startup');
|
|
160
202
|
|
|
161
|
-
// Step
|
|
162
|
-
for (const meta of
|
|
203
|
+
// Step 3: Populate mined indices (these don't need conflict resolution)
|
|
204
|
+
for (const meta of minedMetas) {
|
|
163
205
|
this.#indices.addMined(meta);
|
|
164
206
|
}
|
|
165
207
|
|
|
166
|
-
// Step
|
|
208
|
+
// Step 4: Rebuild pending pool by running pre-add rules for each tx
|
|
167
209
|
// This resolves nullifier conflicts, fee payer balance issues, and pool size limits
|
|
168
210
|
const { rejected } = await this.#rebuildPendingPool(valid);
|
|
169
211
|
|
|
170
|
-
// Step
|
|
212
|
+
// Step 5: Delete invalid and rejected txs from DB only (indices were never populated for these)
|
|
171
213
|
const toDelete = [...deserializationErrors, ...invalid, ...rejected];
|
|
172
214
|
if (toDelete.length === 0) {
|
|
173
215
|
return;
|
|
@@ -187,9 +229,35 @@ export class TxPoolV2Impl {
|
|
|
187
229
|
const errors = new Map<string, TxPoolRejectionError>();
|
|
188
230
|
const acceptedPending = new Set<string>();
|
|
189
231
|
|
|
232
|
+
// Phase 1: Pre-compute all throwable I/O outside the transaction.
|
|
233
|
+
// If any pre-computation throws, the entire call fails before mutations happen.
|
|
234
|
+
const precomputed = new Map<string, { meta: TxMetaData; minedBlockId: L2BlockId | undefined; isValid: boolean }>();
|
|
235
|
+
|
|
236
|
+
const validator = await this.#createTxValidator();
|
|
237
|
+
|
|
238
|
+
for (const tx of txs) {
|
|
239
|
+
const txHash = tx.getTxHash();
|
|
240
|
+
const txHashStr = txHash.toString();
|
|
241
|
+
|
|
242
|
+
const meta = await buildTxMetaData(tx);
|
|
243
|
+
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
244
|
+
|
|
245
|
+
// Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
|
|
246
|
+
let isValid = true;
|
|
247
|
+
if (!minedBlockId) {
|
|
248
|
+
isValid = await this.#validateMeta(meta, validator);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
precomputed.set(txHashStr, { meta, minedBlockId, isValid });
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Phase 2: Apply mutations inside the transaction using only pre-computed results,
|
|
255
|
+
// in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
|
|
190
256
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
191
257
|
const preAddContext: PreAddContext | undefined =
|
|
192
|
-
opts.feeComparisonOnly !== undefined
|
|
258
|
+
opts.feeComparisonOnly !== undefined
|
|
259
|
+
? { feeComparisonOnly: opts.feeComparisonOnly, priceBumpPercentage: this.#config.priceBumpPercentage }
|
|
260
|
+
: undefined;
|
|
193
261
|
|
|
194
262
|
await this.#store.transactionAsync(async () => {
|
|
195
263
|
for (const tx of txs) {
|
|
@@ -202,22 +270,25 @@ export class TxPoolV2Impl {
|
|
|
202
270
|
continue;
|
|
203
271
|
}
|
|
204
272
|
|
|
205
|
-
|
|
206
|
-
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
273
|
+
const { meta, minedBlockId, isValid } = precomputed.get(txHashStr)!;
|
|
207
274
|
const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
|
|
208
275
|
|
|
209
276
|
if (minedBlockId) {
|
|
210
277
|
// Already mined - add directly (protection already set if pre-protected)
|
|
211
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
278
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
212
279
|
accepted.push(txHash);
|
|
213
280
|
} else if (preProtectedSlot !== undefined) {
|
|
214
281
|
// Pre-protected and not mined - add as protected (bypass validation)
|
|
215
|
-
await this.#addTx(tx, { protected: preProtectedSlot }, opts);
|
|
282
|
+
await this.#addTx(tx, { protected: preProtectedSlot }, opts, meta);
|
|
216
283
|
accepted.push(txHash);
|
|
284
|
+
} else if (!isValid) {
|
|
285
|
+
// Failed pre-computed validation
|
|
286
|
+
rejected.push(txHash);
|
|
217
287
|
} else {
|
|
218
|
-
// Regular pending tx -
|
|
288
|
+
// Regular pending tx - run pre-add rules using pre-computed metadata
|
|
219
289
|
const result = await this.#tryAddRegularPendingTx(
|
|
220
290
|
tx,
|
|
291
|
+
meta,
|
|
221
292
|
opts,
|
|
222
293
|
poolAccess,
|
|
223
294
|
acceptedPending,
|
|
@@ -227,8 +298,6 @@ export class TxPoolV2Impl {
|
|
|
227
298
|
);
|
|
228
299
|
if (result.status === 'accepted') {
|
|
229
300
|
acceptedPending.add(txHashStr);
|
|
230
|
-
} else if (result.status === 'rejected') {
|
|
231
|
-
rejected.push(txHash);
|
|
232
301
|
} else {
|
|
233
302
|
ignored.push(txHash);
|
|
234
303
|
}
|
|
@@ -259,27 +328,21 @@ export class TxPoolV2Impl {
|
|
|
259
328
|
return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
|
|
260
329
|
}
|
|
261
330
|
|
|
262
|
-
/**
|
|
331
|
+
/** Adds a validated pending tx, running pre-add rules and evicting conflicts. */
|
|
263
332
|
async #tryAddRegularPendingTx(
|
|
264
333
|
tx: Tx,
|
|
334
|
+
precomputedMeta: TxMetaData,
|
|
265
335
|
opts: { source?: string },
|
|
266
336
|
poolAccess: PreAddPoolAccess,
|
|
267
337
|
acceptedPending: Set<string>,
|
|
268
338
|
ignored: TxHash[],
|
|
269
339
|
errors: Map<string, TxPoolRejectionError>,
|
|
270
340
|
preAddContext?: PreAddContext,
|
|
271
|
-
): Promise<{ status: 'accepted' | 'ignored'
|
|
272
|
-
const
|
|
273
|
-
const txHashStr = txHash.toString();
|
|
274
|
-
|
|
275
|
-
// Build metadata and validate using metadata
|
|
276
|
-
const meta = await buildTxMetaData(tx);
|
|
277
|
-
if (!(await this.#validateMeta(meta))) {
|
|
278
|
-
return { status: 'rejected' };
|
|
279
|
-
}
|
|
341
|
+
): Promise<{ status: 'accepted' | 'ignored' }> {
|
|
342
|
+
const txHashStr = tx.getTxHash().toString();
|
|
280
343
|
|
|
281
344
|
// Run pre-add rules
|
|
282
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(
|
|
345
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
|
|
283
346
|
|
|
284
347
|
if (preAddResult.shouldIgnore) {
|
|
285
348
|
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
@@ -323,7 +386,7 @@ export class TxPoolV2Impl {
|
|
|
323
386
|
}
|
|
324
387
|
|
|
325
388
|
// Add the transaction
|
|
326
|
-
await this.#addTx(tx, 'pending', opts);
|
|
389
|
+
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
327
390
|
return { status: 'accepted' };
|
|
328
391
|
}
|
|
329
392
|
|
|
@@ -332,6 +395,7 @@ export class TxPoolV2Impl {
|
|
|
332
395
|
|
|
333
396
|
// Check if already in pool
|
|
334
397
|
if (this.#indices.has(txHashStr)) {
|
|
398
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
|
|
335
399
|
return 'ignored';
|
|
336
400
|
}
|
|
337
401
|
|
|
@@ -340,26 +404,37 @@ export class TxPoolV2Impl {
|
|
|
340
404
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
341
405
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
342
406
|
|
|
343
|
-
|
|
407
|
+
if (preAddResult.shouldIgnore) {
|
|
408
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
|
|
409
|
+
reason: preAddResult.reason?.message ?? 'no reason provided',
|
|
410
|
+
});
|
|
411
|
+
return 'ignored';
|
|
412
|
+
}
|
|
413
|
+
return 'accepted';
|
|
344
414
|
}
|
|
345
415
|
|
|
346
416
|
async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
|
|
347
417
|
const slotNumber = block.globalVariables.slotNumber;
|
|
348
418
|
|
|
419
|
+
// Precompute setup-call allow-list flags outside the store transaction
|
|
420
|
+
const allowedFlags = await Promise.all(txs.map(tx => this.#checkAllowedSetupCalls(tx)));
|
|
421
|
+
|
|
349
422
|
await this.#store.transactionAsync(async () => {
|
|
350
|
-
for (
|
|
423
|
+
for (let i = 0; i < txs.length; i++) {
|
|
424
|
+
const tx = txs[i];
|
|
351
425
|
const txHash = tx.getTxHash();
|
|
352
426
|
const txHashStr = txHash.toString();
|
|
353
427
|
const isNew = !this.#indices.has(txHashStr);
|
|
354
428
|
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
355
429
|
|
|
356
430
|
if (isNew) {
|
|
431
|
+
const meta = await buildTxMetaData(tx, allowedFlags[i]);
|
|
357
432
|
// New tx - add as mined or protected (callback emitted by #addTx)
|
|
358
433
|
if (minedBlockId) {
|
|
359
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
434
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
360
435
|
this.#indices.setProtection(txHashStr, slotNumber);
|
|
361
436
|
} else {
|
|
362
|
-
await this.#addTx(tx, { protected: slotNumber }, opts);
|
|
437
|
+
await this.#addTx(tx, { protected: slotNumber }, opts, meta);
|
|
363
438
|
}
|
|
364
439
|
} else {
|
|
365
440
|
// Existing tx - update protection and mined status
|
|
@@ -479,6 +554,10 @@ export class TxPoolV2Impl {
|
|
|
479
554
|
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
480
555
|
});
|
|
481
556
|
|
|
557
|
+
if (found.length > 0) {
|
|
558
|
+
this.#callbacks.onTxsMined(found.map(m => m.txHash));
|
|
559
|
+
}
|
|
560
|
+
|
|
482
561
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
483
562
|
}
|
|
484
563
|
|
|
@@ -598,28 +677,29 @@ export class TxPoolV2Impl {
|
|
|
598
677
|
// Step 1: Find mined txs at or before finalized block
|
|
599
678
|
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
600
679
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
680
|
+
// Step 2: Archive in chunks if archiving is enabled. Hydrating an entire epoch's worth of
|
|
681
|
+
// mined txs at once would OOM under load. When archiving is disabled there is no need to hydrate the txs at all.
|
|
682
|
+
if (this.#archive.isEnabled()) {
|
|
683
|
+
for (let i = 0; i < minedTxsToFinalize.length; i += FINALIZE_BLOCK_CHUNK_SIZE) {
|
|
684
|
+
const chunk = minedTxsToFinalize.slice(i, i + FINALIZE_BLOCK_CHUNK_SIZE);
|
|
685
|
+
const txsToArchive: Tx[] = [];
|
|
686
|
+
for (const txHashStr of chunk) {
|
|
606
687
|
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
607
688
|
if (buffer) {
|
|
608
689
|
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
609
690
|
}
|
|
610
691
|
}
|
|
692
|
+
if (txsToArchive.length > 0) {
|
|
693
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
694
|
+
}
|
|
611
695
|
}
|
|
696
|
+
}
|
|
612
697
|
|
|
613
|
-
|
|
698
|
+
// Step 3: Delete mined txs from the active pool and finalize soft-deleted txs in one
|
|
699
|
+
// transaction. Only tx hashes are touched here, so memory is bounded and atomicity is preserved.
|
|
700
|
+
await this.#store.transactionAsync(async () => {
|
|
614
701
|
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
615
|
-
|
|
616
|
-
// Step 4: Finalize soft-deleted txs
|
|
617
702
|
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
618
|
-
|
|
619
|
-
// Step 5: Archive mined txs
|
|
620
|
-
if (txsToArchive.length > 0) {
|
|
621
|
-
await this.#archive.archiveTxs(txsToArchive);
|
|
622
|
-
}
|
|
623
703
|
});
|
|
624
704
|
|
|
625
705
|
if (minedTxsToFinalize.length > 0) {
|
|
@@ -765,9 +845,10 @@ export class TxPoolV2Impl {
|
|
|
765
845
|
tx: Tx,
|
|
766
846
|
state: 'pending' | { protected: SlotNumber } | { mined: L2BlockId },
|
|
767
847
|
opts: { source?: string } = {},
|
|
848
|
+
precomputedMeta?: TxMetaData,
|
|
768
849
|
): Promise<TxMetaData> {
|
|
769
850
|
const txHashStr = tx.getTxHash().toString();
|
|
770
|
-
const meta = await buildTxMetaData(tx);
|
|
851
|
+
const meta = precomputedMeta ?? (await buildTxMetaData(tx));
|
|
771
852
|
meta.receivedAt = this.#dateProvider.now();
|
|
772
853
|
|
|
773
854
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
@@ -824,21 +905,11 @@ export class TxPoolV2Impl {
|
|
|
824
905
|
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
825
906
|
for (const txHashStr of txHashes) {
|
|
826
907
|
this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
|
|
827
|
-
this.#
|
|
908
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
828
909
|
}
|
|
829
910
|
await this.#deleteTxsBatch(txHashes);
|
|
830
911
|
}
|
|
831
912
|
|
|
832
|
-
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
|
|
833
|
-
#addToEvictedCache(txHashStr: string): void {
|
|
834
|
-
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
835
|
-
// FIFO eviction: remove the first (oldest) entry
|
|
836
|
-
const oldest = this.#evictedTxHashes.values().next().value!;
|
|
837
|
-
this.#evictedTxHashes.delete(oldest);
|
|
838
|
-
}
|
|
839
|
-
this.#evictedTxHashes.add(txHashStr);
|
|
840
|
-
}
|
|
841
|
-
|
|
842
913
|
// ============================================================================
|
|
843
914
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
844
915
|
// ============================================================================
|
|
@@ -933,50 +1004,6 @@ export class TxPoolV2Impl {
|
|
|
933
1004
|
};
|
|
934
1005
|
}
|
|
935
1006
|
|
|
936
|
-
/** Loads all transactions from the database, returning loaded txs and deserialization errors */
|
|
937
|
-
async #loadAllTxsFromDb(): Promise<{
|
|
938
|
-
loaded: { tx: Tx; meta: TxMetaData }[];
|
|
939
|
-
errors: string[];
|
|
940
|
-
}> {
|
|
941
|
-
const loaded: { tx: Tx; meta: TxMetaData }[] = [];
|
|
942
|
-
const errors: string[] = [];
|
|
943
|
-
|
|
944
|
-
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
945
|
-
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
946
|
-
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
947
|
-
continue;
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
try {
|
|
951
|
-
const tx = Tx.fromBuffer(buffer);
|
|
952
|
-
const meta = await buildTxMetaData(tx);
|
|
953
|
-
loaded.push({ tx, meta });
|
|
954
|
-
} catch (err) {
|
|
955
|
-
this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
|
|
956
|
-
errors.push(txHashStr);
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
return { loaded, errors };
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
/** Queries block source and marks mined status on transaction metadata */
|
|
964
|
-
async #markMinedStatusBatch(metas: TxMetaData[]): Promise<void> {
|
|
965
|
-
for (const meta of metas) {
|
|
966
|
-
try {
|
|
967
|
-
const txEffect = await this.#l2BlockSource.getTxEffect(TxHash.fromString(meta.txHash));
|
|
968
|
-
if (txEffect) {
|
|
969
|
-
meta.minedL2BlockId = {
|
|
970
|
-
number: txEffect.l2BlockNumber,
|
|
971
|
-
hash: txEffect.l2BlockHash.toString(),
|
|
972
|
-
};
|
|
973
|
-
}
|
|
974
|
-
} catch (err) {
|
|
975
|
-
this.#log.warn(`Failed to check mined status for tx ${meta.txHash}`, { err });
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
|
|
980
1007
|
/**
|
|
981
1008
|
* Rebuilds the pending pool by processing each tx through pre-add rules.
|
|
982
1009
|
* Starts with an empty pending pool and adds txs one by one, resolving conflicts.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Attestation Validation
|
|
2
|
+
|
|
3
|
+
This module validates `CheckpointAttestation` gossipsub messages. Attestations are signatures from committee members endorsing a checkpoint proposal.
|
|
4
|
+
|
|
5
|
+
**Topic**: `checkpoint_attestation` | **Snappy size limit**: 5 KB
|
|
6
|
+
|
|
7
|
+
## Stage 1: AttestationValidator (Gossipsub Validation)
|
|
8
|
+
|
|
9
|
+
| # | Rule | Consequence | Severity | File |
|
|
10
|
+
|---|------|-------------|----------|------|
|
|
11
|
+
| 1 | **Slot timeliness**: `currentSlot` or `nextSlot`. Previous slot within 500ms: IGNORE. Older: REJECT. | REJECT or IGNORE | HighToleranceError | `attestation_validator.ts` |
|
|
12
|
+
| 2 | **Attester signature**: `getSender()` must recover valid address | REJECT | LowToleranceError | same |
|
|
13
|
+
| 3 | **Attester in committee**: recovered address in committee for slot | REJECT | HighToleranceError | same |
|
|
14
|
+
| 4 | **Proposer exists**: `getProposerAttesterAddressInSlot` must return defined | REJECT | HighToleranceError | same |
|
|
15
|
+
| 5 | **Proposer signature**: `getProposer()` must recover valid address | REJECT | LowToleranceError | same |
|
|
16
|
+
| 6 | **Proposer matches expected**: recovered proposer = expected for slot | REJECT | HighToleranceError | same |
|
|
17
|
+
| 7 | **NoCommitteeError**: committee unavailable | REJECT | LowToleranceError | same |
|
|
18
|
+
|
|
19
|
+
**Fisherman mode extension** (`FishermanAttestationValidator`): if a checkpoint proposal for the same archive exists in pool, the attestation's `ConsensusPayload` must `.equals()` the stored proposal's payload. On mismatch: REJECT + LowToleranceError.
|
|
20
|
+
|
|
21
|
+
## Stage 2: Pool Admission
|
|
22
|
+
|
|
23
|
+
| # | Rule | Consequence |
|
|
24
|
+
|---|------|-------------|
|
|
25
|
+
| 8 | Sender recoverable (pool-side) | Silent drop |
|
|
26
|
+
| 9 | Not a duplicate (same slot + proposalId + signer) | IGNORE |
|
|
27
|
+
| 10 | Per-signer cap: `MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER` = 2 | IGNORE |
|
|
28
|
+
|
|
29
|
+
Own attestations added via `addOwnCheckpointAttestations` bypass the per-signer cap.
|
|
30
|
+
|
|
31
|
+
## Stage 3: Equivocation Detection
|
|
32
|
+
|
|
33
|
+
When a signer's attestation count for a slot reaches exactly 2 (different proposals): `duplicateAttestationCallback` fires -> `WANT_TO_SLASH_EVENT` with `OffenseType.DUPLICATE_ATTESTATION`. Attestation still ACCEPTED and rebroadcast. Callback fires once (not again at count 3+).
|
|
34
|
+
|
|
35
|
+
## Validation at L1 Checkpoint Submission (Archiver)
|
|
36
|
+
|
|
37
|
+
| Rule | Consequence | File |
|
|
38
|
+
|------|-------------|------|
|
|
39
|
+
| Each attestation must have recoverable signature (or address-only is allowed but does not count toward quorum) | Checkpoint rejected as invalid | `archiver/src/modules/validation.ts` |
|
|
40
|
+
| Attestation at index `i` must correspond to committee member at index `i` | Checkpoint rejected as invalid | same |
|
|
41
|
+
| Valid attestation count >= floor(committee * 2/3) + 1 | Checkpoint rejected as invalid | same |
|
|
42
|
+
| No committee / escape hatch open | Accepted unconditionally | same |
|
|
43
|
+
|
|
44
|
+
Note: `skipValidateCheckpointAttestations` config flag bypasses all archiver attestation validation.
|
|
45
|
+
|
|
46
|
+
## Gossipsub Topic Scoring
|
|
47
|
+
|
|
48
|
+
P3 enabled with expected messages per slot = `targetCommitteeSize`. Conservative threshold (30% of convergence value). Max P3 penalty = -34 per topic.
|
|
49
|
+
|