@aztec/p2p 0.0.1-commit.b655e406 → 0.0.1-commit.c7c42ec
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/dest/bootstrap/bootstrap.d.ts +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/client/factory.d.ts +2 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +2 -3
- package/dest/client/index.d.ts +1 -1
- package/dest/client/interface.d.ts +4 -2
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +9 -27
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +39 -32
- package/dest/config.d.ts +62 -59
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +19 -12
- package/dest/enr/generate-enr.d.ts +1 -1
- package/dest/enr/index.d.ts +1 -1
- package/dest/errors/attestation-pool.error.d.ts +7 -0
- package/dest/errors/attestation-pool.error.d.ts.map +1 -0
- package/dest/errors/attestation-pool.error.js +12 -0
- package/dest/errors/reqresp.error.d.ts +1 -1
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +28 -6
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- 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 +35 -34
- package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +13 -6
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +41 -18
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +11 -6
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +30 -8
- package/dest/mem_pools/attestation_pool/mocks.d.ts +226 -5
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +2 -2
- package/dest/mem_pools/index.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts +9 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +38 -2
- package/dest/mem_pools/interface.d.ts +3 -4
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +30 -60
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +262 -324
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +18 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +56 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +83 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +5 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.js +88 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +76 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
- package/dest/mem_pools/tx_pool/index.d.ts +1 -2
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/index.js +0 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +6 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +11 -6
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +30 -24
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -3
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +12 -12
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +20 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +67 -0
- package/dest/msg_validators/attestation_validator/index.d.ts +2 -1
- package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/index.js +1 -0
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +1 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +22 -10
- package/dest/msg_validators/block_proposal_validator/index.d.ts +1 -1
- package/dest/msg_validators/index.d.ts +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +2 -2
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- 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/double_spend_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.d.ts +4 -3
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +3 -1
- package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
- package/dest/services/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.d.ts +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/dummy_service.d.ts +1 -1
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/encoding.d.ts +1 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +1 -1
- package/dest/services/gossipsub/scoring.d.ts +1 -1
- package/dest/services/index.d.ts +1 -1
- 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 +9 -2
- package/dest/services/libp2p/libp2p_service.d.ts +14 -70
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +231 -66
- package/dest/services/peer-manager/interface.d.ts +1 -1
- package/dest/services/peer-manager/metrics.d.ts +8 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +28 -0
- package/dest/services/peer-manager/peer_manager.d.ts +1 -32
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +6 -2
- 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 +40 -2
- package/dest/services/reqresp/config.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/index.d.ts +1 -1
- package/dest/services/reqresp/interface.d.ts +2 -2
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +1 -1
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.d.ts +2 -2
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.js +2 -2
- package/dest/services/reqresp/protocols/block.d.ts +1 -1
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +3 -2
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +4 -6
- 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 +1 -1
- package/dest/services/reqresp/protocols/block_txs/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/ping.d.ts +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +6 -5
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +4 -3
- package/dest/services/reqresp/protocols/tx.d.ts +2 -3
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +2 -2
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts +1 -41
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/status.d.ts +2 -2
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/service.d.ts +1 -1
- package/dest/services/tx_collection/config.d.ts +1 -1
- package/dest/services/tx_collection/config.js +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -9
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/index.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.d.ts +6 -7
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +2 -1
- package/dest/services/tx_collection/tx_collection.d.ts +11 -11
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.d.ts +3 -3
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.d.ts +1 -1
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_provider.d.ts +6 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +11 -2
- package/dest/services/tx_provider_instrumentation.d.ts +5 -2
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +14 -1
- package/dest/test-helpers/generate-peer-id-private-keys.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts.map +1 -1
- package/dest/test-helpers/index.d.ts +1 -1
- package/dest/test-helpers/make-enrs.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts +2 -2
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +4 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-tx-helpers.d.ts +2 -2
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -1
- package/dest/test-helpers/mock-tx-helpers.js +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -2
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +12 -8
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/types/index.d.ts +1 -1
- package/dest/util.d.ts +2 -1
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +11 -2
- package/dest/versioning.d.ts +1 -1
- package/package.json +19 -18
- package/src/client/factory.ts +5 -10
- package/src/client/interface.ts +4 -1
- package/src/client/p2p_client.ts +63 -60
- package/src/config.ts +28 -17
- package/src/errors/attestation-pool.error.ts +13 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +29 -5
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +47 -34
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +66 -24
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +50 -16
- package/src/mem_pools/attestation_pool/mocks.ts +3 -3
- package/src/mem_pools/instrumentation.ts +46 -0
- package/src/mem_pools/interface.ts +2 -4
- package/src/mem_pools/tx_pool/README.md +255 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +314 -373
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +71 -0
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +93 -0
- package/src/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.ts +108 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +91 -0
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
- package/src/mem_pools/tx_pool/index.ts +0 -1
- package/src/mem_pools/tx_pool/priority.ts +8 -1
- package/src/mem_pools/tx_pool/tx_pool.ts +11 -5
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +23 -17
- package/src/msg_validators/attestation_validator/attestation_validator.ts +14 -16
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +91 -0
- package/src/msg_validators/attestation_validator/index.ts +1 -0
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +26 -10
- package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +1 -1
- package/src/msg_validators/tx_validator/factory.ts +3 -2
- package/src/msg_validators/tx_validator/metadata_validator.ts +1 -1
- package/src/msg_validators/tx_validator/phases_validator.ts +3 -1
- package/src/msg_validators/tx_validator/test_utils.ts +1 -1
- package/src/msg_validators/tx_validator/timestamp_validator.ts +2 -1
- package/src/services/encoding.ts +1 -1
- package/src/services/libp2p/instrumentation.ts +10 -1
- package/src/services/libp2p/libp2p_service.ts +263 -79
- package/src/services/peer-manager/metrics.ts +32 -0
- package/src/services/peer-manager/peer_manager.ts +6 -2
- package/src/services/peer-manager/peer_scoring.ts +46 -3
- package/src/services/reqresp/interface.ts +1 -1
- package/src/services/reqresp/protocols/auth.ts +2 -2
- package/src/services/reqresp/protocols/block.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
- package/src/services/reqresp/protocols/status.ts +9 -8
- package/src/services/reqresp/protocols/tx.ts +1 -2
- package/src/services/tx_collection/config.ts +1 -1
- package/src/services/tx_collection/fast_tx_collection.ts +3 -2
- package/src/services/tx_collection/slow_tx_collection.ts +7 -6
- package/src/services/tx_collection/tx_collection.ts +10 -9
- package/src/services/tx_provider.ts +21 -5
- package/src/services/tx_provider_instrumentation.ts +19 -2
- package/src/test-helpers/mock-pubsub.ts +1 -1
- package/src/test-helpers/mock-tx-helpers.ts +1 -1
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/testbench/p2p_client_testbench_worker.ts +10 -6
- package/src/util.ts +12 -2
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -80
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -238
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -283
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { randomInt } from '@aztec/foundation/crypto/random';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
5
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import { SerialQueue } from '@aztec/foundation/queue';
|
|
6
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
7
7
|
import { Timer } from '@aztec/foundation/timer';
|
|
8
8
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
9
9
|
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
10
10
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
11
|
-
import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
|
|
11
|
+
import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
|
|
12
12
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
13
13
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
14
14
|
import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
@@ -50,8 +50,13 @@ import { ENR } from '@nethermindeth/enr';
|
|
|
50
50
|
import { createLibp2p } from 'libp2p';
|
|
51
51
|
|
|
52
52
|
import type { P2PConfig } from '../../config.js';
|
|
53
|
+
import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
|
|
53
54
|
import type { MemPools } from '../../mem_pools/interface.js';
|
|
54
|
-
import {
|
|
55
|
+
import {
|
|
56
|
+
AttestationValidator,
|
|
57
|
+
BlockProposalValidator,
|
|
58
|
+
FishermanAttestationValidator,
|
|
59
|
+
} from '../../msg_validators/index.js';
|
|
55
60
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
56
61
|
import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
|
|
57
62
|
import { type MessageValidator, createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
|
|
@@ -116,7 +121,6 @@ type ReceivedMessageValidationResult<T> =
|
|
|
116
121
|
* Lib P2P implementation of the P2PService interface.
|
|
117
122
|
*/
|
|
118
123
|
export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends WithTracer implements P2PService {
|
|
119
|
-
private jobQueue: SerialQueue = new SerialQueue();
|
|
120
124
|
private discoveryRunningPromise?: RunningPromise;
|
|
121
125
|
private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
|
|
122
126
|
|
|
@@ -127,7 +131,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
127
131
|
private protocolVersion = '';
|
|
128
132
|
private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
|
|
129
133
|
|
|
130
|
-
private feesCache: { blockNumber:
|
|
134
|
+
private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
|
|
131
135
|
|
|
132
136
|
/**
|
|
133
137
|
* Callback for when a block is received from a peer.
|
|
@@ -140,6 +144,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
140
144
|
|
|
141
145
|
private instrumentation: P2PInstrumentation;
|
|
142
146
|
|
|
147
|
+
protected logger: Logger;
|
|
148
|
+
|
|
143
149
|
constructor(
|
|
144
150
|
private clientType: T,
|
|
145
151
|
private config: P2PConfig,
|
|
@@ -147,16 +153,19 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
147
153
|
private peerDiscoveryService: PeerDiscoveryService,
|
|
148
154
|
private reqresp: ReqRespInterface,
|
|
149
155
|
private peerManager: PeerManagerInterface,
|
|
150
|
-
protected mempools: MemPools
|
|
156
|
+
protected mempools: MemPools,
|
|
151
157
|
private archiver: L2BlockSource & ContractDataSource,
|
|
152
158
|
private epochCache: EpochCacheInterface,
|
|
153
159
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
154
160
|
private worldStateSynchronizer: WorldStateSynchronizer,
|
|
155
161
|
telemetry: TelemetryClient,
|
|
156
|
-
|
|
162
|
+
logger: Logger = createLogger('p2p:libp2p_service'),
|
|
157
163
|
) {
|
|
158
164
|
super(telemetry, 'LibP2PService');
|
|
159
165
|
|
|
166
|
+
// Create child logger with fisherman prefix if in fisherman mode
|
|
167
|
+
this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
|
|
168
|
+
|
|
160
169
|
this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
|
|
161
170
|
|
|
162
171
|
this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
@@ -174,15 +183,18 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
174
183
|
this.protocolVersion,
|
|
175
184
|
);
|
|
176
185
|
|
|
177
|
-
|
|
186
|
+
// Use FishermanAttestationValidator in fisherman mode to validate attestation payloads against proposals
|
|
187
|
+
this.attestationValidator = config.fishermanMode
|
|
188
|
+
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
|
|
189
|
+
: new AttestationValidator(epochCache);
|
|
178
190
|
this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
|
|
179
191
|
|
|
180
192
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
181
193
|
|
|
182
194
|
this.blockReceivedCallback = async (block: BlockProposal): Promise<BlockAttestation[] | undefined> => {
|
|
183
195
|
this.logger.debug(
|
|
184
|
-
`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber
|
|
185
|
-
{ p2pMessageIdentifier: await block.
|
|
196
|
+
`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
|
|
197
|
+
{ p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
|
|
186
198
|
);
|
|
187
199
|
return undefined;
|
|
188
200
|
};
|
|
@@ -203,7 +215,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
203
215
|
config: P2PConfig,
|
|
204
216
|
peerId: PeerId,
|
|
205
217
|
deps: {
|
|
206
|
-
mempools: MemPools
|
|
218
|
+
mempools: MemPools;
|
|
207
219
|
l2BlockSource: L2BlockSource & ContractDataSource;
|
|
208
220
|
epochCache: EpochCacheInterface;
|
|
209
221
|
proofVerifier: ClientProtocolCircuitVerifier;
|
|
@@ -395,7 +407,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
395
407
|
logger: createLibp2pComponentLogger(logger.module),
|
|
396
408
|
});
|
|
397
409
|
|
|
398
|
-
const peerScoring = new PeerScoring(config);
|
|
410
|
+
const peerScoring = new PeerScoring(config, telemetry);
|
|
399
411
|
const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
|
|
400
412
|
|
|
401
413
|
const peerManager = new PeerManager(
|
|
@@ -450,9 +462,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
450
462
|
}
|
|
451
463
|
const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
|
|
452
464
|
|
|
453
|
-
// Start job queue, peer discovery service and libp2p node
|
|
454
|
-
this.jobQueue.start();
|
|
455
|
-
|
|
456
465
|
await this.peerManager.initializePeers();
|
|
457
466
|
if (!this.config.p2pDiscoveryDisabled) {
|
|
458
467
|
await this.peerDiscoveryService.start();
|
|
@@ -477,8 +486,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
477
486
|
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
|
|
478
487
|
};
|
|
479
488
|
|
|
480
|
-
|
|
481
|
-
if (this.mempools.attestationPool && !this.config.disableTransactions) {
|
|
489
|
+
if (!this.config.disableTransactions) {
|
|
482
490
|
const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool);
|
|
483
491
|
requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
|
|
484
492
|
}
|
|
@@ -490,9 +498,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
490
498
|
// add GossipSub listener
|
|
491
499
|
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
492
500
|
|
|
493
|
-
// Start running promise for peer discovery
|
|
501
|
+
// Start running promise for peer discovery and metrics collection
|
|
494
502
|
this.discoveryRunningPromise = new RunningPromise(
|
|
495
|
-
() =>
|
|
503
|
+
async () => {
|
|
504
|
+
await this.peerManager.heartbeat();
|
|
505
|
+
},
|
|
496
506
|
this.logger,
|
|
497
507
|
this.config.peerCheckIntervalMS,
|
|
498
508
|
);
|
|
@@ -501,9 +511,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
501
511
|
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
502
512
|
const reqrespSubProtocolValidators = {
|
|
503
513
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
504
|
-
// TODO(#11336): A request validator for blocks
|
|
505
514
|
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
506
515
|
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
516
|
+
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
|
|
507
517
|
};
|
|
508
518
|
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
509
519
|
this.logger.info(`Started P2P service`, {
|
|
@@ -525,9 +535,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
525
535
|
// Stop peer manager
|
|
526
536
|
this.logger.debug('Stopping peer manager...');
|
|
527
537
|
await this.peerManager.stop();
|
|
528
|
-
|
|
529
|
-
this.logger.debug('Stopping job queue...');
|
|
530
|
-
await this.jobQueue.end();
|
|
531
538
|
this.logger.debug('Stopping running promise...');
|
|
532
539
|
await this.discoveryRunningPromise?.stop();
|
|
533
540
|
this.logger.debug('Stopping peer discovery service...');
|
|
@@ -615,7 +622,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
615
622
|
if (!this.node.services.pubsub) {
|
|
616
623
|
throw new Error('Pubsub service not available.');
|
|
617
624
|
}
|
|
618
|
-
const p2pMessage = P2PMessage.fromGossipable(message);
|
|
625
|
+
const p2pMessage = P2PMessage.fromGossipable(message, this.config.debugP2PInstrumentMessages);
|
|
619
626
|
const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
|
|
620
627
|
return result.recipients.length;
|
|
621
628
|
}
|
|
@@ -660,13 +667,39 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
660
667
|
return { result: true, topicType };
|
|
661
668
|
}
|
|
662
669
|
|
|
670
|
+
/**
|
|
671
|
+
* Safely deserializes a P2PMessage from raw message data.
|
|
672
|
+
* @param msgId - The message ID.
|
|
673
|
+
* @param source - The peer ID of the message source.
|
|
674
|
+
* @param data - The raw message data.
|
|
675
|
+
* @returns The deserialized P2PMessage or undefined if deserialization fails.
|
|
676
|
+
*/
|
|
677
|
+
private safelyDeserializeP2PMessage(msgId: string, source: PeerId, data: Uint8Array): P2PMessage | undefined {
|
|
678
|
+
try {
|
|
679
|
+
return P2PMessage.fromMessageData(Buffer.from(data), this.config.debugP2PInstrumentMessages);
|
|
680
|
+
} catch (err) {
|
|
681
|
+
this.logger.error(`Error deserializing P2PMessage`, err, {
|
|
682
|
+
msgId,
|
|
683
|
+
source: source.toString(),
|
|
684
|
+
});
|
|
685
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Reject);
|
|
686
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
|
|
687
|
+
return undefined;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
663
691
|
/**
|
|
664
692
|
* Handles a new gossip message that was received by the client.
|
|
665
693
|
* @param topic - The message's topic.
|
|
666
694
|
* @param data - The message data
|
|
667
695
|
*/
|
|
668
696
|
protected async handleNewGossipMessage(msg: Message, msgId: string, source: PeerId) {
|
|
669
|
-
const
|
|
697
|
+
const msgReceivedTime = Date.now();
|
|
698
|
+
let topicType: TopicType | undefined;
|
|
699
|
+
const p2pMessage = this.safelyDeserializeP2PMessage(msgId, source, msg.data);
|
|
700
|
+
if (!p2pMessage) {
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
670
703
|
|
|
671
704
|
const preValidationResult = this.preValidateReceivedMessage(msg, msgId, source);
|
|
672
705
|
|
|
@@ -675,15 +708,25 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
675
708
|
}
|
|
676
709
|
|
|
677
710
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
711
|
+
topicType = TopicType.tx;
|
|
678
712
|
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
679
713
|
}
|
|
680
|
-
if (msg.topic === this.topicStrings[TopicType.block_attestation]
|
|
681
|
-
|
|
714
|
+
if (msg.topic === this.topicStrings[TopicType.block_attestation]) {
|
|
715
|
+
topicType = TopicType.block_attestation;
|
|
716
|
+
if (this.clientType === P2PClientType.Full) {
|
|
717
|
+
await this.processAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
718
|
+
}
|
|
682
719
|
}
|
|
683
720
|
if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
721
|
+
topicType = TopicType.block_proposal;
|
|
684
722
|
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
685
723
|
}
|
|
686
724
|
|
|
725
|
+
if (p2pMessage.timestamp !== undefined && topicType !== undefined) {
|
|
726
|
+
const latency = msgReceivedTime - p2pMessage.timestamp.getTime();
|
|
727
|
+
this.instrumentation.recordMessageLatency(topicType, latency);
|
|
728
|
+
}
|
|
729
|
+
|
|
687
730
|
return;
|
|
688
731
|
}
|
|
689
732
|
|
|
@@ -698,6 +741,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
698
741
|
try {
|
|
699
742
|
resultAndObj = await validationFunc();
|
|
700
743
|
} catch (err) {
|
|
744
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
|
|
701
745
|
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
702
746
|
msgId,
|
|
703
747
|
source: source.toString(),
|
|
@@ -751,6 +795,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
751
795
|
return;
|
|
752
796
|
}
|
|
753
797
|
|
|
798
|
+
this.instrumentation.incrementTxReceived(1);
|
|
754
799
|
await this.mempools.txPool.addTxs([tx]);
|
|
755
800
|
}
|
|
756
801
|
|
|
@@ -763,12 +808,22 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
763
808
|
private async processAttestationFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
764
809
|
const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockAttestation>> = async () => {
|
|
765
810
|
const attestation = BlockAttestation.fromBuffer(payloadData);
|
|
811
|
+
const pool = this.mempools.attestationPool;
|
|
766
812
|
const isValid = await this.validateAttestation(source, attestation);
|
|
767
|
-
const exists = isValid && (await
|
|
813
|
+
const exists = isValid && (await pool.hasAttestation(attestation));
|
|
814
|
+
|
|
815
|
+
let canAdd = true;
|
|
816
|
+
if (isValid && !exists) {
|
|
817
|
+
const slot = attestation.payload.header.slotNumber;
|
|
818
|
+
const { committee } = await this.epochCache.getCommittee(slot);
|
|
819
|
+
const committeeSize = committee?.length ?? 0;
|
|
820
|
+
canAdd = await pool.canAddAttestation(attestation, committeeSize);
|
|
821
|
+
}
|
|
768
822
|
|
|
769
823
|
this.logger.trace(`Validate propagated block attestation`, {
|
|
770
824
|
isValid,
|
|
771
825
|
exists,
|
|
826
|
+
canAdd,
|
|
772
827
|
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
|
|
773
828
|
[Attributes.P2P_ID]: source.toString(),
|
|
774
829
|
});
|
|
@@ -777,6 +832,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
777
832
|
return { result: TopicValidatorResult.Reject };
|
|
778
833
|
} else if (exists) {
|
|
779
834
|
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
835
|
+
} else if (!canAdd) {
|
|
836
|
+
this.logger.warn(`Dropping block attestation due to per-(slot, proposalId) attestation cap`, {
|
|
837
|
+
slot: attestation.payload.header.slotNumber.toString(),
|
|
838
|
+
archive: attestation.archive.toString(),
|
|
839
|
+
source: source.toString(),
|
|
840
|
+
});
|
|
841
|
+
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
780
842
|
} else {
|
|
781
843
|
return { result: TopicValidatorResult.Accept, obj: attestation };
|
|
782
844
|
}
|
|
@@ -794,30 +856,31 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
794
856
|
}
|
|
795
857
|
|
|
796
858
|
this.logger.debug(
|
|
797
|
-
`Received attestation for slot ${attestation.slotNumber
|
|
859
|
+
`Received attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
|
|
798
860
|
{
|
|
799
|
-
p2pMessageIdentifier: await attestation.
|
|
800
|
-
slot: attestation.slotNumber
|
|
861
|
+
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
862
|
+
slot: attestation.slotNumber,
|
|
801
863
|
archive: attestation.archive.toString(),
|
|
802
864
|
source: source.toString(),
|
|
803
865
|
},
|
|
804
866
|
);
|
|
805
867
|
|
|
806
|
-
await this.mempools.attestationPool
|
|
868
|
+
await this.mempools.attestationPool.addAttestations([attestation]);
|
|
807
869
|
}
|
|
808
870
|
|
|
809
871
|
private async processBlockFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
810
872
|
const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockProposal>> = async () => {
|
|
811
873
|
const block = BlockProposal.fromBuffer(payloadData);
|
|
812
874
|
const isValid = await this.validateBlockProposal(source, block);
|
|
875
|
+
const pool = this.mempools.attestationPool;
|
|
813
876
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
const exists = isValid && (await this.mempools.attestationPool?.hasBlockProposal(block));
|
|
877
|
+
const exists = isValid && (await pool.hasBlockProposal(block));
|
|
878
|
+
const canAdd = isValid && (await pool.canAddProposal(block));
|
|
817
879
|
|
|
818
880
|
this.logger.trace(`Validate propagated block proposal`, {
|
|
819
881
|
isValid,
|
|
820
882
|
exists,
|
|
883
|
+
canAdd,
|
|
821
884
|
[Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString(),
|
|
822
885
|
[Attributes.P2P_ID]: source.toString(),
|
|
823
886
|
});
|
|
@@ -826,6 +889,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
826
889
|
return { result: TopicValidatorResult.Reject };
|
|
827
890
|
} else if (exists) {
|
|
828
891
|
return { result: TopicValidatorResult.Ignore, obj: block };
|
|
892
|
+
} else if (!canAdd) {
|
|
893
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
|
|
894
|
+
this.logger.warn(`Penalizing peer for block proposal exceeding per-slot cap`, {
|
|
895
|
+
slot: block.slotNumber.toString(),
|
|
896
|
+
archive: block.archive.toString(),
|
|
897
|
+
source: source.toString(),
|
|
898
|
+
});
|
|
899
|
+
return { result: TopicValidatorResult.Reject };
|
|
829
900
|
} else {
|
|
830
901
|
return { result: TopicValidatorResult.Accept, obj: block };
|
|
831
902
|
}
|
|
@@ -847,36 +918,47 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
847
918
|
|
|
848
919
|
// REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
849
920
|
@trackSpan('Libp2pService.processValidBlockProposal', async block => ({
|
|
850
|
-
[Attributes.SLOT_NUMBER]: block.slotNumber
|
|
921
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber,
|
|
851
922
|
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
852
|
-
[Attributes.P2P_ID]: await block.
|
|
923
|
+
[Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
853
924
|
}))
|
|
854
925
|
private async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
|
|
855
|
-
const slot = block.slotNumber
|
|
856
|
-
const previousSlot = slot -
|
|
926
|
+
const slot = block.slotNumber;
|
|
927
|
+
const previousSlot = SlotNumber(slot - 1);
|
|
857
928
|
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
858
|
-
p2pMessageIdentifier: await block.
|
|
859
|
-
slot: block.slotNumber
|
|
929
|
+
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
|
|
930
|
+
slot: block.slotNumber,
|
|
860
931
|
archive: block.archive.toString(),
|
|
861
932
|
source: sender.toString(),
|
|
862
933
|
});
|
|
863
|
-
const attestationsForPreviousSlot = await this.mempools.attestationPool
|
|
864
|
-
|
|
865
|
-
this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
|
|
866
|
-
}
|
|
934
|
+
const attestationsForPreviousSlot = await this.mempools.attestationPool.getAttestationsForSlot(previousSlot);
|
|
935
|
+
this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
|
|
867
936
|
|
|
868
|
-
//
|
|
937
|
+
// Attempt to add proposal, then mark the txs in this proposal as non-evictable
|
|
938
|
+
try {
|
|
939
|
+
await this.mempools.attestationPool.addBlockProposal(block);
|
|
940
|
+
} catch (err: unknown) {
|
|
941
|
+
// Drop proposals if we hit per-slot cap in the attestation pool; rethrow unknown errors
|
|
942
|
+
if (err instanceof ProposalSlotCapExceededError) {
|
|
943
|
+
this.logger.warn(`Dropping block proposal due to per-slot proposal cap`, {
|
|
944
|
+
slot: String(slot),
|
|
945
|
+
archive: block.archive.toString(),
|
|
946
|
+
error: (err as Error).message,
|
|
947
|
+
});
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
throw err;
|
|
951
|
+
}
|
|
869
952
|
await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
|
|
870
|
-
await this.mempools.attestationPool?.addBlockProposal(block);
|
|
871
953
|
const attestations = await this.blockReceivedCallback(block, sender);
|
|
872
954
|
|
|
873
955
|
// TODO: fix up this pattern - the abstraction is not nice
|
|
874
|
-
// The attestation can be undefined if no handler is registered / the validator deems the block invalid
|
|
956
|
+
// The attestation can be undefined if no handler is registered / the validator deems the block invalid / in fisherman mode
|
|
875
957
|
if (attestations?.length) {
|
|
876
958
|
for (const attestation of attestations) {
|
|
877
|
-
this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber
|
|
878
|
-
p2pMessageIdentifier: await attestation.
|
|
879
|
-
slot: attestation.slotNumber
|
|
959
|
+
this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber}`, {
|
|
960
|
+
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
961
|
+
slot: attestation.slotNumber,
|
|
880
962
|
archive: attestation.archive.toString(),
|
|
881
963
|
});
|
|
882
964
|
await this.broadcastAttestation(attestation);
|
|
@@ -889,9 +971,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
889
971
|
* @param attestation - The attestation to broadcast.
|
|
890
972
|
*/
|
|
891
973
|
@trackSpan('Libp2pService.broadcastAttestation', async attestation => ({
|
|
892
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber
|
|
974
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
893
975
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
894
|
-
[Attributes.P2P_ID]: await attestation.
|
|
976
|
+
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
895
977
|
}))
|
|
896
978
|
private async broadcastAttestation(attestation: BlockAttestation) {
|
|
897
979
|
await this.propagate(attestation);
|
|
@@ -902,19 +984,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
902
984
|
* @param message - The message to propagate.
|
|
903
985
|
*/
|
|
904
986
|
public async propagate<T extends Gossipable>(message: T) {
|
|
905
|
-
const p2pMessageIdentifier = await message.
|
|
987
|
+
const p2pMessageIdentifier = await message.p2pMessageLoggingIdentifier();
|
|
906
988
|
this.logger.trace(`Message ${p2pMessageIdentifier} queued`, { p2pMessageIdentifier });
|
|
907
|
-
void this.
|
|
908
|
-
.
|
|
909
|
-
|
|
910
|
-
})
|
|
911
|
-
.catch(error => {
|
|
912
|
-
this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, { error });
|
|
913
|
-
});
|
|
989
|
+
void this.sendToPeers(message).catch(error => {
|
|
990
|
+
this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, { error });
|
|
991
|
+
});
|
|
914
992
|
}
|
|
915
993
|
|
|
916
994
|
/**
|
|
917
|
-
* Validate the requested block transactions.
|
|
995
|
+
* Validate the requested block transactions. Allow partial returns.
|
|
918
996
|
* @param request - The block transactions request.
|
|
919
997
|
* @param response - The block transactions response.
|
|
920
998
|
* @param peerId - The ID of the peer that made the request.
|
|
@@ -924,14 +1002,71 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
924
1002
|
[Attributes.BLOCK_HASH]: request.blockHash.toString(),
|
|
925
1003
|
}))
|
|
926
1004
|
private async validateRequestedBlockTxs(
|
|
927
|
-
|
|
1005
|
+
request: BlockTxsRequest,
|
|
928
1006
|
response: BlockTxsResponse,
|
|
929
1007
|
peerId: PeerId,
|
|
930
1008
|
): Promise<boolean> {
|
|
931
1009
|
const requestedTxValidator = this.createRequestedTxValidator();
|
|
932
1010
|
|
|
933
1011
|
try {
|
|
934
|
-
|
|
1012
|
+
if (!response.blockHash.equals(request.blockHash)) {
|
|
1013
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1014
|
+
throw new ValidationError(
|
|
1015
|
+
`Received block txs for unexpected block: expected ${request.blockHash.toString()}, got ${response.blockHash.toString()}`,
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
if (response.txIndices.getLength() !== request.txIndices.getLength()) {
|
|
1020
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1021
|
+
throw new ValidationError(
|
|
1022
|
+
`Received block txs with mismatched bitvector length: expected ${request.txIndices.getLength()}, got ${response.txIndices.getLength()}`,
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// Check no duplicates and not exceeding returnable count
|
|
1027
|
+
const requestedIndices = new Set(request.txIndices.getTrueIndices());
|
|
1028
|
+
const availableIndices = new Set(response.txIndices.getTrueIndices());
|
|
1029
|
+
const maxReturnable = [...requestedIndices].filter(i => availableIndices.has(i)).length;
|
|
1030
|
+
|
|
1031
|
+
const returnedHashes = await Promise.all(response.txs.map(tx => tx.getTxHash().toString()));
|
|
1032
|
+
const uniqueReturned = new Set(returnedHashes.map(h => h.toString()));
|
|
1033
|
+
if (uniqueReturned.size !== returnedHashes.length) {
|
|
1034
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1035
|
+
throw new ValidationError(`Received duplicate txs in block txs response`);
|
|
1036
|
+
}
|
|
1037
|
+
if (response.txs.length > maxReturnable) {
|
|
1038
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1039
|
+
throw new ValidationError(
|
|
1040
|
+
`Received more txs (${response.txs.length}) than requested-and-available (${maxReturnable})`,
|
|
1041
|
+
);
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
// Given proposal (should have locally), ensure returned txs are valid subset and match request indices
|
|
1045
|
+
const proposal = await this.mempools.attestationPool.getBlockProposal(request.blockHash.toString());
|
|
1046
|
+
if (proposal) {
|
|
1047
|
+
// Build intersected indices
|
|
1048
|
+
const intersectIdx = request.txIndices.getTrueIndices().filter(i => response.txIndices.isSet(i));
|
|
1049
|
+
|
|
1050
|
+
// Enforce subset membership and preserve increasing order by index.
|
|
1051
|
+
const hashToIndexInProposal = new Map<string, number>(
|
|
1052
|
+
proposal.txHashes.map((h, i) => [h.toString(), i] as [string, number]),
|
|
1053
|
+
);
|
|
1054
|
+
const allowedIndexSet = new Set(intersectIdx);
|
|
1055
|
+
const indices = returnedHashes.map(h => hashToIndexInProposal.get(h));
|
|
1056
|
+
const allAllowed = indices.every(idx => idx !== undefined && allowedIndexSet.has(idx));
|
|
1057
|
+
const strictlyIncreasing = indices.every((idx, i) => (i === 0 ? idx !== undefined : idx! > indices[i - 1]!));
|
|
1058
|
+
if (!allAllowed || !strictlyIncreasing) {
|
|
1059
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1060
|
+
throw new ValidationError('Returned txs do not match expected subset/order for requested indices');
|
|
1061
|
+
}
|
|
1062
|
+
} else {
|
|
1063
|
+
// No local proposal, cannot check the membership/order of the returned txs
|
|
1064
|
+
this.logger.warn(
|
|
1065
|
+
`Block proposal not found for block hash ${request.blockHash.toString()}; cannot validate membership/order of returned txs`,
|
|
1066
|
+
);
|
|
1067
|
+
return false;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
935
1070
|
await Promise.all(response.txs.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator)));
|
|
936
1071
|
return true;
|
|
937
1072
|
} catch (e: any) {
|
|
@@ -955,7 +1090,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
955
1090
|
* ReqRespSubProtocol.TX subprotocol validation.
|
|
956
1091
|
*
|
|
957
1092
|
* @param requestedTxHash - The collection of the txs that was requested.
|
|
958
|
-
* @param responseTx - The
|
|
1093
|
+
* @param responseTx - The collection of txs that was received as a response to the request.
|
|
959
1094
|
* @param peerId - The peer ID of the peer that sent the tx.
|
|
960
1095
|
* @returns True if the whole collection of txs is valid, false otherwise.
|
|
961
1096
|
*/
|
|
@@ -982,6 +1117,53 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
982
1117
|
}
|
|
983
1118
|
}
|
|
984
1119
|
|
|
1120
|
+
/**
|
|
1121
|
+
* Validates a BLOCK response.
|
|
1122
|
+
*
|
|
1123
|
+
* If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
|
|
1124
|
+
* Penalizes on block number mismatch or hash mismatch.
|
|
1125
|
+
*
|
|
1126
|
+
* @param requestedBlockNumber - The requested block number.
|
|
1127
|
+
* @param responseBlock - The block returned by the peer.
|
|
1128
|
+
* @param peerId - The peer that returned the block.
|
|
1129
|
+
* @returns True if the response is valid, false otherwise.
|
|
1130
|
+
*/
|
|
1131
|
+
@trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
|
|
1132
|
+
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
|
|
1133
|
+
}))
|
|
1134
|
+
private async validateRequestedBlock(
|
|
1135
|
+
requestedBlockNumber: Fr,
|
|
1136
|
+
responseBlock: L2Block,
|
|
1137
|
+
peerId: PeerId,
|
|
1138
|
+
): Promise<boolean> {
|
|
1139
|
+
try {
|
|
1140
|
+
const reqNum = Number(requestedBlockNumber.toString());
|
|
1141
|
+
if (responseBlock.number !== reqNum) {
|
|
1142
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1143
|
+
return false;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
const local = await this.archiver.getBlock(BlockNumber(reqNum));
|
|
1147
|
+
if (!local) {
|
|
1148
|
+
// We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
|
|
1149
|
+
// TODO: Consider extending this validator to accept an expected hash or
|
|
1150
|
+
// performing quorum-based checks when using P2P syncing prior to L1 sync.
|
|
1151
|
+
this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
|
|
1152
|
+
return false;
|
|
1153
|
+
}
|
|
1154
|
+
const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
|
|
1155
|
+
if (!localHash.equals(respHash)) {
|
|
1156
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1157
|
+
return false;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
return true;
|
|
1161
|
+
} catch (e) {
|
|
1162
|
+
this.logger.warn(`Error validating requested block`, e);
|
|
1163
|
+
return false;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
985
1167
|
private createRequestedTxValidator(): TxValidator {
|
|
986
1168
|
return new AggregateTxValidator(
|
|
987
1169
|
new DataTxValidator(),
|
|
@@ -996,19 +1178,21 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
996
1178
|
}
|
|
997
1179
|
|
|
998
1180
|
private async validateRequestedTx(tx: Tx, peerId: PeerId, txValidator: TxValidator, requested?: Set<`0x${string}`>) {
|
|
1181
|
+
const penalize = (severity: PeerErrorSeverity) => this.peerManager.penalizePeer(peerId, severity);
|
|
1182
|
+
|
|
999
1183
|
if (!(await tx.validateTxHash())) {
|
|
1000
|
-
|
|
1184
|
+
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1001
1185
|
throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
|
|
1002
1186
|
}
|
|
1003
1187
|
|
|
1004
1188
|
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
1005
|
-
|
|
1189
|
+
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1006
1190
|
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
1007
1191
|
}
|
|
1008
1192
|
|
|
1009
1193
|
const { result } = await txValidator.validateTx(tx);
|
|
1010
1194
|
if (result === 'invalid') {
|
|
1011
|
-
|
|
1195
|
+
penalize(PeerErrorSeverity.LowToleranceError);
|
|
1012
1196
|
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
|
|
1013
1197
|
}
|
|
1014
1198
|
}
|
|
@@ -1034,7 +1218,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1034
1218
|
|
|
1035
1219
|
// Double spend validator has a special case handler
|
|
1036
1220
|
if (name === 'doubleSpendValidator') {
|
|
1037
|
-
const txBlockNumber = currentBlockNumber + 1; // tx is expected to be in the next block
|
|
1221
|
+
const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
|
|
1038
1222
|
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1039
1223
|
}
|
|
1040
1224
|
|
|
@@ -1044,7 +1228,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1044
1228
|
return true;
|
|
1045
1229
|
}
|
|
1046
1230
|
|
|
1047
|
-
private async getGasFees(blockNumber:
|
|
1231
|
+
private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
|
|
1048
1232
|
if (blockNumber === this.feesCache?.blockNumber) {
|
|
1049
1233
|
return this.feesCache.gasFees;
|
|
1050
1234
|
}
|
|
@@ -1085,13 +1269,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1085
1269
|
* @returns The message validators.
|
|
1086
1270
|
*/
|
|
1087
1271
|
private async createMessageValidators(
|
|
1088
|
-
currentBlockNumber:
|
|
1272
|
+
currentBlockNumber: BlockNumber,
|
|
1089
1273
|
nextSlotTimestamp: UInt64,
|
|
1090
1274
|
): Promise<Record<string, MessageValidator>[]> {
|
|
1091
1275
|
const gasFees = await this.getGasFees(currentBlockNumber);
|
|
1092
1276
|
const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
1093
1277
|
|
|
1094
|
-
const blockNumberInWhichTheTxIsConsideredToBeIncluded = currentBlockNumber + 1;
|
|
1278
|
+
const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
|
|
1095
1279
|
|
|
1096
1280
|
return createTxMessageValidators(
|
|
1097
1281
|
nextSlotTimestamp,
|
|
@@ -1153,7 +1337,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1153
1337
|
* @param peerId - The peer ID of the peer that sent the tx.
|
|
1154
1338
|
* @returns Severity
|
|
1155
1339
|
*/
|
|
1156
|
-
private async handleDoubleSpendFailure(tx: Tx, blockNumber:
|
|
1340
|
+
private async handleDoubleSpendFailure(tx: Tx, blockNumber: BlockNumber): Promise<PeerErrorSeverity> {
|
|
1157
1341
|
if (blockNumber <= this.config.doubleSpendSeverePeerPenaltyWindow) {
|
|
1158
1342
|
return PeerErrorSeverity.HighToleranceError;
|
|
1159
1343
|
}
|
|
@@ -1161,7 +1345,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1161
1345
|
const snapshotValidator = new DoubleSpendTxValidator({
|
|
1162
1346
|
nullifiersExist: async (nullifiers: Buffer[]) => {
|
|
1163
1347
|
const merkleTree = this.worldStateSynchronizer.getSnapshot(
|
|
1164
|
-
blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow,
|
|
1348
|
+
BlockNumber(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow),
|
|
1165
1349
|
);
|
|
1166
1350
|
const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
|
|
1167
1351
|
return indices.map(index => index !== undefined);
|
|
@@ -1183,9 +1367,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1183
1367
|
* @returns True if the attestation is valid, false otherwise.
|
|
1184
1368
|
*/
|
|
1185
1369
|
@trackSpan('Libp2pService.validateAttestation', async (_, attestation) => ({
|
|
1186
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber
|
|
1370
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
1187
1371
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1188
|
-
[Attributes.P2P_ID]: await attestation.
|
|
1372
|
+
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1189
1373
|
}))
|
|
1190
1374
|
public async validateAttestation(peerId: PeerId, attestation: BlockAttestation): Promise<boolean> {
|
|
1191
1375
|
const severity = await this.attestationValidator.validate(attestation);
|
|
@@ -1228,7 +1412,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1228
1412
|
private async sendToPeers<T extends Gossipable>(message: T) {
|
|
1229
1413
|
const parent = message.constructor as typeof Gossipable;
|
|
1230
1414
|
|
|
1231
|
-
const identifier = await message.
|
|
1415
|
+
const identifier = await message.p2pMessageLoggingIdentifier().then(i => i.toString());
|
|
1232
1416
|
this.logger.trace(`Sending message ${identifier}`, { p2pMessageIdentifier: identifier });
|
|
1233
1417
|
|
|
1234
1418
|
const recipientsNum = await this.publishToTopic(this.topicStrings[parent.p2pTopic], message);
|