@aztec/archiver 0.76.4 → 0.77.0-testnet-ignition.21
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 +1 -1
- package/dest/archiver/archiver.d.ts +22 -10
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +762 -713
- package/dest/archiver/archiver_store.d.ts +20 -7
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store.js +4 -2
- package/dest/archiver/archiver_store_test_suite.d.ts +2 -2
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +398 -227
- package/dest/archiver/config.d.ts +1 -1
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +10 -12
- package/dest/archiver/data_retrieval.d.ts +17 -14
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +90 -88
- package/dest/archiver/errors.js +1 -2
- package/dest/archiver/index.d.ts +1 -1
- package/dest/archiver/index.d.ts.map +1 -1
- package/dest/archiver/index.js +0 -1
- package/dest/archiver/instrumentation.d.ts +3 -1
- package/dest/archiver/instrumentation.d.ts.map +1 -1
- package/dest/archiver/instrumentation.js +37 -17
- package/dest/archiver/kv_archiver_store/block_store.d.ts +5 -3
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +125 -130
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +45 -37
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +10 -2
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +54 -15
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +16 -9
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +143 -160
- package/dest/archiver/kv_archiver_store/log_store.d.ts +5 -3
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +296 -255
- package/dest/archiver/kv_archiver_store/message_store.d.ts +3 -3
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +45 -50
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts +2 -2
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/nullifier_store.js +36 -43
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +2 -2
- 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 +17 -26
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +16 -7
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +287 -247
- package/dest/archiver/structs/data_retrieval.js +5 -2
- package/dest/archiver/structs/published.js +1 -2
- package/dest/factory.d.ts +20 -6
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +54 -30
- package/dest/index.js +0 -1
- package/dest/rpc/index.d.ts +2 -1
- package/dest/rpc/index.d.ts.map +1 -1
- package/dest/rpc/index.js +8 -4
- package/dest/test/index.js +0 -1
- package/dest/test/mock_archiver.d.ts +3 -2
- package/dest/test/mock_archiver.d.ts.map +1 -1
- package/dest/test/mock_archiver.js +8 -13
- package/dest/test/mock_l1_to_l2_message_source.d.ts +2 -2
- package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
- package/dest/test/mock_l1_to_l2_message_source.js +4 -4
- package/dest/test/mock_l2_block_source.d.ts +5 -3
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +71 -68
- package/package.json +15 -16
- package/src/archiver/archiver.ts +149 -89
- package/src/archiver/archiver_store.ts +27 -27
- package/src/archiver/archiver_store_test_suite.ts +22 -15
- package/src/archiver/config.ts +1 -1
- package/src/archiver/data_retrieval.ts +32 -44
- package/src/archiver/index.ts +1 -1
- package/src/archiver/instrumentation.ts +11 -1
- package/src/archiver/kv_archiver_store/block_store.ts +10 -4
- package/src/archiver/kv_archiver_store/contract_class_store.ts +9 -9
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +81 -3
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +44 -29
- package/src/archiver/kv_archiver_store/log_store.ts +56 -32
- package/src/archiver/kv_archiver_store/message_store.ts +4 -3
- package/src/archiver/kv_archiver_store/nullifier_store.ts +3 -2
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +3 -3
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +110 -57
- package/src/factory.ts +44 -25
- package/src/rpc/index.ts +2 -6
- package/src/test/mock_archiver.ts +3 -2
- package/src/test/mock_l1_to_l2_message_source.ts +2 -2
- package/src/test/mock_l2_block_source.ts +16 -15
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
import { Blob, BlobDeserializationError } from '@aztec/blob-lib';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { AppendOnlyTreeSnapshot, BlockHeader, Fr, Proof } from '@aztec/circuits.js';
|
|
2
|
+
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
3
|
+
import type { EpochProofPublicInputArgs, ViemPublicClient } from '@aztec/ethereum';
|
|
5
4
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
|
+
import type { ViemSignature } from '@aztec/foundation/eth-signature';
|
|
7
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
8
8
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
9
9
|
import { numToUInt32BE } from '@aztec/foundation/serialize';
|
|
10
10
|
import { ForwarderAbi, type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
11
|
+
import { Body, L2Block } from '@aztec/stdlib/block';
|
|
12
|
+
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
13
|
+
import { Proof } from '@aztec/stdlib/proofs';
|
|
14
|
+
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
15
|
+
import { BlockHeader } from '@aztec/stdlib/tx';
|
|
11
16
|
|
|
12
17
|
import {
|
|
13
|
-
type Chain,
|
|
14
18
|
type GetContractEventsReturnType,
|
|
15
19
|
type GetContractReturnType,
|
|
16
20
|
type Hex,
|
|
17
|
-
type HttpTransport,
|
|
18
|
-
type PublicClient,
|
|
19
21
|
decodeFunctionData,
|
|
20
22
|
getAbiItem,
|
|
21
23
|
hexToBytes,
|
|
22
24
|
} from 'viem';
|
|
23
25
|
|
|
24
26
|
import { NoBlobBodiesFoundError } from './errors.js';
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
+
import type { DataRetrieval } from './structs/data_retrieval.js';
|
|
28
|
+
import type { L1Published, L1PublishedData } from './structs/published.js';
|
|
27
29
|
|
|
28
30
|
/**
|
|
29
31
|
* Fetches new L2 blocks.
|
|
@@ -35,8 +37,8 @@ import { type L1Published, type L1PublishedData } from './structs/published.js';
|
|
|
35
37
|
* @returns An array of block; as well as the next eth block to search from.
|
|
36
38
|
*/
|
|
37
39
|
export async function retrieveBlocksFromRollup(
|
|
38
|
-
rollup: GetContractReturnType<typeof RollupAbi,
|
|
39
|
-
publicClient:
|
|
40
|
+
rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>,
|
|
41
|
+
publicClient: ViemPublicClient,
|
|
40
42
|
blobSinkClient: BlobSinkClientInterface,
|
|
41
43
|
searchStartBlock: bigint,
|
|
42
44
|
searchEndBlock: bigint,
|
|
@@ -76,7 +78,9 @@ export async function retrieveBlocksFromRollup(
|
|
|
76
78
|
retrievedBlocks.push(...newBlocks);
|
|
77
79
|
searchStartBlock = lastLog.blockNumber! + 1n;
|
|
78
80
|
} while (searchStartBlock <= searchEndBlock);
|
|
79
|
-
|
|
81
|
+
|
|
82
|
+
// The asyncpool from processL2BlockProposedLogs will not necessarily return the blocks in order, so we sort them before returning.
|
|
83
|
+
return retrievedBlocks.sort((a, b) => Number(a.l1.blockNumber - b.l1.blockNumber));
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
/**
|
|
@@ -87,8 +91,8 @@ export async function retrieveBlocksFromRollup(
|
|
|
87
91
|
* @returns - An array blocks.
|
|
88
92
|
*/
|
|
89
93
|
export async function processL2BlockProposedLogs(
|
|
90
|
-
rollup: GetContractReturnType<typeof RollupAbi,
|
|
91
|
-
publicClient:
|
|
94
|
+
rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>,
|
|
95
|
+
publicClient: ViemPublicClient,
|
|
92
96
|
blobSinkClient: BlobSinkClientInterface,
|
|
93
97
|
logs: GetContractEventsReturnType<typeof RollupAbi, 'L2BlockProposed'>,
|
|
94
98
|
logger: Logger,
|
|
@@ -130,7 +134,7 @@ export async function processL2BlockProposedLogs(
|
|
|
130
134
|
return retrievedBlocks;
|
|
131
135
|
}
|
|
132
136
|
|
|
133
|
-
export async function getL1BlockTime(publicClient:
|
|
137
|
+
export async function getL1BlockTime(publicClient: ViemPublicClient, blockNumber: bigint): Promise<bigint> {
|
|
134
138
|
const block = await publicClient.getBlock({ blockNumber, includeTransactions: false });
|
|
135
139
|
return block.timestamp;
|
|
136
140
|
}
|
|
@@ -196,7 +200,7 @@ function extractRollupProposeCalldata(forwarderData: Hex, rollupAddress: Hex): H
|
|
|
196
200
|
* @returns L2 block from the calldata, deserialized
|
|
197
201
|
*/
|
|
198
202
|
async function getBlockFromRollupTx(
|
|
199
|
-
publicClient:
|
|
203
|
+
publicClient: ViemPublicClient,
|
|
200
204
|
blobSinkClient: BlobSinkClientInterface,
|
|
201
205
|
txHash: `0x${string}`,
|
|
202
206
|
blobHashes: Buffer[], // WORKTODO(md): buffer32?
|
|
@@ -216,8 +220,7 @@ async function getBlockFromRollupTx(
|
|
|
216
220
|
throw new Error(`Unexpected rollup method called ${rollupFunctionName}`);
|
|
217
221
|
}
|
|
218
222
|
|
|
219
|
-
|
|
220
|
-
const [decodedArgs, , bodyHex, blobInputs] = rollupArgs! as readonly [
|
|
223
|
+
const [decodedArgs, , blobInputs] = rollupArgs! as readonly [
|
|
221
224
|
{
|
|
222
225
|
header: Hex;
|
|
223
226
|
archive: Hex;
|
|
@@ -229,7 +232,6 @@ async function getBlockFromRollupTx(
|
|
|
229
232
|
},
|
|
230
233
|
ViemSignature[],
|
|
231
234
|
Hex,
|
|
232
|
-
Hex,
|
|
233
235
|
];
|
|
234
236
|
|
|
235
237
|
const header = BlockHeader.fromBuffer(Buffer.from(hexToBytes(decodedArgs.header)));
|
|
@@ -238,8 +240,6 @@ async function getBlockFromRollupTx(
|
|
|
238
240
|
throw new NoBlobBodiesFoundError(Number(l2BlockNum));
|
|
239
241
|
}
|
|
240
242
|
|
|
241
|
-
// TODO(#9101): Once calldata is removed, we can remove this field encoding and update
|
|
242
|
-
// Body.fromBlobFields to accept blob buffers directly
|
|
243
243
|
let blockFields: Fr[];
|
|
244
244
|
try {
|
|
245
245
|
blockFields = Blob.toEncodedFields(blobBodies);
|
|
@@ -252,22 +252,10 @@ async function getBlockFromRollupTx(
|
|
|
252
252
|
throw err;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
//
|
|
256
|
-
|
|
257
|
-
// verify the block body vs the blob as below.
|
|
258
|
-
const blockBody = Body.fromBuffer(Buffer.from(hexToBytes(bodyHex)));
|
|
259
|
-
|
|
260
|
-
// TODO(#9101): The below reconstruction is currently redundant, but once we extract blobs will be the way to construct blocks.
|
|
261
|
-
// The blob source will give us blockFields, and we must construct the body from them:
|
|
262
|
-
// TODO(#8954): When logs are refactored into fields, we won't need to inject them here.
|
|
263
|
-
const reconstructedBlock = Body.fromBlobFields(blockFields, blockBody.contractClassLogs);
|
|
264
|
-
|
|
265
|
-
if (!reconstructedBlock.toBuffer().equals(blockBody.toBuffer())) {
|
|
266
|
-
// TODO(#9101): Remove below check (without calldata there will be nothing to check against)
|
|
267
|
-
throw new Error(`Block reconstructed from blob fields does not match`);
|
|
268
|
-
}
|
|
255
|
+
// The blob source gives us blockFields, and we must construct the body from them:
|
|
256
|
+
const blockBody = Body.fromBlobFields(blockFields);
|
|
269
257
|
|
|
270
|
-
// TODO
|
|
258
|
+
// TODO: Will this ever throw now that we do not get blocks from calldata at all?
|
|
271
259
|
const blobCheck = await Blob.getBlobs(blockFields);
|
|
272
260
|
if (Blob.getEthBlobEvaluationInputs(blobCheck) !== blobInputs) {
|
|
273
261
|
// NB: We can just check the blobhash here, which is the first 32 bytes of blobInputs
|
|
@@ -305,7 +293,7 @@ async function getBlockFromRollupTx(
|
|
|
305
293
|
* @returns An array of InboxLeaf and next eth block to search from.
|
|
306
294
|
*/
|
|
307
295
|
export async function retrieveL1ToL2Messages(
|
|
308
|
-
inbox: GetContractReturnType<typeof InboxAbi,
|
|
296
|
+
inbox: GetContractReturnType<typeof InboxAbi, ViemPublicClient>,
|
|
309
297
|
searchStartBlock: bigint,
|
|
310
298
|
searchEndBlock: bigint,
|
|
311
299
|
): Promise<DataRetrieval<InboxLeaf>> {
|
|
@@ -342,7 +330,7 @@ export async function retrieveL1ToL2Messages(
|
|
|
342
330
|
|
|
343
331
|
/** Retrieves L2ProofVerified events from the rollup contract. */
|
|
344
332
|
export async function retrieveL2ProofVerifiedEvents(
|
|
345
|
-
publicClient:
|
|
333
|
+
publicClient: ViemPublicClient,
|
|
346
334
|
rollupAddress: EthAddress,
|
|
347
335
|
searchStartBlock: bigint,
|
|
348
336
|
searchEndBlock?: bigint,
|
|
@@ -365,7 +353,7 @@ export async function retrieveL2ProofVerifiedEvents(
|
|
|
365
353
|
|
|
366
354
|
/** Retrieve submitted proofs from the rollup contract */
|
|
367
355
|
export async function retrieveL2ProofsFromRollup(
|
|
368
|
-
publicClient:
|
|
356
|
+
publicClient: ViemPublicClient,
|
|
369
357
|
rollupAddress: EthAddress,
|
|
370
358
|
searchStartBlock: bigint,
|
|
371
359
|
searchEndBlock?: bigint,
|
|
@@ -401,7 +389,7 @@ export type SubmitBlockProof = {
|
|
|
401
389
|
* @returns L2 block metadata (header and archive) from the calldata, deserialized
|
|
402
390
|
*/
|
|
403
391
|
export async function getProofFromSubmitProofTx(
|
|
404
|
-
publicClient:
|
|
392
|
+
publicClient: ViemPublicClient,
|
|
405
393
|
txHash: `0x${string}`,
|
|
406
394
|
expectedProverId: Fr,
|
|
407
395
|
): Promise<SubmitBlockProof> {
|
|
@@ -418,7 +406,7 @@ export async function getProofFromSubmitProofTx(
|
|
|
418
406
|
{
|
|
419
407
|
start: bigint;
|
|
420
408
|
end: bigint;
|
|
421
|
-
args:
|
|
409
|
+
args: EpochProofPublicInputArgs;
|
|
422
410
|
fees: readonly Hex[];
|
|
423
411
|
aggregationObject: Hex;
|
|
424
412
|
proof: Hex;
|
|
@@ -426,8 +414,8 @@ export async function getProofFromSubmitProofTx(
|
|
|
426
414
|
];
|
|
427
415
|
|
|
428
416
|
aggregationObject = Buffer.from(hexToBytes(decodedArgs.aggregationObject));
|
|
429
|
-
proverId = Fr.fromHexString(decodedArgs.args
|
|
430
|
-
archiveRoot = Fr.fromHexString(decodedArgs.args
|
|
417
|
+
proverId = Fr.fromHexString(decodedArgs.args.proverId);
|
|
418
|
+
archiveRoot = Fr.fromHexString(decodedArgs.args.endArchive);
|
|
431
419
|
proof = Proof.fromBuffer(Buffer.from(hexToBytes(decodedArgs.proof)));
|
|
432
420
|
} else {
|
|
433
421
|
throw new Error(`Unexpected proof method called ${functionName}`);
|
package/src/archiver/index.ts
CHANGED
|
@@ -2,6 +2,6 @@ export * from './archiver.js';
|
|
|
2
2
|
export * from './config.js';
|
|
3
3
|
export { type L1Published, type L1PublishedData } from './structs/published.js';
|
|
4
4
|
export { MemoryArchiverStore } from './memory_archiver_store/memory_archiver_store.js';
|
|
5
|
-
export { ArchiverDataStore } from './archiver_store.js';
|
|
5
|
+
export type { ArchiverDataStore } from './archiver_store.js';
|
|
6
6
|
export { KVArchiverDataStore } from './kv_archiver_store/kv_archiver_store.js';
|
|
7
7
|
export { ContractInstanceStore } from './kv_archiver_store/contract_instance_store.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type L2Block } from '@aztec/circuit-types';
|
|
2
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import type { L2Block } from '@aztec/stdlib/block';
|
|
3
3
|
import {
|
|
4
4
|
Attributes,
|
|
5
5
|
type Gauge,
|
|
@@ -20,6 +20,7 @@ export class ArchiverInstrumentation {
|
|
|
20
20
|
private txCount: UpDownCounter;
|
|
21
21
|
private syncDuration: Histogram;
|
|
22
22
|
private l1BlocksSynced: UpDownCounter;
|
|
23
|
+
private l1BlockHeight: Gauge;
|
|
23
24
|
private proofsSubmittedDelay: Histogram;
|
|
24
25
|
private proofsSubmittedCount: UpDownCounter;
|
|
25
26
|
private dbMetrics: LmdbMetrics;
|
|
@@ -62,6 +63,11 @@ export class ArchiverInstrumentation {
|
|
|
62
63
|
valueType: ValueType.INT,
|
|
63
64
|
});
|
|
64
65
|
|
|
66
|
+
this.l1BlockHeight = meter.createGauge(Metrics.ARCHIVER_L1_BLOCK_HEIGHT, {
|
|
67
|
+
description: 'The height of the latest L1 block processed by the archiver',
|
|
68
|
+
valueType: ValueType.INT,
|
|
69
|
+
});
|
|
70
|
+
|
|
65
71
|
this.dbMetrics = new LmdbMetrics(
|
|
66
72
|
meter,
|
|
67
73
|
{
|
|
@@ -119,4 +125,8 @@ export class ArchiverInstrumentation {
|
|
|
119
125
|
});
|
|
120
126
|
}
|
|
121
127
|
}
|
|
128
|
+
|
|
129
|
+
public updateL1BlockHeight(blockNumber: bigint) {
|
|
130
|
+
this.l1BlockHeight.record(Number(blockNumber));
|
|
131
|
+
}
|
|
122
132
|
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { AppendOnlyTreeSnapshot, type AztecAddress, BlockHeader, INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js';
|
|
1
|
+
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
3
2
|
import { toArray } from '@aztec/foundation/iterable';
|
|
4
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
4
|
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncSingleton, Range } from '@aztec/kv-store';
|
|
5
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
6
|
+
import { Body, type InBlock, L2Block, L2BlockHash } from '@aztec/stdlib/block';
|
|
7
|
+
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
8
|
+
import { BlockHeader, TxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
6
9
|
|
|
7
|
-
import {
|
|
10
|
+
import type { L1Published, L1PublishedData } from '../structs/published.js';
|
|
11
|
+
|
|
12
|
+
export { type TxEffect, type TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
8
13
|
|
|
9
14
|
type BlockIndexValue = [blockNumber: number, index: number];
|
|
10
15
|
|
|
@@ -101,7 +106,8 @@ export class BlockStore {
|
|
|
101
106
|
const block = await this.getBlock(blockNumber);
|
|
102
107
|
|
|
103
108
|
if (block === undefined) {
|
|
104
|
-
|
|
109
|
+
this.#log.warn(`Cannot remove block ${blockNumber} from the store since we don't have it`);
|
|
110
|
+
continue;
|
|
105
111
|
}
|
|
106
112
|
await this.#blocks.delete(block.data.number);
|
|
107
113
|
await Promise.all(block.data.body.txEffects.map(tx => this.#txIndex.delete(tx.txHash.toString())));
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type ContractClassPublic,
|
|
3
|
-
type ContractClassPublicWithBlockNumber,
|
|
4
|
-
type ExecutablePrivateFunctionWithMembershipProof,
|
|
5
|
-
Fr,
|
|
6
|
-
FunctionSelector,
|
|
7
|
-
type UnconstrainedFunctionWithMembershipProof,
|
|
8
|
-
Vector,
|
|
9
|
-
} from '@aztec/circuits.js';
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
10
2
|
import { toArray } from '@aztec/foundation/iterable';
|
|
11
3
|
import { BufferReader, numToUInt8, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
12
4
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
5
|
+
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
6
|
+
import type {
|
|
7
|
+
ContractClassPublic,
|
|
8
|
+
ContractClassPublicWithBlockNumber,
|
|
9
|
+
ExecutablePrivateFunctionWithMembershipProof,
|
|
10
|
+
UnconstrainedFunctionWithMembershipProof,
|
|
11
|
+
} from '@aztec/stdlib/contract';
|
|
12
|
+
import { Vector } from '@aztec/stdlib/types';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* LMDB implementation of the ArchiverDataStore interface.
|
|
@@ -1,14 +1,25 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { Fr } from '@aztec/foundation/fields';
|
|
2
2
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
3
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
+
import {
|
|
5
|
+
type ContractInstanceUpdateWithAddress,
|
|
6
|
+
type ContractInstanceWithAddress,
|
|
7
|
+
SerializableContractInstance,
|
|
8
|
+
SerializableContractInstanceUpdate,
|
|
9
|
+
} from '@aztec/stdlib/contract';
|
|
10
|
+
|
|
11
|
+
type ContractInstanceUpdateKey = [string, number] | [string, number, number];
|
|
3
12
|
|
|
4
13
|
/**
|
|
5
14
|
* LMDB implementation of the ArchiverDataStore interface.
|
|
6
15
|
*/
|
|
7
16
|
export class ContractInstanceStore {
|
|
8
17
|
#contractInstances: AztecAsyncMap<string, Buffer>;
|
|
18
|
+
#contractInstanceUpdates: AztecAsyncMap<ContractInstanceUpdateKey, Buffer>;
|
|
9
19
|
|
|
10
20
|
constructor(db: AztecAsyncKVStore) {
|
|
11
21
|
this.#contractInstances = db.openMap('archiver_contract_instances');
|
|
22
|
+
this.#contractInstanceUpdates = db.openMap('archiver_contract_instance_updates');
|
|
12
23
|
}
|
|
13
24
|
|
|
14
25
|
addContractInstance(contractInstance: ContractInstanceWithAddress): Promise<void> {
|
|
@@ -22,8 +33,75 @@ export class ContractInstanceStore {
|
|
|
22
33
|
return this.#contractInstances.delete(contractInstance.address.toString());
|
|
23
34
|
}
|
|
24
35
|
|
|
25
|
-
|
|
36
|
+
getUpdateKey(contractAddress: AztecAddress, blockNumber: number, logIndex?: number): ContractInstanceUpdateKey {
|
|
37
|
+
if (logIndex === undefined) {
|
|
38
|
+
return [contractAddress.toString(), blockNumber];
|
|
39
|
+
} else {
|
|
40
|
+
return [contractAddress.toString(), blockNumber, logIndex];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
addContractInstanceUpdate(
|
|
45
|
+
contractInstanceUpdate: ContractInstanceUpdateWithAddress,
|
|
46
|
+
blockNumber: number,
|
|
47
|
+
logIndex: number,
|
|
48
|
+
): Promise<void> {
|
|
49
|
+
return this.#contractInstanceUpdates.set(
|
|
50
|
+
this.getUpdateKey(contractInstanceUpdate.address, blockNumber, logIndex),
|
|
51
|
+
new SerializableContractInstanceUpdate(contractInstanceUpdate).toBuffer(),
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
deleteContractInstanceUpdate(
|
|
56
|
+
contractInstanceUpdate: ContractInstanceUpdateWithAddress,
|
|
57
|
+
blockNumber: number,
|
|
58
|
+
logIndex: number,
|
|
59
|
+
): Promise<void> {
|
|
60
|
+
return this.#contractInstanceUpdates.delete(
|
|
61
|
+
this.getUpdateKey(contractInstanceUpdate.address, blockNumber, logIndex),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async getCurrentContractInstanceClassId(
|
|
66
|
+
address: AztecAddress,
|
|
67
|
+
blockNumber: number,
|
|
68
|
+
originalClassId: Fr,
|
|
69
|
+
): Promise<Fr> {
|
|
70
|
+
// We need to find the last update before the given block number
|
|
71
|
+
const queryResult = await this.#contractInstanceUpdates
|
|
72
|
+
.valuesAsync({
|
|
73
|
+
reverse: true,
|
|
74
|
+
end: this.getUpdateKey(address, blockNumber + 1), // No update can match this key since it doesn't have a log index. We want the highest key <= blockNumber
|
|
75
|
+
limit: 1,
|
|
76
|
+
})
|
|
77
|
+
.next();
|
|
78
|
+
if (queryResult.done) {
|
|
79
|
+
return originalClassId;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const serializedUpdate = queryResult.value;
|
|
83
|
+
const update = SerializableContractInstanceUpdate.fromBuffer(serializedUpdate);
|
|
84
|
+
if (blockNumber < update.blockOfChange) {
|
|
85
|
+
return update.prevContractClassId.isZero() ? originalClassId : update.prevContractClassId;
|
|
86
|
+
}
|
|
87
|
+
return update.newContractClassId;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async getContractInstance(
|
|
91
|
+
address: AztecAddress,
|
|
92
|
+
blockNumber: number,
|
|
93
|
+
): Promise<ContractInstanceWithAddress | undefined> {
|
|
26
94
|
const contractInstance = await this.#contractInstances.getAsync(address.toString());
|
|
27
|
-
|
|
95
|
+
if (!contractInstance) {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const instance = SerializableContractInstance.fromBuffer(contractInstance).withAddress(address);
|
|
100
|
+
instance.currentContractClassId = await this.getCurrentContractInstanceClassId(
|
|
101
|
+
address,
|
|
102
|
+
blockNumber,
|
|
103
|
+
instance.originalContractClassId,
|
|
104
|
+
);
|
|
105
|
+
return instance;
|
|
28
106
|
}
|
|
29
107
|
}
|
|
@@ -1,32 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type GetContractClassLogsResponse,
|
|
3
|
-
type GetPublicLogsResponse,
|
|
4
|
-
type InBlock,
|
|
5
|
-
type InboxLeaf,
|
|
6
|
-
type L2Block,
|
|
7
|
-
type LogFilter,
|
|
8
|
-
type TxHash,
|
|
9
|
-
type TxReceipt,
|
|
10
|
-
type TxScopedL2Log,
|
|
11
|
-
} from '@aztec/circuit-types';
|
|
12
|
-
import {
|
|
13
|
-
type BlockHeader,
|
|
14
|
-
type ContractClassPublic,
|
|
15
|
-
type ContractInstanceWithAddress,
|
|
16
|
-
type ExecutablePrivateFunctionWithMembershipProof,
|
|
17
|
-
type Fr,
|
|
18
|
-
type PrivateLog,
|
|
19
|
-
type UnconstrainedFunctionWithMembershipProof,
|
|
20
|
-
} from '@aztec/circuits.js';
|
|
21
|
-
import { FunctionSelector } from '@aztec/foundation/abi';
|
|
22
|
-
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
1
|
+
import type { Fr } from '@aztec/foundation/fields';
|
|
23
2
|
import { toArray } from '@aztec/foundation/iterable';
|
|
24
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
import
|
|
28
|
-
import {
|
|
29
|
-
import
|
|
4
|
+
import type { AztecAsyncKVStore, StoreSize } from '@aztec/kv-store';
|
|
5
|
+
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
6
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
|
+
import type { InBlock, L2Block } from '@aztec/stdlib/block';
|
|
8
|
+
import type {
|
|
9
|
+
ContractClassPublic,
|
|
10
|
+
ContractInstanceUpdateWithAddress,
|
|
11
|
+
ContractInstanceWithAddress,
|
|
12
|
+
ExecutablePrivateFunctionWithMembershipProof,
|
|
13
|
+
UnconstrainedFunctionWithMembershipProof,
|
|
14
|
+
} from '@aztec/stdlib/contract';
|
|
15
|
+
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
16
|
+
import { type LogFilter, PrivateLog, type TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
17
|
+
import type { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
18
|
+
import type { BlockHeader, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
19
|
+
|
|
20
|
+
import type { ArchiverDataStore, ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
21
|
+
import type { DataRetrieval } from '../structs/data_retrieval.js';
|
|
22
|
+
import type { L1Published } from '../structs/published.js';
|
|
30
23
|
import { BlockStore } from './block_store.js';
|
|
31
24
|
import { ContractClassStore } from './contract_class_store.js';
|
|
32
25
|
import { ContractInstanceStore } from './contract_instance_store.js';
|
|
@@ -83,8 +76,8 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
83
76
|
return this.#contractClassStore.getContractClassIds();
|
|
84
77
|
}
|
|
85
78
|
|
|
86
|
-
getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
|
|
87
|
-
const contract = this.#contractInstanceStore.getContractInstance(address);
|
|
79
|
+
async getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
|
|
80
|
+
const contract = this.#contractInstanceStore.getContractInstance(address, await this.getSynchedL2BlockNumber());
|
|
88
81
|
return contract;
|
|
89
82
|
}
|
|
90
83
|
|
|
@@ -126,6 +119,28 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
126
119
|
return (await Promise.all(data.map(c => this.#contractInstanceStore.deleteContractInstance(c)))).every(Boolean);
|
|
127
120
|
}
|
|
128
121
|
|
|
122
|
+
async addContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], blockNumber: number): Promise<boolean> {
|
|
123
|
+
return (
|
|
124
|
+
await Promise.all(
|
|
125
|
+
data.map((update, logIndex) =>
|
|
126
|
+
this.#contractInstanceStore.addContractInstanceUpdate(update, blockNumber, logIndex),
|
|
127
|
+
),
|
|
128
|
+
)
|
|
129
|
+
).every(Boolean);
|
|
130
|
+
}
|
|
131
|
+
async deleteContractInstanceUpdates(
|
|
132
|
+
data: ContractInstanceUpdateWithAddress[],
|
|
133
|
+
blockNumber: number,
|
|
134
|
+
): Promise<boolean> {
|
|
135
|
+
return (
|
|
136
|
+
await Promise.all(
|
|
137
|
+
data.map((update, logIndex) =>
|
|
138
|
+
this.#contractInstanceStore.deleteContractInstanceUpdate(update, blockNumber, logIndex),
|
|
139
|
+
),
|
|
140
|
+
)
|
|
141
|
+
).every(Boolean);
|
|
142
|
+
}
|
|
143
|
+
|
|
129
144
|
/**
|
|
130
145
|
* Append new blocks to the store's list.
|
|
131
146
|
* @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
|
|
@@ -1,26 +1,22 @@
|
|
|
1
|
+
import { INITIAL_L2_BLOCK_NUM, MAX_NOTE_HASHES_PER_TX, PUBLIC_LOG_DATA_SIZE_IN_FIELDS } from '@aztec/constants';
|
|
2
|
+
import type { Fr } from '@aztec/foundation/fields';
|
|
3
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
+
import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
|
|
5
|
+
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
6
|
+
import type { L2Block } from '@aztec/stdlib/block';
|
|
7
|
+
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
1
8
|
import {
|
|
2
|
-
|
|
9
|
+
ContractClassLog,
|
|
10
|
+
ExtendedContractClassLog,
|
|
3
11
|
ExtendedPublicLog,
|
|
4
|
-
ExtendedUnencryptedL2Log,
|
|
5
|
-
type GetContractClassLogsResponse,
|
|
6
|
-
type GetPublicLogsResponse,
|
|
7
|
-
type L2Block,
|
|
8
12
|
type LogFilter,
|
|
9
13
|
LogId,
|
|
14
|
+
PrivateLog,
|
|
15
|
+
PublicLog,
|
|
10
16
|
TxScopedL2Log,
|
|
11
|
-
|
|
12
|
-
} from '@aztec/circuit-types';
|
|
13
|
-
import { type Fr, PrivateLog, PublicLog } from '@aztec/circuits.js';
|
|
14
|
-
import {
|
|
15
|
-
INITIAL_L2_BLOCK_NUM,
|
|
16
|
-
MAX_NOTE_HASHES_PER_TX,
|
|
17
|
-
PUBLIC_LOG_DATA_SIZE_IN_FIELDS,
|
|
18
|
-
} from '@aztec/circuits.js/constants';
|
|
19
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
20
|
-
import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
|
|
21
|
-
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
17
|
+
} from '@aztec/stdlib/logs';
|
|
22
18
|
|
|
23
|
-
import {
|
|
19
|
+
import type { BlockStore } from './block_store.js';
|
|
24
20
|
|
|
25
21
|
/**
|
|
26
22
|
* A store for logs
|
|
@@ -173,8 +169,18 @@ export class LogStore {
|
|
|
173
169
|
)
|
|
174
170
|
.flat();
|
|
175
171
|
|
|
172
|
+
const contractClassLogsInBlock = block.body.txEffects
|
|
173
|
+
.map((txEffect, txIndex) =>
|
|
174
|
+
[
|
|
175
|
+
numToUInt32BE(txIndex),
|
|
176
|
+
numToUInt32BE(txEffect.contractClassLogs.length),
|
|
177
|
+
txEffect.contractClassLogs.map(log => log.toBuffer()),
|
|
178
|
+
].flat(),
|
|
179
|
+
)
|
|
180
|
+
.flat();
|
|
181
|
+
|
|
176
182
|
await this.#publicLogsByBlock.set(block.number, Buffer.concat(publicLogsInBlock));
|
|
177
|
-
await this.#contractClassLogsByBlock.set(block.number,
|
|
183
|
+
await this.#contractClassLogsByBlock.set(block.number, Buffer.concat(contractClassLogsInBlock));
|
|
178
184
|
}
|
|
179
185
|
|
|
180
186
|
return true;
|
|
@@ -345,13 +351,22 @@ export class LogStore {
|
|
|
345
351
|
if (typeof blockNumber !== 'number' || typeof txIndex !== 'number') {
|
|
346
352
|
return { logs: [], maxLogsHit: false };
|
|
347
353
|
}
|
|
348
|
-
const contractClassLogsBuffer = await this.#contractClassLogsByBlock.getAsync(blockNumber);
|
|
349
|
-
const contractClassLogsInBlock =
|
|
350
|
-
? ContractClass2BlockL2Logs.fromBuffer(contractClassLogsBuffer)
|
|
351
|
-
: new ContractClass2BlockL2Logs([]);
|
|
352
|
-
const txLogs = contractClassLogsInBlock.txLogs[txIndex].unrollLogs();
|
|
354
|
+
const contractClassLogsBuffer = (await this.#contractClassLogsByBlock.getAsync(blockNumber)) ?? Buffer.alloc(0);
|
|
355
|
+
const contractClassLogsInBlock: [ContractClassLog[]] = [[]];
|
|
353
356
|
|
|
354
|
-
const
|
|
357
|
+
const reader = new BufferReader(contractClassLogsBuffer);
|
|
358
|
+
while (reader.remainingBytes() > 0) {
|
|
359
|
+
const indexOfTx = reader.readNumber();
|
|
360
|
+
const numLogsInTx = reader.readNumber();
|
|
361
|
+
contractClassLogsInBlock[indexOfTx] = [];
|
|
362
|
+
for (let i = 0; i < numLogsInTx; i++) {
|
|
363
|
+
contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const txLogs = contractClassLogsInBlock[txIndex];
|
|
368
|
+
|
|
369
|
+
const logs: ExtendedContractClassLog[] = [];
|
|
355
370
|
const maxLogsHit = this.#accumulateLogs(logs, blockNumber, txIndex, txLogs, filter);
|
|
356
371
|
|
|
357
372
|
return { logs, maxLogsHit };
|
|
@@ -369,16 +384,25 @@ export class LogStore {
|
|
|
369
384
|
};
|
|
370
385
|
}
|
|
371
386
|
|
|
372
|
-
const logs:
|
|
387
|
+
const logs: ExtendedContractClassLog[] = [];
|
|
373
388
|
|
|
374
389
|
let maxLogsHit = false;
|
|
375
390
|
loopOverBlocks: for await (const [blockNumber, logBuffer] of this.#contractClassLogsByBlock.entriesAsync({
|
|
376
391
|
start,
|
|
377
392
|
end,
|
|
378
393
|
})) {
|
|
379
|
-
const contractClassLogsInBlock =
|
|
380
|
-
|
|
381
|
-
|
|
394
|
+
const contractClassLogsInBlock: [ContractClassLog[]] = [[]];
|
|
395
|
+
const reader = new BufferReader(logBuffer);
|
|
396
|
+
while (reader.remainingBytes() > 0) {
|
|
397
|
+
const indexOfTx = reader.readNumber();
|
|
398
|
+
const numLogsInTx = reader.readNumber();
|
|
399
|
+
contractClassLogsInBlock[indexOfTx] = [];
|
|
400
|
+
for (let i = 0; i < numLogsInTx; i++) {
|
|
401
|
+
contractClassLogsInBlock[indexOfTx].push(reader.readObject(ContractClassLog));
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
for (let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < contractClassLogsInBlock.length; txIndex++) {
|
|
405
|
+
const txLogs = contractClassLogsInBlock[txIndex];
|
|
382
406
|
maxLogsHit = this.#accumulateLogs(logs, blockNumber, txIndex, txLogs, filter);
|
|
383
407
|
if (maxLogsHit) {
|
|
384
408
|
this.#log.debug(`Max logs hit at block ${blockNumber}`);
|
|
@@ -391,10 +415,10 @@ export class LogStore {
|
|
|
391
415
|
}
|
|
392
416
|
|
|
393
417
|
#accumulateLogs(
|
|
394
|
-
results: (
|
|
418
|
+
results: (ExtendedContractClassLog | ExtendedPublicLog)[],
|
|
395
419
|
blockNumber: number,
|
|
396
420
|
txIndex: number,
|
|
397
|
-
txLogs: (
|
|
421
|
+
txLogs: (ContractClassLog | PublicLog)[],
|
|
398
422
|
filter: LogFilter,
|
|
399
423
|
): boolean {
|
|
400
424
|
let maxLogsHit = false;
|
|
@@ -402,8 +426,8 @@ export class LogStore {
|
|
|
402
426
|
for (; logIndex < txLogs.length; logIndex++) {
|
|
403
427
|
const log = txLogs[logIndex];
|
|
404
428
|
if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
|
|
405
|
-
if (log instanceof
|
|
406
|
-
results.push(new
|
|
429
|
+
if (log instanceof ContractClassLog) {
|
|
430
|
+
results.push(new ExtendedContractClassLog(new LogId(blockNumber, txIndex, logIndex), log));
|
|
407
431
|
} else {
|
|
408
432
|
results.push(new ExtendedPublicLog(new LogId(blockNumber, txIndex, logIndex), log));
|
|
409
433
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Fr
|
|
1
|
+
import { L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/constants';
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncSingleton } from '@aztec/kv-store';
|
|
5
|
+
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
5
6
|
|
|
6
|
-
import {
|
|
7
|
+
import type { DataRetrieval } from '../structs/data_retrieval.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* LMDB implementation of the ArchiverDataStore interface.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
|
|
2
|
+
import type { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
5
|
+
import type { InBlock, L2Block } from '@aztec/stdlib/block';
|
|
5
6
|
|
|
6
7
|
export class NullifierStore {
|
|
7
8
|
#nullifiersToBlockNumber: AztecAsyncMap<string, number>;
|