@aztec/archiver 0.86.0-starknet.1 → 0.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/archiver/archiver.d.ts +20 -8
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +259 -65
- package/dest/archiver/archiver_store.d.ts +30 -15
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +357 -55
- package/dest/archiver/data_retrieval.d.ts +5 -3
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +41 -23
- package/dest/archiver/errors.d.ts +8 -0
- package/dest/archiver/errors.d.ts.map +1 -1
- package/dest/archiver/errors.js +12 -0
- package/dest/archiver/instrumentation.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.d.ts +4 -1
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +34 -5
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +3 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +17 -3
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +19 -11
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +30 -10
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +1 -1
- package/dest/archiver/kv_archiver_store/message_store.d.ts +21 -15
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +150 -48
- package/dest/archiver/structs/inbox_message.d.ts +14 -0
- package/dest/archiver/structs/inbox_message.d.ts.map +1 -0
- package/dest/archiver/structs/inbox_message.js +38 -0
- package/dest/rpc/index.d.ts +1 -1
- package/dest/test/mock_l2_block_source.d.ts +2 -0
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +8 -1
- package/dest/test/mock_structs.d.ts +9 -0
- package/dest/test/mock_structs.d.ts.map +1 -0
- package/dest/test/mock_structs.js +37 -0
- package/package.json +15 -15
- package/src/archiver/archiver.ts +297 -79
- package/src/archiver/archiver_store.ts +34 -15
- package/src/archiver/archiver_store_test_suite.ts +300 -45
- package/src/archiver/data_retrieval.ts +47 -30
- package/src/archiver/errors.ts +21 -0
- package/src/archiver/instrumentation.ts +4 -1
- package/src/archiver/kv_archiver_store/block_store.ts +37 -8
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +20 -7
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +47 -15
- package/src/archiver/kv_archiver_store/log_store.ts +6 -2
- package/src/archiver/kv_archiver_store/message_store.ts +209 -53
- package/src/archiver/structs/inbox_message.ts +40 -0
- package/src/test/mock_l2_block_source.ts +9 -1
- package/src/test/mock_structs.ts +49 -0
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +0 -23
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +0 -1
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +0 -49
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +0 -61
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
3
|
-
import { type ViemPublicClient } from '@aztec/ethereum';
|
|
2
|
+
import { type L1BlockId, type ViemPublicClient } from '@aztec/ethereum';
|
|
3
|
+
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
4
4
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import { Fr } from '@aztec/foundation/fields';
|
|
6
6
|
import { type Logger } from '@aztec/foundation/log';
|
|
7
|
+
import type { CustomRange } from '@aztec/kv-store';
|
|
7
8
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
8
9
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
10
|
import { type L2Block, type L2BlockSource, type L2Tips } from '@aztec/stdlib/block';
|
|
@@ -12,14 +13,14 @@ import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
|
12
13
|
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
13
14
|
import type { L2LogsSource } from '@aztec/stdlib/interfaces/server';
|
|
14
15
|
import { type LogFilter, type PrivateLog, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
15
|
-
import type {
|
|
16
|
+
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
16
17
|
import { type BlockHeader, type IndexedTxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
17
18
|
import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
|
|
18
19
|
import { EventEmitter } from 'events';
|
|
19
20
|
import type { ArchiverDataStore, ArchiverL1SynchPoint } from './archiver_store.js';
|
|
20
21
|
import type { ArchiverConfig } from './config.js';
|
|
21
22
|
import { ArchiverInstrumentation } from './instrumentation.js';
|
|
22
|
-
import type {
|
|
23
|
+
import type { InboxMessage } from './structs/inbox_message.js';
|
|
23
24
|
import type { PublishedL2Block } from './structs/published.js';
|
|
24
25
|
/**
|
|
25
26
|
* Helper interface to combine all sources this archiver implementation provides.
|
|
@@ -67,7 +68,9 @@ export declare class Archiver extends EventEmitter implements ArchiveSource, Tra
|
|
|
67
68
|
}, dataStore: ArchiverDataStore, config: {
|
|
68
69
|
pollingIntervalMs: number;
|
|
69
70
|
batchSize: number;
|
|
70
|
-
}, blobSinkClient: BlobSinkClientInterface, instrumentation: ArchiverInstrumentation, l1constants: L1RollupConstants
|
|
71
|
+
}, blobSinkClient: BlobSinkClientInterface, instrumentation: ArchiverInstrumentation, l1constants: L1RollupConstants & {
|
|
72
|
+
l1StartBlockHash: Buffer32;
|
|
73
|
+
}, log?: Logger);
|
|
71
74
|
/**
|
|
72
75
|
* Creates a new instance of the Archiver and blocks until it syncs from chain.
|
|
73
76
|
* @param config - The archiver's desired configuration.
|
|
@@ -96,6 +99,9 @@ export declare class Archiver extends EventEmitter implements ArchiveSource, Tra
|
|
|
96
99
|
private handleEpochPrune;
|
|
97
100
|
private nextRange;
|
|
98
101
|
private handleL1ToL2Messages;
|
|
102
|
+
private retrieveL1ToL2Message;
|
|
103
|
+
private rollbackL1ToL2Messages;
|
|
104
|
+
private getL1BlockHash;
|
|
99
105
|
private handleL2blocks;
|
|
100
106
|
private checkForNewBlocksBeforeL1SyncPoint;
|
|
101
107
|
/** Resumes the archiver after a stop. */
|
|
@@ -190,6 +196,7 @@ export declare class Archiver extends EventEmitter implements ArchiveSource, Tra
|
|
|
190
196
|
registerContractFunctionSignatures(address: AztecAddress, signatures: string[]): Promise<void>;
|
|
191
197
|
getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined>;
|
|
192
198
|
getL2Tips(): Promise<L2Tips>;
|
|
199
|
+
rollbackTo(targetL2BlockNumber: number): Promise<void>;
|
|
193
200
|
}
|
|
194
201
|
/**
|
|
195
202
|
* A helper class that we use to deal with some of the logic needed when adding blocks.
|
|
@@ -197,17 +204,18 @@ export declare class Archiver extends EventEmitter implements ArchiveSource, Tra
|
|
|
197
204
|
* I would have preferred to not have this type. But it is useful for handling the logic that any
|
|
198
205
|
* store would need to include otherwise while exposing fewer functions and logic directly to the archiver.
|
|
199
206
|
*/
|
|
200
|
-
export declare class ArchiverStoreHelper implements Omit<ArchiverDataStore, 'addLogs' | 'deleteLogs' | 'addContractClasses' | 'deleteContractClasses' | 'addContractInstances' | 'deleteContractInstances' | 'addContractInstanceUpdates' | 'deleteContractInstanceUpdates' | 'addFunctions' | 'backupTo' | 'close'> {
|
|
207
|
+
export declare class ArchiverStoreHelper implements Omit<ArchiverDataStore, 'addLogs' | 'deleteLogs' | 'addContractClasses' | 'deleteContractClasses' | 'addContractInstances' | 'deleteContractInstances' | 'addContractInstanceUpdates' | 'deleteContractInstanceUpdates' | 'addFunctions' | 'backupTo' | 'close' | 'transactionAsync'> {
|
|
201
208
|
#private;
|
|
202
209
|
protected readonly store: ArchiverDataStore;
|
|
203
210
|
constructor(store: ArchiverDataStore);
|
|
204
211
|
addBlocks(blocks: PublishedL2Block[]): Promise<boolean>;
|
|
205
212
|
unwindBlocks(from: number, blocksToUnwind: number): Promise<boolean>;
|
|
206
213
|
getPublishedBlocks(from: number, limit: number): Promise<PublishedL2Block[]>;
|
|
214
|
+
getPublishedBlock(number: number): Promise<PublishedL2Block | undefined>;
|
|
207
215
|
getBlockHeaders(from: number, limit: number): Promise<BlockHeader[]>;
|
|
208
216
|
getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined>;
|
|
209
217
|
getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined>;
|
|
210
|
-
addL1ToL2Messages(messages:
|
|
218
|
+
addL1ToL2Messages(messages: InboxMessage[]): Promise<void>;
|
|
211
219
|
getL1ToL2Messages(blockNumber: bigint): Promise<Fr[]>;
|
|
212
220
|
getL1ToL2MessageIndex(l1ToL2Message: Fr): Promise<bigint | undefined>;
|
|
213
221
|
getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]>;
|
|
@@ -218,7 +226,7 @@ export declare class ArchiverStoreHelper implements Omit<ArchiverDataStore, 'add
|
|
|
218
226
|
getProvenL2BlockNumber(): Promise<number>;
|
|
219
227
|
setProvenL2BlockNumber(l2BlockNumber: number): Promise<void>;
|
|
220
228
|
setBlockSynchedL1BlockNumber(l1BlockNumber: bigint): Promise<void>;
|
|
221
|
-
|
|
229
|
+
setMessageSynchedL1Block(l1Block: L1BlockId): Promise<void>;
|
|
222
230
|
getSynchPoint(): Promise<ArchiverL1SynchPoint>;
|
|
223
231
|
getContractClass(id: Fr): Promise<ContractClassPublic | undefined>;
|
|
224
232
|
getBytecodeCommitment(contractClassId: Fr): Promise<Fr | undefined>;
|
|
@@ -233,5 +241,9 @@ export declare class ArchiverStoreHelper implements Omit<ArchiverDataStore, 'add
|
|
|
233
241
|
actualSize: number;
|
|
234
242
|
numItems: number;
|
|
235
243
|
}>;
|
|
244
|
+
rollbackL1ToL2MessagesToL2Block(targetBlockNumber: number | bigint): Promise<void>;
|
|
245
|
+
iterateL1ToL2Messages(range?: CustomRange<bigint>): AsyncIterableIterator<InboxMessage>;
|
|
246
|
+
removeL1ToL2Messages(startIndex: bigint): Promise<void>;
|
|
247
|
+
getLastL1ToL2Message(): Promise<InboxMessage | undefined>;
|
|
236
248
|
}
|
|
237
249
|
//# sourceMappingURL=archiver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archiver.d.ts","sourceRoot":"","sources":["../../src/archiver/archiver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"archiver.d.ts","sourceRoot":"","sources":["../../src/archiver/archiver.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,15 +4,15 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
4
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
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
}
|
|
7
|
-
import { BlockTagTooOldError, RollupContract, createEthereumChain } from '@aztec/ethereum';
|
|
7
|
+
import { BlockTagTooOldError, InboxContract, RollupContract, createEthereumChain } from '@aztec/ethereum';
|
|
8
8
|
import { maxBigint } from '@aztec/foundation/bigint';
|
|
9
|
+
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
|
|
9
10
|
import { Fr } from '@aztec/foundation/fields';
|
|
10
11
|
import { createLogger } from '@aztec/foundation/log';
|
|
11
12
|
import { RunningPromise, makeLoggingErrorHandler } from '@aztec/foundation/running-promise';
|
|
12
13
|
import { sleep } from '@aztec/foundation/sleep';
|
|
13
14
|
import { count } from '@aztec/foundation/string';
|
|
14
15
|
import { elapsed } from '@aztec/foundation/timer';
|
|
15
|
-
import { InboxAbi } from '@aztec/l1-artifacts';
|
|
16
16
|
import { ContractClassRegisteredEvent, PrivateFunctionBroadcastedEvent, UtilityFunctionBroadcastedEvent } from '@aztec/protocol-contracts/class-registerer';
|
|
17
17
|
import { ContractInstanceDeployedEvent, ContractInstanceUpdatedEvent } from '@aztec/protocol-contracts/instance-deployer';
|
|
18
18
|
import { L2BlockSourceEvents } from '@aztec/stdlib/block';
|
|
@@ -21,9 +21,9 @@ import { getEpochAtSlot, getEpochNumberAtTimestamp, getSlotAtTimestamp, getSlotR
|
|
|
21
21
|
import { Attributes, trackSpan } from '@aztec/telemetry-client';
|
|
22
22
|
import { EventEmitter } from 'events';
|
|
23
23
|
import groupBy from 'lodash.groupby';
|
|
24
|
-
import { createPublicClient, fallback,
|
|
25
|
-
import { retrieveBlocksFromRollup, retrieveL1ToL2Messages, retrievedBlockToPublishedL2Block } from './data_retrieval.js';
|
|
26
|
-
import { NoBlobBodiesFoundError } from './errors.js';
|
|
24
|
+
import { createPublicClient, fallback, http } from 'viem';
|
|
25
|
+
import { retrieveBlocksFromRollup, retrieveL1ToL2Message, retrieveL1ToL2Messages, retrievedBlockToPublishedL2Block } from './data_retrieval.js';
|
|
26
|
+
import { InitialBlockNumberNotSequentialError, NoBlobBodiesFoundError } from './errors.js';
|
|
27
27
|
import { ArchiverInstrumentation } from './instrumentation.js';
|
|
28
28
|
/**
|
|
29
29
|
* Pulls L2 blocks in a non-blocking manner and provides interface for their retrieval.
|
|
@@ -62,11 +62,7 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
62
62
|
this.tracer = instrumentation.tracer;
|
|
63
63
|
this.store = new ArchiverStoreHelper(dataStore);
|
|
64
64
|
this.rollup = new RollupContract(publicClient, l1Addresses.rollupAddress);
|
|
65
|
-
this.inbox =
|
|
66
|
-
address: l1Addresses.inboxAddress.toString(),
|
|
67
|
-
abi: InboxAbi,
|
|
68
|
-
client: publicClient
|
|
69
|
-
});
|
|
65
|
+
this.inbox = new InboxContract(publicClient, l1Addresses.inboxAddress);
|
|
70
66
|
}
|
|
71
67
|
/**
|
|
72
68
|
* Creates a new instance of the Archiver and blocks until it syncs from chain.
|
|
@@ -86,18 +82,25 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
86
82
|
rollup.getL1StartBlock(),
|
|
87
83
|
rollup.getL1GenesisTime()
|
|
88
84
|
]);
|
|
85
|
+
const l1StartBlockHash = await publicClient.getBlock({
|
|
86
|
+
blockNumber: l1StartBlock,
|
|
87
|
+
includeTransactions: false
|
|
88
|
+
}).then((block)=>Buffer32.fromString(block.hash));
|
|
89
89
|
const { aztecEpochDuration: epochDuration, aztecSlotDuration: slotDuration, ethereumSlotDuration, aztecProofSubmissionWindow: proofSubmissionWindow } = config;
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
batchSize: config.archiverBatchSize ?? 100
|
|
93
|
-
}, deps.blobSinkClient, await ArchiverInstrumentation.new(deps.telemetry, ()=>archiverStore.estimateSize()), {
|
|
90
|
+
const l1Constants = {
|
|
91
|
+
l1StartBlockHash,
|
|
94
92
|
l1StartBlock,
|
|
95
93
|
l1GenesisTime,
|
|
96
94
|
epochDuration,
|
|
97
95
|
slotDuration,
|
|
98
96
|
ethereumSlotDuration,
|
|
99
97
|
proofSubmissionWindow
|
|
100
|
-
}
|
|
98
|
+
};
|
|
99
|
+
const opts = {
|
|
100
|
+
pollingIntervalMs: config.archiverPollingIntervalMS ?? 10_000,
|
|
101
|
+
batchSize: config.archiverBatchSize ?? 100
|
|
102
|
+
};
|
|
103
|
+
const archiver = new Archiver(publicClient, config.l1Contracts, archiverStore, opts, deps.blobSinkClient, await ArchiverInstrumentation.new(deps.telemetry, ()=>archiverStore.estimateSize()), l1Constants);
|
|
101
104
|
await archiver.start(blockUntilSynced);
|
|
102
105
|
return archiver;
|
|
103
106
|
}
|
|
@@ -155,11 +158,21 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
155
158
|
* The archiver will stay back, until there's data on L1 that will move the pointers forward.
|
|
156
159
|
*
|
|
157
160
|
* This code does not handle reorgs.
|
|
158
|
-
*/ const { l1StartBlock } = this.l1constants;
|
|
159
|
-
const { blocksSynchedTo = l1StartBlock, messagesSynchedTo =
|
|
160
|
-
|
|
161
|
+
*/ const { l1StartBlock, l1StartBlockHash } = this.l1constants;
|
|
162
|
+
const { blocksSynchedTo = l1StartBlock, messagesSynchedTo = {
|
|
163
|
+
l1BlockNumber: l1StartBlock,
|
|
164
|
+
l1BlockHash: l1StartBlockHash
|
|
165
|
+
} } = await this.store.getSynchPoint();
|
|
166
|
+
const currentL1Block = await this.publicClient.getBlock({
|
|
167
|
+
includeTransactions: false
|
|
168
|
+
});
|
|
169
|
+
const currentL1BlockNumber = currentL1Block.number;
|
|
170
|
+
const currentL1BlockHash = Buffer32.fromString(currentL1Block.hash);
|
|
161
171
|
if (initialRun) {
|
|
162
|
-
this.log.info(`Starting archiver sync to rollup contract ${this.l1Addresses.rollupAddress.toString()} from L1 block ${
|
|
172
|
+
this.log.info(`Starting archiver sync to rollup contract ${this.l1Addresses.rollupAddress.toString()} from L1 block ${blocksSynchedTo}` + ` to current L1 block ${currentL1BlockNumber} with hash ${currentL1BlockHash.toString()}`, {
|
|
173
|
+
blocksSynchedTo,
|
|
174
|
+
messagesSynchedTo
|
|
175
|
+
});
|
|
163
176
|
}
|
|
164
177
|
// ********** Ensuring Consistency of data pulled from L1 **********
|
|
165
178
|
/**
|
|
@@ -178,7 +191,7 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
178
191
|
* data up to the currentBlockNumber captured at the top of this function. We might want to improve on this
|
|
179
192
|
* in future but for the time being it should give us the guarantees that we need
|
|
180
193
|
*/ // ********** Events that are processed per L1 block **********
|
|
181
|
-
await this.handleL1ToL2Messages(messagesSynchedTo, currentL1BlockNumber);
|
|
194
|
+
await this.handleL1ToL2Messages(messagesSynchedTo, currentL1BlockNumber, currentL1BlockHash);
|
|
182
195
|
// Get L1 timestamp for the current block
|
|
183
196
|
const currentL1Timestamp = !this.l1Timestamp || !this.l1BlockNumber || this.l1BlockNumber !== currentL1BlockNumber ? (await this.publicClient.getBlock({
|
|
184
197
|
blockNumber: currentL1BlockNumber
|
|
@@ -276,34 +289,140 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
276
289
|
nextEnd
|
|
277
290
|
];
|
|
278
291
|
}
|
|
279
|
-
async handleL1ToL2Messages(
|
|
280
|
-
this.log.trace(`Handling L1 to L2 messages from ${
|
|
281
|
-
if (currentL1BlockNumber <=
|
|
292
|
+
async handleL1ToL2Messages(messagesSyncPoint, currentL1BlockNumber, currentL1BlockHash) {
|
|
293
|
+
this.log.trace(`Handling L1 to L2 messages from ${messagesSyncPoint.l1BlockNumber} to ${currentL1BlockNumber}.`);
|
|
294
|
+
if (currentL1BlockNumber <= messagesSyncPoint.l1BlockNumber) {
|
|
282
295
|
return;
|
|
283
296
|
}
|
|
284
|
-
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
297
|
+
// Load remote and local inbox states.
|
|
298
|
+
const localMessagesInserted = await this.store.getTotalL1ToL2MessageCount();
|
|
299
|
+
const localLastMessage = await this.store.getLastL1ToL2Message();
|
|
300
|
+
const remoteMessagesState = await this.inbox.getState({
|
|
301
|
+
blockNumber: currentL1BlockNumber
|
|
302
|
+
});
|
|
303
|
+
this.log.trace(`Retrieved remote inbox state at L1 block ${currentL1BlockNumber}.`, {
|
|
304
|
+
localMessagesInserted,
|
|
305
|
+
localLastMessage,
|
|
306
|
+
remoteMessagesState
|
|
307
|
+
});
|
|
308
|
+
// Compare message count and rolling hash. If they match, no need to retrieve anything.
|
|
309
|
+
if (remoteMessagesState.totalMessagesInserted === localMessagesInserted && remoteMessagesState.messagesRollingHash.equals(localLastMessage?.rollingHash ?? Buffer16.ZERO)) {
|
|
310
|
+
this.log.debug(`No L1 to L2 messages to query between L1 blocks ${messagesSyncPoint.l1BlockNumber} and ${currentL1BlockNumber}.`);
|
|
311
|
+
await this.store.setMessageSynchedL1Block({
|
|
312
|
+
l1BlockHash: currentL1BlockHash,
|
|
313
|
+
l1BlockNumber: currentL1BlockNumber
|
|
314
|
+
});
|
|
289
315
|
return;
|
|
290
316
|
}
|
|
291
|
-
//
|
|
292
|
-
|
|
293
|
-
|
|
317
|
+
// Check if our syncpoint is still valid. If not, there was an L1 reorg and we need to re-retrieve messages.
|
|
318
|
+
// Note that we need to fetch it from logs and not from inbox state at the syncpoint l1 block number, since it
|
|
319
|
+
// could be older than 128 blocks and non-archive nodes cannot resolve it.
|
|
320
|
+
if (localLastMessage) {
|
|
321
|
+
const remoteLastMessage = await this.retrieveL1ToL2Message(localLastMessage.leaf);
|
|
322
|
+
this.log.trace(`Retrieved remote message for local last`, {
|
|
323
|
+
remoteLastMessage,
|
|
324
|
+
localLastMessage
|
|
325
|
+
});
|
|
326
|
+
if (!remoteLastMessage || !remoteLastMessage.rollingHash.equals(localLastMessage.rollingHash)) {
|
|
327
|
+
this.log.warn(`Rolling back L1 to L2 messages due to hash mismatch or msg not found.`, {
|
|
328
|
+
remoteLastMessage,
|
|
329
|
+
messagesSyncPoint,
|
|
330
|
+
localLastMessage
|
|
331
|
+
});
|
|
332
|
+
messagesSyncPoint = await this.rollbackL1ToL2Messages(localLastMessage, messagesSyncPoint);
|
|
333
|
+
this.log.debug(`Rolled back L1 to L2 messages to L1 block ${messagesSyncPoint.l1BlockNumber}.`, {
|
|
334
|
+
messagesSyncPoint
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Retrieve and save messages in batches. Each batch is estimated to acommodate up to L2 'blockBatchSize' blocks,
|
|
339
|
+
let searchStartBlock = 0n;
|
|
340
|
+
let searchEndBlock = messagesSyncPoint.l1BlockNumber;
|
|
341
|
+
let lastMessage;
|
|
342
|
+
let messageCount = 0;
|
|
294
343
|
do {
|
|
295
344
|
[searchStartBlock, searchEndBlock] = this.nextRange(searchEndBlock, currentL1BlockNumber);
|
|
296
345
|
this.log.trace(`Retrieving L1 to L2 messages between L1 blocks ${searchStartBlock} and ${searchEndBlock}.`);
|
|
297
|
-
const
|
|
298
|
-
this.log.verbose(`Retrieved ${
|
|
299
|
-
await this.store.addL1ToL2Messages(
|
|
300
|
-
for (const msg of
|
|
346
|
+
const messages = await retrieveL1ToL2Messages(this.inbox.getContract(), searchStartBlock, searchEndBlock);
|
|
347
|
+
this.log.verbose(`Retrieved ${messages.length} new L1 to L2 messages between L1 blocks ${searchStartBlock} and ${searchEndBlock}.`);
|
|
348
|
+
await this.store.addL1ToL2Messages(messages);
|
|
349
|
+
for (const msg of messages){
|
|
301
350
|
this.log.debug(`Downloaded L1 to L2 message`, {
|
|
302
|
-
|
|
303
|
-
|
|
351
|
+
...msg,
|
|
352
|
+
leaf: msg.leaf.toString()
|
|
304
353
|
});
|
|
354
|
+
lastMessage = msg;
|
|
355
|
+
messageCount++;
|
|
305
356
|
}
|
|
306
357
|
}while (searchEndBlock < currentL1BlockNumber)
|
|
358
|
+
// Log stats for messages retrieved (if any).
|
|
359
|
+
if (messageCount > 0) {
|
|
360
|
+
this.log.info(`Retrieved ${messageCount} new L1 to L2 messages up to message with index ${lastMessage?.index} for L2 block ${lastMessage?.l2BlockNumber}`, {
|
|
361
|
+
lastMessage,
|
|
362
|
+
messageCount
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
// Warn if the resulting rolling hash does not match the remote state we had retrieved.
|
|
366
|
+
if (lastMessage && !lastMessage.rollingHash.equals(remoteMessagesState.messagesRollingHash)) {
|
|
367
|
+
this.log.warn(`Last message retrieved rolling hash does not match remote state.`, {
|
|
368
|
+
lastMessage,
|
|
369
|
+
remoteMessagesState
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
retrieveL1ToL2Message(leaf) {
|
|
374
|
+
return retrieveL1ToL2Message(this.inbox.getContract(), leaf, this.l1constants.l1StartBlock);
|
|
375
|
+
}
|
|
376
|
+
async rollbackL1ToL2Messages(localLastMessage, messagesSyncPoint) {
|
|
377
|
+
// Slowly go back through our messages until we find the last common message.
|
|
378
|
+
// We could query the logs in batch as an optimization, but the depth of the reorg should not be deep, and this
|
|
379
|
+
// is a very rare case, so it's fine to query one log at a time.
|
|
380
|
+
let commonMsg;
|
|
381
|
+
this.log.verbose(`Searching most recent common L1 to L2 message at or before index ${localLastMessage.index}`);
|
|
382
|
+
for await (const msg of this.store.iterateL1ToL2Messages({
|
|
383
|
+
reverse: true,
|
|
384
|
+
end: localLastMessage.index
|
|
385
|
+
})){
|
|
386
|
+
const remoteMsg = await this.retrieveL1ToL2Message(msg.leaf);
|
|
387
|
+
const logCtx = {
|
|
388
|
+
remoteMsg,
|
|
389
|
+
localMsg: msg
|
|
390
|
+
};
|
|
391
|
+
if (remoteMsg && remoteMsg.rollingHash.equals(msg.rollingHash)) {
|
|
392
|
+
this.log.verbose(`Found most recent common L1 to L2 message at index ${msg.index} on L1 block ${msg.l1BlockNumber}`, logCtx);
|
|
393
|
+
commonMsg = remoteMsg;
|
|
394
|
+
break;
|
|
395
|
+
} else if (remoteMsg) {
|
|
396
|
+
this.log.debug(`Local L1 to L2 message with index ${msg.index} has different rolling hash`, logCtx);
|
|
397
|
+
} else {
|
|
398
|
+
this.log.debug(`Local L1 to L2 message with index ${msg.index} not found on L1`, logCtx);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
// Delete everything after the common message we found.
|
|
402
|
+
const lastGoodIndex = commonMsg?.index;
|
|
403
|
+
this.log.warn(`Deleting all local L1 to L2 messages after index ${lastGoodIndex ?? 'undefined'}`);
|
|
404
|
+
await this.store.removeL1ToL2Messages(lastGoodIndex !== undefined ? lastGoodIndex + 1n : 0n);
|
|
405
|
+
// Update the syncpoint so the loop below reprocesses the changed messages. We go to the block before
|
|
406
|
+
// the last common one, so we force reprocessing it, in case new messages were added on that same L1 block
|
|
407
|
+
// after the last common message.
|
|
408
|
+
const syncPointL1BlockNumber = commonMsg ? commonMsg.l1BlockNumber - 1n : this.l1constants.l1StartBlock;
|
|
409
|
+
const syncPointL1BlockHash = await this.getL1BlockHash(syncPointL1BlockNumber);
|
|
410
|
+
messagesSyncPoint = {
|
|
411
|
+
l1BlockNumber: syncPointL1BlockNumber,
|
|
412
|
+
l1BlockHash: syncPointL1BlockHash
|
|
413
|
+
};
|
|
414
|
+
await this.store.setMessageSynchedL1Block(messagesSyncPoint);
|
|
415
|
+
return messagesSyncPoint;
|
|
416
|
+
}
|
|
417
|
+
async getL1BlockHash(l1BlockNumber) {
|
|
418
|
+
const block = await this.publicClient.getBlock({
|
|
419
|
+
blockNumber: l1BlockNumber,
|
|
420
|
+
includeTransactions: false
|
|
421
|
+
});
|
|
422
|
+
if (!block) {
|
|
423
|
+
throw new Error(`Missing L1 block ${l1BlockNumber}`);
|
|
424
|
+
}
|
|
425
|
+
return Buffer32.fromString(block.hash);
|
|
307
426
|
}
|
|
308
427
|
async handleL2blocks(blocksSynchedTo, currentL1BlockNumber) {
|
|
309
428
|
const localPendingBlockNumber = BigInt(await this.getBlockNumber());
|
|
@@ -437,14 +556,32 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
437
556
|
...block.block.getStats()
|
|
438
557
|
});
|
|
439
558
|
}
|
|
440
|
-
|
|
441
|
-
|
|
559
|
+
try {
|
|
560
|
+
const [processDuration] = await elapsed(()=>this.store.addBlocks(publishedBlocks));
|
|
561
|
+
this.instrumentation.processNewBlocks(processDuration / publishedBlocks.length, publishedBlocks.map((b)=>b.block));
|
|
562
|
+
} catch (err) {
|
|
563
|
+
if (err instanceof InitialBlockNumberNotSequentialError) {
|
|
564
|
+
const { previousBlockNumber, newBlockNumber } = err;
|
|
565
|
+
const previousBlock = previousBlockNumber ? await this.store.getPublishedBlock(previousBlockNumber) : undefined;
|
|
566
|
+
const updatedL1SyncPoint = previousBlock?.l1.blockNumber ?? this.l1constants.l1StartBlock;
|
|
567
|
+
await this.store.setBlockSynchedL1BlockNumber(updatedL1SyncPoint);
|
|
568
|
+
this.log.warn(`Attempting to insert block ${newBlockNumber} with previous block ${previousBlockNumber}. Rolling back L1 sync point to ${updatedL1SyncPoint} to try and fetch the missing blocks.`, {
|
|
569
|
+
previousBlockNumber,
|
|
570
|
+
previousBlockHash: await previousBlock?.block.hash(),
|
|
571
|
+
newBlockNumber,
|
|
572
|
+
updatedL1SyncPoint
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
throw err;
|
|
576
|
+
}
|
|
442
577
|
for (const block of publishedBlocks){
|
|
443
578
|
this.log.info(`Downloaded L2 block ${block.block.number}`, {
|
|
444
579
|
blockHash: await block.block.hash(),
|
|
445
580
|
blockNumber: block.block.number,
|
|
446
581
|
txCount: block.block.body.txEffects.length,
|
|
447
|
-
globalVariables: block.block.header.globalVariables.toInspect()
|
|
582
|
+
globalVariables: block.block.header.globalVariables.toInspect(),
|
|
583
|
+
archiveRoot: block.block.archive.root.toString(),
|
|
584
|
+
archiveNextLeafIndex: block.block.archive.nextAvailableLeafIndex
|
|
448
585
|
});
|
|
449
586
|
}
|
|
450
587
|
lastRetrievedBlock = publishedBlocks.at(-1) ?? lastRetrievedBlock;
|
|
@@ -616,11 +753,11 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
616
753
|
if (number < 0) {
|
|
617
754
|
number = await this.store.getSynchedL2BlockNumber();
|
|
618
755
|
}
|
|
619
|
-
if (number
|
|
756
|
+
if (number === 0) {
|
|
620
757
|
return undefined;
|
|
621
758
|
}
|
|
622
|
-
const
|
|
623
|
-
return
|
|
759
|
+
const publishedBlock = await this.store.getPublishedBlock(number);
|
|
760
|
+
return publishedBlock?.block;
|
|
624
761
|
}
|
|
625
762
|
async getBlockHeader(number) {
|
|
626
763
|
if (number === 'latest') {
|
|
@@ -752,6 +889,41 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
752
889
|
}
|
|
753
890
|
};
|
|
754
891
|
}
|
|
892
|
+
async rollbackTo(targetL2BlockNumber) {
|
|
893
|
+
const currentBlocks = await this.getL2Tips();
|
|
894
|
+
const currentL2Block = currentBlocks.latest.number;
|
|
895
|
+
const currentProvenBlock = currentBlocks.proven.number;
|
|
896
|
+
// const currentFinalizedBlock = currentBlocks.finalized.number;
|
|
897
|
+
if (targetL2BlockNumber >= currentL2Block) {
|
|
898
|
+
throw new Error(`Target L2 block ${targetL2BlockNumber} must be less than current L2 block ${currentL2Block}`);
|
|
899
|
+
}
|
|
900
|
+
const blocksToUnwind = currentL2Block - targetL2BlockNumber;
|
|
901
|
+
const targetL2Block = await this.store.getPublishedBlock(targetL2BlockNumber);
|
|
902
|
+
if (!targetL2Block) {
|
|
903
|
+
throw new Error(`Target L2 block ${targetL2BlockNumber} not found`);
|
|
904
|
+
}
|
|
905
|
+
const targetL1BlockNumber = targetL2Block.l1.blockNumber;
|
|
906
|
+
const targetL1BlockHash = await this.getL1BlockHash(targetL1BlockNumber);
|
|
907
|
+
this.log.info(`Unwinding ${blocksToUnwind} blocks from L2 block ${currentL2Block}`);
|
|
908
|
+
await this.store.unwindBlocks(currentL2Block, blocksToUnwind);
|
|
909
|
+
this.log.info(`Unwinding L1 to L2 messages to ${targetL2BlockNumber}`);
|
|
910
|
+
await this.store.rollbackL1ToL2MessagesToL2Block(targetL2BlockNumber);
|
|
911
|
+
this.log.info(`Setting L1 syncpoints to ${targetL1BlockNumber}`);
|
|
912
|
+
await this.store.setBlockSynchedL1BlockNumber(targetL1BlockNumber);
|
|
913
|
+
await this.store.setMessageSynchedL1Block({
|
|
914
|
+
l1BlockNumber: targetL1BlockNumber,
|
|
915
|
+
l1BlockHash: targetL1BlockHash
|
|
916
|
+
});
|
|
917
|
+
if (targetL2BlockNumber < currentProvenBlock) {
|
|
918
|
+
this.log.info(`Clearing proven L2 block number`);
|
|
919
|
+
await this.store.setProvenL2BlockNumber(0);
|
|
920
|
+
}
|
|
921
|
+
// TODO(palla/reorg): Set the finalized block when we add support for it.
|
|
922
|
+
// if (targetL2BlockNumber < currentFinalizedBlock) {
|
|
923
|
+
// this.log.info(`Clearing finalized L2 block number`);
|
|
924
|
+
// await this.store.setFinalizedL2BlockNumber(0);
|
|
925
|
+
// }
|
|
926
|
+
}
|
|
755
927
|
}
|
|
756
928
|
_ts_decorate([
|
|
757
929
|
trackSpan('Archiver.sync', (initialRun)=>({
|
|
@@ -873,30 +1045,37 @@ var Operation = /*#__PURE__*/ function(Operation) {
|
|
|
873
1045
|
}
|
|
874
1046
|
return true;
|
|
875
1047
|
}
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
1048
|
+
addBlocks(blocks) {
|
|
1049
|
+
// Add the blocks to the store. Store will throw if the blocks are not in order, there are gaps,
|
|
1050
|
+
// or if the previous block is not in the store.
|
|
1051
|
+
return this.store.transactionAsync(async ()=>{
|
|
1052
|
+
await this.store.addBlocks(blocks);
|
|
1053
|
+
const opResults = await Promise.all([
|
|
1054
|
+
this.store.addLogs(blocks.map((block)=>block.block)),
|
|
1055
|
+
// Unroll all logs emitted during the retrieved blocks and extract any contract classes and instances from them
|
|
1056
|
+
...blocks.map(async (block)=>{
|
|
1057
|
+
const contractClassLogs = block.block.body.txEffects.flatMap((txEffect)=>txEffect.contractClassLogs);
|
|
1058
|
+
// ContractInstanceDeployed event logs are broadcast in privateLogs.
|
|
1059
|
+
const privateLogs = block.block.body.txEffects.flatMap((txEffect)=>txEffect.privateLogs);
|
|
1060
|
+
const publicLogs = block.block.body.txEffects.flatMap((txEffect)=>txEffect.publicLogs);
|
|
1061
|
+
return (await Promise.all([
|
|
1062
|
+
this.#updateRegisteredContractClasses(contractClassLogs, block.block.number, 0),
|
|
1063
|
+
this.#updateDeployedContractInstances(privateLogs, block.block.number, 0),
|
|
1064
|
+
this.#updateUpdatedContractInstances(publicLogs, block.block.number, 0),
|
|
1065
|
+
this.#storeBroadcastedIndividualFunctions(contractClassLogs, block.block.number)
|
|
1066
|
+
])).every(Boolean);
|
|
1067
|
+
})
|
|
1068
|
+
]);
|
|
1069
|
+
return opResults.every(Boolean);
|
|
1070
|
+
});
|
|
895
1071
|
}
|
|
896
1072
|
async unwindBlocks(from, blocksToUnwind) {
|
|
897
1073
|
const last = await this.getSynchedL2BlockNumber();
|
|
898
1074
|
if (from != last) {
|
|
899
|
-
throw new Error(`
|
|
1075
|
+
throw new Error(`Cannot unwind blocks from block ${from} when the last block is ${last}`);
|
|
1076
|
+
}
|
|
1077
|
+
if (blocksToUnwind <= 0) {
|
|
1078
|
+
throw new Error(`Cannot unwind ${blocksToUnwind} blocks`);
|
|
900
1079
|
}
|
|
901
1080
|
// from - blocksToUnwind = the new head, so + 1 for what we need to remove
|
|
902
1081
|
const blocks = await this.getPublishedBlocks(from - blocksToUnwind + 1, blocksToUnwind);
|
|
@@ -921,6 +1100,9 @@ var Operation = /*#__PURE__*/ function(Operation) {
|
|
|
921
1100
|
getPublishedBlocks(from, limit) {
|
|
922
1101
|
return this.store.getPublishedBlocks(from, limit);
|
|
923
1102
|
}
|
|
1103
|
+
getPublishedBlock(number) {
|
|
1104
|
+
return this.store.getPublishedBlock(number);
|
|
1105
|
+
}
|
|
924
1106
|
getBlockHeaders(from, limit) {
|
|
925
1107
|
return this.store.getBlockHeaders(from, limit);
|
|
926
1108
|
}
|
|
@@ -963,8 +1145,8 @@ var Operation = /*#__PURE__*/ function(Operation) {
|
|
|
963
1145
|
setBlockSynchedL1BlockNumber(l1BlockNumber) {
|
|
964
1146
|
return this.store.setBlockSynchedL1BlockNumber(l1BlockNumber);
|
|
965
1147
|
}
|
|
966
|
-
|
|
967
|
-
return this.store.
|
|
1148
|
+
setMessageSynchedL1Block(l1Block) {
|
|
1149
|
+
return this.store.setMessageSynchedL1Block(l1Block);
|
|
968
1150
|
}
|
|
969
1151
|
getSynchPoint() {
|
|
970
1152
|
return this.store.getSynchPoint();
|
|
@@ -993,4 +1175,16 @@ var Operation = /*#__PURE__*/ function(Operation) {
|
|
|
993
1175
|
estimateSize() {
|
|
994
1176
|
return this.store.estimateSize();
|
|
995
1177
|
}
|
|
1178
|
+
rollbackL1ToL2MessagesToL2Block(targetBlockNumber) {
|
|
1179
|
+
return this.store.rollbackL1ToL2MessagesToL2Block(targetBlockNumber);
|
|
1180
|
+
}
|
|
1181
|
+
iterateL1ToL2Messages(range = {}) {
|
|
1182
|
+
return this.store.iterateL1ToL2Messages(range);
|
|
1183
|
+
}
|
|
1184
|
+
removeL1ToL2Messages(startIndex) {
|
|
1185
|
+
return this.store.removeL1ToL2Messages(startIndex);
|
|
1186
|
+
}
|
|
1187
|
+
getLastL1ToL2Message() {
|
|
1188
|
+
return this.store.getLastL1ToL2Message();
|
|
1189
|
+
}
|
|
996
1190
|
}
|