@aztec/p2p 4.0.0-nightly.20260112 → 4.0.0-nightly.20260113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/client/interface.d.ts +18 -5
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +9 -12
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +59 -103
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +61 -42
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +225 -262
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +21 -18
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +113 -108
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +17 -16
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +89 -128
- package/dest/mem_pools/attestation_pool/mocks.d.ts +7 -6
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +9 -8
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -4
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +12 -10
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -5
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +5 -5
- package/dest/msg_validators/index.d.ts +2 -2
- package/dest/msg_validators/index.d.ts.map +1 -1
- package/dest/msg_validators/index.js +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
- package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/index.js +3 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/{block_proposal_validator/block_proposal_validator.js → proposal_validator/proposal_validator.js} +19 -21
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +183 -0
- package/dest/services/dummy_service.d.ts +6 -2
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +3 -0
- package/dest/services/encoding.d.ts +1 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +4 -2
- package/dest/services/libp2p/libp2p_service.d.ts +26 -10
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +218 -88
- package/dest/services/service.d.ts +16 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +25 -11
- package/dest/testbench/worker_client_manager.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +6 -1
- package/package.json +14 -14
- package/src/client/interface.ts +19 -4
- package/src/client/p2p_client.ts +69 -110
- package/src/mem_pools/attestation_pool/attestation_pool.ts +68 -41
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +231 -287
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +162 -140
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +141 -164
- package/src/mem_pools/attestation_pool/mocks.ts +13 -9
- package/src/msg_validators/attestation_validator/attestation_validator.ts +16 -13
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +7 -7
- package/src/msg_validators/index.ts +1 -1
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -0
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +13 -0
- package/src/msg_validators/proposal_validator/index.ts +3 -0
- package/src/msg_validators/{block_proposal_validator/block_proposal_validator.ts → proposal_validator/proposal_validator.ts} +23 -28
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +206 -0
- package/src/services/dummy_service.ts +6 -0
- package/src/services/encoding.ts +3 -1
- package/src/services/libp2p/libp2p_service.ts +258 -94
- package/src/services/service.ts +19 -4
- package/src/testbench/p2p_client_testbench_worker.ts +34 -11
- package/src/testbench/worker_client_manager.ts +6 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -12
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
- package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/index.js +0 -1
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Used when running testbench commands
|
|
5
5
|
*/ import { MockL2BlockSource } from '@aztec/archiver/test';
|
|
6
6
|
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
7
|
+
import { SecretValue } from '@aztec/foundation/config';
|
|
7
8
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
8
9
|
import { createLogger } from '@aztec/foundation/log';
|
|
9
10
|
import { sleep } from '@aztec/foundation/sleep';
|
|
@@ -46,19 +47,23 @@ function mockTxPool() {
|
|
|
46
47
|
function mockAttestationPool() {
|
|
47
48
|
return {
|
|
48
49
|
isEmpty: ()=>Promise.resolve(false),
|
|
49
|
-
addAttestations: ()=>Promise.resolve(),
|
|
50
|
-
deleteAttestations: ()=>Promise.resolve(),
|
|
51
|
-
deleteAttestationsOlderThan: ()=>Promise.resolve(),
|
|
52
|
-
deleteAttestationsForSlot: ()=>Promise.resolve(),
|
|
53
|
-
deleteAttestationsForSlotAndProposal: ()=>Promise.resolve(),
|
|
54
|
-
getAttestationsForSlot: ()=>Promise.resolve([]),
|
|
55
|
-
getAttestationsForSlotAndProposal: ()=>Promise.resolve([]),
|
|
56
50
|
addBlockProposal: ()=>Promise.resolve(),
|
|
57
51
|
getBlockProposal: ()=>Promise.resolve(undefined),
|
|
58
52
|
hasBlockProposal: ()=>Promise.resolve(false),
|
|
59
|
-
hasAttestation: ()=>Promise.resolve(false),
|
|
60
53
|
canAddProposal: ()=>Promise.resolve(true),
|
|
61
|
-
|
|
54
|
+
// Checkpoint attestation methods
|
|
55
|
+
addCheckpointProposal: ()=>Promise.resolve(),
|
|
56
|
+
getCheckpointProposal: ()=>Promise.resolve(undefined),
|
|
57
|
+
hasCheckpointProposal: ()=>Promise.resolve(false),
|
|
58
|
+
addCheckpointAttestations: ()=>Promise.resolve(),
|
|
59
|
+
getCheckpointAttestationsForSlot: ()=>Promise.resolve([]),
|
|
60
|
+
getCheckpointAttestationsForSlotAndProposal: ()=>Promise.resolve([]),
|
|
61
|
+
deleteCheckpointAttestationsOlderThan: ()=>Promise.resolve(),
|
|
62
|
+
hasReachedCheckpointProposalCap: ()=>Promise.resolve(false),
|
|
63
|
+
hasReachedCheckpointAttestationCap: ()=>Promise.resolve(false),
|
|
64
|
+
canAddCheckpointProposal: ()=>Promise.resolve(true),
|
|
65
|
+
canAddCheckpointAttestation: ()=>Promise.resolve(true),
|
|
66
|
+
hasCheckpointAttestation: ()=>Promise.resolve(false)
|
|
62
67
|
};
|
|
63
68
|
}
|
|
64
69
|
function mockEpochCache() {
|
|
@@ -81,6 +86,7 @@ function mockEpochCache() {
|
|
|
81
86
|
currentSlot: SlotNumber.ZERO,
|
|
82
87
|
nextSlot: SlotNumber.ZERO
|
|
83
88
|
}),
|
|
89
|
+
getProposerAttesterAddressInSlot: ()=>Promise.resolve(undefined),
|
|
84
90
|
getEpochAndSlotInNextL1Slot: ()=>({
|
|
85
91
|
epoch: EpochNumber.ZERO,
|
|
86
92
|
slot: SlotNumber.ZERO,
|
|
@@ -144,9 +150,16 @@ class TestLibP2PService extends LibP2PService {
|
|
|
144
150
|
}
|
|
145
151
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
146
152
|
process.on('message', async (msg)=>{
|
|
147
|
-
|
|
153
|
+
// Note: peerIdPrivateKey comes as a raw string (not SecretValue) because
|
|
154
|
+
// SecretValue's private fields can't be serialized via IPC
|
|
155
|
+
const { type, config: rawConfig, clientIndex } = msg;
|
|
148
156
|
try {
|
|
149
157
|
if (type === 'START') {
|
|
158
|
+
// Re-wrap the peerIdPrivateKey with SecretValue
|
|
159
|
+
const config = {
|
|
160
|
+
...rawConfig,
|
|
161
|
+
peerIdPrivateKey: rawConfig.peerIdPrivateKey ? new SecretValue(rawConfig.peerIdPrivateKey) : undefined
|
|
162
|
+
};
|
|
150
163
|
const txPool = mockTxPool();
|
|
151
164
|
const attestationPool = mockAttestationPool();
|
|
152
165
|
const epochCache = mockEpochCache();
|
|
@@ -164,7 +177,8 @@ process.on('message', async (msg)=>{
|
|
|
164
177
|
};
|
|
165
178
|
const client = await createP2PClient(P2PClientType.Full, config, l2BlockSource, proofVerifier, worldState, epochCache, 'test-p2p-bench-worker', undefined, telemetry, deps);
|
|
166
179
|
// Create test service with validation disabled
|
|
167
|
-
|
|
180
|
+
// Note: Parameter order must match LibP2PService constructor
|
|
181
|
+
const testService = new TestLibP2PService(P2PClientType.Full, config, client.p2pService.node, client.p2pService.peerDiscoveryService, client.p2pService.reqresp, client.p2pService.peerManager, client.p2pService.mempools, client.p2pService.archiver, epochCache, proofVerifier, worldState, telemetry, logger, true);
|
|
168
182
|
// Replace the existing p2pService with our test version
|
|
169
183
|
client.p2pService = testService;
|
|
170
184
|
await client.start();
|
|
@@ -48,4 +48,4 @@ declare class WorkerClientManager {
|
|
|
48
48
|
cleanup(): Promise<void>;
|
|
49
49
|
}
|
|
50
50
|
export { WorkerClientManager, testChainConfig };
|
|
51
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyX2NsaWVudF9tYW5hZ2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdGJlbmNoL3dvcmtlcl9jbGllbnRfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVwRCxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RCxPQUFPLEVBQUUsS0FBSyxZQUFZLEVBQVEsTUFBTSxlQUFlLENBQUM7QUFJeEQsT0FBTyxFQUFFLEtBQUssU0FBUyxFQUF1QixNQUFNLGNBQWMsQ0FBQztBQVFuRSxRQUFBLE1BQU0sZUFBZSxFQUFFLFdBTXRCLENBQUM7QUFFRixjQUFNLG1CQUFtQjtJQUNoQixTQUFTLEVBQUUsWUFBWSxFQUFFLENBQU07SUFDL0IsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLENBQU07SUFDakMsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFNO0lBQ3hCLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBTTtJQUM1QixPQUFPLENBQUMsU0FBUyxDQUFxQjtJQUN0QyxPQUFPLENBQUMsTUFBTSxDQUFTO0lBQ3ZCLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBZ0I7SUFFL0MsWUFBWSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxDQUFDLEVBR3hEO0lBRUQsT0FBTyxTQUtOO0lBRUQ7O09BRUc7SUFDSCxPQUFPLENBQUMsa0JBQWtCO0lBaUIxQjs7T0FFRztJQUNILE9BQU8sQ0FBQyxrQkFBa0I7SUF5RDFCOzs7Ozs7T0FNRztJQUNHLGlCQUFpQixDQUFDLGVBQWUsRUFBRSxNQUFNLHFCQXlDOUM7SUFFRCw0QkFBNEIsU0FFM0I7SUFFRCxrQ0FBa0MsV0FFakM7SUFFRDs7Ozs7T0FLRztJQUNHLFVBQVUsQ0FBQyxXQUFXLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQTRDcEQ7SUFFRDs7T0FFRztJQUNILE9BQU8sQ0FBQyxnQkFBZ0I7SUFzQ3hCOztPQUVHO0lBQ0csT0FBTyxrQkFnQ1o7Q0FDRjtBQUVELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxlQUFlLEVBQUUsQ0FBQyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker_client_manager.d.ts","sourceRoot":"","sources":["../../src/testbench/worker_client_manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,KAAK,YAAY,EAAQ,MAAM,eAAe,CAAC;AAIxD,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,cAAc,CAAC;AAQnE,QAAA,MAAM,eAAe,EAAE,WAMtB,CAAC;AAEF,cAAM,mBAAmB;IAChB,SAAS,EAAE,YAAY,EAAE,CAAM;IAC/B,iBAAiB,EAAE,MAAM,EAAE,CAAM;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAM;IACxB,KAAK,EAAE,MAAM,EAAE,CAAM;IAC5B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,uBAAuB,CAAgB;IAE/C,YAAY,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,EAGxD;IAED,OAAO,SAKN;IAED;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;
|
|
1
|
+
{"version":3,"file":"worker_client_manager.d.ts","sourceRoot":"","sources":["../../src/testbench/worker_client_manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,KAAK,YAAY,EAAQ,MAAM,eAAe,CAAC;AAIxD,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,cAAc,CAAC;AAQnE,QAAA,MAAM,eAAe,EAAE,WAMtB,CAAC;AAEF,cAAM,mBAAmB;IAChB,SAAS,EAAE,YAAY,EAAE,CAAM;IAC/B,iBAAiB,EAAE,MAAM,EAAE,CAAM;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAM;IACxB,KAAK,EAAE,MAAM,EAAE,CAAM;IAC5B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,uBAAuB,CAAgB;IAE/C,YAAY,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,EAGxD;IAED,OAAO,SAKN;IAED;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyD1B;;;;;;OAMG;IACG,iBAAiB,CAAC,eAAe,EAAE,MAAM,qBAyC9C;IAED,4BAA4B,SAE3B;IAED,kCAAkC,WAEjC;IAED;;;;;OAKG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBA4CpD;IAED;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsCxB;;OAEG;IACG,OAAO,kBAgCZ;CACF;AAED,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -55,9 +55,14 @@ class WorkerClientManager {
|
|
|
55
55
|
* Spawns a worker process and returns a promise that resolves when the worker is ready
|
|
56
56
|
*/ spawnWorkerProcess(config, clientIndex) {
|
|
57
57
|
const childProcess = fork(workerPath);
|
|
58
|
+
// Extract the raw peerIdPrivateKey value since SecretValue can't be serialized via IPC
|
|
59
|
+
const serializedConfig = {
|
|
60
|
+
...config,
|
|
61
|
+
peerIdPrivateKey: config.peerIdPrivateKey?.getValue()
|
|
62
|
+
};
|
|
58
63
|
childProcess.send({
|
|
59
64
|
type: 'START',
|
|
60
|
-
config,
|
|
65
|
+
config: serializedConfig,
|
|
61
66
|
clientIndex
|
|
62
67
|
});
|
|
63
68
|
// Handle unexpected child process exit
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/p2p",
|
|
3
|
-
"version": "4.0.0-nightly.
|
|
3
|
+
"version": "4.0.0-nightly.20260113",
|
|
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": "4.0.0-nightly.
|
|
71
|
-
"@aztec/epoch-cache": "4.0.0-nightly.
|
|
72
|
-
"@aztec/ethereum": "4.0.0-nightly.
|
|
73
|
-
"@aztec/foundation": "4.0.0-nightly.
|
|
74
|
-
"@aztec/kv-store": "4.0.0-nightly.
|
|
75
|
-
"@aztec/noir-contracts.js": "4.0.0-nightly.
|
|
76
|
-
"@aztec/noir-protocol-circuits-types": "4.0.0-nightly.
|
|
77
|
-
"@aztec/protocol-contracts": "4.0.0-nightly.
|
|
78
|
-
"@aztec/simulator": "4.0.0-nightly.
|
|
79
|
-
"@aztec/stdlib": "4.0.0-nightly.
|
|
80
|
-
"@aztec/telemetry-client": "4.0.0-nightly.
|
|
70
|
+
"@aztec/constants": "4.0.0-nightly.20260113",
|
|
71
|
+
"@aztec/epoch-cache": "4.0.0-nightly.20260113",
|
|
72
|
+
"@aztec/ethereum": "4.0.0-nightly.20260113",
|
|
73
|
+
"@aztec/foundation": "4.0.0-nightly.20260113",
|
|
74
|
+
"@aztec/kv-store": "4.0.0-nightly.20260113",
|
|
75
|
+
"@aztec/noir-contracts.js": "4.0.0-nightly.20260113",
|
|
76
|
+
"@aztec/noir-protocol-circuits-types": "4.0.0-nightly.20260113",
|
|
77
|
+
"@aztec/protocol-contracts": "4.0.0-nightly.20260113",
|
|
78
|
+
"@aztec/simulator": "4.0.0-nightly.20260113",
|
|
79
|
+
"@aztec/stdlib": "4.0.0-nightly.20260113",
|
|
80
|
+
"@aztec/telemetry-client": "4.0.0-nightly.20260113",
|
|
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": "4.0.0-nightly.
|
|
108
|
-
"@aztec/world-state": "4.0.0-nightly.
|
|
107
|
+
"@aztec/archiver": "4.0.0-nightly.20260113",
|
|
108
|
+
"@aztec/world-state": "4.0.0-nightly.20260113",
|
|
109
109
|
"@jest/globals": "^30.0.0",
|
|
110
110
|
"@types/jest": "^30.0.0",
|
|
111
111
|
"@types/node": "^22.15.17",
|
package/src/client/interface.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EthAddress, L2BlockId } from '@aztec/stdlib/block';
|
|
2
2
|
import type { P2PApiFull } from '@aztec/stdlib/interfaces/server';
|
|
3
|
-
import type {
|
|
3
|
+
import type { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PClientType } from '@aztec/stdlib/p2p';
|
|
4
4
|
import type { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
5
5
|
|
|
6
6
|
import type { PeerId } from '@libp2p/interface';
|
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
ReqRespSubProtocolHandler,
|
|
14
14
|
ReqRespSubProtocolValidators,
|
|
15
15
|
} from '../services/reqresp/interface.js';
|
|
16
|
-
import type { P2PBlockReceivedCallback } from '../services/service.js';
|
|
16
|
+
import type { P2PBlockReceivedCallback, P2PCheckpointReceivedCallback } from '../services/service.js';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Enum defining the possible states of the p2p client.
|
|
@@ -50,8 +50,15 @@ export type P2P<T extends P2PClientType = P2PClientType.Full> = P2PApiFull<T> &
|
|
|
50
50
|
*/
|
|
51
51
|
broadcastProposal(proposal: BlockProposal): Promise<void>;
|
|
52
52
|
|
|
53
|
-
/**
|
|
54
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Broadcasts a checkpoint proposal (last block in a checkpoint) to other peers.
|
|
55
|
+
*
|
|
56
|
+
* @param proposal - the checkpoint proposal
|
|
57
|
+
*/
|
|
58
|
+
broadcastCheckpointProposal(proposal: CheckpointProposal): Promise<void>;
|
|
59
|
+
|
|
60
|
+
/** Broadcasts checkpoint attestations to other peers. */
|
|
61
|
+
broadcastCheckpointAttestations(attestations: CheckpointAttestation[]): Promise<void>;
|
|
55
62
|
|
|
56
63
|
/**
|
|
57
64
|
* Registers a callback from the validator client that determines how to behave when
|
|
@@ -63,6 +70,14 @@ export type P2P<T extends P2PClientType = P2PClientType.Full> = P2PApiFull<T> &
|
|
|
63
70
|
// ^ This pattern is not my favorite (md)
|
|
64
71
|
registerBlockProposalHandler(callback: P2PBlockReceivedCallback): void;
|
|
65
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Registers a callback from the validator client that determines how to behave when
|
|
75
|
+
* foreign checkpoint proposals are received
|
|
76
|
+
*
|
|
77
|
+
* @param handler - A function taking a received checkpoint proposal and producing attestations
|
|
78
|
+
*/
|
|
79
|
+
registerCheckpointProposalHandler(callback: P2PCheckpointReceivedCallback): void;
|
|
80
|
+
|
|
66
81
|
/**
|
|
67
82
|
* Request a list of transactions from another peer by their tx hashes.
|
|
68
83
|
* @param txHashes - Hashes of the txs to query.
|
package/src/client/p2p_client.ts
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
import { GENESIS_BLOCK_HEADER_HASH
|
|
1
|
+
import { GENESIS_BLOCK_HEADER_HASH } from '@aztec/constants';
|
|
2
2
|
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
5
|
-
import type { AztecAsyncKVStore,
|
|
5
|
+
import type { AztecAsyncKVStore, AztecAsyncSingleton } from '@aztec/kv-store';
|
|
6
|
+
import { L2TipsKVStore } from '@aztec/kv-store/stores';
|
|
6
7
|
import {
|
|
7
8
|
type EthAddress,
|
|
8
|
-
type L2BlockId,
|
|
9
9
|
type L2BlockNew,
|
|
10
10
|
type L2BlockSource,
|
|
11
11
|
L2BlockStream,
|
|
12
12
|
type L2BlockStreamEvent,
|
|
13
13
|
type L2Tips,
|
|
14
|
+
type L2TipsStore,
|
|
14
15
|
} from '@aztec/stdlib/block';
|
|
15
16
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
16
17
|
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
17
18
|
import { type PeerInfo, tryStop } from '@aztec/stdlib/interfaces/server';
|
|
18
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
type BlockProposal,
|
|
21
|
+
CheckpointAttestation,
|
|
22
|
+
type CheckpointProposal,
|
|
23
|
+
type P2PClientType,
|
|
24
|
+
} from '@aztec/stdlib/p2p';
|
|
19
25
|
import type { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
20
26
|
import { Attributes, type TelemetryClient, WithTracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
21
27
|
|
|
@@ -33,7 +39,7 @@ import {
|
|
|
33
39
|
type ReqRespSubProtocolValidators,
|
|
34
40
|
} from '../services/reqresp/interface.js';
|
|
35
41
|
import { chunkTxHashesRequest } from '../services/reqresp/protocols/tx.js';
|
|
36
|
-
import type { P2PBlockReceivedCallback, P2PService } from '../services/service.js';
|
|
42
|
+
import type { P2PBlockReceivedCallback, P2PCheckpointReceivedCallback, P2PService } from '../services/service.js';
|
|
37
43
|
import { TxCollection } from '../services/tx_collection/tx_collection.js';
|
|
38
44
|
import { TxProvider } from '../services/tx_provider.js';
|
|
39
45
|
import { type P2P, P2PClientState, type P2PSyncState } from './interface.js';
|
|
@@ -55,10 +61,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
55
61
|
private provenBlockNumberAtStart = -1;
|
|
56
62
|
private finalizedBlockNumberAtStart = -1;
|
|
57
63
|
|
|
58
|
-
private
|
|
59
|
-
private synchedLatestBlockNumber: AztecAsyncSingleton<BlockNumber>;
|
|
60
|
-
private synchedProvenBlockNumber: AztecAsyncSingleton<BlockNumber>;
|
|
61
|
-
private synchedFinalizedBlockNumber: AztecAsyncSingleton<BlockNumber>;
|
|
64
|
+
private l2Tips: L2TipsStore;
|
|
62
65
|
private synchedLatestSlot: AztecAsyncSingleton<bigint>;
|
|
63
66
|
|
|
64
67
|
private txPool: TxPool;
|
|
@@ -107,7 +110,8 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
107
110
|
);
|
|
108
111
|
|
|
109
112
|
// Default to collecting all txs when we see a valid proposal
|
|
110
|
-
// This can be overridden by the validator client to
|
|
113
|
+
// This can be overridden by the validator client to validate, and it will call getTxsForBlockProposal on its own
|
|
114
|
+
// Note: Validators do NOT attest to individual blocks - attestations are only for checkpoint proposals.
|
|
111
115
|
// TODO(palla/txs): We should not trigger a request for txs on a proposal before fully validating it. We need to bring
|
|
112
116
|
// validator-client code into here so we can validate a proposal is reasonable.
|
|
113
117
|
this.registerBlockProposalHandler(async (block, sender) => {
|
|
@@ -116,21 +120,17 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
116
120
|
const constants = this.txCollection.getConstants();
|
|
117
121
|
const nextSlotTimestampSeconds = Number(getTimestampForSlot(SlotNumber(block.slotNumber + 1), constants));
|
|
118
122
|
const deadline = new Date(nextSlotTimestampSeconds * 1000);
|
|
119
|
-
const parentBlock = await this.l2BlockSource.getBlockHeaderByArchive(block.
|
|
123
|
+
const parentBlock = await this.l2BlockSource.getBlockHeaderByArchive(block.blockHeader.lastArchive.root);
|
|
120
124
|
if (!parentBlock) {
|
|
121
125
|
this.log.debug(`Cannot collect txs for proposal as parent block not found`);
|
|
122
|
-
return;
|
|
126
|
+
return false;
|
|
123
127
|
}
|
|
124
128
|
const blockNumber = BlockNumber(parentBlock.getBlockNumber() + 1);
|
|
125
129
|
await this.txProvider.getTxsForBlockProposal(block, blockNumber, { pinnedPeer: sender, deadline });
|
|
126
|
-
return
|
|
130
|
+
return true;
|
|
127
131
|
});
|
|
128
132
|
|
|
129
|
-
|
|
130
|
-
this.synchedBlockHashes = store.openMap('p2p_pool_block_hashes');
|
|
131
|
-
this.synchedLatestBlockNumber = store.openSingleton('p2p_pool_last_l2_block');
|
|
132
|
-
this.synchedProvenBlockNumber = store.openSingleton('p2p_pool_last_proven_l2_block');
|
|
133
|
-
this.synchedFinalizedBlockNumber = store.openSingleton('p2p_pool_last_finalized_l2_block');
|
|
133
|
+
this.l2Tips = new L2TipsKVStore(store, 'p2p_client');
|
|
134
134
|
this.synchedLatestSlot = store.openSingleton('p2p_pool_last_l2_slot');
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -156,7 +156,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
public getL2BlockHash(number: BlockNumber): Promise<string | undefined> {
|
|
159
|
-
return this.
|
|
159
|
+
return this.l2Tips.getL2BlockHash(number);
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
public updateP2PConfig(config: Partial<P2PConfig>): Promise<void> {
|
|
@@ -165,56 +165,20 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
165
165
|
return Promise.resolve();
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
public
|
|
169
|
-
|
|
170
|
-
let latestBlockHash: string | undefined;
|
|
171
|
-
|
|
172
|
-
const provenBlockNumber = await this.getSyncedProvenBlockNum();
|
|
173
|
-
let provenBlockHash: string | undefined;
|
|
174
|
-
|
|
175
|
-
const finalizedBlockNumber = await this.getSyncedFinalizedBlockNum();
|
|
176
|
-
let finalizedBlockHash: string | undefined;
|
|
177
|
-
|
|
178
|
-
if (latestBlockNumber > 0) {
|
|
179
|
-
latestBlockHash = await this.synchedBlockHashes.getAsync(latestBlockNumber);
|
|
180
|
-
if (typeof latestBlockHash === 'undefined') {
|
|
181
|
-
throw new Error(`Block hash for latest block ${latestBlockNumber} not found in p2p client`);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (provenBlockNumber > 0) {
|
|
186
|
-
provenBlockHash = await this.synchedBlockHashes.getAsync(provenBlockNumber);
|
|
187
|
-
if (typeof provenBlockHash === 'undefined') {
|
|
188
|
-
throw new Error(`Block hash for proven block ${provenBlockNumber} not found in p2p client`);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (finalizedBlockNumber > 0) {
|
|
193
|
-
finalizedBlockHash = await this.synchedBlockHashes.getAsync(finalizedBlockNumber);
|
|
194
|
-
if (typeof finalizedBlockHash === 'undefined') {
|
|
195
|
-
throw new Error(`Block hash for finalized block ${finalizedBlockNumber} not found in p2p client`);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const genesisHash = GENESIS_BLOCK_HEADER_HASH.toString();
|
|
200
|
-
|
|
201
|
-
return {
|
|
202
|
-
latest: { hash: latestBlockHash ?? genesisHash, number: latestBlockNumber },
|
|
203
|
-
proven: { hash: provenBlockHash ?? genesisHash, number: provenBlockNumber },
|
|
204
|
-
finalized: { hash: finalizedBlockHash ?? genesisHash, number: finalizedBlockNumber },
|
|
205
|
-
};
|
|
168
|
+
public getL2Tips(): Promise<L2Tips> {
|
|
169
|
+
return this.l2Tips.getL2Tips();
|
|
206
170
|
}
|
|
207
171
|
|
|
208
172
|
public async handleBlockStreamEvent(event: L2BlockStreamEvent): Promise<void> {
|
|
209
173
|
this.log.debug(`Handling block stream event ${event.type}`);
|
|
174
|
+
|
|
210
175
|
switch (event.type) {
|
|
211
176
|
case 'blocks-added':
|
|
212
|
-
await this.handleLatestL2Blocks(event.blocks
|
|
177
|
+
await this.handleLatestL2Blocks(event.blocks);
|
|
213
178
|
break;
|
|
214
179
|
case 'chain-finalized': {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const from = BlockNumber((await this.getSyncedFinalizedBlockNum()) + 1);
|
|
180
|
+
const oldFinalizedBlockNum = await this.getSyncedFinalizedBlockNum();
|
|
181
|
+
const from = BlockNumber(oldFinalizedBlockNum + 1);
|
|
218
182
|
const limit = event.block.number - from + 1;
|
|
219
183
|
if (limit > 0) {
|
|
220
184
|
const oldBlocks = await this.l2BlockSource.getBlocks(from, limit);
|
|
@@ -222,28 +186,24 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
222
186
|
}
|
|
223
187
|
break;
|
|
224
188
|
}
|
|
225
|
-
case 'chain-proven':
|
|
226
|
-
await this.setBlockHash(event.block);
|
|
189
|
+
case 'chain-proven':
|
|
227
190
|
this.txCollection.stopCollectingForBlocksUpTo(event.block.number);
|
|
228
|
-
await this.synchedProvenBlockNumber.set(event.block.number);
|
|
229
191
|
break;
|
|
230
|
-
}
|
|
231
192
|
case 'chain-pruned':
|
|
232
|
-
await this.setBlockHash(event.block);
|
|
233
193
|
this.txCollection.stopCollectingForBlocksAfter(event.block.number);
|
|
234
194
|
await this.handlePruneL2Blocks(event.block.number);
|
|
235
195
|
break;
|
|
196
|
+
case 'chain-checkpointed':
|
|
197
|
+
break;
|
|
236
198
|
default: {
|
|
237
199
|
const _: never = event;
|
|
238
200
|
break;
|
|
239
201
|
}
|
|
240
202
|
}
|
|
241
|
-
}
|
|
242
203
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
204
|
+
// Pass the event through to our l2 tips store
|
|
205
|
+
await this.l2Tips.handleBlockStreamEvent(event);
|
|
206
|
+
await this.startServiceIfSynched();
|
|
247
207
|
}
|
|
248
208
|
|
|
249
209
|
#assertIsReady() {
|
|
@@ -267,9 +227,9 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
267
227
|
|
|
268
228
|
// get the current latest block numbers
|
|
269
229
|
const latestBlockNumbers = await this.l2BlockSource.getL2Tips();
|
|
270
|
-
this.latestBlockNumberAtStart = latestBlockNumbers.
|
|
271
|
-
this.provenBlockNumberAtStart = latestBlockNumbers.proven.number;
|
|
272
|
-
this.finalizedBlockNumberAtStart = latestBlockNumbers.finalized.number;
|
|
230
|
+
this.latestBlockNumberAtStart = latestBlockNumbers.proposed.number;
|
|
231
|
+
this.provenBlockNumberAtStart = latestBlockNumbers.proven.block.number;
|
|
232
|
+
this.finalizedBlockNumberAtStart = latestBlockNumbers.finalized.block.number;
|
|
273
233
|
|
|
274
234
|
const syncedLatestBlock = (await this.getSyncedLatestBlockNum()) + 1;
|
|
275
235
|
const syncedProvenBlock = (await this.getSyncedProvenBlockNum()) + 1;
|
|
@@ -371,23 +331,32 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
371
331
|
return this.p2pService.propagate(proposal);
|
|
372
332
|
}
|
|
373
333
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
334
|
+
@trackSpan('p2pClient.broadcastCheckpointProposal', async proposal => ({
|
|
335
|
+
[Attributes.SLOT_NUMBER]: proposal.slotNumber,
|
|
336
|
+
[Attributes.BLOCK_ARCHIVE]: proposal.archive.toString(),
|
|
337
|
+
[Attributes.P2P_ID]: (await proposal.p2pMessageLoggingIdentifier()).toString(),
|
|
338
|
+
}))
|
|
339
|
+
public broadcastCheckpointProposal(proposal: CheckpointProposal): Promise<void> {
|
|
340
|
+
this.log.verbose(`Broadcasting checkpoint proposal for slot ${proposal.slotNumber} to peers`);
|
|
341
|
+
return this.p2pService.propagate(proposal);
|
|
377
342
|
}
|
|
378
343
|
|
|
379
|
-
public async
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
: this.attestationPool.getAttestationsForSlot(slot));
|
|
344
|
+
public async broadcastCheckpointAttestations(attestations: CheckpointAttestation[]): Promise<void> {
|
|
345
|
+
this.log.verbose(`Broadcasting ${attestations.length} checkpoint attestations to peers`);
|
|
346
|
+
await Promise.all(attestations.map(att => this.p2pService.propagate(att)));
|
|
383
347
|
}
|
|
384
348
|
|
|
385
|
-
public
|
|
386
|
-
|
|
349
|
+
public async getCheckpointAttestationsForSlot(
|
|
350
|
+
slot: SlotNumber,
|
|
351
|
+
proposalId?: string,
|
|
352
|
+
): Promise<CheckpointAttestation[]> {
|
|
353
|
+
return await (proposalId
|
|
354
|
+
? this.attestationPool.getCheckpointAttestationsForSlotAndProposal(slot, proposalId)
|
|
355
|
+
: this.attestationPool.getCheckpointAttestationsForSlot(slot));
|
|
387
356
|
}
|
|
388
357
|
|
|
389
|
-
public
|
|
390
|
-
return this.attestationPool.
|
|
358
|
+
public addCheckpointAttestations(attestations: CheckpointAttestation[]): Promise<void> {
|
|
359
|
+
return this.attestationPool.addCheckpointAttestations(attestations);
|
|
391
360
|
}
|
|
392
361
|
|
|
393
362
|
// REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
@@ -396,6 +365,10 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
396
365
|
this.p2pService.registerBlockReceivedCallback(handler);
|
|
397
366
|
}
|
|
398
367
|
|
|
368
|
+
public registerCheckpointProposalHandler(handler: P2PCheckpointReceivedCallback): void {
|
|
369
|
+
this.p2pService.registerCheckpointReceivedCallback(handler);
|
|
370
|
+
}
|
|
371
|
+
|
|
399
372
|
/**
|
|
400
373
|
* Uses the batched Request Response protocol to request a set of transactions from the network.
|
|
401
374
|
*/
|
|
@@ -638,7 +611,8 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
638
611
|
* @returns Block number of latest L2 Block we've synced with.
|
|
639
612
|
*/
|
|
640
613
|
public async getSyncedLatestBlockNum(): Promise<BlockNumber> {
|
|
641
|
-
|
|
614
|
+
const tips = await this.l2Tips.getL2Tips();
|
|
615
|
+
return tips.proposed.number;
|
|
642
616
|
}
|
|
643
617
|
|
|
644
618
|
/**
|
|
@@ -646,11 +620,13 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
646
620
|
* @returns Block number of latest proven L2 Block we've synced with.
|
|
647
621
|
*/
|
|
648
622
|
public async getSyncedProvenBlockNum(): Promise<BlockNumber> {
|
|
649
|
-
|
|
623
|
+
const tips = await this.l2Tips.getL2Tips();
|
|
624
|
+
return tips.proven.block.number;
|
|
650
625
|
}
|
|
651
626
|
|
|
652
627
|
public async getSyncedFinalizedBlockNum(): Promise<BlockNumber> {
|
|
653
|
-
|
|
628
|
+
const tips = await this.l2Tips.getL2Tips();
|
|
629
|
+
return tips.finalized.block.number;
|
|
654
630
|
}
|
|
655
631
|
|
|
656
632
|
/** Returns latest L2 slot for which we have seen an L2 block. */
|
|
@@ -705,20 +681,8 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
705
681
|
await this.startCollectingMissingTxs(blocks);
|
|
706
682
|
|
|
707
683
|
const lastBlock = blocks.at(-1)!;
|
|
708
|
-
|
|
709
|
-
await Promise.all(
|
|
710
|
-
blocks.map(async block =>
|
|
711
|
-
this.setBlockHash({
|
|
712
|
-
number: block.number,
|
|
713
|
-
hash: await block.hash().then(h => h.toString()),
|
|
714
|
-
}),
|
|
715
|
-
),
|
|
716
|
-
);
|
|
717
|
-
|
|
718
|
-
await this.synchedLatestBlockNumber.set(lastBlock.number);
|
|
719
684
|
await this.synchedLatestSlot.set(BigInt(lastBlock.header.getSlot()));
|
|
720
685
|
this.log.verbose(`Synched to latest block ${lastBlock.number}`);
|
|
721
|
-
await this.startServiceIfSynched();
|
|
722
686
|
}
|
|
723
687
|
|
|
724
688
|
/** Request txs for unproven blocks so the prover node has more chances to get them. */
|
|
@@ -769,12 +733,9 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
769
733
|
await this.txPool.deleteTxs(txHashes, { permanently: true });
|
|
770
734
|
await this.txPool.cleanupDeletedMinedTxs(lastBlockNum);
|
|
771
735
|
|
|
772
|
-
await this.attestationPool.
|
|
736
|
+
await this.attestationPool.deleteCheckpointAttestationsOlderThan(lastBlockSlot);
|
|
773
737
|
|
|
774
|
-
await this.synchedFinalizedBlockNumber.set(lastBlockNum);
|
|
775
738
|
this.log.debug(`Synched to finalized block ${lastBlockNum} at slot ${lastBlockSlot}`);
|
|
776
|
-
|
|
777
|
-
await this.startServiceIfSynched();
|
|
778
739
|
}
|
|
779
740
|
|
|
780
741
|
/**
|
|
@@ -822,18 +783,16 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
822
783
|
} else {
|
|
823
784
|
await this.txPool.markMinedAsPending(minedTxsFromReorg, latestBlock);
|
|
824
785
|
}
|
|
825
|
-
|
|
826
|
-
await this.synchedLatestBlockNumber.set(latestBlock);
|
|
827
|
-
// no need to update block hashes, as they will be updated as new blocks are added
|
|
828
786
|
}
|
|
829
787
|
|
|
830
788
|
private async startServiceIfSynched() {
|
|
831
789
|
if (this.currentState !== P2PClientState.SYNCHING) {
|
|
832
790
|
return;
|
|
833
791
|
}
|
|
834
|
-
const
|
|
835
|
-
const
|
|
836
|
-
const
|
|
792
|
+
const tips = await this.l2Tips.getL2Tips();
|
|
793
|
+
const syncedFinalizedBlock = tips.finalized.block.number;
|
|
794
|
+
const syncedProvenBlock = tips.proven.block.number;
|
|
795
|
+
const syncedLatestBlock = tips.proposed.number;
|
|
837
796
|
|
|
838
797
|
if (
|
|
839
798
|
syncedLatestBlock >= this.latestBlockNumberAtStart &&
|