@aztec/archiver 2.1.0-rc.11 → 2.1.0-rc.12
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/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +31 -16
- package/dest/archiver/errors.d.ts +1 -1
- package/dest/archiver/errors.d.ts.map +1 -1
- package/dest/archiver/errors.js +2 -2
- package/package.json +13 -13
- package/src/archiver/data_retrieval.ts +42 -19
- package/src/archiver/errors.ts +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data_retrieval.d.ts","sourceRoot":"","sources":["../../src/archiver/data_retrieval.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAEV,UAAU,EAGV,gBAAgB,EAEjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"data_retrieval.d.ts","sourceRoot":"","sources":["../../src/archiver/data_retrieval.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Blob, BlobDeserializationError } from '@aztec/blob-lib';
|
|
1
|
+
import { Blob, BlobDeserializationError, EMPTY_BLOB_VERSIONED_HASH } from '@aztec/blob-lib';
|
|
2
2
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
3
3
|
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
|
|
4
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
|
+
import { bufferToHex } from '@aztec/foundation/string';
|
|
6
7
|
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
7
8
|
import { Body, CommitteeAttestation, L2Block, PublishedL2Block } from '@aztec/stdlib/block';
|
|
8
9
|
import { Proof } from '@aztec/stdlib/proofs';
|
|
@@ -206,33 +207,47 @@ export async function getL1BlockTime(publicClient, blockNumber) {
|
|
|
206
207
|
// TODO(md): why is the proposed block header different to the actual block header?
|
|
207
208
|
// This is likely going to be a footgun
|
|
208
209
|
const header = ProposedBlockHeader.fromViem(decodedArgs.header);
|
|
210
|
+
const body = await getBlockBodyFromBlobs(blobSinkClient, blockHash, blobHashes, l2BlockNumber, logger);
|
|
211
|
+
const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
|
|
212
|
+
const stateReference = StateReference.fromViem(decodedArgs.stateReference);
|
|
213
|
+
return {
|
|
214
|
+
l2BlockNumber,
|
|
215
|
+
archiveRoot,
|
|
216
|
+
stateReference,
|
|
217
|
+
header,
|
|
218
|
+
body,
|
|
219
|
+
attestations
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
async function getBlockBodyFromBlobs(blobSinkClient, blockHash, blobHashes, l2BlockNumber, logger) {
|
|
209
223
|
const blobBodies = await blobSinkClient.getBlobSidecar(blockHash, blobHashes);
|
|
210
|
-
|
|
211
|
-
|
|
224
|
+
logger.trace(`Fetched ${blobBodies.length} blob bodies for L2 block ${l2BlockNumber}`, {
|
|
225
|
+
blobHashes: blobHashes.map(bufferToHex),
|
|
226
|
+
l2BlockNumber
|
|
227
|
+
});
|
|
228
|
+
if (blobBodies.length !== blobHashes.length) {
|
|
229
|
+
// If there is exactly one blob hash and it is the empty blob hash, we are fine with not downloading it
|
|
230
|
+
// and just defaulting to an empty block body.
|
|
231
|
+
if (blobHashes.length === 1 && blobBodies.length === 0 && blobHashes[0].equals(EMPTY_BLOB_VERSIONED_HASH)) {
|
|
232
|
+
logger.verbose(`Ignoring error fetching blob body for block ${l2BlockNumber} as it is empty`);
|
|
233
|
+
return Body.empty();
|
|
234
|
+
} else {
|
|
235
|
+
throw new NoBlobBodiesFoundError(l2BlockNumber, blobBodies.length, blobHashes.length);
|
|
236
|
+
}
|
|
212
237
|
}
|
|
213
238
|
let blockFields;
|
|
214
239
|
try {
|
|
215
240
|
blockFields = Blob.toEncodedFields(blobBodies.map((b)=>b.blob));
|
|
216
241
|
} catch (err) {
|
|
217
242
|
if (err instanceof BlobDeserializationError) {
|
|
218
|
-
logger.
|
|
243
|
+
logger.error(err.message);
|
|
219
244
|
} else {
|
|
220
|
-
logger.
|
|
245
|
+
logger.error('Unable to sync: failed to decode fetched blob, this blob was likely not created by us');
|
|
221
246
|
}
|
|
222
247
|
throw err;
|
|
223
248
|
}
|
|
224
249
|
// The blob source gives us blockFields, and we must construct the body from them:
|
|
225
|
-
|
|
226
|
-
const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
|
|
227
|
-
const stateReference = StateReference.fromViem(decodedArgs.stateReference);
|
|
228
|
-
return {
|
|
229
|
-
l2BlockNumber,
|
|
230
|
-
archiveRoot,
|
|
231
|
-
stateReference,
|
|
232
|
-
header,
|
|
233
|
-
body,
|
|
234
|
-
attestations
|
|
235
|
-
};
|
|
250
|
+
return Body.fromBlobFields(blockFields);
|
|
236
251
|
}
|
|
237
252
|
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */ export async function retrieveL1ToL2Message(inbox, leaf, fromBlock, toBlock) {
|
|
238
253
|
const logs = await inbox.getEvents.MessageSent({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare class NoBlobBodiesFoundError extends Error {
|
|
2
|
-
constructor(l2BlockNum: number);
|
|
2
|
+
constructor(l2BlockNum: number, found: number, expected: number);
|
|
3
3
|
}
|
|
4
4
|
export declare class InitialBlockNumberNotSequentialError extends Error {
|
|
5
5
|
readonly newBlockNumber: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/archiver/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,UAAU,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/archiver/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAGhE;AAED,qBAAa,oCAAqC,SAAQ,KAAK;aAE3C,cAAc,EAAE,MAAM;aACtB,mBAAmB,EAAE,MAAM,GAAG,SAAS;gBADvC,cAAc,EAAE,MAAM,EACtB,mBAAmB,EAAE,MAAM,GAAG,SAAS;CAQ1D;AAED,qBAAa,6BAA8B,SAAQ,KAAK;gBAC1C,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS;CAKjE"}
|
package/dest/archiver/errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export class NoBlobBodiesFoundError extends Error {
|
|
2
|
-
constructor(l2BlockNum){
|
|
3
|
-
super(`No blob bodies found for block ${l2BlockNum}`);
|
|
2
|
+
constructor(l2BlockNum, found, expected){
|
|
3
|
+
super(`No blob bodies found for block ${l2BlockNum} (expected ${expected} but found ${found})`);
|
|
4
4
|
}
|
|
5
5
|
}
|
|
6
6
|
export class InitialBlockNumberNotSequentialError extends Error {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/archiver",
|
|
3
|
-
"version": "2.1.0-rc.
|
|
3
|
+
"version": "2.1.0-rc.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -66,18 +66,18 @@
|
|
|
66
66
|
]
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@aztec/blob-lib": "2.1.0-rc.
|
|
70
|
-
"@aztec/blob-sink": "2.1.0-rc.
|
|
71
|
-
"@aztec/constants": "2.1.0-rc.
|
|
72
|
-
"@aztec/epoch-cache": "2.1.0-rc.
|
|
73
|
-
"@aztec/ethereum": "2.1.0-rc.
|
|
74
|
-
"@aztec/foundation": "2.1.0-rc.
|
|
75
|
-
"@aztec/kv-store": "2.1.0-rc.
|
|
76
|
-
"@aztec/l1-artifacts": "2.1.0-rc.
|
|
77
|
-
"@aztec/noir-protocol-circuits-types": "2.1.0-rc.
|
|
78
|
-
"@aztec/protocol-contracts": "2.1.0-rc.
|
|
79
|
-
"@aztec/stdlib": "2.1.0-rc.
|
|
80
|
-
"@aztec/telemetry-client": "2.1.0-rc.
|
|
69
|
+
"@aztec/blob-lib": "2.1.0-rc.12",
|
|
70
|
+
"@aztec/blob-sink": "2.1.0-rc.12",
|
|
71
|
+
"@aztec/constants": "2.1.0-rc.12",
|
|
72
|
+
"@aztec/epoch-cache": "2.1.0-rc.12",
|
|
73
|
+
"@aztec/ethereum": "2.1.0-rc.12",
|
|
74
|
+
"@aztec/foundation": "2.1.0-rc.12",
|
|
75
|
+
"@aztec/kv-store": "2.1.0-rc.12",
|
|
76
|
+
"@aztec/l1-artifacts": "2.1.0-rc.12",
|
|
77
|
+
"@aztec/noir-protocol-circuits-types": "2.1.0-rc.12",
|
|
78
|
+
"@aztec/protocol-contracts": "2.1.0-rc.12",
|
|
79
|
+
"@aztec/stdlib": "2.1.0-rc.12",
|
|
80
|
+
"@aztec/telemetry-client": "2.1.0-rc.12",
|
|
81
81
|
"@spalladino/viem": "2.38.2-eip7594.0",
|
|
82
82
|
"lodash.groupby": "^4.6.0",
|
|
83
83
|
"lodash.omit": "^4.5.0",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Blob, BlobDeserializationError } from '@aztec/blob-lib';
|
|
1
|
+
import { Blob, BlobDeserializationError, EMPTY_BLOB_VERSIONED_HASH } from '@aztec/blob-lib';
|
|
2
2
|
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
3
3
|
import type {
|
|
4
4
|
EpochProofPublicInputArgs,
|
|
@@ -14,6 +14,7 @@ import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
14
14
|
import type { ViemSignature } from '@aztec/foundation/eth-signature';
|
|
15
15
|
import { Fr } from '@aztec/foundation/fields';
|
|
16
16
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
17
|
+
import { bufferToHex } from '@aztec/foundation/string';
|
|
17
18
|
import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
18
19
|
import { Body, CommitteeAttestation, L2Block, PublishedL2Block } from '@aztec/stdlib/block';
|
|
19
20
|
import { Proof } from '@aztec/stdlib/proofs';
|
|
@@ -340,9 +341,44 @@ async function getBlockFromRollupTx(
|
|
|
340
341
|
// TODO(md): why is the proposed block header different to the actual block header?
|
|
341
342
|
// This is likely going to be a footgun
|
|
342
343
|
const header = ProposedBlockHeader.fromViem(decodedArgs.header);
|
|
344
|
+
const body = await getBlockBodyFromBlobs(blobSinkClient, blockHash!, blobHashes, l2BlockNumber, logger);
|
|
345
|
+
|
|
346
|
+
const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
|
|
347
|
+
|
|
348
|
+
const stateReference = StateReference.fromViem(decodedArgs.stateReference);
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
l2BlockNumber,
|
|
352
|
+
archiveRoot,
|
|
353
|
+
stateReference,
|
|
354
|
+
header,
|
|
355
|
+
body,
|
|
356
|
+
attestations,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async function getBlockBodyFromBlobs(
|
|
361
|
+
blobSinkClient: BlobSinkClientInterface,
|
|
362
|
+
blockHash: string,
|
|
363
|
+
blobHashes: Buffer<ArrayBufferLike>[],
|
|
364
|
+
l2BlockNumber: number,
|
|
365
|
+
logger: Logger,
|
|
366
|
+
) {
|
|
343
367
|
const blobBodies = await blobSinkClient.getBlobSidecar(blockHash, blobHashes);
|
|
344
|
-
|
|
345
|
-
|
|
368
|
+
logger.trace(`Fetched ${blobBodies.length} blob bodies for L2 block ${l2BlockNumber}`, {
|
|
369
|
+
blobHashes: blobHashes.map(bufferToHex),
|
|
370
|
+
l2BlockNumber,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
if (blobBodies.length !== blobHashes.length) {
|
|
374
|
+
// If there is exactly one blob hash and it is the empty blob hash, we are fine with not downloading it
|
|
375
|
+
// and just defaulting to an empty block body.
|
|
376
|
+
if (blobHashes.length === 1 && blobBodies.length === 0 && blobHashes[0].equals(EMPTY_BLOB_VERSIONED_HASH)) {
|
|
377
|
+
logger.verbose(`Ignoring error fetching blob body for block ${l2BlockNumber} as it is empty`);
|
|
378
|
+
return Body.empty();
|
|
379
|
+
} else {
|
|
380
|
+
throw new NoBlobBodiesFoundError(l2BlockNumber, blobBodies.length, blobHashes.length);
|
|
381
|
+
}
|
|
346
382
|
}
|
|
347
383
|
|
|
348
384
|
let blockFields: Fr[];
|
|
@@ -350,28 +386,15 @@ async function getBlockFromRollupTx(
|
|
|
350
386
|
blockFields = Blob.toEncodedFields(blobBodies.map(b => b.blob));
|
|
351
387
|
} catch (err: any) {
|
|
352
388
|
if (err instanceof BlobDeserializationError) {
|
|
353
|
-
logger.
|
|
389
|
+
logger.error(err.message);
|
|
354
390
|
} else {
|
|
355
|
-
logger.
|
|
391
|
+
logger.error('Unable to sync: failed to decode fetched blob, this blob was likely not created by us');
|
|
356
392
|
}
|
|
357
393
|
throw err;
|
|
358
394
|
}
|
|
359
395
|
|
|
360
396
|
// The blob source gives us blockFields, and we must construct the body from them:
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
|
|
364
|
-
|
|
365
|
-
const stateReference = StateReference.fromViem(decodedArgs.stateReference);
|
|
366
|
-
|
|
367
|
-
return {
|
|
368
|
-
l2BlockNumber,
|
|
369
|
-
archiveRoot,
|
|
370
|
-
stateReference,
|
|
371
|
-
header,
|
|
372
|
-
body,
|
|
373
|
-
attestations,
|
|
374
|
-
};
|
|
397
|
+
return Body.fromBlobFields(blockFields);
|
|
375
398
|
}
|
|
376
399
|
|
|
377
400
|
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */
|
package/src/archiver/errors.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export class NoBlobBodiesFoundError extends Error {
|
|
2
|
-
constructor(l2BlockNum: number) {
|
|
3
|
-
super(`No blob bodies found for block ${l2BlockNum}`);
|
|
2
|
+
constructor(l2BlockNum: number, found: number, expected: number) {
|
|
3
|
+
super(`No blob bodies found for block ${l2BlockNum} (expected ${expected} but found ${found})`);
|
|
4
4
|
}
|
|
5
5
|
}
|
|
6
6
|
|