@aztec/aztec-node 4.0.0-nightly.20250907 → 4.0.0-nightly.20260108
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/aztec-node/config.d.ts +9 -4
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +22 -20
- package/dest/aztec-node/node_metrics.d.ts +5 -1
- package/dest/aztec-node/node_metrics.d.ts.map +1 -1
- package/dest/aztec-node/node_metrics.js +21 -0
- package/dest/aztec-node/server.d.ts +70 -51
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +589 -98
- package/dest/bin/index.d.ts +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/sentinel/config.d.ts +2 -1
- package/dest/sentinel/config.d.ts.map +1 -1
- package/dest/sentinel/config.js +16 -0
- package/dest/sentinel/factory.d.ts +1 -1
- package/dest/sentinel/factory.d.ts.map +1 -1
- package/dest/sentinel/factory.js +3 -1
- package/dest/sentinel/index.d.ts +1 -1
- package/dest/sentinel/sentinel.d.ts +20 -19
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +33 -21
- package/dest/sentinel/store.d.ts +8 -5
- package/dest/sentinel/store.d.ts.map +1 -1
- package/dest/sentinel/store.js +8 -4
- package/dest/test/index.d.ts +1 -1
- package/package.json +29 -28
- package/src/aztec-node/config.ts +36 -41
- package/src/aztec-node/node_metrics.ts +28 -0
- package/src/aztec-node/server.ts +273 -139
- package/src/sentinel/config.ts +18 -0
- package/src/sentinel/factory.ts +5 -1
- package/src/sentinel/sentinel.ts +60 -40
- package/src/sentinel/store.ts +18 -13
package/src/aztec-node/server.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Archiver, createArchiver } from '@aztec/archiver';
|
|
2
2
|
import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
|
|
3
|
-
import { type
|
|
3
|
+
import { type BlobClientInterface, createBlobClientWithFileStores } from '@aztec/blob-client/client';
|
|
4
4
|
import {
|
|
5
5
|
ARCHIVE_HEIGHT,
|
|
6
6
|
INITIAL_L2_BLOCK_NUM,
|
|
@@ -10,26 +10,25 @@ import {
|
|
|
10
10
|
type PUBLIC_DATA_TREE_HEIGHT,
|
|
11
11
|
} from '@aztec/constants';
|
|
12
12
|
import { EpochCache, type EpochCacheInterface } from '@aztec/epoch-cache';
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
createEthereumChain,
|
|
19
|
-
getPublicClient,
|
|
20
|
-
} from '@aztec/ethereum';
|
|
21
|
-
import { createL1TxUtilsWithBlobsFromEthSigner } from '@aztec/ethereum/l1-tx-utils-with-blobs';
|
|
13
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
14
|
+
import { getPublicClient } from '@aztec/ethereum/client';
|
|
15
|
+
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
16
|
+
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
17
|
+
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
22
18
|
import { compactArray, pick } from '@aztec/foundation/collection';
|
|
19
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
23
20
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
24
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
25
21
|
import { BadRequestError } from '@aztec/foundation/json-rpc';
|
|
26
22
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
27
|
-
import { SerialQueue } from '@aztec/foundation/queue';
|
|
28
23
|
import { count } from '@aztec/foundation/string';
|
|
29
24
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
30
25
|
import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees';
|
|
31
26
|
import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
|
|
32
27
|
import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
|
|
28
|
+
import {
|
|
29
|
+
createForwarderL1TxUtilsFromEthSigner,
|
|
30
|
+
createL1TxUtilsWithBlobsFromEthSigner,
|
|
31
|
+
} from '@aztec/node-lib/factories';
|
|
33
32
|
import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
34
33
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
35
34
|
import {
|
|
@@ -39,6 +38,7 @@ import {
|
|
|
39
38
|
type SequencerPublisher,
|
|
40
39
|
createValidatorForAcceptingTxs,
|
|
41
40
|
} from '@aztec/sequencer-client';
|
|
41
|
+
import { CheckpointsBuilder } from '@aztec/sequencer-client';
|
|
42
42
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
43
43
|
import {
|
|
44
44
|
AttestationsBlockWatcher,
|
|
@@ -47,12 +47,13 @@ import {
|
|
|
47
47
|
type Watcher,
|
|
48
48
|
createSlasher,
|
|
49
49
|
} from '@aztec/slasher';
|
|
50
|
+
import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
50
51
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
51
52
|
import {
|
|
52
|
-
type
|
|
53
|
+
type BlockParameter,
|
|
54
|
+
type DataInBlock,
|
|
53
55
|
type L2Block,
|
|
54
56
|
L2BlockHash,
|
|
55
|
-
type L2BlockNumber,
|
|
56
57
|
type L2BlockSource,
|
|
57
58
|
type PublishedL2Block,
|
|
58
59
|
} from '@aztec/stdlib/block';
|
|
@@ -63,7 +64,7 @@ import type {
|
|
|
63
64
|
NodeInfo,
|
|
64
65
|
ProtocolContractAddresses,
|
|
65
66
|
} from '@aztec/stdlib/contract';
|
|
66
|
-
import
|
|
67
|
+
import { GasFees } from '@aztec/stdlib/gas';
|
|
67
68
|
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
68
69
|
import {
|
|
69
70
|
type AztecNode,
|
|
@@ -74,6 +75,7 @@ import {
|
|
|
74
75
|
type GetPublicLogsResponse,
|
|
75
76
|
} from '@aztec/stdlib/interfaces/client';
|
|
76
77
|
import {
|
|
78
|
+
type AllowedElement,
|
|
77
79
|
type ClientProtocolCircuitVerifier,
|
|
78
80
|
type L2LogsSource,
|
|
79
81
|
type Service,
|
|
@@ -81,8 +83,8 @@ import {
|
|
|
81
83
|
type WorldStateSynchronizer,
|
|
82
84
|
tryStop,
|
|
83
85
|
} from '@aztec/stdlib/interfaces/server';
|
|
84
|
-
import type { LogFilter,
|
|
85
|
-
import type
|
|
86
|
+
import type { LogFilter, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
87
|
+
import { InboxLeaf, type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
86
88
|
import { P2PClientType } from '@aztec/stdlib/p2p';
|
|
87
89
|
import type { Offense, SlashPayloadRound } from '@aztec/stdlib/slashing';
|
|
88
90
|
import type { NullifierLeafPreimage, PublicDataTreeLeaf, PublicDataTreeLeafPreimage } from '@aztec/stdlib/trees';
|
|
@@ -108,7 +110,12 @@ import {
|
|
|
108
110
|
getTelemetryClient,
|
|
109
111
|
trackSpan,
|
|
110
112
|
} from '@aztec/telemetry-client';
|
|
111
|
-
import {
|
|
113
|
+
import {
|
|
114
|
+
NodeKeystoreAdapter,
|
|
115
|
+
ValidatorClient,
|
|
116
|
+
createBlockProposalHandler,
|
|
117
|
+
createValidatorClient,
|
|
118
|
+
} from '@aztec/validator-client';
|
|
112
119
|
import { createWorldStateSynchronizer } from '@aztec/world-state';
|
|
113
120
|
|
|
114
121
|
import { createPublicClient, fallback, http } from 'viem';
|
|
@@ -127,9 +134,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
127
134
|
// Prevent two snapshot operations to happen simultaneously
|
|
128
135
|
private isUploadingSnapshot = false;
|
|
129
136
|
|
|
130
|
-
// Serial queue to ensure that we only send one tx at a time
|
|
131
|
-
private txQueue: SerialQueue = new SerialQueue();
|
|
132
|
-
|
|
133
137
|
public readonly tracer: Tracer;
|
|
134
138
|
|
|
135
139
|
constructor(
|
|
@@ -152,10 +156,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
152
156
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
153
157
|
private telemetry: TelemetryClient = getTelemetryClient(),
|
|
154
158
|
private log = createLogger('node'),
|
|
159
|
+
private blobClient?: BlobClientInterface,
|
|
155
160
|
) {
|
|
156
161
|
this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
|
|
157
162
|
this.tracer = telemetry.getTracer('AztecNodeService');
|
|
158
|
-
this.txQueue.start();
|
|
159
163
|
|
|
160
164
|
this.log.info(`Aztec Node version: ${this.packageVersion}`);
|
|
161
165
|
this.log.info(`Aztec Node started on chain 0x${l1ChainId.toString(16)}`, config.l1Contracts);
|
|
@@ -182,7 +186,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
182
186
|
logger?: Logger;
|
|
183
187
|
publisher?: SequencerPublisher;
|
|
184
188
|
dateProvider?: DateProvider;
|
|
185
|
-
blobSinkClient?: BlobSinkClientInterface;
|
|
186
189
|
p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
|
|
187
190
|
} = {},
|
|
188
191
|
options: {
|
|
@@ -195,8 +198,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
195
198
|
const packageVersion = getPackageVersion() ?? '';
|
|
196
199
|
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
197
200
|
const dateProvider = deps.dateProvider ?? new DateProvider();
|
|
198
|
-
const blobSinkClient =
|
|
199
|
-
deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('node:blob-sink:client') });
|
|
200
201
|
const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
201
202
|
|
|
202
203
|
// Build a key store from file if given or from environment otherwise
|
|
@@ -212,6 +213,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
212
213
|
}
|
|
213
214
|
}
|
|
214
215
|
|
|
216
|
+
await keyStoreManager?.validateSigners();
|
|
217
|
+
|
|
215
218
|
// If we are a validator, verify our configuration before doing too much more.
|
|
216
219
|
if (!config.disableValidator) {
|
|
217
220
|
if (keyStoreManager === undefined) {
|
|
@@ -222,7 +225,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
222
225
|
'KEY STORE CREATED FROM ENVIRONMENT, IT IS RECOMMENDED TO USE A FILE-BASED KEY STORE IN PRODUCTION ENVIRONMENTS',
|
|
223
226
|
);
|
|
224
227
|
}
|
|
225
|
-
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager);
|
|
228
|
+
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager, log);
|
|
226
229
|
}
|
|
227
230
|
|
|
228
231
|
// validate that the actual chain id matches that specified in configuration
|
|
@@ -234,7 +237,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
234
237
|
|
|
235
238
|
const publicClient = createPublicClient({
|
|
236
239
|
chain: ethereumChain.chainInfo,
|
|
237
|
-
transport: fallback(config.l1RpcUrls.map((url: string) => http(url))),
|
|
240
|
+
transport: fallback(config.l1RpcUrls.map((url: string) => http(url, { batch: false }))),
|
|
238
241
|
pollingInterval: config.viemPollingIntervalMS,
|
|
239
242
|
});
|
|
240
243
|
|
|
@@ -262,6 +265,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
262
265
|
);
|
|
263
266
|
}
|
|
264
267
|
|
|
268
|
+
const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
|
|
269
|
+
|
|
265
270
|
// attempt snapshot sync if possible
|
|
266
271
|
await trySnapshotSync(config, log);
|
|
267
272
|
|
|
@@ -269,8 +274,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
269
274
|
|
|
270
275
|
const archiver = await createArchiver(
|
|
271
276
|
config,
|
|
272
|
-
{
|
|
273
|
-
{ blockUntilSync:
|
|
277
|
+
{ blobClient, epochCache, telemetry, dateProvider },
|
|
278
|
+
{ blockUntilSync: !config.skipArchiverInitialSync },
|
|
274
279
|
);
|
|
275
280
|
|
|
276
281
|
// now create the merkle trees and the world state synchronizer
|
|
@@ -280,7 +285,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
280
285
|
options.prefilledPublicData,
|
|
281
286
|
telemetry,
|
|
282
287
|
);
|
|
283
|
-
const circuitVerifier =
|
|
288
|
+
const circuitVerifier =
|
|
289
|
+
config.realProofs || config.debugForceTxProofVerification
|
|
290
|
+
? await BBCircuitVerifier.new(config)
|
|
291
|
+
: new TestCircuitVerifier(config.proverTestVerificationDelayMs);
|
|
284
292
|
if (!config.realProofs) {
|
|
285
293
|
log.warn(`Aztec node is accepting fake proofs`);
|
|
286
294
|
}
|
|
@@ -300,12 +308,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
300
308
|
deps.p2pClientDeps,
|
|
301
309
|
);
|
|
302
310
|
|
|
303
|
-
//
|
|
304
|
-
await worldStateSynchronizer.start();
|
|
305
|
-
|
|
306
|
-
// Start p2p. Note that it depends on world state to be running.
|
|
307
|
-
await p2pClient.start();
|
|
308
|
-
|
|
311
|
+
// We should really not be modifying the config object
|
|
309
312
|
config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
310
313
|
|
|
311
314
|
const blockBuilder = new BlockBuilder(
|
|
@@ -316,17 +319,58 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
316
319
|
telemetry,
|
|
317
320
|
);
|
|
318
321
|
|
|
322
|
+
// We'll accumulate sentinel watchers here
|
|
319
323
|
const watchers: Watcher[] = [];
|
|
320
324
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
325
|
+
// Create validator client if required
|
|
326
|
+
const validatorClient = createValidatorClient(config, {
|
|
327
|
+
p2pClient,
|
|
328
|
+
telemetry,
|
|
329
|
+
dateProvider,
|
|
330
|
+
epochCache,
|
|
331
|
+
blockBuilder,
|
|
332
|
+
blockSource: archiver,
|
|
333
|
+
l1ToL2MessageSource: archiver,
|
|
334
|
+
keyStoreManager,
|
|
335
|
+
blobClient,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
// If we have a validator client, register it as a source of offenses for the slasher,
|
|
339
|
+
// and have it register callbacks on the p2p client *before* we start it, otherwise messages
|
|
340
|
+
// like attestations or auths will fail.
|
|
341
|
+
if (validatorClient) {
|
|
342
|
+
watchers.push(validatorClient);
|
|
343
|
+
if (!options.dontStartSequencer) {
|
|
344
|
+
await validatorClient.registerHandlers();
|
|
327
345
|
}
|
|
328
346
|
}
|
|
329
347
|
|
|
348
|
+
// If there's no validator client but alwaysReexecuteBlockProposals is enabled,
|
|
349
|
+
// create a BlockProposalHandler to reexecute block proposals for monitoring
|
|
350
|
+
if (!validatorClient && config.alwaysReexecuteBlockProposals) {
|
|
351
|
+
log.info('Setting up block proposal reexecution for monitoring');
|
|
352
|
+
createBlockProposalHandler(config, {
|
|
353
|
+
blockBuilder,
|
|
354
|
+
epochCache,
|
|
355
|
+
blockSource: archiver,
|
|
356
|
+
l1ToL2MessageSource: archiver,
|
|
357
|
+
p2pClient,
|
|
358
|
+
dateProvider,
|
|
359
|
+
telemetry,
|
|
360
|
+
}).registerForReexecution(p2pClient);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Start world state and wait for it to sync to the archiver.
|
|
364
|
+
await worldStateSynchronizer.start();
|
|
365
|
+
|
|
366
|
+
// Start p2p. Note that it depends on world state to be running.
|
|
367
|
+
await p2pClient.start();
|
|
368
|
+
|
|
369
|
+
const validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, config);
|
|
370
|
+
if (validatorsSentinel && config.slashInactivityPenalty > 0n) {
|
|
371
|
+
watchers.push(validatorsSentinel);
|
|
372
|
+
}
|
|
373
|
+
|
|
330
374
|
let epochPruneWatcher: EpochPruneWatcher | undefined;
|
|
331
375
|
if (config.slashPrunePenalty > 0n || config.slashDataWithholdingPenalty > 0n) {
|
|
332
376
|
epochPruneWatcher = new EpochPruneWatcher(
|
|
@@ -337,7 +381,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
337
381
|
blockBuilder,
|
|
338
382
|
config,
|
|
339
383
|
);
|
|
340
|
-
await epochPruneWatcher.start();
|
|
341
384
|
watchers.push(epochPruneWatcher);
|
|
342
385
|
}
|
|
343
386
|
|
|
@@ -345,32 +388,25 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
345
388
|
let attestationsBlockWatcher: AttestationsBlockWatcher | undefined;
|
|
346
389
|
if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashAttestDescendantOfInvalidPenalty > 0n) {
|
|
347
390
|
attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config);
|
|
348
|
-
await attestationsBlockWatcher.start();
|
|
349
391
|
watchers.push(attestationsBlockWatcher);
|
|
350
392
|
}
|
|
351
393
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (validatorClient) {
|
|
364
|
-
watchers.push(validatorClient);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
log.verbose(`All Aztec Node subsystems synced`);
|
|
394
|
+
// Start p2p-related services once the archiver has completed sync
|
|
395
|
+
void archiver
|
|
396
|
+
.waitForInitialSync()
|
|
397
|
+
.then(async () => {
|
|
398
|
+
await p2pClient.start();
|
|
399
|
+
await validatorsSentinel?.start();
|
|
400
|
+
await epochPruneWatcher?.start();
|
|
401
|
+
await attestationsBlockWatcher?.start();
|
|
402
|
+
log.info(`All p2p services started`);
|
|
403
|
+
})
|
|
404
|
+
.catch(err => log.error('Failed to start p2p services after archiver sync', err));
|
|
368
405
|
|
|
369
406
|
// Validator enabled, create/start relevant service
|
|
370
407
|
let sequencer: SequencerClient | undefined;
|
|
371
408
|
let slasherClient: SlasherClientInterface | undefined;
|
|
372
|
-
|
|
373
|
-
if (!config.disableValidator) {
|
|
409
|
+
if (!config.disableValidator && validatorClient) {
|
|
374
410
|
// We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher
|
|
375
411
|
// as they are executed when the node is selected as proposer.
|
|
376
412
|
const validatorAddresses = keyStoreManager
|
|
@@ -389,13 +425,30 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
389
425
|
);
|
|
390
426
|
await slasherClient.start();
|
|
391
427
|
|
|
392
|
-
const l1TxUtils =
|
|
393
|
-
|
|
394
|
-
|
|
428
|
+
const l1TxUtils = config.publisherForwarderAddress
|
|
429
|
+
? await createForwarderL1TxUtilsFromEthSigner(
|
|
430
|
+
publicClient,
|
|
431
|
+
keyStoreManager!.createAllValidatorPublisherSigners(),
|
|
432
|
+
config.publisherForwarderAddress,
|
|
433
|
+
{ ...config, scope: 'sequencer' },
|
|
434
|
+
{ telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
|
|
435
|
+
)
|
|
436
|
+
: await createL1TxUtilsWithBlobsFromEthSigner(
|
|
437
|
+
publicClient,
|
|
438
|
+
keyStoreManager!.createAllValidatorPublisherSigners(),
|
|
439
|
+
{ ...config, scope: 'sequencer' },
|
|
440
|
+
{ telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
// Create and start the sequencer client
|
|
444
|
+
const checkpointsBuilder = new CheckpointsBuilder(
|
|
445
|
+
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
446
|
+
archiver,
|
|
447
|
+
dateProvider,
|
|
448
|
+
telemetry,
|
|
449
|
+
);
|
|
395
450
|
|
|
396
451
|
sequencer = await SequencerClient.new(config, {
|
|
397
|
-
// if deps were provided, they should override the defaults,
|
|
398
|
-
// or things that we created in this function
|
|
399
452
|
...deps,
|
|
400
453
|
epochCache,
|
|
401
454
|
l1TxUtils,
|
|
@@ -403,12 +456,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
403
456
|
p2pClient,
|
|
404
457
|
worldStateSynchronizer,
|
|
405
458
|
slasherClient,
|
|
406
|
-
|
|
459
|
+
checkpointsBuilder,
|
|
407
460
|
l2BlockSource: archiver,
|
|
408
461
|
l1ToL2MessageSource: archiver,
|
|
409
462
|
telemetry,
|
|
410
463
|
dateProvider,
|
|
411
|
-
|
|
464
|
+
blobClient,
|
|
412
465
|
nodeKeyStore: keyStoreManager!,
|
|
413
466
|
});
|
|
414
467
|
}
|
|
@@ -416,8 +469,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
416
469
|
if (!options.dontStartSequencer && sequencer) {
|
|
417
470
|
await sequencer.start();
|
|
418
471
|
log.verbose(`Sequencer started`);
|
|
472
|
+
} else if (sequencer) {
|
|
473
|
+
log.warn(`Sequencer created but not started`);
|
|
419
474
|
}
|
|
420
475
|
|
|
476
|
+
const globalVariableBuilder = new GlobalVariableBuilder({
|
|
477
|
+
...config,
|
|
478
|
+
rollupVersion: BigInt(config.rollupVersion),
|
|
479
|
+
l1GenesisTime,
|
|
480
|
+
slotDuration: Number(slotDuration),
|
|
481
|
+
});
|
|
482
|
+
|
|
421
483
|
return new AztecNodeService(
|
|
422
484
|
config,
|
|
423
485
|
p2pClient,
|
|
@@ -432,12 +494,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
432
494
|
epochPruneWatcher,
|
|
433
495
|
ethereumChain.chainInfo.id,
|
|
434
496
|
config.rollupVersion,
|
|
435
|
-
|
|
497
|
+
globalVariableBuilder,
|
|
436
498
|
epochCache,
|
|
437
499
|
packageVersion,
|
|
438
500
|
proofVerifier,
|
|
439
501
|
telemetry,
|
|
440
502
|
log,
|
|
503
|
+
blobClient,
|
|
441
504
|
);
|
|
442
505
|
}
|
|
443
506
|
|
|
@@ -473,6 +536,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
473
536
|
return Promise.resolve(this.p2pClient.getEnr()?.encodeTxt());
|
|
474
537
|
}
|
|
475
538
|
|
|
539
|
+
public async getAllowedPublicSetup(): Promise<AllowedElement[]> {
|
|
540
|
+
return this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
541
|
+
}
|
|
542
|
+
|
|
476
543
|
/**
|
|
477
544
|
* Method to determine if the node is ready to accept transactions.
|
|
478
545
|
* @returns - Flag indicating the readiness for tx submission.
|
|
@@ -508,8 +575,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
508
575
|
* @param number - The block number being requested.
|
|
509
576
|
* @returns The requested block.
|
|
510
577
|
*/
|
|
511
|
-
public async getBlock(number:
|
|
512
|
-
|
|
578
|
+
public async getBlock(number: BlockParameter): Promise<L2Block | undefined> {
|
|
579
|
+
const blockNumber = number === 'latest' ? await this.getBlockNumber() : (number as BlockNumber);
|
|
580
|
+
return await this.blockSource.getBlock(blockNumber);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Get a block specified by its hash.
|
|
585
|
+
* @param blockHash - The block hash being requested.
|
|
586
|
+
* @returns The requested block.
|
|
587
|
+
*/
|
|
588
|
+
public async getBlockByHash(blockHash: Fr): Promise<L2Block | undefined> {
|
|
589
|
+
const publishedBlock = await this.blockSource.getPublishedBlockByHash(blockHash);
|
|
590
|
+
return publishedBlock?.block;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Get a block specified by its archive root.
|
|
595
|
+
* @param archive - The archive root being requested.
|
|
596
|
+
* @returns The requested block.
|
|
597
|
+
*/
|
|
598
|
+
public async getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
|
|
599
|
+
const publishedBlock = await this.blockSource.getPublishedBlockByArchive(archive);
|
|
600
|
+
return publishedBlock?.block;
|
|
513
601
|
}
|
|
514
602
|
|
|
515
603
|
/**
|
|
@@ -518,31 +606,39 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
518
606
|
* @param limit - The maximum number of blocks to obtain.
|
|
519
607
|
* @returns The blocks requested.
|
|
520
608
|
*/
|
|
521
|
-
public async getBlocks(from:
|
|
609
|
+
public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
522
610
|
return (await this.blockSource.getBlocks(from, limit)) ?? [];
|
|
523
611
|
}
|
|
524
612
|
|
|
525
|
-
public async getPublishedBlocks(from:
|
|
613
|
+
public async getPublishedBlocks(from: BlockNumber, limit: number): Promise<PublishedL2Block[]> {
|
|
526
614
|
return (await this.blockSource.getPublishedBlocks(from, limit)) ?? [];
|
|
527
615
|
}
|
|
528
616
|
|
|
529
617
|
/**
|
|
530
|
-
* Method to fetch the current
|
|
531
|
-
* @returns The current
|
|
618
|
+
* Method to fetch the current min L2 fees.
|
|
619
|
+
* @returns The current min L2 fees.
|
|
532
620
|
*/
|
|
533
|
-
public async
|
|
534
|
-
return await this.globalVariableBuilder.
|
|
621
|
+
public async getCurrentMinFees(): Promise<GasFees> {
|
|
622
|
+
return await this.globalVariableBuilder.getCurrentMinFees();
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
public async getMaxPriorityFees(): Promise<GasFees> {
|
|
626
|
+
for await (const tx of this.p2pClient.iteratePendingTxs()) {
|
|
627
|
+
return tx.getGasSettings().maxPriorityFeesPerGas;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
return GasFees.from({ feePerDaGas: 0n, feePerL2Gas: 0n });
|
|
535
631
|
}
|
|
536
632
|
|
|
537
633
|
/**
|
|
538
634
|
* Method to fetch the latest block number synchronized by the node.
|
|
539
635
|
* @returns The block number.
|
|
540
636
|
*/
|
|
541
|
-
public async getBlockNumber(): Promise<
|
|
637
|
+
public async getBlockNumber(): Promise<BlockNumber> {
|
|
542
638
|
return await this.blockSource.getBlockNumber();
|
|
543
639
|
}
|
|
544
640
|
|
|
545
|
-
public async getProvenBlockNumber(): Promise<
|
|
641
|
+
public async getProvenBlockNumber(): Promise<BlockNumber> {
|
|
546
642
|
return await this.blockSource.getProvenBlockNumber();
|
|
547
643
|
}
|
|
548
644
|
|
|
@@ -578,25 +674,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
578
674
|
return this.contractDataSource.getContract(address);
|
|
579
675
|
}
|
|
580
676
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
* @param from - The block number from which to begin retrieving logs.
|
|
584
|
-
* @param limit - The maximum number of blocks to retrieve logs from.
|
|
585
|
-
* @returns An array of private logs from the specified range of blocks.
|
|
586
|
-
*/
|
|
587
|
-
public getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]> {
|
|
588
|
-
return this.logsSource.getPrivateLogs(from, limit);
|
|
677
|
+
public getPrivateLogsByTags(tags: SiloedTag[]): Promise<TxScopedL2Log[][]> {
|
|
678
|
+
return this.logsSource.getPrivateLogsByTags(tags);
|
|
589
679
|
}
|
|
590
680
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
* @param tags - The tags to filter the logs by.
|
|
594
|
-
* @param logsPerTag - The maximum number of logs to return for each tag. By default no limit is set
|
|
595
|
-
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
|
|
596
|
-
* that tag.
|
|
597
|
-
*/
|
|
598
|
-
public getLogsByTags(tags: Fr[], logsPerTag?: number): Promise<TxScopedL2Log[][]> {
|
|
599
|
-
return this.logsSource.getLogsByTags(tags, logsPerTag);
|
|
681
|
+
public getPublicLogsByTagsFromContract(contractAddress: AztecAddress, tags: Tag[]): Promise<TxScopedL2Log[][]> {
|
|
682
|
+
return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags);
|
|
600
683
|
}
|
|
601
684
|
|
|
602
685
|
/**
|
|
@@ -622,7 +705,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
622
705
|
* @param tx - The transaction to be submitted.
|
|
623
706
|
*/
|
|
624
707
|
public async sendTx(tx: Tx) {
|
|
625
|
-
await this
|
|
708
|
+
await this.#sendTx(tx);
|
|
626
709
|
}
|
|
627
710
|
|
|
628
711
|
async #sendTx(tx: Tx) {
|
|
@@ -669,7 +752,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
669
752
|
*/
|
|
670
753
|
public async stop() {
|
|
671
754
|
this.log.info(`Stopping Aztec Node`);
|
|
672
|
-
await this.txQueue.end();
|
|
673
755
|
await tryStop(this.validatorsSentinel);
|
|
674
756
|
await tryStop(this.epochPruneWatcher);
|
|
675
757
|
await tryStop(this.slasherClient);
|
|
@@ -678,10 +760,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
678
760
|
await tryStop(this.p2pClient);
|
|
679
761
|
await tryStop(this.worldStateSynchronizer);
|
|
680
762
|
await tryStop(this.blockSource);
|
|
763
|
+
await tryStop(this.blobClient);
|
|
681
764
|
await tryStop(this.telemetry);
|
|
682
765
|
this.log.info(`Stopped Aztec Node`);
|
|
683
766
|
}
|
|
684
767
|
|
|
768
|
+
/**
|
|
769
|
+
* Returns the blob client used by this node.
|
|
770
|
+
* @internal - Exposed for testing purposes only.
|
|
771
|
+
*/
|
|
772
|
+
public getBlobClient(): BlobClientInterface | undefined {
|
|
773
|
+
return this.blobClient;
|
|
774
|
+
}
|
|
775
|
+
|
|
685
776
|
/**
|
|
686
777
|
* Method to retrieve pending txs.
|
|
687
778
|
* @param limit - The number of items to returns
|
|
@@ -723,10 +814,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
723
814
|
* @returns The indices of leaves and the block metadata of a block in which the leaves were inserted.
|
|
724
815
|
*/
|
|
725
816
|
public async findLeavesIndexes(
|
|
726
|
-
blockNumber:
|
|
817
|
+
blockNumber: BlockParameter,
|
|
727
818
|
treeId: MerkleTreeId,
|
|
728
819
|
leafValues: Fr[],
|
|
729
|
-
): Promise<(
|
|
820
|
+
): Promise<(DataInBlock<bigint> | undefined)[]> {
|
|
730
821
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
731
822
|
const maybeIndices = await committedDb.findLeafIndices(
|
|
732
823
|
treeId,
|
|
@@ -752,7 +843,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
752
843
|
// (note that block number corresponds to the leaf index in the archive tree).
|
|
753
844
|
const blockHashes = await Promise.all(
|
|
754
845
|
uniqueBlockNumbers.map(blockNumber => {
|
|
755
|
-
return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, blockNumber
|
|
846
|
+
return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, BigInt(blockNumber));
|
|
756
847
|
}),
|
|
757
848
|
);
|
|
758
849
|
|
|
@@ -763,7 +854,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
763
854
|
}
|
|
764
855
|
}
|
|
765
856
|
|
|
766
|
-
// Create
|
|
857
|
+
// Create DataInBlock objects by combining indices, blockNumbers and blockHashes and return them.
|
|
767
858
|
return maybeIndices.map((index, i) => {
|
|
768
859
|
if (index === undefined) {
|
|
769
860
|
return undefined;
|
|
@@ -778,7 +869,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
778
869
|
return undefined;
|
|
779
870
|
}
|
|
780
871
|
return {
|
|
781
|
-
l2BlockNumber: Number(blockNumber),
|
|
872
|
+
l2BlockNumber: BlockNumber(Number(blockNumber)),
|
|
782
873
|
l2BlockHash: L2BlockHash.fromField(blockHash),
|
|
783
874
|
data: index,
|
|
784
875
|
};
|
|
@@ -792,7 +883,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
792
883
|
* @returns The sibling path for the leaf index.
|
|
793
884
|
*/
|
|
794
885
|
public async getNullifierSiblingPath(
|
|
795
|
-
blockNumber:
|
|
886
|
+
blockNumber: BlockParameter,
|
|
796
887
|
leafIndex: bigint,
|
|
797
888
|
): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
|
|
798
889
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -806,7 +897,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
806
897
|
* @returns The sibling path for the leaf index.
|
|
807
898
|
*/
|
|
808
899
|
public async getNoteHashSiblingPath(
|
|
809
|
-
blockNumber:
|
|
900
|
+
blockNumber: BlockParameter,
|
|
810
901
|
leafIndex: bigint,
|
|
811
902
|
): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
|
|
812
903
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -814,7 +905,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
814
905
|
}
|
|
815
906
|
|
|
816
907
|
public async getArchiveMembershipWitness(
|
|
817
|
-
blockNumber:
|
|
908
|
+
blockNumber: BlockParameter,
|
|
818
909
|
archive: Fr,
|
|
819
910
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
820
911
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -825,7 +916,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
825
916
|
}
|
|
826
917
|
|
|
827
918
|
public async getNoteHashMembershipWitness(
|
|
828
|
-
blockNumber:
|
|
919
|
+
blockNumber: BlockParameter,
|
|
829
920
|
noteHash: Fr,
|
|
830
921
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
831
922
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -845,7 +936,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
845
936
|
* @returns A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found).
|
|
846
937
|
*/
|
|
847
938
|
public async getL1ToL2MessageMembershipWitness(
|
|
848
|
-
blockNumber:
|
|
939
|
+
blockNumber: BlockParameter,
|
|
849
940
|
l1ToL2Message: Fr,
|
|
850
941
|
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
|
|
851
942
|
const db = await this.#getWorldState(blockNumber);
|
|
@@ -858,13 +949,21 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
858
949
|
return [witness.index, witness.path];
|
|
859
950
|
}
|
|
860
951
|
|
|
952
|
+
public async getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<BlockNumber | undefined> {
|
|
953
|
+
const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
|
|
954
|
+
return messageIndex
|
|
955
|
+
? BlockNumber.fromCheckpointNumber(InboxLeaf.checkpointNumberFromIndex(messageIndex))
|
|
956
|
+
: undefined;
|
|
957
|
+
}
|
|
958
|
+
|
|
861
959
|
/**
|
|
862
960
|
* Returns whether an L1 to L2 message is synced by archiver and if it's ready to be included in a block.
|
|
863
961
|
* @param l1ToL2Message - The L1 to L2 message to check.
|
|
864
962
|
* @returns Whether the message is synced and ready to be included in a block.
|
|
865
963
|
*/
|
|
866
964
|
public async isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise<boolean> {
|
|
867
|
-
|
|
965
|
+
const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
|
|
966
|
+
return messageIndex !== undefined;
|
|
868
967
|
}
|
|
869
968
|
|
|
870
969
|
/**
|
|
@@ -872,8 +971,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
872
971
|
* @param blockNumber - The block number at which to get the data.
|
|
873
972
|
* @returns The L2 to L1 messages (undefined if the block number is not found).
|
|
874
973
|
*/
|
|
875
|
-
public async getL2ToL1Messages(blockNumber:
|
|
876
|
-
const block = await this.blockSource.getBlock(
|
|
974
|
+
public async getL2ToL1Messages(blockNumber: BlockParameter): Promise<Fr[][] | undefined> {
|
|
975
|
+
const block = await this.blockSource.getBlock(
|
|
976
|
+
blockNumber === 'latest' ? await this.getBlockNumber() : (blockNumber as BlockNumber),
|
|
977
|
+
);
|
|
877
978
|
return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
|
|
878
979
|
}
|
|
879
980
|
|
|
@@ -884,7 +985,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
884
985
|
* @returns The sibling path.
|
|
885
986
|
*/
|
|
886
987
|
public async getArchiveSiblingPath(
|
|
887
|
-
blockNumber:
|
|
988
|
+
blockNumber: BlockParameter,
|
|
888
989
|
leafIndex: bigint,
|
|
889
990
|
): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
|
|
890
991
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -898,7 +999,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
898
999
|
* @returns The sibling path.
|
|
899
1000
|
*/
|
|
900
1001
|
public async getPublicDataSiblingPath(
|
|
901
|
-
blockNumber:
|
|
1002
|
+
blockNumber: BlockParameter,
|
|
902
1003
|
leafIndex: bigint,
|
|
903
1004
|
): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
|
|
904
1005
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -912,7 +1013,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
912
1013
|
* @returns The nullifier membership witness (if found).
|
|
913
1014
|
*/
|
|
914
1015
|
public async getNullifierMembershipWitness(
|
|
915
|
-
blockNumber:
|
|
1016
|
+
blockNumber: BlockParameter,
|
|
916
1017
|
nullifier: Fr,
|
|
917
1018
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
918
1019
|
const db = await this.#getWorldState(blockNumber);
|
|
@@ -945,7 +1046,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
945
1046
|
* TODO: This is a confusing behavior and we should eventually address that.
|
|
946
1047
|
*/
|
|
947
1048
|
public async getLowNullifierMembershipWitness(
|
|
948
|
-
blockNumber:
|
|
1049
|
+
blockNumber: BlockParameter,
|
|
949
1050
|
nullifier: Fr,
|
|
950
1051
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
951
1052
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
@@ -963,7 +1064,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
963
1064
|
return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
|
|
964
1065
|
}
|
|
965
1066
|
|
|
966
|
-
async getPublicDataWitness(blockNumber:
|
|
1067
|
+
async getPublicDataWitness(blockNumber: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
967
1068
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
968
1069
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
969
1070
|
if (!lowLeafResult) {
|
|
@@ -989,7 +1090,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
989
1090
|
* @param blockNumber - The block number at which to get the data or 'latest'.
|
|
990
1091
|
* @returns Storage value at the given contract slot.
|
|
991
1092
|
*/
|
|
992
|
-
public async getPublicStorageAt(blockNumber:
|
|
1093
|
+
public async getPublicStorageAt(blockNumber: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
993
1094
|
const committedDb = await this.#getWorldState(blockNumber);
|
|
994
1095
|
const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
|
|
995
1096
|
|
|
@@ -1008,10 +1109,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1008
1109
|
* Returns the currently committed block header, or the initial header if no blocks have been produced.
|
|
1009
1110
|
* @returns The current committed block header.
|
|
1010
1111
|
*/
|
|
1011
|
-
public async getBlockHeader(blockNumber:
|
|
1012
|
-
return blockNumber ===
|
|
1112
|
+
public async getBlockHeader(blockNumber: BlockParameter = 'latest'): Promise<BlockHeader | undefined> {
|
|
1113
|
+
return blockNumber === BlockNumber.ZERO ||
|
|
1114
|
+
(blockNumber === 'latest' && (await this.blockSource.getBlockNumber()) === BlockNumber.ZERO)
|
|
1013
1115
|
? this.worldStateSynchronizer.getCommitted().getInitialHeader()
|
|
1014
|
-
: this.blockSource.getBlockHeader(blockNumber);
|
|
1116
|
+
: this.blockSource.getBlockHeader(blockNumber === 'latest' ? blockNumber : (blockNumber as BlockNumber));
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
/**
|
|
1120
|
+
* Get a block header specified by its hash.
|
|
1121
|
+
* @param blockHash - The block hash being requested.
|
|
1122
|
+
* @returns The requested block header.
|
|
1123
|
+
*/
|
|
1124
|
+
public async getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
|
|
1125
|
+
return await this.blockSource.getBlockHeaderByHash(blockHash);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
/**
|
|
1129
|
+
* Get a block header specified by its archive root.
|
|
1130
|
+
* @param archive - The archive root being requested.
|
|
1131
|
+
* @returns The requested block header.
|
|
1132
|
+
*/
|
|
1133
|
+
public async getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
|
|
1134
|
+
return await this.blockSource.getBlockHeaderByArchive(archive);
|
|
1015
1135
|
}
|
|
1016
1136
|
|
|
1017
1137
|
/**
|
|
@@ -1037,7 +1157,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1037
1157
|
}
|
|
1038
1158
|
|
|
1039
1159
|
const txHash = tx.getTxHash();
|
|
1040
|
-
const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
|
|
1160
|
+
const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
|
|
1041
1161
|
|
|
1042
1162
|
// If sequencer is not initialized, we just set these values to zero for simulation.
|
|
1043
1163
|
const coinbase = EthAddress.ZERO;
|
|
@@ -1062,12 +1182,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1062
1182
|
|
|
1063
1183
|
const merkleTreeFork = await this.worldStateSynchronizer.fork();
|
|
1064
1184
|
try {
|
|
1065
|
-
const
|
|
1066
|
-
merkleTreeFork,
|
|
1067
|
-
newGlobalVariables,
|
|
1185
|
+
const config = PublicSimulatorConfig.from({
|
|
1068
1186
|
skipFeeEnforcement,
|
|
1069
|
-
|
|
1070
|
-
|
|
1187
|
+
collectDebugLogs: true,
|
|
1188
|
+
collectHints: false,
|
|
1189
|
+
collectCallMetadata: true,
|
|
1190
|
+
collectStatistics: false,
|
|
1191
|
+
collectionLimits: CollectionLimitsConfig.from({
|
|
1192
|
+
maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads,
|
|
1193
|
+
}),
|
|
1194
|
+
});
|
|
1195
|
+
const processor = publicProcessorFactory.create(merkleTreeFork, newGlobalVariables, config);
|
|
1071
1196
|
|
|
1072
1197
|
// REFACTOR: Consider merging ProcessReturnValues into ProcessedTx
|
|
1073
1198
|
const [processedTxs, failedTxs, _usedTxs, returns] = await processor.process([tx]);
|
|
@@ -1099,14 +1224,14 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1099
1224
|
|
|
1100
1225
|
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1101
1226
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1102
|
-
const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
|
|
1227
|
+
const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
|
|
1103
1228
|
const validator = createValidatorForAcceptingTxs(db, this.contractDataSource, verifier, {
|
|
1104
1229
|
timestamp: nextSlotTimestamp,
|
|
1105
1230
|
blockNumber,
|
|
1106
1231
|
l1ChainId: this.l1ChainId,
|
|
1107
1232
|
rollupVersion: this.version,
|
|
1108
1233
|
setupAllowList: this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions()),
|
|
1109
|
-
gasFees: await this.
|
|
1234
|
+
gasFees: await this.getCurrentMinFees(),
|
|
1110
1235
|
skipFeeEnforcement,
|
|
1111
1236
|
txsPermitted: !this.config.disableTransactions,
|
|
1112
1237
|
});
|
|
@@ -1125,9 +1250,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1125
1250
|
this.sequencer?.updateConfig(config);
|
|
1126
1251
|
this.slasherClient?.updateConfig(config);
|
|
1127
1252
|
this.validatorsSentinel?.updateConfig(config);
|
|
1128
|
-
// this.blockBuilder.updateConfig(config); // TODO: Spyros has a PR to add the builder to `this`, so we can do this
|
|
1129
1253
|
await this.p2pClient.updateP2PConfig(config);
|
|
1130
|
-
|
|
1254
|
+
const archiver = this.blockSource as Archiver;
|
|
1255
|
+
if ('updateConfig' in archiver) {
|
|
1256
|
+
archiver.updateConfig(config);
|
|
1257
|
+
}
|
|
1131
1258
|
if (newConfig.realProofs !== this.config.realProofs) {
|
|
1132
1259
|
this.proofVerifier = config.realProofs ? await BBCircuitVerifier.new(newConfig) : new TestCircuitVerifier();
|
|
1133
1260
|
}
|
|
@@ -1154,8 +1281,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1154
1281
|
|
|
1155
1282
|
public getValidatorStats(
|
|
1156
1283
|
validatorAddress: EthAddress,
|
|
1157
|
-
fromSlot?:
|
|
1158
|
-
toSlot?:
|
|
1284
|
+
fromSlot?: SlotNumber,
|
|
1285
|
+
toSlot?: SlotNumber,
|
|
1159
1286
|
): Promise<SingleValidatorStats | undefined> {
|
|
1160
1287
|
return this.validatorsSentinel?.getValidatorStats(validatorAddress, fromSlot, toSlot) ?? Promise.resolve(undefined);
|
|
1161
1288
|
}
|
|
@@ -1165,39 +1292,46 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1165
1292
|
// We break support for archiver running remotely to the node
|
|
1166
1293
|
const archiver = this.blockSource as Archiver;
|
|
1167
1294
|
if (!('backupTo' in archiver)) {
|
|
1295
|
+
this.metrics.recordSnapshotError();
|
|
1168
1296
|
throw new Error('Archiver implementation does not support backups. Cannot generate snapshot.');
|
|
1169
1297
|
}
|
|
1170
1298
|
|
|
1171
1299
|
// Test that the archiver has done an initial sync.
|
|
1172
1300
|
if (!archiver.isInitialSyncComplete()) {
|
|
1301
|
+
this.metrics.recordSnapshotError();
|
|
1173
1302
|
throw new Error(`Archiver initial sync not complete. Cannot start snapshot.`);
|
|
1174
1303
|
}
|
|
1175
1304
|
|
|
1176
1305
|
// And it has an L2 block hash
|
|
1177
1306
|
const l2BlockHash = await archiver.getL2Tips().then(tips => tips.latest.hash);
|
|
1178
1307
|
if (!l2BlockHash) {
|
|
1308
|
+
this.metrics.recordSnapshotError();
|
|
1179
1309
|
throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
|
|
1180
1310
|
}
|
|
1181
1311
|
|
|
1182
1312
|
if (this.isUploadingSnapshot) {
|
|
1313
|
+
this.metrics.recordSnapshotError();
|
|
1183
1314
|
throw new Error(`Snapshot upload already in progress. Cannot start another one until complete.`);
|
|
1184
1315
|
}
|
|
1185
1316
|
|
|
1186
1317
|
// Do not wait for the upload to be complete to return to the caller, but flag that an operation is in progress
|
|
1187
1318
|
this.isUploadingSnapshot = true;
|
|
1319
|
+
const timer = new Timer();
|
|
1188
1320
|
void uploadSnapshot(location, this.blockSource as Archiver, this.worldStateSynchronizer, this.config, this.log)
|
|
1189
1321
|
.then(() => {
|
|
1190
1322
|
this.isUploadingSnapshot = false;
|
|
1323
|
+
this.metrics.recordSnapshot(timer.ms());
|
|
1191
1324
|
})
|
|
1192
1325
|
.catch(err => {
|
|
1193
1326
|
this.isUploadingSnapshot = false;
|
|
1327
|
+
this.metrics.recordSnapshotError();
|
|
1194
1328
|
this.log.error(`Error uploading snapshot: ${err}`);
|
|
1195
1329
|
});
|
|
1196
1330
|
|
|
1197
1331
|
return Promise.resolve();
|
|
1198
1332
|
}
|
|
1199
1333
|
|
|
1200
|
-
public async rollbackTo(targetBlock:
|
|
1334
|
+
public async rollbackTo(targetBlock: BlockNumber, force?: boolean): Promise<void> {
|
|
1201
1335
|
const archiver = this.blockSource as Archiver;
|
|
1202
1336
|
if (!('rollbackTo' in archiver)) {
|
|
1203
1337
|
throw new Error('Archiver implementation does not support rollbacks.');
|
|
@@ -1269,12 +1403,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1269
1403
|
* @param blockNumber - The block number at which to get the data.
|
|
1270
1404
|
* @returns An instance of a committed MerkleTreeOperations
|
|
1271
1405
|
*/
|
|
1272
|
-
async #getWorldState(blockNumber:
|
|
1406
|
+
async #getWorldState(blockNumber: BlockParameter) {
|
|
1273
1407
|
if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
|
|
1274
1408
|
throw new Error('Invalid block number to get world state for: ' + blockNumber);
|
|
1275
1409
|
}
|
|
1276
1410
|
|
|
1277
|
-
let blockSyncedTo:
|
|
1411
|
+
let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
|
|
1278
1412
|
try {
|
|
1279
1413
|
// Attempt to sync the world state if necessary
|
|
1280
1414
|
blockSyncedTo = await this.#syncWorldState();
|
|
@@ -1288,7 +1422,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1288
1422
|
return this.worldStateSynchronizer.getCommitted();
|
|
1289
1423
|
} else if (blockNumber <= blockSyncedTo) {
|
|
1290
1424
|
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1291
|
-
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1425
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber as BlockNumber);
|
|
1292
1426
|
} else {
|
|
1293
1427
|
throw new Error(`Block ${blockNumber} not yet synced`);
|
|
1294
1428
|
}
|
|
@@ -1298,8 +1432,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1298
1432
|
* Ensure we fully sync the world state
|
|
1299
1433
|
* @returns A promise that fulfils once the world state is synced
|
|
1300
1434
|
*/
|
|
1301
|
-
async #syncWorldState(): Promise<
|
|
1435
|
+
async #syncWorldState(): Promise<BlockNumber> {
|
|
1302
1436
|
const blockSourceHeight = await this.blockSource.getBlockNumber();
|
|
1303
|
-
return this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
|
|
1437
|
+
return await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
|
|
1304
1438
|
}
|
|
1305
1439
|
}
|