@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,25 +1,26 @@
|
|
|
1
1
|
import { BlobDeserializationError, SpongeBlob, decodeCheckpointBlobDataFromBlobs, encodeBlockBlobData } from '@aztec/blob-lib';
|
|
2
2
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
3
|
-
import {
|
|
4
|
-
import { Fr } from '@aztec/foundation/
|
|
3
|
+
import { CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
6
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
7
|
import { RollupAbi } from '@aztec/l1-artifacts';
|
|
7
|
-
import { Body,
|
|
8
|
-
import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
8
|
+
import { Body, L2Block } from '@aztec/stdlib/block';
|
|
9
|
+
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
9
10
|
import { Proof } from '@aztec/stdlib/proofs';
|
|
10
|
-
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
11
11
|
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
12
12
|
import { BlockHeader, GlobalVariables, PartialStateReference, StateReference } from '@aztec/stdlib/tx';
|
|
13
|
-
import { decodeFunctionData, getAbiItem, hexToBytes
|
|
14
|
-
import { NoBlobBodiesFoundError } from '
|
|
15
|
-
|
|
13
|
+
import { decodeFunctionData, getAbiItem, hexToBytes } from 'viem';
|
|
14
|
+
import { NoBlobBodiesFoundError } from '../errors.js';
|
|
15
|
+
import { CalldataRetriever } from './calldata_retriever.js';
|
|
16
|
+
export async function retrievedToPublishedCheckpoint({ checkpointNumber, archiveRoot, feeAssetPriceModifier, header: checkpointHeader, checkpointBlobData, l1, chainId, version, attestations }) {
|
|
16
17
|
const { blocks: blocksBlobData } = checkpointBlobData;
|
|
17
18
|
// The lastArchiveRoot of a block is the new archive for the previous block.
|
|
18
19
|
const newArchiveRoots = blocksBlobData.map((b)=>b.lastArchiveRoot).slice(1).concat([
|
|
19
20
|
archiveRoot
|
|
20
21
|
]);
|
|
21
|
-
//
|
|
22
|
-
//
|
|
22
|
+
// An error will be thrown from `decodeCheckpointBlobDataFromBlobs` if it can't read a field for the
|
|
23
|
+
// `l1ToL2MessageRoot` of the first block. So below we can safely assume it exists:
|
|
23
24
|
const l1toL2MessageTreeRoot = blocksBlobData[0].l1ToL2MessageRoot;
|
|
24
25
|
const spongeBlob = SpongeBlob.init();
|
|
25
26
|
const l2Blocks = [];
|
|
@@ -45,7 +46,7 @@ export async function retrievedToPublishedCheckpoint({ checkpointNumber, archive
|
|
|
45
46
|
publicDataTree: new AppendOnlyTreeSnapshot(publicDataRoot, blockEndStateField.publicDataNextAvailableLeafIndex)
|
|
46
47
|
})
|
|
47
48
|
});
|
|
48
|
-
const body = Body.fromTxBlobData(
|
|
49
|
+
const body = Body.fromTxBlobData(blockBlobData.txs);
|
|
49
50
|
const blobFields = encodeBlockBlobData(blockBlobData);
|
|
50
51
|
await spongeBlob.absorb(blobFields);
|
|
51
52
|
const clonedSpongeBlob = spongeBlob.clone();
|
|
@@ -59,14 +60,15 @@ export async function retrievedToPublishedCheckpoint({ checkpointNumber, archive
|
|
|
59
60
|
totalManaUsed: new Fr(blockEndStateField.totalManaUsed)
|
|
60
61
|
});
|
|
61
62
|
const newArchive = new AppendOnlyTreeSnapshot(newArchiveRoots[i], l2BlockNumber + 1);
|
|
62
|
-
l2Blocks.push(new
|
|
63
|
+
l2Blocks.push(new L2Block(newArchive, header, body, checkpointNumber, IndexWithinCheckpoint(i)));
|
|
63
64
|
}
|
|
64
65
|
const lastBlock = l2Blocks.at(-1);
|
|
65
66
|
const checkpoint = Checkpoint.from({
|
|
66
67
|
archive: new AppendOnlyTreeSnapshot(archiveRoot, lastBlock.number + 1),
|
|
67
68
|
header: checkpointHeader,
|
|
68
69
|
blocks: l2Blocks,
|
|
69
|
-
number: checkpointNumber
|
|
70
|
+
number: checkpointNumber,
|
|
71
|
+
feeAssetPriceModifier: feeAssetPriceModifier
|
|
70
72
|
});
|
|
71
73
|
return PublishedCheckpoint.from({
|
|
72
74
|
checkpoint,
|
|
@@ -75,242 +77,161 @@ export async function retrievedToPublishedCheckpoint({ checkpointNumber, archive
|
|
|
75
77
|
});
|
|
76
78
|
}
|
|
77
79
|
/**
|
|
78
|
-
* Fetches
|
|
80
|
+
* Fetches checkpoint calldata from the rollup contract without fetching blob data.
|
|
81
|
+
* Returns RetrievedCheckpointFromCalldata objects that preserve the information needed for deferred blob fetching.
|
|
82
|
+
* @param rollup - The rollup contract wrapper.
|
|
79
83
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
80
|
-
* @param
|
|
84
|
+
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
81
85
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
82
86
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
83
|
-
* @param
|
|
84
|
-
* @
|
|
85
|
-
|
|
87
|
+
* @param instrumentation - The archiver instrumentation instance.
|
|
88
|
+
* @param logger - The logger instance.
|
|
89
|
+
* @returns An array of calldata-only checkpoints.
|
|
90
|
+
*/ export async function retrieveCheckpointCalldataFromRollup(rollup, publicClient, debugClient, searchStartBlock, searchEndBlock, instrumentation, logger = createLogger('archiver')) {
|
|
86
91
|
const retrievedCheckpoints = [];
|
|
87
92
|
let rollupConstants;
|
|
88
93
|
do {
|
|
89
94
|
if (searchStartBlock > searchEndBlock) {
|
|
90
95
|
break;
|
|
91
96
|
}
|
|
92
|
-
const checkpointProposedLogs =
|
|
93
|
-
fromBlock: searchStartBlock,
|
|
94
|
-
toBlock: searchEndBlock
|
|
95
|
-
})).filter((log)=>log.blockNumber >= searchStartBlock && log.blockNumber <= searchEndBlock);
|
|
97
|
+
const checkpointProposedLogs = await rollup.getCheckpointProposedEvents(searchStartBlock, searchEndBlock);
|
|
96
98
|
if (checkpointProposedLogs.length === 0) {
|
|
97
99
|
break;
|
|
98
100
|
}
|
|
99
101
|
const lastLog = checkpointProposedLogs.at(-1);
|
|
100
|
-
logger.debug(`Got ${checkpointProposedLogs.length} processed logs for checkpoints
|
|
102
|
+
logger.debug(`Got ${checkpointProposedLogs.length} processed logs for checkpoints ${checkpointProposedLogs[0].args.checkpointNumber}-${lastLog.args.checkpointNumber} between L1 blocks ${searchStartBlock}-${searchEndBlock}`);
|
|
101
103
|
if (rollupConstants === undefined) {
|
|
102
104
|
const [chainId, version, targetCommitteeSize] = await Promise.all([
|
|
103
105
|
publicClient.getChainId(),
|
|
104
|
-
rollup.
|
|
105
|
-
rollup.
|
|
106
|
+
rollup.getVersion(),
|
|
107
|
+
rollup.getTargetCommitteeSize()
|
|
106
108
|
]);
|
|
107
109
|
rollupConstants = {
|
|
108
110
|
chainId: new Fr(chainId),
|
|
109
111
|
version: new Fr(version),
|
|
110
|
-
targetCommitteeSize
|
|
112
|
+
targetCommitteeSize
|
|
111
113
|
};
|
|
112
114
|
}
|
|
113
|
-
const newCheckpoints = await processCheckpointProposedLogs(rollup, publicClient,
|
|
115
|
+
const newCheckpoints = await processCheckpointProposedLogs(rollup, publicClient, debugClient, checkpointProposedLogs, rollupConstants, instrumentation, logger);
|
|
114
116
|
retrievedCheckpoints.push(...newCheckpoints);
|
|
115
|
-
searchStartBlock = lastLog.
|
|
117
|
+
searchStartBlock = lastLog.l1BlockNumber + 1n;
|
|
116
118
|
}while (searchStartBlock <= searchEndBlock)
|
|
117
|
-
// The asyncPool from processCheckpointProposedLogs will not necessarily return the checkpoints in order, so we sort them before returning.
|
|
118
119
|
return retrievedCheckpoints.sort((a, b)=>Number(a.l1.blockNumber - b.l1.blockNumber));
|
|
119
120
|
}
|
|
120
121
|
/**
|
|
121
|
-
* Processes
|
|
122
|
-
* @param rollup - The rollup contract
|
|
122
|
+
* Processes CheckpointProposed logs, fetching only calldata (no blobs).
|
|
123
|
+
* @param rollup - The rollup contract wrapper.
|
|
123
124
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
125
|
+
* @param debugClient - The viem debug client to use for trace/debug RPC methods (optional).
|
|
124
126
|
* @param logs - CheckpointProposed logs.
|
|
125
|
-
* @
|
|
126
|
-
|
|
127
|
+
* @param rollupConstants - The rollup constants (chainId, version, targetCommitteeSize).
|
|
128
|
+
* @param instrumentation - The archiver instrumentation instance.
|
|
129
|
+
* @param logger - The logger instance.
|
|
130
|
+
* @returns An array of calldata-only checkpoints.
|
|
131
|
+
*/ async function processCheckpointProposedLogs(rollup, publicClient, debugClient, logs, { chainId, version, targetCommitteeSize }, instrumentation, logger) {
|
|
127
132
|
const retrievedCheckpoints = [];
|
|
133
|
+
const calldataRetriever = new CalldataRetriever(publicClient, debugClient, targetCommitteeSize, instrumentation, logger, EthAddress.fromString(rollup.address));
|
|
128
134
|
await asyncPool(10, logs, async (log)=>{
|
|
129
|
-
const checkpointNumber =
|
|
135
|
+
const checkpointNumber = log.args.checkpointNumber;
|
|
130
136
|
const archive = log.args.archive;
|
|
131
|
-
const archiveFromChain = await rollup.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const checkpoint = await getCheckpointFromRollupTx(publicClient, blobSinkClient, log.transactionHash, blobHashes, checkpointNumber, rollup.address, targetCommitteeSize, logger);
|
|
138
|
-
const l1 = {
|
|
139
|
-
blockNumber: log.blockNumber,
|
|
140
|
-
blockHash: log.blockHash,
|
|
141
|
-
timestamp: await getL1BlockTime(publicClient, log.blockNumber)
|
|
137
|
+
const archiveFromChain = await rollup.archiveAt(checkpointNumber);
|
|
138
|
+
const blobHashes = log.args.versionedBlobHashes;
|
|
139
|
+
if (archive.equals(archiveFromChain)) {
|
|
140
|
+
const expectedHashes = {
|
|
141
|
+
attestationsHash: log.args.attestationsHash.toString(),
|
|
142
|
+
payloadDigest: log.args.payloadDigest.toString()
|
|
142
143
|
};
|
|
144
|
+
const checkpoint = await calldataRetriever.getCheckpointFromRollupTx(log.l1TransactionHash, blobHashes, checkpointNumber, expectedHashes);
|
|
145
|
+
const { timestamp, parentBeaconBlockRoot } = await getL1Block(publicClient, log.l1BlockNumber);
|
|
146
|
+
const l1 = new L1PublishedData(log.l1BlockNumber, timestamp, log.l1BlockHash.toString());
|
|
143
147
|
retrievedCheckpoints.push({
|
|
144
148
|
...checkpoint,
|
|
145
149
|
l1,
|
|
146
150
|
chainId,
|
|
147
|
-
version
|
|
151
|
+
version,
|
|
152
|
+
blobHashes,
|
|
153
|
+
parentBeaconBlockRoot
|
|
148
154
|
});
|
|
149
|
-
logger.trace(`Retrieved checkpoint ${checkpointNumber} from L1 tx ${log.
|
|
150
|
-
l1BlockNumber: log.
|
|
155
|
+
logger.trace(`Retrieved checkpoint calldata ${checkpointNumber} from L1 tx ${log.l1TransactionHash}`, {
|
|
156
|
+
l1BlockNumber: log.l1BlockNumber,
|
|
151
157
|
checkpointNumber,
|
|
152
158
|
archive: archive.toString(),
|
|
153
159
|
attestations: checkpoint.attestations
|
|
154
160
|
});
|
|
155
161
|
} else {
|
|
156
162
|
logger.warn(`Ignoring checkpoint ${checkpointNumber} due to archive root mismatch`, {
|
|
157
|
-
actual: archive,
|
|
158
|
-
expected: archiveFromChain
|
|
163
|
+
actual: archive.toString(),
|
|
164
|
+
expected: archiveFromChain.toString()
|
|
159
165
|
});
|
|
160
166
|
}
|
|
161
167
|
});
|
|
162
168
|
return retrievedCheckpoints;
|
|
163
169
|
}
|
|
164
|
-
export async function
|
|
170
|
+
export async function getL1Block(publicClient, blockNumber) {
|
|
165
171
|
const block = await publicClient.getBlock({
|
|
166
172
|
blockNumber,
|
|
167
173
|
includeTransactions: false
|
|
168
174
|
});
|
|
169
|
-
return
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
* @param multicall3Data - The multicall3 transaction input data
|
|
174
|
-
* @param rollupAddress - The address of the rollup contract
|
|
175
|
-
* @returns The calldata for the first 'propose' method call to the rollup contract
|
|
176
|
-
*/ function extractRollupProposeCalldata(multicall3Data, rollupAddress) {
|
|
177
|
-
const { functionName: multicall3FunctionName, args: multicall3Args } = decodeFunctionData({
|
|
178
|
-
abi: multicall3Abi,
|
|
179
|
-
data: multicall3Data
|
|
180
|
-
});
|
|
181
|
-
if (multicall3FunctionName !== 'aggregate3') {
|
|
182
|
-
throw new Error(`Unexpected multicall3 method called ${multicall3FunctionName}`);
|
|
183
|
-
}
|
|
184
|
-
if (multicall3Args.length !== 1) {
|
|
185
|
-
throw new Error(`Unexpected number of arguments for multicall3`);
|
|
186
|
-
}
|
|
187
|
-
const [calls] = multicall3Args;
|
|
188
|
-
// Find all rollup calls
|
|
189
|
-
const rollupAddressLower = rollupAddress.toLowerCase();
|
|
190
|
-
for(let i = 0; i < calls.length; i++){
|
|
191
|
-
const addr = calls[i].target;
|
|
192
|
-
if (addr.toLowerCase() !== rollupAddressLower) {
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
const callData = calls[i].callData;
|
|
196
|
-
try {
|
|
197
|
-
const { functionName: rollupFunctionName } = decodeFunctionData({
|
|
198
|
-
abi: RollupAbi,
|
|
199
|
-
data: callData
|
|
200
|
-
});
|
|
201
|
-
if (rollupFunctionName === 'propose') {
|
|
202
|
-
return callData;
|
|
203
|
-
}
|
|
204
|
-
} catch {
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
throw new Error(`Rollup address not found in multicall3 args`);
|
|
175
|
+
return {
|
|
176
|
+
timestamp: block.timestamp,
|
|
177
|
+
parentBeaconBlockRoot: block.parentBeaconBlockRoot
|
|
178
|
+
};
|
|
209
179
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
* @param txHash - Hash of the tx that published it.
|
|
216
|
-
* @param checkpointNumber - Checkpoint number.
|
|
217
|
-
* @returns Checkpoint from the calldata, deserialized
|
|
218
|
-
*/ async function getCheckpointFromRollupTx(publicClient, blobSinkClient, txHash, blobHashes, checkpointNumber, rollupAddress, targetCommitteeSize, logger) {
|
|
219
|
-
logger.trace(`Fetching checkpoint ${checkpointNumber} from rollup tx ${txHash}`);
|
|
220
|
-
const { input: forwarderData, blockHash } = await publicClient.getTransaction({
|
|
221
|
-
hash: txHash
|
|
222
|
-
});
|
|
223
|
-
const rollupData = extractRollupProposeCalldata(forwarderData, rollupAddress);
|
|
224
|
-
const { functionName: rollupFunctionName, args: rollupArgs } = decodeFunctionData({
|
|
225
|
-
abi: RollupAbi,
|
|
226
|
-
data: rollupData
|
|
227
|
-
});
|
|
228
|
-
if (rollupFunctionName !== 'propose') {
|
|
229
|
-
throw new Error(`Unexpected rollup method called ${rollupFunctionName}`);
|
|
230
|
-
}
|
|
231
|
-
const [decodedArgs, packedAttestations, _signers, _blobInput] = rollupArgs;
|
|
232
|
-
const attestations = CommitteeAttestation.fromPacked(packedAttestations, targetCommitteeSize);
|
|
233
|
-
logger.trace(`Recovered propose calldata from tx ${txHash}`, {
|
|
234
|
-
checkpointNumber,
|
|
235
|
-
archive: decodedArgs.archive,
|
|
236
|
-
header: decodedArgs.header,
|
|
237
|
-
l1BlockHash: blockHash,
|
|
238
|
-
blobHashes,
|
|
239
|
-
attestations,
|
|
240
|
-
packedAttestations,
|
|
241
|
-
targetCommitteeSize
|
|
180
|
+
export async function getCheckpointBlobDataFromBlobs(blobClient, blockHash, blobHashes, checkpointNumber, logger, isHistoricalSync, parentBeaconBlockRoot, l1BlockTimestamp) {
|
|
181
|
+
const blobBodies = await blobClient.getBlobSidecar(blockHash, blobHashes, {
|
|
182
|
+
isHistoricalSync,
|
|
183
|
+
parentBeaconBlockRoot,
|
|
184
|
+
l1BlockTimestamp
|
|
242
185
|
});
|
|
243
|
-
const header = CheckpointHeader.fromViem(decodedArgs.header);
|
|
244
|
-
const blobBodies = await blobSinkClient.getBlobSidecar(blockHash, blobHashes);
|
|
245
186
|
if (blobBodies.length === 0) {
|
|
246
187
|
throw new NoBlobBodiesFoundError(checkpointNumber);
|
|
247
188
|
}
|
|
248
189
|
let checkpointBlobData;
|
|
249
190
|
try {
|
|
250
191
|
// Attempt to decode the checkpoint blob data.
|
|
251
|
-
checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies
|
|
192
|
+
checkpointBlobData = decodeCheckpointBlobDataFromBlobs(blobBodies);
|
|
252
193
|
} catch (err) {
|
|
253
194
|
if (err instanceof BlobDeserializationError) {
|
|
254
195
|
logger.fatal(err.message);
|
|
255
196
|
} else {
|
|
256
197
|
logger.fatal('Unable to sync: failed to decode fetched blob, this blob was likely not created by us');
|
|
257
198
|
}
|
|
199
|
+
// Throwing an error since this is most likely caused by a bug.
|
|
258
200
|
throw err;
|
|
259
201
|
}
|
|
260
|
-
|
|
261
|
-
return {
|
|
262
|
-
checkpointNumber,
|
|
263
|
-
archiveRoot,
|
|
264
|
-
header,
|
|
265
|
-
checkpointBlobData,
|
|
266
|
-
attestations
|
|
267
|
-
};
|
|
202
|
+
return checkpointBlobData;
|
|
268
203
|
}
|
|
269
|
-
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */ export async function retrieveL1ToL2Message(inbox,
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
}, {
|
|
273
|
-
fromBlock,
|
|
274
|
-
toBlock
|
|
275
|
-
});
|
|
276
|
-
const messages = mapLogsInboxMessage(logs);
|
|
277
|
-
return messages.length > 0 ? messages[0] : undefined;
|
|
204
|
+
/** Given an L1 to L2 message, retrieves its corresponding event from the Inbox within a specific block range. */ export async function retrieveL1ToL2Message(inbox, message) {
|
|
205
|
+
const log = await inbox.getMessageSentEventByHash(message.leaf.toString(), message.l1BlockNumber);
|
|
206
|
+
return log && mapLogInboxMessage(log);
|
|
278
207
|
}
|
|
279
208
|
/**
|
|
280
209
|
* Fetch L1 to L2 messages.
|
|
281
|
-
* @param
|
|
282
|
-
* @param inboxAddress - The address of the inbox contract to fetch messages from.
|
|
283
|
-
* @param blockUntilSynced - If true, blocks until the archiver has fully synced.
|
|
210
|
+
* @param inbox - The inbox contract wrapper.
|
|
284
211
|
* @param searchStartBlock - The block number to use for starting the search.
|
|
285
212
|
* @param searchEndBlock - The highest block number that we should search up to.
|
|
286
213
|
* @returns An array of InboxLeaf and next eth block to search from.
|
|
287
214
|
*/ export async function retrieveL1ToL2Messages(inbox, searchStartBlock, searchEndBlock) {
|
|
288
215
|
const retrievedL1ToL2Messages = [];
|
|
289
216
|
while(searchStartBlock <= searchEndBlock){
|
|
290
|
-
const messageSentLogs =
|
|
291
|
-
fromBlock: searchStartBlock,
|
|
292
|
-
toBlock: searchEndBlock
|
|
293
|
-
})).filter((log)=>log.blockNumber >= searchStartBlock && log.blockNumber <= searchEndBlock);
|
|
217
|
+
const messageSentLogs = await inbox.getMessageSentEvents(searchStartBlock, searchEndBlock);
|
|
294
218
|
if (messageSentLogs.length === 0) {
|
|
295
219
|
break;
|
|
296
220
|
}
|
|
297
|
-
retrievedL1ToL2Messages.push(...
|
|
298
|
-
searchStartBlock = messageSentLogs.at(-1).
|
|
221
|
+
retrievedL1ToL2Messages.push(...messageSentLogs.map(mapLogInboxMessage));
|
|
222
|
+
searchStartBlock = messageSentLogs.at(-1).l1BlockNumber + 1n;
|
|
299
223
|
}
|
|
300
224
|
return retrievedL1ToL2Messages;
|
|
301
225
|
}
|
|
302
|
-
function
|
|
303
|
-
return
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
rollingHash: Buffer16.fromString(rollingHash)
|
|
312
|
-
};
|
|
313
|
-
});
|
|
226
|
+
function mapLogInboxMessage(log) {
|
|
227
|
+
return {
|
|
228
|
+
index: log.args.index,
|
|
229
|
+
leaf: log.args.leaf,
|
|
230
|
+
l1BlockNumber: log.l1BlockNumber,
|
|
231
|
+
l1BlockHash: log.l1BlockHash,
|
|
232
|
+
checkpointNumber: log.args.checkpointNumber,
|
|
233
|
+
rollingHash: log.args.rollingHash
|
|
234
|
+
};
|
|
314
235
|
}
|
|
315
236
|
/** Retrieves L2ProofVerified events from the rollup contract. */ export async function retrieveL2ProofVerifiedEvents(publicClient, rollupAddress, searchStartBlock, searchEndBlock) {
|
|
316
237
|
const logs = await publicClient.getLogs({
|
|
@@ -325,7 +246,7 @@ function mapLogsInboxMessage(logs) {
|
|
|
325
246
|
});
|
|
326
247
|
return logs.map((log)=>({
|
|
327
248
|
l1BlockNumber: log.blockNumber,
|
|
328
|
-
checkpointNumber:
|
|
249
|
+
checkpointNumber: CheckpointNumber.fromBigInt(log.args.checkpointNumber),
|
|
329
250
|
proverId: Fr.fromHexString(log.args.proverId),
|
|
330
251
|
txHash: log.transactionHash
|
|
331
252
|
}));
|
|
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVidWdfdHguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sMS9kZWJ1Z190eC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFXLE1BQU0sMkJBQTJCLENBQUM7QUFHakUsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR2hDLE9BQU8sS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUUzQyx1RUFBdUU7QUFDdkUsZUFBTyxNQUFNLGVBQWUsRUFBRSxNQUFNLENBQUMsY0FBYyxDQWFsRCxDQUFDO0FBRUY7Ozs7Ozs7O0dBUUc7QUFDSCx3QkFBc0IsMkJBQTJCLENBQy9DLE1BQU0sRUFBRSxxQkFBcUIsRUFDN0IsTUFBTSxFQUFFLEdBQUcsRUFDWCxhQUFhLEVBQUUsVUFBVSxFQUN6QixnQkFBZ0IsRUFBRSxNQUFNLEVBQ3hCLE1BQU0sQ0FBQyxFQUFFLE1BQU0sR0FDZCxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0F3RHJCIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug_tx.d.ts","sourceRoot":"","sources":["../../src/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
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Logger } from '@aztec/foundation/log';
|
|
2
|
+
import { type Hex, type Transaction } from 'viem';
|
|
3
|
+
export declare const SPIRE_PROPOSER_ADDRESS = "0x9ccc2f3ecde026230e11a5c8799ac7524f2bb294";
|
|
4
|
+
export declare const SPIRE_PROPOSER_EXPECTED_IMPLEMENTATION = "0x7d38d47e7c82195e6e607d3b0f1c20c615c7bf42";
|
|
5
|
+
export declare const EIP1967_IMPLEMENTATION_SLOT: "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
|
|
6
|
+
export declare const SpireProposerAbi: readonly [{
|
|
7
|
+
readonly inputs: readonly [{
|
|
8
|
+
readonly components: readonly [{
|
|
9
|
+
readonly internalType: "address";
|
|
10
|
+
readonly name: "proposer";
|
|
11
|
+
readonly type: "address";
|
|
12
|
+
}, {
|
|
13
|
+
readonly internalType: "address";
|
|
14
|
+
readonly name: "target";
|
|
15
|
+
readonly type: "address";
|
|
16
|
+
}, {
|
|
17
|
+
readonly internalType: "bytes";
|
|
18
|
+
readonly name: "data";
|
|
19
|
+
readonly type: "bytes";
|
|
20
|
+
}, {
|
|
21
|
+
readonly internalType: "uint256";
|
|
22
|
+
readonly name: "value";
|
|
23
|
+
readonly type: "uint256";
|
|
24
|
+
}, {
|
|
25
|
+
readonly internalType: "uint256";
|
|
26
|
+
readonly name: "gasLimit";
|
|
27
|
+
readonly type: "uint256";
|
|
28
|
+
}];
|
|
29
|
+
readonly internalType: "struct IProposerMulticall.Call[]";
|
|
30
|
+
readonly name: "_calls";
|
|
31
|
+
readonly type: "tuple[]";
|
|
32
|
+
}];
|
|
33
|
+
readonly name: "multicall";
|
|
34
|
+
readonly outputs: readonly [];
|
|
35
|
+
readonly stateMutability: "nonpayable";
|
|
36
|
+
readonly type: "function";
|
|
37
|
+
}];
|
|
38
|
+
/**
|
|
39
|
+
* Verifies that a proxy contract points to the expected implementation using EIP-1967.
|
|
40
|
+
* @param publicClient - The viem public client
|
|
41
|
+
* @param proxyAddress - The proxy contract address
|
|
42
|
+
* @param expectedImplementation - The expected implementation address
|
|
43
|
+
* @param logger - Logger instance
|
|
44
|
+
* @returns True if the proxy points to the expected implementation
|
|
45
|
+
*/
|
|
46
|
+
export declare function verifyProxyImplementation(publicClient: {
|
|
47
|
+
getStorageAt: (params: {
|
|
48
|
+
address: Hex;
|
|
49
|
+
slot: Hex;
|
|
50
|
+
}) => Promise<Hex | undefined>;
|
|
51
|
+
}, proxyAddress: Hex, expectedImplementation: Hex, logger: Logger): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Attempts to decode transaction as a Spire Proposer Multicall.
|
|
54
|
+
* Spire Proposer is a proxy contract that wraps multiple calls.
|
|
55
|
+
* Returns all wrapped calls if validation succeeds (caller handles hash matching to find the propose call).
|
|
56
|
+
* @param tx - The transaction to decode
|
|
57
|
+
* @param publicClient - The viem public client for proxy verification
|
|
58
|
+
* @param logger - Logger instance
|
|
59
|
+
* @returns Array of wrapped calls with 'to' and 'data', or undefined if not a valid Spire Proposer tx
|
|
60
|
+
*/
|
|
61
|
+
export declare function getCallsFromSpireProposer(tx: Transaction, publicClient: {
|
|
62
|
+
getStorageAt: (params: {
|
|
63
|
+
address: Hex;
|
|
64
|
+
slot: Hex;
|
|
65
|
+
}) => Promise<Hex | undefined>;
|
|
66
|
+
}, logger: Logger): Promise<{
|
|
67
|
+
to: Hex;
|
|
68
|
+
data: Hex;
|
|
69
|
+
}[] | undefined>;
|
|
70
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BpcmVfcHJvcG9zZXIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sMS9zcGlyZV9wcm9wb3Nlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVwRCxPQUFPLEVBQUUsS0FBSyxHQUFHLEVBQUUsS0FBSyxXQUFXLEVBQXdDLE1BQU0sTUFBTSxDQUFDO0FBR3hGLGVBQU8sTUFBTSxzQkFBc0IsK0NBQStDLENBQUM7QUFDbkYsZUFBTyxNQUFNLHNDQUFzQywrQ0FBK0MsQ0FBQztBQUluRyxlQUFPLE1BQU0sMkJBQTJCLHNFQUN1QyxDQUFDO0FBR2hGLGVBQU8sTUFBTSxnQkFBZ0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUFxQm5CLENBQUM7QUFFWDs7Ozs7OztHQU9HO0FBQ0gsd0JBQXNCLHlCQUF5QixDQUM3QyxZQUFZLEVBQUU7SUFBRSxZQUFZLEVBQUUsQ0FBQyxNQUFNLEVBQUU7UUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDO1FBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQTtLQUFFLEtBQUssT0FBTyxDQUFDLEdBQUcsR0FBRyxTQUFTLENBQUMsQ0FBQTtDQUFFLEVBQ2pHLFlBQVksRUFBRSxHQUFHLEVBQ2pCLHNCQUFzQixFQUFFLEdBQUcsRUFDM0IsTUFBTSxFQUFFLE1BQU0sR0FDYixPQUFPLENBQUMsT0FBTyxDQUFDLENBaUNsQjtBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsd0JBQXNCLHlCQUF5QixDQUM3QyxFQUFFLEVBQUUsV0FBVyxFQUNmLFlBQVksRUFBRTtJQUFFLFlBQVksRUFBRSxDQUFDLE1BQU0sRUFBRTtRQUFFLE9BQU8sRUFBRSxHQUFHLENBQUM7UUFBQyxJQUFJLEVBQUUsR0FBRyxDQUFBO0tBQUUsS0FBSyxPQUFPLENBQUMsR0FBRyxHQUFHLFNBQVMsQ0FBQyxDQUFBO0NBQUUsRUFDakcsTUFBTSxFQUFFLE1BQU0sR0FDYixPQUFPLENBQUM7SUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDO0lBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQTtDQUFFLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FvRC9DIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spire_proposer.d.ts","sourceRoot":"","sources":["../../src/l1/spire_proposer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,WAAW,EAAwC,MAAM,MAAM,CAAC;AAGxF,eAAO,MAAM,sBAAsB,+CAA+C,CAAC;AACnF,eAAO,MAAM,sCAAsC,+CAA+C,CAAC;AAInG,eAAO,MAAM,2BAA2B,sEACuC,CAAC;AAGhF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqBnB,CAAC;AAEX;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE;IAAE,YAAY,EAAE,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,GAAG,CAAA;KAAE,KAAK,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,CAAA;CAAE,EACjG,YAAY,EAAE,GAAG,EACjB,sBAAsB,EAAE,GAAG,EAC3B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CAiClB;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,WAAW,EACf,YAAY,EAAE;IAAE,YAAY,EAAE,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,GAAG,CAAA;KAAE,KAAK,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,CAAA;CAAE,EACjG,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,EAAE,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,EAAE,GAAG,SAAS,CAAC,CAoD/C"}
|