@aztec/archiver 0.26.6 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/dest/archiver/archiver.d.ts +12 -16
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +38 -36
- package/dest/archiver/archiver_store.d.ts +18 -21
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +46 -90
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +2 -5
- package/dest/archiver/data_retrieval.d.ts +10 -12
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +23 -22
- package/dest/archiver/eth_log_handlers.d.ts +17 -20
- package/dest/archiver/eth_log_handlers.d.ts.map +1 -1
- package/dest/archiver/eth_log_handlers.js +35 -52
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +1 -9
- package/dest/archiver/kv_archiver_store/contract_store.d.ts +1 -21
- package/dest/archiver/kv_archiver_store/contract_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_store.js +1 -36
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +14 -21
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +25 -28
- package/dest/archiver/kv_archiver_store/message_store.d.ts +11 -1
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +57 -5
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +18 -1
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +48 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +18 -21
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +32 -45
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +15 -3
- package/package.json +9 -9
- package/src/archiver/archiver.ts +46 -46
- package/src/archiver/archiver_store.ts +21 -24
- package/src/archiver/archiver_store_test_suite.ts +54 -115
- package/src/archiver/config.ts +0 -4
- package/src/archiver/data_retrieval.ts +30 -35
- package/src/archiver/eth_log_handlers.ts +42 -74
- package/src/archiver/kv_archiver_store/block_store.ts +0 -10
- package/src/archiver/kv_archiver_store/contract_store.ts +1 -44
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +26 -31
- package/src/archiver/kv_archiver_store/message_store.ts +60 -3
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +48 -1
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +36 -48
- package/src/index.ts +15 -2
package/src/archiver/archiver.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
25
25
|
import { Fr } from '@aztec/foundation/fields';
|
|
26
26
|
import { DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
27
27
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
28
|
+
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
28
29
|
import { ClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer';
|
|
29
30
|
import { InstanceDeployerAddress } from '@aztec/protocol-contracts/instance-deployer';
|
|
30
31
|
import {
|
|
@@ -34,7 +35,7 @@ import {
|
|
|
34
35
|
ContractInstanceWithAddress,
|
|
35
36
|
} from '@aztec/types/contracts';
|
|
36
37
|
|
|
37
|
-
import { Chain, HttpTransport, PublicClient, createPublicClient, http } from 'viem';
|
|
38
|
+
import { Chain, HttpTransport, PublicClient, createPublicClient, getAddress, getContract, http } from 'viem';
|
|
38
39
|
|
|
39
40
|
import { ArchiverDataStore } from './archiver_store.js';
|
|
40
41
|
import { ArchiverConfig } from './config.js';
|
|
@@ -42,7 +43,7 @@ import {
|
|
|
42
43
|
retrieveBlockBodiesFromAvailabilityOracle,
|
|
43
44
|
retrieveBlockMetadataFromRollup,
|
|
44
45
|
retrieveNewCancelledL1ToL2Messages,
|
|
45
|
-
|
|
46
|
+
retrieveNewL1ToL2Messages,
|
|
46
47
|
retrieveNewPendingL1ToL2Messages,
|
|
47
48
|
} from './data_retrieval.js';
|
|
48
49
|
|
|
@@ -72,8 +73,8 @@ export class Archiver implements ArchiveSource {
|
|
|
72
73
|
* @param publicClient - A client for interacting with the Ethereum node.
|
|
73
74
|
* @param rollupAddress - Ethereum address of the rollup contract.
|
|
74
75
|
* @param inboxAddress - Ethereum address of the inbox contract.
|
|
76
|
+
* @param newInboxAddress - Ethereum address of the new inbox contract.
|
|
75
77
|
* @param registryAddress - Ethereum address of the registry contract.
|
|
76
|
-
* @param contractDeploymentEmitterAddress - Ethereum address of the contractDeploymentEmitter contract.
|
|
77
78
|
* @param pollingIntervalMs - The interval for polling for L1 logs (in milliseconds).
|
|
78
79
|
* @param store - An archiver data store for storage & retrieval of blocks, encrypted logs & contract data.
|
|
79
80
|
* @param log - A logger.
|
|
@@ -83,8 +84,8 @@ export class Archiver implements ArchiveSource {
|
|
|
83
84
|
private readonly rollupAddress: EthAddress,
|
|
84
85
|
private readonly availabilityOracleAddress: EthAddress,
|
|
85
86
|
private readonly inboxAddress: EthAddress,
|
|
87
|
+
private readonly newInboxAddress: EthAddress,
|
|
86
88
|
private readonly registryAddress: EthAddress,
|
|
87
|
-
private readonly contractDeploymentEmitterAddress: EthAddress,
|
|
88
89
|
private readonly store: ArchiverDataStore,
|
|
89
90
|
private readonly pollingIntervalMs = 10_000,
|
|
90
91
|
private readonly log: DebugLogger = createDebugLogger('aztec:archiver'),
|
|
@@ -109,13 +110,24 @@ export class Archiver implements ArchiveSource {
|
|
|
109
110
|
pollingInterval: config.viemPollingIntervalMS,
|
|
110
111
|
});
|
|
111
112
|
|
|
113
|
+
// TODO(#4492): Nuke this once the old inbox is purged
|
|
114
|
+
let newInboxAddress!: EthAddress;
|
|
115
|
+
{
|
|
116
|
+
const rollup = getContract({
|
|
117
|
+
address: getAddress(config.l1Contracts.rollupAddress.toString()),
|
|
118
|
+
abi: RollupAbi,
|
|
119
|
+
client: publicClient,
|
|
120
|
+
});
|
|
121
|
+
newInboxAddress = EthAddress.fromString(await rollup.read.NEW_INBOX());
|
|
122
|
+
}
|
|
123
|
+
|
|
112
124
|
const archiver = new Archiver(
|
|
113
125
|
publicClient,
|
|
114
126
|
config.l1Contracts.rollupAddress,
|
|
115
127
|
config.l1Contracts.availabilityOracleAddress,
|
|
116
128
|
config.l1Contracts.inboxAddress,
|
|
129
|
+
newInboxAddress,
|
|
117
130
|
config.l1Contracts.registryAddress,
|
|
118
|
-
config.l1Contracts.contractDeploymentEmitterAddress,
|
|
119
131
|
archiverStore,
|
|
120
132
|
config.archiverPollingIntervalMS,
|
|
121
133
|
);
|
|
@@ -163,6 +175,7 @@ export class Archiver implements ArchiveSource {
|
|
|
163
175
|
|
|
164
176
|
if (
|
|
165
177
|
currentL1BlockNumber <= lastL1Blocks.addedBlock &&
|
|
178
|
+
currentL1BlockNumber <= lastL1Blocks.newMessages &&
|
|
166
179
|
currentL1BlockNumber <= lastL1Blocks.addedMessages &&
|
|
167
180
|
currentL1BlockNumber <= lastL1Blocks.cancelledMessages
|
|
168
181
|
) {
|
|
@@ -192,6 +205,7 @@ export class Archiver implements ArchiveSource {
|
|
|
192
205
|
|
|
193
206
|
// ********** Events that are processed per L1 block **********
|
|
194
207
|
|
|
208
|
+
// TODO(#4492): Nuke the following when purging the old inbox
|
|
195
209
|
// Process l1ToL2Messages, these are consumed as time passes, not each block
|
|
196
210
|
const retrievedPendingL1ToL2Messages = await retrieveNewPendingL1ToL2Messages(
|
|
197
211
|
this.publicClient,
|
|
@@ -235,6 +249,20 @@ export class Archiver implements ArchiveSource {
|
|
|
235
249
|
|
|
236
250
|
// ********** Events that are processed per L2 block **********
|
|
237
251
|
|
|
252
|
+
const retrievedNewL1ToL2Messages = await retrieveNewL1ToL2Messages(
|
|
253
|
+
this.publicClient,
|
|
254
|
+
this.newInboxAddress,
|
|
255
|
+
blockUntilSynced,
|
|
256
|
+
lastL1Blocks.newMessages + 1n,
|
|
257
|
+
currentL1BlockNumber,
|
|
258
|
+
);
|
|
259
|
+
await this.store.addNewL1ToL2Messages(
|
|
260
|
+
retrievedNewL1ToL2Messages.retrievedData,
|
|
261
|
+
// -1n because the function expects the last block in which the message was emitted and not the one after next
|
|
262
|
+
// TODO(#4492): Check whether this could be cleaned up - `nextEthBlockNumber` value doesn't seem to be used much
|
|
263
|
+
retrievedNewL1ToL2Messages.nextEthBlockNumber - 1n,
|
|
264
|
+
);
|
|
265
|
+
|
|
238
266
|
// Read all data from chain and then write to our stores at the end
|
|
239
267
|
const nextExpectedL2BlockNum = BigInt((await this.store.getBlockNumber()) + 1);
|
|
240
268
|
|
|
@@ -291,14 +319,6 @@ export class Archiver implements ArchiveSource {
|
|
|
291
319
|
retrievedBlocks.retrievedData.forEach((block: L2Block) => {
|
|
292
320
|
blockNumberToBodyHash[block.number] = block.header.contentCommitment.txsEffectsHash;
|
|
293
321
|
});
|
|
294
|
-
const retrievedContracts = await retrieveNewContractData(
|
|
295
|
-
this.publicClient,
|
|
296
|
-
this.contractDeploymentEmitterAddress,
|
|
297
|
-
blockUntilSynced,
|
|
298
|
-
lastL1Blocks.addedBlock + 1n,
|
|
299
|
-
currentL1BlockNumber,
|
|
300
|
-
blockNumberToBodyHash,
|
|
301
|
-
);
|
|
302
322
|
|
|
303
323
|
this.log(`Retrieved ${retrievedBlocks.retrievedData.length} block(s) from chain`);
|
|
304
324
|
|
|
@@ -323,18 +343,6 @@ export class Archiver implements ArchiveSource {
|
|
|
323
343
|
}),
|
|
324
344
|
);
|
|
325
345
|
|
|
326
|
-
// store contracts for which we have retrieved L2 blocks
|
|
327
|
-
const lastKnownL2BlockNum = retrievedBlocks.retrievedData[retrievedBlocks.retrievedData.length - 1].number;
|
|
328
|
-
await Promise.all(
|
|
329
|
-
retrievedContracts.retrievedData.map(async ([contracts, l2BlockNum]) => {
|
|
330
|
-
this.log(`Retrieved extended contract data for l2 block number: ${l2BlockNum}`);
|
|
331
|
-
if (l2BlockNum <= lastKnownL2BlockNum) {
|
|
332
|
-
await this.store.addExtendedContractData(contracts, l2BlockNum);
|
|
333
|
-
await this.storeContractDataAsClassesAndInstances(contracts, l2BlockNum);
|
|
334
|
-
}
|
|
335
|
-
}),
|
|
336
|
-
);
|
|
337
|
-
|
|
338
346
|
// from retrieved L2Blocks, confirm L1 to L2 messages that have been published
|
|
339
347
|
// from each l2block fetch all entryKeys in a flattened array:
|
|
340
348
|
this.log(`Confirming l1 to l2 messages in store`);
|
|
@@ -378,6 +386,7 @@ export class Archiver implements ArchiveSource {
|
|
|
378
386
|
* Temporary solution until we source this data from the contract class registerer and instance deployer.
|
|
379
387
|
* @param contracts - The extended contract data to be stored.
|
|
380
388
|
* @param l2BlockNum - The L2 block number to which the contract data corresponds.
|
|
389
|
+
* TODO(palla/purge-old-contract-deploy): Delete this method
|
|
381
390
|
*/
|
|
382
391
|
async storeContractDataAsClassesAndInstances(contracts: ExtendedContractData[], l2BlockNum: number) {
|
|
383
392
|
const classesAndInstances = contracts.map(extendedContractDataToContractClassAndInstance);
|
|
@@ -457,6 +466,7 @@ export class Archiver implements ArchiveSource {
|
|
|
457
466
|
/**
|
|
458
467
|
* Temporary method for creating a fake extended contract data out of classes and instances registered in the node.
|
|
459
468
|
* Used as a fallback if the extended contract data is not found.
|
|
469
|
+
* TODO(palla/purge-old-contract-deploy): Use proper classes
|
|
460
470
|
*/
|
|
461
471
|
private async makeExtendedContractDataFor(address: AztecAddress): Promise<ExtendedContractData | undefined> {
|
|
462
472
|
const instance = await this.store.getContractInstance(address);
|
|
@@ -473,23 +483,14 @@ export class Archiver implements ArchiveSource {
|
|
|
473
483
|
return ExtendedContractData.fromClassAndInstance(contractClass, instance);
|
|
474
484
|
}
|
|
475
485
|
|
|
476
|
-
/**
|
|
477
|
-
* Lookup all contract data in an L2 block.
|
|
478
|
-
* @param blockNum - The block number to get all contract data from.
|
|
479
|
-
* @returns All new contract data in the block (if found).
|
|
480
|
-
*/
|
|
481
|
-
public getExtendedContractDataInBlock(blockNum: number): Promise<ExtendedContractData[]> {
|
|
482
|
-
return this.store.getExtendedContractDataInBlock(blockNum);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
486
|
/**
|
|
486
487
|
* Lookup the contract data for this contract.
|
|
487
488
|
* Contains contract address & the ethereum portal address.
|
|
488
489
|
* @param contractAddress - The contract data address.
|
|
489
490
|
* @returns ContractData with the portal address (if we didn't throw an error).
|
|
490
491
|
*/
|
|
491
|
-
public
|
|
492
|
-
return
|
|
492
|
+
public getContractData(contractAddress: AztecAddress): Promise<ContractData | undefined> {
|
|
493
|
+
return this.makeContractDataFor(contractAddress);
|
|
493
494
|
}
|
|
494
495
|
|
|
495
496
|
/**
|
|
@@ -505,16 +506,6 @@ export class Archiver implements ArchiveSource {
|
|
|
505
506
|
return new ContractData(address, instance.portalContractAddress);
|
|
506
507
|
}
|
|
507
508
|
|
|
508
|
-
/**
|
|
509
|
-
* Lookup the L2 contract data inside a block.
|
|
510
|
-
* Contains contract address & the ethereum portal address.
|
|
511
|
-
* @param l2BlockNum - The L2 block number to get the contract data from.
|
|
512
|
-
* @returns ContractData with the portal address (if we didn't throw an error).
|
|
513
|
-
*/
|
|
514
|
-
public getContractDataInBlock(l2BlockNum: number): Promise<ContractData[] | undefined> {
|
|
515
|
-
return this.store.getContractDataInBlock(l2BlockNum);
|
|
516
|
-
}
|
|
517
|
-
|
|
518
509
|
/**
|
|
519
510
|
* Gets the public function data for a contract.
|
|
520
511
|
* @param contractAddress - The contract address containing the function to fetch.
|
|
@@ -583,6 +574,15 @@ export class Archiver implements ArchiveSource {
|
|
|
583
574
|
return this.store.getConfirmedL1ToL2Message(entryKey);
|
|
584
575
|
}
|
|
585
576
|
|
|
577
|
+
/**
|
|
578
|
+
* Gets new L1 to L2 message (to be) included in a given block.
|
|
579
|
+
* @param blockNumber - L2 block number to get messages for.
|
|
580
|
+
* @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
|
|
581
|
+
*/
|
|
582
|
+
getNewL1ToL2Messages(blockNumber: bigint): Promise<Buffer[]> {
|
|
583
|
+
return this.store.getNewL1ToL2Messages(blockNumber);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
586
|
getContractClassIds(): Promise<Fr[]> {
|
|
587
587
|
return this.store.getContractClassIds();
|
|
588
588
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Body,
|
|
3
|
-
ContractData,
|
|
4
3
|
ExtendedContractData,
|
|
5
4
|
GetUnencryptedLogsResponse,
|
|
6
5
|
L1ToL2Message,
|
|
@@ -8,6 +7,7 @@ import {
|
|
|
8
7
|
L2BlockL2Logs,
|
|
9
8
|
LogFilter,
|
|
10
9
|
LogType,
|
|
10
|
+
NewInboxLeaf,
|
|
11
11
|
TxEffect,
|
|
12
12
|
TxHash,
|
|
13
13
|
TxReceipt,
|
|
@@ -22,6 +22,9 @@ import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/c
|
|
|
22
22
|
export type ArchiverL1SynchPoint = {
|
|
23
23
|
/** The last L1 block that added a new L2 block. */
|
|
24
24
|
addedBlock: bigint;
|
|
25
|
+
/** The last L1 block that added messages from the new inbox. */
|
|
26
|
+
// TODO(#4492): Clean this up and fix the naming
|
|
27
|
+
newMessages: bigint;
|
|
25
28
|
/** The last L1 block that added pending messages */
|
|
26
29
|
addedMessages: bigint;
|
|
27
30
|
/** The last L1 block that cancelled messages */
|
|
@@ -90,11 +93,20 @@ export interface ArchiverDataStore {
|
|
|
90
93
|
blockNumber: number,
|
|
91
94
|
): Promise<boolean>;
|
|
92
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Append new L1 to L2 messages to the store.
|
|
98
|
+
* @param messages - The L1 to L2 messages to be added to the store.
|
|
99
|
+
* @param lastMessageL1BlockNumber - The L1 block number in which the last message was emitted.
|
|
100
|
+
* @returns True if the operation is successful.
|
|
101
|
+
*/
|
|
102
|
+
addNewL1ToL2Messages(messages: NewInboxLeaf[], lastMessageL1BlockNumber: bigint): Promise<boolean>;
|
|
103
|
+
|
|
93
104
|
/**
|
|
94
105
|
* Append new pending L1 to L2 messages to the store.
|
|
95
106
|
* @param messages - The L1 to L2 messages to be added to the store.
|
|
96
107
|
* @param l1BlockNumber - The block number of the L1 block that added the messages.
|
|
97
108
|
* @returns True if the operation is successful.
|
|
109
|
+
* TODO(#4492): Nuke the following when purging the old inbox
|
|
98
110
|
*/
|
|
99
111
|
addPendingL1ToL2Messages(messages: L1ToL2Message[], l1BlockNumber: bigint): Promise<boolean>;
|
|
100
112
|
|
|
@@ -103,6 +115,7 @@ export interface ArchiverDataStore {
|
|
|
103
115
|
* @param entryKeys - The entry keys to be removed from the store.
|
|
104
116
|
* @param l1BlockNumber - The block number of the L1 block that cancelled the messages.
|
|
105
117
|
* @returns True if the operation is successful.
|
|
118
|
+
* TODO(#4492): Nuke the following when purging the old inbox
|
|
106
119
|
*/
|
|
107
120
|
cancelPendingL1ToL2EntryKeys(entryKeys: Fr[], l1BlockNumber: bigint): Promise<boolean>;
|
|
108
121
|
|
|
@@ -128,6 +141,13 @@ export interface ArchiverDataStore {
|
|
|
128
141
|
*/
|
|
129
142
|
getConfirmedL1ToL2Message(entryKey: Fr): Promise<L1ToL2Message>;
|
|
130
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Gets new L1 to L2 message (to be) included in a given block.
|
|
146
|
+
* @param blockNumber - L2 block number to get messages for.
|
|
147
|
+
* @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
|
|
148
|
+
*/
|
|
149
|
+
getNewL1ToL2Messages(blockNumber: bigint): Promise<Buffer[]>;
|
|
150
|
+
|
|
131
151
|
/**
|
|
132
152
|
* Gets up to `limit` amount of logs starting from `from`.
|
|
133
153
|
* @param from - Number of the L2 block to which corresponds the first logs to be returned.
|
|
@@ -159,29 +179,6 @@ export interface ArchiverDataStore {
|
|
|
159
179
|
*/
|
|
160
180
|
getExtendedContractData(contractAddress: AztecAddress): Promise<ExtendedContractData | undefined>;
|
|
161
181
|
|
|
162
|
-
/**
|
|
163
|
-
* Lookup all extended contract data in an L2 block.
|
|
164
|
-
* @param blockNum - The block number to get all contract data from.
|
|
165
|
-
* @returns All extended contract data in the block (if found).
|
|
166
|
-
*/
|
|
167
|
-
getExtendedContractDataInBlock(blockNum: number): Promise<ExtendedContractData[]>;
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Get basic info for an L2 contract.
|
|
171
|
-
* Contains contract address & the ethereum portal address.
|
|
172
|
-
* @param contractAddress - The contract data address.
|
|
173
|
-
* @returns ContractData with the portal address (if we didn't throw an error).
|
|
174
|
-
*/
|
|
175
|
-
getContractData(contractAddress: AztecAddress): Promise<ContractData | undefined>;
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Get basic info for an all L2 contracts deployed in a block.
|
|
179
|
-
* Contains contract address & the ethereum portal address.
|
|
180
|
-
* @param l2BlockNum - Number of the L2 block where contracts were deployed.
|
|
181
|
-
* @returns ContractData with the portal address (if we didn't throw an error).
|
|
182
|
-
*/
|
|
183
|
-
getContractDataInBlock(l2BlockNum: number): Promise<ContractData[] | undefined>;
|
|
184
|
-
|
|
185
182
|
/**
|
|
186
183
|
* Gets the number of the latest L2 block processed.
|
|
187
184
|
* @returns The number of the latest L2 block processed.
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ExtendedContractData,
|
|
3
2
|
L1ToL2Message,
|
|
4
3
|
L2Block,
|
|
5
4
|
L2BlockContext,
|
|
6
5
|
LogId,
|
|
7
6
|
LogType,
|
|
7
|
+
NewInboxLeaf,
|
|
8
8
|
TxHash,
|
|
9
9
|
UnencryptedL2Log,
|
|
10
10
|
} from '@aztec/circuit-types';
|
|
11
11
|
import '@aztec/circuit-types/jest';
|
|
12
|
-
import { AztecAddress, Fr, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
|
|
12
|
+
import { AztecAddress, Fr, INITIAL_L2_BLOCK_NUM, L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/circuits.js';
|
|
13
13
|
import { makeContractClassPublic } from '@aztec/circuits.js/testing';
|
|
14
14
|
import { randomBytes } from '@aztec/foundation/crypto';
|
|
15
15
|
import { ContractClassPublic, ContractInstanceWithAddress, SerializableContractInstance } from '@aztec/types/contracts';
|
|
@@ -96,6 +96,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
96
96
|
addedBlock: 0n,
|
|
97
97
|
addedMessages: 0n,
|
|
98
98
|
cancelledMessages: 0n,
|
|
99
|
+
newMessages: 0n,
|
|
99
100
|
});
|
|
100
101
|
});
|
|
101
102
|
|
|
@@ -105,6 +106,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
105
106
|
addedBlock: blocks.at(-1)!.getL1BlockNumber(),
|
|
106
107
|
addedMessages: 0n,
|
|
107
108
|
cancelledMessages: 0n,
|
|
109
|
+
newMessages: 0n,
|
|
108
110
|
});
|
|
109
111
|
});
|
|
110
112
|
|
|
@@ -114,6 +116,16 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
114
116
|
addedBlock: 0n,
|
|
115
117
|
addedMessages: 1n,
|
|
116
118
|
cancelledMessages: 0n,
|
|
119
|
+
newMessages: 0n,
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
it('returns the L1 block number that most recently added messages from new inbox', async () => {
|
|
123
|
+
await store.addNewL1ToL2Messages([new NewInboxLeaf(0n, 0n, Buffer.alloc(32))], 1n);
|
|
124
|
+
await expect(store.getL1BlockNumber()).resolves.toEqual({
|
|
125
|
+
addedBlock: 0n,
|
|
126
|
+
addedMessages: 0n,
|
|
127
|
+
cancelledMessages: 0n,
|
|
128
|
+
newMessages: 1n,
|
|
117
129
|
});
|
|
118
130
|
});
|
|
119
131
|
it('returns the L1 block number that most recently cancelled pending messages', async () => {
|
|
@@ -124,6 +136,7 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
124
136
|
addedBlock: 0n,
|
|
125
137
|
addedMessages: 1n,
|
|
126
138
|
cancelledMessages: 2n,
|
|
139
|
+
newMessages: 0n,
|
|
127
140
|
});
|
|
128
141
|
});
|
|
129
142
|
});
|
|
@@ -209,6 +222,45 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
209
222
|
});
|
|
210
223
|
});
|
|
211
224
|
|
|
225
|
+
// TODO(#4492): Drop the "New" below once the old inbox is purged
|
|
226
|
+
describe('New L1 to L2 Messages', () => {
|
|
227
|
+
const l2BlockNumber = 13n;
|
|
228
|
+
const l1ToL2MessageSubtreeSize = 2 ** L1_TO_L2_MSG_SUBTREE_HEIGHT;
|
|
229
|
+
|
|
230
|
+
const generateBlockMessages = (blockNumber: bigint, numMessages: number) =>
|
|
231
|
+
Array.from({ length: numMessages }, (_, i) => new NewInboxLeaf(blockNumber, BigInt(i), randomBytes(32)));
|
|
232
|
+
|
|
233
|
+
it('returns messages in correct order', async () => {
|
|
234
|
+
const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize);
|
|
235
|
+
const shuffledMessages = msgs.slice().sort(() => Math.random() - 0.5);
|
|
236
|
+
await store.addNewL1ToL2Messages(shuffledMessages, 100n);
|
|
237
|
+
const retrievedMessages = await store.getNewL1ToL2Messages(l2BlockNumber);
|
|
238
|
+
|
|
239
|
+
const expectedLeavesOrder = msgs.map(msg => msg.leaf);
|
|
240
|
+
expect(expectedLeavesOrder).toEqual(retrievedMessages);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('throws if it is impossible to sequence messages correctly', async () => {
|
|
244
|
+
const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize - 1);
|
|
245
|
+
// We replace a message with index 4 with a message with index at the end of the tree
|
|
246
|
+
// --> with that there will be a gap and it will be impossible to sequence the messages
|
|
247
|
+
msgs[4] = new NewInboxLeaf(l2BlockNumber, BigInt(l1ToL2MessageSubtreeSize - 1), randomBytes(32));
|
|
248
|
+
|
|
249
|
+
await store.addNewL1ToL2Messages(msgs, 100n);
|
|
250
|
+
await expect(async () => {
|
|
251
|
+
await store.getNewL1ToL2Messages(l2BlockNumber);
|
|
252
|
+
}).rejects.toThrow(`L1 to L2 message gap found in block ${l2BlockNumber}`);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('throws if adding more messages than fits into a block', async () => {
|
|
256
|
+
const msgs = generateBlockMessages(l2BlockNumber, l1ToL2MessageSubtreeSize + 1);
|
|
257
|
+
|
|
258
|
+
await expect(async () => {
|
|
259
|
+
await store.addNewL1ToL2Messages(msgs, 100n);
|
|
260
|
+
}).rejects.toThrow(`Message index ${l1ToL2MessageSubtreeSize} out of subtree range`);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
212
264
|
describe('getPendingL1ToL2EntryKeys', () => {
|
|
213
265
|
it('returns previously stored pending L1 to L2 messages', async () => {
|
|
214
266
|
const message = L1ToL2Message.random(Fr.random());
|
|
@@ -364,119 +416,6 @@ export function describeArchiverDataStore(testName: string, getStore: () => Arch
|
|
|
364
416
|
});
|
|
365
417
|
});
|
|
366
418
|
|
|
367
|
-
describe('getContractData', () => {
|
|
368
|
-
let block: L2Block;
|
|
369
|
-
beforeEach(async () => {
|
|
370
|
-
block = L2Block.random(1);
|
|
371
|
-
await store.addBlocks([block]);
|
|
372
|
-
await store.addBlockBodies([block.body]);
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
it('returns previously stored contract data', async () => {
|
|
376
|
-
await expect(store.getContractData(block.body.txEffects[0].contractData[0].contractAddress)).resolves.toEqual(
|
|
377
|
-
block.body.txEffects[0].contractData[0],
|
|
378
|
-
);
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
it('returns undefined if contract data is not found', async () => {
|
|
382
|
-
await expect(store.getContractData(AztecAddress.random())).resolves.toBeUndefined();
|
|
383
|
-
});
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
describe('getContractDataInBlock', () => {
|
|
387
|
-
let block: L2Block;
|
|
388
|
-
beforeEach(async () => {
|
|
389
|
-
block = L2Block.random(1);
|
|
390
|
-
await store.addBlocks([block]);
|
|
391
|
-
await store.addBlockBodies([block.body]);
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
it('returns the contract data for a known block', async () => {
|
|
395
|
-
await expect(store.getContractDataInBlock(block.number)).resolves.toEqual(
|
|
396
|
-
block.body.txEffects.flatMap(txEffect => txEffect.contractData),
|
|
397
|
-
);
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
it('returns an empty array if contract data is not found', async () => {
|
|
401
|
-
await expect(store.getContractDataInBlock(block.number + 1)).resolves.toEqual([]);
|
|
402
|
-
});
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
describe('addExtendedContractData', () => {
|
|
406
|
-
it('stores extended contract data', async () => {
|
|
407
|
-
const block = L2Block.random(1);
|
|
408
|
-
await store.addBlocks([block]);
|
|
409
|
-
await store.addBlockBodies([block.body]);
|
|
410
|
-
await expect(store.addExtendedContractData([ExtendedContractData.random()], block.number)).resolves.toEqual(
|
|
411
|
-
true,
|
|
412
|
-
);
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
it('stores extended contract data for an unknown block', async () => {
|
|
416
|
-
await expect(store.addExtendedContractData([ExtendedContractData.random()], 1)).resolves.toEqual(true);
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
it('"pushes" extended contract data and does not overwrite', async () => {
|
|
420
|
-
const block = L2Block.random(1);
|
|
421
|
-
await store.addBlocks([block]);
|
|
422
|
-
await store.addBlockBodies([block.body]);
|
|
423
|
-
|
|
424
|
-
// Assuming one contract per tx, and the first two txs
|
|
425
|
-
const firstContract = ExtendedContractData.random(block.body.txEffects[0].contractData[0]);
|
|
426
|
-
await store.addExtendedContractData([firstContract], block.number);
|
|
427
|
-
|
|
428
|
-
const secondContract = ExtendedContractData.random(block.body.txEffects[1].contractData[0]);
|
|
429
|
-
await store.addExtendedContractData([secondContract], block.number);
|
|
430
|
-
|
|
431
|
-
await expect(store.getExtendedContractDataInBlock(block.number)).resolves.toEqual([
|
|
432
|
-
firstContract,
|
|
433
|
-
secondContract,
|
|
434
|
-
]);
|
|
435
|
-
});
|
|
436
|
-
});
|
|
437
|
-
|
|
438
|
-
describe('getExtendedContractData', () => {
|
|
439
|
-
let block: L2Block;
|
|
440
|
-
let extendedContractData: ExtendedContractData;
|
|
441
|
-
beforeEach(async () => {
|
|
442
|
-
block = L2Block.random(1);
|
|
443
|
-
extendedContractData = ExtendedContractData.random(block.body.txEffects[0].contractData[0]);
|
|
444
|
-
await store.addBlocks([block]);
|
|
445
|
-
await store.addBlockBodies([block.body]);
|
|
446
|
-
await store.addExtendedContractData([extendedContractData], block.number);
|
|
447
|
-
});
|
|
448
|
-
|
|
449
|
-
it('returns previously stored extended contract data', async () => {
|
|
450
|
-
await expect(store.getExtendedContractData(extendedContractData.contractData.contractAddress)).resolves.toEqual(
|
|
451
|
-
extendedContractData,
|
|
452
|
-
);
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
it('returns undefined if extended contract data is not found', async () => {
|
|
456
|
-
await expect(store.getExtendedContractData(AztecAddress.random())).resolves.toBeUndefined();
|
|
457
|
-
});
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
describe('getExtendedContractDataInBlock', () => {
|
|
461
|
-
let block: L2Block;
|
|
462
|
-
let extendedContractData: ExtendedContractData;
|
|
463
|
-
beforeEach(async () => {
|
|
464
|
-
block = L2Block.random(1);
|
|
465
|
-
extendedContractData = ExtendedContractData.random(block.body.txEffects[0].contractData[0]);
|
|
466
|
-
await store.addBlocks([block]);
|
|
467
|
-
await store.addBlockBodies([block.body]);
|
|
468
|
-
await store.addExtendedContractData([extendedContractData], block.number);
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
it('returns previously stored extended contract data', async () => {
|
|
472
|
-
await expect(store.getExtendedContractDataInBlock(block.number)).resolves.toEqual([extendedContractData]);
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
it('returns an empty array if extended contract data is not found for the block', async () => {
|
|
476
|
-
await expect(store.getExtendedContractDataInBlock(block.number + 1)).resolves.toEqual([]);
|
|
477
|
-
});
|
|
478
|
-
});
|
|
479
|
-
|
|
480
419
|
describe('getUnencryptedLogs', () => {
|
|
481
420
|
const txsPerBlock = 4;
|
|
482
421
|
const numPublicFunctionCalls = 3;
|
package/src/archiver/config.ts
CHANGED
|
@@ -58,7 +58,6 @@ export function getConfigEnvVars(): ArchiverConfig {
|
|
|
58
58
|
ARCHIVER_VIEM_POLLING_INTERVAL_MS,
|
|
59
59
|
AVAILABILITY_ORACLE_CONTRACT_ADDRESS,
|
|
60
60
|
ROLLUP_CONTRACT_ADDRESS,
|
|
61
|
-
CONTRACT_DEPLOYMENT_EMITTER_ADDRESS,
|
|
62
61
|
API_KEY,
|
|
63
62
|
INBOX_CONTRACT_ADDRESS,
|
|
64
63
|
OUTBOX_CONTRACT_ADDRESS,
|
|
@@ -74,9 +73,6 @@ export function getConfigEnvVars(): ArchiverConfig {
|
|
|
74
73
|
registryAddress: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO,
|
|
75
74
|
inboxAddress: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO,
|
|
76
75
|
outboxAddress: OUTBOX_CONTRACT_ADDRESS ? EthAddress.fromString(OUTBOX_CONTRACT_ADDRESS) : EthAddress.ZERO,
|
|
77
|
-
contractDeploymentEmitterAddress: CONTRACT_DEPLOYMENT_EMITTER_ADDRESS
|
|
78
|
-
? EthAddress.fromString(CONTRACT_DEPLOYMENT_EMITTER_ADDRESS)
|
|
79
|
-
: EthAddress.ZERO,
|
|
80
76
|
};
|
|
81
77
|
return {
|
|
82
78
|
rpcUrl: ETHEREUM_HOST || 'http://127.0.0.1:8545/',
|