@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,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The error codes for the ReqResp protocol
|
|
3
|
+
*/
|
|
4
|
+
export enum ReqRespStatus {
|
|
5
|
+
SUCCESS = 0,
|
|
6
|
+
RATE_LIMIT_EXCEEDED = 1,
|
|
7
|
+
BADLY_FORMED_REQUEST = 2,
|
|
8
|
+
UNKNOWN = 127,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class ReqRespStatusError extends Error {
|
|
12
|
+
/**
|
|
13
|
+
* The status code
|
|
14
|
+
*/
|
|
15
|
+
status: ReqRespStatus;
|
|
16
|
+
|
|
17
|
+
constructor(status: ReqRespStatus) {
|
|
18
|
+
super(`ReqResp Error: ${prettyPrintReqRespStatus(status)}`);
|
|
19
|
+
this.status = status;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Parse the status chunk
|
|
25
|
+
* @param chunk
|
|
26
|
+
* @returns
|
|
27
|
+
*
|
|
28
|
+
* @throws ReqRespStatusError if the chunk is not valid
|
|
29
|
+
*/
|
|
30
|
+
export function parseStatusChunk(chunk: Uint8Array): ReqRespStatus {
|
|
31
|
+
if (chunk.length !== 1) {
|
|
32
|
+
throw new ReqRespStatusError(ReqRespStatus.UNKNOWN);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const status = chunk[0];
|
|
36
|
+
// Check if status is a valid ReqRespStatus value
|
|
37
|
+
if (!(status in ReqRespStatus)) {
|
|
38
|
+
throw new ReqRespStatusError(ReqRespStatus.UNKNOWN);
|
|
39
|
+
}
|
|
40
|
+
return status as ReqRespStatus;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Pretty print the ReqResp status
|
|
45
|
+
* @param status
|
|
46
|
+
* @returns
|
|
47
|
+
*/
|
|
48
|
+
export function prettyPrintReqRespStatus(status: ReqRespStatus) {
|
|
49
|
+
switch (status) {
|
|
50
|
+
case ReqRespStatus.SUCCESS:
|
|
51
|
+
return 'SUCCESS';
|
|
52
|
+
case ReqRespStatus.RATE_LIMIT_EXCEEDED:
|
|
53
|
+
return 'RATE_LIMIT_EXCEEDED';
|
|
54
|
+
case ReqRespStatus.BADLY_FORMED_REQUEST:
|
|
55
|
+
return 'BADLY_FORMED_REQUEST';
|
|
56
|
+
case ReqRespStatus.UNKNOWN:
|
|
57
|
+
return 'UNKNOWN';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
|
|
2
|
+
import type { BlockAttestation, BlockProposal, Gossipable } from '@aztec/stdlib/p2p';
|
|
3
|
+
|
|
4
|
+
import type { ENR } from '@chainsafe/enr';
|
|
5
|
+
import type { PeerId } from '@libp2p/interface';
|
|
6
|
+
import type EventEmitter from 'events';
|
|
7
|
+
|
|
8
|
+
import type { ReqRespSubProtocol, SubProtocolMap } from './reqresp/interface.js';
|
|
9
|
+
|
|
10
|
+
export enum PeerDiscoveryState {
|
|
11
|
+
RUNNING = 'running',
|
|
12
|
+
STOPPED = 'stopped',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The interface for a P2P service implementation.
|
|
17
|
+
*/
|
|
18
|
+
export interface P2PService {
|
|
19
|
+
/**
|
|
20
|
+
* Starts the service.
|
|
21
|
+
* @returns An empty promise.
|
|
22
|
+
*/
|
|
23
|
+
start(): Promise<void>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Stops the service.
|
|
27
|
+
* @returns An empty promise.
|
|
28
|
+
*/
|
|
29
|
+
stop(): Promise<void>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Called to have the given transaction propagated through the P2P network.
|
|
33
|
+
* @param message - The message to be propagated.
|
|
34
|
+
*/
|
|
35
|
+
propagate<T extends Gossipable>(message: T): void;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Request information from peers via the request response protocol.
|
|
39
|
+
*
|
|
40
|
+
* @param protocol - The request response protocol to use
|
|
41
|
+
* @param request - The request type, corresponding to the protocol
|
|
42
|
+
* @returns The response type, corresponding to the protocol
|
|
43
|
+
*/
|
|
44
|
+
sendRequest<Protocol extends ReqRespSubProtocol>(
|
|
45
|
+
protocol: Protocol,
|
|
46
|
+
request: InstanceType<SubProtocolMap[Protocol]['request']>,
|
|
47
|
+
): Promise<InstanceType<SubProtocolMap[Protocol]['response']> | undefined>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Send a batch of requests to peers, and return the responses
|
|
51
|
+
*
|
|
52
|
+
* @param protocol - The request response protocol to use
|
|
53
|
+
* @param requests - The requests to send to the peers
|
|
54
|
+
* @returns The responses to the requests
|
|
55
|
+
*/
|
|
56
|
+
sendBatchRequest<Protocol extends ReqRespSubProtocol>(
|
|
57
|
+
protocol: Protocol,
|
|
58
|
+
requests: InstanceType<SubProtocolMap[Protocol]['request']>[],
|
|
59
|
+
): Promise<InstanceType<SubProtocolMap[Protocol]['response']>[] | undefined>;
|
|
60
|
+
|
|
61
|
+
// Leaky abstraction: fix https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
62
|
+
registerBlockReceivedCallback(callback: (block: BlockProposal) => Promise<BlockAttestation | undefined>): void;
|
|
63
|
+
|
|
64
|
+
getEnr(): ENR | undefined;
|
|
65
|
+
|
|
66
|
+
getPeers(includePending?: boolean): PeerInfo[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The interface for a peer discovery service implementation.
|
|
71
|
+
*/
|
|
72
|
+
export interface PeerDiscoveryService extends EventEmitter {
|
|
73
|
+
/**
|
|
74
|
+
* Starts the service.
|
|
75
|
+
* */
|
|
76
|
+
start(): Promise<void>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Stops the service.
|
|
80
|
+
* */
|
|
81
|
+
stop(): Promise<void>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Gets all peers.
|
|
85
|
+
* @returns An array of peer ENRs.
|
|
86
|
+
*/
|
|
87
|
+
getAllPeers(): ENR[];
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Runs findRandomNode query.
|
|
91
|
+
*/
|
|
92
|
+
runRandomNodesQuery(): Promise<void>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Checks if the given peer is a bootstrap peer.
|
|
96
|
+
* @param peerId - The peer ID to check.
|
|
97
|
+
* @returns True if the peer is a bootstrap peer.
|
|
98
|
+
*/
|
|
99
|
+
isBootstrapPeer(peerId: PeerId): boolean;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Event emitted when a new peer is discovered.
|
|
103
|
+
*/
|
|
104
|
+
on(event: 'peer:discovered', listener: (enr: ENR) => void): this;
|
|
105
|
+
emit(event: 'peer:discovered', enr: ENR): boolean;
|
|
106
|
+
|
|
107
|
+
getStatus(): PeerDiscoveryState;
|
|
108
|
+
|
|
109
|
+
getEnr(): ENR | undefined;
|
|
110
|
+
|
|
111
|
+
bootstrapNodes: string[];
|
|
112
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { generatePrivateKey } from 'viem/accounts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate a list of peer id private keys
|
|
5
|
+
* @param numberOfPeers - The number of peer id private keys to generate
|
|
6
|
+
* @returns A list of peer id private keys
|
|
7
|
+
*/
|
|
8
|
+
export function generatePeerIdPrivateKeys(numberOfPeers: number): string[] {
|
|
9
|
+
const peerIdPrivateKeys: string[] = [];
|
|
10
|
+
for (let i = 0; i < numberOfPeers; i++) {
|
|
11
|
+
// magic number is multiaddr prefix: https://multiformats.io/multiaddr/
|
|
12
|
+
peerIdPrivateKeys.push('08021220' + generatePrivateKey().slice(2, 68));
|
|
13
|
+
}
|
|
14
|
+
return peerIdPrivateKeys;
|
|
15
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import getPort from 'get-port';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get a list of ports for a given number of peers
|
|
5
|
+
* @param numberOfPeers - The number of peers to get ports for
|
|
6
|
+
* @returns A list of ports
|
|
7
|
+
*/
|
|
8
|
+
export const getPorts = (numberOfPeers: number) => Promise.all(Array.from({ length: numberOfPeers }, () => getPort()));
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ChainConfig } from '@aztec/stdlib/config';
|
|
2
|
+
|
|
3
|
+
import { SignableENR } from '@chainsafe/enr';
|
|
4
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
|
5
|
+
|
|
6
|
+
import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js';
|
|
7
|
+
import { setAztecEnrKey } from '../versioning.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Make a list of ENRs for a given list of p2p private keys and ports
|
|
11
|
+
* @param p2pPrivateKeys - The private keys of the p2p nodes
|
|
12
|
+
* @param ports - The ports of the p2p nodes
|
|
13
|
+
* @returns A list of ENRs
|
|
14
|
+
*/
|
|
15
|
+
export async function makeEnrs(p2pPrivateKeys: string[], ports: number[], config: ChainConfig) {
|
|
16
|
+
return await Promise.all(
|
|
17
|
+
p2pPrivateKeys.map((pk, i) => {
|
|
18
|
+
return makeEnr(pk, ports[i], config);
|
|
19
|
+
}),
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Make an ENR for a given p2p private key and port
|
|
25
|
+
* @param p2pPrivateKey - The private key of the p2p node
|
|
26
|
+
* @param port - The port of the p2p node
|
|
27
|
+
* @returns The ENR of the p2p node
|
|
28
|
+
*/
|
|
29
|
+
export async function makeEnr(p2pPrivateKey: string, port: number, config: ChainConfig) {
|
|
30
|
+
const peerId = await createLibP2PPeerIdFromPrivateKey(p2pPrivateKey);
|
|
31
|
+
const enr = SignableENR.createFromPeerId(peerId);
|
|
32
|
+
|
|
33
|
+
const udpAnnounceAddress = `127.0.0.1:${port}`;
|
|
34
|
+
const tcpAnnounceAddress = `127.0.0.1:${port}`;
|
|
35
|
+
const udpPublicAddr = multiaddr(convertToMultiaddr(udpAnnounceAddress, 'udp'));
|
|
36
|
+
const tcpPublicAddr = multiaddr(convertToMultiaddr(tcpAnnounceAddress, 'tcp'));
|
|
37
|
+
|
|
38
|
+
// ENRS must include the network and a discoverable address (udp for discv5)
|
|
39
|
+
setAztecEnrKey(enr, config);
|
|
40
|
+
enr.setLocationMultiaddr(udpPublicAddr);
|
|
41
|
+
enr.setLocationMultiaddr(tcpPublicAddr);
|
|
42
|
+
|
|
43
|
+
return enr.encodeTxt();
|
|
44
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { MockL2BlockSource } from '@aztec/archiver/test';
|
|
2
|
+
import type { EpochCache } from '@aztec/epoch-cache';
|
|
3
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
4
|
+
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
5
|
+
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
6
|
+
import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
7
|
+
import { P2PClientType } from '@aztec/stdlib/p2p';
|
|
8
|
+
|
|
9
|
+
import { createP2PClient } from '../client/index.js';
|
|
10
|
+
import type { P2PClient } from '../client/p2p_client.js';
|
|
11
|
+
import type { P2PConfig } from '../config.js';
|
|
12
|
+
import type { AttestationPool } from '../mem_pools/attestation_pool/attestation_pool.js';
|
|
13
|
+
import type { TxPool } from '../mem_pools/tx_pool/index.js';
|
|
14
|
+
import { generatePeerIdPrivateKeys } from '../test-helpers/generate-peer-id-private-keys.js';
|
|
15
|
+
import { getPorts } from './get-ports.js';
|
|
16
|
+
import { makeEnrs } from './make-enrs.js';
|
|
17
|
+
import { AlwaysFalseCircuitVerifier, AlwaysTrueCircuitVerifier } from './reqresp-nodes.js';
|
|
18
|
+
|
|
19
|
+
interface MakeTestP2PClientOptions {
|
|
20
|
+
mockAttestationPool: AttestationPool;
|
|
21
|
+
mockTxPool: TxPool;
|
|
22
|
+
mockEpochCache: EpochCache;
|
|
23
|
+
mockWorldState: WorldStateSynchronizer;
|
|
24
|
+
alwaysTrueVerifier?: boolean;
|
|
25
|
+
p2pBaseConfig: P2PConfig;
|
|
26
|
+
p2pConfigOverrides?: Partial<P2PConfig>;
|
|
27
|
+
logger?: Logger;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates a single P2P client for testing purposes.
|
|
32
|
+
* @param peerIdPrivateKey - The private key of the peer.
|
|
33
|
+
* @param port - The port to run the client on.
|
|
34
|
+
* @param peers - The peers to connect to.
|
|
35
|
+
* @param options - The options for the client.
|
|
36
|
+
* @returns The created client.
|
|
37
|
+
*/
|
|
38
|
+
export async function makeTestP2PClient(
|
|
39
|
+
peerIdPrivateKey: string,
|
|
40
|
+
port: number,
|
|
41
|
+
peers: string[],
|
|
42
|
+
{
|
|
43
|
+
alwaysTrueVerifier = true,
|
|
44
|
+
p2pBaseConfig,
|
|
45
|
+
p2pConfigOverrides = {},
|
|
46
|
+
mockAttestationPool,
|
|
47
|
+
mockTxPool,
|
|
48
|
+
mockEpochCache,
|
|
49
|
+
mockWorldState,
|
|
50
|
+
logger = createLogger('p2p-test-client'),
|
|
51
|
+
}: MakeTestP2PClientOptions,
|
|
52
|
+
) {
|
|
53
|
+
const addr = `127.0.0.1:${port}`;
|
|
54
|
+
const listenAddr = `0.0.0.0:${port}`;
|
|
55
|
+
|
|
56
|
+
// Filter nodes so that we only dial active peers
|
|
57
|
+
|
|
58
|
+
const config: P2PConfig & DataStoreConfig = {
|
|
59
|
+
...p2pBaseConfig,
|
|
60
|
+
p2pEnabled: true,
|
|
61
|
+
peerIdPrivateKey,
|
|
62
|
+
tcpListenAddress: listenAddr, // run on port 0
|
|
63
|
+
udpListenAddress: listenAddr,
|
|
64
|
+
tcpAnnounceAddress: addr,
|
|
65
|
+
udpAnnounceAddress: addr,
|
|
66
|
+
bootstrapNodes: peers,
|
|
67
|
+
peerCheckIntervalMS: 1000,
|
|
68
|
+
maxPeerCount: 10,
|
|
69
|
+
bootstrapNodesAsFullPeers: true,
|
|
70
|
+
...p2pConfigOverrides,
|
|
71
|
+
} as P2PConfig & DataStoreConfig;
|
|
72
|
+
|
|
73
|
+
const l2BlockSource = new MockL2BlockSource();
|
|
74
|
+
await l2BlockSource.createBlocks(100);
|
|
75
|
+
|
|
76
|
+
const proofVerifier = alwaysTrueVerifier ? new AlwaysTrueCircuitVerifier() : new AlwaysFalseCircuitVerifier();
|
|
77
|
+
const kvStore = await openTmpStore('test');
|
|
78
|
+
const deps = {
|
|
79
|
+
txPool: mockTxPool as unknown as TxPool,
|
|
80
|
+
attestationPool: mockAttestationPool as unknown as AttestationPool,
|
|
81
|
+
store: kvStore,
|
|
82
|
+
logger,
|
|
83
|
+
};
|
|
84
|
+
const client = await createP2PClient(
|
|
85
|
+
P2PClientType.Full,
|
|
86
|
+
config,
|
|
87
|
+
l2BlockSource,
|
|
88
|
+
proofVerifier,
|
|
89
|
+
mockWorldState,
|
|
90
|
+
mockEpochCache,
|
|
91
|
+
undefined,
|
|
92
|
+
deps,
|
|
93
|
+
);
|
|
94
|
+
await client.start();
|
|
95
|
+
|
|
96
|
+
return client;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Creates a number of P2P clients for testing purposes.
|
|
101
|
+
* @param numberOfPeers - The number of clients to create.
|
|
102
|
+
* @param options - The options for the clients.
|
|
103
|
+
* @returns The created clients.
|
|
104
|
+
*/
|
|
105
|
+
export async function makeTestP2PClients(numberOfPeers: number, testConfig: MakeTestP2PClientOptions) {
|
|
106
|
+
const clients: P2PClient[] = [];
|
|
107
|
+
const peerIdPrivateKeys = generatePeerIdPrivateKeys(numberOfPeers);
|
|
108
|
+
|
|
109
|
+
const ports = await getPorts(numberOfPeers);
|
|
110
|
+
const peerEnrs = await makeEnrs(peerIdPrivateKeys, ports, testConfig.p2pBaseConfig);
|
|
111
|
+
|
|
112
|
+
for (let i = 0; i < numberOfPeers; i++) {
|
|
113
|
+
const client = await makeTestP2PClient(peerIdPrivateKeys[i], ports[i], peerEnrs, {
|
|
114
|
+
...testConfig,
|
|
115
|
+
logger: createLogger(`p2p:${i}`),
|
|
116
|
+
});
|
|
117
|
+
clients.push(client);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
await Promise.all(clients.map(client => client.isReady()));
|
|
121
|
+
return clients;
|
|
122
|
+
}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
+
import { timesParallel } from '@aztec/foundation/collection';
|
|
3
|
+
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
4
|
+
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
5
|
+
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
6
|
+
import { type ChainConfig, emptyChainConfig } from '@aztec/stdlib/config';
|
|
7
|
+
import type { ClientProtocolCircuitVerifier, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
8
|
+
import type { P2PClientType } from '@aztec/stdlib/p2p';
|
|
9
|
+
import type { Tx } from '@aztec/stdlib/tx';
|
|
10
|
+
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
11
|
+
|
|
12
|
+
import { SignableENR } from '@chainsafe/enr';
|
|
13
|
+
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
14
|
+
import { noise } from '@chainsafe/libp2p-noise';
|
|
15
|
+
import { yamux } from '@chainsafe/libp2p-yamux';
|
|
16
|
+
import { bootstrap } from '@libp2p/bootstrap';
|
|
17
|
+
import { identify } from '@libp2p/identify';
|
|
18
|
+
import type { PeerId } from '@libp2p/interface';
|
|
19
|
+
import { createSecp256k1PeerId } from '@libp2p/peer-id-factory';
|
|
20
|
+
import { tcp } from '@libp2p/tcp';
|
|
21
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
|
22
|
+
import getPort from 'get-port';
|
|
23
|
+
import { type Libp2p, type Libp2pOptions, createLibp2p } from 'libp2p';
|
|
24
|
+
|
|
25
|
+
import { BootstrapNode } from '../bootstrap/bootstrap.js';
|
|
26
|
+
import type { BootnodeConfig, P2PConfig } from '../config.js';
|
|
27
|
+
import type { MemPools } from '../mem_pools/interface.js';
|
|
28
|
+
import { DiscV5Service } from '../services/discv5/discV5_service.js';
|
|
29
|
+
import { LibP2PService } from '../services/libp2p/libp2p_service.js';
|
|
30
|
+
import type { PeerScoring } from '../services/peer-manager/peer_scoring.js';
|
|
31
|
+
import type { P2PReqRespConfig } from '../services/reqresp/config.js';
|
|
32
|
+
import {
|
|
33
|
+
ReqRespSubProtocol,
|
|
34
|
+
type ReqRespSubProtocolHandlers,
|
|
35
|
+
type ReqRespSubProtocolValidators,
|
|
36
|
+
noopValidator,
|
|
37
|
+
} from '../services/reqresp/interface.js';
|
|
38
|
+
import { pingHandler, statusHandler } from '../services/reqresp/protocols/index.js';
|
|
39
|
+
import { ReqResp } from '../services/reqresp/reqresp.js';
|
|
40
|
+
import { type PubSubLibp2p, convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates a libp2p node, pre configured.
|
|
44
|
+
* @param boostrapAddrs - an optional list of bootstrap addresses
|
|
45
|
+
* @returns Lip2p node
|
|
46
|
+
*/
|
|
47
|
+
export async function createLibp2pNode(
|
|
48
|
+
boostrapAddrs: string[] = [],
|
|
49
|
+
peerId?: PeerId,
|
|
50
|
+
port?: number,
|
|
51
|
+
enableGossipSub: boolean = false,
|
|
52
|
+
start: boolean = true,
|
|
53
|
+
): Promise<Libp2p> {
|
|
54
|
+
port = port ?? (await getPort());
|
|
55
|
+
const options: Libp2pOptions = {
|
|
56
|
+
start,
|
|
57
|
+
addresses: {
|
|
58
|
+
listen: [`/ip4/0.0.0.0/tcp/${port}`],
|
|
59
|
+
announce: [`/ip4/0.0.0.0/tcp/${port}`],
|
|
60
|
+
},
|
|
61
|
+
connectionEncryption: [noise()],
|
|
62
|
+
streamMuxers: [yamux()],
|
|
63
|
+
transports: [tcp()],
|
|
64
|
+
services: {
|
|
65
|
+
identify: identify({
|
|
66
|
+
protocolPrefix: 'aztec',
|
|
67
|
+
}),
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
if (boostrapAddrs.length > 0) {
|
|
72
|
+
options.peerDiscovery = [
|
|
73
|
+
bootstrap({
|
|
74
|
+
list: boostrapAddrs,
|
|
75
|
+
}),
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (peerId) {
|
|
80
|
+
options.peerId = peerId;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (enableGossipSub) {
|
|
84
|
+
options.services!.pubsub = gossipsub({
|
|
85
|
+
allowPublishToZeroTopicPeers: true,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return await createLibp2p(options);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Test Libp2p service
|
|
94
|
+
* P2P functionality is operational, however everything else is default
|
|
95
|
+
*
|
|
96
|
+
*
|
|
97
|
+
*/
|
|
98
|
+
export async function createTestLibP2PService<T extends P2PClientType>(
|
|
99
|
+
clientType: T,
|
|
100
|
+
boostrapAddrs: string[] = [],
|
|
101
|
+
l2BlockSource: L2BlockSource,
|
|
102
|
+
worldStateSynchronizer: WorldStateSynchronizer,
|
|
103
|
+
epochCache: EpochCache,
|
|
104
|
+
mempools: MemPools<T>,
|
|
105
|
+
telemetry: TelemetryClient,
|
|
106
|
+
port: number = 0,
|
|
107
|
+
peerId?: PeerId,
|
|
108
|
+
chainConfig: ChainConfig = emptyChainConfig,
|
|
109
|
+
) {
|
|
110
|
+
peerId = peerId ?? (await createSecp256k1PeerId());
|
|
111
|
+
const config = {
|
|
112
|
+
tcpAnnounceAddress: `127.0.0.1:${port}`,
|
|
113
|
+
udpAnnounceAddress: `127.0.0.1:${port}`,
|
|
114
|
+
tcpListenAddress: `0.0.0.0:${port}`,
|
|
115
|
+
udpListenAddress: `0.0.0.0:${port}`,
|
|
116
|
+
bootstrapNodes: boostrapAddrs,
|
|
117
|
+
peerCheckIntervalMS: 1000,
|
|
118
|
+
maxPeerCount: 5,
|
|
119
|
+
p2pEnabled: true,
|
|
120
|
+
peerIdPrivateKey: Buffer.from(peerId.privateKey!).toString('hex'),
|
|
121
|
+
bootstrapNodeEnrVersionCheck: false,
|
|
122
|
+
...chainConfig,
|
|
123
|
+
} as P2PConfig & DataStoreConfig;
|
|
124
|
+
const discoveryService = new DiscV5Service(peerId, config, telemetry);
|
|
125
|
+
const proofVerifier = new AlwaysTrueCircuitVerifier();
|
|
126
|
+
|
|
127
|
+
// No bootstrap nodes provided as the libp2p service will register them in the constructor
|
|
128
|
+
const p2pNode = await createLibp2pNode([], peerId, port, /*enable gossip */ true, /**start */ false);
|
|
129
|
+
|
|
130
|
+
return new LibP2PService<T>(
|
|
131
|
+
clientType,
|
|
132
|
+
config,
|
|
133
|
+
p2pNode as PubSubLibp2p,
|
|
134
|
+
discoveryService,
|
|
135
|
+
mempools,
|
|
136
|
+
l2BlockSource,
|
|
137
|
+
epochCache,
|
|
138
|
+
proofVerifier,
|
|
139
|
+
worldStateSynchronizer,
|
|
140
|
+
telemetry,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* A p2p / req resp node pairing the req node will always contain the p2p node.
|
|
146
|
+
* they are provided as a pair to allow access the p2p node directly
|
|
147
|
+
*/
|
|
148
|
+
export type ReqRespNode = {
|
|
149
|
+
p2p: Libp2p;
|
|
150
|
+
req: ReqResp;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// Mock sub protocol handlers
|
|
154
|
+
export const MOCK_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers = {
|
|
155
|
+
[ReqRespSubProtocol.PING]: pingHandler,
|
|
156
|
+
[ReqRespSubProtocol.STATUS]: statusHandler,
|
|
157
|
+
[ReqRespSubProtocol.TX]: (_msg: any) => Promise.resolve(Buffer.from('tx')),
|
|
158
|
+
[ReqRespSubProtocol.GOODBYE]: (_msg: any) => Promise.resolve(Buffer.from('goodbye')),
|
|
159
|
+
[ReqRespSubProtocol.BLOCK]: (_msg: any) => Promise.resolve(Buffer.from('block')),
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// By default, all requests are valid
|
|
163
|
+
// If you want to test an invalid response, you can override the validator
|
|
164
|
+
export const MOCK_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = {
|
|
165
|
+
[ReqRespSubProtocol.PING]: noopValidator,
|
|
166
|
+
[ReqRespSubProtocol.STATUS]: noopValidator,
|
|
167
|
+
[ReqRespSubProtocol.TX]: noopValidator,
|
|
168
|
+
[ReqRespSubProtocol.GOODBYE]: noopValidator,
|
|
169
|
+
[ReqRespSubProtocol.BLOCK]: noopValidator,
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @param numberOfNodes - the number of nodes to create
|
|
174
|
+
* @returns An array of the created nodes
|
|
175
|
+
*/
|
|
176
|
+
export const createNodes = (peerScoring: PeerScoring, numberOfNodes: number): Promise<ReqRespNode[]> => {
|
|
177
|
+
return timesParallel(numberOfNodes, () => createReqResp(peerScoring));
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export const startNodes = async (
|
|
181
|
+
nodes: ReqRespNode[],
|
|
182
|
+
subProtocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS,
|
|
183
|
+
subProtocolValidators = MOCK_SUB_PROTOCOL_VALIDATORS,
|
|
184
|
+
) => {
|
|
185
|
+
for (const node of nodes) {
|
|
186
|
+
await node.req.start(subProtocolHandlers, subProtocolValidators);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export const stopNodes = async (nodes: ReqRespNode[]): Promise<void> => {
|
|
191
|
+
const stopPromises = nodes.flatMap(node => [node.req.stop(), node.p2p.stop()]);
|
|
192
|
+
await Promise.all(stopPromises);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
// Create a req resp node, exposing the underlying p2p node
|
|
196
|
+
export const createReqResp = async (peerScoring: PeerScoring): Promise<ReqRespNode> => {
|
|
197
|
+
const p2p = await createLibp2pNode();
|
|
198
|
+
const config: P2PReqRespConfig = {
|
|
199
|
+
overallRequestTimeoutMs: 4000,
|
|
200
|
+
individualRequestTimeoutMs: 2000,
|
|
201
|
+
};
|
|
202
|
+
const req = new ReqResp(config, p2p, peerScoring);
|
|
203
|
+
return {
|
|
204
|
+
p2p,
|
|
205
|
+
req,
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Given a node list; hand shake all of the nodes with each other
|
|
210
|
+
export const connectToPeers = async (nodes: ReqRespNode[]): Promise<void> => {
|
|
211
|
+
for (const node of nodes) {
|
|
212
|
+
for (const otherNode of nodes) {
|
|
213
|
+
if (node === otherNode) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
const addr = otherNode.p2p.getMultiaddrs()[0];
|
|
217
|
+
await node.p2p.dial(addr);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// Mock circuit verifier for testing - reimplementation from bb to avoid dependency
|
|
223
|
+
export class AlwaysTrueCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
224
|
+
verifyProof(_tx: Tx): Promise<boolean> {
|
|
225
|
+
return Promise.resolve(true);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
export class AlwaysFalseCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
229
|
+
verifyProof(_tx: Tx): Promise<boolean> {
|
|
230
|
+
return Promise.resolve(false);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Bootnodes
|
|
235
|
+
export function createBootstrapNodeConfig(privateKey: string, port: number, chainConfig: ChainConfig): BootnodeConfig {
|
|
236
|
+
return {
|
|
237
|
+
l1ChainId: chainConfig.l1ChainId,
|
|
238
|
+
udpListenAddress: `0.0.0.0:${port}`,
|
|
239
|
+
udpAnnounceAddress: `127.0.0.1:${port}`,
|
|
240
|
+
peerIdPrivateKey: privateKey,
|
|
241
|
+
dataDirectory: undefined,
|
|
242
|
+
dataStoreMapSizeKB: 0,
|
|
243
|
+
bootstrapNodes: [],
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function createBootstrapNodeFromPrivateKey(
|
|
248
|
+
privateKey: string,
|
|
249
|
+
port: number,
|
|
250
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
251
|
+
chainConfig: ChainConfig = emptyChainConfig,
|
|
252
|
+
): Promise<BootstrapNode> {
|
|
253
|
+
const config = createBootstrapNodeConfig(privateKey, port, chainConfig);
|
|
254
|
+
return startBootstrapNode(config, telemetry);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Create a bootstrap node ENR
|
|
259
|
+
* @param privateKey - the private key of the bootstrap node
|
|
260
|
+
* @param port - the port of the bootstrap node
|
|
261
|
+
* @returns the bootstrap node ENR
|
|
262
|
+
*/
|
|
263
|
+
export async function getBootstrapNodeEnr(privateKey: string, port: number) {
|
|
264
|
+
const peerId = await createLibP2PPeerIdFromPrivateKey(privateKey);
|
|
265
|
+
const enr = SignableENR.createFromPeerId(peerId);
|
|
266
|
+
const listenAddrUdp = multiaddr(convertToMultiaddr(`127.0.0.1:${port}`, 'udp'));
|
|
267
|
+
enr.setLocationMultiaddr(listenAddrUdp);
|
|
268
|
+
|
|
269
|
+
return enr;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export async function createBootstrapNode(
|
|
273
|
+
port: number,
|
|
274
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
275
|
+
chainConfig: ChainConfig = emptyChainConfig,
|
|
276
|
+
): Promise<BootstrapNode> {
|
|
277
|
+
const peerId = await createSecp256k1PeerId();
|
|
278
|
+
const config = createBootstrapNodeConfig(Buffer.from(peerId.privateKey!).toString('hex'), port, chainConfig);
|
|
279
|
+
|
|
280
|
+
return startBootstrapNode(config, telemetry);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async function startBootstrapNode(config: BootnodeConfig, telemetry: TelemetryClient) {
|
|
284
|
+
// Open an ephemeral store that will only exist in memory
|
|
285
|
+
const store = await openTmpStore('bootstrap-node', true);
|
|
286
|
+
const bootstrapNode = new BootstrapNode(store, telemetry);
|
|
287
|
+
await bootstrapNode.start(config);
|
|
288
|
+
return bootstrapNode;
|
|
289
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## P2P Test bench
|
|
2
|
+
|
|
3
|
+
A testbench that runs only the P2P client on a number of worker threads, with the purpose of monitoring and testing the performance of the P2P client.
|
|
4
|
+
|
|
5
|
+
### Running the testbench
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
./run_testbench.sh <outputfile>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This will produce a LONG series of logs that can be used for further analysis.
|
|
12
|
+
|
|
13
|
+
## TODO
|
|
14
|
+
|
|
15
|
+
- Strongly parameterizing the testbench scripts
|
|
16
|
+
- Add traffic shaping options to the testbench
|
|
17
|
+
- Add log parsing step that can categorize a report in json of the propoagation of the message
|
|
18
|
+
- Add multiple different tx sizes
|
|
19
|
+
- Create ci pipeline that can run analysis on the logs and compare against previous runs
|
|
20
|
+
- Create a series of markdown reports detailing what each parameter change does and include graphs to compare performance
|