@aztec/archiver 4.0.0-nightly.20260112 → 4.0.0-nightly.20260114
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 +139 -22
- package/dest/archiver/archive_source_base.d.ts +75 -0
- package/dest/archiver/archive_source_base.d.ts.map +1 -0
- package/dest/archiver/archive_source_base.js +202 -0
- package/dest/archiver/archiver.d.ts +32 -168
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +123 -613
- package/dest/archiver/archiver_store_updates.d.ts +38 -0
- package/dest/archiver/archiver_store_updates.d.ts.map +1 -0
- package/dest/archiver/archiver_store_updates.js +212 -0
- package/dest/archiver/config.js +2 -2
- package/dest/archiver/index.d.ts +3 -2
- package/dest/archiver/index.d.ts.map +1 -1
- package/dest/archiver/index.js +2 -0
- package/dest/archiver/kv_archiver_store/block_store.d.ts +12 -5
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +23 -4
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +173 -12
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +159 -48
- package/dest/archiver/l1/calldata_retriever.d.ts +2 -2
- package/dest/archiver/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/archiver/l1/calldata_retriever.js +2 -2
- package/dest/archiver/l1/data_retrieval.d.ts +9 -11
- package/dest/archiver/l1/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/l1/data_retrieval.js +32 -51
- package/dest/archiver/l1/validate_trace.js +1 -1
- package/dest/archiver/test/fake_l1_state.d.ts +173 -0
- package/dest/archiver/test/fake_l1_state.d.ts.map +1 -0
- package/dest/archiver/test/fake_l1_state.js +364 -0
- package/dest/archiver/validation.d.ts +4 -4
- package/dest/archiver/validation.d.ts.map +1 -1
- package/dest/archiver/validation.js +1 -1
- 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 +12 -3
- package/dest/test/mock_l2_block_source.d.ts +8 -4
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +65 -19
- package/package.json +13 -13
- package/src/archiver/archive_source_base.ts +339 -0
- package/src/archiver/archiver.ts +166 -815
- package/src/archiver/archiver_store_updates.ts +321 -0
- package/src/archiver/config.ts +2 -2
- package/src/archiver/index.ts +2 -1
- package/src/archiver/kv_archiver_store/block_store.ts +36 -8
- package/src/archiver/kv_archiver_store/contract_class_store.ts +1 -1
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +1 -1
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +177 -11
- package/src/archiver/l1/calldata_retriever.ts +2 -2
- package/src/archiver/l1/data_retrieval.ts +51 -68
- package/src/archiver/l1/validate_trace.ts +1 -1
- package/src/archiver/test/fake_l1_state.ts +561 -0
- package/src/archiver/validation.ts +6 -6
- package/src/test/mock_l1_to_l2_message_source.ts +10 -4
- package/src/test/mock_l2_block_source.ts +76 -18
- package/dest/archiver/archiver_store.d.ts +0 -308
- package/dest/archiver/archiver_store.d.ts.map +0 -1
- package/dest/archiver/archiver_store.js +0 -4
- package/dest/archiver/archiver_store_test_suite.d.ts +0 -8
- package/dest/archiver/archiver_store_test_suite.d.ts.map +0 -1
- package/dest/archiver/archiver_store_test_suite.js +0 -2770
- package/src/archiver/archiver_store.ts +0 -372
- package/src/archiver/archiver_store_test_suite.ts +0 -2843
|
@@ -371,7 +371,7 @@ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
|
371
371
|
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
372
372
|
}
|
|
373
373
|
var _dec, _dec1, _dec2, _dec3, _dec4, _initProto;
|
|
374
|
-
import { GENESIS_BLOCK_HEADER_HASH } from '@aztec/constants';
|
|
374
|
+
import { GENESIS_BLOCK_HEADER_HASH, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
375
375
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
376
376
|
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
377
377
|
import { BlockTagTooOldError, InboxContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
@@ -380,23 +380,21 @@ import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
|
380
380
|
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
|
|
381
381
|
import { merge, pick } from '@aztec/foundation/collection';
|
|
382
382
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
383
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
383
384
|
import { createLogger } from '@aztec/foundation/log';
|
|
384
385
|
import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
385
386
|
import { RunningPromise, makeLoggingErrorHandler } from '@aztec/foundation/running-promise';
|
|
386
387
|
import { count } from '@aztec/foundation/string';
|
|
387
388
|
import { DateProvider, Timer, elapsed } from '@aztec/foundation/timer';
|
|
388
389
|
import { isDefined } from '@aztec/foundation/types';
|
|
389
|
-
import {
|
|
390
|
-
import { ContractInstancePublishedEvent, ContractInstanceUpdatedEvent } from '@aztec/protocol-contracts/instance-registry';
|
|
391
|
-
import { CommitteeAttestation, L2Block, L2BlockSourceEvents, PublishedL2Block } from '@aztec/stdlib/block';
|
|
392
|
-
import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
393
|
-
import { computePublicBytecodeCommitment, isValidPrivateFunctionMembershipProof, isValidUtilityFunctionMembershipProof } from '@aztec/stdlib/contract';
|
|
390
|
+
import { GENESIS_CHECKPOINT_HEADER_HASH, L2BlockSourceEvents } from '@aztec/stdlib/block';
|
|
394
391
|
import { getEpochAtSlot, getEpochNumberAtTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
395
392
|
import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
|
|
396
393
|
import { execInSpan, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
397
394
|
import { EventEmitter } from 'events';
|
|
398
|
-
import groupBy from 'lodash.groupby';
|
|
399
395
|
import { createPublicClient, fallback, http } from 'viem';
|
|
396
|
+
import { ArchiveSourceBase } from './archive_source_base.js';
|
|
397
|
+
import { addBlocksWithContractData, addCheckpointsWithContractData, unwindCheckpointsWithContractData } from './archiver_store_updates.js';
|
|
400
398
|
import { InitialCheckpointNumberNotSequentialError, NoBlobBodiesFoundError } from './errors.js';
|
|
401
399
|
import { ArchiverInstrumentation } from './instrumentation.js';
|
|
402
400
|
import { retrieveCheckpointsFromRollup, retrieveL1ToL2Message, retrieveL1ToL2Messages, retrievedToPublishedCheckpoint } from './l1/data_retrieval.js';
|
|
@@ -406,7 +404,7 @@ function mapArchiverConfig(config) {
|
|
|
406
404
|
return {
|
|
407
405
|
pollingIntervalMs: config.archiverPollingIntervalMS,
|
|
408
406
|
batchSize: config.archiverBatchSize,
|
|
409
|
-
|
|
407
|
+
skipValidateCheckpointAttestations: config.skipValidateCheckpointAttestations,
|
|
410
408
|
maxAllowedEthClientDriftSeconds: config.maxAllowedEthClientDriftSeconds,
|
|
411
409
|
ethereumAllowNoDebugHosts: config.ethereumAllowNoDebugHosts
|
|
412
410
|
};
|
|
@@ -416,9 +414,11 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
416
414
|
* Pulls checkpoints in a non-blocking manner and provides interface for their retrieval.
|
|
417
415
|
* Responsible for handling robust L1 polling so that other components do not need to
|
|
418
416
|
* concern themselves with it.
|
|
419
|
-
*/ export class Archiver extends
|
|
417
|
+
*/ export class Archiver extends ArchiveSourceBase {
|
|
420
418
|
publicClient;
|
|
421
419
|
debugClient;
|
|
420
|
+
rollup;
|
|
421
|
+
inbox;
|
|
422
422
|
l1Addresses;
|
|
423
423
|
dataStore;
|
|
424
424
|
config;
|
|
@@ -457,10 +457,8 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
457
457
|
]
|
|
458
458
|
], []));
|
|
459
459
|
}
|
|
460
|
+
/** Event emitter for archiver events (L2BlockProven, L2PruneDetected, etc). */ events;
|
|
460
461
|
/** A loop in which we will be continually fetching new checkpoints. */ runningPromise;
|
|
461
|
-
rollup;
|
|
462
|
-
inbox;
|
|
463
|
-
store;
|
|
464
462
|
l1BlockNumber;
|
|
465
463
|
l1Timestamp;
|
|
466
464
|
initialSyncComplete;
|
|
@@ -471,18 +469,20 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
471
469
|
* Creates a new instance of the Archiver.
|
|
472
470
|
* @param publicClient - A client for interacting with the Ethereum node.
|
|
473
471
|
* @param debugClient - A client for interacting with the Ethereum node for debug/trace methods.
|
|
474
|
-
* @param
|
|
475
|
-
* @param
|
|
476
|
-
* @param
|
|
477
|
-
* @param
|
|
478
|
-
* @param
|
|
472
|
+
* @param rollup - Rollup contract instance.
|
|
473
|
+
* @param inbox - Inbox contract instance.
|
|
474
|
+
* @param l1Addresses - L1 contract addresses (registry, governance proposer, slash factory, slashing proposer).
|
|
475
|
+
* @param dataStore - An archiver data store for storage & retrieval of blocks, encrypted logs & contract data.
|
|
476
|
+
* @param config - Archiver configuration options.
|
|
477
|
+
* @param blobClient - Client for retrieving blob data.
|
|
478
|
+
* @param epochCache - Cache for epoch-related data.
|
|
479
|
+
* @param dateProvider - Provider for current date/time.
|
|
480
|
+
* @param instrumentation - Instrumentation for metrics and tracing.
|
|
481
|
+
* @param l1constants - L1 rollup constants.
|
|
479
482
|
* @param log - A logger.
|
|
480
|
-
*/ constructor(publicClient, debugClient, l1Addresses, dataStore, config, blobClient, epochCache, dateProvider, instrumentation, l1constants, log = createLogger('archiver')){
|
|
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.
|
|
483
|
+
*/ constructor(publicClient, debugClient, rollup, inbox, l1Addresses, dataStore, config, blobClient, epochCache, dateProvider, instrumentation, l1constants, log = createLogger('archiver')){
|
|
484
|
+
super(dataStore), this.publicClient = publicClient, this.debugClient = debugClient, this.rollup = rollup, this.inbox = inbox, 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.events = (_initProto(this), new EventEmitter()), this.initialSyncComplete = false, this.blockQueue = [];
|
|
482
485
|
this.tracer = instrumentation.tracer;
|
|
483
|
-
this.store = new ArchiverStoreHelper(dataStore);
|
|
484
|
-
this.rollup = new RollupContract(publicClient, l1Addresses.rollupAddress);
|
|
485
|
-
this.inbox = new InboxContract(publicClient, l1Addresses.inboxAddress);
|
|
486
486
|
this.initialSyncPromise = promiseWithResolvers();
|
|
487
487
|
// Running promise starts with a small interval inbetween runs, so all iterations needed for the initial sync
|
|
488
488
|
// are done as fast as possible. This then gets updated once the initial sync completes.
|
|
@@ -513,6 +513,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
513
513
|
pollingInterval: config.viemPollingIntervalMS
|
|
514
514
|
});
|
|
515
515
|
const rollup = new RollupContract(publicClient, config.l1Contracts.rollupAddress);
|
|
516
|
+
const inbox = new InboxContract(publicClient, config.l1Contracts.inboxAddress);
|
|
516
517
|
const [l1StartBlock, l1GenesisTime, proofSubmissionEpochs, genesisArchiveRoot, slashingProposerAddress] = await Promise.all([
|
|
517
518
|
rollup.getL1StartBlock(),
|
|
518
519
|
rollup.getL1GenesisTime(),
|
|
@@ -543,7 +544,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
543
544
|
}, mapArchiverConfig(config));
|
|
544
545
|
const epochCache = deps.epochCache ?? await EpochCache.create(config.l1Contracts.rollupAddress, config, deps);
|
|
545
546
|
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
546
|
-
const archiver = new Archiver(publicClient, debugClient, {
|
|
547
|
+
const archiver = new Archiver(publicClient, debugClient, rollup, inbox, {
|
|
547
548
|
...config.l1Contracts,
|
|
548
549
|
slashingProposerAddress
|
|
549
550
|
}, archiverStore, opts, deps.blobClient, epochCache, deps.dateProvider ?? new DateProvider(), await ArchiverInstrumentation.new(telemetry, ()=>archiverStore.estimateSize()), l1Constants);
|
|
@@ -567,7 +568,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
567
568
|
const { l1StartBlock } = this.l1constants;
|
|
568
569
|
const { blocksSynchedTo = l1StartBlock, messagesSynchedTo = l1StartBlock } = await this.store.getSynchPoint();
|
|
569
570
|
const currentL2Checkpoint = await this.getSynchedCheckpointNumber();
|
|
570
|
-
this.log.info(`Starting archiver sync to rollup contract ${this.
|
|
571
|
+
this.log.info(`Starting archiver sync to rollup contract ${this.rollup.address} from L1 block ${blocksSynchedTo} and L2 checkpoint ${currentL2Checkpoint}`, {
|
|
571
572
|
blocksSynchedTo,
|
|
572
573
|
messagesSynchedTo,
|
|
573
574
|
currentL2Checkpoint
|
|
@@ -615,7 +616,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
615
616
|
// Process each block individually to properly resolve/reject each promise
|
|
616
617
|
for (const { block, resolve, reject } of queuedItems){
|
|
617
618
|
try {
|
|
618
|
-
await this.store
|
|
619
|
+
await addBlocksWithContractData(this.store, [
|
|
619
620
|
block
|
|
620
621
|
]);
|
|
621
622
|
this.log.debug(`Added block ${block.number} to store`);
|
|
@@ -732,9 +733,15 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
732
733
|
// but the corresponding blocks have not been processed (see #12631).
|
|
733
734
|
this.l1Timestamp = currentL1Timestamp;
|
|
734
735
|
this.l1BlockNumber = currentL1BlockNumber;
|
|
736
|
+
const l1BlockNumberAtEnd = await this.publicClient.getBlockNumber();
|
|
737
|
+
this.log.trace(`Archiver sync iteration complete`, {
|
|
738
|
+
l1BlockNumberAtStart: currentL1BlockNumber,
|
|
739
|
+
l1TimestampAtStart: currentL1Timestamp,
|
|
740
|
+
l1BlockNumberAtEnd
|
|
741
|
+
});
|
|
735
742
|
// We resolve the initial sync only once we've caught up with the latest L1 block number (with 1 block grace)
|
|
736
743
|
// so if the initial sync took too long, we still go for another iteration.
|
|
737
|
-
if (!this.initialSyncComplete && currentL1BlockNumber + 1n >=
|
|
744
|
+
if (!this.initialSyncComplete && currentL1BlockNumber + 1n >= l1BlockNumberAtEnd) {
|
|
738
745
|
this.log.info(`Initial archiver sync to L1 block ${currentL1BlockNumber} complete`, {
|
|
739
746
|
l1BlockNumber: currentL1BlockNumber,
|
|
740
747
|
syncPoint: await this.store.getSynchPoint(),
|
|
@@ -787,13 +794,11 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
787
794
|
const checkpoints = await Promise.all(checkpointPromises);
|
|
788
795
|
const blockPromises = await Promise.all(checkpoints.filter(isDefined).map((cp)=>this.store.getBlocksForCheckpoint(CheckpointNumber(cp.checkpointNumber))));
|
|
789
796
|
const newBlocks = blockPromises.filter(isDefined).flat();
|
|
790
|
-
// TODO(pw/mbps): Don't convert to legacy blocks here
|
|
791
|
-
const blocks = (await Promise.all(newBlocks.map((x)=>this.getBlock(x.number)))).filter(isDefined);
|
|
792
797
|
// Emit an event for listening services to react to the chain prune
|
|
793
|
-
this.emit(L2BlockSourceEvents.L2PruneDetected, {
|
|
798
|
+
this.events.emit(L2BlockSourceEvents.L2PruneDetected, {
|
|
794
799
|
type: L2BlockSourceEvents.L2PruneDetected,
|
|
795
800
|
epochNumber: pruneFromEpochNumber,
|
|
796
|
-
blocks
|
|
801
|
+
blocks: newBlocks
|
|
797
802
|
});
|
|
798
803
|
this.log.debug(`L2 prune from ${provenCheckpointNumber + 1} to ${localPendingCheckpointNumber} will occur on next checkpoint submission.`);
|
|
799
804
|
await this.unwindCheckpoints(localPendingCheckpointNumber, checkpointsToUnwind);
|
|
@@ -801,7 +806,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
801
806
|
this.instrumentation.processPrune(timer.ms());
|
|
802
807
|
// TODO(palla/reorg): Do we need to set the block synched L1 block number here?
|
|
803
808
|
// Seems like the next iteration should handle this.
|
|
804
|
-
// await this.store.
|
|
809
|
+
// await this.store.setCheckpointSynchedL1BlockNumber(currentL1BlockNumber);
|
|
805
810
|
}
|
|
806
811
|
return {
|
|
807
812
|
rollupCanPrune
|
|
@@ -872,7 +877,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
872
877
|
do {
|
|
873
878
|
[searchStartBlock, searchEndBlock] = this.nextRange(searchEndBlock, currentL1BlockNumber);
|
|
874
879
|
this.log.trace(`Retrieving L1 to L2 messages between L1 blocks ${searchStartBlock} and ${searchEndBlock}.`);
|
|
875
|
-
const messages = await retrieveL1ToL2Messages(this.inbox
|
|
880
|
+
const messages = await retrieveL1ToL2Messages(this.inbox, searchStartBlock, searchEndBlock);
|
|
876
881
|
this.log.verbose(`Retrieved ${messages.length} new L1 to L2 messages between L1 blocks ${searchStartBlock} and ${searchEndBlock}.`);
|
|
877
882
|
const timer = new Timer();
|
|
878
883
|
await this.store.addL1ToL2Messages(messages);
|
|
@@ -908,7 +913,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
908
913
|
let searchEndBlock = this.l1constants.l1StartBlock - 1n;
|
|
909
914
|
do {
|
|
910
915
|
[searchStartBlock, searchEndBlock] = this.nextRange(searchEndBlock, currentL1BlockNumber);
|
|
911
|
-
const message = await retrieveL1ToL2Message(this.inbox
|
|
916
|
+
const message = await retrieveL1ToL2Message(this.inbox, leaf, searchStartBlock, searchEndBlock);
|
|
912
917
|
if (message) {
|
|
913
918
|
return message;
|
|
914
919
|
}
|
|
@@ -1017,7 +1022,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1017
1022
|
const provenSlotNumber = localCheckpointForDestinationProvenCheckpointNumber.header.slotNumber;
|
|
1018
1023
|
const provenEpochNumber = getEpochAtSlot(provenSlotNumber, this.l1constants);
|
|
1019
1024
|
const lastBlockNumberInCheckpoint = localCheckpointForDestinationProvenCheckpointNumber.startBlock + localCheckpointForDestinationProvenCheckpointNumber.numBlocks - 1;
|
|
1020
|
-
this.emit(L2BlockSourceEvents.L2BlockProven, {
|
|
1025
|
+
this.events.emit(L2BlockSourceEvents.L2BlockProven, {
|
|
1021
1026
|
type: L2BlockSourceEvents.L2BlockProven,
|
|
1022
1027
|
blockNumber: BlockNumber(lastBlockNumberInCheckpoint),
|
|
1023
1028
|
slotNumber: provenSlotNumber,
|
|
@@ -1055,7 +1060,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1055
1060
|
// However, in the re-org scenario, our L1 node is temporarily lying to us and we end up potentially missing checkpoints.
|
|
1056
1061
|
// We must only set this block number based on actually retrieved logs.
|
|
1057
1062
|
// TODO(#8621): Tackle this properly when we handle L1 Re-orgs.
|
|
1058
|
-
// await this.store.
|
|
1063
|
+
// await this.store.setCheckpointSynchedL1BlockNumber(currentL1BlockNumber);
|
|
1059
1064
|
this.log.debug(`No checkpoints to retrieve from ${blocksSynchedTo + 1n} to ${currentL1BlockNumber}`);
|
|
1060
1065
|
return rollupStatus;
|
|
1061
1066
|
}
|
|
@@ -1101,7 +1106,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1101
1106
|
[searchStartBlock, searchEndBlock] = this.nextRange(searchEndBlock, currentL1BlockNumber);
|
|
1102
1107
|
this.log.trace(`Retrieving checkpoints from L1 block ${searchStartBlock} to ${searchEndBlock}`);
|
|
1103
1108
|
// TODO(md): Retrieve from blob client then from consensus client, then from peers
|
|
1104
|
-
const retrievedCheckpoints = await execInSpan(this.tracer, 'Archiver.retrieveCheckpointsFromRollup', ()=>retrieveCheckpointsFromRollup(this.rollup
|
|
1109
|
+
const retrievedCheckpoints = await execInSpan(this.tracer, 'Archiver.retrieveCheckpointsFromRollup', ()=>retrieveCheckpointsFromRollup(this.rollup, this.publicClient, this.debugClient, this.blobClient, searchStartBlock, searchEndBlock, this.l1Addresses, this.instrumentation, this.log, !this.initialSyncComplete));
|
|
1105
1110
|
if (retrievedCheckpoints.length === 0) {
|
|
1106
1111
|
// We are not calling `setBlockSynchedL1BlockNumber` because it may cause sync issues if based off infura.
|
|
1107
1112
|
// See further details in earlier comments.
|
|
@@ -1116,7 +1121,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1116
1121
|
const publishedCheckpoints = await Promise.all(retrievedCheckpoints.map((b)=>retrievedToPublishedCheckpoint(b)));
|
|
1117
1122
|
const validCheckpoints = [];
|
|
1118
1123
|
for (const published of publishedCheckpoints){
|
|
1119
|
-
const validationResult = this.config.
|
|
1124
|
+
const validationResult = this.config.skipValidateCheckpointAttestations ? {
|
|
1120
1125
|
valid: true
|
|
1121
1126
|
} : await validateCheckpointAttestations(published, this.epochCache, this.l1constants, this.log);
|
|
1122
1127
|
// Only update the validation result if it has changed, so we can keep track of the first invalid checkpoint
|
|
@@ -1124,7 +1129,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1124
1129
|
// There is an exception though: if a checkpoint is invalidated and replaced with another invalid checkpoint,
|
|
1125
1130
|
// we need to update the validation result, since we need to be able to invalidate the new one.
|
|
1126
1131
|
// See test 'chain progresses if an invalid checkpoint is invalidated with an invalid one' for more info.
|
|
1127
|
-
if (rollupStatus.validationResult?.valid !== validationResult.valid || !rollupStatus.validationResult.valid && !validationResult.valid && rollupStatus.validationResult.
|
|
1132
|
+
if (rollupStatus.validationResult?.valid !== validationResult.valid || !rollupStatus.validationResult.valid && !validationResult.valid && rollupStatus.validationResult.checkpoint.checkpointNumber === validationResult.checkpoint.checkpointNumber) {
|
|
1128
1133
|
rollupStatus.validationResult = validationResult;
|
|
1129
1134
|
}
|
|
1130
1135
|
if (!validationResult.valid) {
|
|
@@ -1133,9 +1138,9 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1133
1138
|
l1BlockNumber: published.l1.blockNumber,
|
|
1134
1139
|
...pick(validationResult, 'reason')
|
|
1135
1140
|
});
|
|
1136
|
-
// Emit event for invalid
|
|
1137
|
-
this.emit(L2BlockSourceEvents.
|
|
1138
|
-
type: L2BlockSourceEvents.
|
|
1141
|
+
// Emit event for invalid checkpoint detection
|
|
1142
|
+
this.events.emit(L2BlockSourceEvents.InvalidAttestationsCheckpointDetected, {
|
|
1143
|
+
type: L2BlockSourceEvents.InvalidAttestationsCheckpointDetected,
|
|
1139
1144
|
validationResult
|
|
1140
1145
|
});
|
|
1141
1146
|
continue;
|
|
@@ -1173,7 +1178,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1173
1178
|
const { previousCheckpointNumber, newCheckpointNumber } = err;
|
|
1174
1179
|
const previousCheckpoint = previousCheckpointNumber ? await this.store.getCheckpointData(CheckpointNumber(previousCheckpointNumber)) : undefined;
|
|
1175
1180
|
const updatedL1SyncPoint = previousCheckpoint?.l1.blockNumber ?? this.l1constants.l1StartBlock;
|
|
1176
|
-
await this.store.
|
|
1181
|
+
await this.store.setCheckpointSynchedL1BlockNumber(updatedL1SyncPoint);
|
|
1177
1182
|
this.log.warn(`Attempting to insert checkpoint ${newCheckpointNumber} with previous block ${previousCheckpointNumber}. Rolling back L1 sync point to ${updatedL1SyncPoint} to try and fetch the missing blocks.`, {
|
|
1178
1183
|
previousCheckpointNumber,
|
|
1179
1184
|
newCheckpointNumber,
|
|
@@ -1232,7 +1237,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1232
1237
|
currentL1BlockNumber,
|
|
1233
1238
|
...status
|
|
1234
1239
|
});
|
|
1235
|
-
await this.store.
|
|
1240
|
+
await this.store.setCheckpointSynchedL1BlockNumber(targetL1BlockNumber);
|
|
1236
1241
|
} else {
|
|
1237
1242
|
this.log.trace(`No new checkpoints behind L1 sync point to retrieve.`, {
|
|
1238
1243
|
latestLocalCheckpointNumber,
|
|
@@ -1268,7 +1273,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1268
1273
|
});
|
|
1269
1274
|
}
|
|
1270
1275
|
getRollupAddress() {
|
|
1271
|
-
return Promise.resolve(this.
|
|
1276
|
+
return Promise.resolve(EthAddress.fromString(this.rollup.address));
|
|
1272
1277
|
}
|
|
1273
1278
|
getRegistryAddress() {
|
|
1274
1279
|
return Promise.resolve(this.l1Addresses.registryAddress);
|
|
@@ -1382,7 +1387,7 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1382
1387
|
return this.store.setProvenCheckpointNumber(checkpointNumber);
|
|
1383
1388
|
}
|
|
1384
1389
|
unwindCheckpoints(from, checkpointsToUnwind) {
|
|
1385
|
-
return this.store
|
|
1390
|
+
return unwindCheckpointsWithContractData(this.store, from, checkpointsToUnwind);
|
|
1386
1391
|
}
|
|
1387
1392
|
async getLastBlockNumberInCheckpoint(checkpointNumber) {
|
|
1388
1393
|
const checkpointData = await this.store.getCheckpointData(checkpointNumber);
|
|
@@ -1392,178 +1397,105 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1392
1397
|
return BlockNumber(checkpointData.startBlock + checkpointData.numBlocks - 1);
|
|
1393
1398
|
}
|
|
1394
1399
|
addCheckpoints(checkpoints, pendingChainValidationStatus) {
|
|
1395
|
-
return this.store
|
|
1396
|
-
}
|
|
1397
|
-
getBlockHeaderByHash(blockHash) {
|
|
1398
|
-
return this.store.getBlockHeaderByHash(blockHash);
|
|
1399
|
-
}
|
|
1400
|
-
getBlockHeaderByArchive(archive) {
|
|
1401
|
-
return this.store.getBlockHeaderByArchive(archive);
|
|
1402
|
-
}
|
|
1403
|
-
/**
|
|
1404
|
-
* Gets an l2 block.
|
|
1405
|
-
* @param number - The block number to return.
|
|
1406
|
-
* @returns The requested L2 block.
|
|
1407
|
-
*/ async getL2BlockNew(number) {
|
|
1408
|
-
// If the number provided is -ve, then return the latest block.
|
|
1409
|
-
if (number < 0) {
|
|
1410
|
-
number = await this.store.getSynchedL2BlockNumber();
|
|
1411
|
-
}
|
|
1412
|
-
if (number === 0) {
|
|
1413
|
-
return undefined;
|
|
1414
|
-
}
|
|
1415
|
-
const publishedBlock = await this.store.store.getBlock(number);
|
|
1416
|
-
return publishedBlock;
|
|
1417
|
-
}
|
|
1418
|
-
async getBlockHeader(number) {
|
|
1419
|
-
if (number === 'latest') {
|
|
1420
|
-
number = await this.store.getSynchedL2BlockNumber();
|
|
1421
|
-
}
|
|
1422
|
-
if (number === 0) {
|
|
1423
|
-
return undefined;
|
|
1424
|
-
}
|
|
1425
|
-
const headers = await this.store.getBlockHeaders(number, 1);
|
|
1426
|
-
return headers.length === 0 ? undefined : headers[0];
|
|
1427
|
-
}
|
|
1428
|
-
getCheckpointedBlock(number) {
|
|
1429
|
-
return this.store.getCheckpointedBlock(number);
|
|
1430
|
-
}
|
|
1431
|
-
getCheckpointedBlockByHash(blockHash) {
|
|
1432
|
-
return this.store.getCheckpointedBlockByHash(blockHash);
|
|
1433
|
-
}
|
|
1434
|
-
getProvenBlockNumber() {
|
|
1435
|
-
return this.store.getProvenBlockNumber();
|
|
1436
|
-
}
|
|
1437
|
-
getCheckpointedBlockByArchive(archive) {
|
|
1438
|
-
return this.store.getCheckpointedBlockByArchive(archive);
|
|
1439
|
-
}
|
|
1440
|
-
getTxEffect(txHash) {
|
|
1441
|
-
return this.store.getTxEffect(txHash);
|
|
1442
|
-
}
|
|
1443
|
-
getSettledTxReceipt(txHash) {
|
|
1444
|
-
return this.store.getSettledTxReceipt(txHash);
|
|
1445
|
-
}
|
|
1446
|
-
getPrivateLogsByTags(tags) {
|
|
1447
|
-
return this.store.getPrivateLogsByTags(tags);
|
|
1448
|
-
}
|
|
1449
|
-
getPublicLogsByTagsFromContract(contractAddress, tags) {
|
|
1450
|
-
return this.store.getPublicLogsByTagsFromContract(contractAddress, tags);
|
|
1451
|
-
}
|
|
1452
|
-
/**
|
|
1453
|
-
* Gets public logs based on the provided filter.
|
|
1454
|
-
* @param filter - The filter to apply to the logs.
|
|
1455
|
-
* @returns The requested logs.
|
|
1456
|
-
*/ getPublicLogs(filter) {
|
|
1457
|
-
return this.store.getPublicLogs(filter);
|
|
1458
|
-
}
|
|
1459
|
-
/**
|
|
1460
|
-
* Gets contract class logs based on the provided filter.
|
|
1461
|
-
* @param filter - The filter to apply to the logs.
|
|
1462
|
-
* @returns The requested logs.
|
|
1463
|
-
*/ getContractClassLogs(filter) {
|
|
1464
|
-
return this.store.getContractClassLogs(filter);
|
|
1465
|
-
}
|
|
1466
|
-
/**
|
|
1467
|
-
* Gets the number of the latest L2 block processed by the block source implementation.
|
|
1468
|
-
* This includes both checkpointed and uncheckpointed blocks.
|
|
1469
|
-
* @returns The number of the latest L2 block processed by the block source implementation.
|
|
1470
|
-
*/ getBlockNumber() {
|
|
1471
|
-
return this.store.getLatestBlockNumber();
|
|
1472
|
-
}
|
|
1473
|
-
getContractClass(id) {
|
|
1474
|
-
return this.store.getContractClass(id);
|
|
1475
|
-
}
|
|
1476
|
-
getBytecodeCommitment(id) {
|
|
1477
|
-
return this.store.getBytecodeCommitment(id);
|
|
1478
|
-
}
|
|
1479
|
-
async getContract(address, maybeTimestamp) {
|
|
1480
|
-
let timestamp;
|
|
1481
|
-
if (maybeTimestamp === undefined) {
|
|
1482
|
-
const latestBlockHeader = await this.getBlockHeader('latest');
|
|
1483
|
-
// If we get undefined block header, it means that the archiver has not yet synced any block so we default to 0.
|
|
1484
|
-
timestamp = latestBlockHeader ? latestBlockHeader.globalVariables.timestamp : 0n;
|
|
1485
|
-
} else {
|
|
1486
|
-
timestamp = maybeTimestamp;
|
|
1487
|
-
}
|
|
1488
|
-
return this.store.getContractInstance(address, timestamp);
|
|
1489
|
-
}
|
|
1490
|
-
/**
|
|
1491
|
-
* Gets L1 to L2 message (to be) included in a given checkpoint.
|
|
1492
|
-
* @param checkpointNumber - Checkpoint number to get messages for.
|
|
1493
|
-
* @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
|
|
1494
|
-
*/ getL1ToL2Messages(checkpointNumber) {
|
|
1495
|
-
return this.store.getL1ToL2Messages(checkpointNumber);
|
|
1496
|
-
}
|
|
1497
|
-
/**
|
|
1498
|
-
* Gets the L1 to L2 message index in the L1 to L2 message tree.
|
|
1499
|
-
* @param l1ToL2Message - The L1 to L2 message.
|
|
1500
|
-
* @returns The index of the L1 to L2 message in the L1 to L2 message tree (undefined if not found).
|
|
1501
|
-
*/ getL1ToL2MessageIndex(l1ToL2Message) {
|
|
1502
|
-
return this.store.getL1ToL2MessageIndex(l1ToL2Message);
|
|
1503
|
-
}
|
|
1504
|
-
getContractClassIds() {
|
|
1505
|
-
return this.store.getContractClassIds();
|
|
1400
|
+
return addCheckpointsWithContractData(this.store, checkpoints, pendingChainValidationStatus);
|
|
1506
1401
|
}
|
|
1507
|
-
|
|
1508
|
-
return this.store.
|
|
1509
|
-
}
|
|
1510
|
-
getDebugFunctionName(address, selector) {
|
|
1511
|
-
return this.store.getDebugFunctionName(address, selector);
|
|
1512
|
-
}
|
|
1513
|
-
async getPendingChainValidationStatus() {
|
|
1514
|
-
return await this.store.getPendingChainValidationStatus() ?? {
|
|
1515
|
-
valid: true
|
|
1516
|
-
};
|
|
1517
|
-
}
|
|
1518
|
-
isPendingChainInvalid() {
|
|
1519
|
-
return this.getPendingChainValidationStatus().then((status)=>!status.valid);
|
|
1402
|
+
getCheckpointedBlockNumber() {
|
|
1403
|
+
return this.store.getCheckpointedL2BlockNumber();
|
|
1520
1404
|
}
|
|
1521
1405
|
async getL2Tips() {
|
|
1522
|
-
const [latestBlockNumber, provenBlockNumber] = await Promise.all([
|
|
1406
|
+
const [latestBlockNumber, provenBlockNumber, checkpointedBlockNumber] = await Promise.all([
|
|
1523
1407
|
this.getBlockNumber(),
|
|
1524
|
-
this.getProvenBlockNumber()
|
|
1408
|
+
this.getProvenBlockNumber(),
|
|
1409
|
+
this.getCheckpointedBlockNumber()
|
|
1525
1410
|
]);
|
|
1526
1411
|
// TODO(#13569): Compute proper finalized block number based on L1 finalized block.
|
|
1527
1412
|
// We just force it 2 epochs worth of proven data for now.
|
|
1528
1413
|
// NOTE: update end-to-end/src/e2e_epochs/epochs_empty_blocks.test.ts as that uses finalized blocks in computations
|
|
1529
1414
|
const finalizedBlockNumber = BlockNumber(Math.max(provenBlockNumber - this.l1constants.epochDuration * 2, 0));
|
|
1530
|
-
const
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1415
|
+
const beforeInitialblockNumber = BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
|
|
1416
|
+
// Get the latest block header and checkpointed blocks for proven, finalised and checkpointed blocks
|
|
1417
|
+
const [latestBlockHeader, provenCheckpointedBlock, finalizedCheckpointedBlock, checkpointedBlock] = await Promise.all([
|
|
1418
|
+
latestBlockNumber > beforeInitialblockNumber ? this.getBlockHeader(latestBlockNumber) : undefined,
|
|
1419
|
+
provenBlockNumber > beforeInitialblockNumber ? this.getCheckpointedBlock(provenBlockNumber) : undefined,
|
|
1420
|
+
finalizedBlockNumber > beforeInitialblockNumber ? this.getCheckpointedBlock(finalizedBlockNumber) : undefined,
|
|
1421
|
+
checkpointedBlockNumber > beforeInitialblockNumber ? this.getCheckpointedBlock(checkpointedBlockNumber) : undefined
|
|
1534
1422
|
]);
|
|
1535
|
-
if (latestBlockNumber >
|
|
1423
|
+
if (latestBlockNumber > beforeInitialblockNumber && !latestBlockHeader) {
|
|
1536
1424
|
throw new Error(`Failed to retrieve latest block header for block ${latestBlockNumber}`);
|
|
1537
1425
|
}
|
|
1538
|
-
if
|
|
1539
|
-
|
|
1426
|
+
// Checkpointed blocks must exist for proven, finalized and checkpointed tips if they are beyond the initial block number.
|
|
1427
|
+
if (checkpointedBlockNumber > beforeInitialblockNumber && !checkpointedBlock?.block.header) {
|
|
1428
|
+
throw new Error(`Failed to retrieve checkpointed block header for block ${checkpointedBlockNumber} (latest block is ${latestBlockNumber})`);
|
|
1429
|
+
}
|
|
1430
|
+
if (provenBlockNumber > beforeInitialblockNumber && !provenCheckpointedBlock?.block.header) {
|
|
1431
|
+
throw new Error(`Failed to retrieve proven checkpointed for block ${provenBlockNumber} (latest block is ${latestBlockNumber})`);
|
|
1540
1432
|
}
|
|
1541
|
-
if (finalizedBlockNumber >
|
|
1433
|
+
if (finalizedBlockNumber > beforeInitialblockNumber && !finalizedCheckpointedBlock?.block.header) {
|
|
1542
1434
|
throw new Error(`Failed to retrieve finalized block header for block ${finalizedBlockNumber} (latest block is ${latestBlockNumber})`);
|
|
1543
1435
|
}
|
|
1544
1436
|
const latestBlockHeaderHash = await latestBlockHeader?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
|
|
1545
|
-
const provenBlockHeaderHash = await
|
|
1546
|
-
const finalizedBlockHeaderHash = await
|
|
1547
|
-
|
|
1548
|
-
|
|
1437
|
+
const provenBlockHeaderHash = await provenCheckpointedBlock?.block.header?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
|
|
1438
|
+
const finalizedBlockHeaderHash = await finalizedCheckpointedBlock?.block.header?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
|
|
1439
|
+
const checkpointedBlockHeaderHash = await checkpointedBlock?.block.header?.hash() ?? GENESIS_BLOCK_HEADER_HASH;
|
|
1440
|
+
// Now attempt to retrieve checkpoints for proven, finalised and checkpointed blocks
|
|
1441
|
+
const [[provenBlockCheckpoint], [finalizedBlockCheckpoint], [checkpointedBlockCheckpoint]] = await Promise.all([
|
|
1442
|
+
provenCheckpointedBlock !== undefined ? await this.getPublishedCheckpoints(provenCheckpointedBlock?.checkpointNumber, 1) : [
|
|
1443
|
+
undefined
|
|
1444
|
+
],
|
|
1445
|
+
finalizedCheckpointedBlock !== undefined ? await this.getPublishedCheckpoints(finalizedCheckpointedBlock?.checkpointNumber, 1) : [
|
|
1446
|
+
undefined
|
|
1447
|
+
],
|
|
1448
|
+
checkpointedBlock !== undefined ? await this.getPublishedCheckpoints(checkpointedBlock?.checkpointNumber, 1) : [
|
|
1449
|
+
undefined
|
|
1450
|
+
]
|
|
1451
|
+
]);
|
|
1452
|
+
const initialcheckpointId = {
|
|
1453
|
+
number: CheckpointNumber.ZERO,
|
|
1454
|
+
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
|
|
1455
|
+
};
|
|
1456
|
+
const makeCheckpointId = (checkpoint)=>{
|
|
1457
|
+
if (checkpoint === undefined) {
|
|
1458
|
+
return initialcheckpointId;
|
|
1459
|
+
}
|
|
1460
|
+
return {
|
|
1461
|
+
number: checkpoint.checkpoint.number,
|
|
1462
|
+
hash: checkpoint.checkpoint.hash().toString()
|
|
1463
|
+
};
|
|
1464
|
+
};
|
|
1465
|
+
const l2Tips = {
|
|
1466
|
+
proposed: {
|
|
1549
1467
|
number: latestBlockNumber,
|
|
1550
1468
|
hash: latestBlockHeaderHash.toString()
|
|
1551
1469
|
},
|
|
1552
1470
|
proven: {
|
|
1553
|
-
|
|
1554
|
-
|
|
1471
|
+
block: {
|
|
1472
|
+
number: provenBlockNumber,
|
|
1473
|
+
hash: provenBlockHeaderHash.toString()
|
|
1474
|
+
},
|
|
1475
|
+
checkpoint: makeCheckpointId(provenBlockCheckpoint)
|
|
1555
1476
|
},
|
|
1556
1477
|
finalized: {
|
|
1557
|
-
|
|
1558
|
-
|
|
1478
|
+
block: {
|
|
1479
|
+
number: finalizedBlockNumber,
|
|
1480
|
+
hash: finalizedBlockHeaderHash.toString()
|
|
1481
|
+
},
|
|
1482
|
+
checkpoint: makeCheckpointId(finalizedBlockCheckpoint)
|
|
1483
|
+
},
|
|
1484
|
+
checkpointed: {
|
|
1485
|
+
block: {
|
|
1486
|
+
number: checkpointedBlockNumber,
|
|
1487
|
+
hash: checkpointedBlockHeaderHash.toString()
|
|
1488
|
+
},
|
|
1489
|
+
checkpoint: makeCheckpointId(checkpointedBlockCheckpoint)
|
|
1559
1490
|
}
|
|
1560
1491
|
};
|
|
1492
|
+
return l2Tips;
|
|
1561
1493
|
}
|
|
1562
1494
|
async rollbackTo(targetL2BlockNumber) {
|
|
1563
1495
|
// TODO(pw/mbps): This still assumes 1 block per checkpoint
|
|
1564
1496
|
const currentBlocks = await this.getL2Tips();
|
|
1565
|
-
const currentL2Block = currentBlocks.
|
|
1566
|
-
const currentProvenBlock = currentBlocks.proven.number;
|
|
1497
|
+
const currentL2Block = currentBlocks.proposed.number;
|
|
1498
|
+
const currentProvenBlock = currentBlocks.proven.block.number;
|
|
1567
1499
|
if (targetL2BlockNumber >= currentL2Block) {
|
|
1568
1500
|
throw new Error(`Target L2 block ${targetL2BlockNumber} must be less than current L2 block ${currentL2Block}`);
|
|
1569
1501
|
}
|
|
@@ -1576,11 +1508,11 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1576
1508
|
const targetCheckpointNumber = CheckpointNumber.fromBlockNumber(targetL2BlockNumber);
|
|
1577
1509
|
const targetL1BlockHash = await this.getL1BlockHash(targetL1BlockNumber);
|
|
1578
1510
|
this.log.info(`Unwinding ${blocksToUnwind} checkpoints from L2 block ${currentL2Block}`);
|
|
1579
|
-
await this.store
|
|
1511
|
+
await unwindCheckpointsWithContractData(this.store, CheckpointNumber(currentL2Block), blocksToUnwind);
|
|
1580
1512
|
this.log.info(`Unwinding L1 to L2 messages to checkpoint ${targetCheckpointNumber}`);
|
|
1581
1513
|
await this.store.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
|
|
1582
1514
|
this.log.info(`Setting L1 syncpoints to ${targetL1BlockNumber}`);
|
|
1583
|
-
await this.store.
|
|
1515
|
+
await this.store.setCheckpointSynchedL1BlockNumber(targetL1BlockNumber);
|
|
1584
1516
|
await this.store.setMessageSynchedL1Block({
|
|
1585
1517
|
l1BlockNumber: targetL1BlockNumber,
|
|
1586
1518
|
l1BlockHash: targetL1BlockHash
|
|
@@ -1595,19 +1527,6 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1595
1527
|
// await this.store.setFinalizedL2BlockNumber(0);
|
|
1596
1528
|
// }
|
|
1597
1529
|
}
|
|
1598
|
-
async getPublishedCheckpoints(checkpointNumber, limit) {
|
|
1599
|
-
const checkpoints = await this.store.getRangeOfCheckpoints(checkpointNumber, limit);
|
|
1600
|
-
const blocks = (await Promise.all(checkpoints.map((ch)=>this.store.getBlocksForCheckpoint(ch.checkpointNumber)))).filter(isDefined);
|
|
1601
|
-
const fullCheckpoints = [];
|
|
1602
|
-
for(let i = 0; i < checkpoints.length; i++){
|
|
1603
|
-
const blocksForCheckpoint = blocks[i];
|
|
1604
|
-
const checkpoint = checkpoints[i];
|
|
1605
|
-
const fullCheckpoint = new Checkpoint(checkpoint.archive, checkpoint.header, blocksForCheckpoint, checkpoint.checkpointNumber);
|
|
1606
|
-
const publishedCheckpoint = new PublishedCheckpoint(fullCheckpoint, checkpoint.l1, checkpoint.attestations.map((x)=>CommitteeAttestation.fromBuffer(x)));
|
|
1607
|
-
fullCheckpoints.push(publishedCheckpoint);
|
|
1608
|
-
}
|
|
1609
|
-
return fullCheckpoints;
|
|
1610
|
-
}
|
|
1611
1530
|
async getCheckpointsForEpoch(epochNumber) {
|
|
1612
1531
|
const [start, end] = getSlotRangeForEpoch(epochNumber, this.l1constants);
|
|
1613
1532
|
const checkpoints = [];
|
|
@@ -1625,413 +1544,4 @@ _dec = trackSpan('Archiver.syncFromL1'), _dec1 = trackSpan('Archiver.sync'), _de
|
|
|
1625
1544
|
}
|
|
1626
1545
|
return checkpoints.reverse();
|
|
1627
1546
|
}
|
|
1628
|
-
/* Legacy APIs */ async getPublishedBlockByHash(blockHash) {
|
|
1629
|
-
const checkpointedBlock = await this.store.getCheckpointedBlockByHash(blockHash);
|
|
1630
|
-
return this.buildOldBlockFromCheckpointedBlock(checkpointedBlock);
|
|
1631
|
-
}
|
|
1632
|
-
async getPublishedBlockByArchive(archive) {
|
|
1633
|
-
const checkpointedBlock = await this.store.getCheckpointedBlockByArchive(archive);
|
|
1634
|
-
return this.buildOldBlockFromCheckpointedBlock(checkpointedBlock);
|
|
1635
|
-
}
|
|
1636
|
-
/**
|
|
1637
|
-
* Gets up to `limit` amount of L2 blocks starting from `from`.
|
|
1638
|
-
* @param from - Number of the first block to return (inclusive).
|
|
1639
|
-
* @param limit - The number of blocks to return.
|
|
1640
|
-
* @param proven - If true, only return blocks that have been proven.
|
|
1641
|
-
* @returns The requested L2 blocks.
|
|
1642
|
-
*/ async getBlocks(from, limit, proven) {
|
|
1643
|
-
const publishedBlocks = await this.getPublishedBlocks(from, limit, proven);
|
|
1644
|
-
return publishedBlocks.map((x)=>x.block);
|
|
1645
|
-
}
|
|
1646
|
-
async getPublishedBlocks(from, limit, proven) {
|
|
1647
|
-
const checkpoints = await this.store.getRangeOfCheckpoints(CheckpointNumber(from), limit);
|
|
1648
|
-
const provenCheckpointNumber = await this.getProvenCheckpointNumber();
|
|
1649
|
-
const blocks = (await Promise.all(checkpoints.map((ch)=>this.store.getBlocksForCheckpoint(ch.checkpointNumber)))).filter(isDefined);
|
|
1650
|
-
const olbBlocks = [];
|
|
1651
|
-
for(let i = 0; i < checkpoints.length; i++){
|
|
1652
|
-
const blockForCheckpoint = blocks[i][0];
|
|
1653
|
-
const checkpoint = checkpoints[i];
|
|
1654
|
-
if (checkpoint.checkpointNumber > provenCheckpointNumber && proven === true) {
|
|
1655
|
-
continue;
|
|
1656
|
-
}
|
|
1657
|
-
const oldCheckpoint = new Checkpoint(blockForCheckpoint.archive, checkpoint.header, [
|
|
1658
|
-
blockForCheckpoint
|
|
1659
|
-
], checkpoint.checkpointNumber);
|
|
1660
|
-
const oldBlock = L2Block.fromCheckpoint(oldCheckpoint);
|
|
1661
|
-
const publishedBlock = new PublishedL2Block(oldBlock, checkpoint.l1, checkpoint.attestations.map((x)=>CommitteeAttestation.fromBuffer(x)));
|
|
1662
|
-
olbBlocks.push(publishedBlock);
|
|
1663
|
-
}
|
|
1664
|
-
return olbBlocks;
|
|
1665
|
-
}
|
|
1666
|
-
async buildOldBlockFromCheckpointedBlock(checkpointedBlock) {
|
|
1667
|
-
if (!checkpointedBlock) {
|
|
1668
|
-
return undefined;
|
|
1669
|
-
}
|
|
1670
|
-
const checkpoint = await this.store.getCheckpointData(checkpointedBlock.checkpointNumber);
|
|
1671
|
-
if (!checkpoint) {
|
|
1672
|
-
return checkpoint;
|
|
1673
|
-
}
|
|
1674
|
-
const fullCheckpoint = new Checkpoint(checkpointedBlock?.block.archive, checkpoint?.header, [
|
|
1675
|
-
checkpointedBlock.block
|
|
1676
|
-
], checkpoint.checkpointNumber);
|
|
1677
|
-
const oldBlock = L2Block.fromCheckpoint(fullCheckpoint);
|
|
1678
|
-
const published = new PublishedL2Block(oldBlock, checkpoint.l1, checkpoint.attestations.map((x)=>CommitteeAttestation.fromBuffer(x)));
|
|
1679
|
-
return published;
|
|
1680
|
-
}
|
|
1681
|
-
async getBlock(number) {
|
|
1682
|
-
// If the number provided is -ve, then return the latest block.
|
|
1683
|
-
if (number < 0) {
|
|
1684
|
-
number = await this.store.getSynchedL2BlockNumber();
|
|
1685
|
-
}
|
|
1686
|
-
if (number === 0) {
|
|
1687
|
-
return undefined;
|
|
1688
|
-
}
|
|
1689
|
-
const publishedBlocks = await this.getPublishedBlocks(number, 1);
|
|
1690
|
-
if (publishedBlocks.length === 0) {
|
|
1691
|
-
return undefined;
|
|
1692
|
-
}
|
|
1693
|
-
return publishedBlocks[0].block;
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
var Operation = /*#__PURE__*/ function(Operation) {
|
|
1697
|
-
Operation[Operation["Store"] = 0] = "Store";
|
|
1698
|
-
Operation[Operation["Delete"] = 1] = "Delete";
|
|
1699
|
-
return Operation;
|
|
1700
|
-
}(Operation || {});
|
|
1701
|
-
/**
|
|
1702
|
-
* A helper class that we use to deal with some of the logic needed when adding blocks.
|
|
1703
|
-
*
|
|
1704
|
-
* I would have preferred to not have this type. But it is useful for handling the logic that any
|
|
1705
|
-
* store would need to include otherwise while exposing fewer functions and logic directly to the archiver.
|
|
1706
|
-
*/ export class ArchiverStoreHelper {
|
|
1707
|
-
store;
|
|
1708
|
-
#log;
|
|
1709
|
-
constructor(store){
|
|
1710
|
-
this.store = store;
|
|
1711
|
-
this.#log = createLogger('archiver:block-helper');
|
|
1712
|
-
}
|
|
1713
|
-
/**
|
|
1714
|
-
* Extracts and stores contract classes out of ContractClassPublished events emitted by the class registry contract.
|
|
1715
|
-
* @param allLogs - All logs emitted in a bunch of blocks.
|
|
1716
|
-
*/ async #updatePublishedContractClasses(allLogs, blockNum, operation) {
|
|
1717
|
-
const contractClassPublishedEvents = allLogs.filter((log)=>ContractClassPublishedEvent.isContractClassPublishedEvent(log)).map((log)=>ContractClassPublishedEvent.fromLog(log));
|
|
1718
|
-
const contractClasses = await Promise.all(contractClassPublishedEvents.map((e)=>e.toContractClassPublic()));
|
|
1719
|
-
if (contractClasses.length > 0) {
|
|
1720
|
-
contractClasses.forEach((c)=>this.#log.verbose(`${Operation[operation]} contract class ${c.id.toString()}`));
|
|
1721
|
-
if (operation == 0) {
|
|
1722
|
-
// TODO: Will probably want to create some worker threads to compute these bytecode commitments as they are expensive
|
|
1723
|
-
const commitments = await Promise.all(contractClasses.map((c)=>computePublicBytecodeCommitment(c.packedBytecode)));
|
|
1724
|
-
return await this.store.addContractClasses(contractClasses, commitments, blockNum);
|
|
1725
|
-
} else if (operation == 1) {
|
|
1726
|
-
return await this.store.deleteContractClasses(contractClasses, blockNum);
|
|
1727
|
-
}
|
|
1728
|
-
}
|
|
1729
|
-
return true;
|
|
1730
|
-
}
|
|
1731
|
-
/**
|
|
1732
|
-
* Extracts and stores contract instances out of ContractInstancePublished events emitted by the canonical deployer contract.
|
|
1733
|
-
* @param allLogs - All logs emitted in a bunch of blocks.
|
|
1734
|
-
*/ async #updateDeployedContractInstances(allLogs, blockNum, operation) {
|
|
1735
|
-
const contractInstances = allLogs.filter((log)=>ContractInstancePublishedEvent.isContractInstancePublishedEvent(log)).map((log)=>ContractInstancePublishedEvent.fromLog(log)).map((e)=>e.toContractInstance());
|
|
1736
|
-
if (contractInstances.length > 0) {
|
|
1737
|
-
contractInstances.forEach((c)=>this.#log.verbose(`${Operation[operation]} contract instance at ${c.address.toString()}`));
|
|
1738
|
-
if (operation == 0) {
|
|
1739
|
-
return await this.store.addContractInstances(contractInstances, blockNum);
|
|
1740
|
-
} else if (operation == 1) {
|
|
1741
|
-
return await this.store.deleteContractInstances(contractInstances, blockNum);
|
|
1742
|
-
}
|
|
1743
|
-
}
|
|
1744
|
-
return true;
|
|
1745
|
-
}
|
|
1746
|
-
/**
|
|
1747
|
-
* Extracts and stores contract instances out of ContractInstancePublished events emitted by the canonical deployer contract.
|
|
1748
|
-
* @param allLogs - All logs emitted in a bunch of blocks.
|
|
1749
|
-
* @param timestamp - Timestamp at which the updates were scheduled.
|
|
1750
|
-
* @param operation - The operation to perform on the contract instance updates (Store or Delete).
|
|
1751
|
-
*/ async #updateUpdatedContractInstances(allLogs, timestamp, operation) {
|
|
1752
|
-
const contractUpdates = allLogs.filter((log)=>ContractInstanceUpdatedEvent.isContractInstanceUpdatedEvent(log)).map((log)=>ContractInstanceUpdatedEvent.fromLog(log)).map((e)=>e.toContractInstanceUpdate());
|
|
1753
|
-
if (contractUpdates.length > 0) {
|
|
1754
|
-
contractUpdates.forEach((c)=>this.#log.verbose(`${Operation[operation]} contract instance update at ${c.address.toString()}`));
|
|
1755
|
-
if (operation == 0) {
|
|
1756
|
-
return await this.store.addContractInstanceUpdates(contractUpdates, timestamp);
|
|
1757
|
-
} else if (operation == 1) {
|
|
1758
|
-
return await this.store.deleteContractInstanceUpdates(contractUpdates, timestamp);
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
return true;
|
|
1762
|
-
}
|
|
1763
|
-
/**
|
|
1764
|
-
* Stores the functions that were broadcasted individually
|
|
1765
|
-
*
|
|
1766
|
-
* @dev Beware that there is not a delete variant of this, since they are added to contract classes
|
|
1767
|
-
* and will be deleted as part of the class if needed.
|
|
1768
|
-
*
|
|
1769
|
-
* @param allLogs - The logs from the block
|
|
1770
|
-
* @param _blockNum - The block number
|
|
1771
|
-
* @returns
|
|
1772
|
-
*/ async #storeBroadcastedIndividualFunctions(allLogs, _blockNum) {
|
|
1773
|
-
// Filter out private and utility function broadcast events
|
|
1774
|
-
const privateFnEvents = allLogs.filter((log)=>PrivateFunctionBroadcastedEvent.isPrivateFunctionBroadcastedEvent(log)).map((log)=>PrivateFunctionBroadcastedEvent.fromLog(log));
|
|
1775
|
-
const utilityFnEvents = allLogs.filter((log)=>UtilityFunctionBroadcastedEvent.isUtilityFunctionBroadcastedEvent(log)).map((log)=>UtilityFunctionBroadcastedEvent.fromLog(log));
|
|
1776
|
-
// Group all events by contract class id
|
|
1777
|
-
for (const [classIdString, classEvents] of Object.entries(groupBy([
|
|
1778
|
-
...privateFnEvents,
|
|
1779
|
-
...utilityFnEvents
|
|
1780
|
-
], (e)=>e.contractClassId.toString()))){
|
|
1781
|
-
const contractClassId = Fr.fromHexString(classIdString);
|
|
1782
|
-
const contractClass = await this.getContractClass(contractClassId);
|
|
1783
|
-
if (!contractClass) {
|
|
1784
|
-
this.#log.warn(`Skipping broadcasted functions as contract class ${contractClassId.toString()} was not found`);
|
|
1785
|
-
continue;
|
|
1786
|
-
}
|
|
1787
|
-
// Split private and utility functions, and filter out invalid ones
|
|
1788
|
-
const allFns = classEvents.map((e)=>e.toFunctionWithMembershipProof());
|
|
1789
|
-
const privateFns = allFns.filter((fn)=>'utilityFunctionsTreeRoot' in fn);
|
|
1790
|
-
const utilityFns = allFns.filter((fn)=>'privateFunctionsArtifactTreeRoot' in fn);
|
|
1791
|
-
const privateFunctionsWithValidity = await Promise.all(privateFns.map(async (fn)=>({
|
|
1792
|
-
fn,
|
|
1793
|
-
valid: await isValidPrivateFunctionMembershipProof(fn, contractClass)
|
|
1794
|
-
})));
|
|
1795
|
-
const validPrivateFns = privateFunctionsWithValidity.filter(({ valid })=>valid).map(({ fn })=>fn);
|
|
1796
|
-
const utilityFunctionsWithValidity = await Promise.all(utilityFns.map(async (fn)=>({
|
|
1797
|
-
fn,
|
|
1798
|
-
valid: await isValidUtilityFunctionMembershipProof(fn, contractClass)
|
|
1799
|
-
})));
|
|
1800
|
-
const validUtilityFns = utilityFunctionsWithValidity.filter(({ valid })=>valid).map(({ fn })=>fn);
|
|
1801
|
-
const validFnCount = validPrivateFns.length + validUtilityFns.length;
|
|
1802
|
-
if (validFnCount !== allFns.length) {
|
|
1803
|
-
this.#log.warn(`Skipping ${allFns.length - validFnCount} invalid functions`);
|
|
1804
|
-
}
|
|
1805
|
-
// Store the functions in the contract class in a single operation
|
|
1806
|
-
if (validFnCount > 0) {
|
|
1807
|
-
this.#log.verbose(`Storing ${validFnCount} functions for contract class ${contractClassId.toString()}`);
|
|
1808
|
-
}
|
|
1809
|
-
return await this.store.addFunctions(contractClassId, validPrivateFns, validUtilityFns);
|
|
1810
|
-
}
|
|
1811
|
-
return true;
|
|
1812
|
-
}
|
|
1813
|
-
async addBlockDataToDB(block) {
|
|
1814
|
-
const contractClassLogs = block.body.txEffects.flatMap((txEffect)=>txEffect.contractClassLogs);
|
|
1815
|
-
// ContractInstancePublished event logs are broadcast in privateLogs.
|
|
1816
|
-
const privateLogs = block.body.txEffects.flatMap((txEffect)=>txEffect.privateLogs);
|
|
1817
|
-
const publicLogs = block.body.txEffects.flatMap((txEffect)=>txEffect.publicLogs);
|
|
1818
|
-
return (await Promise.all([
|
|
1819
|
-
this.#updatePublishedContractClasses(contractClassLogs, block.number, 0),
|
|
1820
|
-
this.#updateDeployedContractInstances(privateLogs, block.number, 0),
|
|
1821
|
-
this.#updateUpdatedContractInstances(publicLogs, block.header.globalVariables.timestamp, 0),
|
|
1822
|
-
this.#storeBroadcastedIndividualFunctions(contractClassLogs, block.number)
|
|
1823
|
-
])).every(Boolean);
|
|
1824
|
-
}
|
|
1825
|
-
addBlocks(blocks, pendingChainValidationStatus) {
|
|
1826
|
-
// Add the blocks to the store. Store will throw if the blocks are not in order, there are gaps,
|
|
1827
|
-
// or if the previous block is not in the store.
|
|
1828
|
-
return this.store.transactionAsync(async ()=>{
|
|
1829
|
-
await this.store.addBlocks(blocks);
|
|
1830
|
-
const opResults = await Promise.all([
|
|
1831
|
-
// Update the pending chain validation status if provided
|
|
1832
|
-
pendingChainValidationStatus && this.store.setPendingChainValidationStatus(pendingChainValidationStatus),
|
|
1833
|
-
// Add any logs emitted during the retrieved blocks
|
|
1834
|
-
this.store.addLogs(blocks),
|
|
1835
|
-
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
1836
|
-
...blocks.map((block)=>{
|
|
1837
|
-
return this.addBlockDataToDB(block);
|
|
1838
|
-
})
|
|
1839
|
-
]);
|
|
1840
|
-
return opResults.every(Boolean);
|
|
1841
|
-
});
|
|
1842
|
-
}
|
|
1843
|
-
addCheckpoints(checkpoints, pendingChainValidationStatus) {
|
|
1844
|
-
// Add the blocks to the store. Store will throw if the blocks are not in order, there are gaps,
|
|
1845
|
-
// or if the previous block is not in the store.
|
|
1846
|
-
return this.store.transactionAsync(async ()=>{
|
|
1847
|
-
await this.store.addCheckpoints(checkpoints);
|
|
1848
|
-
const allBlocks = checkpoints.flatMap((ch)=>ch.checkpoint.blocks);
|
|
1849
|
-
const opResults = await Promise.all([
|
|
1850
|
-
// Update the pending chain validation status if provided
|
|
1851
|
-
pendingChainValidationStatus && this.store.setPendingChainValidationStatus(pendingChainValidationStatus),
|
|
1852
|
-
// Add any logs emitted during the retrieved blocks
|
|
1853
|
-
this.store.addLogs(allBlocks),
|
|
1854
|
-
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
1855
|
-
...allBlocks.map((block)=>{
|
|
1856
|
-
return this.addBlockDataToDB(block);
|
|
1857
|
-
})
|
|
1858
|
-
]);
|
|
1859
|
-
return opResults.every(Boolean);
|
|
1860
|
-
});
|
|
1861
|
-
}
|
|
1862
|
-
async unwindCheckpoints(from, checkpointsToUnwind) {
|
|
1863
|
-
if (checkpointsToUnwind <= 0) {
|
|
1864
|
-
throw new Error(`Cannot unwind ${checkpointsToUnwind} blocks`);
|
|
1865
|
-
}
|
|
1866
|
-
const last = await this.getSynchedCheckpointNumber();
|
|
1867
|
-
if (from != last) {
|
|
1868
|
-
throw new Error(`Cannot unwind checkpoints from checkpoint ${from} when the last checkpoint is ${last}`);
|
|
1869
|
-
}
|
|
1870
|
-
const blocks = [];
|
|
1871
|
-
const lastCheckpointNumber = from + checkpointsToUnwind - 1;
|
|
1872
|
-
for(let checkpointNumber = from; checkpointNumber <= lastCheckpointNumber; checkpointNumber++){
|
|
1873
|
-
const blocksForCheckpoint = await this.store.getBlocksForCheckpoint(checkpointNumber);
|
|
1874
|
-
if (!blocksForCheckpoint) {
|
|
1875
|
-
continue;
|
|
1876
|
-
}
|
|
1877
|
-
blocks.push(...blocksForCheckpoint);
|
|
1878
|
-
}
|
|
1879
|
-
const opResults = await Promise.all([
|
|
1880
|
-
// Prune rolls back to the last proven block, which is by definition valid
|
|
1881
|
-
this.store.setPendingChainValidationStatus({
|
|
1882
|
-
valid: true
|
|
1883
|
-
}),
|
|
1884
|
-
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
1885
|
-
...blocks.map(async (block)=>{
|
|
1886
|
-
const contractClassLogs = block.body.txEffects.flatMap((txEffect)=>txEffect.contractClassLogs);
|
|
1887
|
-
// ContractInstancePublished event logs are broadcast in privateLogs.
|
|
1888
|
-
const privateLogs = block.body.txEffects.flatMap((txEffect)=>txEffect.privateLogs);
|
|
1889
|
-
const publicLogs = block.body.txEffects.flatMap((txEffect)=>txEffect.publicLogs);
|
|
1890
|
-
return (await Promise.all([
|
|
1891
|
-
this.#updatePublishedContractClasses(contractClassLogs, block.number, 1),
|
|
1892
|
-
this.#updateDeployedContractInstances(privateLogs, block.number, 1),
|
|
1893
|
-
this.#updateUpdatedContractInstances(publicLogs, block.header.globalVariables.timestamp, 1)
|
|
1894
|
-
])).every(Boolean);
|
|
1895
|
-
}),
|
|
1896
|
-
this.store.deleteLogs(blocks),
|
|
1897
|
-
this.store.unwindCheckpoints(from, checkpointsToUnwind)
|
|
1898
|
-
]);
|
|
1899
|
-
return opResults.every(Boolean);
|
|
1900
|
-
}
|
|
1901
|
-
getCheckpointData(checkpointNumber) {
|
|
1902
|
-
return this.store.getCheckpointData(checkpointNumber);
|
|
1903
|
-
}
|
|
1904
|
-
getRangeOfCheckpoints(from, limit) {
|
|
1905
|
-
return this.store.getRangeOfCheckpoints(from, limit);
|
|
1906
|
-
}
|
|
1907
|
-
getCheckpointedL2BlockNumber() {
|
|
1908
|
-
return this.store.getCheckpointedL2BlockNumber();
|
|
1909
|
-
}
|
|
1910
|
-
getSynchedCheckpointNumber() {
|
|
1911
|
-
return this.store.getSynchedCheckpointNumber();
|
|
1912
|
-
}
|
|
1913
|
-
setCheckpointSynchedL1BlockNumber(l1BlockNumber) {
|
|
1914
|
-
return this.store.setCheckpointSynchedL1BlockNumber(l1BlockNumber);
|
|
1915
|
-
}
|
|
1916
|
-
getCheckpointedBlock(number) {
|
|
1917
|
-
return this.store.getCheckpointedBlock(number);
|
|
1918
|
-
}
|
|
1919
|
-
getCheckpointedBlockByHash(blockHash) {
|
|
1920
|
-
return this.store.getCheckpointedBlockByHash(blockHash);
|
|
1921
|
-
}
|
|
1922
|
-
getCheckpointedBlockByArchive(archive) {
|
|
1923
|
-
return this.store.getCheckpointedBlockByArchive(archive);
|
|
1924
|
-
}
|
|
1925
|
-
getBlockHeaders(from, limit) {
|
|
1926
|
-
return this.store.getBlockHeaders(from, limit);
|
|
1927
|
-
}
|
|
1928
|
-
getBlockHeaderByHash(blockHash) {
|
|
1929
|
-
return this.store.getBlockHeaderByHash(blockHash);
|
|
1930
|
-
}
|
|
1931
|
-
getBlockHeaderByArchive(archive) {
|
|
1932
|
-
return this.store.getBlockHeaderByArchive(archive);
|
|
1933
|
-
}
|
|
1934
|
-
getBlockByHash(blockHash) {
|
|
1935
|
-
return this.store.getBlockByHash(blockHash);
|
|
1936
|
-
}
|
|
1937
|
-
getBlockByArchive(archive) {
|
|
1938
|
-
return this.store.getBlockByArchive(archive);
|
|
1939
|
-
}
|
|
1940
|
-
getLatestBlockNumber() {
|
|
1941
|
-
return this.store.getLatestBlockNumber();
|
|
1942
|
-
}
|
|
1943
|
-
getBlocksForCheckpoint(checkpointNumber) {
|
|
1944
|
-
return this.store.getBlocksForCheckpoint(checkpointNumber);
|
|
1945
|
-
}
|
|
1946
|
-
getTxEffect(txHash) {
|
|
1947
|
-
return this.store.getTxEffect(txHash);
|
|
1948
|
-
}
|
|
1949
|
-
getSettledTxReceipt(txHash) {
|
|
1950
|
-
return this.store.getSettledTxReceipt(txHash);
|
|
1951
|
-
}
|
|
1952
|
-
addL1ToL2Messages(messages) {
|
|
1953
|
-
return this.store.addL1ToL2Messages(messages);
|
|
1954
|
-
}
|
|
1955
|
-
getL1ToL2Messages(checkpointNumber) {
|
|
1956
|
-
return this.store.getL1ToL2Messages(checkpointNumber);
|
|
1957
|
-
}
|
|
1958
|
-
getL1ToL2MessageIndex(l1ToL2Message) {
|
|
1959
|
-
return this.store.getL1ToL2MessageIndex(l1ToL2Message);
|
|
1960
|
-
}
|
|
1961
|
-
getPrivateLogsByTags(tags) {
|
|
1962
|
-
return this.store.getPrivateLogsByTags(tags);
|
|
1963
|
-
}
|
|
1964
|
-
getPublicLogsByTagsFromContract(contractAddress, tags) {
|
|
1965
|
-
return this.store.getPublicLogsByTagsFromContract(contractAddress, tags);
|
|
1966
|
-
}
|
|
1967
|
-
getPublicLogs(filter) {
|
|
1968
|
-
return this.store.getPublicLogs(filter);
|
|
1969
|
-
}
|
|
1970
|
-
getContractClassLogs(filter) {
|
|
1971
|
-
return this.store.getContractClassLogs(filter);
|
|
1972
|
-
}
|
|
1973
|
-
getSynchedL2BlockNumber() {
|
|
1974
|
-
return this.store.getCheckpointedL2BlockNumber();
|
|
1975
|
-
}
|
|
1976
|
-
getProvenCheckpointNumber() {
|
|
1977
|
-
return this.store.getProvenCheckpointNumber();
|
|
1978
|
-
}
|
|
1979
|
-
getProvenBlockNumber() {
|
|
1980
|
-
return this.store.getProvenBlockNumber();
|
|
1981
|
-
}
|
|
1982
|
-
setProvenCheckpointNumber(checkpointNumber) {
|
|
1983
|
-
return this.store.setProvenCheckpointNumber(checkpointNumber);
|
|
1984
|
-
}
|
|
1985
|
-
setBlockSynchedL1BlockNumber(l1BlockNumber) {
|
|
1986
|
-
return this.store.setCheckpointSynchedL1BlockNumber(l1BlockNumber);
|
|
1987
|
-
}
|
|
1988
|
-
setMessageSynchedL1Block(l1Block) {
|
|
1989
|
-
return this.store.setMessageSynchedL1Block(l1Block);
|
|
1990
|
-
}
|
|
1991
|
-
getSynchPoint() {
|
|
1992
|
-
return this.store.getSynchPoint();
|
|
1993
|
-
}
|
|
1994
|
-
getContractClass(id) {
|
|
1995
|
-
return this.store.getContractClass(id);
|
|
1996
|
-
}
|
|
1997
|
-
getBytecodeCommitment(contractClassId) {
|
|
1998
|
-
return this.store.getBytecodeCommitment(contractClassId);
|
|
1999
|
-
}
|
|
2000
|
-
getContractInstance(address, timestamp) {
|
|
2001
|
-
return this.store.getContractInstance(address, timestamp);
|
|
2002
|
-
}
|
|
2003
|
-
getContractClassIds() {
|
|
2004
|
-
return this.store.getContractClassIds();
|
|
2005
|
-
}
|
|
2006
|
-
registerContractFunctionSignatures(signatures) {
|
|
2007
|
-
return this.store.registerContractFunctionSignatures(signatures);
|
|
2008
|
-
}
|
|
2009
|
-
getDebugFunctionName(address, selector) {
|
|
2010
|
-
return this.store.getDebugFunctionName(address, selector);
|
|
2011
|
-
}
|
|
2012
|
-
getTotalL1ToL2MessageCount() {
|
|
2013
|
-
return this.store.getTotalL1ToL2MessageCount();
|
|
2014
|
-
}
|
|
2015
|
-
estimateSize() {
|
|
2016
|
-
return this.store.estimateSize();
|
|
2017
|
-
}
|
|
2018
|
-
rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber) {
|
|
2019
|
-
return this.store.rollbackL1ToL2MessagesToCheckpoint(targetCheckpointNumber);
|
|
2020
|
-
}
|
|
2021
|
-
iterateL1ToL2Messages(range = {}) {
|
|
2022
|
-
return this.store.iterateL1ToL2Messages(range);
|
|
2023
|
-
}
|
|
2024
|
-
removeL1ToL2Messages(startIndex) {
|
|
2025
|
-
return this.store.removeL1ToL2Messages(startIndex);
|
|
2026
|
-
}
|
|
2027
|
-
getLastL1ToL2Message() {
|
|
2028
|
-
return this.store.getLastL1ToL2Message();
|
|
2029
|
-
}
|
|
2030
|
-
getPendingChainValidationStatus() {
|
|
2031
|
-
return this.store.getPendingChainValidationStatus();
|
|
2032
|
-
}
|
|
2033
|
-
setPendingChainValidationStatus(status) {
|
|
2034
|
-
this.#log.debug(`Setting pending chain validation status to valid ${status?.valid}`, status);
|
|
2035
|
-
return this.store.setPendingChainValidationStatus(status);
|
|
2036
|
-
}
|
|
2037
1547
|
}
|