@aztec/archiver 0.0.1-commit.5daedc8 → 0.0.1-commit.6201a7b05
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 +162 -22
- package/dest/archiver.d.ts +147 -0
- package/dest/archiver.d.ts.map +1 -0
- package/dest/archiver.js +788 -0
- package/dest/config.d.ts +32 -0
- package/dest/config.d.ts.map +1 -0
- package/dest/config.js +83 -0
- package/dest/errors.d.ts +92 -0
- package/dest/errors.d.ts.map +1 -0
- package/dest/errors.js +136 -0
- package/dest/factory.d.ts +8 -7
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +100 -15
- package/dest/index.d.ts +12 -4
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +10 -3
- package/dest/interfaces.d.ts +9 -0
- package/dest/interfaces.d.ts.map +1 -0
- package/dest/interfaces.js +3 -0
- package/dest/l1/bin/retrieve-calldata.d.ts +3 -0
- package/dest/l1/bin/retrieve-calldata.d.ts.map +1 -0
- package/dest/l1/bin/retrieve-calldata.js +152 -0
- package/dest/l1/calldata_retriever.d.ts +136 -0
- package/dest/l1/calldata_retriever.d.ts.map +1 -0
- package/dest/l1/calldata_retriever.js +408 -0
- package/dest/l1/data_retrieval.d.ts +97 -0
- package/dest/l1/data_retrieval.d.ts.map +1 -0
- package/dest/{archiver → l1}/data_retrieval.js +86 -165
- package/dest/l1/debug_tx.d.ts +19 -0
- package/dest/l1/debug_tx.d.ts.map +1 -0
- package/dest/l1/debug_tx.js +73 -0
- package/dest/l1/spire_proposer.d.ts +70 -0
- package/dest/l1/spire_proposer.d.ts.map +1 -0
- package/dest/l1/spire_proposer.js +149 -0
- package/dest/l1/trace_tx.d.ts +97 -0
- package/dest/l1/trace_tx.d.ts.map +1 -0
- package/dest/l1/trace_tx.js +91 -0
- package/dest/l1/types.d.ts +12 -0
- package/dest/l1/types.d.ts.map +1 -0
- package/dest/l1/types.js +3 -0
- package/dest/l1/validate_historical_logs.d.ts +23 -0
- package/dest/l1/validate_historical_logs.d.ts.map +1 -0
- package/dest/l1/validate_historical_logs.js +108 -0
- package/dest/l1/validate_trace.d.ts +32 -0
- package/dest/l1/validate_trace.d.ts.map +1 -0
- package/dest/l1/validate_trace.js +154 -0
- package/dest/modules/data_source_base.d.ts +95 -0
- package/dest/modules/data_source_base.d.ts.map +1 -0
- package/dest/modules/data_source_base.js +234 -0
- package/dest/modules/data_store_updater.d.ts +93 -0
- package/dest/modules/data_store_updater.d.ts.map +1 -0
- package/dest/modules/data_store_updater.js +345 -0
- package/dest/modules/instrumentation.d.ts +55 -0
- package/dest/modules/instrumentation.d.ts.map +1 -0
- package/dest/modules/instrumentation.js +143 -0
- package/dest/modules/l1_synchronizer.d.ts +77 -0
- package/dest/modules/l1_synchronizer.d.ts.map +1 -0
- package/dest/modules/l1_synchronizer.js +1265 -0
- package/dest/modules/validation.d.ts +18 -0
- package/dest/modules/validation.d.ts.map +1 -0
- package/dest/{archiver → modules}/validation.js +13 -7
- package/dest/store/block_store.d.ts +262 -0
- package/dest/store/block_store.d.ts.map +1 -0
- package/dest/store/block_store.js +1048 -0
- package/dest/store/contract_class_store.d.ts +17 -0
- package/dest/store/contract_class_store.d.ts.map +1 -0
- package/dest/store/contract_class_store.js +64 -0
- package/dest/store/contract_instance_store.d.ts +24 -0
- package/dest/store/contract_instance_store.d.ts.map +1 -0
- package/dest/{archiver/kv_archiver_store → store}/contract_instance_store.js +7 -3
- package/dest/store/kv_archiver_store.d.ts +401 -0
- package/dest/store/kv_archiver_store.d.ts.map +1 -0
- package/dest/store/kv_archiver_store.js +525 -0
- package/dest/store/l2_tips_cache.d.ts +20 -0
- package/dest/store/l2_tips_cache.d.ts.map +1 -0
- package/dest/store/l2_tips_cache.js +109 -0
- package/dest/store/log_store.d.ts +57 -0
- package/dest/store/log_store.d.ts.map +1 -0
- package/dest/store/log_store.js +531 -0
- package/dest/store/message_store.d.ts +44 -0
- package/dest/store/message_store.d.ts.map +1 -0
- package/dest/{archiver/kv_archiver_store → store}/message_store.js +36 -23
- package/dest/{archiver/structs → structs}/data_retrieval.d.ts +1 -1
- package/dest/structs/data_retrieval.d.ts.map +1 -0
- package/dest/structs/inbox_message.d.ts +15 -0
- package/dest/structs/inbox_message.d.ts.map +1 -0
- package/dest/{archiver/structs → structs}/inbox_message.js +6 -5
- package/dest/structs/published.d.ts +2 -0
- package/dest/structs/published.d.ts.map +1 -0
- package/dest/test/fake_l1_state.d.ts +214 -0
- package/dest/test/fake_l1_state.d.ts.map +1 -0
- package/dest/test/fake_l1_state.js +517 -0
- package/dest/test/index.d.ts +2 -1
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +4 -1
- package/dest/test/mock_archiver.d.ts +16 -8
- package/dest/test/mock_archiver.d.ts.map +1 -1
- package/dest/test/mock_archiver.js +19 -14
- package/dest/test/mock_l1_to_l2_message_source.d.ts +7 -6
- package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
- package/dest/test/mock_l1_to_l2_message_source.js +23 -12
- package/dest/test/mock_l2_block_source.d.ts +68 -20
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +298 -85
- package/dest/test/mock_structs.d.ts +83 -4
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +157 -11
- package/dest/test/noop_l1_archiver.d.ts +26 -0
- package/dest/test/noop_l1_archiver.d.ts.map +1 -0
- package/dest/test/noop_l1_archiver.js +74 -0
- package/package.json +20 -20
- package/src/archiver.ts +566 -0
- package/src/{archiver/config.ts → config.ts} +51 -14
- package/src/errors.ts +213 -0
- package/src/factory.ts +155 -17
- package/src/index.ts +12 -3
- package/src/interfaces.ts +9 -0
- package/src/l1/README.md +55 -0
- package/src/l1/bin/retrieve-calldata.ts +194 -0
- package/src/l1/calldata_retriever.ts +523 -0
- package/src/{archiver → l1}/data_retrieval.ts +155 -247
- package/src/l1/debug_tx.ts +99 -0
- package/src/l1/spire_proposer.ts +152 -0
- package/src/l1/trace_tx.ts +128 -0
- package/src/l1/types.ts +13 -0
- package/src/l1/validate_historical_logs.ts +140 -0
- package/src/l1/validate_trace.ts +229 -0
- package/src/modules/data_source_base.ts +364 -0
- package/src/modules/data_store_updater.ts +465 -0
- package/src/modules/instrumentation.ts +204 -0
- package/src/modules/l1_synchronizer.ts +1126 -0
- package/src/{archiver → modules}/validation.ts +21 -15
- package/src/store/block_store.ts +1361 -0
- package/src/store/contract_class_store.ts +82 -0
- package/src/{archiver/kv_archiver_store → store}/contract_instance_store.ts +10 -7
- package/src/store/kv_archiver_store.ts +765 -0
- package/src/store/l2_tips_cache.ts +134 -0
- package/src/store/log_store.ts +733 -0
- package/src/{archiver/kv_archiver_store → store}/message_store.ts +48 -28
- package/src/{archiver/structs → structs}/inbox_message.ts +7 -7
- package/src/{archiver/structs → structs}/published.ts +0 -1
- package/src/test/fake_l1_state.ts +770 -0
- package/src/test/fixtures/debug_traceTransaction-multicall3.json +88 -0
- package/src/test/fixtures/debug_traceTransaction-multiplePropose.json +153 -0
- package/src/test/fixtures/debug_traceTransaction-proxied.json +122 -0
- package/src/test/fixtures/trace_transaction-multicall3.json +65 -0
- package/src/test/fixtures/trace_transaction-multiplePropose.json +319 -0
- package/src/test/fixtures/trace_transaction-proxied.json +128 -0
- package/src/test/fixtures/trace_transaction-randomRevert.json +216 -0
- package/src/test/index.ts +4 -0
- package/src/test/mock_archiver.ts +23 -16
- package/src/test/mock_l1_to_l2_message_source.ts +19 -11
- package/src/test/mock_l2_block_source.ts +367 -93
- package/src/test/mock_structs.ts +289 -13
- package/src/test/noop_l1_archiver.ts +117 -0
- package/dest/archiver/archiver.d.ts +0 -287
- package/dest/archiver/archiver.d.ts.map +0 -1
- package/dest/archiver/archiver.js +0 -1408
- package/dest/archiver/archiver_store.d.ts +0 -255
- 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 -1289
- package/dest/archiver/config.d.ts +0 -21
- package/dest/archiver/config.d.ts.map +0 -1
- package/dest/archiver/config.js +0 -55
- package/dest/archiver/data_retrieval.d.ts +0 -79
- package/dest/archiver/data_retrieval.d.ts.map +0 -1
- package/dest/archiver/errors.d.ts +0 -12
- package/dest/archiver/errors.d.ts.map +0 -1
- package/dest/archiver/errors.js +0 -17
- package/dest/archiver/index.d.ts +0 -7
- package/dest/archiver/index.d.ts.map +0 -1
- package/dest/archiver/index.js +0 -4
- package/dest/archiver/instrumentation.d.ts +0 -35
- package/dest/archiver/instrumentation.d.ts.map +0 -1
- package/dest/archiver/instrumentation.js +0 -140
- package/dest/archiver/kv_archiver_store/block_store.d.ts +0 -124
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/block_store.js +0 -370
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +0 -18
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +0 -120
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +0 -24
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +0 -168
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +0 -296
- package/dest/archiver/kv_archiver_store/log_store.d.ts +0 -49
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/log_store.js +0 -336
- package/dest/archiver/kv_archiver_store/message_store.d.ts +0 -39
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +0 -1
- package/dest/archiver/structs/data_retrieval.d.ts.map +0 -1
- package/dest/archiver/structs/inbox_message.d.ts +0 -15
- package/dest/archiver/structs/inbox_message.d.ts.map +0 -1
- package/dest/archiver/structs/published.d.ts +0 -3
- package/dest/archiver/structs/published.d.ts.map +0 -1
- package/dest/archiver/validation.d.ts +0 -17
- package/dest/archiver/validation.d.ts.map +0 -1
- package/dest/rpc/index.d.ts +0 -9
- package/dest/rpc/index.d.ts.map +0 -1
- package/dest/rpc/index.js +0 -15
- package/src/archiver/archiver.ts +0 -1858
- package/src/archiver/archiver_store.ts +0 -305
- package/src/archiver/archiver_store_test_suite.ts +0 -1264
- package/src/archiver/errors.ts +0 -26
- package/src/archiver/index.ts +0 -6
- package/src/archiver/instrumentation.ts +0 -187
- package/src/archiver/kv_archiver_store/block_store.ts +0 -481
- package/src/archiver/kv_archiver_store/contract_class_store.ts +0 -176
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +0 -422
- package/src/archiver/kv_archiver_store/log_store.ts +0 -406
- package/src/rpc/index.ts +0 -16
- /package/dest/{archiver/structs → structs}/data_retrieval.js +0 -0
- /package/dest/{archiver/structs → structs}/published.js +0 -0
- /package/src/{archiver/structs → structs}/data_retrieval.ts +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BlobClientInterface } from '@aztec/blob-client/client';
|
|
1
2
|
import {
|
|
2
3
|
BlobDeserializationError,
|
|
3
4
|
type CheckpointBlobData,
|
|
@@ -5,57 +6,61 @@ import {
|
|
|
5
6
|
decodeCheckpointBlobDataFromBlobs,
|
|
6
7
|
encodeBlockBlobData,
|
|
7
8
|
} from '@aztec/blob-lib';
|
|
8
|
-
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
9
9
|
import type {
|
|
10
|
+
CheckpointProposedLog,
|
|
10
11
|
EpochProofPublicInputArgs,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from '@aztec/ethereum';
|
|
12
|
+
InboxContract,
|
|
13
|
+
MessageSentLog,
|
|
14
|
+
RollupContract,
|
|
15
|
+
} from '@aztec/ethereum/contracts';
|
|
16
|
+
import type { ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
|
|
16
17
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
18
|
+
import { CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
|
|
19
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
20
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
21
21
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
22
|
-
import {
|
|
23
|
-
import { Body, CommitteeAttestation,
|
|
24
|
-
import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
22
|
+
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
23
|
+
import { Body, CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
|
|
24
|
+
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
25
25
|
import { Proof } from '@aztec/stdlib/proofs';
|
|
26
26
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
27
27
|
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
28
28
|
import { BlockHeader, GlobalVariables, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
|
|
29
29
|
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
import { NoBlobBodiesFoundError } from './errors.js';
|
|
41
|
-
import type { DataRetrieval } from './structs/data_retrieval.js';
|
|
42
|
-
import type { InboxMessage } from './structs/inbox_message.js';
|
|
43
|
-
import type { L1PublishedData } from './structs/published.js';
|
|
44
|
-
|
|
45
|
-
export type RetrievedCheckpoint = {
|
|
46
|
-
checkpointNumber: number;
|
|
30
|
+
import { type Hex, decodeFunctionData, getAbiItem, hexToBytes } from 'viem';
|
|
31
|
+
|
|
32
|
+
import { NoBlobBodiesFoundError } from '../errors.js';
|
|
33
|
+
import type { ArchiverInstrumentation } from '../modules/instrumentation.js';
|
|
34
|
+
import type { DataRetrieval } from '../structs/data_retrieval.js';
|
|
35
|
+
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
36
|
+
import { CalldataRetriever } from './calldata_retriever.js';
|
|
37
|
+
|
|
38
|
+
type RetrievedCheckpointBase = {
|
|
39
|
+
checkpointNumber: CheckpointNumber;
|
|
47
40
|
archiveRoot: Fr;
|
|
41
|
+
feeAssetPriceModifier: bigint;
|
|
48
42
|
header: CheckpointHeader;
|
|
49
|
-
checkpointBlobData: CheckpointBlobData;
|
|
50
43
|
l1: L1PublishedData;
|
|
51
44
|
chainId: Fr;
|
|
52
45
|
version: Fr;
|
|
53
46
|
attestations: CommitteeAttestation[];
|
|
54
47
|
};
|
|
55
48
|
|
|
49
|
+
/** Checkpoint data as retrieved from L1 calldata and blob data. */
|
|
50
|
+
export type RetrievedCheckpoint = RetrievedCheckpointBase & { checkpointBlobData: CheckpointBlobData };
|
|
51
|
+
|
|
52
|
+
/** Checkpoint data retrieved from L1 calldata only, without blob data. */
|
|
53
|
+
export type RetrievedCheckpointFromCalldata = RetrievedCheckpointBase & {
|
|
54
|
+
/** Versioned blob hashes from the checkpoint proposed event. */
|
|
55
|
+
blobHashes: Buffer[];
|
|
56
|
+
/** Parent beacon block root from the L1 block, used for blob fetching. */
|
|
57
|
+
parentBeaconBlockRoot: string | undefined;
|
|
58
|
+
};
|
|
59
|
+
|
|
56
60
|
export async function retrievedToPublishedCheckpoint({
|
|
57
61
|
checkpointNumber,
|
|
58
62
|
archiveRoot,
|
|
63
|
+
feeAssetPriceModifier,
|
|
59
64
|
header: checkpointHeader,
|
|
60
65
|
checkpointBlobData,
|
|
61
66
|
l1,
|
|
@@ -71,12 +76,12 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
71
76
|
.slice(1)
|
|
72
77
|
.concat([archiveRoot]);
|
|
73
78
|
|
|
74
|
-
//
|
|
75
|
-
//
|
|
79
|
+
// An error will be thrown from `decodeCheckpointBlobDataFromBlobs` if it can't read a field for the
|
|
80
|
+
// `l1ToL2MessageRoot` of the first block. So below we can safely assume it exists:
|
|
76
81
|
const l1toL2MessageTreeRoot = blocksBlobData[0].l1ToL2MessageRoot!;
|
|
77
82
|
|
|
78
83
|
const spongeBlob = SpongeBlob.init();
|
|
79
|
-
const l2Blocks:
|
|
84
|
+
const l2Blocks: L2Block[] = [];
|
|
80
85
|
for (let i = 0; i < blocksBlobData.length; i++) {
|
|
81
86
|
const blockBlobData = blocksBlobData[i];
|
|
82
87
|
const { blockEndMarker, blockEndStateField, lastArchiveRoot, noteHashRoot, nullifierRoot, publicDataRoot } =
|
|
@@ -107,7 +112,7 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
107
112
|
}),
|
|
108
113
|
});
|
|
109
114
|
|
|
110
|
-
const body = Body.fromTxBlobData(
|
|
115
|
+
const body = Body.fromTxBlobData(blockBlobData.txs);
|
|
111
116
|
|
|
112
117
|
const blobFields = encodeBlockBlobData(blockBlobData);
|
|
113
118
|
await spongeBlob.absorb(blobFields);
|
|
@@ -126,7 +131,7 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
126
131
|
|
|
127
132
|
const newArchive = new AppendOnlyTreeSnapshot(newArchiveRoots[i], l2BlockNumber + 1);
|
|
128
133
|
|
|
129
|
-
l2Blocks.push(new
|
|
134
|
+
l2Blocks.push(new L2Block(newArchive, header, body, checkpointNumber, IndexWithinCheckpoint(i)));
|
|
130
135
|
}
|
|
131
136
|
|
|
132
137
|
const lastBlock = l2Blocks.at(-1)!;
|
|
@@ -135,29 +140,34 @@ export async function retrievedToPublishedCheckpoint({
|
|
|
135
140
|
header: checkpointHeader,
|
|
136
141
|
blocks: l2Blocks,
|
|
137
142
|
number: checkpointNumber,
|
|
143
|
+
feeAssetPriceModifier: feeAssetPriceModifier,
|
|
138
144
|
});
|
|
139
145
|
|
|
140
146
|
return PublishedCheckpoint.from({ checkpoint, l1, attestations });
|
|
141
147
|
}
|
|
142
148
|
|
|
143
149
|
/**
|
|
144
|
-
* Fetches
|
|
150
|
+
* Fetches checkpoint calldata from the rollup contract without fetching blob data.
|
|
151
|
+
* Returns RetrievedCheckpointFromCalldata objects that preserve the information needed for deferred blob fetching.
|
|
152
|
+
* @param rollup - The rollup contract wrapper.
|
|
145
153
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
146
|
-
* @param
|
|
154
|
+
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
147
155
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
148
156
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
149
|
-
* @param
|
|
150
|
-
* @
|
|
157
|
+
* @param instrumentation - The archiver instrumentation instance.
|
|
158
|
+
* @param logger - The logger instance.
|
|
159
|
+
* @returns An array of calldata-only checkpoints.
|
|
151
160
|
*/
|
|
152
|
-
export async function
|
|
153
|
-
rollup:
|
|
161
|
+
export async function retrieveCheckpointCalldataFromRollup(
|
|
162
|
+
rollup: RollupContract,
|
|
154
163
|
publicClient: ViemPublicClient,
|
|
155
|
-
|
|
164
|
+
debugClient: ViemPublicDebugClient,
|
|
156
165
|
searchStartBlock: bigint,
|
|
157
166
|
searchEndBlock: bigint,
|
|
167
|
+
instrumentation: ArchiverInstrumentation,
|
|
158
168
|
logger: Logger = createLogger('archiver'),
|
|
159
|
-
): Promise<
|
|
160
|
-
const retrievedCheckpoints:
|
|
169
|
+
): Promise<RetrievedCheckpointFromCalldata[]> {
|
|
170
|
+
const retrievedCheckpoints: RetrievedCheckpointFromCalldata[] = [];
|
|
161
171
|
|
|
162
172
|
let rollupConstants: { chainId: Fr; version: Fr; targetCommitteeSize: number } | undefined;
|
|
163
173
|
|
|
@@ -165,15 +175,7 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
165
175
|
if (searchStartBlock > searchEndBlock) {
|
|
166
176
|
break;
|
|
167
177
|
}
|
|
168
|
-
const checkpointProposedLogs = (
|
|
169
|
-
await rollup.getEvents.CheckpointProposed(
|
|
170
|
-
{},
|
|
171
|
-
{
|
|
172
|
-
fromBlock: searchStartBlock,
|
|
173
|
-
toBlock: searchEndBlock,
|
|
174
|
-
},
|
|
175
|
-
)
|
|
176
|
-
).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock);
|
|
178
|
+
const checkpointProposedLogs = await rollup.getCheckpointProposedEvents(searchStartBlock, searchEndBlock);
|
|
177
179
|
|
|
178
180
|
if (checkpointProposedLogs.length === 0) {
|
|
179
181
|
break;
|
|
@@ -181,90 +183,108 @@ export async function retrieveCheckpointsFromRollup(
|
|
|
181
183
|
|
|
182
184
|
const lastLog = checkpointProposedLogs.at(-1)!;
|
|
183
185
|
logger.debug(
|
|
184
|
-
`Got ${checkpointProposedLogs.length} processed logs for checkpoints
|
|
186
|
+
`Got ${checkpointProposedLogs.length} processed logs for checkpoints ${checkpointProposedLogs[0].args.checkpointNumber}-${lastLog.args.checkpointNumber} between L1 blocks ${searchStartBlock}-${searchEndBlock}`,
|
|
185
187
|
);
|
|
186
188
|
|
|
187
189
|
if (rollupConstants === undefined) {
|
|
188
190
|
const [chainId, version, targetCommitteeSize] = await Promise.all([
|
|
189
191
|
publicClient.getChainId(),
|
|
190
|
-
rollup.
|
|
191
|
-
rollup.
|
|
192
|
+
rollup.getVersion(),
|
|
193
|
+
rollup.getTargetCommitteeSize(),
|
|
192
194
|
]);
|
|
193
195
|
rollupConstants = {
|
|
194
196
|
chainId: new Fr(chainId),
|
|
195
197
|
version: new Fr(version),
|
|
196
|
-
targetCommitteeSize
|
|
198
|
+
targetCommitteeSize,
|
|
197
199
|
};
|
|
198
200
|
}
|
|
199
201
|
|
|
200
202
|
const newCheckpoints = await processCheckpointProposedLogs(
|
|
201
203
|
rollup,
|
|
202
204
|
publicClient,
|
|
203
|
-
|
|
205
|
+
debugClient,
|
|
204
206
|
checkpointProposedLogs,
|
|
205
207
|
rollupConstants,
|
|
208
|
+
instrumentation,
|
|
206
209
|
logger,
|
|
207
210
|
);
|
|
208
211
|
retrievedCheckpoints.push(...newCheckpoints);
|
|
209
|
-
searchStartBlock = lastLog.
|
|
212
|
+
searchStartBlock = lastLog.l1BlockNumber + 1n;
|
|
210
213
|
} while (searchStartBlock <= searchEndBlock);
|
|
211
214
|
|
|
212
|
-
// The asyncPool from processCheckpointProposedLogs will not necessarily return the checkpoints in order, so we sort them before returning.
|
|
213
215
|
return retrievedCheckpoints.sort((a, b) => Number(a.l1.blockNumber - b.l1.blockNumber));
|
|
214
216
|
}
|
|
215
217
|
|
|
216
218
|
/**
|
|
217
|
-
* Processes
|
|
218
|
-
* @param rollup - The rollup contract
|
|
219
|
+
* Processes CheckpointProposed logs, fetching only calldata (no blobs).
|
|
220
|
+
* @param rollup - The rollup contract wrapper.
|
|
219
221
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
222
|
+
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
220
223
|
* @param logs - CheckpointProposed logs.
|
|
221
|
-
* @
|
|
224
|
+
* @param rollupConstants - The rollup constants (chainId, version, targetCommitteeSize).
|
|
225
|
+
* @param instrumentation - The archiver instrumentation instance.
|
|
226
|
+
* @param logger - The logger instance.
|
|
227
|
+
* @returns An array of calldata-only checkpoints.
|
|
222
228
|
*/
|
|
223
229
|
async function processCheckpointProposedLogs(
|
|
224
|
-
rollup:
|
|
230
|
+
rollup: RollupContract,
|
|
225
231
|
publicClient: ViemPublicClient,
|
|
226
|
-
|
|
227
|
-
logs:
|
|
232
|
+
debugClient: ViemPublicDebugClient,
|
|
233
|
+
logs: CheckpointProposedLog[],
|
|
228
234
|
{ chainId, version, targetCommitteeSize }: { chainId: Fr; version: Fr; targetCommitteeSize: number },
|
|
235
|
+
instrumentation: ArchiverInstrumentation,
|
|
229
236
|
logger: Logger,
|
|
230
|
-
): Promise<
|
|
231
|
-
const retrievedCheckpoints:
|
|
237
|
+
): Promise<RetrievedCheckpointFromCalldata[]> {
|
|
238
|
+
const retrievedCheckpoints: RetrievedCheckpointFromCalldata[] = [];
|
|
239
|
+
const calldataRetriever = new CalldataRetriever(
|
|
240
|
+
publicClient,
|
|
241
|
+
debugClient,
|
|
242
|
+
targetCommitteeSize,
|
|
243
|
+
instrumentation,
|
|
244
|
+
logger,
|
|
245
|
+
EthAddress.fromString(rollup.address),
|
|
246
|
+
);
|
|
247
|
+
|
|
232
248
|
await asyncPool(10, logs, async log => {
|
|
233
|
-
const checkpointNumber =
|
|
234
|
-
const archive = log.args.archive
|
|
235
|
-
const archiveFromChain = await rollup.
|
|
236
|
-
const blobHashes = log.args.versionedBlobHashes
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
249
|
+
const checkpointNumber = log.args.checkpointNumber;
|
|
250
|
+
const archive = log.args.archive;
|
|
251
|
+
const archiveFromChain = await rollup.archiveAt(checkpointNumber);
|
|
252
|
+
const blobHashes = log.args.versionedBlobHashes;
|
|
253
|
+
|
|
254
|
+
if (archive.equals(archiveFromChain)) {
|
|
255
|
+
const expectedHashes = {
|
|
256
|
+
attestationsHash: log.args.attestationsHash.toString() as Hex,
|
|
257
|
+
payloadDigest: log.args.payloadDigest.toString() as Hex,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const checkpoint = await calldataRetriever.getCheckpointFromRollupTx(
|
|
261
|
+
log.l1TransactionHash,
|
|
244
262
|
blobHashes,
|
|
245
263
|
checkpointNumber,
|
|
246
|
-
|
|
247
|
-
targetCommitteeSize,
|
|
248
|
-
logger,
|
|
264
|
+
expectedHashes,
|
|
249
265
|
);
|
|
266
|
+
const { timestamp, parentBeaconBlockRoot } = await getL1Block(publicClient, log.l1BlockNumber);
|
|
267
|
+
const l1 = new L1PublishedData(log.l1BlockNumber, timestamp, log.l1BlockHash.toString());
|
|
268
|
+
|
|
269
|
+
retrievedCheckpoints.push({
|
|
270
|
+
...checkpoint,
|
|
271
|
+
l1,
|
|
272
|
+
chainId,
|
|
273
|
+
version,
|
|
274
|
+
blobHashes,
|
|
275
|
+
parentBeaconBlockRoot,
|
|
276
|
+
});
|
|
250
277
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
blockHash: log.blockHash,
|
|
254
|
-
timestamp: await getL1BlockTime(publicClient, log.blockNumber),
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
retrievedCheckpoints.push({ ...checkpoint, l1, chainId, version });
|
|
258
|
-
logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.transactionHash}`, {
|
|
259
|
-
l1BlockNumber: log.blockNumber,
|
|
278
|
+
logger.trace(`Retrieved checkpoint calldata ${checkpointNumber} from L1 tx ${log.l1TransactionHash}`, {
|
|
279
|
+
l1BlockNumber: log.l1BlockNumber,
|
|
260
280
|
checkpointNumber,
|
|
261
281
|
archive: archive.toString(),
|
|
262
282
|
attestations: checkpoint.attestations,
|
|
263
283
|
});
|
|
264
284
|
} else {
|
|
265
285
|
logger.warn(`Ignoring checkpoint ${checkpointNumber} due to archive root mismatch`, {
|
|
266
|
-
actual: archive,
|
|
267
|
-
expected: archiveFromChain,
|
|
286
|
+
actual: archive.toString(),
|
|
287
|
+
expected: archiveFromChain.toString(),
|
|
268
288
|
});
|
|
269
289
|
}
|
|
270
290
|
});
|
|
@@ -272,123 +292,29 @@ async function processCheckpointProposedLogs(
|
|
|
272
292
|
return retrievedCheckpoints;
|
|
273
293
|
}
|
|
274
294
|
|
|
275
|
-
export async function
|
|
295
|
+
export async function getL1Block(
|
|
296
|
+
publicClient: ViemPublicClient,
|
|
297
|
+
blockNumber: bigint,
|
|
298
|
+
): Promise<{ timestamp: bigint; parentBeaconBlockRoot: string | undefined }> {
|
|
276
299
|
const block = await publicClient.getBlock({ blockNumber, includeTransactions: false });
|
|
277
|
-
return block.timestamp;
|
|
300
|
+
return { timestamp: block.timestamp, parentBeaconBlockRoot: block.parentBeaconBlockRoot };
|
|
278
301
|
}
|
|
279
302
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
*/
|
|
286
|
-
function extractRollupProposeCalldata(multicall3Data: Hex, rollupAddress: Hex): Hex {
|
|
287
|
-
const { functionName: multicall3FunctionName, args: multicall3Args } = decodeFunctionData({
|
|
288
|
-
abi: multicall3Abi,
|
|
289
|
-
data: multicall3Data,
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
if (multicall3FunctionName !== 'aggregate3') {
|
|
293
|
-
throw new Error(`Unexpected multicall3 method called ${multicall3FunctionName}`);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (multicall3Args.length !== 1) {
|
|
297
|
-
throw new Error(`Unexpected number of arguments for multicall3`);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const [calls] = multicall3Args;
|
|
301
|
-
|
|
302
|
-
// Find all rollup calls
|
|
303
|
-
const rollupAddressLower = rollupAddress.toLowerCase();
|
|
304
|
-
|
|
305
|
-
for (let i = 0; i < calls.length; i++) {
|
|
306
|
-
const addr = calls[i].target;
|
|
307
|
-
if (addr.toLowerCase() !== rollupAddressLower) {
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
const callData = calls[i].callData;
|
|
311
|
-
|
|
312
|
-
try {
|
|
313
|
-
const { functionName: rollupFunctionName } = decodeFunctionData({
|
|
314
|
-
abi: RollupAbi,
|
|
315
|
-
data: callData,
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
if (rollupFunctionName === 'propose') {
|
|
319
|
-
return callData;
|
|
320
|
-
}
|
|
321
|
-
} catch {
|
|
322
|
-
// Skip invalid function data
|
|
323
|
-
continue;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
throw new Error(`Rollup address not found in multicall3 args`);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* Gets checkpoint from the calldata of an L1 transaction.
|
|
332
|
-
* Assumes that the checkpoint was published from an EOA.
|
|
333
|
-
* TODO: Add retries and error management.
|
|
334
|
-
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
335
|
-
* @param txHash - Hash of the tx that published it.
|
|
336
|
-
* @param checkpointNumber - Checkpoint number.
|
|
337
|
-
* @returns Checkpoint from the calldata, deserialized
|
|
338
|
-
*/
|
|
339
|
-
async function getCheckpointFromRollupTx(
|
|
340
|
-
publicClient: ViemPublicClient,
|
|
341
|
-
blobSinkClient: BlobSinkClientInterface,
|
|
342
|
-
txHash: `0x${string}`,
|
|
343
|
-
blobHashes: Buffer[], // TODO(md): buffer32?
|
|
344
|
-
checkpointNumber: number,
|
|
345
|
-
rollupAddress: Hex,
|
|
346
|
-
targetCommitteeSize: number,
|
|
303
|
+
export async function getCheckpointBlobDataFromBlobs(
|
|
304
|
+
blobClient: BlobClientInterface,
|
|
305
|
+
blockHash: string,
|
|
306
|
+
blobHashes: Buffer<ArrayBufferLike>[],
|
|
307
|
+
checkpointNumber: CheckpointNumber,
|
|
347
308
|
logger: Logger,
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
309
|
+
isHistoricalSync: boolean,
|
|
310
|
+
parentBeaconBlockRoot?: string,
|
|
311
|
+
l1BlockTimestamp?: bigint,
|
|
312
|
+
): Promise<CheckpointBlobData> {
|
|
313
|
+
const blobBodies = await blobClient.getBlobSidecar(blockHash, blobHashes, {
|
|
314
|
+
isHistoricalSync,
|
|
315
|
+
parentBeaconBlockRoot,
|
|
316
|
+
l1BlockTimestamp,
|
|
356
317
|
});
|
|
357
|
-
|
|
358
|
-
if (rollupFunctionName !== 'propose') {
|
|
359
|
-
throw new Error(`Unexpected rollup method called ${rollupFunctionName}`);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
const [decodedArgs, packedAttestations, _signers, _blobInput] = rollupArgs! as readonly [
|
|
363
|
-
{
|
|
364
|
-
archive: Hex;
|
|
365
|
-
oracleInput: {
|
|
366
|
-
feeAssetPriceModifier: bigint;
|
|
367
|
-
};
|
|
368
|
-
header: ViemHeader;
|
|
369
|
-
txHashes: readonly Hex[];
|
|
370
|
-
},
|
|
371
|
-
ViemCommitteeAttestations,
|
|
372
|
-
Hex[],
|
|
373
|
-
ViemSignature,
|
|
374
|
-
Hex,
|
|
375
|
-
];
|
|
376
|
-
|
|
377
|
-
const attestations = CommitteeAttestation.fromPacked(packedAttestations, targetCommitteeSize);
|
|
378
|
-
|
|
379
|
-
logger.trace(`Recovered propose calldata from tx ${txHash}`, {
|
|
380
|
-
checkpointNumber,
|
|
381
|
-
archive: decodedArgs.archive,
|
|
382
|
-
header: decodedArgs.header,
|
|
383
|
-
l1BlockHash: blockHash,
|
|
384
|
-
blobHashes,
|
|
385
|
-
attestations,
|
|
386
|
-
packedAttestations,
|
|
387
|
-
targetCommitteeSize,
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
const header = CheckpointHeader.fromViem(decodedArgs.header);
|
|
391
|
-
const blobBodies = await blobSinkClient.getBlobSidecar(blockHash, blobHashes);
|
|
392
318
|
if (blobBodies.length === 0) {
|
|
393
319
|
throw new NoBlobBodiesFoundError(checkpointNumber);
|
|
394
320
|
}
|
|
@@ -396,83 +322,65 @@ async function getCheckpointFromRollupTx(
|
|
|
396
322
|
let checkpointBlobData: CheckpointBlobData;
|
|
397
323
|
try {
|
|
398
324
|
// Attempt to decode the checkpoint blob data.
|
|
399
|
-
checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies
|
|
325
|
+
checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies);
|
|
400
326
|
} catch (err: any) {
|
|
401
327
|
if (err instanceof BlobDeserializationError) {
|
|
402
328
|
logger.fatal(err.message);
|
|
403
329
|
} else {
|
|
404
330
|
logger.fatal('Unable to sync: failed to decode fetched blob, this blob was likely not created by us');
|
|
405
331
|
}
|
|
332
|
+
// Throwing an error since this is most likely caused by a bug.
|
|
406
333
|
throw err;
|
|
407
334
|
}
|
|
408
335
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
return {
|
|
412
|
-
checkpointNumber,
|
|
413
|
-
archiveRoot,
|
|
414
|
-
header,
|
|
415
|
-
checkpointBlobData,
|
|
416
|
-
attestations,
|
|
417
|
-
};
|
|
336
|
+
return checkpointBlobData;
|
|
418
337
|
}
|
|
419
338
|
|
|
420
339
|
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */
|
|
421
340
|
export async function retrieveL1ToL2Message(
|
|
422
|
-
inbox:
|
|
423
|
-
|
|
424
|
-
fromBlock: bigint,
|
|
425
|
-
toBlock: bigint,
|
|
341
|
+
inbox: InboxContract,
|
|
342
|
+
message: InboxMessage,
|
|
426
343
|
): Promise<InboxMessage | undefined> {
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
const messages = mapLogsInboxMessage(logs);
|
|
430
|
-
return messages.length > 0 ? messages[0] : undefined;
|
|
344
|
+
const log = await inbox.getMessageSentEventByHash(message.leaf.toString(), message.l1BlockNumber);
|
|
345
|
+
return log && mapLogInboxMessage(log);
|
|
431
346
|
}
|
|
432
347
|
|
|
433
348
|
/**
|
|
434
349
|
* Fetch L1 to L2 messages.
|
|
435
|
-
* @param
|
|
436
|
-
* @param inboxAddress - The address of the inbox contract to fetch messages from.
|
|
437
|
-
* @param blockUntilSynced - If true, blocks until the archiver has fully synced.
|
|
350
|
+
* @param inbox - The inbox contract wrapper.
|
|
438
351
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
439
352
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
440
353
|
* @returns An array of InboxLeaf and next eth block to search from.
|
|
441
354
|
*/
|
|
442
355
|
export async function retrieveL1ToL2Messages(
|
|
443
|
-
inbox:
|
|
356
|
+
inbox: InboxContract,
|
|
444
357
|
searchStartBlock: bigint,
|
|
445
358
|
searchEndBlock: bigint,
|
|
446
359
|
): Promise<InboxMessage[]> {
|
|
447
360
|
const retrievedL1ToL2Messages: InboxMessage[] = [];
|
|
448
361
|
while (searchStartBlock <= searchEndBlock) {
|
|
449
|
-
const messageSentLogs = (
|
|
450
|
-
await inbox.getEvents.MessageSent({}, { fromBlock: searchStartBlock, toBlock: searchEndBlock })
|
|
451
|
-
).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock);
|
|
362
|
+
const messageSentLogs = await inbox.getMessageSentEvents(searchStartBlock, searchEndBlock);
|
|
452
363
|
|
|
453
364
|
if (messageSentLogs.length === 0) {
|
|
454
365
|
break;
|
|
455
366
|
}
|
|
456
367
|
|
|
457
|
-
retrievedL1ToL2Messages.push(...
|
|
458
|
-
searchStartBlock = messageSentLogs.at(-1)!.
|
|
368
|
+
retrievedL1ToL2Messages.push(...messageSentLogs.map(mapLogInboxMessage));
|
|
369
|
+
searchStartBlock = messageSentLogs.at(-1)!.l1BlockNumber + 1n;
|
|
459
370
|
}
|
|
460
371
|
|
|
461
372
|
return retrievedL1ToL2Messages;
|
|
462
373
|
}
|
|
463
374
|
|
|
464
|
-
function
|
|
465
|
-
return
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
rollingHash: Buffer16.fromString(rollingHash!),
|
|
474
|
-
};
|
|
475
|
-
});
|
|
375
|
+
function mapLogInboxMessage(log: MessageSentLog): InboxMessage {
|
|
376
|
+
return {
|
|
377
|
+
index: log.args.index,
|
|
378
|
+
leaf: log.args.leaf,
|
|
379
|
+
l1BlockNumber: log.l1BlockNumber,
|
|
380
|
+
l1BlockHash: log.l1BlockHash,
|
|
381
|
+
checkpointNumber: log.args.checkpointNumber,
|
|
382
|
+
rollingHash: log.args.rollingHash,
|
|
383
|
+
};
|
|
476
384
|
}
|
|
477
385
|
|
|
478
386
|
/** Retrieves L2ProofVerified events from the rollup contract. */
|
|
@@ -481,7 +389,7 @@ export async function retrieveL2ProofVerifiedEvents(
|
|
|
481
389
|
rollupAddress: EthAddress,
|
|
482
390
|
searchStartBlock: bigint,
|
|
483
391
|
searchEndBlock?: bigint,
|
|
484
|
-
): Promise<{ l1BlockNumber: bigint; checkpointNumber:
|
|
392
|
+
): Promise<{ l1BlockNumber: bigint; checkpointNumber: CheckpointNumber; proverId: Fr; txHash: Hex }[]> {
|
|
485
393
|
const logs = await publicClient.getLogs({
|
|
486
394
|
address: rollupAddress.toString(),
|
|
487
395
|
fromBlock: searchStartBlock,
|
|
@@ -492,7 +400,7 @@ export async function retrieveL2ProofVerifiedEvents(
|
|
|
492
400
|
|
|
493
401
|
return logs.map(log => ({
|
|
494
402
|
l1BlockNumber: log.blockNumber,
|
|
495
|
-
checkpointNumber:
|
|
403
|
+
checkpointNumber: CheckpointNumber.fromBigInt(log.args.checkpointNumber),
|
|
496
404
|
proverId: Fr.fromHexString(log.args.proverId),
|
|
497
405
|
txHash: log.transactionHash,
|
|
498
406
|
}));
|