@aztec/p2p 0.0.1-commit.993d52e → 0.0.1-commit.9a89641
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 +5 -4
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +39 -16
- package/dest/client/interface.d.ts +52 -12
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +34 -19
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +120 -73
- package/dest/config.d.ts +160 -110
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +139 -49
- 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/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 +101 -59
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +274 -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 +224 -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 +12 -5
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +38 -17
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +1 -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 +1 -7
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +6 -6
- 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 +5 -4
- 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 +3 -1
- 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 +64 -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 +3 -4
- 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 +6 -7
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +1 -1
- 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 +6 -5
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +41 -9
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +3 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +17 -8
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +20 -7
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +15 -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 +55 -41
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +12 -4
- 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 +23 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +17 -3
- 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 +234 -120
- 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 +11 -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 +11 -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 +35 -10
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +128 -56
- 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 +25 -7
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +55 -16
- 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 +53 -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/timestamp_validator.js +1 -1
- 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 +15 -15
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +15 -16
- package/dest/services/encoding.d.ts +23 -6
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +32 -16
- package/dest/services/gossipsub/topic_score_params.d.ts +6 -12
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +4 -14
- 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 +46 -47
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +460 -320
- 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 +20 -3
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +83 -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 +4 -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 +94 -122
- 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 +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 +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/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 +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 +31 -28
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +12 -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 +42 -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 +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 +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 +75 -216
- package/dest/services/service.d.ts +29 -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 +13 -8
- 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 +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +5 -2
- package/dest/test-helpers/mock-pubsub.d.ts +23 -9
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +44 -44
- package/dest/test-helpers/reqresp-nodes.d.ts +4 -5
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +16 -18
- 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 +15 -14
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +51 -16
- 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 +104 -41
- 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 -16
- package/src/bootstrap/bootstrap.ts +17 -3
- package/src/client/factory.ts +62 -9
- package/src/client/interface.ts +48 -18
- package/src/client/p2p_client.ts +140 -106
- package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
- package/src/config.ts +241 -57
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/errors/reqresp.error.ts +13 -19
- package/src/index.ts +0 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +329 -243
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +244 -69
- package/src/mem_pools/attestation_pool/mocks.ts +13 -8
- package/src/mem_pools/index.ts +0 -3
- package/src/mem_pools/instrumentation.ts +27 -17
- package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +7 -7
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +4 -5
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -2
- 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 +67 -0
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +1 -3
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -7
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +5 -6
- package/src/mem_pools/tx_pool_v2/interfaces.ts +40 -8
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +35 -13
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +62 -41
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +36 -7
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +260 -124
- 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 +150 -58
- package/src/msg_validators/tx_validator/README.md +17 -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 +66 -9
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +117 -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/timestamp_validator.ts +1 -1
- 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 +20 -39
- package/src/services/encoding.ts +35 -19
- package/src/services/gossipsub/README.md +33 -11
- package/src/services/gossipsub/topic_score_params.ts +9 -18
- package/src/services/libp2p/instrumentation.ts +14 -0
- package/src/services/libp2p/libp2p_service.ts +508 -358
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +91 -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 +91 -137
- 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 +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 +21 -47
- 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 +34 -30
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -20
- 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 +3 -13
- package/src/services/reqresp/reqresp.ts +87 -260
- package/src/services/service.ts +35 -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 +10 -8
- 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 -1
- package/src/test-helpers/mock-pubsub.ts +46 -60
- package/src/test-helpers/reqresp-nodes.ts +13 -23
- package/src/test-helpers/test_tx_provider.ts +5 -0
- package/src/test-helpers/testbench-utils.ts +64 -28
- package/src/testbench/p2p_client_testbench_worker.ts +111 -57
- 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 -304
- 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 -24
- 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 -378
- 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 -345
- 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 -373
- 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,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,28 @@ 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
|
*/
|
|
54
|
+
/** A tx that has just transitioned to mined, with the time it spent in the pool. */
|
|
55
|
+
export interface MinedTxInfo {
|
|
56
|
+
txHash: string;
|
|
57
|
+
/** Wall-clock ms from receipt into the pool to being marked mined. Undefined when the
|
|
58
|
+
* receive time is unknown (e.g. a tx hydrated from the DB on restart, receivedAt === 0). */
|
|
59
|
+
minedDelayMs?: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
45
62
|
export interface TxPoolV2Callbacks {
|
|
46
63
|
onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
|
|
47
64
|
onTxsRemoved: (txHashes: string[] | bigint[]) => void;
|
|
65
|
+
onTxsMined: (minedTxs: MinedTxInfo[]) => void;
|
|
48
66
|
}
|
|
49
67
|
|
|
50
68
|
/**
|
|
@@ -55,12 +73,16 @@ export interface TxPoolV2Callbacks {
|
|
|
55
73
|
export class TxPoolV2Impl {
|
|
56
74
|
// === Persistence ===
|
|
57
75
|
#store: AztecAsyncKVStore;
|
|
76
|
+
/** Tx data without its proof. Proofs live in #proofsDB so a tx can be read without loading its proof. */
|
|
58
77
|
#txsDB: AztecAsyncMap<string, Buffer>;
|
|
78
|
+
/** Tx proofs, keyed by tx hash. Written and deleted in lockstep with #txsDB. */
|
|
79
|
+
#proofsDB: AztecAsyncMap<string, Buffer>;
|
|
59
80
|
|
|
60
81
|
// === Dependencies ===
|
|
61
82
|
#l2BlockSource: L2BlockSource;
|
|
62
83
|
#worldStateSynchronizer: WorldStateSynchronizer;
|
|
63
84
|
#createTxValidator: TxPoolV2Dependencies['createTxValidator'];
|
|
85
|
+
#checkAllowedSetupCalls: TxPoolV2Dependencies['checkAllowedSetupCalls'];
|
|
64
86
|
|
|
65
87
|
// === In-Memory Indices ===
|
|
66
88
|
#indices: TxPoolIndices = new TxPoolIndices();
|
|
@@ -72,7 +94,7 @@ export class TxPoolV2Impl {
|
|
|
72
94
|
#evictionManager: EvictionManager;
|
|
73
95
|
#dateProvider: DateProvider;
|
|
74
96
|
#instrumentation: TxPoolV2Instrumentation;
|
|
75
|
-
#evictedTxHashes:
|
|
97
|
+
#evictedTxHashes: FifoSet<string>;
|
|
76
98
|
#log: Logger;
|
|
77
99
|
#callbacks: TxPoolV2Callbacks;
|
|
78
100
|
|
|
@@ -88,14 +110,17 @@ export class TxPoolV2Impl {
|
|
|
88
110
|
) {
|
|
89
111
|
this.#store = store;
|
|
90
112
|
this.#txsDB = store.openMap('txs');
|
|
113
|
+
this.#proofsDB = store.openMap('tx_proofs');
|
|
91
114
|
|
|
92
115
|
this.#l2BlockSource = deps.l2BlockSource;
|
|
93
116
|
this.#worldStateSynchronizer = deps.worldStateSynchronizer;
|
|
94
117
|
this.#createTxValidator = deps.createTxValidator;
|
|
118
|
+
this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
|
|
95
119
|
|
|
96
120
|
this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
|
|
121
|
+
this.#evictedTxHashes = FifoSet.withLimit<string>(this.#config.evictedTxCacheSize);
|
|
97
122
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
98
|
-
this.#deletedPool = new DeletedPool(store, this.#
|
|
123
|
+
this.#deletedPool = new DeletedPool(store, txHashStr => this.#deleteTxData(txHashStr), log);
|
|
99
124
|
this.#dateProvider = dateProvider;
|
|
100
125
|
this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
|
|
101
126
|
this.#log = log;
|
|
@@ -113,6 +138,7 @@ export class TxPoolV2Impl {
|
|
|
113
138
|
|
|
114
139
|
// Post-event eviction rules (run after events to check ALL pending txs)
|
|
115
140
|
this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
|
|
141
|
+
this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
|
|
116
142
|
this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
|
|
117
143
|
this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
|
|
118
144
|
// LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
|
|
@@ -135,46 +161,74 @@ export class TxPoolV2Impl {
|
|
|
135
161
|
// Step 0: Hydrate deleted pool state
|
|
136
162
|
await this.#deletedPool.hydrateFromDatabase();
|
|
137
163
|
|
|
138
|
-
// Step 1:
|
|
139
|
-
const
|
|
164
|
+
// Step 1: Stream txs from DB, building metadata and mined status one at a time.
|
|
165
|
+
const minedMetas: TxMetaData[] = [];
|
|
166
|
+
const pendingMetas: TxMetaData[] = [];
|
|
167
|
+
const deserializationErrors: string[] = [];
|
|
168
|
+
|
|
169
|
+
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
170
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
171
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let meta: TxMetaData;
|
|
176
|
+
let txEffect: Awaited<ReturnType<L2BlockSource['getTxEffect']>>;
|
|
177
|
+
try {
|
|
178
|
+
const tx = Tx.fromBuffer(buffer);
|
|
179
|
+
// Resolve allowed-setup-calls and the tx effect concurrently
|
|
180
|
+
// getTxEffect failures are non-fatal (we just treat the tx as not-yet-mined), so
|
|
181
|
+
// its rejection is swallowed before the Promise.all so it can't fail-fast the batch.
|
|
182
|
+
const txEffectPromise = this.#l2BlockSource.getTxEffect(tx.getTxHash()).catch(err => {
|
|
183
|
+
this.#log.warn(`Failed to check mined status for tx ${txHashStr}`, { err });
|
|
184
|
+
return undefined;
|
|
185
|
+
});
|
|
186
|
+
const [allowedSetupCalls, fetchedTxEffect] = await Promise.all([
|
|
187
|
+
this.#checkAllowedSetupCalls(tx),
|
|
188
|
+
txEffectPromise,
|
|
189
|
+
]);
|
|
190
|
+
meta = await buildTxMetaData(tx, allowedSetupCalls);
|
|
191
|
+
txEffect = fetchedTxEffect;
|
|
192
|
+
} catch (err) {
|
|
193
|
+
this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
|
|
194
|
+
deserializationErrors.push(txHashStr);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
140
197
|
|
|
141
|
-
|
|
142
|
-
|
|
198
|
+
if (txEffect) {
|
|
199
|
+
meta.minedL2BlockId = {
|
|
200
|
+
number: txEffect.l2BlockNumber,
|
|
201
|
+
hash: txEffect.l2BlockHash.toString(),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
143
204
|
|
|
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);
|
|
205
|
+
if (meta.minedL2BlockId !== undefined) {
|
|
206
|
+
minedMetas.push(meta);
|
|
150
207
|
} else {
|
|
151
|
-
|
|
208
|
+
pendingMetas.push(meta);
|
|
152
209
|
}
|
|
153
210
|
}
|
|
154
211
|
|
|
155
|
-
// Step
|
|
156
|
-
const { valid, invalid } = await this.#revalidateMetadata(
|
|
157
|
-
nonMined.map(e => e.meta),
|
|
158
|
-
'on startup',
|
|
159
|
-
);
|
|
212
|
+
// Step 2: Validate non-mined transactions
|
|
213
|
+
const { valid, invalid } = await this.#revalidateMetadata(pendingMetas, 'on startup');
|
|
160
214
|
|
|
161
|
-
// Step
|
|
162
|
-
for (const meta of
|
|
215
|
+
// Step 3: Populate mined indices (these don't need conflict resolution)
|
|
216
|
+
for (const meta of minedMetas) {
|
|
163
217
|
this.#indices.addMined(meta);
|
|
164
218
|
}
|
|
165
219
|
|
|
166
|
-
// Step
|
|
220
|
+
// Step 4: Rebuild pending pool by running pre-add rules for each tx
|
|
167
221
|
// This resolves nullifier conflicts, fee payer balance issues, and pool size limits
|
|
168
222
|
const { rejected } = await this.#rebuildPendingPool(valid);
|
|
169
223
|
|
|
170
|
-
// Step
|
|
224
|
+
// Step 5: Delete invalid and rejected txs from DB only (indices were never populated for these)
|
|
171
225
|
const toDelete = [...deserializationErrors, ...invalid, ...rejected];
|
|
172
226
|
if (toDelete.length === 0) {
|
|
173
227
|
return;
|
|
174
228
|
}
|
|
175
229
|
await this.#store.transactionAsync(async () => {
|
|
176
230
|
for (const txHashStr of toDelete) {
|
|
177
|
-
await this.#
|
|
231
|
+
await this.#deleteTxData(txHashStr);
|
|
178
232
|
}
|
|
179
233
|
});
|
|
180
234
|
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
|
|
@@ -337,6 +391,12 @@ export class TxPoolV2Impl {
|
|
|
337
391
|
}
|
|
338
392
|
}
|
|
339
393
|
|
|
394
|
+
// Randomly drop the transaction for testing purposes (report as accepted so it propagates)
|
|
395
|
+
if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
|
|
396
|
+
this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
|
|
397
|
+
return { status: 'accepted' };
|
|
398
|
+
}
|
|
399
|
+
|
|
340
400
|
// Add the transaction
|
|
341
401
|
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
342
402
|
return { status: 'accepted' };
|
|
@@ -347,6 +407,7 @@ export class TxPoolV2Impl {
|
|
|
347
407
|
|
|
348
408
|
// Check if already in pool
|
|
349
409
|
if (this.#indices.has(txHashStr)) {
|
|
410
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
|
|
350
411
|
return 'ignored';
|
|
351
412
|
}
|
|
352
413
|
|
|
@@ -355,26 +416,37 @@ export class TxPoolV2Impl {
|
|
|
355
416
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
356
417
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
357
418
|
|
|
358
|
-
|
|
419
|
+
if (preAddResult.shouldIgnore) {
|
|
420
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
|
|
421
|
+
reason: preAddResult.reason?.message ?? 'no reason provided',
|
|
422
|
+
});
|
|
423
|
+
return 'ignored';
|
|
424
|
+
}
|
|
425
|
+
return 'accepted';
|
|
359
426
|
}
|
|
360
427
|
|
|
361
428
|
async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
|
|
362
429
|
const slotNumber = block.globalVariables.slotNumber;
|
|
363
430
|
|
|
431
|
+
// Precompute setup-call allow-list flags outside the store transaction
|
|
432
|
+
const allowedFlags = await Promise.all(txs.map(tx => this.#checkAllowedSetupCalls(tx)));
|
|
433
|
+
|
|
364
434
|
await this.#store.transactionAsync(async () => {
|
|
365
|
-
for (
|
|
435
|
+
for (let i = 0; i < txs.length; i++) {
|
|
436
|
+
const tx = txs[i];
|
|
366
437
|
const txHash = tx.getTxHash();
|
|
367
438
|
const txHashStr = txHash.toString();
|
|
368
439
|
const isNew = !this.#indices.has(txHashStr);
|
|
369
440
|
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
370
441
|
|
|
371
442
|
if (isNew) {
|
|
443
|
+
const meta = await buildTxMetaData(tx, allowedFlags[i]);
|
|
372
444
|
// New tx - add as mined or protected (callback emitted by #addTx)
|
|
373
445
|
if (minedBlockId) {
|
|
374
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
446
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
375
447
|
this.#indices.setProtection(txHashStr, slotNumber);
|
|
376
448
|
} else {
|
|
377
|
-
await this.#addTx(tx, { protected: slotNumber }, opts);
|
|
449
|
+
await this.#addTx(tx, { protected: slotNumber }, opts, meta);
|
|
378
450
|
}
|
|
379
451
|
} else {
|
|
380
452
|
// Existing tx - update protection and mined status
|
|
@@ -402,10 +474,11 @@ export class TxPoolV2Impl {
|
|
|
402
474
|
// Update protection for existing tx
|
|
403
475
|
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
404
476
|
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
405
|
-
// Resurrect soft-deleted tx as protected
|
|
477
|
+
// Resurrect soft-deleted tx as protected. Load the proof too: #addTx rewrites both entries, so re-adding
|
|
478
|
+
// a proofless tx would wipe the stored proof.
|
|
406
479
|
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
407
480
|
if (buffer) {
|
|
408
|
-
const tx =
|
|
481
|
+
const tx = await this.#loadTxWithProof(txHashStr, buffer);
|
|
409
482
|
await this.#addTx(tx, { protected: slotNumber });
|
|
410
483
|
softDeletedHits++;
|
|
411
484
|
} else {
|
|
@@ -494,6 +567,18 @@ export class TxPoolV2Impl {
|
|
|
494
567
|
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
495
568
|
});
|
|
496
569
|
|
|
570
|
+
if (found.length > 0) {
|
|
571
|
+
// receivedAt is 0 for txs hydrated from the DB on restart (true receive time lost) — leave
|
|
572
|
+
// their delay undefined so the metric isn't polluted by epoch-sized values.
|
|
573
|
+
const now = this.#dateProvider.now();
|
|
574
|
+
this.#callbacks.onTxsMined(
|
|
575
|
+
found.map(m => ({
|
|
576
|
+
txHash: m.txHash,
|
|
577
|
+
minedDelayMs: m.receivedAt > 0 ? now - m.receivedAt : undefined,
|
|
578
|
+
})),
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
|
|
497
582
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
498
583
|
}
|
|
499
584
|
|
|
@@ -516,29 +601,62 @@ export class TxPoolV2Impl {
|
|
|
516
601
|
}
|
|
517
602
|
|
|
518
603
|
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
604
|
+
await this.#restoreUnprotectedToPending(txsToRestore, 'during prepareForSlot');
|
|
605
|
+
});
|
|
606
|
+
}
|
|
519
607
|
|
|
520
|
-
|
|
521
|
-
|
|
608
|
+
async unprotectTxs(txHashes: TxHash[], slotNumber: SlotNumber): Promise<void> {
|
|
609
|
+
const hashStrs = txHashes.map(h => h.toString());
|
|
522
610
|
|
|
523
|
-
|
|
524
|
-
|
|
611
|
+
await this.#store.transactionAsync(async () => {
|
|
612
|
+
// Only release entries still recorded at this exact slot. A tx that another, still-live proposal
|
|
613
|
+
// raised to a higher slot via updateProtection must keep that protection. Mined txs have no
|
|
614
|
+
// protection entry and so are never matched here.
|
|
615
|
+
const matching = this.#indices.findProtectedTxsAtSlot(hashStrs, slotNumber);
|
|
616
|
+
if (matching.length === 0) {
|
|
617
|
+
this.#log.debug(`Unprotecting txs for slot ${slotNumber}: no matching protections to release`);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
525
620
|
|
|
526
|
-
|
|
527
|
-
await this.#deleteTxsBatch(invalid);
|
|
528
|
-
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
621
|
+
this.#indices.clearProtection(matching);
|
|
529
622
|
|
|
530
|
-
|
|
531
|
-
if (
|
|
532
|
-
|
|
533
|
-
const uniqueFeePayers = new Set<string>(feePayers);
|
|
534
|
-
await this.#evictionManager.evictAfterNewTxs(
|
|
535
|
-
added.map(m => m.txHash),
|
|
536
|
-
[...uniqueFeePayers],
|
|
537
|
-
);
|
|
623
|
+
const txsToRestore = this.#indices.filterRestorable(matching);
|
|
624
|
+
if (txsToRestore.length === 0) {
|
|
625
|
+
return;
|
|
538
626
|
}
|
|
627
|
+
|
|
628
|
+
this.#log.info(`Unprotecting ${txsToRestore.length} txs from failed proposal at slot ${slotNumber}`);
|
|
629
|
+
await this.#restoreUnprotectedToPending(txsToRestore, 'during unprotectTxs');
|
|
539
630
|
});
|
|
540
631
|
}
|
|
541
632
|
|
|
633
|
+
/**
|
|
634
|
+
* Returns just-unprotected txs to the pending pool: revalidates them, resolves nullifier
|
|
635
|
+
* conflicts, deletes losers, then enforces the pool size limit. Must run inside a store
|
|
636
|
+
* transaction; callers clear the protection entries before invoking.
|
|
637
|
+
*/
|
|
638
|
+
async #restoreUnprotectedToPending(txsToRestore: TxMetaData[], context: string): Promise<void> {
|
|
639
|
+
// Step 1: Validate for pending pool
|
|
640
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, context);
|
|
641
|
+
|
|
642
|
+
// Step 2: Resolve nullifier conflicts and add winners to pending indices
|
|
643
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
644
|
+
|
|
645
|
+
// Step 3: Delete invalid txs and evict conflict losers
|
|
646
|
+
await this.#deleteTxsBatch(invalid);
|
|
647
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
648
|
+
|
|
649
|
+
// Step 4: Run eviction rules (enforce pool size limit)
|
|
650
|
+
if (added.length > 0) {
|
|
651
|
+
const feePayers = added.map(meta => meta.feePayer);
|
|
652
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
653
|
+
await this.#evictionManager.evictAfterNewTxs(
|
|
654
|
+
added.map(m => m.txHash),
|
|
655
|
+
[...uniqueFeePayers],
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
542
660
|
async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
|
|
543
661
|
// Step 1: Find transactions mined after the prune point
|
|
544
662
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
@@ -610,56 +728,113 @@ export class TxPoolV2Impl {
|
|
|
610
728
|
async handleFinalizedBlock(block: BlockHeader): Promise<void> {
|
|
611
729
|
const blockNumber = block.globalVariables.blockNumber;
|
|
612
730
|
|
|
613
|
-
//
|
|
614
|
-
|
|
731
|
+
// Hold finalized txs for a configurable margin behind the finalized tip so a prover still
|
|
732
|
+
// proving an epoch with already-finalized blocks isn't starved of its txs. 0 deletes at the finalized tip.
|
|
733
|
+
const cutoffBlock = await this.#finalizationCutoffBlock(block);
|
|
615
734
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
735
|
+
// Step 1: Find mined txs at or before the cutoff block
|
|
736
|
+
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(cutoffBlock);
|
|
737
|
+
|
|
738
|
+
// Step 2: Archive in chunks if archiving is enabled. Hydrating an entire epoch's worth of
|
|
739
|
+
// mined txs at once would OOM under load. When archiving is disabled there is no need to hydrate the txs at all.
|
|
740
|
+
if (this.#archive.isEnabled()) {
|
|
741
|
+
for (let i = 0; i < minedTxsToFinalize.length; i += FINALIZE_BLOCK_CHUNK_SIZE) {
|
|
742
|
+
const chunk = minedTxsToFinalize.slice(i, i + FINALIZE_BLOCK_CHUNK_SIZE);
|
|
743
|
+
const txsToArchive: Tx[] = [];
|
|
744
|
+
for (const txHashStr of chunk) {
|
|
621
745
|
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
622
746
|
if (buffer) {
|
|
623
747
|
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
624
748
|
}
|
|
625
749
|
}
|
|
750
|
+
if (txsToArchive.length > 0) {
|
|
751
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
752
|
+
}
|
|
626
753
|
}
|
|
754
|
+
}
|
|
627
755
|
|
|
628
|
-
|
|
756
|
+
// Step 3: Delete mined txs from the active pool and finalize soft-deleted txs in one
|
|
757
|
+
// transaction. Only tx hashes are touched here, so memory is bounded and atomicity is preserved.
|
|
758
|
+
await this.#store.transactionAsync(async () => {
|
|
629
759
|
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
630
|
-
|
|
631
|
-
// Step 4: Finalize soft-deleted txs
|
|
632
|
-
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
633
|
-
|
|
634
|
-
// Step 5: Archive mined txs
|
|
635
|
-
if (txsToArchive.length > 0) {
|
|
636
|
-
await this.#archive.archiveTxs(txsToArchive);
|
|
637
|
-
}
|
|
760
|
+
await this.#deletedPool.finalizeBlock(cutoffBlock);
|
|
638
761
|
});
|
|
639
762
|
|
|
640
763
|
if (minedTxsToFinalize.length > 0) {
|
|
641
|
-
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${
|
|
764
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${cutoffBlock}`, {
|
|
642
765
|
txHashes: minedTxsToFinalize,
|
|
766
|
+
finalizedBlockNumber: blockNumber,
|
|
767
|
+
cutoffBlock,
|
|
643
768
|
});
|
|
644
769
|
}
|
|
645
770
|
}
|
|
646
771
|
|
|
772
|
+
/**
|
|
773
|
+
* Resolves the block up to which finalized txs may be deleted, given `keepFinalizedTxsForSlots`.
|
|
774
|
+
* With a margin of 0 this is just the finalized block. Otherwise we keep txs whose block is within
|
|
775
|
+
* the margin (in slots) of the finalized tip: take the target slot `finalizedSlot - margin`, find the
|
|
776
|
+
* latest checkpoint at or before it with a single reverse range query (`limit: 1`), and use that
|
|
777
|
+
* checkpoint's last block as the cutoff. This rounds to a checkpoint boundary, so it can retain slightly
|
|
778
|
+
* more than the configured margin but never less, and never deletes past the finalized block.
|
|
779
|
+
*/
|
|
780
|
+
async #finalizationCutoffBlock(block: BlockHeader): Promise<BlockNumber> {
|
|
781
|
+
const keepSlots = this.#config.keepFinalizedTxsForSlots;
|
|
782
|
+
if (keepSlots <= 0) {
|
|
783
|
+
return block.globalVariables.blockNumber;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// The goal here really is to ensure we keep transactions long enough for them to be proven.
|
|
787
|
+
// So we could be smart and calculate the number of slots until the end of the proof submission window.
|
|
788
|
+
// Our approach here is a lot simpler however and we just keep transactions for the configured number
|
|
789
|
+
// of slots past L1 finalisation. This means we may keep transactions in the mined pool for longer
|
|
790
|
+
// than strictly necessary.
|
|
791
|
+
const targetSlot = block.getSlot() - keepSlots;
|
|
792
|
+
if (targetSlot < 0) {
|
|
793
|
+
// The margin reaches past genesis: keep everything.
|
|
794
|
+
return BlockNumber(0);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
const [checkpoint] = await this.#l2BlockSource.getCheckpointsData({
|
|
798
|
+
fromSlot: SlotNumber(targetSlot),
|
|
799
|
+
limit: 1,
|
|
800
|
+
reverse: true,
|
|
801
|
+
});
|
|
802
|
+
// No checkpoint at or before the target slot (e.g. early chain): keep everything.
|
|
803
|
+
return checkpoint ? BlockNumber(checkpoint.startBlock + checkpoint.blockCount - 1) : BlockNumber(0);
|
|
804
|
+
}
|
|
805
|
+
|
|
647
806
|
// === Query Methods ===
|
|
648
807
|
|
|
649
|
-
async getTxByHash(txHash: TxHash): Promise<Tx | undefined> {
|
|
650
|
-
const
|
|
651
|
-
|
|
808
|
+
async getTxByHash(txHash: TxHash, opts: { includeProof?: boolean } = {}): Promise<Tx | undefined> {
|
|
809
|
+
const txHashStr = txHash.toString();
|
|
810
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
811
|
+
if (!buffer) {
|
|
812
|
+
return undefined;
|
|
813
|
+
}
|
|
814
|
+
return opts.includeProof === false ? Tx.fromBuffer(buffer) : this.#loadTxWithProof(txHashStr, buffer);
|
|
652
815
|
}
|
|
653
816
|
|
|
654
|
-
async getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
|
|
817
|
+
async getTxsByHash(txHashes: TxHash[], opts: { includeProof?: boolean } = {}): Promise<(Tx | undefined)[]> {
|
|
655
818
|
const results: (Tx | undefined)[] = [];
|
|
656
819
|
for (const h of txHashes) {
|
|
657
|
-
|
|
658
|
-
results.push(buffer ? Tx.fromBuffer(buffer) : undefined);
|
|
820
|
+
results.push(await this.getTxByHash(h, opts));
|
|
659
821
|
}
|
|
660
822
|
return results;
|
|
661
823
|
}
|
|
662
824
|
|
|
825
|
+
/** Deserializes a tx blob loaded from #txsDB together with its separately-stored proof. */
|
|
826
|
+
async #loadTxWithProof(txHashStr: string, buffer: Buffer): Promise<Tx> {
|
|
827
|
+
const proofBuffer = await this.#proofsDB.getAsync(txHashStr);
|
|
828
|
+
if (!proofBuffer) {
|
|
829
|
+
// #addTx always writes a proof entry (an empty proof serializes to a 4-byte sentinel), so a missing entry
|
|
830
|
+
// means the blob/proof invariant is broken. Return the proofless tx but flag it, since a consumer that needs
|
|
831
|
+
// the proof (eg serving peers) would otherwise fail far away from the root cause.
|
|
832
|
+
this.#log.warn(`Missing stored proof for tx ${txHashStr}`, { txHash: txHashStr });
|
|
833
|
+
return Tx.fromBuffer(buffer);
|
|
834
|
+
}
|
|
835
|
+
return Tx.fromBuffers(buffer, proofBuffer);
|
|
836
|
+
}
|
|
837
|
+
|
|
663
838
|
hasTxs(txHashes: TxHash[]): boolean[] {
|
|
664
839
|
return txHashes.map(h => {
|
|
665
840
|
const hashStr = h.toString();
|
|
@@ -695,6 +870,11 @@ export class TxPoolV2Impl {
|
|
|
695
870
|
return this.#indices.getPendingTxCount();
|
|
696
871
|
}
|
|
697
872
|
|
|
873
|
+
hasEligiblePendingTxs(minCount: number): boolean {
|
|
874
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
875
|
+
return this.#indices.hasEligiblePendingTxs(maxReceivedAt, minCount);
|
|
876
|
+
}
|
|
877
|
+
|
|
698
878
|
getMinedTxHashes(): [TxHash, L2BlockId][] {
|
|
699
879
|
return this.#indices.getMinedTxs().map(([hash, blockId]) => [TxHash.fromString(hash), blockId]);
|
|
700
880
|
}
|
|
@@ -738,6 +918,9 @@ export class TxPoolV2Impl {
|
|
|
738
918
|
if (config.minTxPoolAgeMs !== undefined) {
|
|
739
919
|
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
740
920
|
}
|
|
921
|
+
if (config.keepFinalizedTxsForSlots !== undefined) {
|
|
922
|
+
this.#config.keepFinalizedTxsForSlots = config.keepFinalizedTxsForSlots;
|
|
923
|
+
}
|
|
741
924
|
// Update eviction rules with new config
|
|
742
925
|
this.#evictionManager.updateConfig(config);
|
|
743
926
|
}
|
|
@@ -786,7 +969,8 @@ export class TxPoolV2Impl {
|
|
|
786
969
|
const meta = precomputedMeta ?? (await buildTxMetaData(tx));
|
|
787
970
|
meta.receivedAt = this.#dateProvider.now();
|
|
788
971
|
|
|
789
|
-
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
972
|
+
await this.#txsDB.set(txHashStr, tx.withoutProof().toBuffer());
|
|
973
|
+
await this.#proofsDB.set(txHashStr, tx.chonkProof.toBuffer());
|
|
790
974
|
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
791
975
|
this.#callbacks.onTxsAdded([tx], opts);
|
|
792
976
|
|
|
@@ -825,6 +1009,12 @@ export class TxPoolV2Impl {
|
|
|
825
1009
|
await this.#deletedPool.deleteTx(txHashStr);
|
|
826
1010
|
}
|
|
827
1011
|
|
|
1012
|
+
/** Hard-deletes a tx's stored data (tx blob and proof) from the DB. */
|
|
1013
|
+
async #deleteTxData(txHashStr: string): Promise<void> {
|
|
1014
|
+
await this.#txsDB.delete(txHashStr);
|
|
1015
|
+
await this.#proofsDB.delete(txHashStr);
|
|
1016
|
+
}
|
|
1017
|
+
|
|
828
1018
|
/** Deletes a batch of transactions, emitting callbacks individually for each. */
|
|
829
1019
|
async #deleteTxsBatch(txHashes: string[]): Promise<void> {
|
|
830
1020
|
for (const txHashStr of txHashes) {
|
|
@@ -840,21 +1030,11 @@ export class TxPoolV2Impl {
|
|
|
840
1030
|
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
841
1031
|
for (const txHashStr of txHashes) {
|
|
842
1032
|
this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
|
|
843
|
-
this.#
|
|
1033
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
844
1034
|
}
|
|
845
1035
|
await this.#deleteTxsBatch(txHashes);
|
|
846
1036
|
}
|
|
847
1037
|
|
|
848
|
-
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
|
|
849
|
-
#addToEvictedCache(txHashStr: string): void {
|
|
850
|
-
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
851
|
-
// FIFO eviction: remove the first (oldest) entry
|
|
852
|
-
const oldest = this.#evictedTxHashes.values().next().value!;
|
|
853
|
-
this.#evictedTxHashes.delete(oldest);
|
|
854
|
-
}
|
|
855
|
-
this.#evictedTxHashes.add(txHashStr);
|
|
856
|
-
}
|
|
857
|
-
|
|
858
1038
|
// ============================================================================
|
|
859
1039
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
860
1040
|
// ============================================================================
|
|
@@ -949,50 +1129,6 @@ export class TxPoolV2Impl {
|
|
|
949
1129
|
};
|
|
950
1130
|
}
|
|
951
1131
|
|
|
952
|
-
/** Loads all transactions from the database, returning loaded txs and deserialization errors */
|
|
953
|
-
async #loadAllTxsFromDb(): Promise<{
|
|
954
|
-
loaded: { tx: Tx; meta: TxMetaData }[];
|
|
955
|
-
errors: string[];
|
|
956
|
-
}> {
|
|
957
|
-
const loaded: { tx: Tx; meta: TxMetaData }[] = [];
|
|
958
|
-
const errors: string[] = [];
|
|
959
|
-
|
|
960
|
-
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
961
|
-
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
962
|
-
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
963
|
-
continue;
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
try {
|
|
967
|
-
const tx = Tx.fromBuffer(buffer);
|
|
968
|
-
const meta = await buildTxMetaData(tx);
|
|
969
|
-
loaded.push({ tx, meta });
|
|
970
|
-
} catch (err) {
|
|
971
|
-
this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
|
|
972
|
-
errors.push(txHashStr);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
return { loaded, errors };
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
/** Queries block source and marks mined status on transaction metadata */
|
|
980
|
-
async #markMinedStatusBatch(metas: TxMetaData[]): Promise<void> {
|
|
981
|
-
for (const meta of metas) {
|
|
982
|
-
try {
|
|
983
|
-
const txEffect = await this.#l2BlockSource.getTxEffect(TxHash.fromString(meta.txHash));
|
|
984
|
-
if (txEffect) {
|
|
985
|
-
meta.minedL2BlockId = {
|
|
986
|
-
number: txEffect.l2BlockNumber,
|
|
987
|
-
hash: txEffect.l2BlockHash.toString(),
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
} catch (err) {
|
|
991
|
-
this.#log.warn(`Failed to check mined status for tx ${meta.txHash}`, { err });
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
|
|
996
1132
|
/**
|
|
997
1133
|
* Rebuilds the pending pool by processing each tx through pre-add rules.
|
|
998
1134
|
* Starts with an empty pending pool and adds txs one by one, resolving conflicts.
|
|
@@ -1067,7 +1203,7 @@ export class TxPoolV2Impl {
|
|
|
1067
1203
|
const publicStateSource = new DatabasePublicStateSource(db);
|
|
1068
1204
|
const balance = await publicStateSource.storageRead(
|
|
1069
1205
|
ProtocolContractAddress.FeeJuice,
|
|
1070
|
-
await computeFeePayerBalanceStorageSlot(AztecAddress.
|
|
1206
|
+
await computeFeePayerBalanceStorageSlot(AztecAddress.fromStringUnsafe(feePayer)),
|
|
1071
1207
|
);
|
|
1072
1208
|
return balance.toBigInt();
|
|
1073
1209
|
},
|
|
@@ -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
|
+
|