@aztec/p2p 0.0.1-commit.0c875d939 → 0.0.1-commit.0ec55a70b
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/client/factory.d.ts +8 -7
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +35 -30
- package/dest/client/interface.d.ts +18 -20
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +9 -19
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +81 -104
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +23 -10
- package/dest/config.d.ts +130 -103
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +97 -39
- 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/tx-pool.error.d.ts +8 -0
- package/dest/errors/tx-pool.error.d.ts.map +1 -0
- package/dest/errors/tx-pool.error.js +9 -0
- package/dest/index.d.ts +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 +7 -5
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +16 -9
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
- 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/deleted_pool.d.ts +3 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +9 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +5 -4
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +3 -2
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +2 -1
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +4 -4
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +7 -7
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +12 -6
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
- package/dest/mem_pools/tx_pool_v2/index.d.ts +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/instrumentation.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +27 -10
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +4 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +57 -15
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +115 -20
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +5 -2
- 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 +38 -46
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -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 +12 -5
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +12 -5
- 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 +297 -153
- 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 +2 -2
- 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 +9 -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 +9 -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 +19 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +88 -44
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
- package/dest/msg_validators/tx_validator/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 +24 -20
- 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/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 +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +35 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +133 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +247 -60
- 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 +99 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +137 -53
- package/dest/msg_validators/tx_validator/index.d.ts +3 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +2 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
- package/dest/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/dummy_service.d.ts +8 -5
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +10 -5
- package/dest/services/encoding.d.ts +6 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +16 -9
- package/dest/services/gossipsub/topic_score_params.d.ts +30 -7
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +53 -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 +33 -38
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +256 -213
- 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 +39 -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 +12 -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 +83 -106
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +4 -7
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -13
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +31 -46
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
- 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 +14 -9
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +10 -11
- 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/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 +4 -2
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +30 -12
- package/dest/services/service.d.ts +9 -4
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +65 -75
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.js +4 -2
- package/dest/services/tx_collection/file_store_tx_source.d.ts +16 -6
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_source.js +50 -9
- 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 +2 -1
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -7
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
- 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/slow_tx_collection.d.ts +2 -2
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +10 -8
- package/dest/services/tx_collection/tx_collection.d.ts +5 -7
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +13 -22
- package/dest/services/tx_collection/tx_source.d.ts +13 -7
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +26 -7
- package/dest/services/tx_file_store/tx_file_store.js +1 -1
- package/dest/services/tx_provider.d.ts +3 -3
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +4 -4
- 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 +4 -2
- package/dest/test-helpers/mock-pubsub.d.ts +14 -6
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +43 -12
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +6 -4
- package/dest/test-helpers/testbench-utils.d.ts +6 -3
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +24 -4
- package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +83 -26
- package/dest/testbench/worker_client_manager.d.ts +10 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +55 -3
- package/dest/util.d.ts +3 -3
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/client/factory.ts +63 -50
- package/src/client/interface.ts +20 -21
- package/src/client/p2p_client.ts +89 -135
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +35 -14
- package/src/config.ts +148 -45
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +0 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +17 -12
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
- 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 +10 -2
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +11 -0
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +5 -4
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +5 -0
- package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +4 -4
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +8 -8
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +12 -9
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
- package/src/mem_pools/tx_pool_v2/index.ts +1 -1
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +27 -10
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +166 -28
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -46
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +28 -8
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +332 -149
- 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 +12 -2
- 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 +23 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +34 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +111 -47
- package/src/msg_validators/tx_validator/README.md +127 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
- 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/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +42 -1
- package/src/msg_validators/tx_validator/factory.ts +396 -78
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +199 -54
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
- package/src/msg_validators/tx_validator/timestamp_validator.ts +7 -7
- package/src/services/data_store.ts +5 -13
- package/src/services/dummy_service.ts +13 -7
- package/src/services/encoding.ts +16 -8
- package/src/services/gossipsub/README.md +29 -14
- package/src/services/gossipsub/topic_score_params.ts +85 -17
- package/src/services/libp2p/instrumentation.ts +14 -0
- package/src/services/libp2p/libp2p_service.ts +278 -239
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +45 -11
- package/src/services/peer-manager/peer_scoring.ts +27 -5
- package/src/services/reqresp/README.md +229 -0
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +79 -112
- package/src/services/reqresp/batch-tx-requester/interface.ts +3 -6
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
- package/src/services/reqresp/config.ts +2 -2
- package/src/services/reqresp/interface.ts +21 -11
- package/src/services/reqresp/metrics.ts +0 -1
- 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 +40 -13
- package/src/services/service.ts +17 -3
- package/src/services/tx_collection/fast_tx_collection.ts +71 -76
- package/src/services/tx_collection/file_store_tx_collection.ts +7 -3
- package/src/services/tx_collection/file_store_tx_source.ts +65 -9
- package/src/services/tx_collection/instrumentation.ts +7 -1
- package/src/services/tx_collection/proposal_tx_collector.ts +9 -13
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/slow_tx_collection.ts +8 -9
- package/src/services/tx_collection/tx_collection.ts +5 -6
- package/src/services/tx_collection/tx_collection_sink.ts +15 -29
- package/src/services/tx_collection/tx_source.ts +28 -8
- package/src/services/tx_file_store/tx_file_store.ts +1 -1
- package/src/services/tx_provider.ts +2 -2
- package/src/test-helpers/make-test-p2p-clients.ts +3 -3
- package/src/test-helpers/mock-pubsub.ts +47 -11
- package/src/test-helpers/reqresp-nodes.ts +7 -8
- package/src/test-helpers/testbench-utils.ts +33 -6
- package/src/testbench/p2p_client_testbench_worker.ts +92 -29
- package/src/testbench/worker_client_manager.ts +68 -6
- package/src/util.ts +8 -2
- 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/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/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/protocols/block.ts +0 -37
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
2
|
import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
|
-
import {
|
|
3
|
+
import { maxBy, merge } from '@aztec/foundation/collection';
|
|
4
4
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
5
5
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
6
6
|
import { Timer } from '@aztec/foundation/timer';
|
|
7
7
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
8
8
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
9
|
-
import type { EthAddress,
|
|
9
|
+
import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
|
|
10
10
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
11
|
-
import { GasFees } from '@aztec/stdlib/gas';
|
|
11
|
+
import { type BlockMinFeesProvider, GasFees } from '@aztec/stdlib/gas';
|
|
12
12
|
import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
13
13
|
import {
|
|
14
14
|
BlockProposal,
|
|
@@ -16,13 +16,12 @@ import {
|
|
|
16
16
|
CheckpointProposal,
|
|
17
17
|
type CheckpointProposalCore,
|
|
18
18
|
type Gossipable,
|
|
19
|
-
P2PClientType,
|
|
20
19
|
P2PMessage,
|
|
21
|
-
type ValidationResult as P2PValidationResult,
|
|
22
20
|
PeerErrorSeverity,
|
|
21
|
+
PeerErrorSeverityByHarshness,
|
|
23
22
|
TopicType,
|
|
24
23
|
createTopicString,
|
|
25
|
-
|
|
24
|
+
getTopicsForConfig,
|
|
26
25
|
metricsTopicStrToLabels,
|
|
27
26
|
} from '@aztec/stdlib/p2p';
|
|
28
27
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
@@ -58,6 +57,7 @@ import { ENR } from '@nethermindeth/enr';
|
|
|
58
57
|
import { createLibp2p } from 'libp2p';
|
|
59
58
|
|
|
60
59
|
import type { P2PConfig } from '../../config.js';
|
|
60
|
+
import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
|
|
61
61
|
import type { MemPools } from '../../mem_pools/interface.js';
|
|
62
62
|
import {
|
|
63
63
|
BlockProposalValidator,
|
|
@@ -69,9 +69,11 @@ import {
|
|
|
69
69
|
} from '../../msg_validators/index.js';
|
|
70
70
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
71
71
|
import {
|
|
72
|
-
type
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
type TransactionValidator,
|
|
73
|
+
createFirstStageTxValidationsForGossipedTransactions,
|
|
74
|
+
createSecondStageTxValidationsForGossipedTransactions,
|
|
75
|
+
createTxValidatorForBlockProposalReceivedTxs,
|
|
76
|
+
createTxValidatorForReqResponseReceivedTxs,
|
|
75
77
|
} from '../../msg_validators/tx_validator/factory.js';
|
|
76
78
|
import { GossipSubEvent } from '../../types/index.js';
|
|
77
79
|
import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
|
|
@@ -87,6 +89,9 @@ import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
|
87
89
|
import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js';
|
|
88
90
|
import type { P2PReqRespConfig } from '../reqresp/config.js';
|
|
89
91
|
import {
|
|
92
|
+
AuthRequest,
|
|
93
|
+
BlockTxsRequest,
|
|
94
|
+
BlockTxsResponse,
|
|
90
95
|
DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
91
96
|
type ReqRespInterface,
|
|
92
97
|
type ReqRespResponse,
|
|
@@ -94,17 +99,11 @@ import {
|
|
|
94
99
|
type ReqRespSubProtocolHandler,
|
|
95
100
|
type ReqRespSubProtocolHandlers,
|
|
96
101
|
type ReqRespSubProtocolValidators,
|
|
102
|
+
StatusMessage,
|
|
97
103
|
type SubProtocolMap,
|
|
98
104
|
ValidationError,
|
|
99
|
-
} from '../reqresp/index.js';
|
|
100
|
-
import {
|
|
101
|
-
AuthRequest,
|
|
102
|
-
BlockTxsRequest,
|
|
103
|
-
BlockTxsResponse,
|
|
104
|
-
StatusMessage,
|
|
105
105
|
pingHandler,
|
|
106
106
|
reqGoodbyeHandler,
|
|
107
|
-
reqRespBlockHandler,
|
|
108
107
|
reqRespBlockTxsHandler,
|
|
109
108
|
reqRespStatusHandler,
|
|
110
109
|
reqRespTxHandler,
|
|
@@ -130,12 +129,12 @@ type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: Vali
|
|
|
130
129
|
// REFACTOR: Unify with the type above
|
|
131
130
|
type ReceivedMessageValidationResult<T, M = undefined> =
|
|
132
131
|
| { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
|
|
133
|
-
| { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
|
|
132
|
+
| { obj?: T; result: TopicValidatorResult.Reject; metadata?: M; severity: PeerErrorSeverity };
|
|
134
133
|
|
|
135
134
|
/**
|
|
136
135
|
* Lib P2P implementation of the P2PService interface.
|
|
137
136
|
*/
|
|
138
|
-
export class LibP2PService
|
|
137
|
+
export class LibP2PService extends WithTracer implements P2PService {
|
|
139
138
|
private discoveryRunningPromise?: RunningPromise;
|
|
140
139
|
private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
|
|
141
140
|
|
|
@@ -147,8 +146,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
147
146
|
private protocolVersion = '';
|
|
148
147
|
private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
|
|
149
148
|
|
|
150
|
-
private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
|
|
151
|
-
|
|
152
149
|
/** Callback invoked when a duplicate proposal is detected (triggers slashing). */
|
|
153
150
|
private duplicateProposalCallback?: (info: {
|
|
154
151
|
slot: SlotNumber;
|
|
@@ -171,7 +168,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
171
168
|
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
172
169
|
* @returns The attestations for the checkpoint, if any.
|
|
173
170
|
*/
|
|
174
|
-
private
|
|
171
|
+
private allNodesCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
|
|
172
|
+
/**
|
|
173
|
+
* Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
|
|
174
|
+
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
175
|
+
* @returns The attestations for the checkpoint, if any.
|
|
176
|
+
*/
|
|
177
|
+
private validatorCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
|
|
175
178
|
|
|
176
179
|
private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
|
|
177
180
|
|
|
@@ -182,7 +185,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
182
185
|
protected logger: Logger;
|
|
183
186
|
|
|
184
187
|
constructor(
|
|
185
|
-
private clientType: T,
|
|
186
188
|
private config: P2PConfig,
|
|
187
189
|
protected node: PubSubLibp2p,
|
|
188
190
|
private peerDiscoveryService: PeerDiscoveryService,
|
|
@@ -193,6 +195,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
193
195
|
private epochCache: EpochCacheInterface,
|
|
194
196
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
195
197
|
private worldStateSynchronizer: WorldStateSynchronizer,
|
|
198
|
+
private blockMinFeesProvider: BlockMinFeesProvider,
|
|
196
199
|
telemetry: TelemetryClient,
|
|
197
200
|
logger: Logger = createLogger('p2p:libp2p_service'),
|
|
198
201
|
) {
|
|
@@ -224,36 +227,54 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
224
227
|
this.protocolVersion,
|
|
225
228
|
);
|
|
226
229
|
|
|
227
|
-
|
|
228
|
-
|
|
230
|
+
const p2pPropagationTime = config.attestationPropagationTime;
|
|
231
|
+
const proposalValidatorOpts = {
|
|
229
232
|
txsPermitted: !config.disableTransactions,
|
|
230
|
-
|
|
233
|
+
maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
|
|
234
|
+
maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint,
|
|
235
|
+
p2pPropagationTime,
|
|
236
|
+
signatureContext: {
|
|
237
|
+
chainId: config.l1ChainId,
|
|
238
|
+
rollupAddress: config.l1Contracts.rollupAddress,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
|
|
242
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
|
|
243
|
+
const attestationValidatorOpts = {
|
|
244
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
245
|
+
p2pPropagationTime,
|
|
246
|
+
signatureContext: proposalValidatorOpts.signatureContext,
|
|
247
|
+
};
|
|
231
248
|
this.checkpointAttestationValidator = config.fishermanMode
|
|
232
|
-
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
|
|
233
|
-
: new CheckpointAttestationValidator(epochCache);
|
|
249
|
+
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, attestationValidatorOpts)
|
|
250
|
+
: new CheckpointAttestationValidator(epochCache, attestationValidatorOpts);
|
|
234
251
|
|
|
235
252
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
236
253
|
|
|
237
254
|
this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
|
|
238
|
-
this.logger.
|
|
239
|
-
`Handler not yet registered
|
|
255
|
+
this.logger.warn(
|
|
256
|
+
`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`,
|
|
240
257
|
{ p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
|
|
241
258
|
);
|
|
242
|
-
return
|
|
259
|
+
return true;
|
|
243
260
|
};
|
|
244
261
|
|
|
245
|
-
this.
|
|
246
|
-
|
|
262
|
+
this.allNodesCheckpointReceivedCallback = (
|
|
263
|
+
_checkpoint: CheckpointProposalCore,
|
|
264
|
+
): Promise<CheckpointAttestation[] | undefined> => {
|
|
265
|
+
throw new CheckpointProposalReceivedCallbackNotRegisteredError();
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
this.validatorCheckpointReceivedCallback = (
|
|
269
|
+
_checkpoint: CheckpointProposalCore,
|
|
247
270
|
): Promise<CheckpointAttestation[] | undefined> => {
|
|
248
|
-
this.logger.debug(
|
|
249
|
-
`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
|
|
250
|
-
);
|
|
251
271
|
return Promise.resolve(undefined);
|
|
252
272
|
};
|
|
253
273
|
}
|
|
254
274
|
|
|
255
|
-
public updateConfig(config: Partial<P2PReqRespConfig
|
|
275
|
+
public updateConfig(config: Partial<P2PReqRespConfig & Pick<P2PConfig, 'skipIncomingProposals'>>) {
|
|
256
276
|
this.reqresp.updateConfig(config);
|
|
277
|
+
this.config = merge(this.config, config);
|
|
257
278
|
}
|
|
258
279
|
|
|
259
280
|
/**
|
|
@@ -262,8 +283,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
262
283
|
* @param txPool - The transaction pool to be accessed by the service.
|
|
263
284
|
* @returns The new service.
|
|
264
285
|
*/
|
|
265
|
-
public static async new
|
|
266
|
-
clientType: T,
|
|
286
|
+
public static async new(
|
|
267
287
|
config: P2PConfig,
|
|
268
288
|
peerId: PeerId,
|
|
269
289
|
deps: {
|
|
@@ -273,6 +293,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
273
293
|
proofVerifier: ClientProtocolCircuitVerifier;
|
|
274
294
|
worldStateSynchronizer: WorldStateSynchronizer;
|
|
275
295
|
peerStore: AztecAsyncKVStore;
|
|
296
|
+
blockMinFeesProvider: BlockMinFeesProvider;
|
|
276
297
|
telemetry: TelemetryClient;
|
|
277
298
|
logger: Logger;
|
|
278
299
|
packageVersion: string;
|
|
@@ -285,6 +306,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
285
306
|
mempools,
|
|
286
307
|
proofVerifier,
|
|
287
308
|
peerStore,
|
|
309
|
+
blockMinFeesProvider,
|
|
288
310
|
telemetry,
|
|
289
311
|
logger,
|
|
290
312
|
packageVersion,
|
|
@@ -338,9 +360,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
338
360
|
const l1Constants = epochCache.getL1Constants();
|
|
339
361
|
const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
|
|
340
362
|
slotDurationMs: l1Constants.slotDuration * 1000,
|
|
363
|
+
ethereumSlotDuration: l1Constants.ethereumSlotDuration,
|
|
341
364
|
heartbeatIntervalMs: config.gossipsubInterval,
|
|
342
365
|
targetCommitteeSize: l1Constants.targetCommitteeSize,
|
|
343
366
|
blockDurationMs: config.blockDurationMs,
|
|
367
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
368
|
+
p2pPropagationTime: config.attestationPropagationTime,
|
|
369
|
+
expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
|
|
344
370
|
});
|
|
345
371
|
|
|
346
372
|
const node = await createLibp2p({
|
|
@@ -464,6 +490,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
464
490
|
epochCache,
|
|
465
491
|
);
|
|
466
492
|
|
|
493
|
+
// Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
|
|
494
|
+
reqresp.setShouldRejectPeer(peerId => peerManager.shouldDisableP2PGossip(peerId));
|
|
495
|
+
|
|
467
496
|
// Configure application-specific scoring for gossipsub.
|
|
468
497
|
// The weight scales app score to align with gossipsub thresholds:
|
|
469
498
|
// - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
|
|
@@ -474,7 +503,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
474
503
|
peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
475
504
|
|
|
476
505
|
return new LibP2PService(
|
|
477
|
-
clientType,
|
|
478
506
|
config,
|
|
479
507
|
node,
|
|
480
508
|
peerDiscoveryService,
|
|
@@ -485,6 +513,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
485
513
|
epochCache,
|
|
486
514
|
proofVerifier,
|
|
487
515
|
worldStateSynchronizer,
|
|
516
|
+
blockMinFeesProvider,
|
|
488
517
|
telemetry,
|
|
489
518
|
logger,
|
|
490
519
|
);
|
|
@@ -510,14 +539,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
510
539
|
// Create request response protocol handlers
|
|
511
540
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
512
541
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
513
|
-
const blockHandler = reqRespBlockHandler(this.archiver);
|
|
514
542
|
const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
|
|
515
543
|
|
|
516
544
|
const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
|
|
517
545
|
[ReqRespSubProtocol.PING]: pingHandler,
|
|
518
546
|
[ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
|
|
519
547
|
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
|
|
520
|
-
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
|
|
521
548
|
};
|
|
522
549
|
|
|
523
550
|
if (!this.config.disableTransactions) {
|
|
@@ -538,7 +565,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
538
565
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
539
566
|
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
540
567
|
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
541
|
-
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
|
|
542
568
|
};
|
|
543
569
|
|
|
544
570
|
await this.peerManager.initializePeers();
|
|
@@ -548,7 +574,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
548
574
|
await this.node.start();
|
|
549
575
|
|
|
550
576
|
// Subscribe to standard GossipSub topics by default
|
|
551
|
-
for (const topic of
|
|
577
|
+
for (const topic of getTopicsForConfig(this.config.disableTransactions)) {
|
|
552
578
|
this.subscribeToTopic(this.topicStrings[topic]);
|
|
553
579
|
}
|
|
554
580
|
|
|
@@ -614,6 +640,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
614
640
|
return this.peerManager.getPeers(includePending);
|
|
615
641
|
}
|
|
616
642
|
|
|
643
|
+
public getGossipMeshPeerCount(topicType: TopicType): number {
|
|
644
|
+
return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
|
|
645
|
+
}
|
|
646
|
+
|
|
617
647
|
private handleGossipSubEvent(e: CustomEvent<GossipsubMessage>) {
|
|
618
648
|
this.logger.trace(`Received PUBSUB message.`);
|
|
619
649
|
|
|
@@ -662,8 +692,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
662
692
|
this.blockReceivedCallback = callback;
|
|
663
693
|
}
|
|
664
694
|
|
|
665
|
-
public
|
|
666
|
-
this.
|
|
695
|
+
public registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
696
|
+
this.validatorCheckpointReceivedCallback = callback;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
700
|
+
this.allNodesCheckpointReceivedCallback = callback;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void> {
|
|
704
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
|
|
667
705
|
}
|
|
668
706
|
|
|
669
707
|
/**
|
|
@@ -749,6 +787,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
749
787
|
if (!validator || !validator.addMessage(msgId)) {
|
|
750
788
|
this.instrumentation.incMessagePrevalidationStatus(false, topicType);
|
|
751
789
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
790
|
+
if (topicType === TopicType.tx) {
|
|
791
|
+
this.logger.verbose(`Ignoring already-seen tx gossip message`, { msgId, source: source.toString() });
|
|
792
|
+
}
|
|
752
793
|
return { result: false, topicType };
|
|
753
794
|
}
|
|
754
795
|
|
|
@@ -810,12 +851,19 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
810
851
|
|
|
811
852
|
// Process the message, optionally within a linked span for trace propagation
|
|
812
853
|
const processMessage = async () => {
|
|
854
|
+
if (
|
|
855
|
+
this.config.skipIncomingProposals &&
|
|
856
|
+
(msg.topic === this.topicStrings[TopicType.block_proposal] ||
|
|
857
|
+
msg.topic === this.topicStrings[TopicType.checkpoint_proposal])
|
|
858
|
+
) {
|
|
859
|
+
this.logger.warn(`Ignoring incoming proposal (skipIncomingProposals is set)`, { topic: msg.topic });
|
|
860
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
813
863
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
814
864
|
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
815
865
|
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
816
|
-
|
|
817
|
-
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
818
|
-
}
|
|
866
|
+
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
819
867
|
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
820
868
|
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
821
869
|
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
@@ -877,47 +925,124 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
877
925
|
source: PeerId,
|
|
878
926
|
topicType: TopicType,
|
|
879
927
|
): Promise<ReceivedMessageValidationResult<T, M>> {
|
|
880
|
-
|
|
928
|
+
// Default to reject result with a penalty if validation function throws an error
|
|
929
|
+
let resultAndObj: ReceivedMessageValidationResult<T, M> = {
|
|
930
|
+
result: TopicValidatorResult.Reject,
|
|
931
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
932
|
+
};
|
|
881
933
|
const timer = new Timer();
|
|
882
934
|
try {
|
|
883
935
|
resultAndObj = await validationFunc();
|
|
884
936
|
} catch (err) {
|
|
885
|
-
this.
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
937
|
+
this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
const validationTimeMs = timer.ms();
|
|
941
|
+
const mcacheWindowMs = this.config.gossipsubMcacheLength * this.config.gossipsubInterval;
|
|
942
|
+
if (validationTimeMs > mcacheWindowMs * 0.75) {
|
|
943
|
+
this.instrumentation.incSlowValidation(topicType);
|
|
944
|
+
this.logger.warn(
|
|
945
|
+
`Gossip validation for ${topicType} took ${validationTimeMs}ms, approaching mcache eviction window of ${mcacheWindowMs}ms. ` +
|
|
946
|
+
`Message forwarding may be skipped if validation exceeds the window.`,
|
|
947
|
+
{ msgId, source: source.toString(), topicType, validationTimeMs, mcacheWindowMs },
|
|
948
|
+
);
|
|
891
949
|
}
|
|
892
950
|
|
|
893
951
|
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
952
|
+
this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
|
|
894
953
|
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
954
|
+
} else if (resultAndObj.result === TopicValidatorResult.Reject) {
|
|
955
|
+
this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
|
|
956
|
+
msgId,
|
|
957
|
+
source: source.toString(),
|
|
958
|
+
topicType,
|
|
959
|
+
severity: resultAndObj.severity,
|
|
960
|
+
});
|
|
961
|
+
this.peerManager.penalizePeer(source, resultAndObj.severity);
|
|
962
|
+
} else {
|
|
963
|
+
this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
|
|
895
964
|
}
|
|
896
965
|
|
|
897
966
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
898
967
|
return resultAndObj;
|
|
899
968
|
}
|
|
900
969
|
|
|
970
|
+
private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
|
|
971
|
+
try {
|
|
972
|
+
return deserializeFunc();
|
|
973
|
+
} catch (err) {
|
|
974
|
+
this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
|
|
975
|
+
err,
|
|
976
|
+
msgId,
|
|
977
|
+
source: source.toString(),
|
|
978
|
+
});
|
|
979
|
+
return undefined;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
|
|
901
983
|
protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
|
|
902
984
|
const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
|
|
903
|
-
const tx = Tx.fromBuffer(payloadData);
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
985
|
+
const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
|
|
986
|
+
if (!tx) {
|
|
987
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
991
|
+
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
992
|
+
|
|
993
|
+
// Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
|
|
994
|
+
const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
995
|
+
const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
|
|
996
|
+
if (!firstStageOutcome.allPassed) {
|
|
997
|
+
const { name } = firstStageOutcome.failure;
|
|
998
|
+
let { severity } = firstStageOutcome.failure;
|
|
999
|
+
|
|
1000
|
+
// Double spend validator has a special case handler. We perform more detailed examination
|
|
1001
|
+
// as to how recently the nullifier was entered into the tree and if the transaction should
|
|
1002
|
+
// have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
|
|
1003
|
+
if (name === 'doubleSpendValidator') {
|
|
1004
|
+
const txBlockNumber = BlockNumber(currentBlockNumber + 1);
|
|
1005
|
+
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
|
|
1009
|
+
validator: name,
|
|
1010
|
+
severity,
|
|
1011
|
+
source: source.toString(),
|
|
1012
|
+
});
|
|
1013
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
|
|
1017
|
+
const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
|
|
1018
|
+
if (canAdd === 'ignored') {
|
|
1019
|
+
this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
|
|
1020
|
+
source: source.toString(),
|
|
1021
|
+
});
|
|
1022
|
+
return { result: TopicValidatorResult.Ignore, obj: tx };
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
// Stage 2: expensive proof verification
|
|
1026
|
+
const secondStageValidators = this.createSecondStageMessageValidators();
|
|
1027
|
+
const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
|
|
1028
|
+
if (!secondStageOutcome.allPassed) {
|
|
1029
|
+
const { severity, name } = secondStageOutcome.failure;
|
|
1030
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
|
|
1031
|
+
validator: name,
|
|
1032
|
+
severity,
|
|
1033
|
+
source: source.toString(),
|
|
908
1034
|
});
|
|
909
|
-
return { result: TopicValidatorResult.Reject };
|
|
1035
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
910
1036
|
}
|
|
911
1037
|
|
|
912
|
-
//
|
|
1038
|
+
// Pool add: persist the tx
|
|
913
1039
|
const txHash = tx.getTxHash();
|
|
914
1040
|
const addResult = await this.mempools.txPool.addPendingTxs([tx], { source: 'gossip' });
|
|
915
1041
|
|
|
916
1042
|
const wasAccepted = addResult.accepted.some(h => h.equals(txHash));
|
|
917
1043
|
const wasIgnored = addResult.ignored.some(h => h.equals(txHash));
|
|
918
1044
|
|
|
919
|
-
this.logger.
|
|
920
|
-
isValid,
|
|
1045
|
+
this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
|
|
921
1046
|
wasAccepted,
|
|
922
1047
|
wasIgnored,
|
|
923
1048
|
[Attributes.P2P_ID]: source.toString(),
|
|
@@ -928,7 +1053,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
928
1053
|
} else if (wasIgnored) {
|
|
929
1054
|
return { result: TopicValidatorResult.Ignore, obj: tx };
|
|
930
1055
|
} else {
|
|
931
|
-
|
|
1056
|
+
this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
|
|
1057
|
+
source: source.toString(),
|
|
1058
|
+
txHash: txHash.toString(),
|
|
1059
|
+
});
|
|
1060
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
932
1061
|
}
|
|
933
1062
|
};
|
|
934
1063
|
|
|
@@ -958,7 +1087,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
958
1087
|
source: PeerId,
|
|
959
1088
|
): Promise<void> {
|
|
960
1089
|
const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
|
|
961
|
-
() =>
|
|
1090
|
+
() => {
|
|
1091
|
+
const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
|
|
1092
|
+
if (!attestation) {
|
|
1093
|
+
return Promise.resolve({
|
|
1094
|
+
result: TopicValidatorResult.Reject,
|
|
1095
|
+
severity: PeerErrorSeverity.LowToleranceError,
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
return this.validateAndStoreCheckpointAttestation(source, attestation);
|
|
1099
|
+
},
|
|
962
1100
|
msgId,
|
|
963
1101
|
source,
|
|
964
1102
|
TopicType.checkpoint_attestation,
|
|
@@ -991,8 +1129,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
991
1129
|
|
|
992
1130
|
if (validationResult.result === 'reject') {
|
|
993
1131
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
994
|
-
|
|
995
|
-
return { result: TopicValidatorResult.Reject };
|
|
1132
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
996
1133
|
}
|
|
997
1134
|
|
|
998
1135
|
if (validationResult.result === 'ignore') {
|
|
@@ -1018,16 +1155,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1018
1155
|
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
1019
1156
|
}
|
|
1020
1157
|
|
|
1021
|
-
// Could not add (cap reached for signer),
|
|
1158
|
+
// Could not add (cap reached for signer), penalize and do not re-broadcast
|
|
1022
1159
|
if (!added) {
|
|
1023
|
-
this.logger.warn(`
|
|
1160
|
+
this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
|
|
1024
1161
|
slot: slot.toString(),
|
|
1025
1162
|
archive: attestation.archive.toString(),
|
|
1026
1163
|
source: peerId.toString(),
|
|
1027
1164
|
attester: attestation.getSender()?.toString(),
|
|
1028
1165
|
count,
|
|
1029
1166
|
});
|
|
1030
|
-
return { result: TopicValidatorResult.
|
|
1167
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
1031
1168
|
}
|
|
1032
1169
|
|
|
1033
1170
|
// Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
|
|
@@ -1082,8 +1219,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1082
1219
|
|
|
1083
1220
|
if (validationResult.result === 'reject') {
|
|
1084
1221
|
this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1085
|
-
|
|
1086
|
-
return { result: TopicValidatorResult.Reject };
|
|
1222
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1087
1223
|
}
|
|
1088
1224
|
|
|
1089
1225
|
if (validationResult.result === 'ignore') {
|
|
@@ -1107,7 +1243,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1107
1243
|
|
|
1108
1244
|
// Too many blocks received for this slot and index, penalize peer and do not re-broadcast
|
|
1109
1245
|
if (!added) {
|
|
1110
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1111
1246
|
this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
|
|
1112
1247
|
...block.toBlockInfo(),
|
|
1113
1248
|
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
@@ -1115,7 +1250,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1115
1250
|
proposer: block.getSender()?.toString(),
|
|
1116
1251
|
source: peerId.toString(),
|
|
1117
1252
|
});
|
|
1118
|
-
return {
|
|
1253
|
+
return {
|
|
1254
|
+
result: TopicValidatorResult.Reject,
|
|
1255
|
+
metadata: { isEquivocated },
|
|
1256
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1257
|
+
};
|
|
1119
1258
|
}
|
|
1120
1259
|
|
|
1121
1260
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1160,7 +1299,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1160
1299
|
// Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1161
1300
|
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1162
1301
|
if (!isValid) {
|
|
1163
|
-
this.logger.
|
|
1302
|
+
this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1164
1303
|
}
|
|
1165
1304
|
}
|
|
1166
1305
|
|
|
@@ -1208,8 +1347,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1208
1347
|
|
|
1209
1348
|
if (validationResult.result === 'reject') {
|
|
1210
1349
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1211
|
-
|
|
1212
|
-
return { result: TopicValidatorResult.Reject };
|
|
1350
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1213
1351
|
}
|
|
1214
1352
|
|
|
1215
1353
|
if (validationResult.result === 'ignore') {
|
|
@@ -1224,20 +1362,21 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1224
1362
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1225
1363
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1226
1364
|
});
|
|
1227
|
-
const
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
metadata: { isEquivocated } = {},
|
|
1231
|
-
} = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1232
|
-
if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1365
|
+
const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1366
|
+
const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
|
|
1367
|
+
if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1233
1368
|
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1234
1369
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1235
1370
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1236
1371
|
isEquivocated,
|
|
1237
|
-
result,
|
|
1372
|
+
result: blockProposalResult.result,
|
|
1238
1373
|
});
|
|
1239
|
-
return {
|
|
1240
|
-
|
|
1374
|
+
return {
|
|
1375
|
+
result: TopicValidatorResult.Reject,
|
|
1376
|
+
severity:
|
|
1377
|
+
'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
|
|
1378
|
+
};
|
|
1379
|
+
} else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1241
1380
|
processBlock = true;
|
|
1242
1381
|
}
|
|
1243
1382
|
}
|
|
@@ -1264,13 +1403,17 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1264
1403
|
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1265
1404
|
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1266
1405
|
if (!added) {
|
|
1267
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1268
1406
|
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1269
1407
|
...checkpoint.toCheckpointInfo(),
|
|
1270
1408
|
count,
|
|
1271
1409
|
source: peerId.toString(),
|
|
1272
1410
|
});
|
|
1273
|
-
return {
|
|
1411
|
+
return {
|
|
1412
|
+
result: TopicValidatorResult.Reject,
|
|
1413
|
+
obj: checkpoint,
|
|
1414
|
+
metadata: { isEquivocated, processBlock },
|
|
1415
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1416
|
+
};
|
|
1274
1417
|
}
|
|
1275
1418
|
|
|
1276
1419
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1315,9 +1458,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1315
1458
|
source: sender.toString(),
|
|
1316
1459
|
});
|
|
1317
1460
|
|
|
1461
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
|
|
1462
|
+
|
|
1318
1463
|
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1319
1464
|
// to validate and potentially generate attestations
|
|
1320
|
-
const attestations = await this.
|
|
1465
|
+
const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
|
|
1321
1466
|
if (attestations && attestations.length > 0) {
|
|
1322
1467
|
// If the callback returned attestations, add them to the pool and propagate them
|
|
1323
1468
|
await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
|
|
@@ -1465,53 +1610,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1465
1610
|
}
|
|
1466
1611
|
}
|
|
1467
1612
|
|
|
1468
|
-
/**
|
|
1469
|
-
* Validates a BLOCK response.
|
|
1470
|
-
*
|
|
1471
|
-
* If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
|
|
1472
|
-
* Penalizes on block number mismatch or hash mismatch.
|
|
1473
|
-
*
|
|
1474
|
-
* @param requestedBlockNumber - The requested block number.
|
|
1475
|
-
* @param responseBlock - The block returned by the peer.
|
|
1476
|
-
* @param peerId - The peer that returned the block.
|
|
1477
|
-
* @returns True if the response is valid, false otherwise.
|
|
1478
|
-
*/
|
|
1479
|
-
@trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
|
|
1480
|
-
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
|
|
1481
|
-
}))
|
|
1482
|
-
protected async validateRequestedBlock(
|
|
1483
|
-
requestedBlockNumber: Fr,
|
|
1484
|
-
responseBlock: L2Block,
|
|
1485
|
-
peerId: PeerId,
|
|
1486
|
-
): Promise<boolean> {
|
|
1487
|
-
try {
|
|
1488
|
-
const reqNum = Number(requestedBlockNumber.toString());
|
|
1489
|
-
if (responseBlock.number !== reqNum) {
|
|
1490
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1491
|
-
return false;
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
|
-
const local = await this.archiver.getBlock(BlockNumber(reqNum));
|
|
1495
|
-
if (!local) {
|
|
1496
|
-
// We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
|
|
1497
|
-
// TODO: Consider extending this validator to accept an expected hash or
|
|
1498
|
-
// performing quorum-based checks when using P2P syncing prior to L1 sync.
|
|
1499
|
-
this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
|
|
1500
|
-
return false;
|
|
1501
|
-
}
|
|
1502
|
-
const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
|
|
1503
|
-
if (!localHash.equals(respHash)) {
|
|
1504
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1505
|
-
return false;
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
return true;
|
|
1509
|
-
} catch (e) {
|
|
1510
|
-
this.logger.warn(`Error validating requested block`, e);
|
|
1511
|
-
return false;
|
|
1512
|
-
}
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
1613
|
protected async validateRequestedTx(
|
|
1516
1614
|
tx: Tx,
|
|
1517
1615
|
peerId: PeerId,
|
|
@@ -1532,52 +1630,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1532
1630
|
}
|
|
1533
1631
|
|
|
1534
1632
|
protected createRequestedTxValidator(): TxValidator {
|
|
1535
|
-
return
|
|
1633
|
+
return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
|
|
1536
1634
|
l1ChainId: this.config.l1ChainId,
|
|
1537
1635
|
rollupVersion: this.config.rollupVersion,
|
|
1538
1636
|
});
|
|
1539
1637
|
}
|
|
1540
1638
|
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
}))
|
|
1544
|
-
protected async validatePropagatedTx(tx: Tx, peerId: PeerId): Promise<boolean> {
|
|
1545
|
-
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1546
|
-
|
|
1547
|
-
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1548
|
-
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1549
|
-
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1550
|
-
|
|
1551
|
-
for (const validator of messageValidators) {
|
|
1552
|
-
const outcome = await this.runValidations(tx, validator);
|
|
1553
|
-
|
|
1554
|
-
if (outcome.allPassed) {
|
|
1555
|
-
continue;
|
|
1556
|
-
}
|
|
1557
|
-
const { name } = outcome.failure;
|
|
1558
|
-
let { severity } = outcome.failure;
|
|
1559
|
-
|
|
1560
|
-
// Double spend validator has a special case handler
|
|
1561
|
-
if (name === 'doubleSpendValidator') {
|
|
1562
|
-
const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
|
|
1563
|
-
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1564
|
-
}
|
|
1565
|
-
|
|
1566
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
1567
|
-
return false;
|
|
1568
|
-
}
|
|
1569
|
-
return true;
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
|
|
1573
|
-
if (blockNumber === this.feesCache?.blockNumber) {
|
|
1574
|
-
return this.feesCache.gasFees;
|
|
1575
|
-
}
|
|
1576
|
-
|
|
1577
|
-
const header = await this.archiver.getBlockHeader(blockNumber);
|
|
1578
|
-
const gasFees = header?.globalVariables.gasFees ?? GasFees.empty();
|
|
1579
|
-
this.feesCache = { blockNumber, gasFees };
|
|
1580
|
-
return gasFees;
|
|
1639
|
+
private getGasFees(): Promise<GasFees> {
|
|
1640
|
+
return this.blockMinFeesProvider.getCurrentMinFees();
|
|
1581
1641
|
}
|
|
1582
1642
|
|
|
1583
1643
|
/**
|
|
@@ -1596,60 +1656,62 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1596
1656
|
};
|
|
1597
1657
|
}
|
|
1598
1658
|
|
|
1599
|
-
public async
|
|
1600
|
-
const
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1659
|
+
public async validateTxsReceivedInBlockProposal(txs: Tx[]): Promise<void> {
|
|
1660
|
+
const validator = createTxValidatorForBlockProposalReceivedTxs(
|
|
1661
|
+
this.proofVerifier,
|
|
1662
|
+
{ l1ChainId: this.config.l1ChainId, rollupVersion: this.config.rollupVersion },
|
|
1663
|
+
this.logger.getBindings(),
|
|
1664
|
+
);
|
|
1605
1665
|
|
|
1606
|
-
await Promise.all(
|
|
1666
|
+
const results = await Promise.all(
|
|
1607
1667
|
txs.map(async tx => {
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
if (!outcome.allPassed) {
|
|
1611
|
-
throw new Error('Invalid tx detected', { cause: { outcome } });
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1668
|
+
const result = await validator.validateTx(tx);
|
|
1669
|
+
return result.result !== 'invalid';
|
|
1614
1670
|
}),
|
|
1615
1671
|
);
|
|
1672
|
+
if (results.some(value => value === false)) {
|
|
1673
|
+
throw new Error('Invalid tx detected');
|
|
1674
|
+
}
|
|
1616
1675
|
}
|
|
1617
1676
|
|
|
1618
|
-
/**
|
|
1619
|
-
|
|
1620
|
-
*
|
|
1621
|
-
* Each validator is a pair of a validator and a severity.
|
|
1622
|
-
* If a validator fails, the peer is penalized with the severity of the validator.
|
|
1623
|
-
*
|
|
1624
|
-
* @param currentBlockNumber - The current synced block number.
|
|
1625
|
-
* @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
|
|
1626
|
-
* @returns The message validators.
|
|
1627
|
-
*/
|
|
1628
|
-
private async createMessageValidators(
|
|
1677
|
+
/** Creates the first stage (fast) validators for gossiped transactions. */
|
|
1678
|
+
protected async createFirstStageMessageValidators(
|
|
1629
1679
|
currentBlockNumber: BlockNumber,
|
|
1630
1680
|
nextSlotTimestamp: UInt64,
|
|
1631
|
-
): Promise<Record<string,
|
|
1632
|
-
const gasFees = await this.getGasFees(
|
|
1633
|
-
const allowedInSetup =
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1681
|
+
): Promise<Record<string, TransactionValidator>> {
|
|
1682
|
+
const gasFees = await this.getGasFees();
|
|
1683
|
+
const allowedInSetup = [
|
|
1684
|
+
...(await getDefaultAllowedSetupFunctions()),
|
|
1685
|
+
...(this.config.txPublicSetupAllowListExtend ?? []),
|
|
1686
|
+
];
|
|
1687
|
+
const blockNumber = BlockNumber(currentBlockNumber + 1);
|
|
1688
|
+
const l1Constants = await this.archiver.getL1Constants();
|
|
1689
|
+
|
|
1690
|
+
return createFirstStageTxValidationsForGossipedTransactions(
|
|
1638
1691
|
nextSlotTimestamp,
|
|
1639
|
-
|
|
1692
|
+
blockNumber,
|
|
1640
1693
|
this.worldStateSynchronizer,
|
|
1641
1694
|
gasFees,
|
|
1642
1695
|
this.config.l1ChainId,
|
|
1643
1696
|
this.config.rollupVersion,
|
|
1644
1697
|
protocolContractsHash,
|
|
1645
1698
|
this.archiver,
|
|
1646
|
-
this.proofVerifier,
|
|
1647
1699
|
!this.config.disableTransactions,
|
|
1648
1700
|
allowedInSetup,
|
|
1649
1701
|
this.logger.getBindings(),
|
|
1702
|
+
{
|
|
1703
|
+
rollupManaLimit: l1Constants.rollupManaLimit,
|
|
1704
|
+
maxBlockL2Gas: this.config.validateMaxL2BlockGas,
|
|
1705
|
+
maxBlockDAGas: this.config.validateMaxDABlockGas,
|
|
1706
|
+
},
|
|
1650
1707
|
);
|
|
1651
1708
|
}
|
|
1652
1709
|
|
|
1710
|
+
/** Creates the second stage (expensive proof verification) validators for gossiped transactions. */
|
|
1711
|
+
protected createSecondStageMessageValidators(): Record<string, TransactionValidator> {
|
|
1712
|
+
return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1653
1715
|
/**
|
|
1654
1716
|
* Run validations on a tx.
|
|
1655
1717
|
* @param tx - The tx to validate.
|
|
@@ -1658,7 +1720,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1658
1720
|
*/
|
|
1659
1721
|
private async runValidations(
|
|
1660
1722
|
tx: Tx,
|
|
1661
|
-
messageValidators: Record<string,
|
|
1723
|
+
messageValidators: Record<string, TransactionValidator>,
|
|
1662
1724
|
): Promise<ValidationOutcome> {
|
|
1663
1725
|
const validationPromises = Object.entries(messageValidators).map(async ([name, { validator, severity }]) => {
|
|
1664
1726
|
const { result } = await validator.validateTx(tx);
|
|
@@ -1667,8 +1729,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1667
1729
|
|
|
1668
1730
|
// A promise that resolves when all validations have been run
|
|
1669
1731
|
const allValidations = await Promise.all(validationPromises);
|
|
1670
|
-
const
|
|
1671
|
-
if (
|
|
1732
|
+
const failures = allValidations.filter(x => !x.isValid);
|
|
1733
|
+
if (failures.length > 0) {
|
|
1734
|
+
// Pick the most severe failure (lowest tolerance = harshest penalty)
|
|
1735
|
+
const failed = maxBy(failures, f => PeerErrorSeverityByHarshness.indexOf(f.severity))!;
|
|
1672
1736
|
return {
|
|
1673
1737
|
allPassed: false,
|
|
1674
1738
|
failure: {
|
|
@@ -1721,31 +1785,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1721
1785
|
return PeerErrorSeverity.HighToleranceError;
|
|
1722
1786
|
}
|
|
1723
1787
|
|
|
1724
|
-
/**
|
|
1725
|
-
* Validate a checkpoint attestation.
|
|
1726
|
-
*
|
|
1727
|
-
* @param attestation - The checkpoint attestation to validate.
|
|
1728
|
-
* @returns True if the checkpoint attestation is valid, false otherwise.
|
|
1729
|
-
*/
|
|
1730
|
-
@trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
|
|
1731
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
1732
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1733
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1734
|
-
}))
|
|
1735
|
-
public async validateCheckpointAttestation(
|
|
1736
|
-
peerId: PeerId,
|
|
1737
|
-
attestation: CheckpointAttestation,
|
|
1738
|
-
): Promise<P2PValidationResult> {
|
|
1739
|
-
const result = await this.checkpointAttestationValidator.validate(attestation);
|
|
1740
|
-
|
|
1741
|
-
if (result.result === 'reject') {
|
|
1742
|
-
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1743
|
-
this.peerManager.penalizePeer(peerId, result.severity);
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
return result;
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
1788
|
public getPeerScore(peerId: PeerId): number {
|
|
1750
1789
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
1751
1790
|
}
|