@aztec/archiver 3.0.0-canary.a9708bd → 3.0.0-devnet.2-patch.1
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 +27 -6
- package/dest/archiver/archiver.d.ts +87 -64
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +463 -278
- package/dest/archiver/archiver_store.d.ts +46 -28
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +316 -143
- package/dest/archiver/config.d.ts +6 -23
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +19 -12
- package/dest/archiver/errors.d.ts +1 -1
- package/dest/archiver/errors.d.ts.map +1 -1
- package/dest/archiver/index.d.ts +1 -1
- package/dest/archiver/instrumentation.d.ts +5 -3
- package/dest/archiver/instrumentation.d.ts.map +1 -1
- package/dest/archiver/instrumentation.js +14 -0
- package/dest/archiver/kv_archiver_store/block_store.d.ts +45 -9
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +99 -12
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -2
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +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 +2 -2
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +30 -30
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +26 -15
- package/dest/archiver/kv_archiver_store/log_store.d.ts +3 -10
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +4 -26
- package/dest/archiver/kv_archiver_store/message_store.d.ts +6 -5
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +15 -14
- package/dest/archiver/l1/bin/retrieve-calldata.d.ts +3 -0
- package/dest/archiver/l1/bin/retrieve-calldata.d.ts.map +1 -0
- package/dest/archiver/l1/bin/retrieve-calldata.js +147 -0
- package/dest/archiver/l1/calldata_retriever.d.ts +98 -0
- package/dest/archiver/l1/calldata_retriever.d.ts.map +1 -0
- package/dest/archiver/l1/calldata_retriever.js +403 -0
- package/dest/archiver/l1/data_retrieval.d.ts +87 -0
- package/dest/archiver/l1/data_retrieval.d.ts.map +1 -0
- package/dest/archiver/{data_retrieval.js → l1/data_retrieval.js} +118 -154
- package/dest/archiver/l1/debug_tx.d.ts +19 -0
- package/dest/archiver/l1/debug_tx.d.ts.map +1 -0
- package/dest/archiver/l1/debug_tx.js +73 -0
- package/dest/archiver/l1/spire_proposer.d.ts +70 -0
- package/dest/archiver/l1/spire_proposer.d.ts.map +1 -0
- package/dest/archiver/l1/spire_proposer.js +157 -0
- package/dest/archiver/l1/trace_tx.d.ts +97 -0
- package/dest/archiver/l1/trace_tx.d.ts.map +1 -0
- package/dest/archiver/l1/trace_tx.js +91 -0
- package/dest/archiver/l1/types.d.ts +12 -0
- package/dest/archiver/l1/types.d.ts.map +1 -0
- package/dest/archiver/l1/types.js +3 -0
- package/dest/archiver/l1/validate_trace.d.ts +29 -0
- package/dest/archiver/l1/validate_trace.d.ts.map +1 -0
- package/dest/archiver/l1/validate_trace.js +150 -0
- package/dest/archiver/structs/data_retrieval.d.ts +1 -1
- package/dest/archiver/structs/inbox_message.d.ts +4 -4
- package/dest/archiver/structs/inbox_message.d.ts.map +1 -1
- package/dest/archiver/structs/inbox_message.js +6 -5
- package/dest/archiver/structs/published.d.ts +3 -2
- package/dest/archiver/structs/published.d.ts.map +1 -1
- package/dest/archiver/validation.d.ts +10 -4
- package/dest/archiver/validation.d.ts.map +1 -1
- package/dest/archiver/validation.js +66 -44
- package/dest/factory.d.ts +3 -11
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +5 -17
- package/dest/index.d.ts +2 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/rpc/index.d.ts +2 -2
- package/dest/test/index.d.ts +1 -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 +10 -9
- package/dest/test/mock_l2_block_source.d.ts +24 -20
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +79 -13
- package/dest/test/mock_structs.d.ts +3 -2
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +9 -8
- package/package.json +18 -17
- package/src/archiver/archiver.ts +610 -363
- package/src/archiver/archiver_store.ts +55 -28
- package/src/archiver/archiver_store_test_suite.ts +369 -143
- package/src/archiver/config.ts +26 -51
- package/src/archiver/instrumentation.ts +19 -2
- package/src/archiver/kv_archiver_store/block_store.ts +139 -21
- 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 +48 -33
- package/src/archiver/kv_archiver_store/log_store.ts +4 -30
- package/src/archiver/kv_archiver_store/message_store.ts +21 -18
- package/src/archiver/l1/README.md +98 -0
- package/src/archiver/l1/bin/retrieve-calldata.ts +182 -0
- package/src/archiver/l1/calldata_retriever.ts +531 -0
- package/src/archiver/{data_retrieval.ts → l1/data_retrieval.ts} +198 -242
- package/src/archiver/l1/debug_tx.ts +99 -0
- package/src/archiver/l1/spire_proposer.ts +160 -0
- package/src/archiver/l1/trace_tx.ts +128 -0
- package/src/archiver/l1/types.ts +13 -0
- package/src/archiver/l1/validate_trace.ts +211 -0
- package/src/archiver/structs/inbox_message.ts +8 -8
- package/src/archiver/structs/published.ts +2 -1
- package/src/archiver/validation.ts +86 -32
- package/src/factory.ts +6 -26
- package/src/index.ts +1 -1
- 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/mock_archiver.ts +22 -16
- package/src/test/mock_l1_to_l2_message_source.ts +10 -9
- package/src/test/mock_l2_block_source.ts +110 -27
- package/src/test/mock_structs.ts +10 -9
- package/dest/archiver/data_retrieval.d.ts +0 -78
- package/dest/archiver/data_retrieval.d.ts.map +0 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type CheckpointBlobData } from '@aztec/blob-lib';
|
|
2
|
+
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
3
|
+
import type { ViemClient, ViemPublicClient, ViemPublicDebugClient } from '@aztec/ethereum/types';
|
|
4
|
+
import { CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
5
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
6
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
7
|
+
import { type Logger } from '@aztec/foundation/log';
|
|
8
|
+
import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
9
|
+
import { CommitteeAttestation } from '@aztec/stdlib/block';
|
|
10
|
+
import { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
11
|
+
import { Proof } from '@aztec/stdlib/proofs';
|
|
12
|
+
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
13
|
+
import { type GetContractReturnType, type Hex } from 'viem';
|
|
14
|
+
import type { ArchiverInstrumentation } from '../instrumentation.js';
|
|
15
|
+
import type { DataRetrieval } from '../structs/data_retrieval.js';
|
|
16
|
+
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
17
|
+
import type { L1PublishedData } from '../structs/published.js';
|
|
18
|
+
export type RetrievedCheckpoint = {
|
|
19
|
+
checkpointNumber: CheckpointNumber;
|
|
20
|
+
archiveRoot: Fr;
|
|
21
|
+
header: CheckpointHeader;
|
|
22
|
+
checkpointBlobData: CheckpointBlobData;
|
|
23
|
+
l1: L1PublishedData;
|
|
24
|
+
chainId: Fr;
|
|
25
|
+
version: Fr;
|
|
26
|
+
attestations: CommitteeAttestation[];
|
|
27
|
+
};
|
|
28
|
+
export declare function retrievedToPublishedCheckpoint({ checkpointNumber, archiveRoot, header: checkpointHeader, checkpointBlobData, l1, chainId, version, attestations }: RetrievedCheckpoint): Promise<PublishedCheckpoint>;
|
|
29
|
+
/**
|
|
30
|
+
* Fetches new checkpoints.
|
|
31
|
+
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
32
|
+
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
33
|
+
* @param rollupAddress - The address of the rollup contract.
|
|
34
|
+
* @param searchStartBlock - The block number to use for starting the search.
|
|
35
|
+
* @param searchEndBlock - The highest block number that we should search up to.
|
|
36
|
+
* @param expectedNextL2BlockNum - The next L2 block number that we expect to find.
|
|
37
|
+
* @returns An array of block; as well as the next eth block to search from.
|
|
38
|
+
*/
|
|
39
|
+
export declare function retrieveCheckpointsFromRollup(rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>, publicClient: ViemPublicClient, debugClient: ViemPublicDebugClient, blobSinkClient: BlobSinkClientInterface, searchStartBlock: bigint, searchEndBlock: bigint, contractAddresses: {
|
|
40
|
+
governanceProposerAddress: EthAddress;
|
|
41
|
+
slashFactoryAddress?: EthAddress;
|
|
42
|
+
slashingProposerAddress: EthAddress;
|
|
43
|
+
}, instrumentation: ArchiverInstrumentation, logger?: Logger): Promise<RetrievedCheckpoint[]>;
|
|
44
|
+
export declare function getL1BlockTime(publicClient: ViemPublicClient, blockNumber: bigint): Promise<bigint>;
|
|
45
|
+
export declare function getCheckpointBlobDataFromBlobs(blobSinkClient: BlobSinkClientInterface, blockHash: string, blobHashes: Buffer<ArrayBufferLike>[], checkpointNumber: CheckpointNumber, logger: Logger): Promise<CheckpointBlobData>;
|
|
46
|
+
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */
|
|
47
|
+
export declare function retrieveL1ToL2Message(inbox: GetContractReturnType<typeof InboxAbi, ViemClient>, leaf: Fr, fromBlock: bigint, toBlock: bigint): Promise<InboxMessage | undefined>;
|
|
48
|
+
/**
|
|
49
|
+
* Fetch L1 to L2 messages.
|
|
50
|
+
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
51
|
+
* @param inboxAddress - The address of the inbox contract to fetch messages from.
|
|
52
|
+
* @param blockUntilSynced - If true, blocks until the archiver has fully synced.
|
|
53
|
+
* @param searchStartBlock - The block number to use for starting the search.
|
|
54
|
+
* @param searchEndBlock - The highest block number that we should search up to.
|
|
55
|
+
* @returns An array of InboxLeaf and next eth block to search from.
|
|
56
|
+
*/
|
|
57
|
+
export declare function retrieveL1ToL2Messages(inbox: GetContractReturnType<typeof InboxAbi, ViemClient>, searchStartBlock: bigint, searchEndBlock: bigint): Promise<InboxMessage[]>;
|
|
58
|
+
/** Retrieves L2ProofVerified events from the rollup contract. */
|
|
59
|
+
export declare function retrieveL2ProofVerifiedEvents(publicClient: ViemPublicClient, rollupAddress: EthAddress, searchStartBlock: bigint, searchEndBlock?: bigint): Promise<{
|
|
60
|
+
l1BlockNumber: bigint;
|
|
61
|
+
checkpointNumber: CheckpointNumber;
|
|
62
|
+
proverId: Fr;
|
|
63
|
+
txHash: Hex;
|
|
64
|
+
}[]>;
|
|
65
|
+
/** Retrieve submitted proofs from the rollup contract */
|
|
66
|
+
export declare function retrieveL2ProofsFromRollup(publicClient: ViemPublicClient, rollupAddress: EthAddress, searchStartBlock: bigint, searchEndBlock?: bigint): Promise<DataRetrieval<{
|
|
67
|
+
proof: Proof;
|
|
68
|
+
proverId: Fr;
|
|
69
|
+
checkpointNumber: number;
|
|
70
|
+
txHash: `0x${string}`;
|
|
71
|
+
}>>;
|
|
72
|
+
export type SubmitEpochProof = {
|
|
73
|
+
archiveRoot: Fr;
|
|
74
|
+
proverId: Fr;
|
|
75
|
+
proof: Proof;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Gets epoch proof metadata (archive root and proof) from the calldata of an L1 transaction.
|
|
79
|
+
* Assumes that the block was published from an EOA.
|
|
80
|
+
* TODO: Add retries and error management.
|
|
81
|
+
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
82
|
+
* @param txHash - Hash of the tx that published it.
|
|
83
|
+
* @param expectedProverId - Expected prover ID.
|
|
84
|
+
* @returns Epoch proof metadata from the calldata, deserialized.
|
|
85
|
+
*/
|
|
86
|
+
export declare function getProofFromSubmitProofTx(publicClient: ViemPublicClient, txHash: `0x${string}`, expectedProverId: Fr): Promise<SubmitEpochProof>;
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YV9yZXRyaWV2YWwuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcmNoaXZlci9sMS9kYXRhX3JldHJpZXZhbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsS0FBSyxrQkFBa0IsRUFJeEIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXZFLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRWpHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRW5FLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxLQUFLLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMvRCxPQUFPLEVBQVEsb0JBQW9CLEVBQWMsTUFBTSxxQkFBcUIsQ0FBQztBQUM3RSxPQUFPLEVBQWMsbUJBQW1CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFJeEQsT0FBTyxFQUVMLEtBQUsscUJBQXFCLEVBQzFCLEtBQUssR0FBRyxFQUlULE1BQU0sTUFBTSxDQUFDO0FBR2QsT0FBTyxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRSxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNsRSxPQUFPLEtB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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data_retrieval.d.ts","sourceRoot":"","sources":["../../../src/archiver/l1/data_retrieval.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,67 +1,106 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BlobDeserializationError, SpongeBlob, decodeCheckpointBlobDataFromBlobs, encodeBlockBlobData } from '@aztec/blob-lib';
|
|
2
2
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
3
|
+
import { CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
3
4
|
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
|
|
4
|
-
import { Fr } from '@aztec/foundation/
|
|
5
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
6
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
8
|
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
7
|
-
import { Body,
|
|
9
|
+
import { Body, L2BlockNew } from '@aztec/stdlib/block';
|
|
10
|
+
import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
8
11
|
import { Proof } from '@aztec/stdlib/proofs';
|
|
9
12
|
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
10
|
-
import { BlockHeader, GlobalVariables,
|
|
11
|
-
import { decodeFunctionData, getAbiItem, hexToBytes
|
|
12
|
-
import { NoBlobBodiesFoundError } from '
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
13
|
+
import { BlockHeader, GlobalVariables, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
|
|
14
|
+
import { decodeFunctionData, getAbiItem, hexToBytes } from 'viem';
|
|
15
|
+
import { NoBlobBodiesFoundError } from '../errors.js';
|
|
16
|
+
import { CalldataRetriever } from './calldata_retriever.js';
|
|
17
|
+
export async function retrievedToPublishedCheckpoint({ checkpointNumber, archiveRoot, header: checkpointHeader, checkpointBlobData, l1, chainId, version, attestations }) {
|
|
18
|
+
const { blocks: blocksBlobData } = checkpointBlobData;
|
|
19
|
+
// The lastArchiveRoot of a block is the new archive for the previous block.
|
|
20
|
+
const newArchiveRoots = blocksBlobData.map((b)=>b.lastArchiveRoot).slice(1).concat([
|
|
21
|
+
archiveRoot
|
|
22
|
+
]);
|
|
23
|
+
// An error will be thrown from `decodeCheckpointBlobDataFromBlobs` if it can't read a field for the
|
|
24
|
+
// `l1ToL2MessageRoot` of the first block. So below we can safely assume it exists:
|
|
25
|
+
const l1toL2MessageTreeRoot = blocksBlobData[0].l1ToL2MessageRoot;
|
|
26
|
+
const spongeBlob = SpongeBlob.init();
|
|
27
|
+
const l2Blocks = [];
|
|
28
|
+
for(let i = 0; i < blocksBlobData.length; i++){
|
|
29
|
+
const blockBlobData = blocksBlobData[i];
|
|
30
|
+
const { blockEndMarker, blockEndStateField, lastArchiveRoot, noteHashRoot, nullifierRoot, publicDataRoot } = blockBlobData;
|
|
31
|
+
const l2BlockNumber = blockEndMarker.blockNumber;
|
|
32
|
+
const globalVariables = GlobalVariables.from({
|
|
33
|
+
chainId,
|
|
34
|
+
version,
|
|
35
|
+
blockNumber: l2BlockNumber,
|
|
36
|
+
slotNumber: checkpointHeader.slotNumber,
|
|
37
|
+
timestamp: blockEndMarker.timestamp,
|
|
38
|
+
coinbase: checkpointHeader.coinbase,
|
|
39
|
+
feeRecipient: checkpointHeader.feeRecipient,
|
|
40
|
+
gasFees: checkpointHeader.gasFees
|
|
41
|
+
});
|
|
42
|
+
const state = StateReference.from({
|
|
43
|
+
l1ToL2MessageTree: new AppendOnlyTreeSnapshot(l1toL2MessageTreeRoot, blockEndStateField.l1ToL2MessageNextAvailableLeafIndex),
|
|
44
|
+
partial: PartialStateReference.from({
|
|
45
|
+
noteHashTree: new AppendOnlyTreeSnapshot(noteHashRoot, blockEndStateField.noteHashNextAvailableLeafIndex),
|
|
46
|
+
nullifierTree: new AppendOnlyTreeSnapshot(nullifierRoot, blockEndStateField.nullifierNextAvailableLeafIndex),
|
|
47
|
+
publicDataTree: new AppendOnlyTreeSnapshot(publicDataRoot, blockEndStateField.publicDataNextAvailableLeafIndex)
|
|
48
|
+
})
|
|
49
|
+
});
|
|
50
|
+
const body = Body.fromTxBlobData(checkpointBlobData.blocks[0].txs);
|
|
51
|
+
const blobFields = encodeBlockBlobData(blockBlobData);
|
|
52
|
+
await spongeBlob.absorb(blobFields);
|
|
53
|
+
const clonedSpongeBlob = spongeBlob.clone();
|
|
54
|
+
const spongeBlobHash = await clonedSpongeBlob.squeeze();
|
|
55
|
+
const header = BlockHeader.from({
|
|
56
|
+
lastArchive: new AppendOnlyTreeSnapshot(lastArchiveRoot, l2BlockNumber),
|
|
57
|
+
state,
|
|
58
|
+
spongeBlobHash,
|
|
59
|
+
globalVariables,
|
|
60
|
+
totalFees: body.txEffects.reduce((accum, txEffect)=>accum.add(txEffect.transactionFee), Fr.ZERO),
|
|
61
|
+
totalManaUsed: new Fr(blockEndStateField.totalManaUsed)
|
|
62
|
+
});
|
|
63
|
+
const newArchive = new AppendOnlyTreeSnapshot(newArchiveRoots[i], l2BlockNumber + 1);
|
|
64
|
+
l2Blocks.push(new L2BlockNew(newArchive, header, body, checkpointNumber, i));
|
|
65
|
+
}
|
|
66
|
+
const lastBlock = l2Blocks.at(-1);
|
|
67
|
+
const checkpoint = Checkpoint.from({
|
|
68
|
+
archive: new AppendOnlyTreeSnapshot(archiveRoot, lastBlock.number + 1),
|
|
69
|
+
header: checkpointHeader,
|
|
70
|
+
blocks: l2Blocks,
|
|
71
|
+
number: checkpointNumber
|
|
33
72
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
block,
|
|
73
|
+
return PublishedCheckpoint.from({
|
|
74
|
+
checkpoint,
|
|
37
75
|
l1,
|
|
38
76
|
attestations
|
|
39
|
-
};
|
|
77
|
+
});
|
|
40
78
|
}
|
|
41
79
|
/**
|
|
42
|
-
* Fetches new
|
|
80
|
+
* Fetches new checkpoints.
|
|
43
81
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
82
|
+
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
44
83
|
* @param rollupAddress - The address of the rollup contract.
|
|
45
84
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
46
85
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
47
86
|
* @param expectedNextL2BlockNum - The next L2 block number that we expect to find.
|
|
48
87
|
* @returns An array of block; as well as the next eth block to search from.
|
|
49
|
-
*/ export async function
|
|
50
|
-
const
|
|
88
|
+
*/ export async function retrieveCheckpointsFromRollup(rollup, publicClient, debugClient, blobSinkClient, searchStartBlock, searchEndBlock, contractAddresses, instrumentation, logger = createLogger('archiver')) {
|
|
89
|
+
const retrievedCheckpoints = [];
|
|
51
90
|
let rollupConstants;
|
|
52
91
|
do {
|
|
53
92
|
if (searchStartBlock > searchEndBlock) {
|
|
54
93
|
break;
|
|
55
94
|
}
|
|
56
|
-
const
|
|
95
|
+
const checkpointProposedLogs = (await rollup.getEvents.CheckpointProposed({}, {
|
|
57
96
|
fromBlock: searchStartBlock,
|
|
58
97
|
toBlock: searchEndBlock
|
|
59
98
|
})).filter((log)=>log.blockNumber >= searchStartBlock && log.blockNumber <= searchEndBlock);
|
|
60
|
-
if (
|
|
99
|
+
if (checkpointProposedLogs.length === 0) {
|
|
61
100
|
break;
|
|
62
101
|
}
|
|
63
|
-
const lastLog =
|
|
64
|
-
logger.debug(`Got ${
|
|
102
|
+
const lastLog = checkpointProposedLogs.at(-1);
|
|
103
|
+
logger.debug(`Got ${checkpointProposedLogs.length} processed logs for checkpoints ${checkpointProposedLogs[0].args.checkpointNumber}-${lastLog.args.checkpointNumber} between L1 blocks ${searchStartBlock}-${searchEndBlock}`);
|
|
65
104
|
if (rollupConstants === undefined) {
|
|
66
105
|
const [chainId, version, targetCommitteeSize] = await Promise.all([
|
|
67
106
|
publicClient.getChainId(),
|
|
@@ -74,56 +113,63 @@ export function retrievedBlockToPublishedL2Block(retrievedBlock) {
|
|
|
74
113
|
targetCommitteeSize: Number(targetCommitteeSize)
|
|
75
114
|
};
|
|
76
115
|
}
|
|
77
|
-
const
|
|
78
|
-
|
|
116
|
+
const newCheckpoints = await processCheckpointProposedLogs(rollup, publicClient, debugClient, blobSinkClient, checkpointProposedLogs, rollupConstants, contractAddresses, instrumentation, logger);
|
|
117
|
+
retrievedCheckpoints.push(...newCheckpoints);
|
|
79
118
|
searchStartBlock = lastLog.blockNumber + 1n;
|
|
80
119
|
}while (searchStartBlock <= searchEndBlock)
|
|
81
|
-
// The
|
|
82
|
-
return
|
|
120
|
+
// The asyncPool from processCheckpointProposedLogs will not necessarily return the checkpoints in order, so we sort them before returning.
|
|
121
|
+
return retrievedCheckpoints.sort((a, b)=>Number(a.l1.blockNumber - b.l1.blockNumber));
|
|
83
122
|
}
|
|
84
123
|
/**
|
|
85
|
-
* Processes newly received
|
|
124
|
+
* Processes newly received CheckpointProposed logs.
|
|
86
125
|
* @param rollup - The rollup contract
|
|
87
126
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
88
|
-
* @param
|
|
89
|
-
* @
|
|
90
|
-
|
|
91
|
-
|
|
127
|
+
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
128
|
+
* @param logs - CheckpointProposed logs.
|
|
129
|
+
* @returns - An array of checkpoints.
|
|
130
|
+
*/ async function processCheckpointProposedLogs(rollup, publicClient, debugClient, blobSinkClient, logs, { chainId, version, targetCommitteeSize }, contractAddresses, instrumentation, logger) {
|
|
131
|
+
const retrievedCheckpoints = [];
|
|
132
|
+
const calldataRetriever = new CalldataRetriever(publicClient, debugClient, targetCommitteeSize, instrumentation, logger, {
|
|
133
|
+
...contractAddresses,
|
|
134
|
+
rollupAddress: EthAddress.fromString(rollup.address)
|
|
135
|
+
});
|
|
92
136
|
await asyncPool(10, logs, async (log)=>{
|
|
93
|
-
const
|
|
137
|
+
const checkpointNumber = CheckpointNumber.fromBigInt(log.args.checkpointNumber);
|
|
94
138
|
const archive = log.args.archive;
|
|
95
139
|
const archiveFromChain = await rollup.read.archiveAt([
|
|
96
|
-
BigInt(
|
|
140
|
+
BigInt(checkpointNumber)
|
|
97
141
|
]);
|
|
98
142
|
const blobHashes = log.args.versionedBlobHashes.map((blobHash)=>Buffer.from(blobHash.slice(2), 'hex'));
|
|
99
|
-
// The value from the event and contract will match only if the
|
|
143
|
+
// The value from the event and contract will match only if the checkpoint is in the chain.
|
|
100
144
|
if (archive === archiveFromChain) {
|
|
101
|
-
const
|
|
145
|
+
const checkpoint = await calldataRetriever.getCheckpointFromRollupTx(log.transactionHash, blobHashes, checkpointNumber);
|
|
146
|
+
const checkpointBlobData = await getCheckpointBlobDataFromBlobs(blobSinkClient, checkpoint.blockHash, blobHashes, checkpointNumber, logger);
|
|
102
147
|
const l1 = {
|
|
103
148
|
blockNumber: log.blockNumber,
|
|
104
149
|
blockHash: log.blockHash,
|
|
105
150
|
timestamp: await getL1BlockTime(publicClient, log.blockNumber)
|
|
106
151
|
};
|
|
107
|
-
|
|
108
|
-
...
|
|
152
|
+
retrievedCheckpoints.push({
|
|
153
|
+
...checkpoint,
|
|
154
|
+
checkpointBlobData,
|
|
109
155
|
l1,
|
|
110
156
|
chainId,
|
|
111
157
|
version
|
|
112
158
|
});
|
|
113
|
-
logger.trace(`Retrieved
|
|
159
|
+
logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.transactionHash}`, {
|
|
114
160
|
l1BlockNumber: log.blockNumber,
|
|
115
|
-
|
|
161
|
+
checkpointNumber,
|
|
116
162
|
archive: archive.toString(),
|
|
117
|
-
attestations:
|
|
163
|
+
attestations: checkpoint.attestations
|
|
118
164
|
});
|
|
119
165
|
} else {
|
|
120
|
-
logger.warn(`Ignoring
|
|
166
|
+
logger.warn(`Ignoring checkpoint ${checkpointNumber} due to archive root mismatch`, {
|
|
121
167
|
actual: archive,
|
|
122
168
|
expected: archiveFromChain
|
|
123
169
|
});
|
|
124
170
|
}
|
|
125
171
|
});
|
|
126
|
-
return
|
|
172
|
+
return retrievedCheckpoints;
|
|
127
173
|
}
|
|
128
174
|
export async function getL1BlockTime(publicClient, blockNumber) {
|
|
129
175
|
const block = await publicClient.getBlock({
|
|
@@ -132,107 +178,25 @@ export async function getL1BlockTime(publicClient, blockNumber) {
|
|
|
132
178
|
});
|
|
133
179
|
return block.timestamp;
|
|
134
180
|
}
|
|
135
|
-
|
|
136
|
-
* Extracts the first 'propose' method calldata from a multicall3 transaction's data.
|
|
137
|
-
* @param multicall3Data - The multicall3 transaction input data
|
|
138
|
-
* @param rollupAddress - The address of the rollup contract
|
|
139
|
-
* @returns The calldata for the first 'propose' method call to the rollup contract
|
|
140
|
-
*/ function extractRollupProposeCalldata(multicall3Data, rollupAddress) {
|
|
141
|
-
const { functionName: multicall3FunctionName, args: multicall3Args } = decodeFunctionData({
|
|
142
|
-
abi: multicall3Abi,
|
|
143
|
-
data: multicall3Data
|
|
144
|
-
});
|
|
145
|
-
if (multicall3FunctionName !== 'aggregate3') {
|
|
146
|
-
throw new Error(`Unexpected multicall3 method called ${multicall3FunctionName}`);
|
|
147
|
-
}
|
|
148
|
-
if (multicall3Args.length !== 1) {
|
|
149
|
-
throw new Error(`Unexpected number of arguments for multicall3`);
|
|
150
|
-
}
|
|
151
|
-
const [calls] = multicall3Args;
|
|
152
|
-
// Find all rollup calls
|
|
153
|
-
const rollupAddressLower = rollupAddress.toLowerCase();
|
|
154
|
-
for(let i = 0; i < calls.length; i++){
|
|
155
|
-
const addr = calls[i].target;
|
|
156
|
-
if (addr.toLowerCase() !== rollupAddressLower) {
|
|
157
|
-
continue;
|
|
158
|
-
}
|
|
159
|
-
const callData = calls[i].callData;
|
|
160
|
-
try {
|
|
161
|
-
const { functionName: rollupFunctionName } = decodeFunctionData({
|
|
162
|
-
abi: RollupAbi,
|
|
163
|
-
data: callData
|
|
164
|
-
});
|
|
165
|
-
if (rollupFunctionName === 'propose') {
|
|
166
|
-
return callData;
|
|
167
|
-
}
|
|
168
|
-
} catch {
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
throw new Error(`Rollup address not found in multicall3 args`);
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Gets block from the calldata of an L1 transaction.
|
|
176
|
-
* Assumes that the block was published from an EOA.
|
|
177
|
-
* TODO: Add retries and error management.
|
|
178
|
-
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
179
|
-
* @param txHash - Hash of the tx that published it.
|
|
180
|
-
* @param l2BlockNumber - L2 block number.
|
|
181
|
-
* @returns L2 block from the calldata, deserialized
|
|
182
|
-
*/ async function getBlockFromRollupTx(publicClient, blobSinkClient, txHash, blobHashes, l2BlockNumber, rollupAddress, targetCommitteeSize, logger) {
|
|
183
|
-
const { input: forwarderData, blockHash } = await publicClient.getTransaction({
|
|
184
|
-
hash: txHash
|
|
185
|
-
});
|
|
186
|
-
const rollupData = extractRollupProposeCalldata(forwarderData, rollupAddress);
|
|
187
|
-
const { functionName: rollupFunctionName, args: rollupArgs } = decodeFunctionData({
|
|
188
|
-
abi: RollupAbi,
|
|
189
|
-
data: rollupData
|
|
190
|
-
});
|
|
191
|
-
if (rollupFunctionName !== 'propose') {
|
|
192
|
-
throw new Error(`Unexpected rollup method called ${rollupFunctionName}`);
|
|
193
|
-
}
|
|
194
|
-
const [decodedArgs, packedAttestations, _signers, _blobInput] = rollupArgs;
|
|
195
|
-
const attestations = CommitteeAttestation.fromPacked(packedAttestations, targetCommitteeSize);
|
|
196
|
-
logger.trace(`Recovered propose calldata from tx ${txHash}`, {
|
|
197
|
-
l2BlockNumber,
|
|
198
|
-
archive: decodedArgs.archive,
|
|
199
|
-
stateReference: decodedArgs.stateReference,
|
|
200
|
-
header: decodedArgs.header,
|
|
201
|
-
blobHashes,
|
|
202
|
-
attestations,
|
|
203
|
-
packedAttestations,
|
|
204
|
-
targetCommitteeSize
|
|
205
|
-
});
|
|
206
|
-
// TODO(md): why is the proposed block header different to the actual block header?
|
|
207
|
-
// This is likely going to be a footgun
|
|
208
|
-
const header = ProposedBlockHeader.fromViem(decodedArgs.header);
|
|
181
|
+
export async function getCheckpointBlobDataFromBlobs(blobSinkClient, blockHash, blobHashes, checkpointNumber, logger) {
|
|
209
182
|
const blobBodies = await blobSinkClient.getBlobSidecar(blockHash, blobHashes);
|
|
210
183
|
if (blobBodies.length === 0) {
|
|
211
|
-
throw new NoBlobBodiesFoundError(
|
|
184
|
+
throw new NoBlobBodiesFoundError(checkpointNumber);
|
|
212
185
|
}
|
|
213
|
-
let
|
|
186
|
+
let checkpointBlobData;
|
|
214
187
|
try {
|
|
215
|
-
|
|
188
|
+
// Attempt to decode the checkpoint blob data.
|
|
189
|
+
checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies.map((b)=>b.blob));
|
|
216
190
|
} catch (err) {
|
|
217
191
|
if (err instanceof BlobDeserializationError) {
|
|
218
192
|
logger.fatal(err.message);
|
|
219
193
|
} else {
|
|
220
194
|
logger.fatal('Unable to sync: failed to decode fetched blob, this blob was likely not created by us');
|
|
221
195
|
}
|
|
196
|
+
// Throwing an error since this is most likely caused by a bug.
|
|
222
197
|
throw err;
|
|
223
198
|
}
|
|
224
|
-
|
|
225
|
-
const body = Body.fromBlobFields(blockFields);
|
|
226
|
-
const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
|
|
227
|
-
const stateReference = StateReference.fromViem(decodedArgs.stateReference);
|
|
228
|
-
return {
|
|
229
|
-
l2BlockNumber,
|
|
230
|
-
archiveRoot,
|
|
231
|
-
stateReference,
|
|
232
|
-
header,
|
|
233
|
-
body,
|
|
234
|
-
attestations
|
|
235
|
-
};
|
|
199
|
+
return checkpointBlobData;
|
|
236
200
|
}
|
|
237
201
|
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */ export async function retrieveL1ToL2Message(inbox, leaf, fromBlock, toBlock) {
|
|
238
202
|
const logs = await inbox.getEvents.MessageSent({
|
|
@@ -269,13 +233,13 @@ export async function getL1BlockTime(publicClient, blockNumber) {
|
|
|
269
233
|
}
|
|
270
234
|
function mapLogsInboxMessage(logs) {
|
|
271
235
|
return logs.map((log)=>{
|
|
272
|
-
const { index, hash,
|
|
236
|
+
const { index, hash, checkpointNumber, rollingHash } = log.args;
|
|
273
237
|
return {
|
|
274
238
|
index: index,
|
|
275
239
|
leaf: Fr.fromHexString(hash),
|
|
276
240
|
l1BlockNumber: log.blockNumber,
|
|
277
241
|
l1BlockHash: Buffer32.fromString(log.blockHash),
|
|
278
|
-
|
|
242
|
+
checkpointNumber: CheckpointNumber.fromBigInt(checkpointNumber),
|
|
279
243
|
rollingHash: Buffer16.fromString(rollingHash)
|
|
280
244
|
};
|
|
281
245
|
});
|
|
@@ -293,7 +257,7 @@ function mapLogsInboxMessage(logs) {
|
|
|
293
257
|
});
|
|
294
258
|
return logs.map((log)=>({
|
|
295
259
|
l1BlockNumber: log.blockNumber,
|
|
296
|
-
|
|
260
|
+
checkpointNumber: CheckpointNumber.fromBigInt(log.args.checkpointNumber),
|
|
297
261
|
proverId: Fr.fromHexString(log.args.proverId),
|
|
298
262
|
txHash: log.transactionHash
|
|
299
263
|
}));
|
|
@@ -302,12 +266,12 @@ function mapLogsInboxMessage(logs) {
|
|
|
302
266
|
const logs = await retrieveL2ProofVerifiedEvents(publicClient, rollupAddress, searchStartBlock, searchEndBlock);
|
|
303
267
|
const retrievedData = [];
|
|
304
268
|
const lastProcessedL1BlockNumber = logs.length > 0 ? logs.at(-1).l1BlockNumber : searchStartBlock - 1n;
|
|
305
|
-
for (const { txHash, proverId,
|
|
269
|
+
for (const { txHash, proverId, checkpointNumber } of logs){
|
|
306
270
|
const proofData = await getProofFromSubmitProofTx(publicClient, txHash, proverId);
|
|
307
271
|
retrievedData.push({
|
|
308
272
|
proof: proofData.proof,
|
|
309
273
|
proverId: proofData.proverId,
|
|
310
|
-
|
|
274
|
+
checkpointNumber,
|
|
311
275
|
txHash
|
|
312
276
|
});
|
|
313
277
|
}
|
|
@@ -317,13 +281,13 @@ function mapLogsInboxMessage(logs) {
|
|
|
317
281
|
};
|
|
318
282
|
}
|
|
319
283
|
/**
|
|
320
|
-
* Gets
|
|
284
|
+
* Gets epoch proof metadata (archive root and proof) from the calldata of an L1 transaction.
|
|
321
285
|
* Assumes that the block was published from an EOA.
|
|
322
286
|
* TODO: Add retries and error management.
|
|
323
287
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
324
288
|
* @param txHash - Hash of the tx that published it.
|
|
325
|
-
* @param
|
|
326
|
-
* @returns
|
|
289
|
+
* @param expectedProverId - Expected prover ID.
|
|
290
|
+
* @returns Epoch proof metadata from the calldata, deserialized.
|
|
327
291
|
*/ export async function getProofFromSubmitProofTx(publicClient, txHash, expectedProverId) {
|
|
328
292
|
const { input: data } = await publicClient.getTransaction({
|
|
329
293
|
hash: txHash
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DebugCallTrace, ViemPublicDebugClient } from '@aztec/ethereum/types';
|
|
2
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import type { Logger } from '@aztec/foundation/log';
|
|
4
|
+
import { type ZodFor } from '@aztec/foundation/schemas';
|
|
5
|
+
import type { Hex } from 'viem';
|
|
6
|
+
import type { CallInfo } from './types.js';
|
|
7
|
+
/** Zod schema for validating call trace from debug_traceTransaction */
|
|
8
|
+
export declare const callTraceSchema: ZodFor<DebugCallTrace>;
|
|
9
|
+
/**
|
|
10
|
+
* Traces a transaction and extracts all CALL operations to a specific contract and function selector.
|
|
11
|
+
*
|
|
12
|
+
* @param client - The Viem public client
|
|
13
|
+
* @param txHash - The transaction hash to trace
|
|
14
|
+
* @param targetAddress - The contract address to filter for
|
|
15
|
+
* @param functionSelector - The 4-byte function selector to filter for (with or without 0x prefix)
|
|
16
|
+
* @returns Array of CallInfo objects containing from, gasUsed, input, and value for matching calls
|
|
17
|
+
*/
|
|
18
|
+
export declare function getSuccessfulCallsFromDebug(client: ViemPublicDebugClient, txHash: Hex, targetAddress: EthAddress, functionSelector: string, logger?: Logger): Promise<CallInfo[]>;
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVidWdfdHguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcmNoaXZlci9sMS9kZWJ1Z190eC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFXLE1BQU0sMkJBQTJCLENBQUM7QUFHakUsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR2hDLE9BQU8sS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUUzQyx1RUFBdUU7QUFDdkUsZUFBTyxNQUFNLGVBQWUsRUFBRSxNQUFNLENBQUMsY0FBYyxDQWFsRCxDQUFDO0FBRUY7Ozs7Ozs7O0dBUUc7QUFDSCx3QkFBc0IsMkJBQTJCLENBQy9DLE1BQU0sRUFBRSxxQkFBcUIsRUFDN0IsTUFBTSxFQUFFLEdBQUcsRUFDWCxhQUFhLEVBQUUsVUFBVSxFQUN6QixnQkFBZ0IsRUFBRSxNQUFNLEVBQ3hCLE1BQU0sQ0FBQyxFQUFFLE1BQU0sR0FDZCxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0F3RHJCIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug_tx.d.ts","sourceRoot":"","sources":["../../../src/archiver/l1/debug_tx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,KAAK,MAAM,EAAW,MAAM,2BAA2B,CAAC;AAGjE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAGhC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,uEAAuE;AACvE,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,cAAc,CAalD,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,GAAG,EACX,aAAa,EAAE,UAAU,EACzB,gBAAgB,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,QAAQ,EAAE,CAAC,CAwDrB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
+
import { schemas } from '@aztec/foundation/schemas';
|
|
3
|
+
import { withHexPrefix } from '@aztec/foundation/string';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
/** Zod schema for validating call trace from debug_traceTransaction */ export const callTraceSchema = z.lazy(()=>z.object({
|
|
6
|
+
from: schemas.HexStringWith0x,
|
|
7
|
+
to: schemas.HexStringWith0x.optional(),
|
|
8
|
+
type: z.string(),
|
|
9
|
+
input: schemas.HexStringWith0x.optional(),
|
|
10
|
+
output: schemas.HexStringWith0x.optional(),
|
|
11
|
+
gas: schemas.HexStringWith0x.optional(),
|
|
12
|
+
gasUsed: schemas.HexStringWith0x.optional(),
|
|
13
|
+
value: schemas.HexStringWith0x.optional(),
|
|
14
|
+
error: z.string().optional(),
|
|
15
|
+
calls: z.array(callTraceSchema).optional()
|
|
16
|
+
}));
|
|
17
|
+
/**
|
|
18
|
+
* Traces a transaction and extracts all CALL operations to a specific contract and function selector.
|
|
19
|
+
*
|
|
20
|
+
* @param client - The Viem public client
|
|
21
|
+
* @param txHash - The transaction hash to trace
|
|
22
|
+
* @param targetAddress - The contract address to filter for
|
|
23
|
+
* @param functionSelector - The 4-byte function selector to filter for (with or without 0x prefix)
|
|
24
|
+
* @returns Array of CallInfo objects containing from, gasUsed, input, and value for matching calls
|
|
25
|
+
*/ export async function getSuccessfulCallsFromDebug(client, txHash, targetAddress, functionSelector, logger) {
|
|
26
|
+
// Normalize inputs for comparison
|
|
27
|
+
const normalizedTarget = targetAddress.toString().toLowerCase();
|
|
28
|
+
const normalizedSelector = withHexPrefix(functionSelector.toLowerCase());
|
|
29
|
+
// Call debug_traceTransaction with callTracer
|
|
30
|
+
// Using 'any' here because debug_traceTransaction is not in viem's standard RPC types
|
|
31
|
+
const rawTrace = await client.request({
|
|
32
|
+
method: 'debug_traceTransaction',
|
|
33
|
+
params: [
|
|
34
|
+
txHash,
|
|
35
|
+
{
|
|
36
|
+
tracer: 'callTracer'
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
});
|
|
40
|
+
if (rawTrace === null || rawTrace === undefined) {
|
|
41
|
+
throw new Error(`Failed to retrieve debug_traceTransaction for ${txHash}`);
|
|
42
|
+
}
|
|
43
|
+
logger?.trace(`Retrieved debug_traceTransaction for ${txHash}`, {
|
|
44
|
+
trace: rawTrace
|
|
45
|
+
});
|
|
46
|
+
// Validate the response with zod
|
|
47
|
+
const trace = callTraceSchema.parse(rawTrace);
|
|
48
|
+
const results = [];
|
|
49
|
+
/**
|
|
50
|
+
* Recursively traverse the call trace tree
|
|
51
|
+
*/ function traverseCalls(callTrace) {
|
|
52
|
+
// Skip calls that have errors, and all its descendants
|
|
53
|
+
if (callTrace.error) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// Check if this is a CALL (not DELEGATECALL or STATICCALL) to the target address with matching selector
|
|
57
|
+
if (callTrace.type.toUpperCase() === 'CALL' && callTrace.to?.toLowerCase() === normalizedTarget && callTrace.input?.toLowerCase().startsWith(normalizedSelector)) {
|
|
58
|
+
results.push({
|
|
59
|
+
from: EthAddress.fromString(callTrace.from),
|
|
60
|
+
gasUsed: callTrace.gasUsed === undefined ? undefined : BigInt(callTrace.gasUsed),
|
|
61
|
+
input: callTrace.input,
|
|
62
|
+
value: callTrace.value ? BigInt(callTrace.value) : 0n
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// Recursively process nested calls
|
|
66
|
+
for (const nestedCall of callTrace.calls ?? []){
|
|
67
|
+
traverseCalls(nestedCall);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Start traversal from the root trace
|
|
71
|
+
traverseCalls(trace);
|
|
72
|
+
return results;
|
|
73
|
+
}
|