@aztec/aztec-node 0.0.1-commit.d3ec352c → 0.0.1-commit.e6bd8901
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 +5 -2
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +7 -1
- package/dest/aztec-node/node_metrics.d.ts +1 -1
- package/dest/aztec-node/node_metrics.d.ts.map +1 -1
- package/dest/aztec-node/node_metrics.js +5 -16
- package/dest/aztec-node/server.d.ts +46 -114
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +617 -183
- package/dest/sentinel/sentinel.d.ts +5 -4
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +31 -26
- package/dest/sentinel/store.d.ts +2 -2
- package/dest/sentinel/store.d.ts.map +1 -1
- package/package.json +26 -26
- package/src/aztec-node/config.ts +12 -8
- package/src/aztec-node/node_metrics.ts +5 -23
- package/src/aztec-node/server.ts +286 -219
- package/src/sentinel/sentinel.ts +41 -32
package/src/aztec-node/server.ts
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
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
|
-
INITIAL_L2_BLOCK_NUM,
|
|
7
6
|
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
8
7
|
type NOTE_HASH_TREE_HEIGHT,
|
|
9
8
|
type NULLIFIER_TREE_HEIGHT,
|
|
10
9
|
type PUBLIC_DATA_TREE_HEIGHT,
|
|
11
10
|
} from '@aztec/constants';
|
|
12
11
|
import { EpochCache, type EpochCacheInterface } from '@aztec/epoch-cache';
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
getPublicClient,
|
|
19
|
-
} from '@aztec/ethereum';
|
|
20
|
-
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
12
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
13
|
+
import { getPublicClient } from '@aztec/ethereum/client';
|
|
14
|
+
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
15
|
+
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
16
|
+
import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
21
17
|
import { compactArray, pick } from '@aztec/foundation/collection';
|
|
18
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
22
19
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
23
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
24
20
|
import { BadRequestError } from '@aztec/foundation/json-rpc';
|
|
25
21
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
26
22
|
import { count } from '@aztec/foundation/string';
|
|
@@ -28,16 +24,13 @@ import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
|
28
24
|
import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees';
|
|
29
25
|
import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
|
|
30
26
|
import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
|
|
31
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
createForwarderL1TxUtilsFromEthSigner,
|
|
29
|
+
createL1TxUtilsWithBlobsFromEthSigner,
|
|
30
|
+
} from '@aztec/node-lib/factories';
|
|
32
31
|
import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
33
32
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
34
|
-
import {
|
|
35
|
-
BlockBuilder,
|
|
36
|
-
GlobalVariableBuilder,
|
|
37
|
-
SequencerClient,
|
|
38
|
-
type SequencerPublisher,
|
|
39
|
-
createValidatorForAcceptingTxs,
|
|
40
|
-
} from '@aztec/sequencer-client';
|
|
33
|
+
import { GlobalVariableBuilder, SequencerClient, type SequencerPublisher } from '@aztec/sequencer-client';
|
|
41
34
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
42
35
|
import {
|
|
43
36
|
AttestationsBlockWatcher,
|
|
@@ -48,14 +41,8 @@ import {
|
|
|
48
41
|
} from '@aztec/slasher';
|
|
49
42
|
import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
50
43
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
51
|
-
import {
|
|
52
|
-
|
|
53
|
-
type DataInBlock,
|
|
54
|
-
type L2Block,
|
|
55
|
-
L2BlockHash,
|
|
56
|
-
type L2BlockSource,
|
|
57
|
-
type PublishedL2Block,
|
|
58
|
-
} from '@aztec/stdlib/block';
|
|
44
|
+
import { type BlockParameter, type DataInBlock, L2Block, L2BlockHash, type L2BlockSource } from '@aztec/stdlib/block';
|
|
45
|
+
import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
59
46
|
import type {
|
|
60
47
|
ContractClassPublic,
|
|
61
48
|
ContractDataSource,
|
|
@@ -82,7 +69,7 @@ import {
|
|
|
82
69
|
type WorldStateSynchronizer,
|
|
83
70
|
tryStop,
|
|
84
71
|
} from '@aztec/stdlib/interfaces/server';
|
|
85
|
-
import type { LogFilter,
|
|
72
|
+
import type { LogFilter, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
86
73
|
import { InboxLeaf, type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
87
74
|
import { P2PClientType } from '@aztec/stdlib/p2p';
|
|
88
75
|
import type { Offense, SlashPayloadRound } from '@aztec/stdlib/slashing';
|
|
@@ -110,10 +97,13 @@ import {
|
|
|
110
97
|
trackSpan,
|
|
111
98
|
} from '@aztec/telemetry-client';
|
|
112
99
|
import {
|
|
100
|
+
FullNodeCheckpointsBuilder as CheckpointsBuilder,
|
|
101
|
+
FullNodeCheckpointsBuilder,
|
|
113
102
|
NodeKeystoreAdapter,
|
|
114
103
|
ValidatorClient,
|
|
115
104
|
createBlockProposalHandler,
|
|
116
105
|
createValidatorClient,
|
|
106
|
+
createValidatorForAcceptingTxs,
|
|
117
107
|
} from '@aztec/validator-client';
|
|
118
108
|
import { createWorldStateSynchronizer } from '@aztec/world-state';
|
|
119
109
|
|
|
@@ -129,6 +119,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
129
119
|
*/
|
|
130
120
|
export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
131
121
|
private metrics: NodeMetrics;
|
|
122
|
+
private initialHeaderHashPromise: Promise<L2BlockHash> | undefined = undefined;
|
|
132
123
|
|
|
133
124
|
// Prevent two snapshot operations to happen simultaneously
|
|
134
125
|
private isUploadingSnapshot = false;
|
|
@@ -155,6 +146,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
155
146
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
156
147
|
private telemetry: TelemetryClient = getTelemetryClient(),
|
|
157
148
|
private log = createLogger('node'),
|
|
149
|
+
private blobClient?: BlobClientInterface,
|
|
158
150
|
) {
|
|
159
151
|
this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
|
|
160
152
|
this.tracer = telemetry.getTracer('AztecNodeService');
|
|
@@ -184,7 +176,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
184
176
|
logger?: Logger;
|
|
185
177
|
publisher?: SequencerPublisher;
|
|
186
178
|
dateProvider?: DateProvider;
|
|
187
|
-
blobSinkClient?: BlobSinkClientInterface;
|
|
188
179
|
p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
|
|
189
180
|
} = {},
|
|
190
181
|
options: {
|
|
@@ -197,8 +188,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
197
188
|
const packageVersion = getPackageVersion() ?? '';
|
|
198
189
|
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
199
190
|
const dateProvider = deps.dateProvider ?? new DateProvider();
|
|
200
|
-
const blobSinkClient =
|
|
201
|
-
deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('node:blob-sink:client') });
|
|
202
191
|
const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
203
192
|
|
|
204
193
|
// Build a key store from file if given or from environment otherwise
|
|
@@ -238,7 +227,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
238
227
|
|
|
239
228
|
const publicClient = createPublicClient({
|
|
240
229
|
chain: ethereumChain.chainInfo,
|
|
241
|
-
transport: fallback(config.l1RpcUrls.map((url: string) => http(url))),
|
|
230
|
+
transport: fallback(config.l1RpcUrls.map((url: string) => http(url, { batch: false }))),
|
|
242
231
|
pollingInterval: config.viemPollingIntervalMS,
|
|
243
232
|
});
|
|
244
233
|
|
|
@@ -266,6 +255,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
266
255
|
);
|
|
267
256
|
}
|
|
268
257
|
|
|
258
|
+
const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
|
|
259
|
+
|
|
269
260
|
// attempt snapshot sync if possible
|
|
270
261
|
await trySnapshotSync(config, log);
|
|
271
262
|
|
|
@@ -273,7 +264,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
273
264
|
|
|
274
265
|
const archiver = await createArchiver(
|
|
275
266
|
config,
|
|
276
|
-
{
|
|
267
|
+
{ blobClient, epochCache, telemetry, dateProvider },
|
|
277
268
|
{ blockUntilSync: !config.skipArchiverInitialSync },
|
|
278
269
|
);
|
|
279
270
|
|
|
@@ -284,9 +275,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
284
275
|
options.prefilledPublicData,
|
|
285
276
|
telemetry,
|
|
286
277
|
);
|
|
287
|
-
const circuitVerifier =
|
|
288
|
-
|
|
289
|
-
|
|
278
|
+
const circuitVerifier =
|
|
279
|
+
config.realProofs || config.debugForceTxProofVerification
|
|
280
|
+
? await BBCircuitVerifier.new(config)
|
|
281
|
+
: new TestCircuitVerifier(config.proverTestVerificationDelayMs);
|
|
290
282
|
if (!config.realProofs) {
|
|
291
283
|
log.warn(`Aztec node is accepting fake proofs`);
|
|
292
284
|
}
|
|
@@ -309,7 +301,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
309
301
|
// We should really not be modifying the config object
|
|
310
302
|
config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
311
303
|
|
|
312
|
-
|
|
304
|
+
// Create FullNodeCheckpointsBuilder for validator and non-validator block proposal handling
|
|
305
|
+
const validatorCheckpointsBuilder = new FullNodeCheckpointsBuilder(
|
|
313
306
|
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
314
307
|
worldStateSynchronizer,
|
|
315
308
|
archiver,
|
|
@@ -321,15 +314,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
321
314
|
const watchers: Watcher[] = [];
|
|
322
315
|
|
|
323
316
|
// Create validator client if required
|
|
324
|
-
const validatorClient = createValidatorClient(config, {
|
|
317
|
+
const validatorClient = await createValidatorClient(config, {
|
|
318
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
319
|
+
worldState: worldStateSynchronizer,
|
|
325
320
|
p2pClient,
|
|
326
321
|
telemetry,
|
|
327
322
|
dateProvider,
|
|
328
323
|
epochCache,
|
|
329
|
-
blockBuilder,
|
|
330
324
|
blockSource: archiver,
|
|
331
325
|
l1ToL2MessageSource: archiver,
|
|
332
326
|
keyStoreManager,
|
|
327
|
+
blobClient,
|
|
333
328
|
});
|
|
334
329
|
|
|
335
330
|
// If we have a validator client, register it as a source of offenses for the slasher,
|
|
@@ -347,7 +342,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
347
342
|
if (!validatorClient && config.alwaysReexecuteBlockProposals) {
|
|
348
343
|
log.info('Setting up block proposal reexecution for monitoring');
|
|
349
344
|
createBlockProposalHandler(config, {
|
|
350
|
-
|
|
345
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
346
|
+
worldState: worldStateSynchronizer,
|
|
351
347
|
epochCache,
|
|
352
348
|
blockSource: archiver,
|
|
353
349
|
l1ToL2MessageSource: archiver,
|
|
@@ -375,7 +371,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
375
371
|
archiver,
|
|
376
372
|
epochCache,
|
|
377
373
|
p2pClient.getTxProvider(),
|
|
378
|
-
|
|
374
|
+
validatorCheckpointsBuilder,
|
|
379
375
|
config,
|
|
380
376
|
);
|
|
381
377
|
watchers.push(epochPruneWatcher);
|
|
@@ -403,7 +399,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
403
399
|
// Validator enabled, create/start relevant service
|
|
404
400
|
let sequencer: SequencerClient | undefined;
|
|
405
401
|
let slasherClient: SlasherClientInterface | undefined;
|
|
406
|
-
if (!config.disableValidator) {
|
|
402
|
+
if (!config.disableValidator && validatorClient) {
|
|
407
403
|
// We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher
|
|
408
404
|
// as they are executed when the node is selected as proposer.
|
|
409
405
|
const validatorAddresses = keyStoreManager
|
|
@@ -422,14 +418,30 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
422
418
|
);
|
|
423
419
|
await slasherClient.start();
|
|
424
420
|
|
|
425
|
-
const l1TxUtils =
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
421
|
+
const l1TxUtils = config.publisherForwarderAddress
|
|
422
|
+
? await createForwarderL1TxUtilsFromEthSigner(
|
|
423
|
+
publicClient,
|
|
424
|
+
keyStoreManager!.createAllValidatorPublisherSigners(),
|
|
425
|
+
config.publisherForwarderAddress,
|
|
426
|
+
{ ...config, scope: 'sequencer' },
|
|
427
|
+
{ telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
|
|
428
|
+
)
|
|
429
|
+
: await createL1TxUtilsWithBlobsFromEthSigner(
|
|
430
|
+
publicClient,
|
|
431
|
+
keyStoreManager!.createAllValidatorPublisherSigners(),
|
|
432
|
+
{ ...config, scope: 'sequencer' },
|
|
433
|
+
{ telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
|
|
434
|
+
);
|
|
431
435
|
|
|
432
436
|
// Create and start the sequencer client
|
|
437
|
+
const checkpointsBuilder = new CheckpointsBuilder(
|
|
438
|
+
{ ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
|
|
439
|
+
worldStateSynchronizer,
|
|
440
|
+
archiver,
|
|
441
|
+
dateProvider,
|
|
442
|
+
telemetry,
|
|
443
|
+
);
|
|
444
|
+
|
|
433
445
|
sequencer = await SequencerClient.new(config, {
|
|
434
446
|
...deps,
|
|
435
447
|
epochCache,
|
|
@@ -438,12 +450,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
438
450
|
p2pClient,
|
|
439
451
|
worldStateSynchronizer,
|
|
440
452
|
slasherClient,
|
|
441
|
-
|
|
453
|
+
checkpointsBuilder,
|
|
442
454
|
l2BlockSource: archiver,
|
|
443
455
|
l1ToL2MessageSource: archiver,
|
|
444
456
|
telemetry,
|
|
445
457
|
dateProvider,
|
|
446
|
-
|
|
458
|
+
blobClient,
|
|
447
459
|
nodeKeyStore: keyStoreManager!,
|
|
448
460
|
});
|
|
449
461
|
}
|
|
@@ -455,6 +467,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
455
467
|
log.warn(`Sequencer created but not started`);
|
|
456
468
|
}
|
|
457
469
|
|
|
470
|
+
const globalVariableBuilder = new GlobalVariableBuilder({
|
|
471
|
+
...config,
|
|
472
|
+
rollupVersion: BigInt(config.rollupVersion),
|
|
473
|
+
l1GenesisTime,
|
|
474
|
+
slotDuration: Number(slotDuration),
|
|
475
|
+
});
|
|
476
|
+
|
|
458
477
|
return new AztecNodeService(
|
|
459
478
|
config,
|
|
460
479
|
p2pClient,
|
|
@@ -469,12 +488,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
469
488
|
epochPruneWatcher,
|
|
470
489
|
ethereumChain.chainInfo.id,
|
|
471
490
|
config.rollupVersion,
|
|
472
|
-
|
|
491
|
+
globalVariableBuilder,
|
|
473
492
|
epochCache,
|
|
474
493
|
packageVersion,
|
|
475
494
|
proofVerifier,
|
|
476
495
|
telemetry,
|
|
477
496
|
log,
|
|
497
|
+
blobClient,
|
|
478
498
|
);
|
|
479
499
|
}
|
|
480
500
|
|
|
@@ -545,13 +565,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
545
565
|
}
|
|
546
566
|
|
|
547
567
|
/**
|
|
548
|
-
* Get a block specified by its number.
|
|
549
|
-
* @param
|
|
568
|
+
* Get a block specified by its block number, block hash, or 'latest'.
|
|
569
|
+
* @param block - The block parameter (block number, block hash, or 'latest').
|
|
550
570
|
* @returns The requested block.
|
|
551
571
|
*/
|
|
552
|
-
public async getBlock(
|
|
553
|
-
|
|
554
|
-
|
|
572
|
+
public async getBlock(block: BlockParameter): Promise<L2Block | undefined> {
|
|
573
|
+
if (L2BlockHash.isL2BlockHash(block)) {
|
|
574
|
+
return this.getBlockByHash(Fr.fromBuffer(block.toBuffer()));
|
|
575
|
+
}
|
|
576
|
+
const blockNumber = block === 'latest' ? await this.getBlockNumber() : (block as BlockNumber);
|
|
577
|
+
if (blockNumber === BlockNumber.ZERO) {
|
|
578
|
+
return this.buildInitialBlock();
|
|
579
|
+
}
|
|
580
|
+
return await this.blockSource.getL2Block(blockNumber);
|
|
555
581
|
}
|
|
556
582
|
|
|
557
583
|
/**
|
|
@@ -560,8 +586,16 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
560
586
|
* @returns The requested block.
|
|
561
587
|
*/
|
|
562
588
|
public async getBlockByHash(blockHash: Fr): Promise<L2Block | undefined> {
|
|
563
|
-
const
|
|
564
|
-
|
|
589
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
590
|
+
if (blockHash.equals(Fr.fromBuffer(initialBlockHash.toBuffer()))) {
|
|
591
|
+
return this.buildInitialBlock();
|
|
592
|
+
}
|
|
593
|
+
return await this.blockSource.getL2BlockByHash(blockHash);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
private buildInitialBlock(): L2Block {
|
|
597
|
+
const initialHeader = this.worldStateSynchronizer.getCommitted().getInitialHeader();
|
|
598
|
+
return L2Block.empty(initialHeader);
|
|
565
599
|
}
|
|
566
600
|
|
|
567
601
|
/**
|
|
@@ -570,8 +604,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
570
604
|
* @returns The requested block.
|
|
571
605
|
*/
|
|
572
606
|
public async getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
|
|
573
|
-
|
|
574
|
-
return publishedBlock?.block;
|
|
607
|
+
return await this.blockSource.getL2BlockByArchive(archive);
|
|
575
608
|
}
|
|
576
609
|
|
|
577
610
|
/**
|
|
@@ -581,19 +614,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
581
614
|
* @returns The blocks requested.
|
|
582
615
|
*/
|
|
583
616
|
public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
|
|
584
|
-
return (await this.blockSource.getBlocks(from, limit)) ?? [];
|
|
617
|
+
return (await this.blockSource.getBlocks(from, BlockNumber(limit))) ?? [];
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
public async getCheckpoints(from: CheckpointNumber, limit: number): Promise<PublishedCheckpoint[]> {
|
|
621
|
+
return (await this.blockSource.getCheckpoints(from, limit)) ?? [];
|
|
585
622
|
}
|
|
586
623
|
|
|
587
|
-
public async
|
|
588
|
-
return (await this.blockSource.
|
|
624
|
+
public async getCheckpointedBlocks(from: BlockNumber, limit: number) {
|
|
625
|
+
return (await this.blockSource.getCheckpointedBlocks(from, limit)) ?? [];
|
|
589
626
|
}
|
|
590
627
|
|
|
591
628
|
/**
|
|
592
|
-
* Method to fetch the current
|
|
593
|
-
* @returns The current
|
|
629
|
+
* Method to fetch the current min L2 fees.
|
|
630
|
+
* @returns The current min L2 fees.
|
|
594
631
|
*/
|
|
595
|
-
public async
|
|
596
|
-
return await this.globalVariableBuilder.
|
|
632
|
+
public async getCurrentMinFees(): Promise<GasFees> {
|
|
633
|
+
return await this.globalVariableBuilder.getCurrentMinFees();
|
|
597
634
|
}
|
|
598
635
|
|
|
599
636
|
public async getMaxPriorityFees(): Promise<GasFees> {
|
|
@@ -616,6 +653,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
616
653
|
return await this.blockSource.getProvenBlockNumber();
|
|
617
654
|
}
|
|
618
655
|
|
|
656
|
+
public async getCheckpointedBlockNumber(): Promise<BlockNumber> {
|
|
657
|
+
return await this.blockSource.getCheckpointedL2BlockNumber();
|
|
658
|
+
}
|
|
659
|
+
|
|
619
660
|
/**
|
|
620
661
|
* Method to fetch the version of the package.
|
|
621
662
|
* @returns The node package version
|
|
@@ -648,25 +689,45 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
648
689
|
return this.contractDataSource.getContract(address);
|
|
649
690
|
}
|
|
650
691
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
692
|
+
public async getPrivateLogsByTags(
|
|
693
|
+
tags: SiloedTag[],
|
|
694
|
+
page?: number,
|
|
695
|
+
referenceBlock?: L2BlockHash,
|
|
696
|
+
): Promise<TxScopedL2Log[][]> {
|
|
697
|
+
if (referenceBlock) {
|
|
698
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
699
|
+
if (!referenceBlock.equals(initialBlockHash)) {
|
|
700
|
+
const blockHashFr = Fr.fromBuffer(referenceBlock.toBuffer());
|
|
701
|
+
const header = await this.blockSource.getBlockHeaderByHash(blockHashFr);
|
|
702
|
+
if (!header) {
|
|
703
|
+
throw new Error(
|
|
704
|
+
`Block ${referenceBlock.toString()} not found in the node. This might indicate a reorg has occurred.`,
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return this.logsSource.getPrivateLogsByTags(tags, page);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
public async getPublicLogsByTagsFromContract(
|
|
713
|
+
contractAddress: AztecAddress,
|
|
714
|
+
tags: Tag[],
|
|
715
|
+
page?: number,
|
|
716
|
+
referenceBlock?: L2BlockHash,
|
|
717
|
+
): Promise<TxScopedL2Log[][]> {
|
|
718
|
+
if (referenceBlock) {
|
|
719
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
720
|
+
if (!referenceBlock.equals(initialBlockHash)) {
|
|
721
|
+
const blockHashFr = Fr.fromBuffer(referenceBlock.toBuffer());
|
|
722
|
+
const header = await this.blockSource.getBlockHeaderByHash(blockHashFr);
|
|
723
|
+
if (!header) {
|
|
724
|
+
throw new Error(
|
|
725
|
+
`Block ${referenceBlock.toString()} not found in the node. This might indicate a reorg has occurred.`,
|
|
726
|
+
);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags, page);
|
|
670
731
|
}
|
|
671
732
|
|
|
672
733
|
/**
|
|
@@ -713,21 +774,26 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
713
774
|
}
|
|
714
775
|
|
|
715
776
|
public async getTxReceipt(txHash: TxHash): Promise<TxReceipt> {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
// and we would incorrectly return a TxReceipt with status DROPPED
|
|
721
|
-
if ((await this.p2pClient.getTxStatus(txHash)) === 'pending') {
|
|
722
|
-
txReceipt = new TxReceipt(txHash, TxStatus.PENDING, '');
|
|
723
|
-
}
|
|
777
|
+
// Check the tx pool status first. If the tx is known to the pool (pending or mined), we'll use that
|
|
778
|
+
// as a fallback if we don't find a settled receipt in the archiver.
|
|
779
|
+
const txPoolStatus = await this.p2pClient.getTxStatus(txHash);
|
|
780
|
+
const isKnownToPool = txPoolStatus === 'pending' || txPoolStatus === 'mined';
|
|
724
781
|
|
|
782
|
+
// Then get the actual tx from the archiver, which tracks every tx in a mined block.
|
|
725
783
|
const settledTxReceipt = await this.blockSource.getSettledTxReceipt(txHash);
|
|
784
|
+
|
|
726
785
|
if (settledTxReceipt) {
|
|
727
|
-
|
|
786
|
+
// If the archiver has the receipt then return it.
|
|
787
|
+
return settledTxReceipt;
|
|
788
|
+
} else if (isKnownToPool) {
|
|
789
|
+
// If the tx is in the pool but not in the archiver, it's pending.
|
|
790
|
+
// This handles race conditions between archiver and p2p, where the archiver
|
|
791
|
+
// has pruned the block in which a tx was mined, but p2p has not caught up yet.
|
|
792
|
+
return new TxReceipt(txHash, TxStatus.PENDING, undefined, undefined);
|
|
793
|
+
} else {
|
|
794
|
+
// Otherwise, if we don't know the tx, we consider it dropped.
|
|
795
|
+
return new TxReceipt(txHash, TxStatus.DROPPED, undefined, 'Tx dropped by P2P node');
|
|
728
796
|
}
|
|
729
|
-
|
|
730
|
-
return txReceipt;
|
|
731
797
|
}
|
|
732
798
|
|
|
733
799
|
public getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined> {
|
|
@@ -747,10 +813,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
747
813
|
await tryStop(this.p2pClient);
|
|
748
814
|
await tryStop(this.worldStateSynchronizer);
|
|
749
815
|
await tryStop(this.blockSource);
|
|
816
|
+
await tryStop(this.blobClient);
|
|
750
817
|
await tryStop(this.telemetry);
|
|
751
818
|
this.log.info(`Stopped Aztec Node`);
|
|
752
819
|
}
|
|
753
820
|
|
|
821
|
+
/**
|
|
822
|
+
* Returns the blob client used by this node.
|
|
823
|
+
* @internal - Exposed for testing purposes only.
|
|
824
|
+
*/
|
|
825
|
+
public getBlobClient(): BlobClientInterface | undefined {
|
|
826
|
+
return this.blobClient;
|
|
827
|
+
}
|
|
828
|
+
|
|
754
829
|
/**
|
|
755
830
|
* Method to retrieve pending txs.
|
|
756
831
|
* @param limit - The number of items to returns
|
|
@@ -783,20 +858,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
783
858
|
return compactArray(await Promise.all(txHashes.map(txHash => this.getTxByHash(txHash))));
|
|
784
859
|
}
|
|
785
860
|
|
|
786
|
-
/**
|
|
787
|
-
* Find the indexes of the given leaves in the given tree along with a block metadata pointing to the block in which
|
|
788
|
-
* the leaves were inserted.
|
|
789
|
-
* @param blockNumber - The block number at which to get the data or 'latest' for latest data.
|
|
790
|
-
* @param treeId - The tree to search in.
|
|
791
|
-
* @param leafValues - The values to search for.
|
|
792
|
-
* @returns The indices of leaves and the block metadata of a block in which the leaves were inserted.
|
|
793
|
-
*/
|
|
794
861
|
public async findLeavesIndexes(
|
|
795
|
-
|
|
862
|
+
block: BlockParameter,
|
|
796
863
|
treeId: MerkleTreeId,
|
|
797
864
|
leafValues: Fr[],
|
|
798
865
|
): Promise<(DataInBlock<bigint> | undefined)[]> {
|
|
799
|
-
const committedDb = await this.#getWorldState(
|
|
866
|
+
const committedDb = await this.#getWorldState(block);
|
|
800
867
|
const maybeIndices = await committedDb.findLeafIndices(
|
|
801
868
|
treeId,
|
|
802
869
|
leafValues.map(x => x.toBuffer()),
|
|
@@ -854,39 +921,27 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
854
921
|
});
|
|
855
922
|
}
|
|
856
923
|
|
|
857
|
-
/**
|
|
858
|
-
* Returns a sibling path for the given index in the nullifier tree.
|
|
859
|
-
* @param blockNumber - The block number at which to get the data.
|
|
860
|
-
* @param leafIndex - The index of the leaf for which the sibling path is required.
|
|
861
|
-
* @returns The sibling path for the leaf index.
|
|
862
|
-
*/
|
|
863
924
|
public async getNullifierSiblingPath(
|
|
864
|
-
|
|
925
|
+
block: BlockParameter,
|
|
865
926
|
leafIndex: bigint,
|
|
866
927
|
): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
|
|
867
|
-
const committedDb = await this.#getWorldState(
|
|
928
|
+
const committedDb = await this.#getWorldState(block);
|
|
868
929
|
return committedDb.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, leafIndex);
|
|
869
930
|
}
|
|
870
931
|
|
|
871
|
-
/**
|
|
872
|
-
* Returns a sibling path for the given index in the data tree.
|
|
873
|
-
* @param blockNumber - The block number at which to get the data.
|
|
874
|
-
* @param leafIndex - The index of the leaf for which the sibling path is required.
|
|
875
|
-
* @returns The sibling path for the leaf index.
|
|
876
|
-
*/
|
|
877
932
|
public async getNoteHashSiblingPath(
|
|
878
|
-
|
|
933
|
+
block: BlockParameter,
|
|
879
934
|
leafIndex: bigint,
|
|
880
935
|
): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
|
|
881
|
-
const committedDb = await this.#getWorldState(
|
|
936
|
+
const committedDb = await this.#getWorldState(block);
|
|
882
937
|
return committedDb.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
883
938
|
}
|
|
884
939
|
|
|
885
940
|
public async getArchiveMembershipWitness(
|
|
886
|
-
|
|
941
|
+
block: BlockParameter,
|
|
887
942
|
archive: Fr,
|
|
888
943
|
): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
|
|
889
|
-
const committedDb = await this.#getWorldState(
|
|
944
|
+
const committedDb = await this.#getWorldState(block);
|
|
890
945
|
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.ARCHIVE>(MerkleTreeId.ARCHIVE, [archive]);
|
|
891
946
|
return pathAndIndex === undefined
|
|
892
947
|
? undefined
|
|
@@ -894,10 +949,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
894
949
|
}
|
|
895
950
|
|
|
896
951
|
public async getNoteHashMembershipWitness(
|
|
897
|
-
|
|
952
|
+
block: BlockParameter,
|
|
898
953
|
noteHash: Fr,
|
|
899
954
|
): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
|
|
900
|
-
const committedDb = await this.#getWorldState(
|
|
955
|
+
const committedDb = await this.#getWorldState(block);
|
|
901
956
|
const [pathAndIndex] = await committedDb.findSiblingPaths<MerkleTreeId.NOTE_HASH_TREE>(
|
|
902
957
|
MerkleTreeId.NOTE_HASH_TREE,
|
|
903
958
|
[noteHash],
|
|
@@ -907,17 +962,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
907
962
|
: MembershipWitness.fromSiblingPath(pathAndIndex.index, pathAndIndex.path);
|
|
908
963
|
}
|
|
909
964
|
|
|
910
|
-
/**
|
|
911
|
-
* Returns the index and a sibling path for a leaf in the committed l1 to l2 data tree.
|
|
912
|
-
* @param blockNumber - The block number at which to get the data.
|
|
913
|
-
* @param l1ToL2Message - The l1ToL2Message to get the index / sibling path for.
|
|
914
|
-
* @returns A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found).
|
|
915
|
-
*/
|
|
916
965
|
public async getL1ToL2MessageMembershipWitness(
|
|
917
|
-
|
|
966
|
+
block: BlockParameter,
|
|
918
967
|
l1ToL2Message: Fr,
|
|
919
968
|
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
|
|
920
|
-
const db = await this.#getWorldState(
|
|
969
|
+
const db = await this.#getWorldState(block);
|
|
921
970
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, [l1ToL2Message]);
|
|
922
971
|
if (!witness) {
|
|
923
972
|
return undefined;
|
|
@@ -929,7 +978,9 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
929
978
|
|
|
930
979
|
public async getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<BlockNumber | undefined> {
|
|
931
980
|
const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
|
|
932
|
-
return messageIndex
|
|
981
|
+
return messageIndex
|
|
982
|
+
? BlockNumber.fromCheckpointNumber(InboxLeaf.checkpointNumberFromIndex(messageIndex))
|
|
983
|
+
: undefined;
|
|
933
984
|
}
|
|
934
985
|
|
|
935
986
|
/**
|
|
@@ -943,56 +994,52 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
943
994
|
}
|
|
944
995
|
|
|
945
996
|
/**
|
|
946
|
-
* Returns all the L2 to L1 messages in
|
|
947
|
-
* @param
|
|
948
|
-
* @returns The L2 to L1 messages (
|
|
997
|
+
* Returns all the L2 to L1 messages in an epoch.
|
|
998
|
+
* @param epoch - The epoch at which to get the data.
|
|
999
|
+
* @returns The L2 to L1 messages (empty array if the epoch is not found).
|
|
949
1000
|
*/
|
|
950
|
-
public async getL2ToL1Messages(
|
|
951
|
-
|
|
952
|
-
|
|
1001
|
+
public async getL2ToL1Messages(epoch: EpochNumber): Promise<Fr[][][][]> {
|
|
1002
|
+
// Assumes `getCheckpointedBlocksForEpoch` returns blocks in ascending order of block number.
|
|
1003
|
+
const checkpointedBlocks = await this.blockSource.getCheckpointedBlocksForEpoch(epoch);
|
|
1004
|
+
const blocksInCheckpoints: L2Block[][] = [];
|
|
1005
|
+
let previousSlotNumber = SlotNumber.ZERO;
|
|
1006
|
+
let checkpointIndex = -1;
|
|
1007
|
+
for (const checkpointedBlock of checkpointedBlocks) {
|
|
1008
|
+
const block = checkpointedBlock.block;
|
|
1009
|
+
const slotNumber = block.header.globalVariables.slotNumber;
|
|
1010
|
+
if (slotNumber !== previousSlotNumber) {
|
|
1011
|
+
checkpointIndex++;
|
|
1012
|
+
blocksInCheckpoints.push([]);
|
|
1013
|
+
previousSlotNumber = slotNumber;
|
|
1014
|
+
}
|
|
1015
|
+
blocksInCheckpoints[checkpointIndex].push(block);
|
|
1016
|
+
}
|
|
1017
|
+
return blocksInCheckpoints.map(blocks =>
|
|
1018
|
+
blocks.map(block => block.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs)),
|
|
953
1019
|
);
|
|
954
|
-
return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
|
|
955
1020
|
}
|
|
956
1021
|
|
|
957
|
-
/**
|
|
958
|
-
* Returns a sibling path for a leaf in the committed blocks tree.
|
|
959
|
-
* @param blockNumber - The block number at which to get the data.
|
|
960
|
-
* @param leafIndex - Index of the leaf in the tree.
|
|
961
|
-
* @returns The sibling path.
|
|
962
|
-
*/
|
|
963
1022
|
public async getArchiveSiblingPath(
|
|
964
|
-
|
|
1023
|
+
block: BlockParameter,
|
|
965
1024
|
leafIndex: bigint,
|
|
966
1025
|
): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
|
|
967
|
-
const committedDb = await this.#getWorldState(
|
|
1026
|
+
const committedDb = await this.#getWorldState(block);
|
|
968
1027
|
return committedDb.getSiblingPath(MerkleTreeId.ARCHIVE, leafIndex);
|
|
969
1028
|
}
|
|
970
1029
|
|
|
971
|
-
/**
|
|
972
|
-
* Returns a sibling path for a leaf in the committed public data tree.
|
|
973
|
-
* @param blockNumber - The block number at which to get the data.
|
|
974
|
-
* @param leafIndex - Index of the leaf in the tree.
|
|
975
|
-
* @returns The sibling path.
|
|
976
|
-
*/
|
|
977
1030
|
public async getPublicDataSiblingPath(
|
|
978
|
-
|
|
1031
|
+
block: BlockParameter,
|
|
979
1032
|
leafIndex: bigint,
|
|
980
1033
|
): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
|
|
981
|
-
const committedDb = await this.#getWorldState(
|
|
1034
|
+
const committedDb = await this.#getWorldState(block);
|
|
982
1035
|
return committedDb.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, leafIndex);
|
|
983
1036
|
}
|
|
984
1037
|
|
|
985
|
-
/**
|
|
986
|
-
* Returns a nullifier membership witness for a given nullifier at a given block.
|
|
987
|
-
* @param blockNumber - The block number at which to get the index.
|
|
988
|
-
* @param nullifier - Nullifier we try to find witness for.
|
|
989
|
-
* @returns The nullifier membership witness (if found).
|
|
990
|
-
*/
|
|
991
1038
|
public async getNullifierMembershipWitness(
|
|
992
|
-
|
|
1039
|
+
block: BlockParameter,
|
|
993
1040
|
nullifier: Fr,
|
|
994
1041
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
995
|
-
const db = await this.#getWorldState(
|
|
1042
|
+
const db = await this.#getWorldState(block);
|
|
996
1043
|
const [witness] = await db.findSiblingPaths(MerkleTreeId.NULLIFIER_TREE, [nullifier.toBuffer()]);
|
|
997
1044
|
if (!witness) {
|
|
998
1045
|
return undefined;
|
|
@@ -1009,7 +1056,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1009
1056
|
|
|
1010
1057
|
/**
|
|
1011
1058
|
* Returns a low nullifier membership witness for a given nullifier at a given block.
|
|
1012
|
-
* @param
|
|
1059
|
+
* @param block - The block parameter (block number, block hash, or 'latest') at which to get the data.
|
|
1013
1060
|
* @param nullifier - Nullifier we try to find the low nullifier witness for.
|
|
1014
1061
|
* @returns The low nullifier membership witness (if found).
|
|
1015
1062
|
* @remarks Low nullifier witness can be used to perform a nullifier non-inclusion proof by leveraging the "linked
|
|
@@ -1022,10 +1069,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1022
1069
|
* TODO: This is a confusing behavior and we should eventually address that.
|
|
1023
1070
|
*/
|
|
1024
1071
|
public async getLowNullifierMembershipWitness(
|
|
1025
|
-
|
|
1072
|
+
block: BlockParameter,
|
|
1026
1073
|
nullifier: Fr,
|
|
1027
1074
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
1028
|
-
const committedDb = await this.#getWorldState(
|
|
1075
|
+
const committedDb = await this.#getWorldState(block);
|
|
1029
1076
|
const findResult = await committedDb.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
|
|
1030
1077
|
if (!findResult) {
|
|
1031
1078
|
return undefined;
|
|
@@ -1040,8 +1087,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1040
1087
|
return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
|
|
1041
1088
|
}
|
|
1042
1089
|
|
|
1043
|
-
async getPublicDataWitness(
|
|
1044
|
-
const committedDb = await this.#getWorldState(
|
|
1090
|
+
async getPublicDataWitness(block: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
1091
|
+
const committedDb = await this.#getWorldState(block);
|
|
1045
1092
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
1046
1093
|
if (!lowLeafResult) {
|
|
1047
1094
|
return undefined;
|
|
@@ -1055,19 +1102,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1055
1102
|
}
|
|
1056
1103
|
}
|
|
1057
1104
|
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
*
|
|
1061
|
-
* @remarks The storage slot here refers to the slot as it is defined in Noir not the index in the merkle tree.
|
|
1062
|
-
* Aztec's version of `eth_getStorageAt`.
|
|
1063
|
-
*
|
|
1064
|
-
* @param contract - Address of the contract to query.
|
|
1065
|
-
* @param slot - Slot to query.
|
|
1066
|
-
* @param blockNumber - The block number at which to get the data or 'latest'.
|
|
1067
|
-
* @returns Storage value at the given contract slot.
|
|
1068
|
-
*/
|
|
1069
|
-
public async getPublicStorageAt(blockNumber: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
1070
|
-
const committedDb = await this.#getWorldState(blockNumber);
|
|
1105
|
+
public async getPublicStorageAt(block: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
1106
|
+
const committedDb = await this.#getWorldState(block);
|
|
1071
1107
|
const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
|
|
1072
1108
|
|
|
1073
1109
|
const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
@@ -1081,24 +1117,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1081
1117
|
return preimage.leaf.value;
|
|
1082
1118
|
}
|
|
1083
1119
|
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
return await this.blockSource.getBlockHeaderByHash(blockHash);
|
|
1120
|
+
public async getBlockHeader(block: BlockParameter = 'latest'): Promise<BlockHeader | undefined> {
|
|
1121
|
+
if (L2BlockHash.isL2BlockHash(block)) {
|
|
1122
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
1123
|
+
if (block.equals(initialBlockHash)) {
|
|
1124
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1125
|
+
return this.worldStateSynchronizer.getCommitted().getInitialHeader();
|
|
1126
|
+
}
|
|
1127
|
+
const blockHashFr = Fr.fromBuffer(block.toBuffer());
|
|
1128
|
+
return this.blockSource.getBlockHeaderByHash(blockHashFr);
|
|
1129
|
+
} else {
|
|
1130
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1131
|
+
const blockNumber = block === 'latest' ? await this.getBlockNumber() : (block as BlockNumber);
|
|
1132
|
+
if (blockNumber === BlockNumber.ZERO) {
|
|
1133
|
+
return this.worldStateSynchronizer.getCommitted().getInitialHeader();
|
|
1134
|
+
}
|
|
1135
|
+
return this.blockSource.getBlockHeader(block);
|
|
1136
|
+
}
|
|
1102
1137
|
}
|
|
1103
1138
|
|
|
1104
1139
|
/**
|
|
@@ -1207,7 +1242,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1207
1242
|
l1ChainId: this.l1ChainId,
|
|
1208
1243
|
rollupVersion: this.version,
|
|
1209
1244
|
setupAllowList: this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions()),
|
|
1210
|
-
gasFees: await this.
|
|
1245
|
+
gasFees: await this.getCurrentMinFees(),
|
|
1211
1246
|
skipFeeEnforcement,
|
|
1212
1247
|
txsPermitted: !this.config.disableTransactions,
|
|
1213
1248
|
});
|
|
@@ -1279,7 +1314,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1279
1314
|
}
|
|
1280
1315
|
|
|
1281
1316
|
// And it has an L2 block hash
|
|
1282
|
-
const l2BlockHash = await archiver.getL2Tips().then(tips => tips.
|
|
1317
|
+
const l2BlockHash = await archiver.getL2Tips().then(tips => tips.proposed.hash);
|
|
1283
1318
|
if (!l2BlockHash) {
|
|
1284
1319
|
this.metrics.recordSnapshotError();
|
|
1285
1320
|
throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
|
|
@@ -1313,7 +1348,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1313
1348
|
throw new Error('Archiver implementation does not support rollbacks.');
|
|
1314
1349
|
}
|
|
1315
1350
|
|
|
1316
|
-
const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.number);
|
|
1351
|
+
const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.block.number);
|
|
1317
1352
|
if (targetBlock < finalizedBlock) {
|
|
1318
1353
|
if (force) {
|
|
1319
1354
|
this.log.warn(`Clearing world state database to allow rolling back behind finalized block ${finalizedBlock}`);
|
|
@@ -1374,16 +1409,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1374
1409
|
}
|
|
1375
1410
|
}
|
|
1376
1411
|
|
|
1412
|
+
#getInitialHeaderHash(): Promise<L2BlockHash> {
|
|
1413
|
+
if (!this.initialHeaderHashPromise) {
|
|
1414
|
+
this.initialHeaderHashPromise = this.worldStateSynchronizer
|
|
1415
|
+
.getCommitted()
|
|
1416
|
+
.getInitialHeader()
|
|
1417
|
+
.hash()
|
|
1418
|
+
.then(hash => L2BlockHash.fromField(hash));
|
|
1419
|
+
}
|
|
1420
|
+
return this.initialHeaderHashPromise;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1377
1423
|
/**
|
|
1378
1424
|
* Returns an instance of MerkleTreeOperations having first ensured the world state is fully synched
|
|
1379
|
-
* @param
|
|
1425
|
+
* @param block - The block parameter (block number, block hash, or 'latest') at which to get the data.
|
|
1380
1426
|
* @returns An instance of a committed MerkleTreeOperations
|
|
1381
1427
|
*/
|
|
1382
|
-
async #getWorldState(
|
|
1383
|
-
if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
|
|
1384
|
-
throw new Error('Invalid block number to get world state for: ' + blockNumber);
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1428
|
+
async #getWorldState(block: BlockParameter) {
|
|
1387
1429
|
let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
|
|
1388
1430
|
try {
|
|
1389
1431
|
// Attempt to sync the world state if necessary
|
|
@@ -1392,15 +1434,40 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
|
|
|
1392
1434
|
this.log.error(`Error getting world state: ${err}`);
|
|
1393
1435
|
}
|
|
1394
1436
|
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
this.log.debug(`Using committed db for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1437
|
+
if (block === 'latest') {
|
|
1438
|
+
this.log.debug(`Using committed db for block 'latest', world state synced upto ${blockSyncedTo}`);
|
|
1398
1439
|
return this.worldStateSynchronizer.getCommitted();
|
|
1399
|
-
}
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
if (L2BlockHash.isL2BlockHash(block)) {
|
|
1443
|
+
const initialBlockHash = await this.#getInitialHeaderHash();
|
|
1444
|
+
if (block.equals(initialBlockHash)) {
|
|
1445
|
+
// Block source doesn't handle initial header so we need to handle the case separately.
|
|
1446
|
+
return this.worldStateSynchronizer.getSnapshot(BlockNumber.ZERO);
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
const blockHashFr = Fr.fromBuffer(block.toBuffer());
|
|
1450
|
+
const header = await this.blockSource.getBlockHeaderByHash(blockHashFr);
|
|
1451
|
+
if (!header) {
|
|
1452
|
+
throw new Error(
|
|
1453
|
+
`Block hash ${block.toString()} not found when querying world state. If the node API has been queried with anchor block hash possibly a reorg has occurred.`,
|
|
1454
|
+
);
|
|
1455
|
+
}
|
|
1456
|
+
const blockNumber = header.getBlockNumber();
|
|
1400
1457
|
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1401
|
-
return this.worldStateSynchronizer.getSnapshot(blockNumber
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1458
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
// Block number provided
|
|
1462
|
+
{
|
|
1463
|
+
const blockNumber = block as BlockNumber;
|
|
1464
|
+
|
|
1465
|
+
if (blockNumber > blockSyncedTo) {
|
|
1466
|
+
throw new Error(`Queried block ${block} not yet synced by the node (node is synced upto ${blockSyncedTo}).`);
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
|
|
1470
|
+
return this.worldStateSynchronizer.getSnapshot(blockNumber);
|
|
1404
1471
|
}
|
|
1405
1472
|
}
|
|
1406
1473
|
|