@aztec/archiver 0.0.1-commit.9ef841308 → 0.0.1-commit.a89ec08
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/archiver.d.ts +2 -1
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +1 -0
- package/dest/config.d.ts +3 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +1 -2
- package/dest/errors.d.ts +1 -15
- package/dest/errors.d.ts.map +1 -1
- package/dest/errors.js +0 -18
- package/dest/factory.d.ts +2 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +3 -1
- package/dest/l1/calldata_retriever.d.ts +1 -1
- package/dest/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/l1/calldata_retriever.js +1 -2
- package/dest/l1/data_retrieval.d.ts +3 -6
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/l1/data_retrieval.js +6 -12
- package/dest/modules/data_source_base.d.ts +3 -3
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +4 -4
- package/dest/modules/data_store_updater.d.ts +6 -3
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +56 -5
- package/dest/modules/instrumentation.d.ts +1 -12
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +0 -10
- package/dest/modules/l1_synchronizer.d.ts +1 -1
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +13 -18
- package/dest/store/block_store.d.ts +2 -1
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +50 -5
- package/dest/store/contract_class_store.d.ts +3 -2
- package/dest/store/contract_class_store.d.ts.map +1 -1
- package/dest/store/contract_class_store.js +65 -1
- package/dest/store/kv_archiver_store.d.ts +8 -10
- package/dest/store/kv_archiver_store.d.ts.map +1 -1
- package/dest/store/kv_archiver_store.js +8 -10
- package/dest/store/log_store.d.ts +3 -6
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/store/log_store.js +6 -45
- package/dest/store/message_store.d.ts +1 -5
- package/dest/store/message_store.d.ts.map +1 -1
- package/dest/store/message_store.js +0 -13
- package/dest/test/fake_l1_state.d.ts +8 -1
- package/dest/test/fake_l1_state.d.ts.map +1 -1
- package/dest/test/fake_l1_state.js +16 -11
- package/package.json +13 -13
- package/src/archiver.ts +1 -0
- package/src/config.ts +1 -8
- package/src/errors.ts +0 -30
- package/src/factory.ts +3 -1
- package/src/l1/calldata_retriever.ts +1 -2
- package/src/l1/data_retrieval.ts +9 -17
- package/src/modules/data_source_base.ts +3 -8
- package/src/modules/data_store_updater.ts +82 -3
- package/src/modules/instrumentation.ts +0 -20
- package/src/modules/l1_synchronizer.ts +25 -29
- package/src/store/block_store.ts +62 -5
- package/src/store/contract_class_store.ts +103 -1
- package/src/store/kv_archiver_store.ts +15 -12
- package/src/store/log_store.ts +15 -60
- package/src/store/message_store.ts +0 -19
- package/src/test/fake_l1_state.ts +20 -15
|
@@ -2,7 +2,14 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
2
2
|
import { toArray } from '@aztec/foundation/iterable';
|
|
3
3
|
import { BufferReader, numToUInt8, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
4
4
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
5
|
-
import
|
|
5
|
+
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
6
|
+
import type {
|
|
7
|
+
ContractClassPublic,
|
|
8
|
+
ContractClassPublicWithBlockNumber,
|
|
9
|
+
ExecutablePrivateFunctionWithMembershipProof,
|
|
10
|
+
UtilityFunctionWithMembershipProof,
|
|
11
|
+
} from '@aztec/stdlib/contract';
|
|
12
|
+
import { Vector } from '@aztec/stdlib/types';
|
|
6
13
|
|
|
7
14
|
/**
|
|
8
15
|
* LMDB-based contract class storage for the archiver.
|
|
@@ -57,6 +64,37 @@ export class ContractClassStore {
|
|
|
57
64
|
async getContractClassIds(): Promise<Fr[]> {
|
|
58
65
|
return (await toArray(this.#contractClasses.keysAsync())).map(key => Fr.fromHexString(key));
|
|
59
66
|
}
|
|
67
|
+
|
|
68
|
+
async addFunctions(
|
|
69
|
+
contractClassId: Fr,
|
|
70
|
+
newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
|
|
71
|
+
newUtilityFunctions: UtilityFunctionWithMembershipProof[],
|
|
72
|
+
): Promise<boolean> {
|
|
73
|
+
await this.db.transactionAsync(async () => {
|
|
74
|
+
const existingClassBuffer = await this.#contractClasses.getAsync(contractClassId.toString());
|
|
75
|
+
if (!existingClassBuffer) {
|
|
76
|
+
throw new Error(`Unknown contract class ${contractClassId} when adding private functions to store`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const existingClass = deserializeContractClassPublic(existingClassBuffer);
|
|
80
|
+
const { privateFunctions: existingPrivateFns, utilityFunctions: existingUtilityFns } = existingClass;
|
|
81
|
+
|
|
82
|
+
const updatedClass: Omit<ContractClassPublicWithBlockNumber, 'id'> = {
|
|
83
|
+
...existingClass,
|
|
84
|
+
privateFunctions: [
|
|
85
|
+
...existingPrivateFns,
|
|
86
|
+
...newPrivateFunctions.filter(newFn => !existingPrivateFns.some(f => f.selector.equals(newFn.selector))),
|
|
87
|
+
],
|
|
88
|
+
utilityFunctions: [
|
|
89
|
+
...existingUtilityFns,
|
|
90
|
+
...newUtilityFunctions.filter(newFn => !existingUtilityFns.some(f => f.selector.equals(newFn.selector))),
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
await this.#contractClasses.set(contractClassId.toString(), serializeContractClassPublic(updatedClass));
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
60
98
|
}
|
|
61
99
|
|
|
62
100
|
function serializeContractClassPublic(contractClass: Omit<ContractClassPublicWithBlockNumber, 'id'>): Buffer {
|
|
@@ -64,19 +102,83 @@ function serializeContractClassPublic(contractClass: Omit<ContractClassPublicWit
|
|
|
64
102
|
contractClass.l2BlockNumber,
|
|
65
103
|
numToUInt8(contractClass.version),
|
|
66
104
|
contractClass.artifactHash,
|
|
105
|
+
contractClass.privateFunctions.length,
|
|
106
|
+
contractClass.privateFunctions.map(serializePrivateFunction),
|
|
107
|
+
contractClass.utilityFunctions.length,
|
|
108
|
+
contractClass.utilityFunctions.map(serializeUtilityFunction),
|
|
67
109
|
contractClass.packedBytecode.length,
|
|
68
110
|
contractClass.packedBytecode,
|
|
69
111
|
contractClass.privateFunctionsRoot,
|
|
70
112
|
);
|
|
71
113
|
}
|
|
72
114
|
|
|
115
|
+
function serializePrivateFunction(fn: ExecutablePrivateFunctionWithMembershipProof): Buffer {
|
|
116
|
+
return serializeToBuffer(
|
|
117
|
+
fn.selector,
|
|
118
|
+
fn.vkHash,
|
|
119
|
+
fn.bytecode.length,
|
|
120
|
+
fn.bytecode,
|
|
121
|
+
fn.functionMetadataHash,
|
|
122
|
+
fn.artifactMetadataHash,
|
|
123
|
+
fn.utilityFunctionsTreeRoot,
|
|
124
|
+
new Vector(fn.privateFunctionTreeSiblingPath),
|
|
125
|
+
fn.privateFunctionTreeLeafIndex,
|
|
126
|
+
new Vector(fn.artifactTreeSiblingPath),
|
|
127
|
+
fn.artifactTreeLeafIndex,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function serializeUtilityFunction(fn: UtilityFunctionWithMembershipProof): Buffer {
|
|
132
|
+
return serializeToBuffer(
|
|
133
|
+
fn.selector,
|
|
134
|
+
fn.bytecode.length,
|
|
135
|
+
fn.bytecode,
|
|
136
|
+
fn.functionMetadataHash,
|
|
137
|
+
fn.artifactMetadataHash,
|
|
138
|
+
fn.privateFunctionsArtifactTreeRoot,
|
|
139
|
+
new Vector(fn.artifactTreeSiblingPath),
|
|
140
|
+
fn.artifactTreeLeafIndex,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
73
144
|
function deserializeContractClassPublic(buffer: Buffer): Omit<ContractClassPublicWithBlockNumber, 'id'> {
|
|
74
145
|
const reader = BufferReader.asReader(buffer);
|
|
75
146
|
return {
|
|
76
147
|
l2BlockNumber: reader.readNumber(),
|
|
77
148
|
version: reader.readUInt8() as 1,
|
|
78
149
|
artifactHash: reader.readObject(Fr),
|
|
150
|
+
privateFunctions: reader.readVector({ fromBuffer: deserializePrivateFunction }),
|
|
151
|
+
utilityFunctions: reader.readVector({ fromBuffer: deserializeUtilityFunction }),
|
|
79
152
|
packedBytecode: reader.readBuffer(),
|
|
80
153
|
privateFunctionsRoot: reader.readObject(Fr),
|
|
81
154
|
};
|
|
82
155
|
}
|
|
156
|
+
|
|
157
|
+
function deserializePrivateFunction(buffer: Buffer | BufferReader): ExecutablePrivateFunctionWithMembershipProof {
|
|
158
|
+
const reader = BufferReader.asReader(buffer);
|
|
159
|
+
return {
|
|
160
|
+
selector: reader.readObject(FunctionSelector),
|
|
161
|
+
vkHash: reader.readObject(Fr),
|
|
162
|
+
bytecode: reader.readBuffer(),
|
|
163
|
+
functionMetadataHash: reader.readObject(Fr),
|
|
164
|
+
artifactMetadataHash: reader.readObject(Fr),
|
|
165
|
+
utilityFunctionsTreeRoot: reader.readObject(Fr),
|
|
166
|
+
privateFunctionTreeSiblingPath: reader.readVector(Fr),
|
|
167
|
+
privateFunctionTreeLeafIndex: reader.readNumber(),
|
|
168
|
+
artifactTreeSiblingPath: reader.readVector(Fr),
|
|
169
|
+
artifactTreeLeafIndex: reader.readNumber(),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function deserializeUtilityFunction(buffer: Buffer | BufferReader): UtilityFunctionWithMembershipProof {
|
|
174
|
+
const reader = BufferReader.asReader(buffer);
|
|
175
|
+
return {
|
|
176
|
+
selector: reader.readObject(FunctionSelector),
|
|
177
|
+
bytecode: reader.readBuffer(),
|
|
178
|
+
functionMetadataHash: reader.readObject(Fr),
|
|
179
|
+
artifactMetadataHash: reader.readObject(Fr),
|
|
180
|
+
privateFunctionsArtifactTreeRoot: reader.readObject(Fr),
|
|
181
|
+
artifactTreeSiblingPath: reader.readVector(Fr),
|
|
182
|
+
artifactTreeLeafIndex: reader.readNumber(),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
@@ -20,6 +20,8 @@ import type {
|
|
|
20
20
|
ContractDataSource,
|
|
21
21
|
ContractInstanceUpdateWithAddress,
|
|
22
22
|
ContractInstanceWithAddress,
|
|
23
|
+
ExecutablePrivateFunctionWithMembershipProof,
|
|
24
|
+
UtilityFunctionWithMembershipProof,
|
|
23
25
|
} from '@aztec/stdlib/contract';
|
|
24
26
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
25
27
|
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
@@ -36,7 +38,7 @@ import { ContractInstanceStore } from './contract_instance_store.js';
|
|
|
36
38
|
import { LogStore } from './log_store.js';
|
|
37
39
|
import { MessageStore } from './message_store.js';
|
|
38
40
|
|
|
39
|
-
export const ARCHIVER_DB_VERSION =
|
|
41
|
+
export const ARCHIVER_DB_VERSION = 5;
|
|
40
42
|
export const MAX_FUNCTION_SIGNATURES = 1000;
|
|
41
43
|
export const MAX_FUNCTION_NAME_LEN = 256;
|
|
42
44
|
|
|
@@ -188,6 +190,15 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
188
190
|
return this.#contractClassStore.getBytecodeCommitment(contractClassId);
|
|
189
191
|
}
|
|
190
192
|
|
|
193
|
+
/** Adds private functions to a contract class. */
|
|
194
|
+
addFunctions(
|
|
195
|
+
contractClassId: Fr,
|
|
196
|
+
privateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
|
|
197
|
+
utilityFunctions: UtilityFunctionWithMembershipProof[],
|
|
198
|
+
): Promise<boolean> {
|
|
199
|
+
return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, utilityFunctions);
|
|
200
|
+
}
|
|
201
|
+
|
|
191
202
|
/**
|
|
192
203
|
* Add new contract instances from an L2 block to the store's list.
|
|
193
204
|
* @param data - List of contract instances to be added.
|
|
@@ -459,11 +470,10 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
459
470
|
* array implies no logs match that tag.
|
|
460
471
|
* @param tags - The tags to search for.
|
|
461
472
|
* @param page - The page number (0-indexed) for pagination. Returns at most 10 logs per tag per page.
|
|
462
|
-
* @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
|
|
463
473
|
*/
|
|
464
|
-
getPrivateLogsByTags(tags: SiloedTag[], page?: number
|
|
474
|
+
getPrivateLogsByTags(tags: SiloedTag[], page?: number): Promise<TxScopedL2Log[][]> {
|
|
465
475
|
try {
|
|
466
|
-
return this.#logStore.getPrivateLogsByTags(tags, page
|
|
476
|
+
return this.#logStore.getPrivateLogsByTags(tags, page);
|
|
467
477
|
} catch (err) {
|
|
468
478
|
return Promise.reject(err);
|
|
469
479
|
}
|
|
@@ -475,16 +485,14 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
475
485
|
* @param contractAddress - The contract address to search logs for.
|
|
476
486
|
* @param tags - The tags to search for.
|
|
477
487
|
* @param page - The page number (0-indexed) for pagination. Returns at most 10 logs per tag per page.
|
|
478
|
-
* @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
|
|
479
488
|
*/
|
|
480
489
|
getPublicLogsByTagsFromContract(
|
|
481
490
|
contractAddress: AztecAddress,
|
|
482
491
|
tags: Tag[],
|
|
483
492
|
page?: number,
|
|
484
|
-
upToBlockNumber?: BlockNumber,
|
|
485
493
|
): Promise<TxScopedL2Log[][]> {
|
|
486
494
|
try {
|
|
487
|
-
return this.#logStore.getPublicLogsByTagsFromContract(contractAddress, tags, page
|
|
495
|
+
return this.#logStore.getPublicLogsByTagsFromContract(contractAddress, tags, page);
|
|
488
496
|
} catch (err) {
|
|
489
497
|
return Promise.reject(err);
|
|
490
498
|
}
|
|
@@ -591,11 +599,6 @@ export class KVArchiverDataStore implements ContractDataSource {
|
|
|
591
599
|
return this.#messageStore.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
|
|
592
600
|
}
|
|
593
601
|
|
|
594
|
-
/** Persists the inbox tree-in-progress checkpoint number from L1 state. */
|
|
595
|
-
public setInboxTreeInProgress(value: bigint): Promise<void> {
|
|
596
|
-
return this.#messageStore.setInboxTreeInProgress(value);
|
|
597
|
-
}
|
|
598
|
-
|
|
599
602
|
/** Returns an async iterator to all L1 to L2 messages on the range. */
|
|
600
603
|
public iterateL1ToL2Messages(range: CustomRange<bigint> = {}): AsyncIterableIterator<InboxMessage> {
|
|
601
604
|
return this.#messageStore.iterateL1ToL2Messages(range);
|
package/src/store/log_store.ts
CHANGED
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
} from '@aztec/stdlib/logs';
|
|
23
23
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
24
24
|
|
|
25
|
-
import { OutOfOrderLogInsertionError } from '../errors.js';
|
|
26
25
|
import type { BlockStore } from './block_store.js';
|
|
27
26
|
|
|
28
27
|
/**
|
|
@@ -166,21 +165,10 @@ export class LogStore {
|
|
|
166
165
|
|
|
167
166
|
for (const taggedLogBuffer of currentPrivateTaggedLogs) {
|
|
168
167
|
if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const lastExisting = TxScopedL2Log.fromBuffer(taggedLogBuffer.logBuffers.at(-1)!);
|
|
174
|
-
const firstNew = TxScopedL2Log.fromBuffer(newLogs[0]);
|
|
175
|
-
if (lastExisting.blockNumber > firstNew.blockNumber) {
|
|
176
|
-
throw new OutOfOrderLogInsertionError(
|
|
177
|
-
'private',
|
|
178
|
-
taggedLogBuffer.tag,
|
|
179
|
-
lastExisting.blockNumber,
|
|
180
|
-
firstNew.blockNumber,
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
privateTaggedLogs.set(taggedLogBuffer.tag, taggedLogBuffer.logBuffers.concat(newLogs));
|
|
168
|
+
privateTaggedLogs.set(
|
|
169
|
+
taggedLogBuffer.tag,
|
|
170
|
+
taggedLogBuffer.logBuffers!.concat(privateTaggedLogs.get(taggedLogBuffer.tag)!),
|
|
171
|
+
);
|
|
184
172
|
}
|
|
185
173
|
}
|
|
186
174
|
|
|
@@ -212,21 +200,10 @@ export class LogStore {
|
|
|
212
200
|
|
|
213
201
|
for (const taggedLogBuffer of currentPublicTaggedLogs) {
|
|
214
202
|
if (taggedLogBuffer.logBuffers && taggedLogBuffer.logBuffers.length > 0) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const lastExisting = TxScopedL2Log.fromBuffer(taggedLogBuffer.logBuffers.at(-1)!);
|
|
220
|
-
const firstNew = TxScopedL2Log.fromBuffer(newLogs[0]);
|
|
221
|
-
if (lastExisting.blockNumber > firstNew.blockNumber) {
|
|
222
|
-
throw new OutOfOrderLogInsertionError(
|
|
223
|
-
'public',
|
|
224
|
-
taggedLogBuffer.tag,
|
|
225
|
-
lastExisting.blockNumber,
|
|
226
|
-
firstNew.blockNumber,
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
publicTaggedLogs.set(taggedLogBuffer.tag, taggedLogBuffer.logBuffers.concat(newLogs));
|
|
203
|
+
publicTaggedLogs.set(
|
|
204
|
+
taggedLogBuffer.tag,
|
|
205
|
+
taggedLogBuffer.logBuffers!.concat(publicTaggedLogs.get(taggedLogBuffer.tag)!),
|
|
206
|
+
);
|
|
230
207
|
}
|
|
231
208
|
}
|
|
232
209
|
|
|
@@ -376,30 +353,17 @@ export class LogStore {
|
|
|
376
353
|
* array implies no logs match that tag.
|
|
377
354
|
* @param tags - The tags to search for.
|
|
378
355
|
* @param page - The page number (0-indexed) for pagination.
|
|
379
|
-
* @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
|
|
380
356
|
* @returns An array of log arrays, one per tag. Returns at most MAX_LOGS_PER_TAG logs per tag per page. If
|
|
381
357
|
* MAX_LOGS_PER_TAG logs are returned for a tag, the caller should fetch the next page to check for more logs.
|
|
382
358
|
*/
|
|
383
|
-
async getPrivateLogsByTags(
|
|
384
|
-
tags: SiloedTag[],
|
|
385
|
-
page: number = 0,
|
|
386
|
-
upToBlockNumber?: BlockNumber,
|
|
387
|
-
): Promise<TxScopedL2Log[][]> {
|
|
359
|
+
async getPrivateLogsByTags(tags: SiloedTag[], page: number = 0): Promise<TxScopedL2Log[][]> {
|
|
388
360
|
const logs = await Promise.all(tags.map(tag => this.#privateLogsByTag.getAsync(tag.toString())));
|
|
389
|
-
|
|
390
361
|
const start = page * MAX_LOGS_PER_TAG;
|
|
391
362
|
const end = start + MAX_LOGS_PER_TAG;
|
|
392
363
|
|
|
393
|
-
return logs.map(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const cutoff = deserialized.findIndex(log => log.blockNumber > upToBlockNumber);
|
|
397
|
-
if (cutoff !== -1) {
|
|
398
|
-
return deserialized.slice(0, cutoff);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
return deserialized;
|
|
402
|
-
});
|
|
364
|
+
return logs.map(
|
|
365
|
+
logBuffers => logBuffers?.slice(start, end).map(logBuffer => TxScopedL2Log.fromBuffer(logBuffer)) ?? [],
|
|
366
|
+
);
|
|
403
367
|
}
|
|
404
368
|
|
|
405
369
|
/**
|
|
@@ -408,7 +372,6 @@ export class LogStore {
|
|
|
408
372
|
* @param contractAddress - The contract address to search logs for.
|
|
409
373
|
* @param tags - The tags to search for.
|
|
410
374
|
* @param page - The page number (0-indexed) for pagination.
|
|
411
|
-
* @param upToBlockNumber - If set, only return logs from blocks up to and including this block number.
|
|
412
375
|
* @returns An array of log arrays, one per tag. Returns at most MAX_LOGS_PER_TAG logs per tag per page. If
|
|
413
376
|
* MAX_LOGS_PER_TAG logs are returned for a tag, the caller should fetch the next page to check for more logs.
|
|
414
377
|
*/
|
|
@@ -416,7 +379,6 @@ export class LogStore {
|
|
|
416
379
|
contractAddress: AztecAddress,
|
|
417
380
|
tags: Tag[],
|
|
418
381
|
page: number = 0,
|
|
419
|
-
upToBlockNumber?: BlockNumber,
|
|
420
382
|
): Promise<TxScopedL2Log[][]> {
|
|
421
383
|
const logs = await Promise.all(
|
|
422
384
|
tags.map(tag => {
|
|
@@ -427,16 +389,9 @@ export class LogStore {
|
|
|
427
389
|
const start = page * MAX_LOGS_PER_TAG;
|
|
428
390
|
const end = start + MAX_LOGS_PER_TAG;
|
|
429
391
|
|
|
430
|
-
return logs.map(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
const cutoff = deserialized.findIndex(log => log.blockNumber > upToBlockNumber);
|
|
434
|
-
if (cutoff !== -1) {
|
|
435
|
-
return deserialized.slice(0, cutoff);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
return deserialized;
|
|
439
|
-
});
|
|
392
|
+
return logs.map(
|
|
393
|
+
logBuffers => logBuffers?.slice(start, end).map(logBuffer => TxScopedL2Log.fromBuffer(logBuffer)) ?? [],
|
|
394
|
+
);
|
|
440
395
|
}
|
|
441
396
|
|
|
442
397
|
/**
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
} from '@aztec/kv-store';
|
|
15
15
|
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
16
16
|
|
|
17
|
-
import { L1ToL2MessagesNotReadyError } from '../errors.js';
|
|
18
17
|
import {
|
|
19
18
|
type InboxMessage,
|
|
20
19
|
deserializeInboxMessage,
|
|
@@ -41,8 +40,6 @@ export class MessageStore {
|
|
|
41
40
|
#lastSynchedL1Block: AztecAsyncSingleton<Buffer>;
|
|
42
41
|
/** Stores total messages stored */
|
|
43
42
|
#totalMessageCount: AztecAsyncSingleton<bigint>;
|
|
44
|
-
/** Stores the checkpoint number whose message tree is currently being filled on L1. */
|
|
45
|
-
#inboxTreeInProgress: AztecAsyncSingleton<bigint>;
|
|
46
43
|
|
|
47
44
|
#log = createLogger('archiver:message_store');
|
|
48
45
|
|
|
@@ -51,7 +48,6 @@ export class MessageStore {
|
|
|
51
48
|
this.#l1ToL2MessageIndices = db.openMap('archiver_l1_to_l2_message_indices');
|
|
52
49
|
this.#lastSynchedL1Block = db.openSingleton('archiver_last_l1_block_id');
|
|
53
50
|
this.#totalMessageCount = db.openSingleton('archiver_l1_to_l2_message_count');
|
|
54
|
-
this.#inboxTreeInProgress = db.openSingleton('archiver_inbox_tree_in_progress');
|
|
55
51
|
}
|
|
56
52
|
|
|
57
53
|
public async getTotalL1ToL2MessageCount(): Promise<bigint> {
|
|
@@ -189,22 +185,7 @@ export class MessageStore {
|
|
|
189
185
|
return msg ? deserializeInboxMessage(msg) : undefined;
|
|
190
186
|
}
|
|
191
187
|
|
|
192
|
-
/** Returns the inbox tree-in-progress checkpoint number from L1, or undefined if not yet set. */
|
|
193
|
-
public getInboxTreeInProgress(): Promise<bigint | undefined> {
|
|
194
|
-
return this.#inboxTreeInProgress.getAsync();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/** Persists the inbox tree-in-progress checkpoint number from L1 state. */
|
|
198
|
-
public async setInboxTreeInProgress(value: bigint): Promise<void> {
|
|
199
|
-
await this.#inboxTreeInProgress.set(value);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
188
|
public async getL1ToL2Messages(checkpointNumber: CheckpointNumber): Promise<Fr[]> {
|
|
203
|
-
const treeInProgress = await this.#inboxTreeInProgress.getAsync();
|
|
204
|
-
if (treeInProgress !== undefined && BigInt(checkpointNumber) >= treeInProgress) {
|
|
205
|
-
throw new L1ToL2MessagesNotReadyError(checkpointNumber, treeInProgress);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
189
|
const messages: Fr[] = [];
|
|
209
190
|
|
|
210
191
|
const [startIndex, endIndex] = InboxLeaf.indexRangeForCheckpoint(checkpointNumber);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { BlobClientInterface } from '@aztec/blob-client/client';
|
|
2
2
|
import { type Blob, getBlobsPerL1Block, getPrefixedEthBlobCommitments } from '@aztec/blob-lib';
|
|
3
|
-
import { INITIAL_CHECKPOINT_NUMBER } from '@aztec/constants';
|
|
4
3
|
import type { CheckpointProposedLog, InboxContract, MessageSentLog, RollupContract } from '@aztec/ethereum/contracts';
|
|
5
4
|
import { MULTI_CALL_3_ADDRESS } from '@aztec/ethereum/contracts';
|
|
6
5
|
import type { ViemPublicClient } from '@aztec/ethereum/types';
|
|
@@ -332,6 +331,21 @@ export class FakeL1State {
|
|
|
332
331
|
this.updatePendingCheckpointNumber();
|
|
333
332
|
}
|
|
334
333
|
|
|
334
|
+
/**
|
|
335
|
+
* Moves a checkpoint to a different L1 block number (simulates L1 reorg that
|
|
336
|
+
* re-includes the same checkpoint transaction in a different block).
|
|
337
|
+
* The checkpoint content stays the same — only the L1 metadata changes.
|
|
338
|
+
* Auto-updates pending status.
|
|
339
|
+
*/
|
|
340
|
+
moveCheckpointToL1Block(checkpointNumber: CheckpointNumber, newL1BlockNumber: bigint): void {
|
|
341
|
+
for (const cpData of this.checkpoints) {
|
|
342
|
+
if (cpData.checkpointNumber === checkpointNumber) {
|
|
343
|
+
cpData.l1BlockNumber = newL1BlockNumber;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
this.updatePendingCheckpointNumber();
|
|
347
|
+
}
|
|
348
|
+
|
|
335
349
|
/**
|
|
336
350
|
* Removes messages after a given total index (simulates L1 reorg).
|
|
337
351
|
* Auto-updates rolling hash.
|
|
@@ -451,22 +465,13 @@ export class FakeL1State {
|
|
|
451
465
|
createMockInboxContract(_publicClient: MockProxy<ViemPublicClient>): MockProxy<InboxContract> {
|
|
452
466
|
const mockInbox = mock<InboxContract>();
|
|
453
467
|
|
|
454
|
-
mockInbox.getState.mockImplementation(() =>
|
|
455
|
-
|
|
456
|
-
// after its messages are sealed, so treeInProgress > checkpointNumber for all published checkpoints.
|
|
457
|
-
const maxFromMessages =
|
|
458
|
-
this.messages.length > 0 ? Math.max(...this.messages.map(m => Number(m.checkpointNumber))) + 1 : 0;
|
|
459
|
-
const maxFromCheckpoints =
|
|
460
|
-
this.checkpoints.length > 0
|
|
461
|
-
? Math.max(...this.checkpoints.filter(cp => !cp.pruned).map(cp => Number(cp.checkpointNumber))) + 1
|
|
462
|
-
: 0;
|
|
463
|
-
const treeInProgress = Math.max(maxFromMessages, maxFromCheckpoints, INITIAL_CHECKPOINT_NUMBER);
|
|
464
|
-
return Promise.resolve({
|
|
468
|
+
mockInbox.getState.mockImplementation(() =>
|
|
469
|
+
Promise.resolve({
|
|
465
470
|
messagesRollingHash: this.messagesRollingHash,
|
|
466
471
|
totalMessagesInserted: BigInt(this.messages.length),
|
|
467
|
-
treeInProgress:
|
|
468
|
-
})
|
|
469
|
-
|
|
472
|
+
treeInProgress: 0n,
|
|
473
|
+
}),
|
|
474
|
+
);
|
|
470
475
|
|
|
471
476
|
// Mock the wrapper methods for fetching message events
|
|
472
477
|
mockInbox.getMessageSentEvents.mockImplementation((fromBlock: bigint, toBlock: bigint) =>
|