@aztec/p2p 0.0.1-commit.3e3d0c9cd → 0.0.1-commit.3f5453c7b
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/client/factory.d.ts +1 -1
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +5 -4
- package/dest/client/interface.d.ts +9 -2
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +3 -2
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +21 -6
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +17 -6
- package/dest/config.d.ts +10 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +15 -0
- 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/index.d.ts +1 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +0 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +7 -5
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +11 -8
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
- package/dest/mem_pools/index.d.ts +1 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +4 -4
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +5 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +5 -2
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +20 -11
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +4 -2
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
- package/dest/msg_validators/clock_tolerance.d.ts +12 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +54 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +2 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +2 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +3 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +19 -11
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +35 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +1 -1
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +8 -2
- 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/gas_validator.js +11 -9
- package/dest/msg_validators/tx_validator/phases_validator.js +1 -1
- 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 +6 -3
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +6 -1
- package/dest/services/encoding.d.ts +5 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +7 -1
- package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +21 -4
- package/dest/services/libp2p/libp2p_service.d.ts +15 -25
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +121 -112
- 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 +37 -10
- package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +32 -10
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -7
- 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 +43 -56
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +1 -2
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +4 -4
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +7 -7
- package/dest/services/reqresp/interface.d.ts +14 -9
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +10 -11
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +0 -1
- package/dest/services/reqresp/protocols/index.d.ts +1 -2
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.js +0 -1
- package/dest/services/reqresp/protocols/tx.d.ts +1 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +1 -3
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
- package/dest/services/reqresp/reqresp.d.ts +4 -2
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +27 -10
- package/dest/services/service.d.ts +5 -2
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +57 -73
- package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_source.js +39 -29
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +4 -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.js +1 -1
- package/dest/services/tx_collection/tx_collection.d.ts +3 -6
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.d.ts +6 -5
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +9 -7
- package/dest/test-helpers/mock-pubsub.d.ts +11 -3
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +35 -10
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +1 -2
- package/dest/test-helpers/testbench-utils.d.ts +1 -1
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +21 -2
- package/dest/testbench/p2p_client_testbench_worker.js +66 -15
- package/dest/testbench/worker_client_manager.d.ts +8 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +49 -1
- package/package.json +14 -14
- package/src/client/factory.ts +7 -2
- package/src/client/interface.ts +9 -1
- package/src/client/p2p_client.ts +23 -6
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +18 -8
- package/src/config.ts +30 -1
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/index.ts +0 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +12 -8
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
- package/src/mem_pools/index.ts +0 -3
- package/src/mem_pools/tx_pool_v2/interfaces.ts +4 -4
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +7 -1
- package/src/msg_validators/attestation_validator/README.md +1 -1
- package/src/msg_validators/attestation_validator/attestation_validator.ts +21 -9
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +4 -1
- package/src/msg_validators/clock_tolerance.ts +72 -3
- package/src/msg_validators/proposal_validator/README.md +4 -4
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +4 -1
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +4 -1
- package/src/msg_validators/proposal_validator/proposal_validator.ts +17 -10
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +42 -1
- package/src/msg_validators/tx_validator/factory.ts +7 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +25 -9
- package/src/msg_validators/tx_validator/phases_validator.ts +1 -1
- package/src/services/data_store.ts +5 -13
- package/src/services/dummy_service.ts +8 -2
- package/src/services/encoding.ts +9 -1
- package/src/services/gossipsub/topic_score_params.ts +36 -4
- package/src/services/libp2p/libp2p_service.ts +122 -128
- package/src/services/peer-manager/peer_manager.ts +43 -10
- package/src/services/peer-manager/peer_scoring.ts +27 -5
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +35 -60
- package/src/services/reqresp/batch-tx-requester/interface.ts +0 -1
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +6 -6
- package/src/services/reqresp/interface.ts +21 -11
- package/src/services/reqresp/metrics.ts +0 -1
- package/src/services/reqresp/protocols/index.ts +0 -1
- package/src/services/reqresp/protocols/tx.ts +1 -3
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
- package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
- package/src/services/reqresp/reqresp.ts +36 -11
- package/src/services/service.ts +6 -1
- package/src/services/tx_collection/fast_tx_collection.ts +57 -83
- package/src/services/tx_collection/file_store_tx_source.ts +43 -31
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/slow_tx_collection.ts +1 -1
- package/src/services/tx_collection/tx_collection.ts +3 -5
- package/src/services/tx_collection/tx_source.ts +8 -7
- package/src/test-helpers/mock-pubsub.ts +31 -5
- package/src/test-helpers/reqresp-nodes.ts +2 -2
- package/src/test-helpers/testbench-utils.ts +29 -3
- package/src/testbench/p2p_client_testbench_worker.ts +70 -14
- package/src/testbench/worker_client_manager.ts +55 -1
- 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 -123
- 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 -402
- 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/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
- package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
- 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 -163
- 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 -321
- package/src/services/reqresp/protocols/block.ts +0 -37
- package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
|
@@ -28,8 +28,6 @@ export class AztecDatastore implements Datastore {
|
|
|
28
28
|
#memoryDatastore: Map<string, MemoryItem>;
|
|
29
29
|
#dbDatastore: AztecAsyncMap<string, Uint8Array>;
|
|
30
30
|
|
|
31
|
-
#batchOps: BatchOp[] = [];
|
|
32
|
-
|
|
33
31
|
private maxMemoryItems: number;
|
|
34
32
|
|
|
35
33
|
constructor(db: AztecAsyncKVStore, { maxMemoryItems } = { maxMemoryItems: 50 }) {
|
|
@@ -92,23 +90,17 @@ export class AztecDatastore implements Datastore {
|
|
|
92
90
|
}
|
|
93
91
|
|
|
94
92
|
batch(): Batch {
|
|
93
|
+
const ops: BatchOp[] = [];
|
|
95
94
|
return {
|
|
96
95
|
put: (key, value) => {
|
|
97
|
-
|
|
98
|
-
type: 'put',
|
|
99
|
-
key,
|
|
100
|
-
value,
|
|
101
|
-
});
|
|
96
|
+
ops.push({ type: 'put', key, value });
|
|
102
97
|
},
|
|
103
98
|
delete: key => {
|
|
104
|
-
|
|
105
|
-
type: 'del',
|
|
106
|
-
key,
|
|
107
|
-
});
|
|
99
|
+
ops.push({ type: 'del', key });
|
|
108
100
|
},
|
|
109
101
|
commit: async () => {
|
|
110
102
|
await this.#db.transactionAsync(async () => {
|
|
111
|
-
for (const op of
|
|
103
|
+
for (const op of ops) {
|
|
112
104
|
if (op.type === 'put' && op.value) {
|
|
113
105
|
await this.put(op.key, op.value);
|
|
114
106
|
} else if (op.type === 'del') {
|
|
@@ -116,7 +108,7 @@ export class AztecDatastore implements Datastore {
|
|
|
116
108
|
}
|
|
117
109
|
}
|
|
118
110
|
});
|
|
119
|
-
|
|
111
|
+
ops.length = 0;
|
|
120
112
|
},
|
|
121
113
|
};
|
|
122
114
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
2
|
import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
|
|
3
|
-
import type { Gossipable, PeerErrorSeverity, TopicType } from '@aztec/stdlib/p2p';
|
|
3
|
+
import type { CheckpointProposalCore, Gossipable, PeerErrorSeverity, TopicType } from '@aztec/stdlib/p2p';
|
|
4
4
|
import { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
5
5
|
|
|
6
6
|
import type { PeerId } from '@libp2p/interface';
|
|
@@ -86,7 +86,12 @@ export class DummyP2PService implements P2PService {
|
|
|
86
86
|
/**
|
|
87
87
|
* Register a callback into the validator client for when a checkpoint proposal is received
|
|
88
88
|
*/
|
|
89
|
-
public
|
|
89
|
+
public registerValidatorCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {}
|
|
90
|
+
public registerAllNodesCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {}
|
|
91
|
+
|
|
92
|
+
public notifyOwnCheckpointProposal(_checkpoint: CheckpointProposalCore): Promise<void> {
|
|
93
|
+
return Promise.resolve();
|
|
94
|
+
}
|
|
90
95
|
|
|
91
96
|
/**
|
|
92
97
|
* Register a callback for when a duplicate proposal is detected
|
|
@@ -282,6 +287,7 @@ export class DummyPeerManager implements PeerManagerInterface {
|
|
|
282
287
|
|
|
283
288
|
export class DummyReqResp implements ReqRespInterface {
|
|
284
289
|
updateConfig(_config: Partial<P2PReqRespConfig>): void {}
|
|
290
|
+
setShouldRejectPeer(): void {}
|
|
285
291
|
start(
|
|
286
292
|
_subProtocolHandlers: ReqRespSubProtocolHandlers,
|
|
287
293
|
_subProtocolValidators: ReqRespSubProtocolValidators,
|
package/src/services/encoding.ts
CHANGED
|
@@ -9,6 +9,14 @@ import { webcrypto } from 'node:crypto';
|
|
|
9
9
|
import { compressSync, uncompressSync } from 'snappy';
|
|
10
10
|
import xxhashFactory from 'xxhash-wasm';
|
|
11
11
|
|
|
12
|
+
/** Thrown when a Snappy-compressed response exceeds the allowed decompressed size. */
|
|
13
|
+
export class OversizedSnappyResponseError extends Error {
|
|
14
|
+
constructor(decompressedSize: number, maxSizeKb: number) {
|
|
15
|
+
super(`Decompressed size ${decompressedSize} exceeds maximum allowed size of ${maxSizeKb}kb`);
|
|
16
|
+
this.name = 'OversizedSnappyResponseError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
// Load WASM
|
|
13
21
|
const xxhash = await xxhashFactory();
|
|
14
22
|
|
|
@@ -86,7 +94,7 @@ export class SnappyTransform implements DataTransform {
|
|
|
86
94
|
const { decompressedSize } = readSnappyPreamble(data);
|
|
87
95
|
if (decompressedSize > maxSizeKb * 1024) {
|
|
88
96
|
this.logger.warn(`Decompressed size ${decompressedSize} exceeds maximum allowed size of ${maxSizeKb}kb`);
|
|
89
|
-
throw new
|
|
97
|
+
throw new OversizedSnappyResponseError(decompressedSize, maxSizeKb);
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
return Buffer.from(uncompressSync(data, { asBuffer: true }));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TopicType, createTopicString } from '@aztec/stdlib/p2p';
|
|
2
|
-
import {
|
|
2
|
+
import { createCheckpointTimingModel } from '@aztec/stdlib/timetable';
|
|
3
3
|
|
|
4
4
|
import { createTopicScoreParams } from '@chainsafe/libp2p-gossipsub/score';
|
|
5
5
|
|
|
@@ -9,12 +9,18 @@ import { createTopicScoreParams } from '@chainsafe/libp2p-gossipsub/score';
|
|
|
9
9
|
export type TopicScoringNetworkParams = {
|
|
10
10
|
/** L2 slot duration in milliseconds */
|
|
11
11
|
slotDurationMs: number;
|
|
12
|
+
/** L1 slot duration in seconds */
|
|
13
|
+
ethereumSlotDuration: number;
|
|
12
14
|
/** Gossipsub heartbeat interval in milliseconds */
|
|
13
15
|
heartbeatIntervalMs: number;
|
|
14
16
|
/** Target committee size (number of validators expected to attest per slot) */
|
|
15
17
|
targetCommitteeSize: number;
|
|
16
18
|
/** Duration per block in milliseconds when building multiple blocks per slot. If undefined, single block mode. */
|
|
17
19
|
blockDurationMs?: number;
|
|
20
|
+
/** Time budget in seconds reserved for L1 publishing. Defaults to ethereumSlotDuration. */
|
|
21
|
+
l1PublishingTime?: number;
|
|
22
|
+
/** One-way proposal/attestation propagation budget in seconds. */
|
|
23
|
+
p2pPropagationTime?: number;
|
|
18
24
|
/** Expected number of block proposals per slot for scoring override. 0 disables scoring, undefined falls back to blocksPerSlot - 1. */
|
|
19
25
|
expectedBlockProposalsPerSlot?: number;
|
|
20
26
|
};
|
|
@@ -25,10 +31,32 @@ export type TopicScoringNetworkParams = {
|
|
|
25
31
|
*
|
|
26
32
|
* @param slotDurationMs - L2 slot duration in milliseconds
|
|
27
33
|
* @param blockDurationMs - Duration per block in milliseconds (undefined = single block mode)
|
|
34
|
+
* @param opts - Shared checkpoint timing inputs used by the sequencer and validators
|
|
28
35
|
* @returns Number of blocks per slot
|
|
29
36
|
*/
|
|
30
|
-
export function calculateBlocksPerSlot(
|
|
31
|
-
|
|
37
|
+
export function calculateBlocksPerSlot(
|
|
38
|
+
slotDurationMs: number,
|
|
39
|
+
blockDurationMs: number | undefined,
|
|
40
|
+
opts?: {
|
|
41
|
+
ethereumSlotDuration: number;
|
|
42
|
+
l1PublishingTime?: number;
|
|
43
|
+
p2pPropagationTime?: number;
|
|
44
|
+
},
|
|
45
|
+
): number {
|
|
46
|
+
if (!opts) {
|
|
47
|
+
return createCheckpointTimingModel({
|
|
48
|
+
aztecSlotDuration: slotDurationMs / 1000,
|
|
49
|
+
blockDuration: blockDurationMs ? blockDurationMs / 1000 : undefined,
|
|
50
|
+
}).calculateMaxBlocksPerSlot();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return createCheckpointTimingModel({
|
|
54
|
+
aztecSlotDuration: slotDurationMs / 1000,
|
|
55
|
+
ethereumSlotDuration: opts.ethereumSlotDuration,
|
|
56
|
+
blockDuration: blockDurationMs ? blockDurationMs / 1000 : undefined,
|
|
57
|
+
l1PublishingTime: opts.l1PublishingTime ?? opts.ethereumSlotDuration,
|
|
58
|
+
p2pPropagationTime: opts.p2pPropagationTime,
|
|
59
|
+
}).calculateMaxBlocksPerSlot();
|
|
32
60
|
}
|
|
33
61
|
|
|
34
62
|
/**
|
|
@@ -279,7 +307,11 @@ export class TopicScoreParamsFactory {
|
|
|
279
307
|
const { slotDurationMs, heartbeatIntervalMs, blockDurationMs } = params;
|
|
280
308
|
|
|
281
309
|
// Compute values that are the same for all topics
|
|
282
|
-
this.blocksPerSlot = calculateBlocksPerSlot(slotDurationMs, blockDurationMs
|
|
310
|
+
this.blocksPerSlot = calculateBlocksPerSlot(slotDurationMs, blockDurationMs, {
|
|
311
|
+
ethereumSlotDuration: params.ethereumSlotDuration,
|
|
312
|
+
l1PublishingTime: params.l1PublishingTime,
|
|
313
|
+
p2pPropagationTime: params.p2pPropagationTime,
|
|
314
|
+
});
|
|
283
315
|
this.heartbeatsPerSlot = slotDurationMs / heartbeatIntervalMs;
|
|
284
316
|
this.invalidDecay = computeDecay(heartbeatIntervalMs, slotDurationMs, INVALID_DECAY_WINDOW_SLOTS);
|
|
285
317
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
2
|
import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { maxBy } from '@aztec/foundation/collection';
|
|
4
|
-
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
4
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
6
5
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
7
6
|
import { Timer } from '@aztec/foundation/timer';
|
|
8
7
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
9
8
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
10
|
-
import type { EthAddress,
|
|
9
|
+
import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
|
|
11
10
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
12
11
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
13
12
|
import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
@@ -18,7 +17,6 @@ import {
|
|
|
18
17
|
type CheckpointProposalCore,
|
|
19
18
|
type Gossipable,
|
|
20
19
|
P2PMessage,
|
|
21
|
-
type ValidationResult as P2PValidationResult,
|
|
22
20
|
PeerErrorSeverity,
|
|
23
21
|
PeerErrorSeverityByHarshness,
|
|
24
22
|
TopicType,
|
|
@@ -59,6 +57,7 @@ import { ENR } from '@nethermindeth/enr';
|
|
|
59
57
|
import { createLibp2p } from 'libp2p';
|
|
60
58
|
|
|
61
59
|
import type { P2PConfig } from '../../config.js';
|
|
60
|
+
import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
|
|
62
61
|
import type { MemPools } from '../../mem_pools/interface.js';
|
|
63
62
|
import {
|
|
64
63
|
BlockProposalValidator,
|
|
@@ -105,7 +104,6 @@ import {
|
|
|
105
104
|
ValidationError,
|
|
106
105
|
pingHandler,
|
|
107
106
|
reqGoodbyeHandler,
|
|
108
|
-
reqRespBlockHandler,
|
|
109
107
|
reqRespBlockTxsHandler,
|
|
110
108
|
reqRespStatusHandler,
|
|
111
109
|
reqRespTxHandler,
|
|
@@ -131,7 +129,7 @@ type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: Vali
|
|
|
131
129
|
// REFACTOR: Unify with the type above
|
|
132
130
|
type ReceivedMessageValidationResult<T, M = undefined> =
|
|
133
131
|
| { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
|
|
134
|
-
| { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
|
|
132
|
+
| { obj?: T; result: TopicValidatorResult.Reject; metadata?: M; severity: PeerErrorSeverity };
|
|
135
133
|
|
|
136
134
|
/**
|
|
137
135
|
* Lib P2P implementation of the P2PService interface.
|
|
@@ -172,7 +170,13 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
172
170
|
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
173
171
|
* @returns The attestations for the checkpoint, if any.
|
|
174
172
|
*/
|
|
175
|
-
private
|
|
173
|
+
private allNodesCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
|
|
174
|
+
/**
|
|
175
|
+
* Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
|
|
176
|
+
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
177
|
+
* @returns The attestations for the checkpoint, if any.
|
|
178
|
+
*/
|
|
179
|
+
private validatorCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
|
|
176
180
|
|
|
177
181
|
private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
|
|
178
182
|
|
|
@@ -224,15 +228,19 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
224
228
|
this.protocolVersion,
|
|
225
229
|
);
|
|
226
230
|
|
|
231
|
+
const p2pPropagationTime = config.attestationPropagationTime;
|
|
227
232
|
const proposalValidatorOpts = {
|
|
228
233
|
txsPermitted: !config.disableTransactions,
|
|
229
|
-
maxTxsPerBlock: config.validateMaxTxsPerBlock,
|
|
234
|
+
maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
|
|
235
|
+
p2pPropagationTime,
|
|
230
236
|
};
|
|
231
237
|
this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
|
|
232
238
|
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
|
|
233
239
|
this.checkpointAttestationValidator = config.fishermanMode
|
|
234
|
-
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry
|
|
235
|
-
|
|
240
|
+
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, {
|
|
241
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
242
|
+
})
|
|
243
|
+
: new CheckpointAttestationValidator(epochCache, { l1PublishingTime: config.l1PublishingTime });
|
|
236
244
|
|
|
237
245
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
238
246
|
|
|
@@ -244,12 +252,15 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
244
252
|
return true;
|
|
245
253
|
};
|
|
246
254
|
|
|
247
|
-
this.
|
|
248
|
-
|
|
255
|
+
this.allNodesCheckpointReceivedCallback = (
|
|
256
|
+
_checkpoint: CheckpointProposalCore,
|
|
257
|
+
): Promise<CheckpointAttestation[] | undefined> => {
|
|
258
|
+
throw new CheckpointProposalReceivedCallbackNotRegisteredError();
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
this.validatorCheckpointReceivedCallback = (
|
|
262
|
+
_checkpoint: CheckpointProposalCore,
|
|
249
263
|
): Promise<CheckpointAttestation[] | undefined> => {
|
|
250
|
-
this.logger.debug(
|
|
251
|
-
`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
|
|
252
|
-
);
|
|
253
264
|
return Promise.resolve(undefined);
|
|
254
265
|
};
|
|
255
266
|
}
|
|
@@ -339,9 +350,12 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
339
350
|
const l1Constants = epochCache.getL1Constants();
|
|
340
351
|
const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
|
|
341
352
|
slotDurationMs: l1Constants.slotDuration * 1000,
|
|
353
|
+
ethereumSlotDuration: l1Constants.ethereumSlotDuration,
|
|
342
354
|
heartbeatIntervalMs: config.gossipsubInterval,
|
|
343
355
|
targetCommitteeSize: l1Constants.targetCommitteeSize,
|
|
344
356
|
blockDurationMs: config.blockDurationMs,
|
|
357
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
358
|
+
p2pPropagationTime: config.attestationPropagationTime,
|
|
345
359
|
expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
|
|
346
360
|
});
|
|
347
361
|
|
|
@@ -466,6 +480,9 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
466
480
|
epochCache,
|
|
467
481
|
);
|
|
468
482
|
|
|
483
|
+
// Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
|
|
484
|
+
reqresp.setShouldRejectPeer(peerId => peerManager.shouldDisableP2PGossip(peerId));
|
|
485
|
+
|
|
469
486
|
// Configure application-specific scoring for gossipsub.
|
|
470
487
|
// The weight scales app score to align with gossipsub thresholds:
|
|
471
488
|
// - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
|
|
@@ -511,14 +528,12 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
511
528
|
// Create request response protocol handlers
|
|
512
529
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
513
530
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
514
|
-
const blockHandler = reqRespBlockHandler(this.archiver);
|
|
515
531
|
const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
|
|
516
532
|
|
|
517
533
|
const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
|
|
518
534
|
[ReqRespSubProtocol.PING]: pingHandler,
|
|
519
535
|
[ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
|
|
520
536
|
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
|
|
521
|
-
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
|
|
522
537
|
};
|
|
523
538
|
|
|
524
539
|
if (!this.config.disableTransactions) {
|
|
@@ -539,7 +554,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
539
554
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
540
555
|
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
541
556
|
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
542
|
-
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
|
|
543
557
|
};
|
|
544
558
|
|
|
545
559
|
await this.peerManager.initializePeers();
|
|
@@ -667,8 +681,16 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
667
681
|
this.blockReceivedCallback = callback;
|
|
668
682
|
}
|
|
669
683
|
|
|
670
|
-
public
|
|
671
|
-
this.
|
|
684
|
+
public registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
685
|
+
this.validatorCheckpointReceivedCallback = callback;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
689
|
+
this.allNodesCheckpointReceivedCallback = callback;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void> {
|
|
693
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
|
|
672
694
|
}
|
|
673
695
|
|
|
674
696
|
/**
|
|
@@ -883,30 +905,56 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
883
905
|
source: PeerId,
|
|
884
906
|
topicType: TopicType,
|
|
885
907
|
): Promise<ReceivedMessageValidationResult<T, M>> {
|
|
886
|
-
|
|
908
|
+
// Default to reject result with a penalty if validation function throws an error
|
|
909
|
+
let resultAndObj: ReceivedMessageValidationResult<T, M> = {
|
|
910
|
+
result: TopicValidatorResult.Reject,
|
|
911
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
912
|
+
};
|
|
887
913
|
const timer = new Timer();
|
|
888
914
|
try {
|
|
889
915
|
resultAndObj = await validationFunc();
|
|
890
916
|
} catch (err) {
|
|
891
|
-
this.
|
|
892
|
-
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
893
|
-
msgId,
|
|
894
|
-
source: source.toString(),
|
|
895
|
-
topicType,
|
|
896
|
-
});
|
|
917
|
+
this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
|
|
897
918
|
}
|
|
898
919
|
|
|
899
920
|
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
921
|
+
this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
|
|
900
922
|
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
923
|
+
} else if (resultAndObj.result === TopicValidatorResult.Reject) {
|
|
924
|
+
this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
|
|
925
|
+
msgId,
|
|
926
|
+
source: source.toString(),
|
|
927
|
+
topicType,
|
|
928
|
+
severity: resultAndObj.severity,
|
|
929
|
+
});
|
|
930
|
+
this.peerManager.penalizePeer(source, resultAndObj.severity);
|
|
931
|
+
} else {
|
|
932
|
+
this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
|
|
901
933
|
}
|
|
902
934
|
|
|
903
935
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
904
936
|
return resultAndObj;
|
|
905
937
|
}
|
|
906
938
|
|
|
939
|
+
private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
|
|
940
|
+
try {
|
|
941
|
+
return deserializeFunc();
|
|
942
|
+
} catch (err) {
|
|
943
|
+
this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
|
|
944
|
+
err,
|
|
945
|
+
msgId,
|
|
946
|
+
source: source.toString(),
|
|
947
|
+
});
|
|
948
|
+
return undefined;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
|
|
907
952
|
protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
|
|
908
953
|
const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
|
|
909
|
-
const tx = Tx.fromBuffer(payloadData);
|
|
954
|
+
const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
|
|
955
|
+
if (!tx) {
|
|
956
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
|
|
957
|
+
}
|
|
910
958
|
|
|
911
959
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
912
960
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
@@ -931,8 +979,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
931
979
|
severity,
|
|
932
980
|
source: source.toString(),
|
|
933
981
|
});
|
|
934
|
-
|
|
935
|
-
return { result: TopicValidatorResult.Reject };
|
|
982
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
936
983
|
}
|
|
937
984
|
|
|
938
985
|
// Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
|
|
@@ -954,8 +1001,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
954
1001
|
severity,
|
|
955
1002
|
source: source.toString(),
|
|
956
1003
|
});
|
|
957
|
-
|
|
958
|
-
return { result: TopicValidatorResult.Reject };
|
|
1004
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
959
1005
|
}
|
|
960
1006
|
|
|
961
1007
|
// Pool add: persist the tx
|
|
@@ -976,7 +1022,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
976
1022
|
} else if (wasIgnored) {
|
|
977
1023
|
return { result: TopicValidatorResult.Ignore, obj: tx };
|
|
978
1024
|
} else {
|
|
979
|
-
|
|
1025
|
+
this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
|
|
1026
|
+
source: source.toString(),
|
|
1027
|
+
txHash: txHash.toString(),
|
|
1028
|
+
});
|
|
1029
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
980
1030
|
}
|
|
981
1031
|
};
|
|
982
1032
|
|
|
@@ -1006,7 +1056,16 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1006
1056
|
source: PeerId,
|
|
1007
1057
|
): Promise<void> {
|
|
1008
1058
|
const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
|
|
1009
|
-
() =>
|
|
1059
|
+
() => {
|
|
1060
|
+
const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
|
|
1061
|
+
if (!attestation) {
|
|
1062
|
+
return Promise.resolve({
|
|
1063
|
+
result: TopicValidatorResult.Reject,
|
|
1064
|
+
severity: PeerErrorSeverity.LowToleranceError,
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
return this.validateAndStoreCheckpointAttestation(source, attestation);
|
|
1068
|
+
},
|
|
1010
1069
|
msgId,
|
|
1011
1070
|
source,
|
|
1012
1071
|
TopicType.checkpoint_attestation,
|
|
@@ -1039,8 +1098,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1039
1098
|
|
|
1040
1099
|
if (validationResult.result === 'reject') {
|
|
1041
1100
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1042
|
-
|
|
1043
|
-
return { result: TopicValidatorResult.Reject };
|
|
1101
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1044
1102
|
}
|
|
1045
1103
|
|
|
1046
1104
|
if (validationResult.result === 'ignore') {
|
|
@@ -1066,16 +1124,16 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1066
1124
|
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
1067
1125
|
}
|
|
1068
1126
|
|
|
1069
|
-
// Could not add (cap reached for signer),
|
|
1127
|
+
// Could not add (cap reached for signer), penalize and do not re-broadcast
|
|
1070
1128
|
if (!added) {
|
|
1071
|
-
this.logger.warn(`
|
|
1129
|
+
this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
|
|
1072
1130
|
slot: slot.toString(),
|
|
1073
1131
|
archive: attestation.archive.toString(),
|
|
1074
1132
|
source: peerId.toString(),
|
|
1075
1133
|
attester: attestation.getSender()?.toString(),
|
|
1076
1134
|
count,
|
|
1077
1135
|
});
|
|
1078
|
-
return { result: TopicValidatorResult.
|
|
1136
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
1079
1137
|
}
|
|
1080
1138
|
|
|
1081
1139
|
// Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
|
|
@@ -1130,8 +1188,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1130
1188
|
|
|
1131
1189
|
if (validationResult.result === 'reject') {
|
|
1132
1190
|
this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1133
|
-
|
|
1134
|
-
return { result: TopicValidatorResult.Reject };
|
|
1191
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1135
1192
|
}
|
|
1136
1193
|
|
|
1137
1194
|
if (validationResult.result === 'ignore') {
|
|
@@ -1155,7 +1212,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1155
1212
|
|
|
1156
1213
|
// Too many blocks received for this slot and index, penalize peer and do not re-broadcast
|
|
1157
1214
|
if (!added) {
|
|
1158
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1159
1215
|
this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
|
|
1160
1216
|
...block.toBlockInfo(),
|
|
1161
1217
|
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
@@ -1163,7 +1219,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1163
1219
|
proposer: block.getSender()?.toString(),
|
|
1164
1220
|
source: peerId.toString(),
|
|
1165
1221
|
});
|
|
1166
|
-
return {
|
|
1222
|
+
return {
|
|
1223
|
+
result: TopicValidatorResult.Reject,
|
|
1224
|
+
metadata: { isEquivocated },
|
|
1225
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1226
|
+
};
|
|
1167
1227
|
}
|
|
1168
1228
|
|
|
1169
1229
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1256,8 +1316,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1256
1316
|
|
|
1257
1317
|
if (validationResult.result === 'reject') {
|
|
1258
1318
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1259
|
-
|
|
1260
|
-
return { result: TopicValidatorResult.Reject };
|
|
1319
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1261
1320
|
}
|
|
1262
1321
|
|
|
1263
1322
|
if (validationResult.result === 'ignore') {
|
|
@@ -1272,20 +1331,21 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1272
1331
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1273
1332
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1274
1333
|
});
|
|
1275
|
-
const
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
metadata: { isEquivocated } = {},
|
|
1279
|
-
} = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1280
|
-
if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1334
|
+
const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1335
|
+
const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
|
|
1336
|
+
if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1281
1337
|
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1282
1338
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1283
1339
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1284
1340
|
isEquivocated,
|
|
1285
|
-
result,
|
|
1341
|
+
result: blockProposalResult.result,
|
|
1286
1342
|
});
|
|
1287
|
-
return {
|
|
1288
|
-
|
|
1343
|
+
return {
|
|
1344
|
+
result: TopicValidatorResult.Reject,
|
|
1345
|
+
severity:
|
|
1346
|
+
'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
|
|
1347
|
+
};
|
|
1348
|
+
} else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1289
1349
|
processBlock = true;
|
|
1290
1350
|
}
|
|
1291
1351
|
}
|
|
@@ -1312,13 +1372,17 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1312
1372
|
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1313
1373
|
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1314
1374
|
if (!added) {
|
|
1315
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1316
1375
|
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1317
1376
|
...checkpoint.toCheckpointInfo(),
|
|
1318
1377
|
count,
|
|
1319
1378
|
source: peerId.toString(),
|
|
1320
1379
|
});
|
|
1321
|
-
return {
|
|
1380
|
+
return {
|
|
1381
|
+
result: TopicValidatorResult.Reject,
|
|
1382
|
+
obj: checkpoint,
|
|
1383
|
+
metadata: { isEquivocated, processBlock },
|
|
1384
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1385
|
+
};
|
|
1322
1386
|
}
|
|
1323
1387
|
|
|
1324
1388
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1363,9 +1427,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1363
1427
|
source: sender.toString(),
|
|
1364
1428
|
});
|
|
1365
1429
|
|
|
1430
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
|
|
1431
|
+
|
|
1366
1432
|
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1367
1433
|
// to validate and potentially generate attestations
|
|
1368
|
-
const attestations = await this.
|
|
1434
|
+
const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
|
|
1369
1435
|
if (attestations && attestations.length > 0) {
|
|
1370
1436
|
// If the callback returned attestations, add them to the pool and propagate them
|
|
1371
1437
|
await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
|
|
@@ -1513,53 +1579,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1513
1579
|
}
|
|
1514
1580
|
}
|
|
1515
1581
|
|
|
1516
|
-
/**
|
|
1517
|
-
* Validates a BLOCK response.
|
|
1518
|
-
*
|
|
1519
|
-
* If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
|
|
1520
|
-
* Penalizes on block number mismatch or hash mismatch.
|
|
1521
|
-
*
|
|
1522
|
-
* @param requestedBlockNumber - The requested block number.
|
|
1523
|
-
* @param responseBlock - The block returned by the peer.
|
|
1524
|
-
* @param peerId - The peer that returned the block.
|
|
1525
|
-
* @returns True if the response is valid, false otherwise.
|
|
1526
|
-
*/
|
|
1527
|
-
@trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
|
|
1528
|
-
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
|
|
1529
|
-
}))
|
|
1530
|
-
protected async validateRequestedBlock(
|
|
1531
|
-
requestedBlockNumber: Fr,
|
|
1532
|
-
responseBlock: L2Block,
|
|
1533
|
-
peerId: PeerId,
|
|
1534
|
-
): Promise<boolean> {
|
|
1535
|
-
try {
|
|
1536
|
-
const reqNum = Number(requestedBlockNumber.toString());
|
|
1537
|
-
if (responseBlock.number !== reqNum) {
|
|
1538
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1539
|
-
return false;
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
const local = await this.archiver.getBlock(BlockNumber(reqNum));
|
|
1543
|
-
if (!local) {
|
|
1544
|
-
// We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
|
|
1545
|
-
// TODO: Consider extending this validator to accept an expected hash or
|
|
1546
|
-
// performing quorum-based checks when using P2P syncing prior to L1 sync.
|
|
1547
|
-
this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
|
|
1548
|
-
return false;
|
|
1549
|
-
}
|
|
1550
|
-
const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
|
|
1551
|
-
if (!localHash.equals(respHash)) {
|
|
1552
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1553
|
-
return false;
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
return true;
|
|
1557
|
-
} catch (e) {
|
|
1558
|
-
this.logger.warn(`Error validating requested block`, e);
|
|
1559
|
-
return false;
|
|
1560
|
-
}
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
1582
|
protected async validateRequestedTx(
|
|
1564
1583
|
tx: Tx,
|
|
1565
1584
|
peerId: PeerId,
|
|
@@ -1742,31 +1761,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1742
1761
|
return PeerErrorSeverity.HighToleranceError;
|
|
1743
1762
|
}
|
|
1744
1763
|
|
|
1745
|
-
/**
|
|
1746
|
-
* Validate a checkpoint attestation.
|
|
1747
|
-
*
|
|
1748
|
-
* @param attestation - The checkpoint attestation to validate.
|
|
1749
|
-
* @returns True if the checkpoint attestation is valid, false otherwise.
|
|
1750
|
-
*/
|
|
1751
|
-
@trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
|
|
1752
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
1753
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1754
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1755
|
-
}))
|
|
1756
|
-
public async validateCheckpointAttestation(
|
|
1757
|
-
peerId: PeerId,
|
|
1758
|
-
attestation: CheckpointAttestation,
|
|
1759
|
-
): Promise<P2PValidationResult> {
|
|
1760
|
-
const result = await this.checkpointAttestationValidator.validate(attestation);
|
|
1761
|
-
|
|
1762
|
-
if (result.result === 'reject') {
|
|
1763
|
-
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1764
|
-
this.peerManager.penalizePeer(peerId, result.severity);
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
return result;
|
|
1768
|
-
}
|
|
1769
|
-
|
|
1770
1764
|
public getPeerScore(peerId: PeerId): number {
|
|
1771
1765
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
1772
1766
|
}
|