@aztec/p2p 0.0.0-test.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dest/bootstrap/bootstrap.d.ts +38 -0
- package/dest/bootstrap/bootstrap.d.ts.map +1 -0
- package/dest/bootstrap/bootstrap.js +123 -0
- package/dest/client/factory.d.ts +21 -0
- package/dest/client/factory.d.ts.map +1 -0
- package/dest/client/factory.js +37 -0
- package/dest/client/index.d.ts +3 -0
- package/dest/client/index.d.ts.map +1 -0
- package/dest/client/index.js +2 -0
- package/dest/client/p2p_client.d.ts +314 -0
- package/dest/client/p2p_client.d.ts.map +1 -0
- package/dest/client/p2p_client.js +505 -0
- package/dest/config.d.ts +180 -0
- package/dest/config.d.ts.map +1 -0
- package/dest/config.js +193 -0
- package/dest/enr/generate-enr.d.ts +9 -0
- package/dest/enr/generate-enr.d.ts.map +1 -0
- package/dest/enr/generate-enr.js +30 -0
- package/dest/enr/index.d.ts +2 -0
- package/dest/enr/index.d.ts.map +1 -0
- package/dest/enr/index.js +1 -0
- package/dest/errors/reqresp.error.d.ts +28 -0
- package/dest/errors/reqresp.error.d.ts.map +1 -0
- package/dest/errors/reqresp.error.js +30 -0
- package/dest/index.d.ts +8 -0
- package/dest/index.d.ts.map +1 -0
- package/dest/index.js +7 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +57 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.js +6 -0
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +3 -0
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +195 -0
- package/dest/mem_pools/attestation_pool/index.d.ts +3 -0
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/index.js +2 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +22 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +112 -0
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +17 -0
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +129 -0
- package/dest/mem_pools/attestation_pool/mocks.d.ts +19 -0
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/mocks.js +33 -0
- package/dest/mem_pools/index.d.ts +4 -0
- package/dest/mem_pools/index.d.ts.map +1 -0
- package/dest/mem_pools/index.js +1 -0
- package/dest/mem_pools/instrumentation.d.ts +30 -0
- package/dest/mem_pools/instrumentation.d.ts.map +1 -0
- package/dest/mem_pools/instrumentation.js +84 -0
- package/dest/mem_pools/interface.d.ts +11 -0
- package/dest/mem_pools/interface.d.ts.map +1 -0
- package/dest/mem_pools/interface.js +3 -0
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +66 -0
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +245 -0
- package/dest/mem_pools/tx_pool/index.d.ts +4 -0
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/index.js +3 -0
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +56 -0
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +141 -0
- package/dest/mem_pools/tx_pool/priority.d.ts +8 -0
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/priority.js +10 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +66 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/tx_pool.js +3 -0
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +7 -0
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +169 -0
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +8 -0
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/attestation_validator.js +19 -0
- package/dest/msg_validators/attestation_validator/index.d.ts +2 -0
- package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/index.js +1 -0
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +8 -0
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +21 -0
- package/dest/msg_validators/block_proposal_validator/index.d.ts +2 -0
- package/dest/msg_validators/block_proposal_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/block_proposal_validator/index.js +1 -0
- package/dest/msg_validators/index.d.ts +4 -0
- package/dest/msg_validators/index.d.ts.map +1 -0
- package/dest/msg_validators/index.js +3 -0
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +7 -0
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +31 -0
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +11 -0
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/block_header_validator.js +26 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts +6 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/data_validator.js +107 -0
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +12 -0
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/double_spend_validator.js +41 -0
- package/dest/msg_validators/tx_validator/index.d.ts +7 -0
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/index.js +6 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +10 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/metadata_validator.js +44 -0
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +25 -0
- package/dest/services/data_store.d.ts +27 -0
- package/dest/services/data_store.d.ts.map +1 -0
- package/dest/services/data_store.js +188 -0
- package/dest/services/discv5/discV5_service.d.ts +42 -0
- package/dest/services/discv5/discV5_service.d.ts.map +1 -0
- package/dest/services/discv5/discV5_service.js +214 -0
- package/dest/services/dummy_service.d.ts +85 -0
- package/dest/services/dummy_service.d.ts.map +1 -0
- package/dest/services/dummy_service.js +92 -0
- package/dest/services/encoding.d.ts +31 -0
- package/dest/services/encoding.d.ts.map +1 -0
- package/dest/services/encoding.js +66 -0
- package/dest/services/gossipsub/scoring.d.ts +7 -0
- package/dest/services/gossipsub/scoring.d.ts.map +1 -0
- package/dest/services/gossipsub/scoring.js +10 -0
- package/dest/services/index.d.ts +3 -0
- package/dest/services/index.d.ts.map +1 -0
- package/dest/services/index.js +2 -0
- package/dest/services/libp2p/libp2p_service.d.ts +186 -0
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -0
- package/dest/services/libp2p/libp2p_service.js +712 -0
- package/dest/services/peer-manager/metrics.d.ts +12 -0
- package/dest/services/peer-manager/metrics.d.ts.map +1 -0
- package/dest/services/peer-manager/metrics.js +33 -0
- package/dest/services/peer-manager/peer_manager.d.ts +94 -0
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -0
- package/dest/services/peer-manager/peer_manager.js +445 -0
- package/dest/services/peer-manager/peer_scoring.d.ts +28 -0
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -0
- package/dest/services/peer-manager/peer_scoring.js +86 -0
- package/dest/services/reqresp/config.d.ts +16 -0
- package/dest/services/reqresp/config.d.ts.map +1 -0
- package/dest/services/reqresp/config.js +20 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +45 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +88 -0
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +61 -0
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -0
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +181 -0
- package/dest/services/reqresp/index.d.ts +6 -0
- package/dest/services/reqresp/index.d.ts.map +1 -0
- package/dest/services/reqresp/index.js +4 -0
- package/dest/services/reqresp/interface.d.ts +116 -0
- package/dest/services/reqresp/interface.d.ts.map +1 -0
- package/dest/services/reqresp/interface.js +84 -0
- package/dest/services/reqresp/metrics.d.ts +15 -0
- package/dest/services/reqresp/metrics.d.ts.map +1 -0
- package/dest/services/reqresp/metrics.js +55 -0
- package/dest/services/reqresp/protocols/block.d.ts +4 -0
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block.js +8 -0
- package/dest/services/reqresp/protocols/goodbye.d.ts +51 -0
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/goodbye.js +87 -0
- package/dest/services/reqresp/protocols/index.d.ts +9 -0
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/index.js +7 -0
- package/dest/services/reqresp/protocols/ping.d.ts +9 -0
- package/dest/services/reqresp/protocols/ping.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/ping.js +7 -0
- package/dest/services/reqresp/protocols/status.d.ts +9 -0
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/status.js +7 -0
- package/dest/services/reqresp/protocols/tx.d.ts +13 -0
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/tx.js +20 -0
- package/dest/services/reqresp/rate-limiter/index.d.ts +2 -0
- package/dest/services/reqresp/rate-limiter/index.d.ts.map +1 -0
- package/dest/services/reqresp/rate-limiter/index.js +1 -0
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +102 -0
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -0
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +184 -0
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +3 -0
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -0
- package/dest/services/reqresp/rate-limiter/rate_limits.js +54 -0
- package/dest/services/reqresp/reqresp.d.ts +166 -0
- package/dest/services/reqresp/reqresp.d.ts.map +1 -0
- package/dest/services/reqresp/reqresp.js +516 -0
- package/dest/services/reqresp/status.d.ts +31 -0
- package/dest/services/reqresp/status.d.ts.map +1 -0
- package/dest/services/reqresp/status.js +51 -0
- package/dest/services/service.d.ts +87 -0
- package/dest/services/service.d.ts.map +1 -0
- package/dest/services/service.js +5 -0
- package/dest/test-helpers/generate-peer-id-private-keys.d.ts +7 -0
- package/dest/test-helpers/generate-peer-id-private-keys.d.ts.map +1 -0
- package/dest/test-helpers/generate-peer-id-private-keys.js +13 -0
- package/dest/test-helpers/get-ports.d.ts +7 -0
- package/dest/test-helpers/get-ports.d.ts.map +1 -0
- package/dest/test-helpers/get-ports.js +8 -0
- package/dest/test-helpers/index.d.ts +6 -0
- package/dest/test-helpers/index.d.ts.map +1 -0
- package/dest/test-helpers/index.js +5 -0
- package/dest/test-helpers/make-enrs.d.ts +16 -0
- package/dest/test-helpers/make-enrs.d.ts.map +1 -0
- package/dest/test-helpers/make-enrs.js +32 -0
- package/dest/test-helpers/make-test-p2p-clients.d.ts +36 -0
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -0
- package/dest/test-helpers/make-test-p2p-clients.js +68 -0
- package/dest/test-helpers/reqresp-nodes.d.ts +66 -0
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -0
- package/dest/test-helpers/reqresp-nodes.js +207 -0
- package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -0
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -0
- package/dest/testbench/p2p_client_testbench_worker.js +132 -0
- package/dest/testbench/parse_log_file.d.ts +2 -0
- package/dest/testbench/parse_log_file.d.ts.map +1 -0
- package/dest/testbench/parse_log_file.js +131 -0
- package/dest/testbench/testbench.d.ts +2 -0
- package/dest/testbench/testbench.d.ts.map +1 -0
- package/dest/testbench/testbench.js +61 -0
- package/dest/testbench/worker_client_manager.d.ts +56 -0
- package/dest/testbench/worker_client_manager.d.ts.map +1 -0
- package/dest/testbench/worker_client_manager.js +266 -0
- package/dest/types/index.d.ts +32 -0
- package/dest/types/index.d.ts.map +1 -0
- package/dest/types/index.js +28 -0
- package/dest/util.d.ts +53 -0
- package/dest/util.d.ts.map +1 -0
- package/dest/util.js +140 -0
- package/dest/versioning.d.ts +12 -0
- package/dest/versioning.d.ts.map +1 -0
- package/dest/versioning.js +33 -0
- package/package.json +127 -0
- package/src/bootstrap/bootstrap.ts +146 -0
- package/src/client/factory.ts +89 -0
- package/src/client/index.ts +2 -0
- package/src/client/p2p_client.ts +754 -0
- package/src/config.ts +371 -0
- package/src/enr/generate-enr.ts +39 -0
- package/src/enr/index.ts +1 -0
- package/src/errors/reqresp.error.ts +35 -0
- package/src/index.ts +7 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +62 -0
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +230 -0
- package/src/mem_pools/attestation_pool/index.ts +2 -0
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +159 -0
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +161 -0
- package/src/mem_pools/attestation_pool/mocks.ts +44 -0
- package/src/mem_pools/index.ts +3 -0
- package/src/mem_pools/instrumentation.ts +126 -0
- package/src/mem_pools/interface.ts +12 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +309 -0
- package/src/mem_pools/tx_pool/index.ts +3 -0
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +174 -0
- package/src/mem_pools/tx_pool/priority.ts +13 -0
- package/src/mem_pools/tx_pool/tx_pool.ts +76 -0
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +130 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +26 -0
- package/src/msg_validators/attestation_validator/index.ts +1 -0
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +29 -0
- package/src/msg_validators/block_proposal_validator/index.ts +1 -0
- package/src/msg_validators/index.ts +3 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +32 -0
- package/src/msg_validators/tx_validator/block_header_validator.ts +25 -0
- package/src/msg_validators/tx_validator/data_validator.ts +106 -0
- package/src/msg_validators/tx_validator/double_spend_validator.ts +38 -0
- package/src/msg_validators/tx_validator/index.ts +6 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +48 -0
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +18 -0
- package/src/services/data_store.ts +235 -0
- package/src/services/discv5/discV5_service.ts +256 -0
- package/src/services/dummy_service.ts +134 -0
- package/src/services/encoding.ts +79 -0
- package/src/services/gossipsub/scoring.ts +13 -0
- package/src/services/index.ts +2 -0
- package/src/services/libp2p/libp2p_service.ts +871 -0
- package/src/services/peer-manager/metrics.ts +41 -0
- package/src/services/peer-manager/peer_manager.ts +530 -0
- package/src/services/peer-manager/peer_scoring.ts +105 -0
- package/src/services/reqresp/config.ts +35 -0
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +94 -0
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +217 -0
- package/src/services/reqresp/index.ts +4 -0
- package/src/services/reqresp/interface.ts +185 -0
- package/src/services/reqresp/metrics.ts +57 -0
- package/src/services/reqresp/protocols/block.ts +15 -0
- package/src/services/reqresp/protocols/goodbye.ts +101 -0
- package/src/services/reqresp/protocols/index.ts +8 -0
- package/src/services/reqresp/protocols/ping.ts +8 -0
- package/src/services/reqresp/protocols/status.ts +8 -0
- package/src/services/reqresp/protocols/tx.ts +29 -0
- package/src/services/reqresp/rate-limiter/index.ts +1 -0
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +228 -0
- package/src/services/reqresp/rate-limiter/rate_limits.ts +55 -0
- package/src/services/reqresp/reqresp.ts +661 -0
- package/src/services/reqresp/status.ts +59 -0
- package/src/services/service.ts +112 -0
- package/src/test-helpers/generate-peer-id-private-keys.ts +15 -0
- package/src/test-helpers/get-ports.ts +8 -0
- package/src/test-helpers/index.ts +5 -0
- package/src/test-helpers/make-enrs.ts +44 -0
- package/src/test-helpers/make-test-p2p-clients.ts +122 -0
- package/src/test-helpers/reqresp-nodes.ts +289 -0
- package/src/testbench/README.md +20 -0
- package/src/testbench/p2p_client_testbench_worker.ts +152 -0
- package/src/testbench/parse_log_file.ts +175 -0
- package/src/testbench/testbench.ts +66 -0
- package/src/testbench/worker_client_manager.ts +318 -0
- package/src/types/index.ts +36 -0
- package/src/util.ts +196 -0
- package/src/versioning.ts +50 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { filter, map, sort, take } from '@aztec/foundation/iterable';
|
|
2
|
+
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
3
|
+
|
|
4
|
+
import { type Batch, type Datastore, Key, type KeyQuery, type Pair, type Query } from 'interface-datastore';
|
|
5
|
+
import type { AwaitIterable } from 'interface-store';
|
|
6
|
+
|
|
7
|
+
type MemoryItem = {
|
|
8
|
+
lastAccessedMs: number;
|
|
9
|
+
data: Uint8Array;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type BatchOp = {
|
|
13
|
+
type: 'put' | 'del';
|
|
14
|
+
key: Key;
|
|
15
|
+
value?: Uint8Array;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
class KeyNotFoundError extends Error {
|
|
19
|
+
code: string;
|
|
20
|
+
constructor(message: string) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.code = 'ERR_NOT_FOUND';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class AztecDatastore implements Datastore {
|
|
27
|
+
#memoryDatastore: Map<string, MemoryItem>;
|
|
28
|
+
#dbDatastore: AztecAsyncMap<string, Uint8Array>;
|
|
29
|
+
|
|
30
|
+
#batchOps: BatchOp[] = [];
|
|
31
|
+
|
|
32
|
+
private maxMemoryItems: number;
|
|
33
|
+
|
|
34
|
+
constructor(db: AztecAsyncKVStore, { maxMemoryItems } = { maxMemoryItems: 50 }) {
|
|
35
|
+
this.#memoryDatastore = new Map();
|
|
36
|
+
this.#dbDatastore = db.openMap('p2p_datastore');
|
|
37
|
+
|
|
38
|
+
this.maxMemoryItems = maxMemoryItems;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async has(key: Key): Promise<boolean> {
|
|
42
|
+
return this.#memoryDatastore.has(key.toString()) || (await this.#dbDatastore.hasAsync(key.toString()));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async get(key: Key): Promise<Uint8Array> {
|
|
46
|
+
const keyStr = key.toString();
|
|
47
|
+
const memoryItem = this.#memoryDatastore.get(keyStr);
|
|
48
|
+
if (memoryItem) {
|
|
49
|
+
memoryItem.lastAccessedMs = Date.now();
|
|
50
|
+
return memoryItem.data;
|
|
51
|
+
}
|
|
52
|
+
const dbItem = await this.#dbDatastore.getAsync(keyStr);
|
|
53
|
+
|
|
54
|
+
if (!dbItem) {
|
|
55
|
+
throw new KeyNotFoundError(`Key not found`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return Uint8Array.from(dbItem);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
put(key: Key, val: Uint8Array): Promise<Key> {
|
|
62
|
+
return this._put(key, val);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async *putMany(source: AwaitIterable<Pair>): AwaitIterable<Key> {
|
|
66
|
+
for await (const { key, value } of source) {
|
|
67
|
+
await this.put(key, value);
|
|
68
|
+
yield key;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async *getMany(source: AwaitIterable<Key>): AwaitIterable<Pair> {
|
|
73
|
+
for await (const key of source) {
|
|
74
|
+
yield {
|
|
75
|
+
key,
|
|
76
|
+
value: await this.get(key),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async *deleteMany(source: AwaitIterable<Key>): AwaitIterable<Key> {
|
|
82
|
+
for await (const key of source) {
|
|
83
|
+
await this.delete(key);
|
|
84
|
+
yield key;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async delete(key: Key): Promise<void> {
|
|
89
|
+
this.#memoryDatastore.delete(key.toString());
|
|
90
|
+
await this.#dbDatastore.delete(key.toString());
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
batch(): Batch {
|
|
94
|
+
return {
|
|
95
|
+
put: (key, value) => {
|
|
96
|
+
this.#batchOps.push({
|
|
97
|
+
type: 'put',
|
|
98
|
+
key,
|
|
99
|
+
value,
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
delete: key => {
|
|
103
|
+
this.#batchOps.push({
|
|
104
|
+
type: 'del',
|
|
105
|
+
key,
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
commit: async () => {
|
|
109
|
+
for (const op of this.#batchOps) {
|
|
110
|
+
if (op.type === 'put' && op.value) {
|
|
111
|
+
await this.put(op.key, op.value);
|
|
112
|
+
} else if (op.type === 'del') {
|
|
113
|
+
await this.delete(op.key);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
this.#batchOps = []; // Clear operations after commit
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
query(q: Query): AwaitIterable<Pair> {
|
|
122
|
+
let it = this.all(); //
|
|
123
|
+
const { prefix, filters, orders, offset, limit } = q;
|
|
124
|
+
|
|
125
|
+
if (prefix != null) {
|
|
126
|
+
it = filter(it, e => e.key.toString().startsWith(`${prefix}`));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (Array.isArray(filters)) {
|
|
130
|
+
it = filters.reduce((it, f) => filter(it, f), it);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (Array.isArray(orders)) {
|
|
134
|
+
it = orders.reduce((it, f) => sort(it, f), it);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (offset != null) {
|
|
138
|
+
let i = 0;
|
|
139
|
+
it = filter(it, () => i++ >= offset);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (limit != null) {
|
|
143
|
+
it = take(it, limit);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return it;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
queryKeys(q: KeyQuery): AsyncIterable<Key> {
|
|
150
|
+
let it = map(this.all(), ({ key }) => key);
|
|
151
|
+
const { prefix, filters, orders, offset, limit } = q;
|
|
152
|
+
if (prefix != null) {
|
|
153
|
+
it = filter(it, e => e.toString().startsWith(`${prefix}`));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (Array.isArray(filters)) {
|
|
157
|
+
it = filters.reduce((it, f) => filter(it, f), it);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (Array.isArray(orders)) {
|
|
161
|
+
it = orders.reduce((it, f) => sort(it, f), it);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (offset != null) {
|
|
165
|
+
let i = 0;
|
|
166
|
+
it = filter(it, () => i++ >= offset);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (limit != null) {
|
|
170
|
+
it = take(it, limit);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return it;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private async _put(key: Key, val: Uint8Array): Promise<Key> {
|
|
177
|
+
const keyStr = key.toString();
|
|
178
|
+
while (this.#memoryDatastore.size >= this.maxMemoryItems) {
|
|
179
|
+
this.pruneMemoryDatastore();
|
|
180
|
+
}
|
|
181
|
+
const memoryItem = this.#memoryDatastore.get(keyStr);
|
|
182
|
+
if (memoryItem) {
|
|
183
|
+
// update existing
|
|
184
|
+
memoryItem.lastAccessedMs = Date.now();
|
|
185
|
+
memoryItem.data = val;
|
|
186
|
+
} else {
|
|
187
|
+
// new entry
|
|
188
|
+
this.#memoryDatastore.set(keyStr, { data: val, lastAccessedMs: Date.now() });
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Always add to DB
|
|
192
|
+
await this.#dbDatastore.set(keyStr, val);
|
|
193
|
+
|
|
194
|
+
return key;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private async *all(): AsyncIterable<Pair> {
|
|
198
|
+
for (const [key, value] of this.#memoryDatastore.entries()) {
|
|
199
|
+
yield {
|
|
200
|
+
key: new Key(key),
|
|
201
|
+
value: value.data,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
for await (const [key, value] of this.#dbDatastore.entriesAsync()) {
|
|
206
|
+
if (!this.#memoryDatastore.has(key)) {
|
|
207
|
+
yield {
|
|
208
|
+
key: new Key(key),
|
|
209
|
+
value,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Prune memory store
|
|
217
|
+
*/
|
|
218
|
+
private pruneMemoryDatastore(): void {
|
|
219
|
+
let oldestAccessedMs = Date.now() + 1000;
|
|
220
|
+
let oldestKey: string | undefined = undefined;
|
|
221
|
+
let oldestValue: Uint8Array | undefined = undefined;
|
|
222
|
+
|
|
223
|
+
for (const [key, value] of this.#memoryDatastore) {
|
|
224
|
+
if (value.lastAccessedMs < oldestAccessedMs) {
|
|
225
|
+
oldestAccessedMs = value.lastAccessedMs;
|
|
226
|
+
oldestKey = key;
|
|
227
|
+
oldestValue = value.data;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (oldestKey && oldestValue) {
|
|
232
|
+
this.#memoryDatastore.delete(oldestKey);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
3
|
+
import { type ComponentsVersions, checkCompressedComponentVersion } from '@aztec/stdlib/versioning';
|
|
4
|
+
import { OtelMetricsAdapter, type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
5
|
+
|
|
6
|
+
import { Discv5, type Discv5EventEmitter } from '@chainsafe/discv5';
|
|
7
|
+
import { ENR, SignableENR } from '@chainsafe/enr';
|
|
8
|
+
import type { PeerId } from '@libp2p/interface';
|
|
9
|
+
import { type Multiaddr, multiaddr } from '@multiformats/multiaddr';
|
|
10
|
+
import EventEmitter from 'events';
|
|
11
|
+
|
|
12
|
+
import type { P2PConfig } from '../../config.js';
|
|
13
|
+
import { AZTEC_ENR_KEY, Discv5Event, PeerEvent } from '../../types/index.js';
|
|
14
|
+
import { convertToMultiaddr } from '../../util.js';
|
|
15
|
+
import { setAztecEnrKey } from '../../versioning.js';
|
|
16
|
+
import { type PeerDiscoveryService, PeerDiscoveryState } from '../service.js';
|
|
17
|
+
|
|
18
|
+
const delayBeforeStart = 2000; // 2sec
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Peer discovery service using Discv5.
|
|
22
|
+
*/
|
|
23
|
+
export class DiscV5Service extends EventEmitter implements PeerDiscoveryService {
|
|
24
|
+
/** The Discv5 instance */
|
|
25
|
+
private discv5: Discv5 & Discv5EventEmitter;
|
|
26
|
+
|
|
27
|
+
/** This instance's ENR */
|
|
28
|
+
private enr: SignableENR;
|
|
29
|
+
|
|
30
|
+
/** Version identifiers. */
|
|
31
|
+
private versions: ComponentsVersions;
|
|
32
|
+
|
|
33
|
+
/** UDP listen addr */
|
|
34
|
+
private listenMultiAddrUdp: Multiaddr;
|
|
35
|
+
|
|
36
|
+
private currentState = PeerDiscoveryState.STOPPED;
|
|
37
|
+
|
|
38
|
+
public readonly bootstrapNodes: string[] = [];
|
|
39
|
+
private bootstrapNodePeerIds: PeerId[] = [];
|
|
40
|
+
private bootstrapNodeEnrs: ENR[] = [];
|
|
41
|
+
|
|
42
|
+
private startTime = 0;
|
|
43
|
+
|
|
44
|
+
constructor(
|
|
45
|
+
private peerId: PeerId,
|
|
46
|
+
private config: P2PConfig,
|
|
47
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
48
|
+
private logger = createLogger('p2p:discv5_service'),
|
|
49
|
+
) {
|
|
50
|
+
super();
|
|
51
|
+
const { tcpAnnounceAddress, udpAnnounceAddress, udpListenAddress, bootstrapNodes } = config;
|
|
52
|
+
this.bootstrapNodes = bootstrapNodes ?? [];
|
|
53
|
+
this.bootstrapNodeEnrs = this.bootstrapNodes.map(x => ENR.decodeTxt(x));
|
|
54
|
+
// create ENR from PeerId
|
|
55
|
+
this.enr = SignableENR.createFromPeerId(peerId);
|
|
56
|
+
// Add aztec identification to ENR
|
|
57
|
+
this.versions = setAztecEnrKey(this.enr, config);
|
|
58
|
+
|
|
59
|
+
if (!tcpAnnounceAddress) {
|
|
60
|
+
throw new Error('You need to provide at least a TCP announce address.');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const multiAddrTcp = multiaddr(`${convertToMultiaddr(tcpAnnounceAddress, 'tcp')}/p2p/${peerId.toString()}`);
|
|
64
|
+
// if no udp announce address is provided, use the tcp announce address
|
|
65
|
+
const multiAddrUdp = multiaddr(
|
|
66
|
+
`${convertToMultiaddr(udpAnnounceAddress || tcpAnnounceAddress, 'udp')}/p2p/${peerId.toString()}`,
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
this.listenMultiAddrUdp = multiaddr(convertToMultiaddr(udpListenAddress, 'udp'));
|
|
70
|
+
|
|
71
|
+
// set location multiaddr in ENR record
|
|
72
|
+
this.enr.setLocationMultiaddr(multiAddrUdp);
|
|
73
|
+
this.enr.setLocationMultiaddr(multiAddrTcp);
|
|
74
|
+
|
|
75
|
+
const metricsRegistry = new OtelMetricsAdapter(telemetry);
|
|
76
|
+
this.discv5 = Discv5.create({
|
|
77
|
+
enr: this.enr,
|
|
78
|
+
peerId,
|
|
79
|
+
bindAddrs: { ip4: this.listenMultiAddrUdp },
|
|
80
|
+
config: {
|
|
81
|
+
lookupTimeout: 2000,
|
|
82
|
+
requestTimeout: 2000,
|
|
83
|
+
allowUnverifiedSessions: true,
|
|
84
|
+
},
|
|
85
|
+
metricsRegistry,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Hook onto the onEstablished method to check the peer's version from the ENR,
|
|
89
|
+
// so we don't add it to our dht if it doesn't have the correct version.
|
|
90
|
+
// In addition, we'll hook onto onDiscovered to to repeat the same check there,
|
|
91
|
+
// just in case. Note that not adding the peer to the dht could lead to it
|
|
92
|
+
// being "readded" constantly, we'll need to keep an eye on whether this
|
|
93
|
+
// turns out to be a problem or not.
|
|
94
|
+
const origOnEstablished = this.discv5.onEstablished.bind(this.discv5);
|
|
95
|
+
this.discv5.onEstablished = (...args: unknown[]) => {
|
|
96
|
+
const enr = args[1] as ENR;
|
|
97
|
+
// A special case is for bootnodes. If this is a bootnode and we have been told to skip version checks
|
|
98
|
+
// then proceed straight to handling the event
|
|
99
|
+
if (!this.config.bootstrapNodeEnrVersionCheck && this.isOurBootnode(enr)) {
|
|
100
|
+
return origOnEstablished(...args);
|
|
101
|
+
}
|
|
102
|
+
if (this.validateEnr(enr)) {
|
|
103
|
+
return origOnEstablished(...args);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
this.discv5.on(Discv5Event.DISCOVERED, this.onDiscovered.bind(this));
|
|
108
|
+
this.discv5.on(Discv5Event.ENR_ADDED, this.onEnrAdded.bind(this));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public async start(): Promise<void> {
|
|
112
|
+
if (this.currentState === PeerDiscoveryState.RUNNING) {
|
|
113
|
+
throw new Error('DiscV5Service already started');
|
|
114
|
+
}
|
|
115
|
+
this.logger.debug('Starting DiscV5');
|
|
116
|
+
await this.discv5.start();
|
|
117
|
+
this.startTime = Date.now();
|
|
118
|
+
|
|
119
|
+
this.logger.info(`DiscV5 service started`, {
|
|
120
|
+
nodeId: this.enr.nodeId,
|
|
121
|
+
peerId: this.peerId,
|
|
122
|
+
enrUdp: await this.enr.getFullMultiaddr('udp'),
|
|
123
|
+
enrTcp: await this.enr.getFullMultiaddr('tcp'),
|
|
124
|
+
versions: this.versions,
|
|
125
|
+
});
|
|
126
|
+
this.currentState = PeerDiscoveryState.RUNNING;
|
|
127
|
+
|
|
128
|
+
// Add bootnode ENR if provided
|
|
129
|
+
if (this.bootstrapNodes?.length) {
|
|
130
|
+
// Do this conversion once since it involves an async function call
|
|
131
|
+
this.bootstrapNodePeerIds = await Promise.all(this.bootstrapNodeEnrs.map(enr => enr.peerId()));
|
|
132
|
+
this.logger.info(`Adding ${this.bootstrapNodes} bootstrap nodes ENRs: ${this.bootstrapNodes.join(', ')}`);
|
|
133
|
+
for (const enr of this.bootstrapNodeEnrs) {
|
|
134
|
+
try {
|
|
135
|
+
if (this.config.bootstrapNodeEnrVersionCheck) {
|
|
136
|
+
const value = enr.kvs.get(AZTEC_ENR_KEY);
|
|
137
|
+
if (!value) {
|
|
138
|
+
throw new Error('ENR does not contain aztec key');
|
|
139
|
+
}
|
|
140
|
+
checkCompressedComponentVersion(Buffer.from(value).toString(), this.versions);
|
|
141
|
+
}
|
|
142
|
+
this.discv5.addEnr(enr);
|
|
143
|
+
} catch (e) {
|
|
144
|
+
this.logger.error(`Error adding bootratrap node ${enr.encodeTxt()}`, e);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
public async runRandomNodesQuery(): Promise<void> {
|
|
151
|
+
if (this.currentState !== PeerDiscoveryState.RUNNING) {
|
|
152
|
+
throw new Error('DiscV5Service not running');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// First, wait some time before starting the peer discovery
|
|
156
|
+
// reference: https://github.com/ChainSafe/lodestar/issues/3423
|
|
157
|
+
const msSinceStart = Date.now() - this.startTime;
|
|
158
|
+
if (Date.now() - this.startTime <= delayBeforeStart) {
|
|
159
|
+
await sleep(delayBeforeStart - msSinceStart);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
await this.discv5.findRandomNode();
|
|
164
|
+
} catch (err) {
|
|
165
|
+
this.logger.error(`Error running discV5 random node query: ${err}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public getAllPeers(): ENR[] {
|
|
170
|
+
return this.discv5.kadValues();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public getEnr(): ENR {
|
|
174
|
+
return this.enr.toENR();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public getPeerId(): PeerId {
|
|
178
|
+
return this.peerId;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public getStatus(): PeerDiscoveryState {
|
|
182
|
+
return this.currentState;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public isBootstrapPeer(peerId: PeerId): boolean {
|
|
186
|
+
return this.bootstrapNodePeerIds.some(node => node.equals(peerId));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
public async stop(): Promise<void> {
|
|
190
|
+
await this.discv5.off(Discv5Event.DISCOVERED, this.onDiscovered);
|
|
191
|
+
await this.discv5.off(Discv5Event.ENR_ADDED, this.onEnrAdded);
|
|
192
|
+
|
|
193
|
+
await this.discv5.stop();
|
|
194
|
+
|
|
195
|
+
this.currentState = PeerDiscoveryState.STOPPED;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private async onEnrAdded(enr: ENR) {
|
|
199
|
+
const multiAddrTcp = await enr.getFullMultiaddr('tcp');
|
|
200
|
+
const multiAddrUdp = await enr.getFullMultiaddr('udp');
|
|
201
|
+
this.logger.debug(`Added ENR ${enr.encodeTxt()}`, { multiAddrTcp, multiAddrUdp, nodeId: enr.nodeId });
|
|
202
|
+
this.onDiscovered(enr);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private isOurBootnode(enr: ENR) {
|
|
206
|
+
return this.bootstrapNodeEnrs.some(x => x.nodeId === enr.nodeId);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private onDiscovered(enr: ENR) {
|
|
210
|
+
// Find out if this is one of our bootnodes
|
|
211
|
+
if (this.isOurBootnode(enr)) {
|
|
212
|
+
// it is, what we do here depends
|
|
213
|
+
if (!this.config.bootstrapNodesAsFullPeers) {
|
|
214
|
+
// we don't consider bootnodes as full peers, don't perform any checks and don't emit anything
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (!this.config.bootstrapNodeEnrVersionCheck) {
|
|
218
|
+
// we do consider bootnodes to be full peers and we have been told to NOT version check them, so emit
|
|
219
|
+
this.logger.trace(`Skipping version check for bootnode ${enr.nodeId}`);
|
|
220
|
+
this.emit(PeerEvent.DISCOVERED, enr);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// here, we do consider bootnodes as full peers and we must version check so we continue to regular validation
|
|
224
|
+
}
|
|
225
|
+
if (this.validateEnr(enr)) {
|
|
226
|
+
this.emit(PeerEvent.DISCOVERED, enr);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private validateEnr(enr: ENR): boolean {
|
|
231
|
+
// Check the peer is an aztec peer
|
|
232
|
+
const value = enr.kvs.get(AZTEC_ENR_KEY);
|
|
233
|
+
if (!value) {
|
|
234
|
+
this.logger.warn(`Peer node ${enr.nodeId} does not have aztec key in ENR`);
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// And check it has the correct version
|
|
239
|
+
let compressedVersion;
|
|
240
|
+
try {
|
|
241
|
+
compressedVersion = Buffer.from(value).toString();
|
|
242
|
+
checkCompressedComponentVersion(compressedVersion, this.versions);
|
|
243
|
+
return true;
|
|
244
|
+
} catch (err: any) {
|
|
245
|
+
if (err.name === 'ComponentsVersionsError') {
|
|
246
|
+
this.logger.debug(`Peer node ${enr.nodeId} has incorrect version: ${err.message}`, {
|
|
247
|
+
compressedVersion,
|
|
248
|
+
expected: this.versions,
|
|
249
|
+
});
|
|
250
|
+
} else {
|
|
251
|
+
this.logger.error(`Error checking peer version`, err);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
|
|
2
|
+
import type { BlockAttestation, BlockProposal, Gossipable } from '@aztec/stdlib/p2p';
|
|
3
|
+
import { TxHash } from '@aztec/stdlib/tx';
|
|
4
|
+
|
|
5
|
+
import type { PeerId } from '@libp2p/interface';
|
|
6
|
+
import EventEmitter from 'events';
|
|
7
|
+
|
|
8
|
+
import type { ReqRespSubProtocol, SubProtocolMap } from './reqresp/interface.js';
|
|
9
|
+
import { type P2PService, type PeerDiscoveryService, PeerDiscoveryState } from './service.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A dummy implementation of the P2P Service.
|
|
13
|
+
*/
|
|
14
|
+
export class DummyP2PService implements P2PService {
|
|
15
|
+
/** Returns an empty array for peers. */
|
|
16
|
+
getPeers(): PeerInfo[] {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Starts the dummy implementation.
|
|
22
|
+
* @returns A resolved promise.
|
|
23
|
+
*/
|
|
24
|
+
public start() {
|
|
25
|
+
return Promise.resolve();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Stops the dummy implementation.
|
|
30
|
+
* @returns A resolved promise.
|
|
31
|
+
*/
|
|
32
|
+
public stop() {
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Called to have the given message propagated through the P2P network.
|
|
38
|
+
* @param _ - The message to be propagated.
|
|
39
|
+
*/
|
|
40
|
+
public propagate<T extends Gossipable>(_: T) {}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Called upon receipt of settled transactions.
|
|
44
|
+
* @param _ - The hashes of the settled transactions.
|
|
45
|
+
*/
|
|
46
|
+
public settledTxs(_: TxHash[]) {}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Register a callback into the validator client for when a block proposal is received
|
|
50
|
+
*/
|
|
51
|
+
public registerBlockReceivedCallback(_: (block: BlockProposal) => Promise<BlockAttestation>) {}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Sends a request to a peer.
|
|
55
|
+
* @param _protocol - The protocol to send the request on.
|
|
56
|
+
* @param _request - The request to send.
|
|
57
|
+
* @returns The response from the peer, otherwise undefined.
|
|
58
|
+
*/
|
|
59
|
+
public sendRequest<Protocol extends ReqRespSubProtocol>(
|
|
60
|
+
_protocol: Protocol,
|
|
61
|
+
_request: InstanceType<SubProtocolMap[Protocol]['request']>,
|
|
62
|
+
): Promise<InstanceType<SubProtocolMap[Protocol]['response']> | undefined> {
|
|
63
|
+
return Promise.resolve(undefined);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sends a batch request to a peer.
|
|
68
|
+
* @param _protocol - The protocol to send the request on.
|
|
69
|
+
* @param _requests - The requests to send.
|
|
70
|
+
* @returns The responses from the peer, otherwise undefined.
|
|
71
|
+
*/
|
|
72
|
+
public sendBatchRequest<Protocol extends ReqRespSubProtocol>(
|
|
73
|
+
_protocol: Protocol,
|
|
74
|
+
_requests: InstanceType<SubProtocolMap[Protocol]['request']>[],
|
|
75
|
+
): Promise<InstanceType<SubProtocolMap[Protocol]['response']>[]> {
|
|
76
|
+
return Promise.resolve([]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Returns the ENR of the peer.
|
|
81
|
+
* @returns The ENR of the peer, otherwise undefined.
|
|
82
|
+
*/
|
|
83
|
+
public getEnr(): undefined {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* A dummy implementation of the Peer Discovery Service.
|
|
90
|
+
*/
|
|
91
|
+
export class DummyPeerDiscoveryService extends EventEmitter implements PeerDiscoveryService {
|
|
92
|
+
private currentState = PeerDiscoveryState.STOPPED;
|
|
93
|
+
public bootstrapNodes: string[] = [];
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Starts the dummy implementation.
|
|
97
|
+
* @returns A resolved promise.
|
|
98
|
+
*/
|
|
99
|
+
public start() {
|
|
100
|
+
this.currentState = PeerDiscoveryState.RUNNING;
|
|
101
|
+
return Promise.resolve();
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Stops the dummy implementation.
|
|
105
|
+
* @returns A resolved promise.
|
|
106
|
+
*/
|
|
107
|
+
public stop() {
|
|
108
|
+
this.currentState = PeerDiscoveryState.STOPPED;
|
|
109
|
+
return Promise.resolve();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Called to discover peers in the network.
|
|
113
|
+
* @returns An array of discovered peer addresses.
|
|
114
|
+
*/
|
|
115
|
+
public getAllPeers() {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public runRandomNodesQuery(): Promise<void> {
|
|
120
|
+
return Promise.resolve();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public isBootstrapPeer(_: PeerId): boolean {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public getStatus(): PeerDiscoveryState {
|
|
128
|
+
return this.currentState;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public getEnr(): undefined {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Taken from lodestar: https://github.com/ChainSafe/lodestar
|
|
2
|
+
import { sha256 } from '@aztec/foundation/crypto';
|
|
3
|
+
|
|
4
|
+
import type { RPC } from '@chainsafe/libp2p-gossipsub/message';
|
|
5
|
+
import type { DataTransform } from '@chainsafe/libp2p-gossipsub/types';
|
|
6
|
+
import type { Message } from '@libp2p/interface';
|
|
7
|
+
import { compressSync, uncompressSync } from 'snappy';
|
|
8
|
+
import xxhashFactory from 'xxhash-wasm';
|
|
9
|
+
|
|
10
|
+
// Load WASM
|
|
11
|
+
const xxhash = await xxhashFactory();
|
|
12
|
+
|
|
13
|
+
// Use salt to prevent msgId from being mined for collisions
|
|
14
|
+
const h64Seed = BigInt(Math.floor(Math.random() * 1e9));
|
|
15
|
+
|
|
16
|
+
// Shared buffer to convert msgId to string
|
|
17
|
+
const sharedMsgIdBuf = Buffer.alloc(20);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The function used to generate a gossipsub message id
|
|
21
|
+
* We use the first 8 bytes of SHA256(data) for content addressing
|
|
22
|
+
*/
|
|
23
|
+
export function fastMsgIdFn(rpcMsg: RPC.Message): string {
|
|
24
|
+
if (rpcMsg.data) {
|
|
25
|
+
return xxhash.h64Raw(rpcMsg.data, h64Seed).toString(16);
|
|
26
|
+
}
|
|
27
|
+
return '0000000000000000';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function msgIdToStrFn(msgId: Uint8Array): string {
|
|
31
|
+
// This happens serially, no need to reallocate the buffer
|
|
32
|
+
sharedMsgIdBuf.set(msgId);
|
|
33
|
+
return `0x${sharedMsgIdBuf.toString('hex')}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get the message identifier from a libp2p message
|
|
38
|
+
*
|
|
39
|
+
* Follows similarly to:
|
|
40
|
+
* https://github.com/ethereum/consensus-specs/blob/v1.1.0-alpha.7/specs/altair/p2p-interface.md#topics-and-messages
|
|
41
|
+
*
|
|
42
|
+
* @param message - The libp2p message
|
|
43
|
+
* @returns The message identifier
|
|
44
|
+
*/
|
|
45
|
+
export function getMsgIdFn(message: Message) {
|
|
46
|
+
const { topic } = message;
|
|
47
|
+
|
|
48
|
+
const vec = [Buffer.from(topic), message.data];
|
|
49
|
+
return sha256(Buffer.concat(vec)).subarray(0, 20);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Snappy transform for libp2p gossipsub
|
|
54
|
+
*/
|
|
55
|
+
export class SnappyTransform implements DataTransform {
|
|
56
|
+
// Topic string included to satisfy DataTransform interface
|
|
57
|
+
inboundTransform(_topicStr: string, data: Uint8Array): Uint8Array {
|
|
58
|
+
return this.inboundTransformNoTopic(Buffer.from(data));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public inboundTransformNoTopic(data: Buffer): Buffer {
|
|
62
|
+
if (data.length === 0) {
|
|
63
|
+
return data;
|
|
64
|
+
}
|
|
65
|
+
return Buffer.from(uncompressSync(data, { asBuffer: true }));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Topic string included to satisfy DataTransform interface
|
|
69
|
+
outboundTransform(_topicStr: string, data: Uint8Array): Uint8Array {
|
|
70
|
+
return this.outboundTransformNoTopic(Buffer.from(data));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public outboundTransformNoTopic(data: Buffer): Buffer {
|
|
74
|
+
if (data.length === 0) {
|
|
75
|
+
return data;
|
|
76
|
+
}
|
|
77
|
+
return Buffer.from(compressSync(data));
|
|
78
|
+
}
|
|
79
|
+
}
|