@aztec/ethereum 3.0.0-canary.a9708bd → 3.0.0-devnet.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/client.d.ts +1 -1
- package/dest/client.d.ts.map +1 -1
- package/dest/config.d.ts +11 -6
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +124 -64
- package/dest/contracts/empire_base.d.ts +1 -1
- package/dest/contracts/empire_base.d.ts.map +1 -1
- package/dest/contracts/empire_slashing_proposer.d.ts +2 -2
- package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/empire_slashing_proposer.js +1 -1
- package/dest/contracts/fee_asset_handler.d.ts +3 -3
- package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
- package/dest/contracts/governance.js +7 -3
- package/dest/contracts/governance_proposer.d.ts +1 -2
- package/dest/contracts/governance_proposer.d.ts.map +1 -1
- package/dest/contracts/governance_proposer.js +1 -2
- package/dest/contracts/multicall.d.ts +3 -5
- package/dest/contracts/multicall.d.ts.map +1 -1
- package/dest/contracts/multicall.js +6 -4
- package/dest/contracts/rollup.d.ts +39 -19
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +84 -88
- package/dest/contracts/slasher_contract.d.ts +10 -0
- package/dest/contracts/slasher_contract.d.ts.map +1 -1
- package/dest/contracts/slasher_contract.js +18 -0
- package/dest/contracts/tally_slashing_proposer.d.ts +22 -3
- package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/tally_slashing_proposer.js +55 -5
- package/dest/deploy_l1_contracts.d.ts +22 -7
- package/dest/deploy_l1_contracts.d.ts.map +1 -1
- package/dest/deploy_l1_contracts.js +555 -362
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/l1_artifacts.d.ts +8729 -6014
- package/dest/l1_artifacts.d.ts.map +1 -1
- package/dest/l1_artifacts.js +10 -5
- package/dest/l1_contract_addresses.d.ts +5 -1
- package/dest/l1_contract_addresses.d.ts.map +1 -1
- package/dest/l1_contract_addresses.js +16 -26
- package/dest/l1_reader.d.ts +1 -1
- package/dest/l1_reader.d.ts.map +1 -1
- package/dest/l1_reader.js +8 -8
- package/dest/l1_tx_utils/config.d.ts +59 -0
- package/dest/l1_tx_utils/config.d.ts.map +1 -0
- package/dest/l1_tx_utils/config.js +73 -0
- package/dest/l1_tx_utils/constants.d.ts +6 -0
- package/dest/l1_tx_utils/constants.d.ts.map +1 -0
- package/dest/l1_tx_utils/constants.js +14 -0
- package/dest/l1_tx_utils/factory.d.ts +24 -0
- package/dest/l1_tx_utils/factory.d.ts.map +1 -0
- package/dest/l1_tx_utils/factory.js +12 -0
- package/dest/l1_tx_utils/index.d.ts +10 -0
- package/dest/l1_tx_utils/index.d.ts.map +1 -0
- package/dest/l1_tx_utils/index.js +10 -0
- package/dest/l1_tx_utils/interfaces.d.ts +76 -0
- package/dest/l1_tx_utils/interfaces.d.ts.map +1 -0
- package/dest/l1_tx_utils/interfaces.js +4 -0
- package/dest/l1_tx_utils/l1_tx_utils.d.ts +95 -0
- package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/l1_tx_utils.js +610 -0
- package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +26 -0
- package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +1 -0
- package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +26 -0
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +81 -0
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/readonly_l1_tx_utils.js +294 -0
- package/dest/l1_tx_utils/signer.d.ts +4 -0
- package/dest/l1_tx_utils/signer.d.ts.map +1 -0
- package/dest/l1_tx_utils/signer.js +16 -0
- package/dest/l1_tx_utils/types.d.ts +67 -0
- package/dest/l1_tx_utils/types.d.ts.map +1 -0
- package/dest/l1_tx_utils/types.js +26 -0
- package/dest/l1_tx_utils/utils.d.ts +4 -0
- package/dest/l1_tx_utils/utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/utils.js +14 -0
- package/dest/publisher_manager.d.ts +7 -2
- package/dest/publisher_manager.d.ts.map +1 -1
- package/dest/publisher_manager.js +36 -8
- package/dest/queries.d.ts.map +1 -1
- package/dest/queries.js +11 -12
- package/dest/test/chain_monitor.d.ts +11 -0
- package/dest/test/chain_monitor.d.ts.map +1 -1
- package/dest/test/chain_monitor.js +81 -12
- package/dest/test/delayed_tx_utils.d.ts +2 -2
- package/dest/test/delayed_tx_utils.d.ts.map +1 -1
- package/dest/test/delayed_tx_utils.js +2 -2
- package/dest/test/eth_cheat_codes.d.ts +32 -6
- package/dest/test/eth_cheat_codes.d.ts.map +1 -1
- package/dest/test/eth_cheat_codes.js +115 -28
- package/dest/test/rollup_cheat_codes.d.ts +11 -9
- package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
- package/dest/test/rollup_cheat_codes.js +38 -6
- package/dest/test/upgrade_utils.d.ts.map +1 -1
- package/dest/test/upgrade_utils.js +3 -2
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +10 -161
- package/dest/zkPassportVerifierAddress.js +1 -1
- package/package.json +7 -7
- package/src/client.ts +1 -1
- package/src/config.ts +136 -68
- package/src/contracts/empire_base.ts +1 -1
- package/src/contracts/empire_slashing_proposer.ts +7 -3
- package/src/contracts/fee_asset_handler.ts +1 -1
- package/src/contracts/governance.ts +3 -3
- package/src/contracts/governance_proposer.ts +3 -4
- package/src/contracts/multicall.ts +12 -10
- package/src/contracts/rollup.ts +104 -106
- package/src/contracts/slasher_contract.ts +22 -0
- package/src/contracts/tally_slashing_proposer.ts +54 -6
- package/src/deploy_l1_contracts.ts +570 -328
- package/src/index.ts +1 -1
- package/src/l1_artifacts.ts +14 -6
- package/src/l1_contract_addresses.ts +17 -26
- package/src/l1_reader.ts +9 -9
- package/src/l1_tx_utils/README.md +177 -0
- package/src/l1_tx_utils/config.ts +140 -0
- package/src/l1_tx_utils/constants.ts +18 -0
- package/src/l1_tx_utils/factory.ts +64 -0
- package/src/l1_tx_utils/index.ts +12 -0
- package/src/l1_tx_utils/interfaces.ts +86 -0
- package/src/l1_tx_utils/l1_tx_utils.ts +718 -0
- package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +77 -0
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +372 -0
- package/src/l1_tx_utils/signer.ts +28 -0
- package/src/l1_tx_utils/types.ts +85 -0
- package/src/l1_tx_utils/utils.ts +16 -0
- package/src/publisher_manager.ts +51 -9
- package/src/queries.ts +13 -8
- package/src/test/chain_monitor.ts +89 -9
- package/src/test/delayed_tx_utils.ts +2 -2
- package/src/test/eth_cheat_codes.ts +142 -29
- package/src/test/rollup_cheat_codes.ts +54 -14
- package/src/test/upgrade_utils.ts +3 -2
- package/src/utils.ts +13 -185
- package/src/zkPassportVerifierAddress.ts +1 -1
- package/dest/l1_tx_utils.d.ts +0 -250
- package/dest/l1_tx_utils.d.ts.map +0 -1
- package/dest/l1_tx_utils.js +0 -826
- package/dest/l1_tx_utils_with_blobs.d.ts +0 -19
- package/dest/l1_tx_utils_with_blobs.d.ts.map +0 -1
- package/dest/l1_tx_utils_with_blobs.js +0 -85
- package/src/l1_tx_utils.ts +0 -1105
- package/src/l1_tx_utils_with_blobs.ts +0 -144
|
@@ -2,27 +2,34 @@ import { toBigIntBE, toHex } from '@aztec/foundation/bigint-buffer';
|
|
|
2
2
|
import { keccak256 } from '@aztec/foundation/crypto';
|
|
3
3
|
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import {
|
|
5
|
+
import { pluralize } from '@aztec/foundation/string';
|
|
6
|
+
import { createPublicClient, fallback, hexToNumber, http } from 'viem';
|
|
6
7
|
/**
|
|
7
8
|
* A class that provides utility functions for interacting with ethereum (L1).
|
|
8
9
|
*/ export class EthCheatCodes {
|
|
9
10
|
rpcUrls;
|
|
11
|
+
dateProvider;
|
|
10
12
|
logger;
|
|
11
13
|
publicClient;
|
|
12
14
|
constructor(/**
|
|
13
15
|
* The RPC URL to use for interacting with the chain
|
|
14
16
|
*/ rpcUrls, /**
|
|
17
|
+
* The date provider to use for time operations
|
|
18
|
+
*/ dateProvider, /**
|
|
15
19
|
* The logger to use for the eth cheatcodes
|
|
16
20
|
*/ logger = createLogger('ethereum:cheat_codes')){
|
|
17
21
|
this.rpcUrls = rpcUrls;
|
|
22
|
+
this.dateProvider = dateProvider;
|
|
18
23
|
this.logger = logger;
|
|
19
24
|
this.publicClient = createPublicClient({
|
|
20
25
|
transport: fallback(this.rpcUrls.map((url)=>http(url)))
|
|
21
26
|
});
|
|
22
27
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.
|
|
28
|
+
rpcCall(method, params) {
|
|
29
|
+
this.logger.debug(`Calling ${method} with params: ${jsonStringify(params)} on ${this.rpcUrls.join(', ')}`);
|
|
30
|
+
return this.doRpcCall(method, params);
|
|
31
|
+
}
|
|
32
|
+
async doRpcCall(method, params) {
|
|
26
33
|
return await this.publicClient.transport.request({
|
|
27
34
|
method,
|
|
28
35
|
params
|
|
@@ -33,7 +40,7 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
33
40
|
* @returns True if automine is on, false otherwise
|
|
34
41
|
*/ async isAutoMining() {
|
|
35
42
|
try {
|
|
36
|
-
const res = await this.
|
|
43
|
+
const res = await this.doRpcCall('anvil_getAutomine', []);
|
|
37
44
|
return res;
|
|
38
45
|
} catch (err) {
|
|
39
46
|
this.logger.error(`Calling "anvil_getAutomine" failed with:`, err);
|
|
@@ -44,21 +51,21 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
44
51
|
* Get the current blocknumber
|
|
45
52
|
* @returns The current block number
|
|
46
53
|
*/ async blockNumber() {
|
|
47
|
-
const res = await this.
|
|
54
|
+
const res = await this.doRpcCall('eth_blockNumber', []);
|
|
48
55
|
return parseInt(res, 16);
|
|
49
56
|
}
|
|
50
57
|
/**
|
|
51
58
|
* Get the current chainId
|
|
52
59
|
* @returns The current chainId
|
|
53
60
|
*/ async chainId() {
|
|
54
|
-
const res = await this.
|
|
61
|
+
const res = await this.doRpcCall('eth_chainId', []);
|
|
55
62
|
return parseInt(res, 16);
|
|
56
63
|
}
|
|
57
64
|
/**
|
|
58
65
|
* Get the current timestamp
|
|
59
66
|
* @returns The current timestamp
|
|
60
67
|
*/ async timestamp() {
|
|
61
|
-
const res = await this.
|
|
68
|
+
const res = await this.doRpcCall('eth_getBlockByNumber', [
|
|
62
69
|
'latest',
|
|
63
70
|
true
|
|
64
71
|
]);
|
|
@@ -73,7 +80,7 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
73
80
|
}
|
|
74
81
|
async doMine(numberOfBlocks = 1) {
|
|
75
82
|
try {
|
|
76
|
-
await this.
|
|
83
|
+
await this.doRpcCall('hardhat_mine', [
|
|
77
84
|
numberOfBlocks
|
|
78
85
|
]);
|
|
79
86
|
} catch (err) {
|
|
@@ -84,7 +91,8 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
84
91
|
* Mines a single block with evm_mine
|
|
85
92
|
*/ async evmMine() {
|
|
86
93
|
try {
|
|
87
|
-
await this.
|
|
94
|
+
await this.doRpcCall('evm_mine', []);
|
|
95
|
+
this.logger.warn(`Mined 1 L1 block with evm_mine`);
|
|
88
96
|
} catch (err) {
|
|
89
97
|
throw new Error(`Error mining: ${err}`);
|
|
90
98
|
}
|
|
@@ -105,7 +113,7 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
105
113
|
this.logger.warn(`Set balance for ${account} to ${balance}`);
|
|
106
114
|
}
|
|
107
115
|
async getBalance(account) {
|
|
108
|
-
const res = await this.
|
|
116
|
+
const res = await this.doRpcCall('eth_getBalance', [
|
|
109
117
|
account.toString(),
|
|
110
118
|
'latest'
|
|
111
119
|
]);
|
|
@@ -142,7 +150,7 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
142
150
|
* @param seconds - The interval to use between blocks
|
|
143
151
|
*/ getIntervalMining() {
|
|
144
152
|
try {
|
|
145
|
-
return this.
|
|
153
|
+
return this.doRpcCall('anvil_getIntervalMining', []);
|
|
146
154
|
} catch (err) {
|
|
147
155
|
throw new Error(`Error getting interval mining: ${err}`);
|
|
148
156
|
}
|
|
@@ -206,7 +214,7 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
206
214
|
/**
|
|
207
215
|
* Set the next block timestamp and mines the block.
|
|
208
216
|
* Optionally resets interval mining so the next block is mined in `blockInterval` seconds from now.
|
|
209
|
-
*
|
|
217
|
+
* Always updates the injected date provider to follow L1 time.
|
|
210
218
|
* @param timestamp - The timestamp to set the next block to
|
|
211
219
|
*/ async warp(timestamp, opts = {}) {
|
|
212
220
|
let blockInterval = null;
|
|
@@ -226,8 +234,10 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
226
234
|
]);
|
|
227
235
|
// And mine a block so the timestamp goes into effect now
|
|
228
236
|
await this.doMine();
|
|
229
|
-
// Update the date provider
|
|
230
|
-
|
|
237
|
+
// Update the injected date provider so it follows L1 time
|
|
238
|
+
if ('setTime' in this.dateProvider) {
|
|
239
|
+
this.dateProvider.setTime(Number(timestamp) * 1000);
|
|
240
|
+
}
|
|
231
241
|
} catch (err) {
|
|
232
242
|
throw new Error(`Error warping: ${err}`);
|
|
233
243
|
} finally{
|
|
@@ -260,7 +270,7 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
260
270
|
* @param contract - The contract address
|
|
261
271
|
* @param slot - The storage slot
|
|
262
272
|
* @param value - The value to set the storage slot to
|
|
263
|
-
*/ async store(contract, slot, value) {
|
|
273
|
+
*/ async store(contract, slot, value, opts = {}) {
|
|
264
274
|
// for the rpc call, we need to change value to be a 32 byte hex string.
|
|
265
275
|
try {
|
|
266
276
|
await this.rpcCall('hardhat_setStorageAt', [
|
|
@@ -271,7 +281,9 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
271
281
|
} catch (err) {
|
|
272
282
|
throw new Error(`Error setting storage for contract ${contract} at ${slot}: ${err}`);
|
|
273
283
|
}
|
|
274
|
-
|
|
284
|
+
if (!opts.silent) {
|
|
285
|
+
this.logger.warn(`Set L1 storage for contract ${contract} at ${slot} to ${value}`);
|
|
286
|
+
}
|
|
275
287
|
}
|
|
276
288
|
/**
|
|
277
289
|
* Computes the slot value for a given map and key.
|
|
@@ -333,31 +345,28 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
333
345
|
* @param contract - The contract address
|
|
334
346
|
* @returns The bytecode for the contract
|
|
335
347
|
*/ async getBytecode(contract) {
|
|
336
|
-
|
|
348
|
+
return await this.doRpcCall('eth_getCode', [
|
|
337
349
|
contract.toString(),
|
|
338
350
|
'latest'
|
|
339
351
|
]);
|
|
340
|
-
return res;
|
|
341
352
|
}
|
|
342
353
|
/**
|
|
343
354
|
* Get the raw transaction object for a given transaction hash
|
|
344
355
|
* @param txHash - The transaction hash
|
|
345
356
|
* @returns The raw transaction
|
|
346
357
|
*/ async getRawTransaction(txHash) {
|
|
347
|
-
|
|
358
|
+
return await this.doRpcCall('debug_getRawTransaction', [
|
|
348
359
|
txHash
|
|
349
360
|
]);
|
|
350
|
-
return res;
|
|
351
361
|
}
|
|
352
362
|
/**
|
|
353
363
|
* Get the trace for a given transaction hash
|
|
354
364
|
* @param txHash - The transaction hash
|
|
355
365
|
* @returns The trace
|
|
356
366
|
*/ async debugTraceTransaction(txHash) {
|
|
357
|
-
|
|
367
|
+
return await this.doRpcCall('debug_traceTransaction', [
|
|
358
368
|
txHash
|
|
359
369
|
]);
|
|
360
|
-
return res;
|
|
361
370
|
}
|
|
362
371
|
/**
|
|
363
372
|
* Triggers a reorg of the given depth, removing those blocks from the chain.
|
|
@@ -373,9 +382,6 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
373
382
|
* Causes Anvil to reorg until the given block number is the new tip
|
|
374
383
|
* @param blockNumber - The block number that's going to be the new tip
|
|
375
384
|
*/ reorgTo(blockNumber) {
|
|
376
|
-
this.logger.info('reorgTo', {
|
|
377
|
-
blockNumber
|
|
378
|
-
});
|
|
379
385
|
if (blockNumber <= 0) {
|
|
380
386
|
throw new Error(`Can't reorg to block before genesis: ${blockNumber}`);
|
|
381
387
|
}
|
|
@@ -389,6 +395,7 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
389
395
|
await this.rpcCall('anvil_rollback', [
|
|
390
396
|
depth
|
|
391
397
|
]);
|
|
398
|
+
this.logger.warn(`Reorged L1 chain to block number ${blockNumber} (depth ${depth})`);
|
|
392
399
|
});
|
|
393
400
|
}
|
|
394
401
|
/**
|
|
@@ -418,10 +425,68 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
418
425
|
});
|
|
419
426
|
}
|
|
420
427
|
traceTransaction(txHash) {
|
|
421
|
-
return this.
|
|
428
|
+
return this.doRpcCall('trace_transaction', [
|
|
422
429
|
txHash
|
|
423
430
|
]);
|
|
424
431
|
}
|
|
432
|
+
async getTxPoolStatus() {
|
|
433
|
+
const { pending, queued } = await this.doRpcCall('txpool_status', []);
|
|
434
|
+
return {
|
|
435
|
+
pending: hexToNumber(pending),
|
|
436
|
+
queued: hexToNumber(queued)
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
async getTxPoolContents() {
|
|
440
|
+
const txpoolContent = await this.doRpcCall('txpool_content', []);
|
|
441
|
+
return mapTxPoolContent(txpoolContent);
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Mines an empty block by temporarily removing all pending transactions from the mempool,
|
|
445
|
+
* mining a block, and then re-adding the transactions back to the pool.
|
|
446
|
+
*/ async mineEmptyBlock(blockCount = 1) {
|
|
447
|
+
await this.execWithPausedAnvil(async ()=>{
|
|
448
|
+
// Get all pending and queued transactions from the pool
|
|
449
|
+
const txs = await this.getTxPoolContents();
|
|
450
|
+
this.logger.debug(`Found ${txs.length} transactions in pool`);
|
|
451
|
+
// Get raw transactions before dropping them
|
|
452
|
+
const rawTxs = [];
|
|
453
|
+
for (const tx of txs){
|
|
454
|
+
try {
|
|
455
|
+
const rawTx = await this.doRpcCall('debug_getRawTransaction', [
|
|
456
|
+
tx.hash
|
|
457
|
+
]);
|
|
458
|
+
if (rawTx) {
|
|
459
|
+
rawTxs.push(rawTx);
|
|
460
|
+
this.logger.debug(`Got raw tx for ${tx.hash}`);
|
|
461
|
+
} else {
|
|
462
|
+
this.logger.warn(`No raw tx found for ${tx.hash}`);
|
|
463
|
+
}
|
|
464
|
+
} catch {
|
|
465
|
+
this.logger.warn(`Failed to get raw transaction for ${tx.hash}`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
this.logger.debug(`Retrieved ${rawTxs.length} raw transactions`);
|
|
469
|
+
// Drop all transactions from the mempool
|
|
470
|
+
await this.doRpcCall('anvil_dropAllTransactions', []);
|
|
471
|
+
// Mine an empty block
|
|
472
|
+
await this.doMine(blockCount);
|
|
473
|
+
// Re-add the transactions to the pool
|
|
474
|
+
for (const rawTx of rawTxs){
|
|
475
|
+
try {
|
|
476
|
+
const txHash = await this.doRpcCall('eth_sendRawTransaction', [
|
|
477
|
+
rawTx
|
|
478
|
+
]);
|
|
479
|
+
this.logger.debug(`Re-added transaction ${txHash}`);
|
|
480
|
+
} catch (err) {
|
|
481
|
+
this.logger.warn(`Failed to re-add transaction: ${err}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (rawTxs.length !== txs.length) {
|
|
485
|
+
this.logger.warn(`Failed to add all txs back: had ${txs.length} but re-added ${rawTxs.length}`);
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
this.logger.warn(`Mined ${blockCount} empty L1 ${pluralize('block', blockCount)}`);
|
|
489
|
+
}
|
|
425
490
|
async execWithPausedAnvil(fn) {
|
|
426
491
|
const [blockInterval, wasAutoMining] = await Promise.all([
|
|
427
492
|
this.getIntervalMining(),
|
|
@@ -438,7 +503,7 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
438
503
|
silent: true
|
|
439
504
|
});
|
|
440
505
|
}
|
|
441
|
-
await fn();
|
|
506
|
+
return await fn();
|
|
442
507
|
} finally{
|
|
443
508
|
try {
|
|
444
509
|
// restore automine if necessary
|
|
@@ -462,4 +527,26 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
462
527
|
}
|
|
463
528
|
}
|
|
464
529
|
}
|
|
530
|
+
async syncDateProvider() {
|
|
531
|
+
const timestamp = await this.timestamp();
|
|
532
|
+
if ('setTime' in this.dateProvider) {
|
|
533
|
+
this.dateProvider.setTime(timestamp * 1000);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
function mapTxPoolContent(content) {
|
|
538
|
+
const result = [];
|
|
539
|
+
const processPool = (pool, poolState)=>{
|
|
540
|
+
for (const txsByNonce of Object.values(pool)){
|
|
541
|
+
for (const tx of Object.values(txsByNonce)){
|
|
542
|
+
result.push({
|
|
543
|
+
...tx,
|
|
544
|
+
poolState
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
processPool(content.pending, 'pending');
|
|
550
|
+
processPool(content.queued, 'queued');
|
|
551
|
+
return result;
|
|
465
552
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ViemPublicClient } from '@aztec/ethereum';
|
|
2
2
|
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
3
|
-
import type {
|
|
3
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
4
4
|
import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
|
|
5
5
|
import { type GetContractReturnType, type Hex } from 'viem';
|
|
6
6
|
import { EthCheatCodes } from './eth_cheat_codes.js';
|
|
@@ -11,7 +11,7 @@ export declare class RollupCheatCodes {
|
|
|
11
11
|
private rollup;
|
|
12
12
|
private logger;
|
|
13
13
|
constructor(ethCheatCodes: EthCheatCodes, addresses: Pick<L1ContractAddresses, 'rollupAddress'>);
|
|
14
|
-
static create(rpcUrls: string[], addresses: Pick<L1ContractAddresses, 'rollupAddress'
|
|
14
|
+
static create(rpcUrls: string[], addresses: Pick<L1ContractAddresses, 'rollupAddress'>, dateProvider: DateProvider): RollupCheatCodes;
|
|
15
15
|
/** Returns the current slot */
|
|
16
16
|
getSlot(): Promise<bigint>;
|
|
17
17
|
/** Returns the current epoch */
|
|
@@ -38,15 +38,12 @@ export declare class RollupCheatCodes {
|
|
|
38
38
|
* @param epoch - The epoch to advance to
|
|
39
39
|
* @param opts - Options
|
|
40
40
|
*/
|
|
41
|
-
advanceToEpoch(epoch: bigint, opts?: {
|
|
42
|
-
/**
|
|
43
|
-
|
|
41
|
+
advanceToEpoch(epoch: bigint | number, opts?: {
|
|
42
|
+
/** Offset in seconds */
|
|
43
|
+
offset?: number;
|
|
44
44
|
}): Promise<bigint>;
|
|
45
45
|
/** Warps time in L1 until the next epoch */
|
|
46
|
-
advanceToNextEpoch(
|
|
47
|
-
/** Optional test date provider to update with the epoch timestamp */
|
|
48
|
-
updateDateProvider?: TestDateProvider;
|
|
49
|
-
}): Promise<void>;
|
|
46
|
+
advanceToNextEpoch(): Promise<void>;
|
|
50
47
|
/** Warps time in L1 until the beginning of the next slot. */
|
|
51
48
|
advanceToNextSlot(): Promise<bigint[]>;
|
|
52
49
|
/**
|
|
@@ -59,6 +56,11 @@ export declare class RollupCheatCodes {
|
|
|
59
56
|
* @param maybeBlockNumber - The block number to mark as proven (defaults to latest pending)
|
|
60
57
|
*/
|
|
61
58
|
markAsProven(maybeBlockNumber?: number | bigint): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Overrides the inProgress field of the Inbox contract state
|
|
61
|
+
* @param howMuch - How many blocks to move it forward
|
|
62
|
+
*/
|
|
63
|
+
advanceInboxInProgress(howMuch: number | bigint): Promise<bigint>;
|
|
62
64
|
/**
|
|
63
65
|
* Executes an action impersonated as the owner of the Rollup contract.
|
|
64
66
|
* @param action - The action to execute
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rollup_cheat_codes.d.ts","sourceRoot":"","sources":["../../src/test/rollup_cheat_codes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAGjF,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"rollup_cheat_codes.d.ts","sourceRoot":"","sources":["../../src/test/rollup_cheat_codes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAGjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE1D,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,GAAG,EAMT,MAAM,MAAM,CAAC;AAGd,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,8CAA8C;AAC9C,qBAAa,gBAAgB;IAOzB,OAAO,CAAC,aAAa;IANvB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAA4D;IAE1E,OAAO,CAAC,MAAM,CAAuC;gBAG3C,aAAa,EAAE,aAAa,EACpC,SAAS,EAAE,IAAI,CAAC,mBAAmB,EAAE,eAAe,CAAC;IAavD,MAAM,CAAC,MAAM,CACX,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,IAAI,CAAC,mBAAmB,EAAE,eAAe,CAAC,EACrD,YAAY,EAAE,YAAY,GACzB,gBAAgB;IAKnB,+BAA+B;IAClB,OAAO;IAKpB,gCAAgC;IACnB,QAAQ;IAKrB;;;OAGG;IACU,OAAO,IAAI,OAAO,CAAC;QAC9B,4BAA4B,CAAC,OAAO,EAAE,MAAM,CAAC;QAC7C,2BAA2B,CAAC,MAAM,EAAE,MAAM,CAAC;KAC5C,CAAC;IAQF;;OAEG;IACU,WAAW;IAmBxB,0EAA0E;IAC7D,SAAS,IAAI,OAAO,CAAC;QAChC,qBAAqB,CAAC,aAAa,EAAE,MAAM,CAAC;QAC5C,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC;KAC3C,CAAC;IAQF;;;;OAIG;IACU,cAAc,CACzB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,IAAI,GAAE;QACJ,wBAAwB;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;KACZ;IAcR,4CAA4C;IAC/B,kBAAkB;IAa/B,6DAA6D;IAChD,iBAAiB;IAQ9B;;;OAGG;IACU,YAAY,CAAC,OAAO,EAAE,MAAM;IASzC;;;OAGG;IACI,YAAY,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM;IAiCtD;;;OAGG;IACI,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqCxE;;;OAGG;IACU,OAAO,CAClB,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,qBAAqB,CAAC,OAAO,SAAS,EAAE,gBAAgB,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC;IAQ1G;;OAEG;IACU,UAAU;IASvB,4CAA4C;IAC/B,oBAAoB;IAQjC;;;OAGG;IACU,sBAAsB,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM;IAMtE;;;OAGG;IACU,qBAAqB,CAAC,QAAQ,EAAE,MAAM;CAWpD"}
|
|
@@ -23,8 +23,8 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
|
|
|
23
23
|
client: this.client
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
static create(rpcUrls, addresses) {
|
|
27
|
-
const ethCheatCodes = new EthCheatCodes(rpcUrls);
|
|
26
|
+
static create(rpcUrls, addresses, dateProvider) {
|
|
27
|
+
const ethCheatCodes = new EthCheatCodes(rpcUrls, dateProvider);
|
|
28
28
|
return new RollupCheatCodes(ethCheatCodes, addresses);
|
|
29
29
|
}
|
|
30
30
|
/** Returns the current slot */ async getSlot() {
|
|
@@ -85,8 +85,8 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
|
|
|
85
85
|
*/ async advanceToEpoch(epoch, opts = {}) {
|
|
86
86
|
const { epochDuration: slotsInEpoch } = await this.getConfig();
|
|
87
87
|
const timestamp = await this.rollup.read.getTimestampForSlot([
|
|
88
|
-
epoch * slotsInEpoch
|
|
89
|
-
]);
|
|
88
|
+
BigInt(epoch) * slotsInEpoch
|
|
89
|
+
]) + BigInt(opts.offset ?? 0);
|
|
90
90
|
try {
|
|
91
91
|
await this.ethCheatCodes.warp(Number(timestamp), {
|
|
92
92
|
...opts,
|
|
@@ -99,14 +99,13 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
|
|
|
99
99
|
}
|
|
100
100
|
return timestamp;
|
|
101
101
|
}
|
|
102
|
-
/** Warps time in L1 until the next epoch */ async advanceToNextEpoch(
|
|
102
|
+
/** Warps time in L1 until the next epoch */ async advanceToNextEpoch() {
|
|
103
103
|
const slot = await this.getSlot();
|
|
104
104
|
const { epochDuration, slotDuration } = await this.getConfig();
|
|
105
105
|
const slotsUntilNextEpoch = epochDuration - slot % epochDuration + 1n;
|
|
106
106
|
const timeToNextEpoch = slotsUntilNextEpoch * slotDuration;
|
|
107
107
|
const l1Timestamp = BigInt((await this.client.getBlock()).timestamp);
|
|
108
108
|
await this.ethCheatCodes.warp(Number(l1Timestamp + timeToNextEpoch), {
|
|
109
|
-
...opts,
|
|
110
109
|
silent: true,
|
|
111
110
|
resetBlockInterval: true
|
|
112
111
|
});
|
|
@@ -173,6 +172,39 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
|
|
|
173
172
|
});
|
|
174
173
|
}
|
|
175
174
|
/**
|
|
175
|
+
* Overrides the inProgress field of the Inbox contract state
|
|
176
|
+
* @param howMuch - How many blocks to move it forward
|
|
177
|
+
*/ advanceInboxInProgress(howMuch) {
|
|
178
|
+
return this.ethCheatCodes.execWithPausedAnvil(async ()=>{
|
|
179
|
+
// Storage slot 2 contains the InboxState struct
|
|
180
|
+
const inboxStateSlot = 2n;
|
|
181
|
+
// Get inbox and its current state values
|
|
182
|
+
const inboxAddress = await this.rollup.read.getInbox();
|
|
183
|
+
const currentStateValue = await this.ethCheatCodes.load(EthAddress.fromString(inboxAddress), inboxStateSlot);
|
|
184
|
+
// Extract current values from the packed storage slot
|
|
185
|
+
// Storage layout: rollingHash (128 bits) | totalMessagesInserted (64 bits) | inProgress (64 bits)
|
|
186
|
+
const currentRollingHash = currentStateValue & (1n << 128n) - 1n;
|
|
187
|
+
const currentTotalMessages = currentStateValue >> 128n & (1n << 64n) - 1n;
|
|
188
|
+
const currentInProgress = currentStateValue >> 192n;
|
|
189
|
+
const newInProgress = currentInProgress + BigInt(howMuch);
|
|
190
|
+
// Pack new values: rollingHash (low 128 bits) | totalMessages (middle 64 bits) | inProgress (high 64 bits)
|
|
191
|
+
const newValue = BigInt(newInProgress) << 192n | currentTotalMessages << 128n | currentRollingHash;
|
|
192
|
+
await this.ethCheatCodes.store(EthAddress.fromString(inboxAddress), inboxStateSlot, newValue, {
|
|
193
|
+
silent: true
|
|
194
|
+
});
|
|
195
|
+
this.logger.warn(`Inbox inProgress advanced from ${currentInProgress} to ${newInProgress}`, {
|
|
196
|
+
inbox: inboxAddress,
|
|
197
|
+
oldValue: '0x' + currentStateValue.toString(16),
|
|
198
|
+
newValue: '0x' + newValue.toString(16),
|
|
199
|
+
rollingHash: currentRollingHash,
|
|
200
|
+
totalMessages: currentTotalMessages,
|
|
201
|
+
oldInProgress: currentInProgress,
|
|
202
|
+
newInProgress
|
|
203
|
+
});
|
|
204
|
+
return newInProgress;
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
176
208
|
* Executes an action impersonated as the owner of the Rollup contract.
|
|
177
209
|
* @param action - The action to execute
|
|
178
210
|
*/ async asOwner(action) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade_utils.d.ts","sourceRoot":"","sources":["../../src/test/upgrade_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"upgrade_utils.d.ts","sourceRoot":"","sources":["../../src/test/upgrade_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAGlE,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAAe,MAAM,MAAM,CAAC;AAGvF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG9E,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,qBAAqB,CAAC,OAAO,aAAa,EAAE,gBAAgB,CAAC,EACzE,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,iBAAiB,EAC7B,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,iBAmCf;AAED,wBAAsB,wBAAwB,CAC5C,cAAc,EAAE,KAAK,MAAM,EAAE,EAC7B,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE,iBAAiB,EAC7B,YAAY,EAAE,gBAAgB,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IACT,UAAU,EAAE,qBAAqB,CAAC,OAAO,aAAa,EAAE,gBAAgB,CAAC,CAAC;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAyCD"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
1
2
|
import { GovernanceAbi } from '@aztec/l1-artifacts/GovernanceAbi';
|
|
2
3
|
import { TestERC20Abi as StakingAssetAbi } from '@aztec/l1-artifacts/TestERC20Abi';
|
|
3
4
|
import { getContract } from 'viem';
|
|
4
5
|
import { extractProposalIdFromLogs } from '../contracts/governance.js';
|
|
5
|
-
import { createL1TxUtilsFromViemWallet } from '../l1_tx_utils.js';
|
|
6
|
+
import { createL1TxUtilsFromViemWallet } from '../l1_tx_utils/index.js';
|
|
6
7
|
import { EthCheatCodes } from './eth_cheat_codes.js';
|
|
7
8
|
export async function executeGovernanceProposal(proposalId, governance, voteAmount, privateKey, l1Client, rpcUrls, logger) {
|
|
8
9
|
const proposal = await governance.read.getProposal([
|
|
@@ -15,7 +16,7 @@ export async function executeGovernanceProposal(proposalId, governance, voteAmou
|
|
|
15
16
|
value: 1n
|
|
16
17
|
});
|
|
17
18
|
};
|
|
18
|
-
const cheatCodes = new EthCheatCodes(rpcUrls, logger);
|
|
19
|
+
const cheatCodes = new EthCheatCodes(rpcUrls, new DateProvider(), logger);
|
|
19
20
|
const timeToActive = proposal.creation + proposal.config.votingDelay;
|
|
20
21
|
logger.info(`Warping to ${timeToActive + 1n}`);
|
|
21
22
|
await cheatCodes.warp(Number(timeToActive + 1n));
|
package/dest/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACL,KAAK,GAAG,EAER,KAAK,iBAAiB,EAEtB,KAAK,wBAAwB,EAC7B,KAAK,GAAG,EACR,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;gBAET,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE;CAKlD;AAED,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAMZ;AAED,wBAAgB,eAAe,CAC7B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,GAAG,SAAS,CAgBxB;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,OAW7C;AA0BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAE,GAAe,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACL,KAAK,GAAG,EAER,KAAK,iBAAiB,EAEtB,KAAK,wBAAwB,EAC7B,KAAK,GAAG,EACR,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;gBAET,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE;CAKlD;AAED,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAMZ;AAED,wBAAgB,eAAe,CAC7B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,GAAG,SAAS,CAgBxB;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,OAW7C;AA0BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAE,GAAe,GAAG,kBAAkB,CAwEpF;AAyBD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,sBAa7C"}
|
package/dest/utils.js
CHANGED
|
@@ -118,34 +118,16 @@ function getNestedErrorData(error) {
|
|
|
118
118
|
if (error instanceof Error) {
|
|
119
119
|
return new FormattedViemError(error.message, error?.metaMessages);
|
|
120
120
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
//
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
// If we found a specific error detail, format it clearly
|
|
134
|
-
if (errorDetail) {
|
|
135
|
-
// Look for key sections of the formatted result to replace with highlighted error
|
|
136
|
-
let replaced = false;
|
|
137
|
-
// Try to find the Details: section
|
|
138
|
-
const detailsMatch = formattedRes.match(/Details: ([^\n]+)/);
|
|
139
|
-
if (detailsMatch) {
|
|
140
|
-
formattedRes = formattedRes.replace(detailsMatch[0], `Details: *${errorDetail}*`);
|
|
141
|
-
replaced = true;
|
|
142
|
-
}
|
|
143
|
-
// If we didn't find a Details section, add the error at the beginning
|
|
144
|
-
if (!replaced) {
|
|
145
|
-
formattedRes = `Error: *${errorDetail}*\n\n${formattedRes}`;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return new FormattedViemError(formattedRes.replace(/\\n/g, '\n'), error?.metaMessages);
|
|
121
|
+
const body = String(error);
|
|
122
|
+
const length = body.length;
|
|
123
|
+
// LogExplorer can only render up to 2500 characters in it's summary view. Try to keep the whole message below this number
|
|
124
|
+
// Limit the error to 2000 chacaters in order to allow code higher up to decorate this error with extra details (up to 500 characters)
|
|
125
|
+
if (length > 2000) {
|
|
126
|
+
const chunk = 950;
|
|
127
|
+
const truncated = length - 2 * chunk;
|
|
128
|
+
return new FormattedViemError(body.slice(0, chunk) + `...${truncated} characters truncated...` + body.slice(-1 * chunk));
|
|
129
|
+
}
|
|
130
|
+
return new FormattedViemError(body);
|
|
149
131
|
}
|
|
150
132
|
function stripAbis(obj) {
|
|
151
133
|
if (!obj || typeof obj !== 'object') {
|
|
@@ -166,139 +148,6 @@ function stripAbis(obj) {
|
|
|
166
148
|
}
|
|
167
149
|
});
|
|
168
150
|
}
|
|
169
|
-
function extractAndFormatRequestBody(message) {
|
|
170
|
-
// First check if message is extremely large and contains very large hex strings
|
|
171
|
-
if (message.length > 50000) {
|
|
172
|
-
message = replaceHexStrings(message, {
|
|
173
|
-
minLength: 10000,
|
|
174
|
-
truncateLength: 200
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
// Add a specific check for RPC calls with large params
|
|
178
|
-
if (message.includes('"method":"eth_sendRawTransaction"')) {
|
|
179
|
-
message = replaceHexStrings(message, {
|
|
180
|
-
pattern: /"params":\s*\[\s*"(0x[a-fA-F0-9]{1000,})"\s*\]/g,
|
|
181
|
-
transform: (hex)=>`"params":["${truncateHex(hex, 200)}"]`
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
// First handle Request body JSON
|
|
185
|
-
const requestBodyRegex = /Request body: ({[\s\S]*?})\n/g;
|
|
186
|
-
let result = message.replace(requestBodyRegex, (match, body)=>{
|
|
187
|
-
return `Request body: ${formatRequestBody(body)}\n`;
|
|
188
|
-
});
|
|
189
|
-
// Then handle Arguments section
|
|
190
|
-
const argsRegex = /((?:Request |Estimate Gas )?Arguments:[\s\S]*?(?=\n\n|$))/g;
|
|
191
|
-
result = result.replace(argsRegex, (section)=>{
|
|
192
|
-
const lines = section.split('\n');
|
|
193
|
-
const processedLines = lines.map((line)=>{
|
|
194
|
-
// Check if line contains a colon followed by content
|
|
195
|
-
const colonIndex = line.indexOf(':');
|
|
196
|
-
if (colonIndex !== -1) {
|
|
197
|
-
const [prefix, content] = [
|
|
198
|
-
line.slice(0, colonIndex + 1),
|
|
199
|
-
line.slice(colonIndex + 1).trim()
|
|
200
|
-
];
|
|
201
|
-
// If content contains a hex string, truncate it
|
|
202
|
-
if (content.includes('0x')) {
|
|
203
|
-
const processedContent = replaceHexStrings(content);
|
|
204
|
-
return `${prefix} ${processedContent}`;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return line;
|
|
208
|
-
});
|
|
209
|
-
return processedLines.join('\n');
|
|
210
|
-
});
|
|
211
|
-
// Finally, catch any remaining hex strings in the message
|
|
212
|
-
result = replaceHexStrings(result);
|
|
213
|
-
return result;
|
|
214
|
-
}
|
|
215
|
-
function truncateHex(hex, length = 100) {
|
|
216
|
-
if (!hex || typeof hex !== 'string') {
|
|
217
|
-
return hex;
|
|
218
|
-
}
|
|
219
|
-
if (!hex.startsWith('0x')) {
|
|
220
|
-
return hex;
|
|
221
|
-
}
|
|
222
|
-
if (hex.length <= length * 2) {
|
|
223
|
-
return hex;
|
|
224
|
-
}
|
|
225
|
-
// For extremely large hex strings, use more aggressive truncation
|
|
226
|
-
if (hex.length > 10000) {
|
|
227
|
-
return `${hex.slice(0, length)}...<${hex.length - length * 2} chars omitted>...${hex.slice(-length)}`;
|
|
228
|
-
}
|
|
229
|
-
return `${hex.slice(0, length)}...${hex.slice(-length)}`;
|
|
230
|
-
}
|
|
231
|
-
function replaceHexStrings(text, options = {}) {
|
|
232
|
-
const { minLength = 10, maxLength = Infinity, truncateLength = 100, pattern, transform = (hex)=>truncateHex(hex, truncateLength) } = options;
|
|
233
|
-
const hexRegex = pattern ?? new RegExp(`(0x[a-fA-F0-9]{${minLength},${maxLength}})`, 'g');
|
|
234
|
-
return text.replace(hexRegex, (match)=>transform(match));
|
|
235
|
-
}
|
|
236
|
-
function formatRequestBody(body) {
|
|
237
|
-
try {
|
|
238
|
-
// Special handling for eth_sendRawTransaction
|
|
239
|
-
if (body.includes('"method":"eth_sendRawTransaction"')) {
|
|
240
|
-
try {
|
|
241
|
-
const parsed = JSON.parse(body);
|
|
242
|
-
if (parsed.params && Array.isArray(parsed.params) && parsed.params.length > 0) {
|
|
243
|
-
// These are likely large transaction hex strings
|
|
244
|
-
parsed.params = parsed.params.map((param)=>{
|
|
245
|
-
if (typeof param === 'string' && param.startsWith('0x') && param.length > 1000) {
|
|
246
|
-
return truncateHex(param, 200);
|
|
247
|
-
}
|
|
248
|
-
return param;
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
return JSON.stringify(parsed, null, 2);
|
|
252
|
-
} catch {
|
|
253
|
-
// If specific parsing fails, fall back to regex-based truncation
|
|
254
|
-
return replaceHexStrings(body, {
|
|
255
|
-
pattern: /"params":\s*\[\s*"(0x[a-fA-F0-9]{1000,})"\s*\]/g,
|
|
256
|
-
transform: (hex)=>`"params":["${truncateHex(hex, 200)}"]`
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
// For extremely large request bodies, use simple truncation instead of parsing
|
|
261
|
-
if (body.length > 50000) {
|
|
262
|
-
const jsonStart = body.indexOf('{');
|
|
263
|
-
const jsonEnd = body.lastIndexOf('}');
|
|
264
|
-
if (jsonStart >= 0 && jsonEnd > jsonStart) {
|
|
265
|
-
return replaceHexStrings(body, {
|
|
266
|
-
minLength: 10000,
|
|
267
|
-
truncateLength: 200
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
const parsed = JSON.parse(body);
|
|
272
|
-
// Process the entire request body
|
|
273
|
-
const processed = processParams(parsed);
|
|
274
|
-
return JSON.stringify(processed, null, 2);
|
|
275
|
-
} catch {
|
|
276
|
-
// If JSON parsing fails, do a simple truncation of any large hex strings
|
|
277
|
-
return replaceHexStrings(body, {
|
|
278
|
-
minLength: 1000,
|
|
279
|
-
truncateLength: 150
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
// Recursively process all parameters that might contain hex strings
|
|
284
|
-
function processParams(obj) {
|
|
285
|
-
if (Array.isArray(obj)) {
|
|
286
|
-
return obj.map((item)=>processParams(item));
|
|
287
|
-
}
|
|
288
|
-
if (typeof obj === 'object' && obj !== null) {
|
|
289
|
-
const result = {};
|
|
290
|
-
for (const [key, value] of Object.entries(obj)){
|
|
291
|
-
result[key] = processParams(value);
|
|
292
|
-
}
|
|
293
|
-
return result;
|
|
294
|
-
}
|
|
295
|
-
if (typeof obj === 'string') {
|
|
296
|
-
if (obj.startsWith('0x')) {
|
|
297
|
-
return truncateHex(obj);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
return obj;
|
|
301
|
-
}
|
|
302
151
|
export function tryGetCustomErrorName(err) {
|
|
303
152
|
try {
|
|
304
153
|
// See https://viem.sh/docs/contract/simulateContract#handling-custom-errors
|