@aztec/archiver 0.0.1-commit.6c91f13 → 0.0.1-commit.96bb3f7

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.
Files changed (45) hide show
  1. package/README.md +14 -14
  2. package/dest/archiver/archiver.d.ts +13 -10
  3. package/dest/archiver/archiver.d.ts.map +1 -1
  4. package/dest/archiver/archiver.js +514 -57
  5. package/dest/archiver/archiver_store.d.ts +11 -4
  6. package/dest/archiver/archiver_store.d.ts.map +1 -1
  7. package/dest/archiver/archiver_store_test_suite.d.ts +1 -1
  8. package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
  9. package/dest/archiver/archiver_store_test_suite.js +6 -6
  10. package/dest/archiver/config.js +2 -2
  11. package/dest/archiver/instrumentation.d.ts +1 -1
  12. package/dest/archiver/instrumentation.d.ts.map +1 -1
  13. package/dest/archiver/instrumentation.js +15 -63
  14. package/dest/archiver/kv_archiver_store/block_store.d.ts +11 -4
  15. package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
  16. package/dest/archiver/kv_archiver_store/block_store.js +22 -3
  17. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +5 -4
  18. package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
  19. package/dest/archiver/kv_archiver_store/kv_archiver_store.js +3 -0
  20. package/dest/archiver/l1/calldata_retriever.d.ts +2 -2
  21. package/dest/archiver/l1/calldata_retriever.d.ts.map +1 -1
  22. package/dest/archiver/l1/calldata_retriever.js +2 -2
  23. package/dest/archiver/l1/validate_trace.js +1 -1
  24. package/dest/archiver/validation.d.ts +4 -4
  25. package/dest/archiver/validation.d.ts.map +1 -1
  26. package/dest/archiver/validation.js +1 -1
  27. package/dest/test/mock_l1_to_l2_message_source.d.ts +2 -2
  28. package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
  29. package/dest/test/mock_l1_to_l2_message_source.js +12 -3
  30. package/dest/test/mock_l2_block_source.d.ts +8 -4
  31. package/dest/test/mock_l2_block_source.d.ts.map +1 -1
  32. package/dest/test/mock_l2_block_source.js +65 -19
  33. package/package.json +13 -13
  34. package/src/archiver/archiver.ts +179 -71
  35. package/src/archiver/archiver_store.ts +11 -3
  36. package/src/archiver/archiver_store_test_suite.ts +12 -13
  37. package/src/archiver/config.ts +2 -2
  38. package/src/archiver/instrumentation.ts +14 -63
  39. package/src/archiver/kv_archiver_store/block_store.ts +35 -7
  40. package/src/archiver/kv_archiver_store/kv_archiver_store.ts +7 -3
  41. package/src/archiver/l1/calldata_retriever.ts +2 -2
  42. package/src/archiver/l1/validate_trace.ts +1 -1
  43. package/src/archiver/validation.ts +6 -6
  44. package/src/test/mock_l1_to_l2_message_source.ts +10 -4
  45. package/src/test/mock_l2_block_source.ts +76 -18
@@ -1,10 +1,377 @@
1
- function _ts_decorate(decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1
+ function applyDecs2203RFactory() {
2
+ function createAddInitializerMethod(initializers, decoratorFinishedRef) {
3
+ return function addInitializer(initializer) {
4
+ assertNotFinished(decoratorFinishedRef, "addInitializer");
5
+ assertCallable(initializer, "An initializer");
6
+ initializers.push(initializer);
7
+ };
8
+ }
9
+ function memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value) {
10
+ var kindStr;
11
+ switch(kind){
12
+ case 1:
13
+ kindStr = "accessor";
14
+ break;
15
+ case 2:
16
+ kindStr = "method";
17
+ break;
18
+ case 3:
19
+ kindStr = "getter";
20
+ break;
21
+ case 4:
22
+ kindStr = "setter";
23
+ break;
24
+ default:
25
+ kindStr = "field";
26
+ }
27
+ var ctx = {
28
+ kind: kindStr,
29
+ name: isPrivate ? "#" + name : name,
30
+ static: isStatic,
31
+ private: isPrivate,
32
+ metadata: metadata
33
+ };
34
+ var decoratorFinishedRef = {
35
+ v: false
36
+ };
37
+ ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
38
+ var get, set;
39
+ if (kind === 0) {
40
+ if (isPrivate) {
41
+ get = desc.get;
42
+ set = desc.set;
43
+ } else {
44
+ get = function() {
45
+ return this[name];
46
+ };
47
+ set = function(v) {
48
+ this[name] = v;
49
+ };
50
+ }
51
+ } else if (kind === 2) {
52
+ get = function() {
53
+ return desc.value;
54
+ };
55
+ } else {
56
+ if (kind === 1 || kind === 3) {
57
+ get = function() {
58
+ return desc.get.call(this);
59
+ };
60
+ }
61
+ if (kind === 1 || kind === 4) {
62
+ set = function(v) {
63
+ desc.set.call(this, v);
64
+ };
65
+ }
66
+ }
67
+ ctx.access = get && set ? {
68
+ get: get,
69
+ set: set
70
+ } : get ? {
71
+ get: get
72
+ } : {
73
+ set: set
74
+ };
75
+ try {
76
+ return dec(value, ctx);
77
+ } finally{
78
+ decoratorFinishedRef.v = true;
79
+ }
80
+ }
81
+ function assertNotFinished(decoratorFinishedRef, fnName) {
82
+ if (decoratorFinishedRef.v) {
83
+ throw new Error("attempted to call " + fnName + " after decoration was finished");
84
+ }
85
+ }
86
+ function assertCallable(fn, hint) {
87
+ if (typeof fn !== "function") {
88
+ throw new TypeError(hint + " must be a function");
89
+ }
90
+ }
91
+ function assertValidReturnValue(kind, value) {
92
+ var type = typeof value;
93
+ if (kind === 1) {
94
+ if (type !== "object" || value === null) {
95
+ throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
96
+ }
97
+ if (value.get !== undefined) {
98
+ assertCallable(value.get, "accessor.get");
99
+ }
100
+ if (value.set !== undefined) {
101
+ assertCallable(value.set, "accessor.set");
102
+ }
103
+ if (value.init !== undefined) {
104
+ assertCallable(value.init, "accessor.init");
105
+ }
106
+ } else if (type !== "function") {
107
+ var hint;
108
+ if (kind === 0) {
109
+ hint = "field";
110
+ } else if (kind === 10) {
111
+ hint = "class";
112
+ } else {
113
+ hint = "method";
114
+ }
115
+ throw new TypeError(hint + " decorators must return a function or void 0");
116
+ }
117
+ }
118
+ function applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata) {
119
+ var decs = decInfo[0];
120
+ var desc, init, value;
121
+ if (isPrivate) {
122
+ if (kind === 0 || kind === 1) {
123
+ desc = {
124
+ get: decInfo[3],
125
+ set: decInfo[4]
126
+ };
127
+ } else if (kind === 3) {
128
+ desc = {
129
+ get: decInfo[3]
130
+ };
131
+ } else if (kind === 4) {
132
+ desc = {
133
+ set: decInfo[3]
134
+ };
135
+ } else {
136
+ desc = {
137
+ value: decInfo[3]
138
+ };
139
+ }
140
+ } else if (kind !== 0) {
141
+ desc = Object.getOwnPropertyDescriptor(base, name);
142
+ }
143
+ if (kind === 1) {
144
+ value = {
145
+ get: desc.get,
146
+ set: desc.set
147
+ };
148
+ } else if (kind === 2) {
149
+ value = desc.value;
150
+ } else if (kind === 3) {
151
+ value = desc.get;
152
+ } else if (kind === 4) {
153
+ value = desc.set;
154
+ }
155
+ var newValue, get, set;
156
+ if (typeof decs === "function") {
157
+ newValue = memberDec(decs, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
158
+ if (newValue !== void 0) {
159
+ assertValidReturnValue(kind, newValue);
160
+ if (kind === 0) {
161
+ init = newValue;
162
+ } else if (kind === 1) {
163
+ init = newValue.init;
164
+ get = newValue.get || value.get;
165
+ set = newValue.set || value.set;
166
+ value = {
167
+ get: get,
168
+ set: set
169
+ };
170
+ } else {
171
+ value = newValue;
172
+ }
173
+ }
174
+ } else {
175
+ for(var i = decs.length - 1; i >= 0; i--){
176
+ var dec = decs[i];
177
+ newValue = memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
178
+ if (newValue !== void 0) {
179
+ assertValidReturnValue(kind, newValue);
180
+ var newInit;
181
+ if (kind === 0) {
182
+ newInit = newValue;
183
+ } else if (kind === 1) {
184
+ newInit = newValue.init;
185
+ get = newValue.get || value.get;
186
+ set = newValue.set || value.set;
187
+ value = {
188
+ get: get,
189
+ set: set
190
+ };
191
+ } else {
192
+ value = newValue;
193
+ }
194
+ if (newInit !== void 0) {
195
+ if (init === void 0) {
196
+ init = newInit;
197
+ } else if (typeof init === "function") {
198
+ init = [
199
+ init,
200
+ newInit
201
+ ];
202
+ } else {
203
+ init.push(newInit);
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }
209
+ if (kind === 0 || kind === 1) {
210
+ if (init === void 0) {
211
+ init = function(instance, init) {
212
+ return init;
213
+ };
214
+ } else if (typeof init !== "function") {
215
+ var ownInitializers = init;
216
+ init = function(instance, init) {
217
+ var value = init;
218
+ for(var i = 0; i < ownInitializers.length; i++){
219
+ value = ownInitializers[i].call(instance, value);
220
+ }
221
+ return value;
222
+ };
223
+ } else {
224
+ var originalInitializer = init;
225
+ init = function(instance, init) {
226
+ return originalInitializer.call(instance, init);
227
+ };
228
+ }
229
+ ret.push(init);
230
+ }
231
+ if (kind !== 0) {
232
+ if (kind === 1) {
233
+ desc.get = value.get;
234
+ desc.set = value.set;
235
+ } else if (kind === 2) {
236
+ desc.value = value;
237
+ } else if (kind === 3) {
238
+ desc.get = value;
239
+ } else if (kind === 4) {
240
+ desc.set = value;
241
+ }
242
+ if (isPrivate) {
243
+ if (kind === 1) {
244
+ ret.push(function(instance, args) {
245
+ return value.get.call(instance, args);
246
+ });
247
+ ret.push(function(instance, args) {
248
+ return value.set.call(instance, args);
249
+ });
250
+ } else if (kind === 2) {
251
+ ret.push(value);
252
+ } else {
253
+ ret.push(function(instance, args) {
254
+ return value.call(instance, args);
255
+ });
256
+ }
257
+ } else {
258
+ Object.defineProperty(base, name, desc);
259
+ }
260
+ }
261
+ }
262
+ function applyMemberDecs(Class, decInfos, metadata) {
263
+ var ret = [];
264
+ var protoInitializers;
265
+ var staticInitializers;
266
+ var existingProtoNonFields = new Map();
267
+ var existingStaticNonFields = new Map();
268
+ for(var i = 0; i < decInfos.length; i++){
269
+ var decInfo = decInfos[i];
270
+ if (!Array.isArray(decInfo)) continue;
271
+ var kind = decInfo[1];
272
+ var name = decInfo[2];
273
+ var isPrivate = decInfo.length > 3;
274
+ var isStatic = kind >= 5;
275
+ var base;
276
+ var initializers;
277
+ if (isStatic) {
278
+ base = Class;
279
+ kind = kind - 5;
280
+ staticInitializers = staticInitializers || [];
281
+ initializers = staticInitializers;
282
+ } else {
283
+ base = Class.prototype;
284
+ protoInitializers = protoInitializers || [];
285
+ initializers = protoInitializers;
286
+ }
287
+ if (kind !== 0 && !isPrivate) {
288
+ var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
289
+ var existingKind = existingNonFields.get(name) || 0;
290
+ if (existingKind === true || existingKind === 3 && kind !== 4 || existingKind === 4 && kind !== 3) {
291
+ throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
292
+ } else if (!existingKind && kind > 2) {
293
+ existingNonFields.set(name, kind);
294
+ } else {
295
+ existingNonFields.set(name, true);
296
+ }
297
+ }
298
+ applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
299
+ }
300
+ pushInitializers(ret, protoInitializers);
301
+ pushInitializers(ret, staticInitializers);
302
+ return ret;
303
+ }
304
+ function pushInitializers(ret, initializers) {
305
+ if (initializers) {
306
+ ret.push(function(instance) {
307
+ for(var i = 0; i < initializers.length; i++){
308
+ initializers[i].call(instance);
309
+ }
310
+ return instance;
311
+ });
312
+ }
313
+ }
314
+ function applyClassDecs(targetClass, classDecs, metadata) {
315
+ if (classDecs.length > 0) {
316
+ var initializers = [];
317
+ var newClass = targetClass;
318
+ var name = targetClass.name;
319
+ for(var i = classDecs.length - 1; i >= 0; i--){
320
+ var decoratorFinishedRef = {
321
+ v: false
322
+ };
323
+ try {
324
+ var nextNewClass = classDecs[i](newClass, {
325
+ kind: "class",
326
+ name: name,
327
+ addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
328
+ metadata
329
+ });
330
+ } finally{
331
+ decoratorFinishedRef.v = true;
332
+ }
333
+ if (nextNewClass !== undefined) {
334
+ assertValidReturnValue(10, nextNewClass);
335
+ newClass = nextNewClass;
336
+ }
337
+ }
338
+ return [
339
+ defineMetadata(newClass, metadata),
340
+ function() {
341
+ for(var i = 0; i < initializers.length; i++){
342
+ initializers[i].call(newClass);
343
+ }
344
+ }
345
+ ];
346
+ }
347
+ }
348
+ function defineMetadata(Class, metadata) {
349
+ return Object.defineProperty(Class, Symbol.metadata || Symbol.for("Symbol.metadata"), {
350
+ configurable: true,
351
+ enumerable: true,
352
+ value: metadata
353
+ });
354
+ }
355
+ return function applyDecs2203R(targetClass, memberDecs, classDecs, parentClass) {
356
+ if (parentClass !== void 0) {
357
+ var parentMetadata = parentClass[Symbol.metadata || Symbol.for("Symbol.metadata")];
358
+ }
359
+ var metadata = Object.create(parentMetadata === void 0 ? null : parentMetadata);
360
+ var e = applyMemberDecs(targetClass, memberDecs, metadata);
361
+ if (!classDecs.length) defineMetadata(targetClass, metadata);
362
+ return {
363
+ e: e,
364
+ get c () {
365
+ return applyClassDecs(targetClass, classDecs, metadata);
366
+ }
367
+ };
368
+ };
369
+ }
370
+ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
371
+ return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
6
372
  }
7
- import { GENESIS_BLOCK_HEADER_HASH } from '@aztec/constants';
373
+ var _dec, _dec1, _dec2, _dec3, _dec4, _initProto;
374
+ import { GENESIS_BLOCK_HEADER_HASH, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
8
375
  import { EpochCache } from '@aztec/epoch-cache';
9
376
  import { createEthereumChain } from '@aztec/ethereum/chain';
10
377
  import { BlockTagTooOldError, InboxContract, RollupContract } from '@aztec/ethereum/contracts';
@@ -21,12 +388,12 @@ import { DateProvider, Timer, elapsed } from '@aztec/foundation/timer';
21
388
  import { isDefined } from '@aztec/foundation/types';
22
389
  import { ContractClassPublishedEvent, PrivateFunctionBroadcastedEvent, UtilityFunctionBroadcastedEvent } from '@aztec/protocol-contracts/class-registry';
23
390
  import { ContractInstancePublishedEvent, ContractInstanceUpdatedEvent } from '@aztec/protocol-contracts/instance-registry';
24
- import { CommitteeAttestation, L2Block, L2BlockSourceEvents, PublishedL2Block } from '@aztec/stdlib/block';
391
+ import { CommitteeAttestation, GENESIS_CHECKPOINT_HEADER_HASH, L2Block, L2BlockSourceEvents, PublishedL2Block } from '@aztec/stdlib/block';
25
392
  import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
26
393
  import { computePublicBytecodeCommitment, isValidPrivateFunctionMembershipProof, isValidUtilityFunctionMembershipProof } from '@aztec/stdlib/contract';
27
394
  import { getEpochAtSlot, getEpochNumberAtTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
28
395
  import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
29
- import { getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
396
+ import { execInSpan, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
30
397
  import { EventEmitter } from 'events';
31
398
  import groupBy from 'lodash.groupby';
32
399
  import { createPublicClient, fallback, http } from 'viem';
@@ -39,11 +406,12 @@ function mapArchiverConfig(config) {
39
406
  return {
40
407
  pollingIntervalMs: config.archiverPollingIntervalMS,
41
408
  batchSize: config.archiverBatchSize,
42
- skipValidateBlockAttestations: config.skipValidateBlockAttestations,
409
+ skipValidateCheckpointAttestations: config.skipValidateCheckpointAttestations,
43
410
  maxAllowedEthClientDriftSeconds: config.maxAllowedEthClientDriftSeconds,
44
411
  ethereumAllowNoDebugHosts: config.ethereumAllowNoDebugHosts
45
412
  };
46
413
  }
414
+ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _dec2 = trackSpan('Archiver.handleEpochPrune'), _dec3 = trackSpan('Archiver.handleL1ToL2Messages'), _dec4 = trackSpan('Archiver.handleCheckpoints');
47
415
  /**
48
416
  * Pulls checkpoints in a non-blocking manner and provides interface for their retrieval.
49
417
  * Responsible for handling robust L1 polling so that other components do not need to
@@ -60,6 +428,35 @@ function mapArchiverConfig(config) {
60
428
  instrumentation;
61
429
  l1constants;
62
430
  log;
431
+ static{
432
+ ({ e: [_initProto] } = _apply_decs_2203_r(this, [
433
+ [
434
+ _dec,
435
+ 2,
436
+ "syncFromL1"
437
+ ],
438
+ [
439
+ _dec1,
440
+ 2,
441
+ "sync"
442
+ ],
443
+ [
444
+ _dec2,
445
+ 2,
446
+ "handleEpochPrune"
447
+ ],
448
+ [
449
+ _dec3,
450
+ 2,
451
+ "handleL1ToL2Messages"
452
+ ],
453
+ [
454
+ _dec4,
455
+ 2,
456
+ "handleCheckpoints"
457
+ ]
458
+ ], []));
459
+ }
63
460
  /** A loop in which we will be continually fetching new checkpoints. */ runningPromise;
64
461
  rollup;
65
462
  inbox;
@@ -81,7 +478,7 @@ function mapArchiverConfig(config) {
81
478
  * @param store - An archiver data store for storage & retrieval of blocks, encrypted logs & contract data.
82
479
  * @param log - A logger.
83
480
  */ constructor(publicClient, debugClient, l1Addresses, dataStore, config, blobClient, epochCache, dateProvider, instrumentation, l1constants, log = createLogger('archiver')){
84
- super(), this.publicClient = publicClient, this.debugClient = debugClient, this.l1Addresses = l1Addresses, this.dataStore = dataStore, this.config = config, this.blobClient = blobClient, this.epochCache = epochCache, this.dateProvider = dateProvider, this.instrumentation = instrumentation, this.l1constants = l1constants, this.log = log, this.initialSyncComplete = false, this.blockQueue = [];
481
+ super(), this.publicClient = publicClient, this.debugClient = debugClient, this.l1Addresses = l1Addresses, this.dataStore = dataStore, this.config = config, this.blobClient = blobClient, this.epochCache = epochCache, this.dateProvider = dateProvider, this.instrumentation = instrumentation, this.l1constants = l1constants, this.log = log, this.initialSyncComplete = (_initProto(this), false), this.blockQueue = [];
85
482
  this.tracer = instrumentation.tracer;
86
483
  this.store = new ArchiverStoreHelper(dataStore);
87
484
  this.rollup = new RollupContract(publicClient, l1Addresses.rollupAddress);
@@ -136,7 +533,7 @@ function mapArchiverConfig(config) {
136
533
  slotDuration,
137
534
  ethereumSlotDuration,
138
535
  proofSubmissionEpochs: Number(proofSubmissionEpochs),
139
- genesisArchiveRoot: Fr.fromHexString(genesisArchiveRoot)
536
+ genesisArchiveRoot: Fr.fromString(genesisArchiveRoot.toString())
140
537
  };
141
538
  const opts = merge({
142
539
  pollingIntervalMs: 10_000,
@@ -390,13 +787,11 @@ function mapArchiverConfig(config) {
390
787
  const checkpoints = await Promise.all(checkpointPromises);
391
788
  const blockPromises = await Promise.all(checkpoints.filter(isDefined).map((cp)=>this.store.getBlocksForCheckpoint(CheckpointNumber(cp.checkpointNumber))));
392
789
  const newBlocks = blockPromises.filter(isDefined).flat();
393
- // TODO(pw/mbps): Don't convert to legacy blocks here
394
- const blocks = (await Promise.all(newBlocks.map((x)=>this.getBlock(x.number)))).filter(isDefined);
395
790
  // Emit an event for listening services to react to the chain prune
396
791
  this.emit(L2BlockSourceEvents.L2PruneDetected, {
397
792
  type: L2BlockSourceEvents.L2PruneDetected,
398
793
  epochNumber: pruneFromEpochNumber,
399
- blocks
794
+ blocks: newBlocks
400
795
  });
401
796
  this.log.debug(`L2 prune from ${provenCheckpointNumber + 1} to ${localPendingCheckpointNumber} will occur on next checkpoint submission.`);
402
797
  await this.unwindCheckpoints(localPendingCheckpointNumber, checkpointsToUnwind);
@@ -572,16 +967,14 @@ function mapArchiverConfig(config) {
572
967
  async handleCheckpoints(blocksSynchedTo, currentL1BlockNumber) {
573
968
  const localPendingCheckpointNumber = await this.getSynchedCheckpointNumber();
574
969
  const initialValidationResult = await this.store.getPendingChainValidationStatus();
575
- const [rollupProvenCheckpointNumber, provenArchive, rollupPendingCheckpointNumber, pendingArchive, archiveForLocalPendingCheckpointNumber] = await this.rollup.status(localPendingCheckpointNumber, {
576
- blockNumber: currentL1BlockNumber
577
- });
578
- const provenCheckpointNumber = CheckpointNumber.fromBigInt(rollupProvenCheckpointNumber);
579
- const pendingCheckpointNumber = CheckpointNumber.fromBigInt(rollupPendingCheckpointNumber);
970
+ const { provenCheckpointNumber, provenArchive, pendingCheckpointNumber, pendingArchive, archiveOfMyCheckpoint: archiveForLocalPendingCheckpointNumber } = await execInSpan(this.tracer, 'Archiver.getRollupStatus', ()=>this.rollup.status(localPendingCheckpointNumber, {
971
+ blockNumber: currentL1BlockNumber
972
+ }));
580
973
  const rollupStatus = {
581
974
  provenCheckpointNumber,
582
- provenArchive,
975
+ provenArchive: provenArchive.toString(),
583
976
  pendingCheckpointNumber,
584
- pendingArchive,
977
+ pendingArchive: pendingArchive.toString(),
585
978
  validationResult: initialValidationResult
586
979
  };
587
980
  this.log.trace(`Retrieved rollup status at current L1 block ${currentL1BlockNumber}.`, {
@@ -612,7 +1005,7 @@ function mapArchiverConfig(config) {
612
1005
  this.log.error(`Hit local checkpoint greater than last synched checkpoint: ${localCheckpointForDestinationProvenCheckpointNumber.checkpointNumber} > ${synched}`);
613
1006
  }
614
1007
  this.log.trace(`Local checkpoint for remote proven checkpoint ${provenCheckpointNumber} is ${localCheckpointForDestinationProvenCheckpointNumber?.archive.root.toString() ?? 'undefined'}`);
615
- if (localCheckpointForDestinationProvenCheckpointNumber && provenArchive === localCheckpointForDestinationProvenCheckpointNumber.archive.root.toString()) {
1008
+ if (localCheckpointForDestinationProvenCheckpointNumber && provenArchive.equals(localCheckpointForDestinationProvenCheckpointNumber.archive.root)) {
616
1009
  const localProvenCheckpointNumber = await this.getProvenCheckpointNumber();
617
1010
  if (localProvenCheckpointNumber !== provenCheckpointNumber) {
618
1011
  await this.setProvenCheckpointNumber(provenCheckpointNumber);
@@ -651,7 +1044,7 @@ function mapArchiverConfig(config) {
651
1044
  throw new Error(`Missing checkpoint ${localPendingCheckpointNumber}`);
652
1045
  }
653
1046
  const localPendingArchiveRoot = localPendingCheckpoint.archive.root.toString();
654
- const noCheckpointSinceLast = localPendingCheckpoint && pendingArchive === localPendingArchiveRoot;
1047
+ const noCheckpointSinceLast = localPendingCheckpoint && pendingArchive.toString() === localPendingArchiveRoot;
655
1048
  if (noCheckpointSinceLast) {
656
1049
  // We believe the following line causes a problem when we encounter L1 re-orgs.
657
1050
  // Basically, by setting the synched L1 block number here, we are saying that we have
@@ -664,7 +1057,7 @@ function mapArchiverConfig(config) {
664
1057
  this.log.debug(`No checkpoints to retrieve from ${blocksSynchedTo + 1n} to ${currentL1BlockNumber}`);
665
1058
  return rollupStatus;
666
1059
  }
667
- const localPendingCheckpointInChain = archiveForLocalPendingCheckpointNumber === localPendingArchiveRoot;
1060
+ const localPendingCheckpointInChain = archiveForLocalPendingCheckpointNumber.equals(localPendingCheckpoint.archive.root);
668
1061
  if (!localPendingCheckpointInChain) {
669
1062
  // If our local pending checkpoint tip is not in the chain on L1 a "prune" must have happened
670
1063
  // or the L1 have reorged.
@@ -686,7 +1079,7 @@ function mapArchiverConfig(config) {
686
1079
  archiveAtContract,
687
1080
  archiveLocal: candidateCheckpoint.archive.root.toString()
688
1081
  });
689
- if (archiveAtContract === candidateCheckpoint.archive.root.toString()) {
1082
+ if (archiveAtContract.equals(candidateCheckpoint.archive.root)) {
690
1083
  break;
691
1084
  }
692
1085
  tipAfterUnwind--;
@@ -706,7 +1099,7 @@ function mapArchiverConfig(config) {
706
1099
  [searchStartBlock, searchEndBlock] = this.nextRange(searchEndBlock, currentL1BlockNumber);
707
1100
  this.log.trace(`Retrieving checkpoints from L1 block ${searchStartBlock} to ${searchEndBlock}`);
708
1101
  // TODO(md): Retrieve from blob client then from consensus client, then from peers
709
- const retrievedCheckpoints = await retrieveCheckpointsFromRollup(this.rollup.getContract(), this.publicClient, this.debugClient, this.blobClient, searchStartBlock, searchEndBlock, this.l1Addresses, this.instrumentation, this.log, !this.initialSyncComplete);
1102
+ const retrievedCheckpoints = await execInSpan(this.tracer, 'Archiver.retrieveCheckpointsFromRollup', ()=>retrieveCheckpointsFromRollup(this.rollup.getContract(), this.publicClient, this.debugClient, this.blobClient, searchStartBlock, searchEndBlock, this.l1Addresses, this.instrumentation, this.log, !this.initialSyncComplete));
710
1103
  if (retrievedCheckpoints.length === 0) {
711
1104
  // We are not calling `setBlockSynchedL1BlockNumber` because it may cause sync issues if based off infura.
712
1105
  // See further details in earlier comments.
@@ -721,7 +1114,7 @@ function mapArchiverConfig(config) {
721
1114
  const publishedCheckpoints = await Promise.all(retrievedCheckpoints.map((b)=>retrievedToPublishedCheckpoint(b)));
722
1115
  const validCheckpoints = [];
723
1116
  for (const published of publishedCheckpoints){
724
- const validationResult = this.config.skipValidateBlockAttestations ? {
1117
+ const validationResult = this.config.skipValidateCheckpointAttestations ? {
725
1118
  valid: true
726
1119
  } : await validateCheckpointAttestations(published, this.epochCache, this.l1constants, this.log);
727
1120
  // Only update the validation result if it has changed, so we can keep track of the first invalid checkpoint
@@ -729,7 +1122,7 @@ function mapArchiverConfig(config) {
729
1122
  // There is an exception though: if a checkpoint is invalidated and replaced with another invalid checkpoint,
730
1123
  // we need to update the validation result, since we need to be able to invalidate the new one.
731
1124
  // See test 'chain progresses if an invalid checkpoint is invalidated with an invalid one' for more info.
732
- if (rollupStatus.validationResult?.valid !== validationResult.valid || !rollupStatus.validationResult.valid && !validationResult.valid && rollupStatus.validationResult.block.blockNumber === validationResult.block.blockNumber) {
1125
+ if (rollupStatus.validationResult?.valid !== validationResult.valid || !rollupStatus.validationResult.valid && !validationResult.valid && rollupStatus.validationResult.checkpoint.checkpointNumber === validationResult.checkpoint.checkpointNumber) {
733
1126
  rollupStatus.validationResult = validationResult;
734
1127
  }
735
1128
  if (!validationResult.valid) {
@@ -738,9 +1131,9 @@ function mapArchiverConfig(config) {
738
1131
  l1BlockNumber: published.l1.blockNumber,
739
1132
  ...pick(validationResult, 'reason')
740
1133
  });
741
- // Emit event for invalid block detection
742
- this.emit(L2BlockSourceEvents.InvalidAttestationsBlockDetected, {
743
- type: L2BlockSourceEvents.InvalidAttestationsBlockDetected,
1134
+ // Emit event for invalid checkpoint detection
1135
+ this.emit(L2BlockSourceEvents.InvalidAttestationsCheckpointDetected, {
1136
+ type: L2BlockSourceEvents.InvalidAttestationsCheckpointDetected,
744
1137
  validationResult
745
1138
  });
746
1139
  continue;
@@ -750,7 +1143,7 @@ function mapArchiverConfig(config) {
750
1143
  // checkpoints we just retrieved.
751
1144
  const l1ToL2Messages = await this.getL1ToL2Messages(published.checkpoint.number);
752
1145
  const computedInHash = computeInHashFromL1ToL2Messages(l1ToL2Messages);
753
- const publishedInHash = published.checkpoint.header.contentCommitment.inHash;
1146
+ const publishedInHash = published.checkpoint.header.inHash;
754
1147
  if (!computedInHash.equals(publishedInHash)) {
755
1148
  this.log.fatal(`Mismatch inHash for checkpoint ${published.checkpoint.number}`, {
756
1149
  checkpointHash: published.checkpoint.hash(),
@@ -771,7 +1164,7 @@ function mapArchiverConfig(config) {
771
1164
  }
772
1165
  try {
773
1166
  const updatedValidationResult = rollupStatus.validationResult === initialValidationResult ? undefined : rollupStatus.validationResult;
774
- const [processDuration] = await elapsed(()=>this.addCheckpoints(validCheckpoints, updatedValidationResult));
1167
+ const [processDuration] = await elapsed(()=>execInSpan(this.tracer, 'Archiver.addCheckpoints', ()=>this.addCheckpoints(validCheckpoints, updatedValidationResult)));
775
1168
  this.instrumentation.processNewBlocks(processDuration / validCheckpoints.length, validCheckpoints.flatMap((c)=>c.checkpoint.blocks));
776
1169
  } catch (err) {
777
1170
  if (err instanceof InitialCheckpointNumberNotSequentialError) {
@@ -1020,6 +1413,14 @@ function mapArchiverConfig(config) {
1020
1413
  const publishedBlock = await this.store.store.getBlock(number);
1021
1414
  return publishedBlock;
1022
1415
  }
1416
+ async getL2BlocksNew(from, limit, proven) {
1417
+ const blocks = await this.store.store.getBlocks(from, limit);
1418
+ if (proven === true) {
1419
+ const provenBlockNumber = await this.store.getProvenBlockNumber();
1420
+ return blocks.filter((b)=>b.number <= provenBlockNumber);
1421
+ }
1422
+ return blocks;
1423
+ }
1023
1424
  async getBlockHeader(number) {
1024
1425
  if (number === 'latest') {
1025
1426
  number = await this.store.getSynchedL2BlockNumber();
@@ -1033,12 +1434,23 @@ function mapArchiverConfig(config) {
1033
1434
  getCheckpointedBlock(number) {
1034
1435
  return this.store.getCheckpointedBlock(number);
1035
1436
  }
1437
+ async getCheckpointedBlocks(from, limit, proven) {
1438
+ const blocks = await this.store.store.getCheckpointedBlocks(from, limit);
1439
+ if (proven === true) {
1440
+ const provenBlockNumber = await this.store.getProvenBlockNumber();
1441
+ return blocks.filter((b)=>b.block.number <= provenBlockNumber);
1442
+ }
1443
+ return blocks;
1444
+ }
1036
1445
  getCheckpointedBlockByHash(blockHash) {
1037
1446
  return this.store.getCheckpointedBlockByHash(blockHash);
1038
1447
  }
1039
1448
  getProvenBlockNumber() {
1040
1449
  return this.store.getProvenBlockNumber();
1041
1450
  }
1451
+ getCheckpointedBlockNumber() {
1452
+ return this.store.getCheckpointedL2BlockNumber();
1453
+ }
1042
1454
  getCheckpointedBlockByArchive(archive) {
1043
1455
  return this.store.getCheckpointedBlockByArchive(archive);
1044
1456
  }
@@ -1124,51 +1536,99 @@ function mapArchiverConfig(config) {
1124
1536
  return this.getPendingChainValidationStatus().then((status)=>!status.valid);
1125
1537
  }
1126
1538
  async getL2Tips() {
1127
- const [latestBlockNumber, provenBlockNumber] = await Promise.all([
1539
+ const [latestBlockNumber, provenBlockNumber, checkpointedBlockNumber] = await Promise.all([
1128
1540
  this.getBlockNumber(),
1129
- this.getProvenBlockNumber()
1541
+ this.getProvenBlockNumber(),
1542
+ this.getCheckpointedBlockNumber()
1130
1543
  ]);
1131
1544
  // TODO(#13569): Compute proper finalized block number based on L1 finalized block.
1132
1545
  // We just force it 2 epochs worth of proven data for now.
1133
1546
  // NOTE: update end-to-end/src/e2e_epochs/epochs_empty_blocks.test.ts as that uses finalized blocks in computations
1134
1547
  const finalizedBlockNumber = BlockNumber(Math.max(provenBlockNumber - this.l1constants.epochDuration * 2, 0));
1135
- const [latestBlockHeader, provenBlockHeader, finalizedBlockHeader] = await Promise.all([
1136
- latestBlockNumber > 0 ? this.getBlockHeader(latestBlockNumber) : undefined,
1137
- provenBlockNumber > 0 ? this.getBlockHeader(provenBlockNumber) : undefined,
1138
- finalizedBlockNumber > 0 ? this.getBlockHeader(finalizedBlockNumber) : undefined
1548
+ const beforeInitialblockNumber = BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
1549
+ // Get the latest block header and checkpointed blocks for proven, finalised and checkpointed blocks
1550
+ const [latestBlockHeader, provenCheckpointedBlock, finalizedCheckpointedBlock, checkpointedBlock] = await Promise.all([
1551
+ latestBlockNumber > beforeInitialblockNumber ? this.getBlockHeader(latestBlockNumber) : undefined,
1552
+ provenBlockNumber > beforeInitialblockNumber ? this.getCheckpointedBlock(provenBlockNumber) : undefined,
1553
+ finalizedBlockNumber > beforeInitialblockNumber ? this.getCheckpointedBlock(finalizedBlockNumber) : undefined,
1554
+ checkpointedBlockNumber > beforeInitialblockNumber ? this.getCheckpointedBlock(checkpointedBlockNumber) : undefined
1139
1555
  ]);
1140
- if (latestBlockNumber > 0 && !latestBlockHeader) {
1556
+ if (latestBlockNumber > beforeInitialblockNumber && !latestBlockHeader) {
1141
1557
  throw new Error(`Failed to retrieve latest block header for block ${latestBlockNumber}`);
1142
1558
  }
1143
- if (provenBlockNumber > 0 && !provenBlockHeader) {
1144
- throw new Error(`Failed to retrieve proven block header for block ${provenBlockNumber} (latest block is ${latestBlockNumber})`);
1559
+ // Checkpointed blocks must exist for proven, finalized and checkpointed tips if they are beyond the initial block number.
1560
+ if (checkpointedBlockNumber > beforeInitialblockNumber && !checkpointedBlock?.block.header) {
1561
+ throw new Error(`Failed to retrieve checkpointed block header for block ${checkpointedBlockNumber} (latest block is ${latestBlockNumber})`);
1562
+ }
1563
+ if (provenBlockNumber > beforeInitialblockNumber && !provenCheckpointedBlock?.block.header) {
1564
+ throw new Error(`Failed to retrieve proven checkpointed for block ${provenBlockNumber} (latest block is ${latestBlockNumber})`);
1145
1565
  }
1146
- if (finalizedBlockNumber > 0 && !finalizedBlockHeader) {
1566
+ if (finalizedBlockNumber > beforeInitialblockNumber && !finalizedCheckpointedBlock?.block.header) {
1147
1567
  throw new Error(`Failed to retrieve finalized block header for block ${finalizedBlockNumber} (latest block is ${latestBlockNumber})`);
1148
1568
  }
1149
1569
  const latestBlockHeaderHash = await latestBlockHeader?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
1150
- const provenBlockHeaderHash = await provenBlockHeader?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
1151
- const finalizedBlockHeaderHash = await finalizedBlockHeader?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
1152
- return {
1153
- latest: {
1570
+ const provenBlockHeaderHash = await provenCheckpointedBlock?.block.header?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
1571
+ const finalizedBlockHeaderHash = await finalizedCheckpointedBlock?.block.header?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
1572
+ const checkpointedBlockHeaderHash = await checkpointedBlock?.block.header?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
1573
+ // Now attempt to retrieve checkpoints for proven, finalised and checkpointed blocks
1574
+ const [[provenBlockCheckpoint], [finalizedBlockCheckpoint], [checkpointedBlockCheckpoint]] = await Promise.all([
1575
+ provenCheckpointedBlock !== undefined ? await this.getPublishedCheckpoints(provenCheckpointedBlock?.checkpointNumber, 1) : [
1576
+ undefined
1577
+ ],
1578
+ finalizedCheckpointedBlock !== undefined ? await this.getPublishedCheckpoints(finalizedCheckpointedBlock?.checkpointNumber, 1) : [
1579
+ undefined
1580
+ ],
1581
+ checkpointedBlock !== undefined ? await this.getPublishedCheckpoints(checkpointedBlock?.checkpointNumber, 1) : [
1582
+ undefined
1583
+ ]
1584
+ ]);
1585
+ const initialcheckpointId = {
1586
+ number: CheckpointNumber.ZERO,
1587
+ hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
1588
+ };
1589
+ const makeCheckpointId = (checkpoint)=>{
1590
+ if (checkpoint === undefined) {
1591
+ return initialcheckpointId;
1592
+ }
1593
+ return {
1594
+ number: checkpoint.checkpoint.number,
1595
+ hash: checkpoint.checkpoint.hash().toString()
1596
+ };
1597
+ };
1598
+ const l2Tips = {
1599
+ proposed: {
1154
1600
  number: latestBlockNumber,
1155
1601
  hash: latestBlockHeaderHash.toString()
1156
1602
  },
1157
1603
  proven: {
1158
- number: provenBlockNumber,
1159
- hash: provenBlockHeaderHash.toString()
1604
+ block: {
1605
+ number: provenBlockNumber,
1606
+ hash: provenBlockHeaderHash.toString()
1607
+ },
1608
+ checkpoint: makeCheckpointId(provenBlockCheckpoint)
1160
1609
  },
1161
1610
  finalized: {
1162
- number: finalizedBlockNumber,
1163
- hash: finalizedBlockHeaderHash.toString()
1611
+ block: {
1612
+ number: finalizedBlockNumber,
1613
+ hash: finalizedBlockHeaderHash.toString()
1614
+ },
1615
+ checkpoint: makeCheckpointId(finalizedBlockCheckpoint)
1616
+ },
1617
+ checkpointed: {
1618
+ block: {
1619
+ number: checkpointedBlockNumber,
1620
+ hash: checkpointedBlockHeaderHash.toString()
1621
+ },
1622
+ checkpoint: makeCheckpointId(checkpointedBlockCheckpoint)
1164
1623
  }
1165
1624
  };
1625
+ return l2Tips;
1166
1626
  }
1167
1627
  async rollbackTo(targetL2BlockNumber) {
1168
1628
  // TODO(pw/mbps): This still assumes 1 block per checkpoint
1169
1629
  const currentBlocks = await this.getL2Tips();
1170
- const currentL2Block = currentBlocks.latest.number;
1171
- const currentProvenBlock = currentBlocks.proven.number;
1630
+ const currentL2Block = currentBlocks.proposed.number;
1631
+ const currentProvenBlock = currentBlocks.proven.block.number;
1172
1632
  if (targetL2BlockNumber >= currentL2Block) {
1173
1633
  throw new Error(`Target L2 block ${targetL2BlockNumber} must be less than current L2 block ${currentL2Block}`);
1174
1634
  }
@@ -1298,9 +1758,6 @@ function mapArchiverConfig(config) {
1298
1758
  return publishedBlocks[0].block;
1299
1759
  }
1300
1760
  }
1301
- _ts_decorate([
1302
- trackSpan('Archiver.sync')
1303
- ], Archiver.prototype, "sync", null);
1304
1761
  var Operation = /*#__PURE__*/ function(Operation) {
1305
1762
  Operation[Operation["Store"] = 0] = "Store";
1306
1763
  Operation[Operation["Delete"] = 1] = "Delete";
@@ -1579,7 +2036,7 @@ var Operation = /*#__PURE__*/ function(Operation) {
1579
2036
  return this.store.getContractClassLogs(filter);
1580
2037
  }
1581
2038
  getSynchedL2BlockNumber() {
1582
- return this.store.getCheckpointedL2BlockNumber();
2039
+ return this.store.getLatestBlockNumber();
1583
2040
  }
1584
2041
  getProvenCheckpointNumber() {
1585
2042
  return this.store.getProvenCheckpointNumber();