@aztec/p2p 0.0.1-commit.e558bd1c → 0.0.1-commit.e5a3663dd
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 +10 -9
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +54 -15
- package/dest/client/interface.d.ts +47 -34
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +39 -51
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +173 -226
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +23 -10
- package/dest/config.d.ts +137 -92
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +113 -40
- 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 +2 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +24 -13
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +80 -43
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +57 -57
- package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/index.js +1 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +7 -5
- package/dest/mem_pools/index.d.ts +2 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.d.ts +4 -2
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +33 -15
- package/dest/mem_pools/interface.d.ts +3 -3
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -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 +7 -3
- 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 +7 -5
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +9 -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 +14 -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 +3 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +2 -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 +33 -12
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +5 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +81 -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 +147 -19
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
- 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 +50 -45
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +12 -5
- 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 +17 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +14 -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 +365 -189
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +37 -12
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
- package/dest/msg_validators/clock_tolerance.d.ts +12 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +61 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -4
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -4
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +19 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +88 -44
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
- 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/block_header_validator.d.ts +16 -3
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.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/double_spend_validator.d.ts +13 -3
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
- 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 +20 -4
- 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 +13 -6
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +13 -5
- package/dest/services/encoding.d.ts +7 -3
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +18 -11
- package/dest/services/gossipsub/index.d.ts +3 -0
- package/dest/services/gossipsub/index.d.ts.map +1 -0
- package/dest/services/gossipsub/index.js +2 -0
- package/dest/services/gossipsub/scoring.d.ts +21 -3
- package/dest/services/gossipsub/scoring.d.ts.map +1 -1
- package/dest/services/gossipsub/scoring.js +24 -7
- package/dest/services/gossipsub/topic_score_params.d.ts +184 -0
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
- package/dest/services/gossipsub/topic_score_params.js +363 -0
- 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 +42 -39
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +336 -269
- 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 +57 -12
- 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 +23 -9
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +23 -10
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +0 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +7 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +15 -0
- 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 +7 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +21 -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 +40 -15
- package/dest/services/service.d.ts +26 -4
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +19 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +46 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts +3 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +80 -76
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts +38 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_source.js +100 -0
- package/dest/services/tx_collection/index.d.ts +2 -1
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +1 -0
- 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 +7 -3
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +60 -26
- package/dest/services/tx_collection/tx_collection.d.ts +23 -13
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +75 -3
- package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +26 -29
- 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/config.d.ts +1 -3
- package/dest/services/tx_file_store/config.d.ts.map +1 -1
- package/dest/services/tx_file_store/config.js +0 -4
- package/dest/services/tx_file_store/tx_file_store.d.ts +4 -3
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
- package/dest/services/tx_file_store/tx_file_store.js +9 -6
- package/dest/services/tx_provider.d.ts +4 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +9 -8
- package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
- 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 +40 -6
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +139 -13
- 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 +8 -5
- package/dest/test-helpers/testbench-utils.d.ts +35 -24
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +125 -38
- 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 +84 -27
- 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 +108 -26
- package/src/client/interface.ts +52 -34
- package/src/client/p2p_client.ts +201 -269
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +35 -14
- package/src/config.ts +181 -46
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +109 -53
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +61 -57
- package/src/mem_pools/attestation_pool/index.ts +3 -3
- package/src/mem_pools/attestation_pool/mocks.ts +14 -8
- package/src/mem_pools/index.ts +1 -1
- package/src/mem_pools/instrumentation.ts +22 -14
- package/src/mem_pools/interface.ts +2 -2
- package/src/mem_pools/tx_pool_v2/README.md +85 -11
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -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 +7 -3
- 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 +5 -5
- 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 +14 -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 +2 -1
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +35 -12
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +215 -27
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +58 -45
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +34 -8
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +412 -187
- package/src/msg_validators/attestation_validator/README.md +49 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -9
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +12 -2
- package/src/msg_validators/clock_tolerance.ts +79 -3
- package/src/msg_validators/proposal_validator/README.md +123 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +23 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +34 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +111 -47
- package/src/msg_validators/tx_validator/README.md +127 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
- 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/block_header_validator.ts +15 -3
- 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/double_spend_validator.ts +11 -6
- 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 +23 -18
- package/src/services/data_store.ts +5 -13
- package/src/services/dummy_service.ts +19 -7
- package/src/services/encoding.ts +18 -10
- package/src/services/gossipsub/README.md +641 -0
- package/src/services/gossipsub/index.ts +2 -0
- package/src/services/gossipsub/scoring.ts +29 -5
- package/src/services/gossipsub/topic_score_params.ts +519 -0
- package/src/services/libp2p/instrumentation.ts +14 -0
- package/src/services/libp2p/libp2p_service.ts +358 -298
- 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 +52 -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 +45 -10
- package/src/services/reqresp/metrics.ts +0 -1
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +2 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +17 -0
- package/src/services/reqresp/protocols/index.ts +0 -1
- package/src/services/reqresp/protocols/tx.ts +23 -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 +53 -16
- package/src/services/service.ts +37 -3
- package/src/services/tx_collection/config.ts +68 -0
- package/src/services/tx_collection/fast_tx_collection.ts +83 -76
- package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
- package/src/services/tx_collection/file_store_tx_source.ts +129 -0
- package/src/services/tx_collection/index.ts +1 -0
- 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 +66 -33
- package/src/services/tx_collection/tx_collection.ts +114 -19
- package/src/services/tx_collection/tx_collection_sink.ts +30 -34
- package/src/services/tx_collection/tx_source.ts +28 -8
- package/src/services/tx_file_store/config.ts +0 -6
- package/src/services/tx_file_store/tx_file_store.ts +10 -8
- package/src/services/tx_provider.ts +10 -9
- package/src/test-helpers/make-test-p2p-clients.ts +6 -6
- package/src/test-helpers/mock-pubsub.ts +180 -14
- package/src/test-helpers/reqresp-nodes.ts +9 -9
- package/src/test-helpers/testbench-utils.ts +147 -43
- package/src/testbench/p2p_client_testbench_worker.ts +93 -30
- 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
|
@@ -370,21 +370,20 @@ function applyDecs2203RFactory() {
|
|
|
370
370
|
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
371
371
|
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
372
372
|
}
|
|
373
|
-
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6,
|
|
373
|
+
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _initProto;
|
|
374
374
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
375
|
-
import {
|
|
375
|
+
import { maxBy, merge } from '@aztec/foundation/collection';
|
|
376
376
|
import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
377
377
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
378
378
|
import { Timer } from '@aztec/foundation/timer';
|
|
379
379
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
380
|
-
import {
|
|
381
|
-
import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PClientType, P2PMessage, PeerErrorSeverity, TopicType, createTopicString, getTopicsForClientAndConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
|
|
380
|
+
import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PMessage, PeerErrorSeverity, PeerErrorSeverityByHarshness, TopicType, createTopicString, getTopicsForConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
|
|
382
381
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
383
382
|
import { Tx } from '@aztec/stdlib/tx';
|
|
384
383
|
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
385
384
|
import { Attributes, OtelMetricsAdapter, SpanStatusCode, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
386
385
|
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
387
|
-
import { createPeerScoreParams
|
|
386
|
+
import { createPeerScoreParams } from '@chainsafe/libp2p-gossipsub/score';
|
|
388
387
|
import { SignaturePolicy } from '@chainsafe/libp2p-gossipsub/types';
|
|
389
388
|
import { noise } from '@chainsafe/libp2p-noise';
|
|
390
389
|
import { yamux } from '@chainsafe/libp2p-yamux';
|
|
@@ -395,20 +394,21 @@ import { mplex } from '@libp2p/mplex';
|
|
|
395
394
|
import { tcp } from '@libp2p/tcp';
|
|
396
395
|
import { ENR } from '@nethermindeth/enr';
|
|
397
396
|
import { createLibp2p } from 'libp2p';
|
|
397
|
+
import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
|
|
398
398
|
import { BlockProposalValidator, CheckpointAttestationValidator, CheckpointProposalValidator, DoubleSpendTxValidator, FishermanAttestationValidator, getDefaultAllowedSetupFunctions } from '../../msg_validators/index.js';
|
|
399
399
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
400
|
-
import {
|
|
400
|
+
import { createFirstStageTxValidationsForGossipedTransactions, createSecondStageTxValidationsForGossipedTransactions, createTxValidatorForBlockProposalReceivedTxs, createTxValidatorForReqResponseReceivedTxs } from '../../msg_validators/tx_validator/factory.js';
|
|
401
401
|
import { GossipSubEvent } from '../../types/index.js';
|
|
402
402
|
import { convertToMultiaddr } from '../../util.js';
|
|
403
403
|
import { getVersions } from '../../versioning.js';
|
|
404
404
|
import { AztecDatastore } from '../data_store.js';
|
|
405
405
|
import { DiscV5Service } from '../discv5/discV5_service.js';
|
|
406
406
|
import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
|
|
407
|
-
import { gossipScoreThresholds } from '../gossipsub/scoring.js';
|
|
407
|
+
import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring.js';
|
|
408
|
+
import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
|
|
408
409
|
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
409
410
|
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
410
|
-
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError } from '../reqresp/index.js';
|
|
411
|
-
import { pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
|
|
411
|
+
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError, pingHandler, reqGoodbyeHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
|
|
412
412
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
413
413
|
import { P2PInstrumentation } from './instrumentation.js';
|
|
414
414
|
_dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation)=>({
|
|
@@ -430,19 +430,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
430
430
|
[Attributes.BLOCK_ARCHIVE]: request.archiveRoot.toString()
|
|
431
431
|
})), _dec6 = trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx)=>({
|
|
432
432
|
[Attributes.TX_HASH]: requestedTxHash.toString()
|
|
433
|
-
})), _dec7 = trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock)=>({
|
|
434
|
-
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString()
|
|
435
|
-
})), _dec8 = trackSpan('Libp2pService.validatePropagatedTx', (tx)=>({
|
|
436
|
-
[Attributes.TX_HASH]: tx.getTxHash().toString()
|
|
437
|
-
})), _dec9 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
|
|
438
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
439
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
440
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then((i)=>i.toString())
|
|
441
433
|
}));
|
|
442
434
|
/**
|
|
443
435
|
* Lib P2P implementation of the P2PService interface.
|
|
444
436
|
*/ export class LibP2PService extends WithTracer {
|
|
445
|
-
clientType;
|
|
446
437
|
config;
|
|
447
438
|
node;
|
|
448
439
|
peerDiscoveryService;
|
|
@@ -453,6 +444,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
453
444
|
epochCache;
|
|
454
445
|
proofVerifier;
|
|
455
446
|
worldStateSynchronizer;
|
|
447
|
+
blockMinFeesProvider;
|
|
456
448
|
static{
|
|
457
449
|
({ e: [_initProto] } = _apply_decs_2203_r(this, [
|
|
458
450
|
[
|
|
@@ -489,21 +481,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
489
481
|
_dec6,
|
|
490
482
|
2,
|
|
491
483
|
"validateRequestedTxs"
|
|
492
|
-
],
|
|
493
|
-
[
|
|
494
|
-
_dec7,
|
|
495
|
-
2,
|
|
496
|
-
"validateRequestedBlock"
|
|
497
|
-
],
|
|
498
|
-
[
|
|
499
|
-
_dec8,
|
|
500
|
-
2,
|
|
501
|
-
"validatePropagatedTx"
|
|
502
|
-
],
|
|
503
|
-
[
|
|
504
|
-
_dec9,
|
|
505
|
-
2,
|
|
506
|
-
"validateCheckpointAttestation"
|
|
507
484
|
]
|
|
508
485
|
], []));
|
|
509
486
|
}
|
|
@@ -515,8 +492,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
515
492
|
checkpointAttestationValidator;
|
|
516
493
|
protocolVersion;
|
|
517
494
|
topicStrings;
|
|
518
|
-
feesCache;
|
|
519
495
|
/** Callback invoked when a duplicate proposal is detected (triggers slashing). */ duplicateProposalCallback;
|
|
496
|
+
/** Callback invoked when a duplicate attestation is detected (triggers slashing). */ duplicateAttestationCallback;
|
|
520
497
|
/**
|
|
521
498
|
* Callback for when a block is received from a peer.
|
|
522
499
|
* @param block - The block received from the peer.
|
|
@@ -526,13 +503,18 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
526
503
|
* Callback for when a checkpoint proposal is received from a peer.
|
|
527
504
|
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
528
505
|
* @returns The attestations for the checkpoint, if any.
|
|
529
|
-
*/
|
|
506
|
+
*/ allNodesCheckpointReceivedCallback;
|
|
507
|
+
/**
|
|
508
|
+
* Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
|
|
509
|
+
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
510
|
+
* @returns The attestations for the checkpoint, if any.
|
|
511
|
+
*/ validatorCheckpointReceivedCallback;
|
|
530
512
|
gossipSubEventHandler;
|
|
531
513
|
instrumentation;
|
|
532
514
|
telemetry;
|
|
533
515
|
logger;
|
|
534
|
-
constructor(
|
|
535
|
-
super(telemetry, 'LibP2PService'), this.
|
|
516
|
+
constructor(config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, blockMinFeesProvider, telemetry, logger = createLogger('p2p:libp2p_service')){
|
|
517
|
+
super(telemetry, 'LibP2PService'), this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.reqresp = reqresp, this.peerManager = peerManager, this.mempools = mempools, this.archiver = archiver, this.epochCache = epochCache, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.blockMinFeesProvider = blockMinFeesProvider, this.msgIdSeenValidators = (_initProto(this), {}), this.protocolVersion = '', this.topicStrings = {};
|
|
536
518
|
this.telemetry = telemetry;
|
|
537
519
|
// Create child logger with fisherman prefix if in fisherman mode
|
|
538
520
|
this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
|
|
@@ -548,35 +530,50 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
548
530
|
this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
|
|
549
531
|
this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
|
|
550
532
|
this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
533
|
+
const p2pPropagationTime = config.attestationPropagationTime;
|
|
534
|
+
const proposalValidatorOpts = {
|
|
535
|
+
txsPermitted: !config.disableTransactions,
|
|
536
|
+
maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
|
|
537
|
+
maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint,
|
|
538
|
+
p2pPropagationTime,
|
|
539
|
+
signatureContext: {
|
|
540
|
+
chainId: config.l1ChainId,
|
|
541
|
+
rollupAddress: config.l1Contracts.rollupAddress
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
|
|
545
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
|
|
546
|
+
const attestationValidatorOpts = {
|
|
547
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
548
|
+
p2pPropagationTime,
|
|
549
|
+
signatureContext: proposalValidatorOpts.signatureContext
|
|
550
|
+
};
|
|
551
|
+
this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, attestationValidatorOpts) : new CheckpointAttestationValidator(epochCache, attestationValidatorOpts);
|
|
558
552
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
559
553
|
this.blockReceivedCallback = async (block)=>{
|
|
560
|
-
this.logger.
|
|
554
|
+
this.logger.warn(`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`, {
|
|
561
555
|
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier()
|
|
562
556
|
});
|
|
563
|
-
return
|
|
557
|
+
return true;
|
|
564
558
|
};
|
|
565
|
-
this.
|
|
566
|
-
|
|
559
|
+
this.allNodesCheckpointReceivedCallback = (_checkpoint)=>{
|
|
560
|
+
throw new CheckpointProposalReceivedCallbackNotRegisteredError();
|
|
561
|
+
};
|
|
562
|
+
this.validatorCheckpointReceivedCallback = (_checkpoint)=>{
|
|
567
563
|
return Promise.resolve(undefined);
|
|
568
564
|
};
|
|
569
565
|
}
|
|
570
566
|
updateConfig(config) {
|
|
571
567
|
this.reqresp.updateConfig(config);
|
|
568
|
+
this.config = merge(this.config, config);
|
|
572
569
|
}
|
|
573
570
|
/**
|
|
574
571
|
* Creates an instance of the LibP2P service.
|
|
575
572
|
* @param config - The configuration to use when creating the service.
|
|
576
573
|
* @param txPool - The transaction pool to be accessed by the service.
|
|
577
574
|
* @returns The new service.
|
|
578
|
-
*/ static async new(
|
|
579
|
-
const { worldStateSynchronizer, epochCache, l2BlockSource, mempools, proofVerifier, peerStore, telemetry, logger, packageVersion } = deps;
|
|
575
|
+
*/ static async new(config, peerId, deps) {
|
|
576
|
+
const { worldStateSynchronizer, epochCache, l2BlockSource, mempools, proofVerifier, peerStore, blockMinFeesProvider, telemetry, logger, packageVersion } = deps;
|
|
580
577
|
const { p2pPort, maxPeerCount, listenAddress } = config;
|
|
581
578
|
const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
|
|
582
579
|
const datastore = new AztecDatastore(peerStore);
|
|
@@ -595,10 +592,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
595
592
|
}
|
|
596
593
|
const versions = getVersions(config);
|
|
597
594
|
const protocolVersion = compressComponentVersions(versions);
|
|
598
|
-
const txTopic = createTopicString(TopicType.tx, protocolVersion);
|
|
599
|
-
const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
|
|
600
|
-
const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
|
|
601
|
-
const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
|
|
602
595
|
const preferredPeersEnrs = config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
|
|
603
596
|
const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
|
|
604
597
|
const peerId = await enr.peerId();
|
|
@@ -616,6 +609,18 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
616
609
|
const announceTcpMultiaddr = config.p2pIp ? [
|
|
617
610
|
convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')
|
|
618
611
|
] : [];
|
|
612
|
+
// Create dynamic topic score params based on network configuration
|
|
613
|
+
const l1Constants = epochCache.getL1Constants();
|
|
614
|
+
const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
|
|
615
|
+
slotDurationMs: l1Constants.slotDuration * 1000,
|
|
616
|
+
ethereumSlotDuration: l1Constants.ethereumSlotDuration,
|
|
617
|
+
heartbeatIntervalMs: config.gossipsubInterval,
|
|
618
|
+
targetCommitteeSize: l1Constants.targetCommitteeSize,
|
|
619
|
+
blockDurationMs: config.blockDurationMs,
|
|
620
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
621
|
+
p2pPropagationTime: config.attestationPropagationTime,
|
|
622
|
+
expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot
|
|
623
|
+
});
|
|
619
624
|
const node = await createLibp2p({
|
|
620
625
|
start: false,
|
|
621
626
|
peerId,
|
|
@@ -716,28 +721,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
716
721
|
scoreParams: createPeerScoreParams({
|
|
717
722
|
// IPColocation factor can be disabled for local testing - default to -5
|
|
718
723
|
IPColocationFactorWeight: config.debugDisableColocationPenalty ? 0 : -5.0,
|
|
719
|
-
topics:
|
|
720
|
-
[txTopic]: createTopicScoreParams({
|
|
721
|
-
topicWeight: 1,
|
|
722
|
-
invalidMessageDeliveriesWeight: -20,
|
|
723
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
724
|
-
}),
|
|
725
|
-
[blockProposalTopic]: createTopicScoreParams({
|
|
726
|
-
topicWeight: 1,
|
|
727
|
-
invalidMessageDeliveriesWeight: -20,
|
|
728
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
729
|
-
}),
|
|
730
|
-
[checkpointProposalTopic]: createTopicScoreParams({
|
|
731
|
-
topicWeight: 1,
|
|
732
|
-
invalidMessageDeliveriesWeight: -20,
|
|
733
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
734
|
-
}),
|
|
735
|
-
[checkpointAttestationTopic]: createTopicScoreParams({
|
|
736
|
-
topicWeight: 1,
|
|
737
|
-
invalidMessageDeliveriesWeight: -20,
|
|
738
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
739
|
-
})
|
|
740
|
-
}
|
|
724
|
+
topics: topicScoreParams
|
|
741
725
|
})
|
|
742
726
|
}),
|
|
743
727
|
components: (components)=>({
|
|
@@ -749,10 +733,16 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
749
733
|
const peerScoring = new PeerScoring(config, telemetry);
|
|
750
734
|
const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
|
|
751
735
|
const peerManager = new PeerManager(node, peerDiscoveryService, config, telemetry, createLogger(`${logger.module}:peer_manager`), peerScoring, reqresp, worldStateSynchronizer, protocolVersion, epochCache);
|
|
752
|
-
//
|
|
753
|
-
|
|
736
|
+
// Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
|
|
737
|
+
reqresp.setShouldRejectPeer((peerId)=>peerManager.shouldDisableP2PGossip(peerId));
|
|
738
|
+
// Configure application-specific scoring for gossipsub.
|
|
739
|
+
// The weight scales app score to align with gossipsub thresholds:
|
|
740
|
+
// - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
|
|
741
|
+
// - Ban (-100) × 10 = -1000 = publishThreshold (cannot publish)
|
|
742
|
+
// Note: positive topic scores can offset penalties, so alignment is best-effort.
|
|
743
|
+
node.services.pubsub.score.params.appSpecificWeight = APP_SPECIFIC_WEIGHT;
|
|
754
744
|
node.services.pubsub.score.params.appSpecificScore = (peerId)=>peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
755
|
-
return new LibP2PService(
|
|
745
|
+
return new LibP2PService(config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, blockMinFeesProvider, telemetry, logger);
|
|
756
746
|
}
|
|
757
747
|
/**
|
|
758
748
|
* Starts the LibP2P service.
|
|
@@ -771,13 +761,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
771
761
|
// Create request response protocol handlers
|
|
772
762
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
773
763
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
774
|
-
const blockHandler = reqRespBlockHandler(this.archiver);
|
|
775
764
|
const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
|
|
776
765
|
const requestResponseHandlers = {
|
|
777
766
|
[ReqRespSubProtocol.PING]: pingHandler,
|
|
778
767
|
[ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
|
|
779
|
-
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this)
|
|
780
|
-
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this)
|
|
768
|
+
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this)
|
|
781
769
|
};
|
|
782
770
|
if (!this.config.disableTransactions) {
|
|
783
771
|
const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.archiver, this.mempools.txPool);
|
|
@@ -790,14 +778,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
790
778
|
const reqrespSubProtocolValidators = {
|
|
791
779
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
792
780
|
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
793
|
-
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this)
|
|
794
|
-
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this)
|
|
781
|
+
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this)
|
|
795
782
|
};
|
|
796
783
|
await this.peerManager.initializePeers();
|
|
797
784
|
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
798
785
|
await this.node.start();
|
|
799
786
|
// Subscribe to standard GossipSub topics by default
|
|
800
|
-
for (const topic of
|
|
787
|
+
for (const topic of getTopicsForConfig(this.config.disableTransactions)){
|
|
801
788
|
this.subscribeToTopic(this.topicStrings[topic]);
|
|
802
789
|
}
|
|
803
790
|
// add GossipSub listener
|
|
@@ -845,6 +832,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
845
832
|
getPeers(includePending) {
|
|
846
833
|
return this.peerManager.getPeers(includePending);
|
|
847
834
|
}
|
|
835
|
+
getGossipMeshPeerCount(topicType) {
|
|
836
|
+
return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
|
|
837
|
+
}
|
|
848
838
|
handleGossipSubEvent(e) {
|
|
849
839
|
this.logger.trace(`Received PUBSUB message.`);
|
|
850
840
|
const safeJob = async ()=>{
|
|
@@ -876,8 +866,14 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
876
866
|
registerBlockReceivedCallback(callback) {
|
|
877
867
|
this.blockReceivedCallback = callback;
|
|
878
868
|
}
|
|
879
|
-
|
|
880
|
-
this.
|
|
869
|
+
registerValidatorCheckpointReceivedCallback(callback) {
|
|
870
|
+
this.validatorCheckpointReceivedCallback = callback;
|
|
871
|
+
}
|
|
872
|
+
registerAllNodesCheckpointReceivedCallback(callback) {
|
|
873
|
+
this.allNodesCheckpointReceivedCallback = callback;
|
|
874
|
+
}
|
|
875
|
+
async notifyOwnCheckpointProposal(checkpoint) {
|
|
876
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
|
|
881
877
|
}
|
|
882
878
|
/**
|
|
883
879
|
* Registers a callback to be invoked when a duplicate proposal is detected.
|
|
@@ -886,6 +882,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
886
882
|
this.duplicateProposalCallback = callback;
|
|
887
883
|
}
|
|
888
884
|
/**
|
|
885
|
+
* Registers a callback to be invoked when a duplicate attestation is detected.
|
|
886
|
+
* A validator signing attestations for different proposals at the same slot.
|
|
887
|
+
* This callback is triggered on the first duplicate (when count goes from 1 to 2).
|
|
888
|
+
*/ registerDuplicateAttestationCallback(callback) {
|
|
889
|
+
this.duplicateAttestationCallback = callback;
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
889
892
|
* Subscribes to a topic.
|
|
890
893
|
* @param topic - The topic to subscribe to.
|
|
891
894
|
*/ subscribeToTopic(topic) {
|
|
@@ -936,6 +939,12 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
936
939
|
if (!validator || !validator.addMessage(msgId)) {
|
|
937
940
|
this.instrumentation.incMessagePrevalidationStatus(false, topicType);
|
|
938
941
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
942
|
+
if (topicType === TopicType.tx) {
|
|
943
|
+
this.logger.verbose(`Ignoring already-seen tx gossip message`, {
|
|
944
|
+
msgId,
|
|
945
|
+
source: source.toString()
|
|
946
|
+
});
|
|
947
|
+
}
|
|
939
948
|
return {
|
|
940
949
|
result: false,
|
|
941
950
|
topicType
|
|
@@ -993,12 +1002,17 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
993
1002
|
}
|
|
994
1003
|
// Process the message, optionally within a linked span for trace propagation
|
|
995
1004
|
const processMessage = async ()=>{
|
|
1005
|
+
if (this.config.skipIncomingProposals && (msg.topic === this.topicStrings[TopicType.block_proposal] || msg.topic === this.topicStrings[TopicType.checkpoint_proposal])) {
|
|
1006
|
+
this.logger.warn(`Ignoring incoming proposal (skipIncomingProposals is set)`, {
|
|
1007
|
+
topic: msg.topic
|
|
1008
|
+
});
|
|
1009
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
996
1012
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
997
1013
|
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
998
1014
|
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
999
|
-
|
|
1000
|
-
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
1001
|
-
}
|
|
1015
|
+
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
1002
1016
|
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
1003
1017
|
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
1004
1018
|
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
@@ -1043,49 +1057,162 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1043
1057
|
return;
|
|
1044
1058
|
}
|
|
1045
1059
|
async validateReceivedMessage(validationFunc, msgId, source, topicType) {
|
|
1060
|
+
// Default to reject result with a penalty if validation function throws an error
|
|
1046
1061
|
let resultAndObj = {
|
|
1047
|
-
result: TopicValidatorResult.Reject
|
|
1062
|
+
result: TopicValidatorResult.Reject,
|
|
1063
|
+
severity: PeerErrorSeverity.MidToleranceError
|
|
1048
1064
|
};
|
|
1049
1065
|
const timer = new Timer();
|
|
1050
1066
|
try {
|
|
1051
1067
|
resultAndObj = await validationFunc();
|
|
1052
1068
|
} catch (err) {
|
|
1053
|
-
this.
|
|
1054
|
-
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
1069
|
+
this.logger.error(`Error validating gossipsub message`, err, {
|
|
1055
1070
|
msgId,
|
|
1056
1071
|
source: source.toString(),
|
|
1057
1072
|
topicType
|
|
1058
1073
|
});
|
|
1059
1074
|
}
|
|
1075
|
+
const validationTimeMs = timer.ms();
|
|
1076
|
+
const mcacheWindowMs = this.config.gossipsubMcacheLength * this.config.gossipsubInterval;
|
|
1077
|
+
if (validationTimeMs > mcacheWindowMs * 0.75) {
|
|
1078
|
+
this.instrumentation.incSlowValidation(topicType);
|
|
1079
|
+
this.logger.warn(`Gossip validation for ${topicType} took ${validationTimeMs}ms, approaching mcache eviction window of ${mcacheWindowMs}ms. ` + `Message forwarding may be skipped if validation exceeds the window.`, {
|
|
1080
|
+
msgId,
|
|
1081
|
+
source: source.toString(),
|
|
1082
|
+
topicType,
|
|
1083
|
+
validationTimeMs,
|
|
1084
|
+
mcacheWindowMs
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1060
1087
|
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
1088
|
+
this.logger.debug(`Message ${topicType} accepted by validator`, {
|
|
1089
|
+
msgId,
|
|
1090
|
+
source: source.toString(),
|
|
1091
|
+
topicType
|
|
1092
|
+
});
|
|
1061
1093
|
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
1094
|
+
} else if (resultAndObj.result === TopicValidatorResult.Reject) {
|
|
1095
|
+
this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
|
|
1096
|
+
msgId,
|
|
1097
|
+
source: source.toString(),
|
|
1098
|
+
topicType,
|
|
1099
|
+
severity: resultAndObj.severity
|
|
1100
|
+
});
|
|
1101
|
+
this.peerManager.penalizePeer(source, resultAndObj.severity);
|
|
1102
|
+
} else {
|
|
1103
|
+
this.logger.trace(`Message ${topicType} ignored by validator`, {
|
|
1104
|
+
msgId,
|
|
1105
|
+
source: source.toString(),
|
|
1106
|
+
topicType
|
|
1107
|
+
});
|
|
1062
1108
|
}
|
|
1063
1109
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
1064
1110
|
return resultAndObj;
|
|
1065
1111
|
}
|
|
1112
|
+
tryDeserialize(deserializeFunc, msgId, source) {
|
|
1113
|
+
try {
|
|
1114
|
+
return deserializeFunc();
|
|
1115
|
+
} catch (err) {
|
|
1116
|
+
this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
|
|
1117
|
+
err,
|
|
1118
|
+
msgId,
|
|
1119
|
+
source: source.toString()
|
|
1120
|
+
});
|
|
1121
|
+
return undefined;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1066
1124
|
async handleGossipedTx(payloadData, msgId, source) {
|
|
1067
1125
|
const validationFunc = async ()=>{
|
|
1068
|
-
const tx = Tx.fromBuffer(payloadData);
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1126
|
+
const tx = this.tryDeserialize(()=>Tx.fromBuffer(payloadData), msgId, source);
|
|
1127
|
+
if (!tx) {
|
|
1128
|
+
return {
|
|
1129
|
+
result: TopicValidatorResult.Reject,
|
|
1130
|
+
severity: PeerErrorSeverity.LowToleranceError
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1134
|
+
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1135
|
+
// Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
|
|
1136
|
+
const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1137
|
+
const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
|
|
1138
|
+
if (!firstStageOutcome.allPassed) {
|
|
1139
|
+
const { name } = firstStageOutcome.failure;
|
|
1140
|
+
let { severity } = firstStageOutcome.failure;
|
|
1141
|
+
// Double spend validator has a special case handler. We perform more detailed examination
|
|
1142
|
+
// as to how recently the nullifier was entered into the tree and if the transaction should
|
|
1143
|
+
// have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
|
|
1144
|
+
if (name === 'doubleSpendValidator') {
|
|
1145
|
+
const txBlockNumber = BlockNumber(currentBlockNumber + 1);
|
|
1146
|
+
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1147
|
+
}
|
|
1148
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
|
|
1149
|
+
validator: name,
|
|
1150
|
+
severity,
|
|
1151
|
+
source: source.toString()
|
|
1152
|
+
});
|
|
1153
|
+
return {
|
|
1154
|
+
result: TopicValidatorResult.Reject,
|
|
1155
|
+
severity
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
// Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
|
|
1159
|
+
const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
|
|
1160
|
+
if (canAdd === 'ignored') {
|
|
1161
|
+
this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
|
|
1162
|
+
source: source.toString()
|
|
1163
|
+
});
|
|
1164
|
+
return {
|
|
1165
|
+
result: TopicValidatorResult.Ignore,
|
|
1166
|
+
obj: tx
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
// Stage 2: expensive proof verification
|
|
1170
|
+
const secondStageValidators = this.createSecondStageMessageValidators();
|
|
1171
|
+
const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
|
|
1172
|
+
if (!secondStageOutcome.allPassed) {
|
|
1173
|
+
const { severity, name } = secondStageOutcome.failure;
|
|
1174
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
|
|
1175
|
+
validator: name,
|
|
1176
|
+
severity,
|
|
1177
|
+
source: source.toString()
|
|
1178
|
+
});
|
|
1179
|
+
return {
|
|
1180
|
+
result: TopicValidatorResult.Reject,
|
|
1181
|
+
severity
|
|
1182
|
+
};
|
|
1183
|
+
}
|
|
1184
|
+
// Pool add: persist the tx
|
|
1185
|
+
const txHash = tx.getTxHash();
|
|
1186
|
+
const addResult = await this.mempools.txPool.addPendingTxs([
|
|
1187
|
+
tx
|
|
1188
|
+
], {
|
|
1189
|
+
source: 'gossip'
|
|
1190
|
+
});
|
|
1191
|
+
const wasAccepted = addResult.accepted.some((h)=>h.equals(txHash));
|
|
1192
|
+
const wasIgnored = addResult.ignored.some((h)=>h.equals(txHash));
|
|
1193
|
+
this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
|
|
1194
|
+
wasAccepted,
|
|
1195
|
+
wasIgnored,
|
|
1074
1196
|
[Attributes.P2P_ID]: source.toString()
|
|
1075
1197
|
});
|
|
1076
|
-
if (
|
|
1198
|
+
if (wasAccepted) {
|
|
1077
1199
|
return {
|
|
1078
|
-
result: TopicValidatorResult.
|
|
1200
|
+
result: TopicValidatorResult.Accept,
|
|
1201
|
+
obj: tx
|
|
1079
1202
|
};
|
|
1080
|
-
} else if (
|
|
1203
|
+
} else if (wasIgnored) {
|
|
1081
1204
|
return {
|
|
1082
1205
|
result: TopicValidatorResult.Ignore,
|
|
1083
1206
|
obj: tx
|
|
1084
1207
|
};
|
|
1085
1208
|
} else {
|
|
1209
|
+
this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
|
|
1210
|
+
source: source.toString(),
|
|
1211
|
+
txHash: txHash.toString()
|
|
1212
|
+
});
|
|
1086
1213
|
return {
|
|
1087
|
-
result: TopicValidatorResult.
|
|
1088
|
-
|
|
1214
|
+
result: TopicValidatorResult.Reject,
|
|
1215
|
+
severity: PeerErrorSeverity.HighToleranceError
|
|
1089
1216
|
};
|
|
1090
1217
|
}
|
|
1091
1218
|
};
|
|
@@ -1093,26 +1220,29 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1093
1220
|
if (result !== TopicValidatorResult.Accept || !tx) {
|
|
1094
1221
|
return;
|
|
1095
1222
|
}
|
|
1223
|
+
// Tx was accepted into pool and will be propagated - just log and record metrics
|
|
1096
1224
|
const txHash = tx.getTxHash();
|
|
1097
1225
|
const txHashString = txHash.toString();
|
|
1098
1226
|
this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
|
|
1099
1227
|
source: source.toString(),
|
|
1100
1228
|
txHash: txHashString
|
|
1101
1229
|
});
|
|
1102
|
-
if (this.config.dropTransactions && randomInt(1000) < this.config.dropTransactionsProbability * 1000) {
|
|
1103
|
-
this.logger.warn(`Intentionally dropping tx ${txHashString} (probability rule)`);
|
|
1104
|
-
return;
|
|
1105
|
-
}
|
|
1106
1230
|
this.instrumentation.incrementTxReceived(1);
|
|
1107
|
-
await this.mempools.txPool.addTxs([
|
|
1108
|
-
tx
|
|
1109
|
-
]);
|
|
1110
1231
|
}
|
|
1111
1232
|
/**
|
|
1112
1233
|
* Process a checkpoint attestation from a peer.
|
|
1113
1234
|
* Validates the attestation and adds it to the pool.
|
|
1114
1235
|
*/ async processCheckpointAttestationFromPeer(payloadData, msgId, source) {
|
|
1115
|
-
const { result, obj: attestation } = await this.validateReceivedMessage(()=>
|
|
1236
|
+
const { result, obj: attestation } = await this.validateReceivedMessage(()=>{
|
|
1237
|
+
const attestation = this.tryDeserialize(()=>CheckpointAttestation.fromBuffer(payloadData), msgId, source);
|
|
1238
|
+
if (!attestation) {
|
|
1239
|
+
return Promise.resolve({
|
|
1240
|
+
result: TopicValidatorResult.Reject,
|
|
1241
|
+
severity: PeerErrorSeverity.LowToleranceError
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1244
|
+
return this.validateAndStoreCheckpointAttestation(source, attestation);
|
|
1245
|
+
}, msgId, source, TopicType.checkpoint_attestation);
|
|
1116
1246
|
if (result !== TopicValidatorResult.Accept || !attestation) {
|
|
1117
1247
|
return;
|
|
1118
1248
|
}
|
|
@@ -1127,9 +1257,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1127
1257
|
const validationResult = await this.checkpointAttestationValidator.validate(attestation);
|
|
1128
1258
|
if (validationResult.result === 'reject') {
|
|
1129
1259
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1130
|
-
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1131
1260
|
return {
|
|
1132
|
-
result: TopicValidatorResult.Reject
|
|
1261
|
+
result: TopicValidatorResult.Reject,
|
|
1262
|
+
severity: validationResult.severity
|
|
1133
1263
|
};
|
|
1134
1264
|
}
|
|
1135
1265
|
if (validationResult.result === 'ignore') {
|
|
@@ -1138,38 +1268,56 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1138
1268
|
obj: attestation
|
|
1139
1269
|
};
|
|
1140
1270
|
}
|
|
1141
|
-
// Get committee size for the attestation's slot
|
|
1142
|
-
const slot = attestation.payload.header.slotNumber;
|
|
1143
|
-
const { committee } = await this.epochCache.getCommittee(slot);
|
|
1144
|
-
const committeeSize = committee?.length ?? 0;
|
|
1145
1271
|
// Try to add the attestation: this handles existence check, cap check, and adding in one call
|
|
1146
|
-
|
|
1272
|
+
// count is the number of attestations by this signer for this slot (for duplicate detection)
|
|
1273
|
+
const slot = attestation.payload.header.slotNumber;
|
|
1274
|
+
const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddCheckpointAttestation(attestation);
|
|
1147
1275
|
this.logger.trace(`Validate propagated checkpoint attestation`, {
|
|
1148
1276
|
added,
|
|
1149
1277
|
alreadyExists,
|
|
1278
|
+
count,
|
|
1150
1279
|
[Attributes.SLOT_NUMBER]: slot.toString(),
|
|
1151
1280
|
[Attributes.P2P_ID]: peerId.toString()
|
|
1152
1281
|
});
|
|
1153
|
-
//
|
|
1282
|
+
// Exact same attestation received, no need to re-broadcast
|
|
1154
1283
|
if (alreadyExists) {
|
|
1155
1284
|
return {
|
|
1156
1285
|
result: TopicValidatorResult.Ignore,
|
|
1157
1286
|
obj: attestation
|
|
1158
1287
|
};
|
|
1159
1288
|
}
|
|
1160
|
-
// Could not add (cap reached),
|
|
1289
|
+
// Could not add (cap reached for signer), penalize and do not re-broadcast
|
|
1161
1290
|
if (!added) {
|
|
1162
|
-
this.logger.warn(`
|
|
1291
|
+
this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
|
|
1163
1292
|
slot: slot.toString(),
|
|
1164
1293
|
archive: attestation.archive.toString(),
|
|
1165
|
-
source: peerId.toString()
|
|
1294
|
+
source: peerId.toString(),
|
|
1295
|
+
attester: attestation.getSender()?.toString(),
|
|
1296
|
+
count
|
|
1166
1297
|
});
|
|
1167
1298
|
return {
|
|
1168
|
-
result: TopicValidatorResult.
|
|
1169
|
-
|
|
1299
|
+
result: TopicValidatorResult.Reject,
|
|
1300
|
+
severity: PeerErrorSeverity.HighToleranceError
|
|
1170
1301
|
};
|
|
1171
1302
|
}
|
|
1172
|
-
//
|
|
1303
|
+
// Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
|
|
1304
|
+
// count is the number of attestations by this signer for this slot
|
|
1305
|
+
if (count === 2) {
|
|
1306
|
+
const attester = attestation.getSender();
|
|
1307
|
+
if (attester) {
|
|
1308
|
+
this.logger.warn(`Detected duplicate attestation (equivocation) at slot ${slot}`, {
|
|
1309
|
+
slot: slot.toString(),
|
|
1310
|
+
archive: attestation.archive.toString(),
|
|
1311
|
+
source: peerId.toString(),
|
|
1312
|
+
attester: attester.toString()
|
|
1313
|
+
});
|
|
1314
|
+
this.duplicateAttestationCallback?.({
|
|
1315
|
+
slot,
|
|
1316
|
+
attester
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
// Attestation was added successfully - accept it so other nodes can also detect the equivocation
|
|
1173
1321
|
return {
|
|
1174
1322
|
result: TopicValidatorResult.Accept,
|
|
1175
1323
|
obj: attestation
|
|
@@ -1187,9 +1335,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1187
1335
|
const validationResult = await this.blockProposalValidator.validate(block);
|
|
1188
1336
|
if (validationResult.result === 'reject') {
|
|
1189
1337
|
this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1190
|
-
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1191
1338
|
return {
|
|
1192
|
-
result: TopicValidatorResult.Reject
|
|
1339
|
+
result: TopicValidatorResult.Reject,
|
|
1340
|
+
severity: validationResult.severity
|
|
1193
1341
|
};
|
|
1194
1342
|
}
|
|
1195
1343
|
if (validationResult.result === 'ignore') {
|
|
@@ -1199,8 +1347,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1199
1347
|
};
|
|
1200
1348
|
}
|
|
1201
1349
|
// Try to add the proposal: this handles existence check, cap check, and adding in one call
|
|
1202
|
-
const { added, alreadyExists,
|
|
1203
|
-
const isEquivocated =
|
|
1350
|
+
const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddBlockProposal(block);
|
|
1351
|
+
const isEquivocated = count !== undefined && count > 1;
|
|
1204
1352
|
// Duplicate proposal received, no need to re-broadcast
|
|
1205
1353
|
if (alreadyExists) {
|
|
1206
1354
|
this.logger.debug(`Ignoring duplicate block proposal received`, {
|
|
@@ -1219,11 +1367,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1219
1367
|
}
|
|
1220
1368
|
// Too many blocks received for this slot and index, penalize peer and do not re-broadcast
|
|
1221
1369
|
if (!added) {
|
|
1222
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1223
1370
|
this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
|
|
1224
1371
|
...block.toBlockInfo(),
|
|
1225
1372
|
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
1226
|
-
|
|
1373
|
+
count,
|
|
1227
1374
|
proposer: block.getSender()?.toString(),
|
|
1228
1375
|
source: peerId.toString()
|
|
1229
1376
|
});
|
|
@@ -1231,7 +1378,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1231
1378
|
result: TopicValidatorResult.Reject,
|
|
1232
1379
|
metadata: {
|
|
1233
1380
|
isEquivocated
|
|
1234
|
-
}
|
|
1381
|
+
},
|
|
1382
|
+
severity: PeerErrorSeverity.HighToleranceError
|
|
1235
1383
|
};
|
|
1236
1384
|
}
|
|
1237
1385
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1244,7 +1392,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1244
1392
|
proposer: proposer?.toString()
|
|
1245
1393
|
});
|
|
1246
1394
|
// Invoke the duplicate callback on the first duplicate spotted only
|
|
1247
|
-
if (proposer &&
|
|
1395
|
+
if (proposer && count === 2) {
|
|
1248
1396
|
this.duplicateProposalCallback?.({
|
|
1249
1397
|
slot: block.slotNumber,
|
|
1250
1398
|
proposer,
|
|
@@ -1274,13 +1422,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1274
1422
|
source: sender.toString(),
|
|
1275
1423
|
...block.toBlockInfo()
|
|
1276
1424
|
});
|
|
1277
|
-
// Mark the txs in this proposal as
|
|
1278
|
-
await this.mempools.txPool.
|
|
1425
|
+
// Mark the txs in this proposal as protected
|
|
1426
|
+
await this.mempools.txPool.protectTxs(block.txHashes, block.blockHeader);
|
|
1279
1427
|
// Call the block received callback to validate the proposal.
|
|
1280
1428
|
// Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1281
1429
|
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1282
1430
|
if (!isValid) {
|
|
1283
|
-
this.logger.
|
|
1431
|
+
this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1284
1432
|
}
|
|
1285
1433
|
}
|
|
1286
1434
|
/**
|
|
@@ -1305,9 +1453,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1305
1453
|
const validationResult = await this.checkpointProposalValidator.validate(checkpoint);
|
|
1306
1454
|
if (validationResult.result === 'reject') {
|
|
1307
1455
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1308
|
-
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1309
1456
|
return {
|
|
1310
|
-
result: TopicValidatorResult.Reject
|
|
1457
|
+
result: TopicValidatorResult.Reject,
|
|
1458
|
+
severity: validationResult.severity
|
|
1311
1459
|
};
|
|
1312
1460
|
}
|
|
1313
1461
|
if (validationResult.result === 'ignore') {
|
|
@@ -1324,26 +1472,28 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1324
1472
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1325
1473
|
[Attributes.P2P_ID]: peerId.toString()
|
|
1326
1474
|
});
|
|
1327
|
-
const
|
|
1328
|
-
|
|
1475
|
+
const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1476
|
+
const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
|
|
1477
|
+
if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1329
1478
|
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1330
1479
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1331
1480
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1332
1481
|
isEquivocated,
|
|
1333
|
-
result
|
|
1482
|
+
result: blockProposalResult.result
|
|
1334
1483
|
});
|
|
1335
1484
|
return {
|
|
1336
|
-
result: TopicValidatorResult.Reject
|
|
1485
|
+
result: TopicValidatorResult.Reject,
|
|
1486
|
+
severity: 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError
|
|
1337
1487
|
};
|
|
1338
|
-
} else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1488
|
+
} else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1339
1489
|
processBlock = true;
|
|
1340
1490
|
}
|
|
1341
1491
|
}
|
|
1342
1492
|
// Try to add the checkpoint proposal core: this handles existence check, cap check, and adding in one call
|
|
1343
1493
|
const checkpointCore = checkpoint.toCore();
|
|
1344
1494
|
const tryAddResult = await this.mempools.attestationPool.tryAddCheckpointProposal(checkpointCore);
|
|
1345
|
-
const { added, alreadyExists,
|
|
1346
|
-
const isEquivocated =
|
|
1495
|
+
const { added, alreadyExists, count } = tryAddResult;
|
|
1496
|
+
const isEquivocated = count !== undefined && count > 1;
|
|
1347
1497
|
// Duplicate proposal received, do not re-broadcast
|
|
1348
1498
|
if (alreadyExists) {
|
|
1349
1499
|
this.logger.debug(`Ignoring duplicate checkpoint proposal received`, {
|
|
@@ -1362,10 +1512,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1362
1512
|
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1363
1513
|
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1364
1514
|
if (!added) {
|
|
1365
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1366
1515
|
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1367
1516
|
...checkpoint.toCheckpointInfo(),
|
|
1368
|
-
|
|
1517
|
+
count,
|
|
1369
1518
|
source: peerId.toString()
|
|
1370
1519
|
});
|
|
1371
1520
|
return {
|
|
@@ -1374,7 +1523,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1374
1523
|
metadata: {
|
|
1375
1524
|
isEquivocated,
|
|
1376
1525
|
processBlock
|
|
1377
|
-
}
|
|
1526
|
+
},
|
|
1527
|
+
severity: PeerErrorSeverity.HighToleranceError
|
|
1378
1528
|
};
|
|
1379
1529
|
}
|
|
1380
1530
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1387,7 +1537,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1387
1537
|
proposer: proposer?.toString()
|
|
1388
1538
|
});
|
|
1389
1539
|
// Invoke the duplicate callback on the first duplicate spotted only
|
|
1390
|
-
if (proposer &&
|
|
1540
|
+
if (proposer && count === 2) {
|
|
1391
1541
|
this.duplicateProposalCallback?.({
|
|
1392
1542
|
slot: checkpoint.slotNumber,
|
|
1393
1543
|
proposer,
|
|
@@ -1424,9 +1574,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1424
1574
|
archive: checkpoint.archive.toString(),
|
|
1425
1575
|
source: sender.toString()
|
|
1426
1576
|
});
|
|
1577
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
|
|
1427
1578
|
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1428
1579
|
// to validate and potentially generate attestations
|
|
1429
|
-
const attestations = await this.
|
|
1580
|
+
const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
|
|
1430
1581
|
if (attestations && attestations.length > 0) {
|
|
1431
1582
|
// If the callback returned attestations, add them to the pool and propagate them
|
|
1432
1583
|
await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
|
|
@@ -1546,45 +1697,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1546
1697
|
return false;
|
|
1547
1698
|
}
|
|
1548
1699
|
}
|
|
1549
|
-
/**
|
|
1550
|
-
* Validates a BLOCK response.
|
|
1551
|
-
*
|
|
1552
|
-
* If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
|
|
1553
|
-
* Penalizes on block number mismatch or hash mismatch.
|
|
1554
|
-
*
|
|
1555
|
-
* @param requestedBlockNumber - The requested block number.
|
|
1556
|
-
* @param responseBlock - The block returned by the peer.
|
|
1557
|
-
* @param peerId - The peer that returned the block.
|
|
1558
|
-
* @returns True if the response is valid, false otherwise.
|
|
1559
|
-
*/ async validateRequestedBlock(requestedBlockNumber, responseBlock, peerId) {
|
|
1560
|
-
try {
|
|
1561
|
-
const reqNum = Number(requestedBlockNumber.toString());
|
|
1562
|
-
if (responseBlock.number !== reqNum) {
|
|
1563
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1564
|
-
return false;
|
|
1565
|
-
}
|
|
1566
|
-
const local = await this.archiver.getBlock(BlockNumber(reqNum));
|
|
1567
|
-
if (!local) {
|
|
1568
|
-
// We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
|
|
1569
|
-
// TODO: Consider extending this validator to accept an expected hash or
|
|
1570
|
-
// performing quorum-based checks when using P2P syncing prior to L1 sync.
|
|
1571
|
-
this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
|
|
1572
|
-
return false;
|
|
1573
|
-
}
|
|
1574
|
-
const [localHash, respHash] = await Promise.all([
|
|
1575
|
-
local.hash(),
|
|
1576
|
-
responseBlock.hash()
|
|
1577
|
-
]);
|
|
1578
|
-
if (!localHash.equals(respHash)) {
|
|
1579
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1580
|
-
return false;
|
|
1581
|
-
}
|
|
1582
|
-
return true;
|
|
1583
|
-
} catch (e) {
|
|
1584
|
-
this.logger.warn(`Error validating requested block`, e);
|
|
1585
|
-
return false;
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
1700
|
async validateRequestedTx(tx, peerId, txValidator, requested) {
|
|
1589
1701
|
const penalize = (severity)=>this.peerManager.penalizePeer(peerId, severity);
|
|
1590
1702
|
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
@@ -1598,44 +1710,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1598
1710
|
}
|
|
1599
1711
|
}
|
|
1600
1712
|
createRequestedTxValidator() {
|
|
1601
|
-
return
|
|
1713
|
+
return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
|
|
1602
1714
|
l1ChainId: this.config.l1ChainId,
|
|
1603
1715
|
rollupVersion: this.config.rollupVersion
|
|
1604
1716
|
});
|
|
1605
1717
|
}
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1609
|
-
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1610
|
-
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1611
|
-
for (const validator of messageValidators){
|
|
1612
|
-
const outcome = await this.runValidations(tx, validator);
|
|
1613
|
-
if (outcome.allPassed) {
|
|
1614
|
-
continue;
|
|
1615
|
-
}
|
|
1616
|
-
const { name } = outcome.failure;
|
|
1617
|
-
let { severity } = outcome.failure;
|
|
1618
|
-
// Double spend validator has a special case handler
|
|
1619
|
-
if (name === 'doubleSpendValidator') {
|
|
1620
|
-
const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
|
|
1621
|
-
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1622
|
-
}
|
|
1623
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
1624
|
-
return false;
|
|
1625
|
-
}
|
|
1626
|
-
return true;
|
|
1627
|
-
}
|
|
1628
|
-
async getGasFees(blockNumber) {
|
|
1629
|
-
if (blockNumber === this.feesCache?.blockNumber) {
|
|
1630
|
-
return this.feesCache.gasFees;
|
|
1631
|
-
}
|
|
1632
|
-
const header = await this.archiver.getBlockHeader(blockNumber);
|
|
1633
|
-
const gasFees = header?.globalVariables.gasFees ?? GasFees.empty();
|
|
1634
|
-
this.feesCache = {
|
|
1635
|
-
blockNumber,
|
|
1636
|
-
gasFees
|
|
1637
|
-
};
|
|
1638
|
-
return gasFees;
|
|
1718
|
+
getGasFees() {
|
|
1719
|
+
return this.blockMinFeesProvider.getCurrentMinFees();
|
|
1639
1720
|
}
|
|
1640
1721
|
/**
|
|
1641
1722
|
* Get the BatchTxRequesterLibP2PService dependencies for creating BatchTxRequester instances
|
|
@@ -1651,38 +1732,35 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1651
1732
|
peerScoring: this.peerManager
|
|
1652
1733
|
};
|
|
1653
1734
|
}
|
|
1654
|
-
async
|
|
1655
|
-
const
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
await Promise.all(txs.map(async (tx)=>{
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
if (!outcome.allPassed) {
|
|
1663
|
-
throw new Error('Invalid tx detected', {
|
|
1664
|
-
cause: {
|
|
1665
|
-
outcome
|
|
1666
|
-
}
|
|
1667
|
-
});
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1735
|
+
async validateTxsReceivedInBlockProposal(txs) {
|
|
1736
|
+
const validator = createTxValidatorForBlockProposalReceivedTxs(this.proofVerifier, {
|
|
1737
|
+
l1ChainId: this.config.l1ChainId,
|
|
1738
|
+
rollupVersion: this.config.rollupVersion
|
|
1739
|
+
}, this.logger.getBindings());
|
|
1740
|
+
const results = await Promise.all(txs.map(async (tx)=>{
|
|
1741
|
+
const result = await validator.validateTx(tx);
|
|
1742
|
+
return result.result !== 'invalid';
|
|
1670
1743
|
}));
|
|
1744
|
+
if (results.some((value)=>value === false)) {
|
|
1745
|
+
throw new Error('Invalid tx detected');
|
|
1746
|
+
}
|
|
1671
1747
|
}
|
|
1672
|
-
/**
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1748
|
+
/** Creates the first stage (fast) validators for gossiped transactions. */ async createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp) {
|
|
1749
|
+
const gasFees = await this.getGasFees();
|
|
1750
|
+
const allowedInSetup = [
|
|
1751
|
+
...await getDefaultAllowedSetupFunctions(),
|
|
1752
|
+
...this.config.txPublicSetupAllowListExtend ?? []
|
|
1753
|
+
];
|
|
1754
|
+
const blockNumber = BlockNumber(currentBlockNumber + 1);
|
|
1755
|
+
const l1Constants = await this.archiver.getL1Constants();
|
|
1756
|
+
return createFirstStageTxValidationsForGossipedTransactions(nextSlotTimestamp, blockNumber, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings(), {
|
|
1757
|
+
rollupManaLimit: l1Constants.rollupManaLimit,
|
|
1758
|
+
maxBlockL2Gas: this.config.validateMaxL2BlockGas,
|
|
1759
|
+
maxBlockDAGas: this.config.validateMaxDABlockGas
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1762
|
+
/** Creates the second stage (expensive proof verification) validators for gossiped transactions. */ createSecondStageMessageValidators() {
|
|
1763
|
+
return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
|
|
1686
1764
|
}
|
|
1687
1765
|
/**
|
|
1688
1766
|
* Run validations on a tx.
|
|
@@ -1700,8 +1778,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1700
1778
|
});
|
|
1701
1779
|
// A promise that resolves when all validations have been run
|
|
1702
1780
|
const allValidations = await Promise.all(validationPromises);
|
|
1703
|
-
const
|
|
1704
|
-
if (
|
|
1781
|
+
const failures = allValidations.filter((x)=>!x.isValid);
|
|
1782
|
+
if (failures.length > 0) {
|
|
1783
|
+
// Pick the most severe failure (lowest tolerance = harshest penalty)
|
|
1784
|
+
const failed = maxBy(failures, (f)=>PeerErrorSeverityByHarshness.indexOf(f.severity));
|
|
1705
1785
|
return {
|
|
1706
1786
|
allPassed: false,
|
|
1707
1787
|
failure: {
|
|
@@ -1748,19 +1828,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1748
1828
|
}
|
|
1749
1829
|
return PeerErrorSeverity.HighToleranceError;
|
|
1750
1830
|
}
|
|
1751
|
-
/**
|
|
1752
|
-
* Validate a checkpoint attestation.
|
|
1753
|
-
*
|
|
1754
|
-
* @param attestation - The checkpoint attestation to validate.
|
|
1755
|
-
* @returns True if the checkpoint attestation is valid, false otherwise.
|
|
1756
|
-
*/ async validateCheckpointAttestation(peerId, attestation) {
|
|
1757
|
-
const result = await this.checkpointAttestationValidator.validate(attestation);
|
|
1758
|
-
if (result.result === 'reject') {
|
|
1759
|
-
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1760
|
-
this.peerManager.penalizePeer(peerId, result.severity);
|
|
1761
|
-
}
|
|
1762
|
-
return result;
|
|
1763
|
-
}
|
|
1764
1831
|
getPeerScore(peerId) {
|
|
1765
1832
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
1766
1833
|
}
|