@aztec/p2p 0.0.1-commit.0c875d939 → 0.0.1-commit.0dc957cde
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 +34 -29
- 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 +126 -103
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +93 -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/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 +16 -14
- 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 +5 -2
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +20 -11
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +4 -2
- 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 +54 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +7 -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 +7 -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 +15 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +67 -47
- 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 +32 -37
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +241 -212
- 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 +62 -49
- 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 +139 -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/index.ts +0 -3
- package/src/mem_pools/instrumentation.ts +17 -13
- 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 +21 -9
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +4 -1
- package/src/msg_validators/clock_tolerance.ts +72 -3
- package/src/msg_validators/proposal_validator/README.md +123 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +17 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +23 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +79 -49
- 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 +259 -238
- 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 } 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,30 +227,39 @@ 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
|
+
p2pPropagationTime,
|
|
235
|
+
};
|
|
236
|
+
this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
|
|
237
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
|
|
231
238
|
this.checkpointAttestationValidator = config.fishermanMode
|
|
232
|
-
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry
|
|
233
|
-
|
|
239
|
+
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, {
|
|
240
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
241
|
+
})
|
|
242
|
+
: new CheckpointAttestationValidator(epochCache, { l1PublishingTime: config.l1PublishingTime });
|
|
234
243
|
|
|
235
244
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
236
245
|
|
|
237
246
|
this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
|
|
238
|
-
this.logger.
|
|
239
|
-
`Handler not yet registered
|
|
247
|
+
this.logger.warn(
|
|
248
|
+
`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`,
|
|
240
249
|
{ p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
|
|
241
250
|
);
|
|
242
|
-
return
|
|
251
|
+
return true;
|
|
243
252
|
};
|
|
244
253
|
|
|
245
|
-
this.
|
|
246
|
-
|
|
254
|
+
this.allNodesCheckpointReceivedCallback = (
|
|
255
|
+
_checkpoint: CheckpointProposalCore,
|
|
256
|
+
): Promise<CheckpointAttestation[] | undefined> => {
|
|
257
|
+
throw new CheckpointProposalReceivedCallbackNotRegisteredError();
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
this.validatorCheckpointReceivedCallback = (
|
|
261
|
+
_checkpoint: CheckpointProposalCore,
|
|
247
262
|
): 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
263
|
return Promise.resolve(undefined);
|
|
252
264
|
};
|
|
253
265
|
}
|
|
@@ -262,8 +274,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
262
274
|
* @param txPool - The transaction pool to be accessed by the service.
|
|
263
275
|
* @returns The new service.
|
|
264
276
|
*/
|
|
265
|
-
public static async new
|
|
266
|
-
clientType: T,
|
|
277
|
+
public static async new(
|
|
267
278
|
config: P2PConfig,
|
|
268
279
|
peerId: PeerId,
|
|
269
280
|
deps: {
|
|
@@ -273,6 +284,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
273
284
|
proofVerifier: ClientProtocolCircuitVerifier;
|
|
274
285
|
worldStateSynchronizer: WorldStateSynchronizer;
|
|
275
286
|
peerStore: AztecAsyncKVStore;
|
|
287
|
+
blockMinFeesProvider: BlockMinFeesProvider;
|
|
276
288
|
telemetry: TelemetryClient;
|
|
277
289
|
logger: Logger;
|
|
278
290
|
packageVersion: string;
|
|
@@ -285,6 +297,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
285
297
|
mempools,
|
|
286
298
|
proofVerifier,
|
|
287
299
|
peerStore,
|
|
300
|
+
blockMinFeesProvider,
|
|
288
301
|
telemetry,
|
|
289
302
|
logger,
|
|
290
303
|
packageVersion,
|
|
@@ -338,9 +351,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
338
351
|
const l1Constants = epochCache.getL1Constants();
|
|
339
352
|
const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
|
|
340
353
|
slotDurationMs: l1Constants.slotDuration * 1000,
|
|
354
|
+
ethereumSlotDuration: l1Constants.ethereumSlotDuration,
|
|
341
355
|
heartbeatIntervalMs: config.gossipsubInterval,
|
|
342
356
|
targetCommitteeSize: l1Constants.targetCommitteeSize,
|
|
343
357
|
blockDurationMs: config.blockDurationMs,
|
|
358
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
359
|
+
p2pPropagationTime: config.attestationPropagationTime,
|
|
360
|
+
expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
|
|
344
361
|
});
|
|
345
362
|
|
|
346
363
|
const node = await createLibp2p({
|
|
@@ -464,6 +481,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
464
481
|
epochCache,
|
|
465
482
|
);
|
|
466
483
|
|
|
484
|
+
// Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
|
|
485
|
+
reqresp.setShouldRejectPeer(peerId => peerManager.shouldDisableP2PGossip(peerId));
|
|
486
|
+
|
|
467
487
|
// Configure application-specific scoring for gossipsub.
|
|
468
488
|
// The weight scales app score to align with gossipsub thresholds:
|
|
469
489
|
// - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
|
|
@@ -474,7 +494,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
474
494
|
peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
475
495
|
|
|
476
496
|
return new LibP2PService(
|
|
477
|
-
clientType,
|
|
478
497
|
config,
|
|
479
498
|
node,
|
|
480
499
|
peerDiscoveryService,
|
|
@@ -485,6 +504,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
485
504
|
epochCache,
|
|
486
505
|
proofVerifier,
|
|
487
506
|
worldStateSynchronizer,
|
|
507
|
+
blockMinFeesProvider,
|
|
488
508
|
telemetry,
|
|
489
509
|
logger,
|
|
490
510
|
);
|
|
@@ -510,14 +530,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
510
530
|
// Create request response protocol handlers
|
|
511
531
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
512
532
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
513
|
-
const blockHandler = reqRespBlockHandler(this.archiver);
|
|
514
533
|
const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
|
|
515
534
|
|
|
516
535
|
const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
|
|
517
536
|
[ReqRespSubProtocol.PING]: pingHandler,
|
|
518
537
|
[ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
|
|
519
538
|
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
|
|
520
|
-
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
|
|
521
539
|
};
|
|
522
540
|
|
|
523
541
|
if (!this.config.disableTransactions) {
|
|
@@ -538,7 +556,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
538
556
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
539
557
|
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
540
558
|
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
541
|
-
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
|
|
542
559
|
};
|
|
543
560
|
|
|
544
561
|
await this.peerManager.initializePeers();
|
|
@@ -548,7 +565,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
548
565
|
await this.node.start();
|
|
549
566
|
|
|
550
567
|
// Subscribe to standard GossipSub topics by default
|
|
551
|
-
for (const topic of
|
|
568
|
+
for (const topic of getTopicsForConfig(this.config.disableTransactions)) {
|
|
552
569
|
this.subscribeToTopic(this.topicStrings[topic]);
|
|
553
570
|
}
|
|
554
571
|
|
|
@@ -614,6 +631,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
614
631
|
return this.peerManager.getPeers(includePending);
|
|
615
632
|
}
|
|
616
633
|
|
|
634
|
+
public getGossipMeshPeerCount(topicType: TopicType): number {
|
|
635
|
+
return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
|
|
636
|
+
}
|
|
637
|
+
|
|
617
638
|
private handleGossipSubEvent(e: CustomEvent<GossipsubMessage>) {
|
|
618
639
|
this.logger.trace(`Received PUBSUB message.`);
|
|
619
640
|
|
|
@@ -662,8 +683,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
662
683
|
this.blockReceivedCallback = callback;
|
|
663
684
|
}
|
|
664
685
|
|
|
665
|
-
public
|
|
666
|
-
this.
|
|
686
|
+
public registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
687
|
+
this.validatorCheckpointReceivedCallback = callback;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
691
|
+
this.allNodesCheckpointReceivedCallback = callback;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void> {
|
|
695
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
|
|
667
696
|
}
|
|
668
697
|
|
|
669
698
|
/**
|
|
@@ -749,6 +778,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
749
778
|
if (!validator || !validator.addMessage(msgId)) {
|
|
750
779
|
this.instrumentation.incMessagePrevalidationStatus(false, topicType);
|
|
751
780
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
781
|
+
if (topicType === TopicType.tx) {
|
|
782
|
+
this.logger.verbose(`Ignoring already-seen tx gossip message`, { msgId, source: source.toString() });
|
|
783
|
+
}
|
|
752
784
|
return { result: false, topicType };
|
|
753
785
|
}
|
|
754
786
|
|
|
@@ -813,9 +845,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
813
845
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
814
846
|
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
815
847
|
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
816
|
-
|
|
817
|
-
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
818
|
-
}
|
|
848
|
+
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
819
849
|
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
820
850
|
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
821
851
|
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
@@ -877,47 +907,124 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
877
907
|
source: PeerId,
|
|
878
908
|
topicType: TopicType,
|
|
879
909
|
): Promise<ReceivedMessageValidationResult<T, M>> {
|
|
880
|
-
|
|
910
|
+
// Default to reject result with a penalty if validation function throws an error
|
|
911
|
+
let resultAndObj: ReceivedMessageValidationResult<T, M> = {
|
|
912
|
+
result: TopicValidatorResult.Reject,
|
|
913
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
914
|
+
};
|
|
881
915
|
const timer = new Timer();
|
|
882
916
|
try {
|
|
883
917
|
resultAndObj = await validationFunc();
|
|
884
918
|
} catch (err) {
|
|
885
|
-
this.
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
919
|
+
this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
const validationTimeMs = timer.ms();
|
|
923
|
+
const mcacheWindowMs = this.config.gossipsubMcacheLength * this.config.gossipsubInterval;
|
|
924
|
+
if (validationTimeMs > mcacheWindowMs * 0.75) {
|
|
925
|
+
this.instrumentation.incSlowValidation(topicType);
|
|
926
|
+
this.logger.warn(
|
|
927
|
+
`Gossip validation for ${topicType} took ${validationTimeMs}ms, approaching mcache eviction window of ${mcacheWindowMs}ms. ` +
|
|
928
|
+
`Message forwarding may be skipped if validation exceeds the window.`,
|
|
929
|
+
{ msgId, source: source.toString(), topicType, validationTimeMs, mcacheWindowMs },
|
|
930
|
+
);
|
|
891
931
|
}
|
|
892
932
|
|
|
893
933
|
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
934
|
+
this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
|
|
894
935
|
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
936
|
+
} else if (resultAndObj.result === TopicValidatorResult.Reject) {
|
|
937
|
+
this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
|
|
938
|
+
msgId,
|
|
939
|
+
source: source.toString(),
|
|
940
|
+
topicType,
|
|
941
|
+
severity: resultAndObj.severity,
|
|
942
|
+
});
|
|
943
|
+
this.peerManager.penalizePeer(source, resultAndObj.severity);
|
|
944
|
+
} else {
|
|
945
|
+
this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
|
|
895
946
|
}
|
|
896
947
|
|
|
897
948
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
898
949
|
return resultAndObj;
|
|
899
950
|
}
|
|
900
951
|
|
|
952
|
+
private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
|
|
953
|
+
try {
|
|
954
|
+
return deserializeFunc();
|
|
955
|
+
} catch (err) {
|
|
956
|
+
this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
|
|
957
|
+
err,
|
|
958
|
+
msgId,
|
|
959
|
+
source: source.toString(),
|
|
960
|
+
});
|
|
961
|
+
return undefined;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
901
965
|
protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
|
|
902
966
|
const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
|
|
903
|
-
const tx = Tx.fromBuffer(payloadData);
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
967
|
+
const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
|
|
968
|
+
if (!tx) {
|
|
969
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
973
|
+
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
974
|
+
|
|
975
|
+
// Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
|
|
976
|
+
const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
977
|
+
const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
|
|
978
|
+
if (!firstStageOutcome.allPassed) {
|
|
979
|
+
const { name } = firstStageOutcome.failure;
|
|
980
|
+
let { severity } = firstStageOutcome.failure;
|
|
981
|
+
|
|
982
|
+
// Double spend validator has a special case handler. We perform more detailed examination
|
|
983
|
+
// as to how recently the nullifier was entered into the tree and if the transaction should
|
|
984
|
+
// have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
|
|
985
|
+
if (name === 'doubleSpendValidator') {
|
|
986
|
+
const txBlockNumber = BlockNumber(currentBlockNumber + 1);
|
|
987
|
+
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
|
|
991
|
+
validator: name,
|
|
992
|
+
severity,
|
|
993
|
+
source: source.toString(),
|
|
994
|
+
});
|
|
995
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
// Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
|
|
999
|
+
const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
|
|
1000
|
+
if (canAdd === 'ignored') {
|
|
1001
|
+
this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
|
|
1002
|
+
source: source.toString(),
|
|
1003
|
+
});
|
|
1004
|
+
return { result: TopicValidatorResult.Ignore, obj: tx };
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// Stage 2: expensive proof verification
|
|
1008
|
+
const secondStageValidators = this.createSecondStageMessageValidators();
|
|
1009
|
+
const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
|
|
1010
|
+
if (!secondStageOutcome.allPassed) {
|
|
1011
|
+
const { severity, name } = secondStageOutcome.failure;
|
|
1012
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
|
|
1013
|
+
validator: name,
|
|
1014
|
+
severity,
|
|
1015
|
+
source: source.toString(),
|
|
908
1016
|
});
|
|
909
|
-
return { result: TopicValidatorResult.Reject };
|
|
1017
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
910
1018
|
}
|
|
911
1019
|
|
|
912
|
-
//
|
|
1020
|
+
// Pool add: persist the tx
|
|
913
1021
|
const txHash = tx.getTxHash();
|
|
914
1022
|
const addResult = await this.mempools.txPool.addPendingTxs([tx], { source: 'gossip' });
|
|
915
1023
|
|
|
916
1024
|
const wasAccepted = addResult.accepted.some(h => h.equals(txHash));
|
|
917
1025
|
const wasIgnored = addResult.ignored.some(h => h.equals(txHash));
|
|
918
1026
|
|
|
919
|
-
this.logger.
|
|
920
|
-
isValid,
|
|
1027
|
+
this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
|
|
921
1028
|
wasAccepted,
|
|
922
1029
|
wasIgnored,
|
|
923
1030
|
[Attributes.P2P_ID]: source.toString(),
|
|
@@ -928,7 +1035,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
928
1035
|
} else if (wasIgnored) {
|
|
929
1036
|
return { result: TopicValidatorResult.Ignore, obj: tx };
|
|
930
1037
|
} else {
|
|
931
|
-
|
|
1038
|
+
this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
|
|
1039
|
+
source: source.toString(),
|
|
1040
|
+
txHash: txHash.toString(),
|
|
1041
|
+
});
|
|
1042
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
932
1043
|
}
|
|
933
1044
|
};
|
|
934
1045
|
|
|
@@ -958,7 +1069,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
958
1069
|
source: PeerId,
|
|
959
1070
|
): Promise<void> {
|
|
960
1071
|
const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
|
|
961
|
-
() =>
|
|
1072
|
+
() => {
|
|
1073
|
+
const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
|
|
1074
|
+
if (!attestation) {
|
|
1075
|
+
return Promise.resolve({
|
|
1076
|
+
result: TopicValidatorResult.Reject,
|
|
1077
|
+
severity: PeerErrorSeverity.LowToleranceError,
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
return this.validateAndStoreCheckpointAttestation(source, attestation);
|
|
1081
|
+
},
|
|
962
1082
|
msgId,
|
|
963
1083
|
source,
|
|
964
1084
|
TopicType.checkpoint_attestation,
|
|
@@ -991,8 +1111,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
991
1111
|
|
|
992
1112
|
if (validationResult.result === 'reject') {
|
|
993
1113
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
994
|
-
|
|
995
|
-
return { result: TopicValidatorResult.Reject };
|
|
1114
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
996
1115
|
}
|
|
997
1116
|
|
|
998
1117
|
if (validationResult.result === 'ignore') {
|
|
@@ -1018,16 +1137,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1018
1137
|
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
1019
1138
|
}
|
|
1020
1139
|
|
|
1021
|
-
// Could not add (cap reached for signer),
|
|
1140
|
+
// Could not add (cap reached for signer), penalize and do not re-broadcast
|
|
1022
1141
|
if (!added) {
|
|
1023
|
-
this.logger.warn(`
|
|
1142
|
+
this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
|
|
1024
1143
|
slot: slot.toString(),
|
|
1025
1144
|
archive: attestation.archive.toString(),
|
|
1026
1145
|
source: peerId.toString(),
|
|
1027
1146
|
attester: attestation.getSender()?.toString(),
|
|
1028
1147
|
count,
|
|
1029
1148
|
});
|
|
1030
|
-
return { result: TopicValidatorResult.
|
|
1149
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
1031
1150
|
}
|
|
1032
1151
|
|
|
1033
1152
|
// Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
|
|
@@ -1082,8 +1201,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1082
1201
|
|
|
1083
1202
|
if (validationResult.result === 'reject') {
|
|
1084
1203
|
this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1085
|
-
|
|
1086
|
-
return { result: TopicValidatorResult.Reject };
|
|
1204
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1087
1205
|
}
|
|
1088
1206
|
|
|
1089
1207
|
if (validationResult.result === 'ignore') {
|
|
@@ -1107,7 +1225,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1107
1225
|
|
|
1108
1226
|
// Too many blocks received for this slot and index, penalize peer and do not re-broadcast
|
|
1109
1227
|
if (!added) {
|
|
1110
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1111
1228
|
this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
|
|
1112
1229
|
...block.toBlockInfo(),
|
|
1113
1230
|
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
@@ -1115,7 +1232,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1115
1232
|
proposer: block.getSender()?.toString(),
|
|
1116
1233
|
source: peerId.toString(),
|
|
1117
1234
|
});
|
|
1118
|
-
return {
|
|
1235
|
+
return {
|
|
1236
|
+
result: TopicValidatorResult.Reject,
|
|
1237
|
+
metadata: { isEquivocated },
|
|
1238
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1239
|
+
};
|
|
1119
1240
|
}
|
|
1120
1241
|
|
|
1121
1242
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1160,7 +1281,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1160
1281
|
// Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1161
1282
|
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1162
1283
|
if (!isValid) {
|
|
1163
|
-
this.logger.
|
|
1284
|
+
this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1164
1285
|
}
|
|
1165
1286
|
}
|
|
1166
1287
|
|
|
@@ -1208,8 +1329,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1208
1329
|
|
|
1209
1330
|
if (validationResult.result === 'reject') {
|
|
1210
1331
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1211
|
-
|
|
1212
|
-
return { result: TopicValidatorResult.Reject };
|
|
1332
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1213
1333
|
}
|
|
1214
1334
|
|
|
1215
1335
|
if (validationResult.result === 'ignore') {
|
|
@@ -1224,20 +1344,21 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1224
1344
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1225
1345
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1226
1346
|
});
|
|
1227
|
-
const
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
metadata: { isEquivocated } = {},
|
|
1231
|
-
} = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1232
|
-
if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1347
|
+
const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1348
|
+
const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
|
|
1349
|
+
if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1233
1350
|
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1234
1351
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1235
1352
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1236
1353
|
isEquivocated,
|
|
1237
|
-
result,
|
|
1354
|
+
result: blockProposalResult.result,
|
|
1238
1355
|
});
|
|
1239
|
-
return {
|
|
1240
|
-
|
|
1356
|
+
return {
|
|
1357
|
+
result: TopicValidatorResult.Reject,
|
|
1358
|
+
severity:
|
|
1359
|
+
'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
|
|
1360
|
+
};
|
|
1361
|
+
} else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1241
1362
|
processBlock = true;
|
|
1242
1363
|
}
|
|
1243
1364
|
}
|
|
@@ -1264,13 +1385,17 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1264
1385
|
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1265
1386
|
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1266
1387
|
if (!added) {
|
|
1267
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1268
1388
|
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1269
1389
|
...checkpoint.toCheckpointInfo(),
|
|
1270
1390
|
count,
|
|
1271
1391
|
source: peerId.toString(),
|
|
1272
1392
|
});
|
|
1273
|
-
return {
|
|
1393
|
+
return {
|
|
1394
|
+
result: TopicValidatorResult.Reject,
|
|
1395
|
+
obj: checkpoint,
|
|
1396
|
+
metadata: { isEquivocated, processBlock },
|
|
1397
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1398
|
+
};
|
|
1274
1399
|
}
|
|
1275
1400
|
|
|
1276
1401
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1315,9 +1440,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1315
1440
|
source: sender.toString(),
|
|
1316
1441
|
});
|
|
1317
1442
|
|
|
1443
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
|
|
1444
|
+
|
|
1318
1445
|
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1319
1446
|
// to validate and potentially generate attestations
|
|
1320
|
-
const attestations = await this.
|
|
1447
|
+
const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
|
|
1321
1448
|
if (attestations && attestations.length > 0) {
|
|
1322
1449
|
// If the callback returned attestations, add them to the pool and propagate them
|
|
1323
1450
|
await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
|
|
@@ -1465,53 +1592,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1465
1592
|
}
|
|
1466
1593
|
}
|
|
1467
1594
|
|
|
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
1595
|
protected async validateRequestedTx(
|
|
1516
1596
|
tx: Tx,
|
|
1517
1597
|
peerId: PeerId,
|
|
@@ -1532,52 +1612,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1532
1612
|
}
|
|
1533
1613
|
|
|
1534
1614
|
protected createRequestedTxValidator(): TxValidator {
|
|
1535
|
-
return
|
|
1615
|
+
return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
|
|
1536
1616
|
l1ChainId: this.config.l1ChainId,
|
|
1537
1617
|
rollupVersion: this.config.rollupVersion,
|
|
1538
1618
|
});
|
|
1539
1619
|
}
|
|
1540
1620
|
|
|
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;
|
|
1621
|
+
private getGasFees(): Promise<GasFees> {
|
|
1622
|
+
return this.blockMinFeesProvider.getCurrentMinFees();
|
|
1581
1623
|
}
|
|
1582
1624
|
|
|
1583
1625
|
/**
|
|
@@ -1596,60 +1638,62 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1596
1638
|
};
|
|
1597
1639
|
}
|
|
1598
1640
|
|
|
1599
|
-
public async
|
|
1600
|
-
const
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1641
|
+
public async validateTxsReceivedInBlockProposal(txs: Tx[]): Promise<void> {
|
|
1642
|
+
const validator = createTxValidatorForBlockProposalReceivedTxs(
|
|
1643
|
+
this.proofVerifier,
|
|
1644
|
+
{ l1ChainId: this.config.l1ChainId, rollupVersion: this.config.rollupVersion },
|
|
1645
|
+
this.logger.getBindings(),
|
|
1646
|
+
);
|
|
1605
1647
|
|
|
1606
|
-
await Promise.all(
|
|
1648
|
+
const results = await Promise.all(
|
|
1607
1649
|
txs.map(async tx => {
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
if (!outcome.allPassed) {
|
|
1611
|
-
throw new Error('Invalid tx detected', { cause: { outcome } });
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1650
|
+
const result = await validator.validateTx(tx);
|
|
1651
|
+
return result.result !== 'invalid';
|
|
1614
1652
|
}),
|
|
1615
1653
|
);
|
|
1654
|
+
if (results.some(value => value === false)) {
|
|
1655
|
+
throw new Error('Invalid tx detected');
|
|
1656
|
+
}
|
|
1616
1657
|
}
|
|
1617
1658
|
|
|
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(
|
|
1659
|
+
/** Creates the first stage (fast) validators for gossiped transactions. */
|
|
1660
|
+
protected async createFirstStageMessageValidators(
|
|
1629
1661
|
currentBlockNumber: BlockNumber,
|
|
1630
1662
|
nextSlotTimestamp: UInt64,
|
|
1631
|
-
): Promise<Record<string,
|
|
1632
|
-
const gasFees = await this.getGasFees(
|
|
1633
|
-
const allowedInSetup =
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1663
|
+
): Promise<Record<string, TransactionValidator>> {
|
|
1664
|
+
const gasFees = await this.getGasFees();
|
|
1665
|
+
const allowedInSetup = [
|
|
1666
|
+
...(await getDefaultAllowedSetupFunctions()),
|
|
1667
|
+
...(this.config.txPublicSetupAllowListExtend ?? []),
|
|
1668
|
+
];
|
|
1669
|
+
const blockNumber = BlockNumber(currentBlockNumber + 1);
|
|
1670
|
+
const l1Constants = await this.archiver.getL1Constants();
|
|
1671
|
+
|
|
1672
|
+
return createFirstStageTxValidationsForGossipedTransactions(
|
|
1638
1673
|
nextSlotTimestamp,
|
|
1639
|
-
|
|
1674
|
+
blockNumber,
|
|
1640
1675
|
this.worldStateSynchronizer,
|
|
1641
1676
|
gasFees,
|
|
1642
1677
|
this.config.l1ChainId,
|
|
1643
1678
|
this.config.rollupVersion,
|
|
1644
1679
|
protocolContractsHash,
|
|
1645
1680
|
this.archiver,
|
|
1646
|
-
this.proofVerifier,
|
|
1647
1681
|
!this.config.disableTransactions,
|
|
1648
1682
|
allowedInSetup,
|
|
1649
1683
|
this.logger.getBindings(),
|
|
1684
|
+
{
|
|
1685
|
+
rollupManaLimit: l1Constants.rollupManaLimit,
|
|
1686
|
+
maxBlockL2Gas: this.config.validateMaxL2BlockGas,
|
|
1687
|
+
maxBlockDAGas: this.config.validateMaxDABlockGas,
|
|
1688
|
+
},
|
|
1650
1689
|
);
|
|
1651
1690
|
}
|
|
1652
1691
|
|
|
1692
|
+
/** Creates the second stage (expensive proof verification) validators for gossiped transactions. */
|
|
1693
|
+
protected createSecondStageMessageValidators(): Record<string, TransactionValidator> {
|
|
1694
|
+
return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1653
1697
|
/**
|
|
1654
1698
|
* Run validations on a tx.
|
|
1655
1699
|
* @param tx - The tx to validate.
|
|
@@ -1658,7 +1702,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1658
1702
|
*/
|
|
1659
1703
|
private async runValidations(
|
|
1660
1704
|
tx: Tx,
|
|
1661
|
-
messageValidators: Record<string,
|
|
1705
|
+
messageValidators: Record<string, TransactionValidator>,
|
|
1662
1706
|
): Promise<ValidationOutcome> {
|
|
1663
1707
|
const validationPromises = Object.entries(messageValidators).map(async ([name, { validator, severity }]) => {
|
|
1664
1708
|
const { result } = await validator.validateTx(tx);
|
|
@@ -1667,8 +1711,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1667
1711
|
|
|
1668
1712
|
// A promise that resolves when all validations have been run
|
|
1669
1713
|
const allValidations = await Promise.all(validationPromises);
|
|
1670
|
-
const
|
|
1671
|
-
if (
|
|
1714
|
+
const failures = allValidations.filter(x => !x.isValid);
|
|
1715
|
+
if (failures.length > 0) {
|
|
1716
|
+
// Pick the most severe failure (lowest tolerance = harshest penalty)
|
|
1717
|
+
const failed = maxBy(failures, f => PeerErrorSeverityByHarshness.indexOf(f.severity))!;
|
|
1672
1718
|
return {
|
|
1673
1719
|
allPassed: false,
|
|
1674
1720
|
failure: {
|
|
@@ -1721,31 +1767,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1721
1767
|
return PeerErrorSeverity.HighToleranceError;
|
|
1722
1768
|
}
|
|
1723
1769
|
|
|
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
1770
|
public getPeerScore(peerId: PeerId): number {
|
|
1750
1771
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
1751
1772
|
}
|