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