@aztec/p2p 0.0.1-commit.e61ad554 → 0.0.1-commit.f146247c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bootstrap/bootstrap.d.ts +4 -3
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +4 -4
- package/dest/client/factory.d.ts +1 -1
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +6 -5
- package/dest/client/p2p_client.d.ts +1 -1
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +9 -2
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +2 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +1 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +305 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +73 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +1 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +8 -0
- package/dest/config.d.ts +8 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +2 -0
- package/dest/mem_pools/instrumentation.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +2 -2
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +7 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.js +5 -5
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +3 -3
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +5 -4
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +4 -3
- package/dest/msg_validators/tx_validator/data_validator.d.ts +3 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +4 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +3 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +8 -3
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +21 -11
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +3 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +2 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
- package/dest/msg_validators/tx_validator/size_validator.d.ts +3 -1
- package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/size_validator.js +4 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +2 -2
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.js +2 -2
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -2
- 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 +10 -6
- package/dest/services/discv5/discV5_service.js +1 -1
- package/dest/services/dummy_service.d.ts +13 -1
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +39 -0
- package/dest/services/libp2p/instrumentation.d.ts +1 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +14 -3
- package/dest/services/libp2p/libp2p_service.d.ts +9 -3
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +37 -28
- package/dest/services/peer-manager/metrics.d.ts +2 -2
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +20 -5
- package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +8 -2
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +47 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +566 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts +17 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/config.js +27 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +50 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/interface.js +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +37 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +151 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +54 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +139 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +20 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +21 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +22 -3
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +63 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +12 -0
- package/dest/services/reqresp/interface.d.ts +3 -1
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.d.ts +6 -5
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +17 -5
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +5 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +5 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +16 -3
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +18 -6
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +43 -13
- package/dest/services/reqresp/reqresp.d.ts +6 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +58 -22
- package/dest/services/service.d.ts +4 -1
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +4 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +9 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +6 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +16 -5
- package/dest/services/tx_collection/index.d.ts +2 -1
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +1 -0
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +9 -2
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +48 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -0
- package/dest/services/tx_collection/proposal_tx_collector.js +50 -0
- package/dest/services/tx_collection/tx_collection.d.ts +4 -4
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +5 -5
- package/dest/services/tx_provider_instrumentation.d.ts +1 -1
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +5 -5
- package/dest/test-helpers/index.d.ts +3 -1
- package/dest/test-helpers/index.d.ts.map +1 -1
- package/dest/test-helpers/index.js +2 -0
- package/dest/test-helpers/test_tx_provider.d.ts +40 -0
- package/dest/test-helpers/test_tx_provider.d.ts.map +1 -0
- package/dest/test-helpers/test_tx_provider.js +41 -0
- package/dest/test-helpers/testbench-utils.d.ts +158 -0
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
- package/dest/test-helpers/testbench-utils.js +297 -0
- package/dest/testbench/p2p_client_testbench_worker.d.ts +28 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +212 -131
- package/dest/testbench/worker_client_manager.d.ts +51 -6
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +226 -44
- package/package.json +14 -14
- package/src/bootstrap/bootstrap.ts +7 -4
- package/src/client/factory.ts +6 -10
- package/src/client/p2p_client.ts +9 -2
- package/src/client/test/tx_proposal_collector/README.md +227 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +336 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
- package/src/config.ts +6 -1
- package/src/mem_pools/instrumentation.ts +2 -1
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +8 -2
- package/src/msg_validators/proposal_validator/proposal_validator.ts +5 -5
- package/src/msg_validators/tx_validator/archive_cache.ts +3 -3
- package/src/msg_validators/tx_validator/block_header_validator.ts +7 -8
- package/src/msg_validators/tx_validator/data_validator.ts +6 -2
- package/src/msg_validators/tx_validator/double_spend_validator.ts +4 -3
- package/src/msg_validators/tx_validator/factory.ts +64 -23
- package/src/msg_validators/tx_validator/gas_validator.ts +9 -3
- package/src/msg_validators/tx_validator/metadata_validator.ts +6 -3
- package/src/msg_validators/tx_validator/phases_validator.ts +5 -3
- package/src/msg_validators/tx_validator/size_validator.ts +6 -2
- package/src/msg_validators/tx_validator/timestamp_validator.ts +6 -3
- package/src/msg_validators/tx_validator/tx_permitted_validator.ts +8 -3
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +8 -3
- package/src/services/data_store.ts +10 -7
- package/src/services/discv5/discV5_service.ts +1 -1
- package/src/services/dummy_service.ts +45 -0
- package/src/services/libp2p/instrumentation.ts +15 -2
- package/src/services/libp2p/libp2p_service.ts +60 -46
- package/src/services/peer-manager/metrics.ts +21 -4
- package/src/services/peer-manager/peer_scoring.ts +4 -1
- package/src/services/reqresp/batch-tx-requester/README.md +305 -0
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +706 -0
- package/src/services/reqresp/batch-tx-requester/config.ts +40 -0
- package/src/services/reqresp/batch-tx-requester/interface.ts +57 -0
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +209 -0
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +205 -0
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +37 -0
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +65 -4
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +16 -0
- package/src/services/reqresp/interface.ts +3 -0
- package/src/services/reqresp/metrics.ts +34 -9
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +7 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +18 -4
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +51 -9
- package/src/services/reqresp/reqresp.ts +66 -19
- package/src/services/service.ts +4 -0
- package/src/services/tx_collection/config.ts +15 -1
- package/src/services/tx_collection/fast_tx_collection.ts +36 -13
- package/src/services/tx_collection/index.ts +5 -0
- package/src/services/tx_collection/instrumentation.ts +11 -2
- package/src/services/tx_collection/proposal_tx_collector.ts +114 -0
- package/src/services/tx_collection/tx_collection.ts +4 -4
- package/src/services/tx_provider_instrumentation.ts +11 -5
- package/src/test-helpers/index.ts +2 -0
- package/src/test-helpers/test_tx_provider.ts +64 -0
- package/src/test-helpers/testbench-utils.ts +374 -0
- package/src/testbench/p2p_client_testbench_worker.ts +321 -122
- package/src/testbench/worker_client_manager.ts +304 -47
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { SecretValue } from '@aztec/foundation/config';
|
|
2
1
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
2
|
import { sleep } from '@aztec/foundation/sleep';
|
|
4
3
|
import { fork } from 'child_process';
|
|
4
|
+
import { existsSync } from 'fs';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import { getP2PDefaultConfig } from '../config.js';
|
|
8
8
|
import { generatePeerIdPrivateKeys } from '../test-helpers/generate-peer-id-private-keys.js';
|
|
9
9
|
import { getPorts } from '../test-helpers/get-ports.js';
|
|
10
10
|
import { makeEnr, makeEnrs } from '../test-helpers/make-enrs.js';
|
|
11
|
+
import { BENCHMARK_CONSTANTS } from '../test-helpers/testbench-utils.js';
|
|
11
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
const
|
|
13
|
+
const p2pRoot = path.resolve(__dirname, '../..');
|
|
14
|
+
const workerTsPath = path.join(__dirname, 'p2p_client_testbench_worker.ts');
|
|
15
|
+
const workerJsPath = path.join(p2pRoot, 'dest/testbench/p2p_client_testbench_worker.js');
|
|
16
|
+
const tsconfigPath = path.join(p2pRoot, 'tsconfig.json');
|
|
13
17
|
const testChainConfig = {
|
|
14
18
|
l1ChainId: 31337,
|
|
15
19
|
rollupVersion: 1,
|
|
@@ -22,6 +26,7 @@ class WorkerClientManager {
|
|
|
22
26
|
peerIdPrivateKeys = [];
|
|
23
27
|
peerEnrs = [];
|
|
24
28
|
ports = [];
|
|
29
|
+
peerIds = [];
|
|
25
30
|
p2pConfig;
|
|
26
31
|
logger;
|
|
27
32
|
messageReceivedByClient = [];
|
|
@@ -36,12 +41,15 @@ class WorkerClientManager {
|
|
|
36
41
|
});
|
|
37
42
|
}
|
|
38
43
|
/**
|
|
39
|
-
* Creates a client configuration object
|
|
44
|
+
* Creates a client configuration object for IPC.
|
|
45
|
+
* Note: We send the raw peerIdPrivateKey string instead of SecretValue
|
|
46
|
+
* because SecretValue.toJSON() returns '[Redacted]', losing the value.
|
|
47
|
+
* The worker must re-wrap it in SecretValue.
|
|
40
48
|
*/ createClientConfig(clientIndex, port, otherNodes) {
|
|
41
49
|
return {
|
|
42
50
|
...getP2PDefaultConfig(),
|
|
43
51
|
p2pEnabled: true,
|
|
44
|
-
peerIdPrivateKey:
|
|
52
|
+
peerIdPrivateKey: this.peerIdPrivateKeys[clientIndex],
|
|
45
53
|
listenAddress: '127.0.0.1',
|
|
46
54
|
p2pIp: '127.0.0.1',
|
|
47
55
|
p2pPort: port,
|
|
@@ -52,17 +60,29 @@ class WorkerClientManager {
|
|
|
52
60
|
};
|
|
53
61
|
}
|
|
54
62
|
/**
|
|
55
|
-
* Spawns a worker process and returns a promise that resolves when the worker is ready
|
|
63
|
+
* Spawns a worker process and returns a promise that resolves when the worker is ready.
|
|
64
|
+
* Config uses raw string for peerIdPrivateKey (not SecretValue) for IPC serialization.
|
|
56
65
|
*/ spawnWorkerProcess(config, clientIndex) {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
...
|
|
61
|
-
|
|
66
|
+
const useCompiled = existsSync(workerJsPath);
|
|
67
|
+
const workerPath = useCompiled ? workerJsPath : workerTsPath;
|
|
68
|
+
const execArgv = [
|
|
69
|
+
...process.execArgv
|
|
70
|
+
];
|
|
71
|
+
if (!useCompiled && !execArgv.includes('ts-node/esm')) {
|
|
72
|
+
execArgv.push('--loader', 'ts-node/esm');
|
|
73
|
+
}
|
|
74
|
+
const env = {
|
|
75
|
+
...process.env,
|
|
76
|
+
TS_NODE_PROJECT: tsconfigPath
|
|
62
77
|
};
|
|
78
|
+
const childProcess = fork(workerPath, {
|
|
79
|
+
cwd: p2pRoot,
|
|
80
|
+
execArgv,
|
|
81
|
+
env
|
|
82
|
+
});
|
|
63
83
|
childProcess.send({
|
|
64
84
|
type: 'START',
|
|
65
|
-
config
|
|
85
|
+
config,
|
|
66
86
|
clientIndex
|
|
67
87
|
});
|
|
68
88
|
// Handle unexpected child process exit
|
|
@@ -78,29 +98,54 @@ class WorkerClientManager {
|
|
|
78
98
|
});
|
|
79
99
|
// Create ready signal promise
|
|
80
100
|
const readySignal = new Promise((resolve, reject)=>{
|
|
81
|
-
|
|
101
|
+
let resolved = false;
|
|
82
102
|
const timeout = setTimeout(()=>{
|
|
103
|
+
if (resolved) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
resolved = true;
|
|
107
|
+
childProcess.off('message', messageHandler);
|
|
108
|
+
childProcess.off('exit', exitHandler);
|
|
83
109
|
reject(new Error(`Timeout waiting for worker ${clientIndex} to be ready`));
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
|
|
110
|
+
}, BENCHMARK_CONSTANTS.WORKER_READY_TIMEOUT_MS);
|
|
111
|
+
const messageHandler = (msg)=>{
|
|
112
|
+
if (resolved) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// Only handle READY or ERROR messages; ignore others (e.g., GOSSIP_RECEIVED)
|
|
87
116
|
if (msg.type === 'READY') {
|
|
117
|
+
resolved = true;
|
|
118
|
+
clearTimeout(timeout);
|
|
119
|
+
childProcess.off('message', messageHandler);
|
|
120
|
+
childProcess.off('exit', exitHandler);
|
|
121
|
+
if (typeof msg.peerId === 'string') {
|
|
122
|
+
this.peerIds[clientIndex] = msg.peerId;
|
|
123
|
+
}
|
|
88
124
|
resolve();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
125
|
+
} else if (msg.type === 'ERROR') {
|
|
126
|
+
resolved = true;
|
|
127
|
+
clearTimeout(timeout);
|
|
128
|
+
childProcess.off('message', messageHandler);
|
|
129
|
+
childProcess.off('exit', exitHandler);
|
|
92
130
|
reject(new Error(msg.error));
|
|
93
131
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
132
|
+
// Ignore other message types and keep waiting for READY/ERROR
|
|
133
|
+
};
|
|
134
|
+
const exitHandler = (code)=>{
|
|
135
|
+
if (resolved) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
resolved = true;
|
|
97
139
|
clearTimeout(timeout);
|
|
140
|
+
childProcess.off('message', messageHandler);
|
|
98
141
|
if (code === 0) {
|
|
99
142
|
resolve();
|
|
100
143
|
} else {
|
|
101
144
|
reject(new Error(`Worker ${clientIndex} exited with code ${code} before becoming ready`));
|
|
102
145
|
}
|
|
103
|
-
}
|
|
146
|
+
};
|
|
147
|
+
childProcess.on('message', messageHandler);
|
|
148
|
+
childProcess.once('exit', exitHandler);
|
|
104
149
|
});
|
|
105
150
|
return [
|
|
106
151
|
childProcess,
|
|
@@ -108,34 +153,46 @@ class WorkerClientManager {
|
|
|
108
153
|
];
|
|
109
154
|
}
|
|
110
155
|
/**
|
|
111
|
-
* Creates a number of worker clients in separate processes
|
|
112
|
-
* All are configured to connect to each other and
|
|
156
|
+
* Creates a number of worker clients in separate processes.
|
|
157
|
+
* All are configured to connect to each other and overridden with the test-specific config.
|
|
113
158
|
*
|
|
114
159
|
* @param numberOfClients - The number of clients to create
|
|
160
|
+
* @param options - Optional overrides for seeding/bootstrapping strategy
|
|
115
161
|
* @returns The ENRs of the created clients
|
|
116
|
-
*/ async makeWorkerClients(numberOfClients) {
|
|
162
|
+
*/ async makeWorkerClients(numberOfClients, options = {}) {
|
|
117
163
|
try {
|
|
164
|
+
const bootstrapMode = options.bootstrapMode ?? (this.p2pConfig.bootstrapNodesAsFullPeers ? 'all' : 'subset');
|
|
165
|
+
const seedPeerLimit = options.seedPeerLimit ?? 10;
|
|
166
|
+
const batchSize = options.batchSize ?? (bootstrapMode === 'all' ? Math.min(5, numberOfClients) : numberOfClients);
|
|
167
|
+
const batchDelayMs = options.batchDelayMs ?? (bootstrapMode === 'all' ? 500 : 0);
|
|
118
168
|
this.messageReceivedByClient = new Array(numberOfClients).fill(0);
|
|
119
169
|
this.peerIdPrivateKeys = generatePeerIdPrivateKeys(numberOfClients);
|
|
120
170
|
this.ports = await getPorts(numberOfClients);
|
|
121
171
|
this.peerEnrs = await makeEnrs(this.peerIdPrivateKeys, this.ports, testChainConfig);
|
|
172
|
+
this.peerIds = new Array(numberOfClients);
|
|
122
173
|
this.processes = [];
|
|
123
174
|
const readySignals = [];
|
|
124
|
-
for(let
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
175
|
+
for(let batchStart = 0; batchStart < numberOfClients; batchStart += batchSize){
|
|
176
|
+
const batchEnd = Math.min(batchStart + batchSize, numberOfClients);
|
|
177
|
+
const batchPromises = [];
|
|
178
|
+
for(let i = batchStart; i < batchEnd; i++){
|
|
179
|
+
this.logger.info(`Creating client ${i}`);
|
|
180
|
+
const otherNodes = bootstrapMode === 'all' ? this.peerEnrs.filter((_, ind)=>ind !== i) : this.peerEnrs.filter((_, ind)=>ind < Math.min(i, seedPeerLimit));
|
|
181
|
+
const config = this.createClientConfig(i, this.ports[i], otherNodes);
|
|
182
|
+
const [childProcess, readySignal] = this.spawnWorkerProcess(config, i);
|
|
183
|
+
readySignals.push(readySignal);
|
|
184
|
+
batchPromises.push(readySignal);
|
|
185
|
+
this.processes.push(childProcess);
|
|
186
|
+
}
|
|
187
|
+
await Promise.all(batchPromises);
|
|
188
|
+
if (batchEnd < numberOfClients && batchDelayMs > 0) {
|
|
189
|
+
await sleep(batchDelayMs);
|
|
190
|
+
}
|
|
132
191
|
}
|
|
133
|
-
|
|
134
|
-
await sleep(10000);
|
|
135
|
-
// Wait for all peers to be booted up with timeout
|
|
192
|
+
await sleep(BENCHMARK_CONSTANTS.PEER_DISCOVERY_WAIT_MS);
|
|
136
193
|
await Promise.race([
|
|
137
194
|
Promise.all(readySignals),
|
|
138
|
-
new Promise((_, reject)=>setTimeout(()=>reject(new Error('Timeout waiting for all workers to be ready')),
|
|
195
|
+
new Promise((_, reject)=>setTimeout(()=>reject(new Error('Timeout waiting for all workers to be ready')), BENCHMARK_CONSTANTS.WORKER_READY_TIMEOUT_MS))
|
|
139
196
|
]);
|
|
140
197
|
return this.peerEnrs;
|
|
141
198
|
} catch (error) {
|
|
@@ -177,10 +234,9 @@ class WorkerClientManager {
|
|
|
177
234
|
const config = this.createClientConfig(clientIndex, newPort, otherNodes);
|
|
178
235
|
const [childProcess, readySignal] = this.spawnWorkerProcess(config, clientIndex);
|
|
179
236
|
this.processes[clientIndex] = childProcess;
|
|
180
|
-
// Wait for the process to be ready with a timeout
|
|
181
237
|
await Promise.race([
|
|
182
238
|
readySignal,
|
|
183
|
-
new Promise((_, reject)=>setTimeout(()=>reject(new Error(`Timeout waiting for client ${clientIndex} to be ready`)),
|
|
239
|
+
new Promise((_, reject)=>setTimeout(()=>reject(new Error(`Timeout waiting for client ${clientIndex} to be ready`)), BENCHMARK_CONSTANTS.WORKER_READY_TIMEOUT_MS))
|
|
184
240
|
]);
|
|
185
241
|
} catch (error) {
|
|
186
242
|
this.logger.error(`Error during changePort for client ${clientIndex}:`, error);
|
|
@@ -196,15 +252,14 @@ class WorkerClientManager {
|
|
|
196
252
|
return Promise.resolve();
|
|
197
253
|
}
|
|
198
254
|
return new Promise((resolve)=>{
|
|
199
|
-
// Set a timeout for the graceful exit
|
|
200
255
|
const forceKillTimeout = setTimeout(()=>{
|
|
201
256
|
this.logger.warn(`Process ${index} didn't exit gracefully, force killing...`);
|
|
202
257
|
try {
|
|
203
|
-
process1.kill('SIGKILL');
|
|
258
|
+
process1.kill('SIGKILL');
|
|
204
259
|
} catch (e) {
|
|
205
260
|
this.logger.error(`Error force killing process ${index}:`, e);
|
|
206
261
|
}
|
|
207
|
-
},
|
|
262
|
+
}, BENCHMARK_CONSTANTS.GRACEFUL_SHUTDOWN_TIMEOUT_MS);
|
|
208
263
|
// Listen for process exit
|
|
209
264
|
process1.once('exit', ()=>{
|
|
210
265
|
clearTimeout(forceKillTimeout);
|
|
@@ -233,7 +288,6 @@ class WorkerClientManager {
|
|
|
233
288
|
this.logger.info(`Cleaning up ${this.processes.length} worker processes`);
|
|
234
289
|
// Create array of promises for each process termination
|
|
235
290
|
const terminationPromises = this.processes.map((process1, index)=>this.terminateProcess(process1, index));
|
|
236
|
-
// Wait for all processes to terminate with a timeout
|
|
237
291
|
try {
|
|
238
292
|
await Promise.race([
|
|
239
293
|
Promise.all(terminationPromises),
|
|
@@ -250,14 +304,142 @@ class WorkerClientManager {
|
|
|
250
304
|
}
|
|
251
305
|
});
|
|
252
306
|
resolve();
|
|
253
|
-
},
|
|
307
|
+
}, BENCHMARK_CONSTANTS.CLEANUP_TIMEOUT_MS);
|
|
254
308
|
})
|
|
255
309
|
]);
|
|
256
310
|
} catch (error) {
|
|
257
311
|
this.logger.error('Error during cleanup:', error);
|
|
258
312
|
}
|
|
259
313
|
this.processes = [];
|
|
314
|
+
this.peerIds = [];
|
|
260
315
|
this.logger.info('All worker processes cleaned up');
|
|
261
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* Run a req/resp benchmark across all worker clients.
|
|
319
|
+
*
|
|
320
|
+
* This sends a BENCH_REQRESP command to all workers:
|
|
321
|
+
* - Aggregator (client 0) runs the collector and returns timing results
|
|
322
|
+
* - Responders (clients 1..N) populate their tx pools based on distribution
|
|
323
|
+
*
|
|
324
|
+
* All workers generate the same txs deterministically from a shared seed,
|
|
325
|
+
* then filter based on their peerIndex and distribution pattern.
|
|
326
|
+
*/ async runReqRespBenchmark(config) {
|
|
327
|
+
const peerCount = this.processes.length;
|
|
328
|
+
if (peerCount < 2) {
|
|
329
|
+
throw new Error('Need at least 2 peers to run req/resp benchmark');
|
|
330
|
+
}
|
|
331
|
+
const seed = config.seed ?? Date.now();
|
|
332
|
+
const blockNumber = config.blockNumber ?? 1;
|
|
333
|
+
const pinnedPeerId = config.pinnedPeerIndex !== undefined ? this.peerIds[config.pinnedPeerIndex] : undefined;
|
|
334
|
+
this.logger.info(`Starting req/resp benchmark: txCount=${config.txCount}, distribution=${config.distribution}, collector=${config.collectorType}`);
|
|
335
|
+
const readyPromises = [];
|
|
336
|
+
for(let i = 1; i < peerCount; i++){
|
|
337
|
+
const cmd = {
|
|
338
|
+
type: 'BENCH_REQRESP',
|
|
339
|
+
txCount: config.txCount,
|
|
340
|
+
peerCount,
|
|
341
|
+
distribution: config.distribution,
|
|
342
|
+
collectorType: config.collectorType,
|
|
343
|
+
timeoutMs: config.timeoutMs,
|
|
344
|
+
isAggregator: false,
|
|
345
|
+
peerIndex: i,
|
|
346
|
+
pinnedPeerIndex: config.pinnedPeerIndex,
|
|
347
|
+
pinnedPeerId,
|
|
348
|
+
blockNumber,
|
|
349
|
+
seed
|
|
350
|
+
};
|
|
351
|
+
this.processes[i].send(cmd);
|
|
352
|
+
readyPromises.push(this.waitForBenchReady(i, 30000));
|
|
353
|
+
}
|
|
354
|
+
await Promise.all(readyPromises);
|
|
355
|
+
this.logger.info('All responder peers ready, starting aggregator benchmark...');
|
|
356
|
+
const aggregatorCmd = {
|
|
357
|
+
type: 'BENCH_REQRESP',
|
|
358
|
+
txCount: config.txCount,
|
|
359
|
+
peerCount,
|
|
360
|
+
distribution: config.distribution,
|
|
361
|
+
collectorType: config.collectorType,
|
|
362
|
+
timeoutMs: config.timeoutMs,
|
|
363
|
+
isAggregator: true,
|
|
364
|
+
peerIndex: 0,
|
|
365
|
+
pinnedPeerIndex: config.pinnedPeerIndex,
|
|
366
|
+
pinnedPeerId,
|
|
367
|
+
blockNumber,
|
|
368
|
+
seed
|
|
369
|
+
};
|
|
370
|
+
this.processes[0].send(aggregatorCmd);
|
|
371
|
+
const result = await this.waitForBenchResult(0, config.timeoutMs + 30000);
|
|
372
|
+
this.logger.info(`Benchmark complete: fetched=${result.fetchedCount}/${config.txCount}, duration=${result.durationMs.toFixed(0)}ms, success=${result.success}`);
|
|
373
|
+
return {
|
|
374
|
+
txCount: config.txCount,
|
|
375
|
+
distribution: config.distribution,
|
|
376
|
+
collector: config.collectorType,
|
|
377
|
+
durationMs: result.durationMs,
|
|
378
|
+
fetchedCount: result.fetchedCount,
|
|
379
|
+
success: result.success,
|
|
380
|
+
error: result.error
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
waitForBenchReady(clientIndex, timeoutMs) {
|
|
384
|
+
return new Promise((resolve, reject)=>{
|
|
385
|
+
let resolved = false;
|
|
386
|
+
const handler = (msg)=>{
|
|
387
|
+
if (resolved) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (msg.type === 'BENCH_READY') {
|
|
391
|
+
resolved = true;
|
|
392
|
+
clearTimeout(timeout);
|
|
393
|
+
this.processes[clientIndex].off('message', handler);
|
|
394
|
+
resolve();
|
|
395
|
+
} else if (msg.type === 'ERROR') {
|
|
396
|
+
resolved = true;
|
|
397
|
+
clearTimeout(timeout);
|
|
398
|
+
this.processes[clientIndex].off('message', handler);
|
|
399
|
+
reject(new Error(`Client ${clientIndex} error: ${msg.error}`));
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
const timeout = setTimeout(()=>{
|
|
403
|
+
if (resolved) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
resolved = true;
|
|
407
|
+
this.processes[clientIndex].off('message', handler);
|
|
408
|
+
reject(new Error(`Timeout waiting for BENCH_READY from client ${clientIndex}`));
|
|
409
|
+
}, timeoutMs);
|
|
410
|
+
this.processes[clientIndex].on('message', handler);
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
waitForBenchResult(clientIndex, timeoutMs) {
|
|
414
|
+
return new Promise((resolve, reject)=>{
|
|
415
|
+
let resolved = false;
|
|
416
|
+
const handler = (msg)=>{
|
|
417
|
+
if (resolved) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (msg.type === 'BENCH_RESULT') {
|
|
421
|
+
resolved = true;
|
|
422
|
+
clearTimeout(timeout);
|
|
423
|
+
this.processes[clientIndex].off('message', handler);
|
|
424
|
+
resolve(msg);
|
|
425
|
+
} else if (msg.type === 'ERROR') {
|
|
426
|
+
resolved = true;
|
|
427
|
+
clearTimeout(timeout);
|
|
428
|
+
this.processes[clientIndex].off('message', handler);
|
|
429
|
+
reject(new Error(`Client ${clientIndex} error: ${msg.error}`));
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
const timeout = setTimeout(()=>{
|
|
433
|
+
if (resolved) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
resolved = true;
|
|
437
|
+
this.processes[clientIndex].off('message', handler);
|
|
438
|
+
reject(new Error(`Timeout waiting for BENCH_RESULT from client ${clientIndex}`));
|
|
439
|
+
}, timeoutMs);
|
|
440
|
+
this.processes[clientIndex].on('message', handler);
|
|
441
|
+
});
|
|
442
|
+
}
|
|
262
443
|
}
|
|
263
444
|
export { WorkerClientManager, testChainConfig };
|
|
445
|
+
export { COLLECTOR_DISPLAY_NAMES } from './p2p_client_testbench_worker.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/p2p",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.f146247c",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -67,17 +67,17 @@
|
|
|
67
67
|
]
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@aztec/constants": "0.0.1-commit.
|
|
71
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
72
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
73
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
74
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
75
|
-
"@aztec/noir-contracts.js": "0.0.1-commit.
|
|
76
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
77
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
78
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
79
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
80
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
70
|
+
"@aztec/constants": "0.0.1-commit.f146247c",
|
|
71
|
+
"@aztec/epoch-cache": "0.0.1-commit.f146247c",
|
|
72
|
+
"@aztec/ethereum": "0.0.1-commit.f146247c",
|
|
73
|
+
"@aztec/foundation": "0.0.1-commit.f146247c",
|
|
74
|
+
"@aztec/kv-store": "0.0.1-commit.f146247c",
|
|
75
|
+
"@aztec/noir-contracts.js": "0.0.1-commit.f146247c",
|
|
76
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.f146247c",
|
|
77
|
+
"@aztec/protocol-contracts": "0.0.1-commit.f146247c",
|
|
78
|
+
"@aztec/simulator": "0.0.1-commit.f146247c",
|
|
79
|
+
"@aztec/stdlib": "0.0.1-commit.f146247c",
|
|
80
|
+
"@aztec/telemetry-client": "0.0.1-commit.f146247c",
|
|
81
81
|
"@chainsafe/libp2p-gossipsub": "13.0.0",
|
|
82
82
|
"@chainsafe/libp2p-noise": "^15.0.0",
|
|
83
83
|
"@chainsafe/libp2p-yamux": "^6.0.2",
|
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
"xxhash-wasm": "^1.1.0"
|
|
105
105
|
},
|
|
106
106
|
"devDependencies": {
|
|
107
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
108
|
-
"@aztec/world-state": "0.0.1-commit.
|
|
107
|
+
"@aztec/archiver": "0.0.1-commit.f146247c",
|
|
108
|
+
"@aztec/world-state": "0.0.1-commit.f146247c",
|
|
109
109
|
"@jest/globals": "^30.0.0",
|
|
110
110
|
"@types/jest": "^30.0.0",
|
|
111
111
|
"@types/node": "^22.15.17",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
1
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
2
2
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
3
3
|
import type { P2PBootstrapApi } from '@aztec/stdlib/interfaces/server';
|
|
4
4
|
import { OtelMetricsAdapter, type TelemetryClient } from '@aztec/telemetry-client';
|
|
@@ -18,12 +18,15 @@ import { convertToMultiaddr, getPeerIdPrivateKey, getPublicIp } from '../util.js
|
|
|
18
18
|
export class BootstrapNode implements P2PBootstrapApi {
|
|
19
19
|
private node?: Discv5EventEmitter = undefined;
|
|
20
20
|
private peerId?: PeerId;
|
|
21
|
+
private logger: Logger;
|
|
21
22
|
|
|
22
23
|
constructor(
|
|
23
24
|
private store: AztecAsyncKVStore,
|
|
24
25
|
private telemetry: TelemetryClient,
|
|
25
|
-
|
|
26
|
-
) {
|
|
26
|
+
bindings?: LoggerBindings,
|
|
27
|
+
) {
|
|
28
|
+
this.logger = createLogger('p2p:bootstrap', bindings);
|
|
29
|
+
}
|
|
27
30
|
|
|
28
31
|
/**
|
|
29
32
|
* Starts the bootstrap node.
|
|
@@ -65,7 +68,7 @@ export class BootstrapNode implements P2PBootstrapApi {
|
|
|
65
68
|
|
|
66
69
|
this.logger.debug(`Starting bootstrap node ${peerId} listening on ${listenAddrUdp.toString()}`);
|
|
67
70
|
|
|
68
|
-
const metricsRegistry = new OtelMetricsAdapter(this.telemetry);
|
|
71
|
+
const metricsRegistry = new OtelMetricsAdapter(this.telemetry, this.logger.getBindings());
|
|
69
72
|
this.node = Discv5.create({
|
|
70
73
|
enr: ourEnr,
|
|
71
74
|
peerId,
|
package/src/client/factory.ts
CHANGED
|
@@ -62,15 +62,11 @@ export async function createP2PClient<T extends P2PClientType>(
|
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
1,
|
|
71
|
-
config,
|
|
72
|
-
createLogger('p2p-attestation:lmdb-v2'),
|
|
73
|
-
);
|
|
65
|
+
const bindings = logger.getBindings();
|
|
66
|
+
const store = deps.store ?? (await createStore(P2P_STORE_NAME, 2, config, bindings));
|
|
67
|
+
const archive = await createStore(P2P_ARCHIVE_STORE_NAME, 1, config, bindings);
|
|
68
|
+
const peerStore = await createStore(P2P_PEER_STORE_NAME, 1, config, bindings);
|
|
69
|
+
const attestationStore = await createStore(P2P_ATTESTATION_STORE_NAME, 1, config, bindings);
|
|
74
70
|
const l1Constants = await archiver.getL1Constants();
|
|
75
71
|
|
|
76
72
|
const mempools: MemPools = {
|
|
@@ -110,7 +106,7 @@ export async function createP2PClient<T extends P2PClientType>(
|
|
|
110
106
|
}
|
|
111
107
|
|
|
112
108
|
const txCollection = new TxCollection(
|
|
113
|
-
p2pService,
|
|
109
|
+
p2pService.getBatchTxRequesterService(),
|
|
114
110
|
nodeSources,
|
|
115
111
|
l1Constants,
|
|
116
112
|
mempools.txPool,
|
package/src/client/p2p_client.ts
CHANGED
|
@@ -326,8 +326,10 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
326
326
|
[Attributes.BLOCK_ARCHIVE]: proposal.archive.toString(),
|
|
327
327
|
[Attributes.P2P_ID]: (await proposal.p2pMessageLoggingIdentifier()).toString(),
|
|
328
328
|
}))
|
|
329
|
-
public broadcastProposal(proposal: BlockProposal): Promise<void> {
|
|
329
|
+
public async broadcastProposal(proposal: BlockProposal): Promise<void> {
|
|
330
330
|
this.log.verbose(`Broadcasting proposal for slot ${proposal.slotNumber} to peers`);
|
|
331
|
+
// Store our own proposal so we can respond to req/resp requests for it
|
|
332
|
+
await this.attestationPool.addBlockProposal(proposal);
|
|
331
333
|
return this.p2pService.propagate(proposal);
|
|
332
334
|
}
|
|
333
335
|
|
|
@@ -336,8 +338,13 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
336
338
|
[Attributes.BLOCK_ARCHIVE]: proposal.archive.toString(),
|
|
337
339
|
[Attributes.P2P_ID]: (await proposal.p2pMessageLoggingIdentifier()).toString(),
|
|
338
340
|
}))
|
|
339
|
-
public broadcastCheckpointProposal(proposal: CheckpointProposal): Promise<void> {
|
|
341
|
+
public async broadcastCheckpointProposal(proposal: CheckpointProposal): Promise<void> {
|
|
340
342
|
this.log.verbose(`Broadcasting checkpoint proposal for slot ${proposal.slotNumber} to peers`);
|
|
343
|
+
const blockProposal = proposal.getBlockProposal();
|
|
344
|
+
if (blockProposal) {
|
|
345
|
+
// Store our own last-block proposal so we can respond to req/resp requests for it.
|
|
346
|
+
await this.attestationPool.addBlockProposal(blockProposal);
|
|
347
|
+
}
|
|
341
348
|
return this.p2pService.propagate(proposal);
|
|
342
349
|
}
|
|
343
350
|
|