@aztec/ethereum 3.0.0-canary.a9708bd → 3.0.0-devnet.20251212
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/account.d.ts +1 -1
- package/dest/chain.d.ts +1 -1
- package/dest/client.d.ts +2 -2
- package/dest/client.d.ts.map +1 -1
- package/dest/config.d.ts +16 -8
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +160 -62
- package/dest/constants.d.ts +1 -1
- package/dest/contracts/empire_base.d.ts +7 -6
- package/dest/contracts/empire_base.d.ts.map +1 -1
- package/dest/contracts/empire_base.js +1 -1
- package/dest/contracts/empire_slashing_proposer.d.ts +7 -6
- package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/empire_slashing_proposer.js +9 -3
- package/dest/contracts/errors.d.ts +1 -1
- package/dest/contracts/errors.d.ts.map +1 -1
- package/dest/contracts/fee_asset_handler.d.ts +4 -4
- package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
- package/dest/contracts/fee_juice.d.ts +1 -1
- package/dest/contracts/fee_juice.d.ts.map +1 -1
- package/dest/contracts/governance.d.ts +16 -16
- package/dest/contracts/governance.d.ts.map +1 -1
- package/dest/contracts/governance.js +7 -3
- package/dest/contracts/governance_proposer.d.ts +6 -6
- package/dest/contracts/governance_proposer.d.ts.map +1 -1
- package/dest/contracts/governance_proposer.js +9 -4
- package/dest/contracts/gse.d.ts +1 -1
- package/dest/contracts/gse.d.ts.map +1 -1
- package/dest/contracts/inbox.d.ts +1 -1
- package/dest/contracts/inbox.d.ts.map +1 -1
- package/dest/contracts/index.d.ts +1 -1
- package/dest/contracts/multicall.d.ts +5 -7
- package/dest/contracts/multicall.d.ts.map +1 -1
- package/dest/contracts/multicall.js +6 -4
- package/dest/contracts/registry.d.ts +1 -1
- package/dest/contracts/registry.d.ts.map +1 -1
- package/dest/contracts/rollup.d.ts +83 -72
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +144 -139
- package/dest/contracts/slasher_contract.d.ts +11 -1
- 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 +30 -9
- package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/tally_slashing_proposer.js +58 -8
- package/dest/contracts/utils.d.ts +1 -1
- package/dest/deploy_l1_contracts.d.ts +477 -15
- package/dest/deploy_l1_contracts.d.ts.map +1 -1
- package/dest/deploy_l1_contracts.js +610 -386
- package/dest/eth-signer/eth-signer.d.ts +1 -1
- package/dest/eth-signer/index.d.ts +1 -1
- package/dest/forwarder_proxy.d.ts +32 -0
- package/dest/forwarder_proxy.d.ts.map +1 -0
- package/dest/forwarder_proxy.js +93 -0
- package/dest/l1_artifacts.d.ts +14258 -6015
- package/dest/l1_artifacts.d.ts.map +1 -1
- package/dest/l1_artifacts.js +10 -5
- package/dest/l1_contract_addresses.d.ts +8 -4
- package/dest/l1_contract_addresses.d.ts.map +1 -1
- package/dest/l1_contract_addresses.js +16 -26
- package/dest/l1_reader.d.ts +4 -2
- package/dest/l1_reader.d.ts.map +1 -1
- package/dest/l1_reader.js +14 -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 +96 -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/forwarder_l1_tx_utils.d.ts +41 -0
- package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +48 -0
- package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
- package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
- package/dest/l1_tx_utils/index-blobs.js +2 -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 +94 -0
- package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/l1_tx_utils.js +623 -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 +94 -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 +431 -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/l1_types.d.ts +1 -1
- package/dest/publisher_manager.d.ts +8 -3
- package/dest/publisher_manager.d.ts.map +1 -1
- package/dest/publisher_manager.js +36 -8
- package/dest/queries.d.ts +1 -1
- package/dest/queries.d.ts.map +1 -1
- package/dest/queries.js +13 -12
- package/dest/test/chain_monitor.d.ts +33 -19
- package/dest/test/chain_monitor.d.ts.map +1 -1
- package/dest/test/chain_monitor.js +100 -33
- package/dest/test/delayed_tx_utils.d.ts +3 -3
- 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 +36 -14
- package/dest/test/eth_cheat_codes.d.ts.map +1 -1
- package/dest/test/eth_cheat_codes.js +124 -31
- package/dest/test/eth_cheat_codes_with_state.d.ts +1 -1
- package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -1
- package/dest/test/index.d.ts +1 -1
- package/dest/test/rollup_cheat_codes.d.ts +23 -20
- package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
- package/dest/test/rollup_cheat_codes.js +79 -42
- package/dest/test/start_anvil.d.ts +2 -1
- package/dest/test/start_anvil.d.ts.map +1 -1
- package/dest/test/start_anvil.js +2 -1
- package/dest/test/tx_delayer.d.ts +1 -1
- package/dest/test/tx_delayer.d.ts.map +1 -1
- package/dest/test/tx_delayer.js +3 -2
- package/dest/test/upgrade_utils.d.ts +1 -1
- package/dest/test/upgrade_utils.d.ts.map +1 -1
- package/dest/test/upgrade_utils.js +3 -2
- package/dest/types.d.ts +57 -2
- package/dest/types.d.ts.map +1 -1
- package/dest/utils.d.ts +2 -2
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +10 -161
- package/dest/zkPassportVerifierAddress.d.ts +1 -1
- package/dest/zkPassportVerifierAddress.js +1 -1
- package/package.json +27 -13
- package/src/client.ts +1 -1
- package/src/config.ts +177 -65
- package/src/contracts/empire_base.ts +7 -6
- package/src/contracts/empire_slashing_proposer.ts +18 -8
- package/src/contracts/fee_asset_handler.ts +1 -1
- package/src/contracts/governance.ts +3 -3
- package/src/contracts/governance_proposer.ts +14 -9
- package/src/contracts/multicall.ts +12 -10
- package/src/contracts/rollup.ts +170 -171
- package/src/contracts/slasher_contract.ts +22 -0
- package/src/contracts/tally_slashing_proposer.ts +63 -12
- package/src/deploy_l1_contracts.ts +610 -337
- package/src/forwarder_proxy.ts +108 -0
- package/src/l1_artifacts.ts +14 -6
- package/src/l1_contract_addresses.ts +17 -26
- package/src/l1_reader.ts +17 -9
- package/src/l1_tx_utils/README.md +177 -0
- package/src/l1_tx_utils/config.ts +161 -0
- package/src/l1_tx_utils/constants.ts +18 -0
- package/src/l1_tx_utils/factory.ts +64 -0
- package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +119 -0
- package/src/l1_tx_utils/index-blobs.ts +2 -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 +738 -0
- package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +77 -0
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +557 -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 +16 -8
- package/src/test/chain_monitor.ts +118 -36
- package/src/test/delayed_tx_utils.ts +2 -2
- package/src/test/eth_cheat_codes.ts +149 -30
- package/src/test/rollup_cheat_codes.ts +94 -52
- package/src/test/start_anvil.ts +2 -0
- package/src/test/tx_delayer.ts +4 -2
- package/src/test/upgrade_utils.ts +3 -2
- package/src/types.ts +62 -0
- package/src/utils.ts +12 -184
- package/src/zkPassportVerifierAddress.ts +1 -1
- package/dest/index.d.ts +0 -18
- package/dest/index.d.ts.map +0 -1
- package/dest/index.js +0 -17
- 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/index.ts +0 -17
- package/src/l1_tx_utils.ts +0 -1105
- package/src/l1_tx_utils_with_blobs.ts +0 -144
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { toBigIntBE, toHex } from '@aztec/foundation/bigint-buffer';
|
|
2
|
-
import { keccak256 } from '@aztec/foundation/crypto';
|
|
2
|
+
import { keccak256 } from '@aztec/foundation/crypto/keccak';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
|
-
import
|
|
6
|
+
import { pluralize } from '@aztec/foundation/string';
|
|
7
|
+
import type { DateProvider, TestDateProvider } from '@aztec/foundation/timer';
|
|
7
8
|
|
|
8
|
-
import { type Hex, createPublicClient, fallback, http } from 'viem';
|
|
9
|
+
import { type Chain, type Hex, type Transaction, createPublicClient, fallback, hexToNumber, http } from 'viem';
|
|
10
|
+
import { foundry } from 'viem/chains';
|
|
9
11
|
|
|
10
12
|
import type { ViemPublicClient } from '../types.js';
|
|
11
13
|
|
|
@@ -19,19 +21,31 @@ export class EthCheatCodes {
|
|
|
19
21
|
* The RPC URL to use for interacting with the chain
|
|
20
22
|
*/
|
|
21
23
|
public rpcUrls: string[],
|
|
24
|
+
/**
|
|
25
|
+
* The date provider to use for time operations
|
|
26
|
+
*/
|
|
27
|
+
public dateProvider: DateProvider | TestDateProvider,
|
|
22
28
|
/**
|
|
23
29
|
* The logger to use for the eth cheatcodes
|
|
24
30
|
*/
|
|
25
31
|
public logger = createLogger('ethereum:cheat_codes'),
|
|
32
|
+
/**
|
|
33
|
+
* The chain configuration provided to Anvil
|
|
34
|
+
*/
|
|
35
|
+
public chain: Chain = foundry,
|
|
26
36
|
) {
|
|
27
37
|
this.publicClient = createPublicClient({
|
|
28
38
|
transport: fallback(this.rpcUrls.map(url => http(url))),
|
|
39
|
+
chain: chain,
|
|
29
40
|
});
|
|
30
41
|
}
|
|
31
42
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.
|
|
43
|
+
public rpcCall(method: string, params: any[]) {
|
|
44
|
+
this.logger.debug(`Calling ${method} with params: ${jsonStringify(params)} on ${this.rpcUrls.join(', ')}`);
|
|
45
|
+
return this.doRpcCall(method, params);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private async doRpcCall(method: string, params: any[]) {
|
|
35
49
|
return (await this.publicClient.transport.request({
|
|
36
50
|
method,
|
|
37
51
|
params,
|
|
@@ -44,7 +58,7 @@ export class EthCheatCodes {
|
|
|
44
58
|
*/
|
|
45
59
|
public async isAutoMining(): Promise<boolean> {
|
|
46
60
|
try {
|
|
47
|
-
const res = await this.
|
|
61
|
+
const res = await this.doRpcCall('anvil_getAutomine', []);
|
|
48
62
|
return res;
|
|
49
63
|
} catch (err) {
|
|
50
64
|
this.logger.error(`Calling "anvil_getAutomine" failed with:`, err);
|
|
@@ -57,7 +71,7 @@ export class EthCheatCodes {
|
|
|
57
71
|
* @returns The current block number
|
|
58
72
|
*/
|
|
59
73
|
public async blockNumber(): Promise<number> {
|
|
60
|
-
const res = await this.
|
|
74
|
+
const res = await this.doRpcCall('eth_blockNumber', []);
|
|
61
75
|
return parseInt(res, 16);
|
|
62
76
|
}
|
|
63
77
|
|
|
@@ -66,7 +80,7 @@ export class EthCheatCodes {
|
|
|
66
80
|
* @returns The current chainId
|
|
67
81
|
*/
|
|
68
82
|
public async chainId(): Promise<number> {
|
|
69
|
-
const res = await this.
|
|
83
|
+
const res = await this.doRpcCall('eth_chainId', []);
|
|
70
84
|
return parseInt(res, 16);
|
|
71
85
|
}
|
|
72
86
|
|
|
@@ -75,7 +89,7 @@ export class EthCheatCodes {
|
|
|
75
89
|
* @returns The current timestamp
|
|
76
90
|
*/
|
|
77
91
|
public async timestamp(): Promise<number> {
|
|
78
|
-
const res = await this.
|
|
92
|
+
const res = await this.doRpcCall('eth_getBlockByNumber', ['latest', true]);
|
|
79
93
|
return parseInt(res.timestamp, 16);
|
|
80
94
|
}
|
|
81
95
|
|
|
@@ -90,7 +104,7 @@ export class EthCheatCodes {
|
|
|
90
104
|
|
|
91
105
|
private async doMine(numberOfBlocks = 1): Promise<void> {
|
|
92
106
|
try {
|
|
93
|
-
await this.
|
|
107
|
+
await this.doRpcCall('hardhat_mine', [numberOfBlocks]);
|
|
94
108
|
} catch (err) {
|
|
95
109
|
throw new Error(`Error mining: ${err}`);
|
|
96
110
|
}
|
|
@@ -101,7 +115,8 @@ export class EthCheatCodes {
|
|
|
101
115
|
*/
|
|
102
116
|
public async evmMine(): Promise<void> {
|
|
103
117
|
try {
|
|
104
|
-
await this.
|
|
118
|
+
await this.doRpcCall('evm_mine', []);
|
|
119
|
+
this.logger.warn(`Mined 1 L1 block with evm_mine`);
|
|
105
120
|
} catch (err) {
|
|
106
121
|
throw new Error(`Error mining: ${err}`);
|
|
107
122
|
}
|
|
@@ -122,7 +137,7 @@ export class EthCheatCodes {
|
|
|
122
137
|
}
|
|
123
138
|
|
|
124
139
|
public async getBalance(account: EthAddress | Hex): Promise<bigint> {
|
|
125
|
-
const res = await this.
|
|
140
|
+
const res = await this.doRpcCall('eth_getBalance', [account.toString(), 'latest']);
|
|
126
141
|
return BigInt(res);
|
|
127
142
|
}
|
|
128
143
|
|
|
@@ -158,7 +173,7 @@ export class EthCheatCodes {
|
|
|
158
173
|
*/
|
|
159
174
|
public getIntervalMining(): Promise<number | null> {
|
|
160
175
|
try {
|
|
161
|
-
return this.
|
|
176
|
+
return this.doRpcCall('anvil_getIntervalMining', []);
|
|
162
177
|
} catch (err) {
|
|
163
178
|
throw new Error(`Error getting interval mining: ${err}`);
|
|
164
179
|
}
|
|
@@ -225,12 +240,12 @@ export class EthCheatCodes {
|
|
|
225
240
|
/**
|
|
226
241
|
* Set the next block timestamp and mines the block.
|
|
227
242
|
* Optionally resets interval mining so the next block is mined in `blockInterval` seconds from now.
|
|
228
|
-
*
|
|
243
|
+
* Always updates the injected date provider to follow L1 time.
|
|
229
244
|
* @param timestamp - The timestamp to set the next block to
|
|
230
245
|
*/
|
|
231
246
|
public async warp(
|
|
232
247
|
timestamp: number | bigint,
|
|
233
|
-
opts: { silent?: boolean; resetBlockInterval?: boolean
|
|
248
|
+
opts: { silent?: boolean; resetBlockInterval?: boolean } = {},
|
|
234
249
|
): Promise<void> {
|
|
235
250
|
let blockInterval: number | null = null;
|
|
236
251
|
try {
|
|
@@ -245,8 +260,10 @@ export class EthCheatCodes {
|
|
|
245
260
|
await this.rpcCall('evm_setNextBlockTimestamp', [Number(timestamp)]);
|
|
246
261
|
// And mine a block so the timestamp goes into effect now
|
|
247
262
|
await this.doMine();
|
|
248
|
-
// Update the date provider
|
|
249
|
-
|
|
263
|
+
// Update the injected date provider so it follows L1 time
|
|
264
|
+
if ('setTime' in this.dateProvider) {
|
|
265
|
+
this.dateProvider.setTime(Number(timestamp) * 1000);
|
|
266
|
+
}
|
|
250
267
|
} catch (err) {
|
|
251
268
|
throw new Error(`Error warping: ${err}`);
|
|
252
269
|
} finally {
|
|
@@ -277,14 +294,21 @@ export class EthCheatCodes {
|
|
|
277
294
|
* @param slot - The storage slot
|
|
278
295
|
* @param value - The value to set the storage slot to
|
|
279
296
|
*/
|
|
280
|
-
public async store(
|
|
297
|
+
public async store(
|
|
298
|
+
contract: EthAddress,
|
|
299
|
+
slot: bigint,
|
|
300
|
+
value: bigint,
|
|
301
|
+
opts: { silent?: boolean } = {},
|
|
302
|
+
): Promise<void> {
|
|
281
303
|
// for the rpc call, we need to change value to be a 32 byte hex string.
|
|
282
304
|
try {
|
|
283
305
|
await this.rpcCall('hardhat_setStorageAt', [contract.toString(), toHex(slot), toHex(value, true)]);
|
|
284
306
|
} catch (err) {
|
|
285
307
|
throw new Error(`Error setting storage for contract ${contract} at ${slot}: ${err}`);
|
|
286
308
|
}
|
|
287
|
-
|
|
309
|
+
if (!opts.silent) {
|
|
310
|
+
this.logger.warn(`Set L1 storage for contract ${contract} at ${slot} to ${value}`);
|
|
311
|
+
}
|
|
288
312
|
}
|
|
289
313
|
|
|
290
314
|
/**
|
|
@@ -350,8 +374,7 @@ export class EthCheatCodes {
|
|
|
350
374
|
* @returns The bytecode for the contract
|
|
351
375
|
*/
|
|
352
376
|
public async getBytecode(contract: EthAddress): Promise<`0x${string}`> {
|
|
353
|
-
|
|
354
|
-
return res;
|
|
377
|
+
return await this.doRpcCall('eth_getCode', [contract.toString(), 'latest']);
|
|
355
378
|
}
|
|
356
379
|
|
|
357
380
|
/**
|
|
@@ -360,8 +383,7 @@ export class EthCheatCodes {
|
|
|
360
383
|
* @returns The raw transaction
|
|
361
384
|
*/
|
|
362
385
|
public async getRawTransaction(txHash: Hex): Promise<`0x${string}`> {
|
|
363
|
-
|
|
364
|
-
return res;
|
|
386
|
+
return await this.doRpcCall('debug_getRawTransaction', [txHash]);
|
|
365
387
|
}
|
|
366
388
|
|
|
367
389
|
/**
|
|
@@ -370,8 +392,7 @@ export class EthCheatCodes {
|
|
|
370
392
|
* @returns The trace
|
|
371
393
|
*/
|
|
372
394
|
public async debugTraceTransaction(txHash: Hex): Promise<any> {
|
|
373
|
-
|
|
374
|
-
return res;
|
|
395
|
+
return await this.doRpcCall('debug_traceTransaction', [txHash]);
|
|
375
396
|
}
|
|
376
397
|
|
|
377
398
|
/**
|
|
@@ -389,7 +410,6 @@ export class EthCheatCodes {
|
|
|
389
410
|
* @param blockNumber - The block number that's going to be the new tip
|
|
390
411
|
*/
|
|
391
412
|
public reorgTo(blockNumber: number): Promise<void> {
|
|
392
|
-
this.logger.info('reorgTo', { blockNumber });
|
|
393
413
|
if (blockNumber <= 0) {
|
|
394
414
|
throw new Error(`Can't reorg to block before genesis: ${blockNumber}`);
|
|
395
415
|
}
|
|
@@ -405,6 +425,7 @@ export class EthCheatCodes {
|
|
|
405
425
|
|
|
406
426
|
const depth = Number(currentTip - BigInt(blockNumber) + 1n);
|
|
407
427
|
await this.rpcCall('anvil_rollback', [depth]);
|
|
428
|
+
this.logger.warn(`Reorged L1 chain to block number ${blockNumber} (depth ${depth})`);
|
|
408
429
|
});
|
|
409
430
|
}
|
|
410
431
|
|
|
@@ -431,10 +452,73 @@ export class EthCheatCodes {
|
|
|
431
452
|
}
|
|
432
453
|
|
|
433
454
|
public traceTransaction(txHash: Hex): Promise<any> {
|
|
434
|
-
return this.
|
|
455
|
+
return this.doRpcCall('trace_transaction', [txHash]);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
public async getTxPoolStatus(): Promise<{ pending: number; queued: number }> {
|
|
459
|
+
const { pending, queued } = await this.doRpcCall('txpool_status', []);
|
|
460
|
+
return { pending: hexToNumber(pending), queued: hexToNumber(queued) };
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
public async getTxPoolContents(): Promise<TxPoolTransaction[]> {
|
|
464
|
+
const txpoolContent = await this.doRpcCall('txpool_content', []);
|
|
465
|
+
return mapTxPoolContent(txpoolContent);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Mines an empty block by temporarily removing all pending transactions from the mempool,
|
|
470
|
+
* mining a block, and then re-adding the transactions back to the pool.
|
|
471
|
+
*/
|
|
472
|
+
public async mineEmptyBlock(blockCount: number = 1): Promise<void> {
|
|
473
|
+
await this.execWithPausedAnvil(async () => {
|
|
474
|
+
// Get all pending and queued transactions from the pool
|
|
475
|
+
const txs = await this.getTxPoolContents();
|
|
476
|
+
|
|
477
|
+
this.logger.debug(`Found ${txs.length} transactions in pool`);
|
|
478
|
+
|
|
479
|
+
// Get raw transactions before dropping them
|
|
480
|
+
const rawTxs: Hex[] = [];
|
|
481
|
+
for (const tx of txs) {
|
|
482
|
+
try {
|
|
483
|
+
const rawTx = await this.doRpcCall('debug_getRawTransaction', [tx.hash]);
|
|
484
|
+
if (rawTx) {
|
|
485
|
+
rawTxs.push(rawTx);
|
|
486
|
+
this.logger.debug(`Got raw tx for ${tx.hash}`);
|
|
487
|
+
} else {
|
|
488
|
+
this.logger.warn(`No raw tx found for ${tx.hash}`);
|
|
489
|
+
}
|
|
490
|
+
} catch {
|
|
491
|
+
this.logger.warn(`Failed to get raw transaction for ${tx.hash}`);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
this.logger.debug(`Retrieved ${rawTxs.length} raw transactions`);
|
|
496
|
+
|
|
497
|
+
// Drop all transactions from the mempool
|
|
498
|
+
await this.doRpcCall('anvil_dropAllTransactions', []);
|
|
499
|
+
|
|
500
|
+
// Mine an empty block
|
|
501
|
+
await this.doMine(blockCount);
|
|
502
|
+
|
|
503
|
+
// Re-add the transactions to the pool
|
|
504
|
+
for (const rawTx of rawTxs) {
|
|
505
|
+
try {
|
|
506
|
+
const txHash = await this.doRpcCall('eth_sendRawTransaction', [rawTx]);
|
|
507
|
+
this.logger.debug(`Re-added transaction ${txHash}`);
|
|
508
|
+
} catch (err) {
|
|
509
|
+
this.logger.warn(`Failed to re-add transaction: ${err}`);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (rawTxs.length !== txs.length) {
|
|
514
|
+
this.logger.warn(`Failed to add all txs back: had ${txs.length} but re-added ${rawTxs.length}`);
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
this.logger.warn(`Mined ${blockCount} empty L1 ${pluralize('block', blockCount)}`);
|
|
435
519
|
}
|
|
436
520
|
|
|
437
|
-
public async execWithPausedAnvil(fn: () => Promise<
|
|
521
|
+
public async execWithPausedAnvil<T>(fn: () => Promise<T>): Promise<T> {
|
|
438
522
|
const [blockInterval, wasAutoMining] = await Promise.all([this.getIntervalMining(), this.isAutoMining()]);
|
|
439
523
|
try {
|
|
440
524
|
if (blockInterval !== null) {
|
|
@@ -445,7 +529,7 @@ export class EthCheatCodes {
|
|
|
445
529
|
await this.setAutomine(false, { silent: true });
|
|
446
530
|
}
|
|
447
531
|
|
|
448
|
-
await fn();
|
|
532
|
+
return await fn();
|
|
449
533
|
} finally {
|
|
450
534
|
try {
|
|
451
535
|
// restore automine if necessary
|
|
@@ -466,4 +550,39 @@ export class EthCheatCodes {
|
|
|
466
550
|
}
|
|
467
551
|
}
|
|
468
552
|
}
|
|
553
|
+
|
|
554
|
+
public async syncDateProvider() {
|
|
555
|
+
const timestamp = await this.timestamp();
|
|
556
|
+
if ('setTime' in this.dateProvider) {
|
|
557
|
+
this.dateProvider.setTime(timestamp * 1000);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
type TxPoolState = 'pending' | 'queued';
|
|
563
|
+
|
|
564
|
+
interface TxPoolContent {
|
|
565
|
+
pending: Record<Hex, Record<string, Transaction>>;
|
|
566
|
+
queued: Record<Hex, Record<string, Transaction>>;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
export type TxPoolTransaction = Transaction & {
|
|
570
|
+
poolState: TxPoolState;
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
function mapTxPoolContent(content: TxPoolContent): TxPoolTransaction[] {
|
|
574
|
+
const result: TxPoolTransaction[] = [];
|
|
575
|
+
|
|
576
|
+
const processPool = (pool: Record<Hex, Record<string, Transaction>>, poolState: TxPoolState) => {
|
|
577
|
+
for (const txsByNonce of Object.values(pool)) {
|
|
578
|
+
for (const tx of Object.values(txsByNonce)) {
|
|
579
|
+
result.push({ ...tx, poolState });
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
processPool(content.pending, 'pending');
|
|
585
|
+
processPool(content.queued, 'queued');
|
|
586
|
+
|
|
587
|
+
return result;
|
|
469
588
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { RollupContract
|
|
1
|
+
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
2
2
|
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
3
|
+
import type { ViemPublicClient } from '@aztec/ethereum/types';
|
|
4
|
+
import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
6
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import type {
|
|
7
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
6
8
|
import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
|
|
7
9
|
|
|
8
10
|
import {
|
|
@@ -14,7 +16,6 @@ import {
|
|
|
14
16
|
hexToBigInt,
|
|
15
17
|
http,
|
|
16
18
|
} from 'viem';
|
|
17
|
-
import { foundry } from 'viem/chains';
|
|
18
19
|
|
|
19
20
|
import { EthCheatCodes } from './eth_cheat_codes.js';
|
|
20
21
|
|
|
@@ -30,7 +31,7 @@ export class RollupCheatCodes {
|
|
|
30
31
|
addresses: Pick<L1ContractAddresses, 'rollupAddress'>,
|
|
31
32
|
) {
|
|
32
33
|
this.client = createPublicClient({
|
|
33
|
-
chain:
|
|
34
|
+
chain: ethCheatCodes.chain,
|
|
34
35
|
transport: fallback(ethCheatCodes.rpcUrls.map(url => http(url))),
|
|
35
36
|
});
|
|
36
37
|
this.rollup = getContract({
|
|
@@ -40,21 +41,25 @@ export class RollupCheatCodes {
|
|
|
40
41
|
});
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
static create(
|
|
44
|
-
|
|
44
|
+
static create(
|
|
45
|
+
rpcUrls: string[],
|
|
46
|
+
addresses: Pick<L1ContractAddresses, 'rollupAddress'>,
|
|
47
|
+
dateProvider: DateProvider,
|
|
48
|
+
): RollupCheatCodes {
|
|
49
|
+
const ethCheatCodes = new EthCheatCodes(rpcUrls, dateProvider);
|
|
45
50
|
return new RollupCheatCodes(ethCheatCodes, addresses);
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
/** Returns the current slot */
|
|
49
|
-
public async getSlot() {
|
|
54
|
+
public async getSlot(): Promise<SlotNumber> {
|
|
50
55
|
const ts = BigInt((await this.client.getBlock()).timestamp);
|
|
51
|
-
return await this.rollup.read.getSlotAt([ts]);
|
|
56
|
+
return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([ts]));
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
/** Returns the current epoch */
|
|
55
|
-
public async getEpoch() {
|
|
60
|
+
public async getEpoch(): Promise<EpochNumber> {
|
|
56
61
|
const slotNumber = await this.getSlot();
|
|
57
|
-
return await this.rollup.read.getEpochAtSlot([slotNumber]);
|
|
62
|
+
return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/**
|
|
@@ -62,13 +67,13 @@ export class RollupCheatCodes {
|
|
|
62
67
|
* @returns The pending and proven chain tips
|
|
63
68
|
*/
|
|
64
69
|
public async getTips(): Promise<{
|
|
65
|
-
/** The pending chain tip */ pending:
|
|
66
|
-
/** The proven chain tip */ proven:
|
|
70
|
+
/** The pending chain tip */ pending: CheckpointNumber;
|
|
71
|
+
/** The proven chain tip */ proven: CheckpointNumber;
|
|
67
72
|
}> {
|
|
68
|
-
const
|
|
73
|
+
const { pending, proven } = await this.rollup.read.getTips();
|
|
69
74
|
return {
|
|
70
|
-
pending:
|
|
71
|
-
proven:
|
|
75
|
+
pending: CheckpointNumber.fromBigInt(pending),
|
|
76
|
+
proven: CheckpointNumber.fromBigInt(proven),
|
|
72
77
|
};
|
|
73
78
|
}
|
|
74
79
|
|
|
@@ -77,16 +82,16 @@ export class RollupCheatCodes {
|
|
|
77
82
|
*/
|
|
78
83
|
public async debugRollup() {
|
|
79
84
|
const rollup = new RollupContract(this.client, this.rollup.address);
|
|
80
|
-
const pendingNum = await rollup.
|
|
81
|
-
const provenNum = await rollup.
|
|
85
|
+
const pendingNum = await rollup.getCheckpointNumber();
|
|
86
|
+
const provenNum = await rollup.getProvenCheckpointNumber();
|
|
82
87
|
const validators = await rollup.getAttesters();
|
|
83
88
|
const committee = await rollup.getCurrentEpochCommittee();
|
|
84
89
|
const archive = await rollup.archive();
|
|
85
90
|
const slot = await this.getSlot();
|
|
86
91
|
const epochNum = await rollup.getEpochNumberForSlotNumber(slot);
|
|
87
92
|
|
|
88
|
-
this.logger.info(`Pending
|
|
89
|
-
this.logger.info(`Proven
|
|
93
|
+
this.logger.info(`Pending checkpoint num: ${pendingNum}`);
|
|
94
|
+
this.logger.info(`Proven checkpoint num: ${provenNum}`);
|
|
90
95
|
this.logger.info(`Validators: ${validators.map(v => v.toString()).join(', ')}`);
|
|
91
96
|
this.logger.info(`Committee: ${committee?.map(v => v.toString()).join(', ')}`);
|
|
92
97
|
this.logger.info(`Archive: ${archive}`);
|
|
@@ -97,13 +102,13 @@ export class RollupCheatCodes {
|
|
|
97
102
|
/** Fetches the epoch and slot duration config from the rollup contract */
|
|
98
103
|
public async getConfig(): Promise<{
|
|
99
104
|
/** Epoch duration */ epochDuration: bigint;
|
|
100
|
-
/** Slot duration */ slotDuration:
|
|
105
|
+
/** Slot duration */ slotDuration: number;
|
|
101
106
|
}> {
|
|
102
107
|
const [epochDuration, slotDuration] = await Promise.all([
|
|
103
108
|
this.rollup.read.getEpochDuration(),
|
|
104
109
|
this.rollup.read.getSlotDuration(),
|
|
105
110
|
]);
|
|
106
|
-
return { epochDuration, slotDuration };
|
|
111
|
+
return { epochDuration, slotDuration: Number(slotDuration) };
|
|
107
112
|
}
|
|
108
113
|
|
|
109
114
|
/**
|
|
@@ -112,17 +117,18 @@ export class RollupCheatCodes {
|
|
|
112
117
|
* @param opts - Options
|
|
113
118
|
*/
|
|
114
119
|
public async advanceToEpoch(
|
|
115
|
-
epoch:
|
|
120
|
+
epoch: EpochNumber,
|
|
116
121
|
opts: {
|
|
117
|
-
/**
|
|
118
|
-
|
|
122
|
+
/** Offset in seconds */
|
|
123
|
+
offset?: number;
|
|
119
124
|
} = {},
|
|
120
125
|
) {
|
|
121
126
|
const { epochDuration: slotsInEpoch } = await this.getConfig();
|
|
122
|
-
const
|
|
127
|
+
const slotNumber = SlotNumber(epoch * Number(slotsInEpoch));
|
|
128
|
+
const timestamp = (await this.rollup.read.getTimestampForSlot([BigInt(slotNumber)])) + BigInt(opts.offset ?? 0);
|
|
123
129
|
try {
|
|
124
130
|
await this.ethCheatCodes.warp(Number(timestamp), { ...opts, silent: true, resetBlockInterval: true });
|
|
125
|
-
this.logger.warn(`Warped to epoch ${epoch}
|
|
131
|
+
this.logger.warn(`Warped to epoch ${epoch}`, { offset: opts.offset, timestamp });
|
|
126
132
|
} catch (err) {
|
|
127
133
|
this.logger.warn(`Warp to epoch ${epoch} failed: ${err}`);
|
|
128
134
|
}
|
|
@@ -130,19 +136,13 @@ export class RollupCheatCodes {
|
|
|
130
136
|
}
|
|
131
137
|
|
|
132
138
|
/** Warps time in L1 until the next epoch */
|
|
133
|
-
public async advanceToNextEpoch(
|
|
134
|
-
opts: {
|
|
135
|
-
/** Optional test date provider to update with the epoch timestamp */
|
|
136
|
-
updateDateProvider?: TestDateProvider;
|
|
137
|
-
} = {},
|
|
138
|
-
) {
|
|
139
|
+
public async advanceToNextEpoch() {
|
|
139
140
|
const slot = await this.getSlot();
|
|
140
141
|
const { epochDuration, slotDuration } = await this.getConfig();
|
|
141
|
-
const slotsUntilNextEpoch = epochDuration - (slot % epochDuration) + 1n;
|
|
142
|
-
const timeToNextEpoch = slotsUntilNextEpoch * slotDuration;
|
|
142
|
+
const slotsUntilNextEpoch = epochDuration - (BigInt(slot) % epochDuration) + 1n;
|
|
143
|
+
const timeToNextEpoch = slotsUntilNextEpoch * BigInt(slotDuration);
|
|
143
144
|
const l1Timestamp = BigInt((await this.client.getBlock()).timestamp);
|
|
144
145
|
await this.ethCheatCodes.warp(Number(l1Timestamp + timeToNextEpoch), {
|
|
145
|
-
...opts,
|
|
146
146
|
silent: true,
|
|
147
147
|
resetBlockInterval: true,
|
|
148
148
|
});
|
|
@@ -152,10 +152,11 @@ export class RollupCheatCodes {
|
|
|
152
152
|
/** Warps time in L1 until the beginning of the next slot. */
|
|
153
153
|
public async advanceToNextSlot() {
|
|
154
154
|
const currentSlot = await this.getSlot();
|
|
155
|
-
const
|
|
155
|
+
const nextSlot = SlotNumber(currentSlot + 1);
|
|
156
|
+
const timestamp = await this.rollup.read.getTimestampForSlot([BigInt(nextSlot)]);
|
|
156
157
|
await this.ethCheatCodes.warp(Number(timestamp), { silent: true, resetBlockInterval: true });
|
|
157
|
-
this.logger.warn(`Advanced to slot ${
|
|
158
|
-
return [timestamp,
|
|
158
|
+
this.logger.warn(`Advanced to slot ${nextSlot}`);
|
|
159
|
+
return [timestamp, nextSlot];
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
/**
|
|
@@ -164,42 +165,42 @@ export class RollupCheatCodes {
|
|
|
164
165
|
*/
|
|
165
166
|
public async advanceSlots(howMany: number) {
|
|
166
167
|
const l1Timestamp = (await this.client.getBlock()).timestamp;
|
|
167
|
-
const slotDuration = await this.rollup.read.getSlotDuration();
|
|
168
|
-
const timeToWarp = BigInt(howMany) * slotDuration;
|
|
168
|
+
const slotDuration = Number(await this.rollup.read.getSlotDuration());
|
|
169
|
+
const timeToWarp = BigInt(howMany) * BigInt(slotDuration);
|
|
169
170
|
await this.ethCheatCodes.warp(l1Timestamp + timeToWarp, { silent: true, resetBlockInterval: true });
|
|
170
171
|
const [slot, epoch] = await Promise.all([this.getSlot(), this.getEpoch()]);
|
|
171
172
|
this.logger.warn(`Advanced ${howMany} slots up to slot ${slot} in epoch ${epoch}`);
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
/**
|
|
175
|
-
* Marks the specified
|
|
176
|
-
* @param
|
|
176
|
+
* Marks the specified checkpoint (or latest if none) as proven
|
|
177
|
+
* @param maybeCheckpointNumber - The checkpoint number to mark as proven (defaults to latest pending)
|
|
177
178
|
*/
|
|
178
|
-
public markAsProven(
|
|
179
|
+
public markAsProven(maybeCheckpointNumber?: number | bigint) {
|
|
179
180
|
return this.ethCheatCodes.execWithPausedAnvil(async () => {
|
|
180
181
|
const tipsBefore = await this.getTips();
|
|
181
182
|
const { pending, proven } = tipsBefore;
|
|
182
183
|
|
|
183
|
-
let
|
|
184
|
-
if (
|
|
185
|
-
|
|
184
|
+
let checkpointNumber = maybeCheckpointNumber;
|
|
185
|
+
if (checkpointNumber === undefined || checkpointNumber > pending) {
|
|
186
|
+
checkpointNumber = pending;
|
|
186
187
|
}
|
|
187
|
-
if (
|
|
188
|
-
this.logger.debug(`
|
|
188
|
+
if (checkpointNumber <= proven) {
|
|
189
|
+
this.logger.debug(`Checkpoint ${checkpointNumber} is already proven`);
|
|
189
190
|
return;
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
// @note @LHerskind this is heavily dependent on the storage layout and size of values
|
|
193
194
|
// The rollupStore is a struct and if the size of elements or the struct changes, this can break
|
|
194
|
-
const
|
|
195
|
+
const provenCheckpointNumberSlot = hexToBigInt(RollupContract.stfStorageSlot);
|
|
195
196
|
|
|
196
197
|
// Need to pack it as a single 32 byte word
|
|
197
|
-
const newValue = (BigInt(tipsBefore.pending) << 128n) | BigInt(
|
|
198
|
-
await this.ethCheatCodes.store(EthAddress.fromString(this.rollup.address),
|
|
198
|
+
const newValue = (BigInt(tipsBefore.pending) << 128n) | BigInt(checkpointNumber);
|
|
199
|
+
await this.ethCheatCodes.store(EthAddress.fromString(this.rollup.address), provenCheckpointNumberSlot, newValue);
|
|
199
200
|
|
|
200
201
|
const tipsAfter = await this.getTips();
|
|
201
202
|
if (tipsAfter.pending < tipsAfter.proven) {
|
|
202
|
-
throw new Error('Overwrote pending tip to a
|
|
203
|
+
throw new Error('Overwrote pending tip to a checkpoint in the past');
|
|
203
204
|
}
|
|
204
205
|
|
|
205
206
|
this.logger.info(
|
|
@@ -208,6 +209,47 @@ export class RollupCheatCodes {
|
|
|
208
209
|
});
|
|
209
210
|
}
|
|
210
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Overrides the inProgress field of the Inbox contract state
|
|
214
|
+
* @param howMuch - How many checkpoints to move it forward
|
|
215
|
+
*/
|
|
216
|
+
public advanceInboxInProgress(howMuch: number | bigint): Promise<bigint> {
|
|
217
|
+
return this.ethCheatCodes.execWithPausedAnvil(async () => {
|
|
218
|
+
// Storage slot 2 contains the InboxState struct
|
|
219
|
+
const inboxStateSlot = 2n;
|
|
220
|
+
|
|
221
|
+
// Get inbox and its current state values
|
|
222
|
+
const inboxAddress = await this.rollup.read.getInbox();
|
|
223
|
+
const currentStateValue = await this.ethCheatCodes.load(EthAddress.fromString(inboxAddress), inboxStateSlot);
|
|
224
|
+
|
|
225
|
+
// Extract current values from the packed storage slot
|
|
226
|
+
// Storage layout: rollingHash (128 bits) | totalMessagesInserted (64 bits) | inProgress (64 bits)
|
|
227
|
+
const currentRollingHash = currentStateValue & ((1n << 128n) - 1n);
|
|
228
|
+
const currentTotalMessages = (currentStateValue >> 128n) & ((1n << 64n) - 1n);
|
|
229
|
+
const currentInProgress = currentStateValue >> 192n;
|
|
230
|
+
const newInProgress = currentInProgress + BigInt(howMuch);
|
|
231
|
+
|
|
232
|
+
// Pack new values: rollingHash (low 128 bits) | totalMessages (middle 64 bits) | inProgress (high 64 bits)
|
|
233
|
+
const newValue = (BigInt(newInProgress) << 192n) | (currentTotalMessages << 128n) | currentRollingHash;
|
|
234
|
+
|
|
235
|
+
await this.ethCheatCodes.store(EthAddress.fromString(inboxAddress), inboxStateSlot, newValue, {
|
|
236
|
+
silent: true,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
this.logger.warn(`Inbox inProgress advanced from ${currentInProgress} to ${newInProgress}`, {
|
|
240
|
+
inbox: inboxAddress,
|
|
241
|
+
oldValue: '0x' + currentStateValue.toString(16),
|
|
242
|
+
newValue: '0x' + newValue.toString(16),
|
|
243
|
+
rollingHash: currentRollingHash,
|
|
244
|
+
totalMessages: currentTotalMessages,
|
|
245
|
+
oldInProgress: currentInProgress,
|
|
246
|
+
newInProgress,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
return newInProgress;
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
211
253
|
/**
|
|
212
254
|
* Executes an action impersonated as the owner of the Rollup contract.
|
|
213
255
|
* @param action - The action to execute
|
package/src/test/start_anvil.ts
CHANGED
|
@@ -15,6 +15,7 @@ export async function startAnvil(
|
|
|
15
15
|
log?: boolean;
|
|
16
16
|
captureMethodCalls?: boolean;
|
|
17
17
|
accounts?: number;
|
|
18
|
+
chainId?: number;
|
|
18
19
|
} = {},
|
|
19
20
|
): Promise<{ anvil: Anvil; methodCalls?: string[]; rpcUrl: string; stop: () => Promise<void> }> {
|
|
20
21
|
const anvilBinary = resolve(dirname(fileURLToPath(import.meta.url)), '../../', 'scripts/anvil_kill_wrapper.sh');
|
|
@@ -35,6 +36,7 @@ export async function startAnvil(
|
|
|
35
36
|
stopTimeout: 1000,
|
|
36
37
|
accounts: opts.accounts ?? 20,
|
|
37
38
|
gasLimit: 45_000_000n,
|
|
39
|
+
chainId: opts.chainId ?? 31337,
|
|
38
40
|
});
|
|
39
41
|
|
|
40
42
|
// Listen to the anvil output to get the port.
|
package/src/test/tx_delayer.ts
CHANGED
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
|
|
19
19
|
import { type ViemClient, isExtendedClient } from '../types.js';
|
|
20
20
|
|
|
21
|
+
const MAX_WAIT_TIME_SECONDS = 180;
|
|
22
|
+
|
|
21
23
|
export function waitUntilBlock<T extends Client>(
|
|
22
24
|
client: T,
|
|
23
25
|
blockNumber: number | bigint,
|
|
@@ -36,7 +38,7 @@ export function waitUntilBlock<T extends Client>(
|
|
|
36
38
|
return currentBlockNumber >= BigInt(blockNumber);
|
|
37
39
|
},
|
|
38
40
|
`Wait until L1 block ${blockNumber}`,
|
|
39
|
-
timeout ??
|
|
41
|
+
timeout ?? MAX_WAIT_TIME_SECONDS,
|
|
40
42
|
0.1,
|
|
41
43
|
);
|
|
42
44
|
}
|
|
@@ -66,7 +68,7 @@ export function waitUntilL1Timestamp<T extends Client>(
|
|
|
66
68
|
return currentTs >= BigInt(timestamp);
|
|
67
69
|
},
|
|
68
70
|
`Wait until L1 timestamp ${timestamp}`,
|
|
69
|
-
timeout ??
|
|
71
|
+
timeout ?? MAX_WAIT_TIME_SECONDS,
|
|
70
72
|
0.1,
|
|
71
73
|
);
|
|
72
74
|
}
|