@aztec-labs/ethereum 6.0.0-nightly.20260829
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 +3 -0
- package/dest/account.d.ts +2 -0
- package/dest/account.d.ts.map +1 -0
- package/dest/account.js +4 -0
- package/dest/chain.d.ts +25 -0
- package/dest/chain.d.ts.map +1 -0
- package/dest/chain.js +53 -0
- package/dest/client.d.ts +42 -0
- package/dest/client.d.ts.map +1 -0
- package/dest/client.js +104 -0
- package/dest/config.d.ts +103 -0
- package/dest/config.d.ts.map +1 -0
- package/dest/config.js +233 -0
- package/dest/constants.d.ts +4 -0
- package/dest/constants.d.ts.map +1 -0
- package/dest/constants.js +2 -0
- package/dest/contracts/chain_state_override.d.ts +81 -0
- package/dest/contracts/chain_state_override.d.ts.map +1 -0
- package/dest/contracts/chain_state_override.js +139 -0
- package/dest/contracts/empire_base.d.ts +30 -0
- package/dest/contracts/empire_base.d.ts.map +1 -0
- package/dest/contracts/empire_base.js +84 -0
- package/dest/contracts/errors.d.ts +7 -0
- package/dest/contracts/errors.d.ts.map +1 -0
- package/dest/contracts/errors.js +12 -0
- package/dest/contracts/fee_asset_handler.d.ts +20 -0
- package/dest/contracts/fee_asset_handler.d.ts.map +1 -0
- package/dest/contracts/fee_asset_handler.js +59 -0
- package/dest/contracts/fee_asset_price_oracle.d.ts +105 -0
- package/dest/contracts/fee_asset_price_oracle.d.ts.map +1 -0
- package/dest/contracts/fee_asset_price_oracle.js +656 -0
- package/dest/contracts/fee_juice.d.ts +14 -0
- package/dest/contracts/fee_juice.d.ts.map +1 -0
- package/dest/contracts/fee_juice.js +59 -0
- package/dest/contracts/governance.d.ts +192 -0
- package/dest/contracts/governance.d.ts.map +1 -0
- package/dest/contracts/governance.js +471 -0
- package/dest/contracts/governance_proposer.d.ts +63 -0
- package/dest/contracts/governance_proposer.d.ts.map +1 -0
- package/dest/contracts/governance_proposer.js +536 -0
- package/dest/contracts/gse.d.ts +38 -0
- package/dest/contracts/gse.d.ts.map +1 -0
- package/dest/contracts/gse.js +81 -0
- package/dest/contracts/inbox.d.ts +94 -0
- package/dest/contracts/inbox.d.ts.map +1 -0
- package/dest/contracts/inbox.js +141 -0
- package/dest/contracts/index.d.ts +18 -0
- package/dest/contracts/index.d.ts.map +1 -0
- package/dest/contracts/index.js +17 -0
- package/dest/contracts/log.d.ts +13 -0
- package/dest/contracts/log.d.ts.map +1 -0
- package/dest/contracts/log.js +1 -0
- package/dest/contracts/multicall.d.ts +138 -0
- package/dest/contracts/multicall.d.ts.map +1 -0
- package/dest/contracts/multicall.js +266 -0
- package/dest/contracts/outbox.d.ts +64 -0
- package/dest/contracts/outbox.d.ts.map +1 -0
- package/dest/contracts/outbox.js +113 -0
- package/dest/contracts/registry.d.ts +31 -0
- package/dest/contracts/registry.d.ts.map +1 -0
- package/dest/contracts/registry.js +142 -0
- package/dest/contracts/rollup.d.ts +5836 -0
- package/dest/contracts/rollup.d.ts.map +1 -0
- package/dest/contracts/rollup.js +1612 -0
- package/dest/contracts/slasher_contract.d.ts +44 -0
- package/dest/contracts/slasher_contract.d.ts.map +1 -0
- package/dest/contracts/slasher_contract.js +75 -0
- package/dest/contracts/slashing_proposer.d.ts +174 -0
- package/dest/contracts/slashing_proposer.d.ts.map +1 -0
- package/dest/contracts/slashing_proposer.js +755 -0
- package/dest/contracts/utils.d.ts +3 -0
- package/dest/contracts/utils.d.ts.map +1 -0
- package/dest/contracts/utils.js +11 -0
- package/dest/contracts/watch_event.d.ts +36 -0
- package/dest/contracts/watch_event.d.ts.map +1 -0
- package/dest/contracts/watch_event.js +66 -0
- package/dest/deploy_aztec_l1_contracts.d.ts +267 -0
- package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -0
- package/dest/deploy_aztec_l1_contracts.js +424 -0
- package/dest/deploy_l1_contract.d.ts +68 -0
- package/dest/deploy_l1_contract.d.ts.map +1 -0
- package/dest/deploy_l1_contract.js +312 -0
- package/dest/eth-signer/eth-signer.d.ts +21 -0
- package/dest/eth-signer/eth-signer.d.ts.map +1 -0
- package/dest/eth-signer/eth-signer.js +5 -0
- package/dest/eth-signer/index.d.ts +2 -0
- package/dest/eth-signer/index.d.ts.map +1 -0
- package/dest/eth-signer/index.js +1 -0
- 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/foundry_binary.d.ts +13 -0
- package/dest/foundry_binary.d.ts.map +1 -0
- package/dest/foundry_binary.js +52 -0
- package/dest/l1_artifacts.d.ts +81896 -0
- package/dest/l1_artifacts.d.ts.map +1 -0
- package/dest/l1_artifacts.js +151 -0
- package/dest/l1_contract_addresses.d.ts +73 -0
- package/dest/l1_contract_addresses.d.ts.map +1 -0
- package/dest/l1_contract_addresses.js +120 -0
- package/dest/l1_reader.d.ts +18 -0
- package/dest/l1_reader.d.ts.map +1 -0
- package/dest/l1_reader.js +35 -0
- package/dest/l1_tx_utils/config.d.ts +65 -0
- package/dest/l1_tx_utils/config.d.ts.map +1 -0
- package/dest/l1_tx_utils/config.js +109 -0
- package/dest/l1_tx_utils/constants.d.ts +12 -0
- package/dest/l1_tx_utils/constants.d.ts.map +1 -0
- package/dest/l1_tx_utils/constants.js +39 -0
- package/dest/l1_tx_utils/factory.d.ts +32 -0
- package/dest/l1_tx_utils/factory.d.ts.map +1 -0
- package/dest/l1_tx_utils/factory.js +22 -0
- package/dest/l1_tx_utils/fee-strategies/index.d.ts +10 -0
- package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -0
- package/dest/l1_tx_utils/fee-strategies/index.js +12 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +8 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +129 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +23 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +191 -0
- package/dest/l1_tx_utils/fee-strategies/types.d.ts +51 -0
- package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -0
- package/dest/l1_tx_utils/fee-strategies/types.js +3 -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 +42 -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 +13 -0
- package/dest/l1_tx_utils/index.d.ts.map +1 -0
- package/dest/l1_tx_utils/index.js +13 -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_fee_analyzer.d.ts +252 -0
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -0
- package/dest/l1_tx_utils/l1_fee_analyzer.js +568 -0
- package/dest/l1_tx_utils/l1_tx_utils.d.ts +113 -0
- package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/l1_tx_utils.js +720 -0
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +83 -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 +357 -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/tx_delayer.d.ts +58 -0
- package/dest/l1_tx_utils/tx_delayer.d.ts.map +1 -0
- package/dest/l1_tx_utils/tx_delayer.js +223 -0
- package/dest/l1_tx_utils/types.d.ts +93 -0
- package/dest/l1_tx_utils/types.d.ts.map +1 -0
- package/dest/l1_tx_utils/types.js +36 -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 +6 -0
- package/dest/l1_types.d.ts.map +1 -0
- package/dest/l1_types.js +1 -0
- package/dest/publisher_manager.d.ts +42 -0
- package/dest/publisher_manager.d.ts.map +1 -0
- package/dest/publisher_manager.js +199 -0
- package/dest/queries.d.ts +25 -0
- package/dest/queries.d.ts.map +1 -0
- package/dest/queries.js +144 -0
- package/dest/test/blob_kzg_warmup.d.ts +19 -0
- package/dest/test/blob_kzg_warmup.d.ts.map +1 -0
- package/dest/test/blob_kzg_warmup.js +64 -0
- package/dest/test/chain_monitor.d.ts +126 -0
- package/dest/test/chain_monitor.d.ts.map +1 -0
- package/dest/test/chain_monitor.js +314 -0
- package/dest/test/eth_cheat_codes.d.ts +260 -0
- package/dest/test/eth_cheat_codes.d.ts.map +1 -0
- package/dest/test/eth_cheat_codes.js +608 -0
- package/dest/test/eth_cheat_codes_with_state.d.ts +18 -0
- package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -0
- package/dest/test/eth_cheat_codes_with_state.js +34 -0
- package/dest/test/index.d.ts +8 -0
- package/dest/test/index.d.ts.map +1 -0
- package/dest/test/index.js +7 -0
- package/dest/test/recording_rpc_server.d.ts +18 -0
- package/dest/test/recording_rpc_server.d.ts.map +1 -0
- package/dest/test/recording_rpc_server.js +68 -0
- package/dest/test/rollup_cheat_codes.d.ts +142 -0
- package/dest/test/rollup_cheat_codes.d.ts.map +1 -0
- package/dest/test/rollup_cheat_codes.js +338 -0
- package/dest/test/start_anvil.d.ts +40 -0
- package/dest/test/start_anvil.d.ts.map +1 -0
- package/dest/test/start_anvil.js +210 -0
- package/dest/test/upgrade_utils.d.ts +12 -0
- package/dest/test/upgrade_utils.d.ts.map +1 -0
- package/dest/test/upgrade_utils.js +111 -0
- package/dest/types.d.ts +68 -0
- package/dest/types.d.ts.map +1 -0
- package/dest/types.js +3 -0
- package/dest/utils.d.ts +45 -0
- package/dest/utils.d.ts.map +1 -0
- package/dest/utils.js +260 -0
- package/dest/zkPassportVerifierAddress.d.ts +15 -0
- package/dest/zkPassportVerifierAddress.d.ts.map +1 -0
- package/dest/zkPassportVerifierAddress.js +11 -0
- package/package.json +122 -0
- package/src/account.ts +5 -0
- package/src/chain.ts +71 -0
- package/src/client.ts +165 -0
- package/src/config.ts +342 -0
- package/src/constants.ts +4 -0
- package/src/contracts/README.md +157 -0
- package/src/contracts/chain_state_override.ts +203 -0
- package/src/contracts/empire_base.ts +89 -0
- package/src/contracts/errors.ts +13 -0
- package/src/contracts/fee_asset_handler.ts +66 -0
- package/src/contracts/fee_asset_price_oracle.ts +284 -0
- package/src/contracts/fee_juice.ts +57 -0
- package/src/contracts/governance.ts +597 -0
- package/src/contracts/governance_proposer.ts +181 -0
- package/src/contracts/gse.ts +105 -0
- package/src/contracts/inbox.ts +223 -0
- package/src/contracts/index.ts +17 -0
- package/src/contracts/log.ts +13 -0
- package/src/contracts/multicall.ts +298 -0
- package/src/contracts/outbox.ts +132 -0
- package/src/contracts/registry.ts +161 -0
- package/src/contracts/rollup.ts +1502 -0
- package/src/contracts/slasher_contract.ts +89 -0
- package/src/contracts/slashing_proposer.ts +397 -0
- package/src/contracts/utils.ts +14 -0
- package/src/contracts/watch_event.ts +109 -0
- package/src/deploy_aztec_l1_contracts.ts +663 -0
- package/src/deploy_l1_contract.ts +361 -0
- package/src/eth-signer/eth-signer.ts +24 -0
- package/src/eth-signer/index.ts +1 -0
- package/src/forwarder_proxy.ts +107 -0
- package/src/foundry_binary.ts +57 -0
- package/src/l1_artifacts.ts +231 -0
- package/src/l1_contract_addresses.ts +149 -0
- package/src/l1_reader.ts +57 -0
- package/src/l1_tx_utils/README.md +177 -0
- package/src/l1_tx_utils/config.ts +181 -0
- package/src/l1_tx_utils/constants.ts +29 -0
- package/src/l1_tx_utils/factory.ts +64 -0
- package/src/l1_tx_utils/fee-strategies/index.ts +22 -0
- package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +162 -0
- package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +244 -0
- package/src/l1_tx_utils/fee-strategies/types.ts +55 -0
- package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +107 -0
- package/src/l1_tx_utils/index-blobs.ts +2 -0
- package/src/l1_tx_utils/index.ts +15 -0
- package/src/l1_tx_utils/interfaces.ts +86 -0
- package/src/l1_tx_utils/l1_fee_analyzer.ts +874 -0
- package/src/l1_tx_utils/l1_tx_utils.ts +840 -0
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +459 -0
- package/src/l1_tx_utils/signer.ts +27 -0
- package/src/l1_tx_utils/tx_delayer.ts +302 -0
- package/src/l1_tx_utils/types.ts +116 -0
- package/src/l1_tx_utils/utils.ts +15 -0
- package/src/l1_types.ts +6 -0
- package/src/publisher_manager.ts +239 -0
- package/src/queries.ts +189 -0
- package/src/test/blob_kzg_warmup.ts +65 -0
- package/src/test/chain_monitor.ts +389 -0
- package/src/test/eth_cheat_codes.ts +624 -0
- package/src/test/eth_cheat_codes_with_state.ts +38 -0
- package/src/test/index.ts +7 -0
- package/src/test/recording_rpc_server.ts +69 -0
- package/src/test/rollup_cheat_codes.ts +398 -0
- package/src/test/start_anvil.ts +255 -0
- package/src/test/upgrade_utils.ts +109 -0
- package/src/types.ts +97 -0
- package/src/utils.ts +344 -0
- package/src/zkPassportVerifierAddress.ts +15 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { InboxContract } from '@aztec-labs/ethereum/contracts';
|
|
2
|
+
import { SlotNumber } from '@aztec-labs/foundation/branded-types';
|
|
3
|
+
import { createLogger } from '@aztec-labs/foundation/log';
|
|
4
|
+
import { promiseWithResolvers } from '@aztec-labs/foundation/promise';
|
|
5
|
+
import { DateProvider } from '@aztec-labs/foundation/timer';
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
/** Utility class that polls the chain on quick intervals and logs new L1 blocks, L2 blocks, and L2 proofs. */ export class ChainMonitor extends EventEmitter {
|
|
8
|
+
rollup;
|
|
9
|
+
dateProvider;
|
|
10
|
+
logger;
|
|
11
|
+
intervalMs;
|
|
12
|
+
l1Client;
|
|
13
|
+
includeFeeData;
|
|
14
|
+
inbox;
|
|
15
|
+
handle;
|
|
16
|
+
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
17
|
+
running;
|
|
18
|
+
/** Current L1 block number */ l1BlockNumber;
|
|
19
|
+
/** Current checkpoint number */ checkpointNumber;
|
|
20
|
+
/** Current proven checkpoint number */ provenCheckpointNumber;
|
|
21
|
+
/** L1 timestamp for the current checkpoint */ checkpointTimestamp;
|
|
22
|
+
/** L1 timestamp for the proven checkpoint */ provenCheckpointTimestamp;
|
|
23
|
+
/** Total number of L2 messages pushed into the Inbox */ totalL2Messages;
|
|
24
|
+
/** Current L2 epoch number */ l2EpochNumber;
|
|
25
|
+
/** Current L2 slot number */ l2SlotNumber;
|
|
26
|
+
/** Current L2 fee data (components of the minimum fee per mana). */ l2FeeData;
|
|
27
|
+
constructor(rollup, dateProvider = new DateProvider(), logger = createLogger('aztecjs:utils:chain_monitor'), intervalMs = 200, options = {}){
|
|
28
|
+
super(), this.rollup = rollup, this.dateProvider = dateProvider, this.logger = logger, this.intervalMs = intervalMs, this.running = new Set(), this.totalL2Messages = 0;
|
|
29
|
+
this.l1Client = rollup.client;
|
|
30
|
+
this.includeFeeData = options.includeFeeData ?? true;
|
|
31
|
+
}
|
|
32
|
+
start() {
|
|
33
|
+
if (this.handle) {
|
|
34
|
+
throw new Error('Chain monitor already started');
|
|
35
|
+
}
|
|
36
|
+
this.handle = setInterval(this.safeRun.bind(this), this.intervalMs);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
async stop() {
|
|
40
|
+
try {
|
|
41
|
+
this.removeAllListeners();
|
|
42
|
+
if (this.handle) {
|
|
43
|
+
clearInterval(this.handle);
|
|
44
|
+
this.handle = undefined;
|
|
45
|
+
}
|
|
46
|
+
await Promise.allSettled([
|
|
47
|
+
...this.running
|
|
48
|
+
]);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
this.logger.error('Error stopping chain monitor', err);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async getInbox() {
|
|
54
|
+
if (!this.inbox) {
|
|
55
|
+
const { inboxAddress } = await this.rollup.getRollupAddresses();
|
|
56
|
+
this.inbox = new InboxContract(this.l1Client, inboxAddress);
|
|
57
|
+
}
|
|
58
|
+
return this.inbox;
|
|
59
|
+
}
|
|
60
|
+
safeRun() {
|
|
61
|
+
const running = promiseWithResolvers();
|
|
62
|
+
this.running.add(running.promise);
|
|
63
|
+
void this.run().catch((error)=>{
|
|
64
|
+
this.logger.error('Error in chain monitor loop', error);
|
|
65
|
+
}).finally(()=>{
|
|
66
|
+
running.resolve();
|
|
67
|
+
this.running.delete(running.promise);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async run(force = false) {
|
|
71
|
+
const newL1BlockNumber = Number(await this.l1Client.getBlockNumber({
|
|
72
|
+
cacheTime: 0
|
|
73
|
+
}));
|
|
74
|
+
if (!force && this.l1BlockNumber === newL1BlockNumber) {
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
this.l1BlockNumber = newL1BlockNumber;
|
|
78
|
+
const [l2SlotNumber, l2Epoch, l1block] = await Promise.all([
|
|
79
|
+
this.rollup.getSlotNumber(),
|
|
80
|
+
this.rollup.getCurrentEpoch(),
|
|
81
|
+
this.l1Client.getBlock({
|
|
82
|
+
blockNumber: BigInt(newL1BlockNumber),
|
|
83
|
+
includeTransactions: false
|
|
84
|
+
})
|
|
85
|
+
]);
|
|
86
|
+
const timestamp = l1block.timestamp;
|
|
87
|
+
const timestampString = new Date(Number(timestamp) * 1000).toTimeString().split(' ')[0];
|
|
88
|
+
this.emit('l1-block', {
|
|
89
|
+
l1BlockNumber: newL1BlockNumber,
|
|
90
|
+
timestamp
|
|
91
|
+
});
|
|
92
|
+
let msg = `L1 block ${newL1BlockNumber} mined at ${timestampString}`;
|
|
93
|
+
const newCheckpointNumber = await this.rollup.getCheckpointNumber();
|
|
94
|
+
if (this.checkpointNumber !== newCheckpointNumber) {
|
|
95
|
+
const epochNumber = await this.rollup.getEpochNumberForCheckpoint(newCheckpointNumber);
|
|
96
|
+
msg += ` with new checkpoint ${newCheckpointNumber} for epoch ${epochNumber}`;
|
|
97
|
+
this.checkpointNumber = newCheckpointNumber;
|
|
98
|
+
this.checkpointTimestamp = timestamp;
|
|
99
|
+
this.emit('checkpoint', {
|
|
100
|
+
checkpointNumber: newCheckpointNumber,
|
|
101
|
+
l1BlockNumber: newL1BlockNumber,
|
|
102
|
+
l2SlotNumber,
|
|
103
|
+
timestamp
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const newProvenCheckpointNumber = await this.rollup.getProvenCheckpointNumber();
|
|
107
|
+
if (this.provenCheckpointNumber !== newProvenCheckpointNumber) {
|
|
108
|
+
const epochNumber = await this.rollup.getEpochNumberForCheckpoint(newProvenCheckpointNumber);
|
|
109
|
+
msg += ` with proof up to checkpoint ${newProvenCheckpointNumber} for epoch ${epochNumber}`;
|
|
110
|
+
this.provenCheckpointNumber = newProvenCheckpointNumber;
|
|
111
|
+
this.provenCheckpointTimestamp = timestamp;
|
|
112
|
+
this.emit('checkpoint-proven', {
|
|
113
|
+
provenCheckpointNumber: newProvenCheckpointNumber,
|
|
114
|
+
l1BlockNumber: newL1BlockNumber,
|
|
115
|
+
timestamp
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
const inbox = await this.getInbox();
|
|
119
|
+
const newTotalL2Messages = await inbox.getState().then((s)=>Number(s.totalMessagesInserted));
|
|
120
|
+
if (this.totalL2Messages !== newTotalL2Messages) {
|
|
121
|
+
msg += ` with ${newTotalL2Messages - this.totalL2Messages} new L2 messages (total ${newTotalL2Messages})`;
|
|
122
|
+
this.totalL2Messages = newTotalL2Messages;
|
|
123
|
+
this.emit('l2-messages', {
|
|
124
|
+
totalL2Messages: newTotalL2Messages,
|
|
125
|
+
l1BlockNumber: newL1BlockNumber
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
let committee;
|
|
129
|
+
if (l2Epoch !== this.l2EpochNumber) {
|
|
130
|
+
this.l2EpochNumber = l2Epoch;
|
|
131
|
+
committee = await this.rollup.getCurrentEpochCommittee();
|
|
132
|
+
this.emit('l2-epoch', {
|
|
133
|
+
l2EpochNumber: l2Epoch,
|
|
134
|
+
timestamp,
|
|
135
|
+
committee
|
|
136
|
+
});
|
|
137
|
+
msg += ` starting new epoch ${this.l2EpochNumber}`;
|
|
138
|
+
}
|
|
139
|
+
if (l2SlotNumber !== this.l2SlotNumber) {
|
|
140
|
+
this.l2SlotNumber = l2SlotNumber;
|
|
141
|
+
this.emit('l2-slot', {
|
|
142
|
+
l2SlotNumber,
|
|
143
|
+
timestamp
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (this.includeFeeData) {
|
|
147
|
+
const feeData = await this.fetchFeeData(timestamp);
|
|
148
|
+
if (this.hasFeeDataChanged(feeData)) {
|
|
149
|
+
msg += ` with L2 min fee ${feeData.minFeePerMana}`;
|
|
150
|
+
this.l2FeeData = feeData;
|
|
151
|
+
this.emit('l2-fees', feeData);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
this.logger.info(msg, {
|
|
155
|
+
currentTimestamp: this.dateProvider.nowInSeconds(),
|
|
156
|
+
l1Timestamp: timestamp,
|
|
157
|
+
l1BlockNumber: this.l1BlockNumber,
|
|
158
|
+
l2SlotNumber,
|
|
159
|
+
l2Epoch,
|
|
160
|
+
checkpointNumber: this.checkpointNumber,
|
|
161
|
+
provenCheckpointNumber: this.provenCheckpointNumber,
|
|
162
|
+
totalL2Messages: this.totalL2Messages,
|
|
163
|
+
committee,
|
|
164
|
+
...this.l2FeeData
|
|
165
|
+
});
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
waitUntilL2Slot(slot) {
|
|
169
|
+
if (this.l2SlotNumber >= slot) {
|
|
170
|
+
return Promise.resolve();
|
|
171
|
+
}
|
|
172
|
+
return new Promise((resolve)=>{
|
|
173
|
+
const listener = (data)=>{
|
|
174
|
+
if (data.l2SlotNumber >= slot) {
|
|
175
|
+
this.off('l2-slot', listener);
|
|
176
|
+
resolve();
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
this.on('l2-slot', listener);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async waitUntilNextL2Slot() {
|
|
183
|
+
const targetSlot = SlotNumber.add((await this.run()).l2SlotNumber, 1);
|
|
184
|
+
return this.waitUntilL2Slot(targetSlot);
|
|
185
|
+
}
|
|
186
|
+
waitUntilL1Block(block) {
|
|
187
|
+
const targetBlock = typeof block === 'bigint' ? block.valueOf() : block;
|
|
188
|
+
if (this.l1BlockNumber >= targetBlock) {
|
|
189
|
+
return Promise.resolve();
|
|
190
|
+
}
|
|
191
|
+
return new Promise((resolve)=>{
|
|
192
|
+
const listener = (data)=>{
|
|
193
|
+
if (data.l1BlockNumber >= targetBlock) {
|
|
194
|
+
this.off('l1-block', listener);
|
|
195
|
+
resolve();
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
this.on('l1-block', listener);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
waitUntilL1Timestamp(timestamp) {
|
|
202
|
+
const targetTimestamp = typeof timestamp === 'bigint' ? timestamp.valueOf() : timestamp;
|
|
203
|
+
if (this.l1BlockNumber >= targetTimestamp) {
|
|
204
|
+
return Promise.resolve();
|
|
205
|
+
}
|
|
206
|
+
return new Promise((resolve)=>{
|
|
207
|
+
const listener = (data)=>{
|
|
208
|
+
if (data.timestamp >= targetTimestamp) {
|
|
209
|
+
this.off('l1-block', listener);
|
|
210
|
+
resolve();
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
this.on('l1-block', listener);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
waitUntilCheckpoint(checkpointNumber) {
|
|
217
|
+
if (this.checkpointNumber >= checkpointNumber) {
|
|
218
|
+
return Promise.resolve();
|
|
219
|
+
}
|
|
220
|
+
return new Promise((resolve)=>{
|
|
221
|
+
const listener = (data)=>{
|
|
222
|
+
if (data.checkpointNumber >= checkpointNumber) {
|
|
223
|
+
this.off('checkpoint', listener);
|
|
224
|
+
resolve();
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
this.on('checkpoint', listener);
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Resolves with the first `checkpoint` event whose payload satisfies `match`. Unlike
|
|
232
|
+
* {@link waitUntilCheckpoint} (which waits for a target number), this lets callers wait for an
|
|
233
|
+
* arbitrary checkpoint property (e.g. one published in the first half of its slot). Rejects after
|
|
234
|
+
* `opts.timeout` ms if provided; otherwise waits indefinitely.
|
|
235
|
+
*
|
|
236
|
+
* By default this is purely event-driven and only resolves on the *next* matching checkpoint that
|
|
237
|
+
* arrives after the call. Set `checkCurrentCheckpoint` to also test the current checkpoint first (via
|
|
238
|
+
* a fresh {@link run} snapshot) and short-circuit if it already satisfies `match`. Use it only for
|
|
239
|
+
* latching state predicates (e.g. "checkpoint number has passed N"), where an already-satisfied
|
|
240
|
+
* result is valid and you want to avoid missing an advance that landed before the listener attached.
|
|
241
|
+
* Do NOT set it when the predicate depends on observing the checkpoint live (e.g. one published
|
|
242
|
+
* mid-slot that the caller then times against wall-clock), since it may return a checkpoint whose
|
|
243
|
+
* slot has already elapsed.
|
|
244
|
+
*/ async waitForCheckpoint(match, opts = {}) {
|
|
245
|
+
if (opts.checkCurrentCheckpoint) {
|
|
246
|
+
await this.run();
|
|
247
|
+
const current = {
|
|
248
|
+
checkpointNumber: this.checkpointNumber,
|
|
249
|
+
l1BlockNumber: this.l1BlockNumber,
|
|
250
|
+
l2SlotNumber: this.l2SlotNumber,
|
|
251
|
+
timestamp: this.checkpointTimestamp
|
|
252
|
+
};
|
|
253
|
+
if (match(current)) {
|
|
254
|
+
return current;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return new Promise((resolve, reject)=>{
|
|
258
|
+
let timer;
|
|
259
|
+
const listener = (event)=>{
|
|
260
|
+
if (match(event)) {
|
|
261
|
+
if (timer) {
|
|
262
|
+
clearTimeout(timer);
|
|
263
|
+
}
|
|
264
|
+
this.off('checkpoint', listener);
|
|
265
|
+
resolve(event);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
if (opts.timeout !== undefined) {
|
|
269
|
+
timer = setTimeout(()=>{
|
|
270
|
+
this.off('checkpoint', listener);
|
|
271
|
+
reject(new Error(`Timed out after ${opts.timeout}ms waiting for a matching checkpoint`));
|
|
272
|
+
}, opts.timeout);
|
|
273
|
+
}
|
|
274
|
+
this.on('checkpoint', listener);
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
/** Resolves once the proven checkpoint number reaches `checkpointNumber`. */ waitUntilCheckpointProven(checkpointNumber) {
|
|
278
|
+
if (this.provenCheckpointNumber >= checkpointNumber) {
|
|
279
|
+
return Promise.resolve();
|
|
280
|
+
}
|
|
281
|
+
return new Promise((resolve)=>{
|
|
282
|
+
const listener = (data)=>{
|
|
283
|
+
if (data.provenCheckpointNumber >= checkpointNumber) {
|
|
284
|
+
this.off('checkpoint-proven', listener);
|
|
285
|
+
resolve();
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
this.on('checkpoint-proven', listener);
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
async fetchFeeData(timestamp) {
|
|
292
|
+
const [components, minFeePerMana, l1Fees, ethPerFeeAsset, manaTarget] = await Promise.all([
|
|
293
|
+
this.rollup.getManaMinFeeComponentsAt(timestamp, true),
|
|
294
|
+
this.rollup.getManaMinFeeAt(timestamp, true),
|
|
295
|
+
this.rollup.getL1FeesAt(timestamp),
|
|
296
|
+
this.rollup.getEthPerFeeAsset(),
|
|
297
|
+
this.rollup.getManaTarget()
|
|
298
|
+
]);
|
|
299
|
+
return {
|
|
300
|
+
...components,
|
|
301
|
+
minFeePerMana,
|
|
302
|
+
l1BaseFee: l1Fees.baseFee,
|
|
303
|
+
l1BlobFee: l1Fees.blobFee,
|
|
304
|
+
ethPerFeeAsset,
|
|
305
|
+
manaTarget
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
hasFeeDataChanged(newData) {
|
|
309
|
+
if (!this.l2FeeData) {
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
return this.l2FeeData.sequencerCost !== newData.sequencerCost || this.l2FeeData.proverCost !== newData.proverCost || this.l2FeeData.congestionCost !== newData.congestionCost || this.l2FeeData.l1BaseFee !== newData.l1BaseFee || this.l2FeeData.l1BlobFee !== newData.l1BlobFee || this.l2FeeData.ethPerFeeAsset !== newData.ethPerFeeAsset;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec-labs/foundation/eth-address';
|
|
2
|
+
import type { DateProvider, TestDateProvider } from '@aztec-labs/foundation/timer';
|
|
3
|
+
import { type Chain, type Hex, type Transaction } from 'viem';
|
|
4
|
+
import type { ViemPublicClient } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* A class that provides utility functions for interacting with ethereum (L1).
|
|
7
|
+
*/
|
|
8
|
+
export declare class EthCheatCodes {
|
|
9
|
+
/**
|
|
10
|
+
* The RPC URL to use for interacting with the chain
|
|
11
|
+
*/
|
|
12
|
+
rpcUrls: string[];
|
|
13
|
+
/**
|
|
14
|
+
* The date provider to use for time operations
|
|
15
|
+
*/
|
|
16
|
+
dateProvider: DateProvider | TestDateProvider;
|
|
17
|
+
/**
|
|
18
|
+
* The logger to use for the eth cheatcodes
|
|
19
|
+
*/
|
|
20
|
+
logger: import("@aztec-labs/foundation/log").Logger;
|
|
21
|
+
/**
|
|
22
|
+
* The chain configuration provided to Anvil
|
|
23
|
+
*/
|
|
24
|
+
chain: Chain;
|
|
25
|
+
readonly publicClient: ViemPublicClient;
|
|
26
|
+
constructor(
|
|
27
|
+
/**
|
|
28
|
+
* The RPC URL to use for interacting with the chain
|
|
29
|
+
*/
|
|
30
|
+
rpcUrls: string[],
|
|
31
|
+
/**
|
|
32
|
+
* The date provider to use for time operations
|
|
33
|
+
*/
|
|
34
|
+
dateProvider: DateProvider | TestDateProvider,
|
|
35
|
+
/**
|
|
36
|
+
* The logger to use for the eth cheatcodes
|
|
37
|
+
*/
|
|
38
|
+
logger?: import("@aztec-labs/foundation/log").Logger,
|
|
39
|
+
/**
|
|
40
|
+
* The chain configuration provided to Anvil
|
|
41
|
+
*/
|
|
42
|
+
chain?: Chain);
|
|
43
|
+
rpcCall(method: string, params: any[]): Promise<any>;
|
|
44
|
+
private doRpcCall;
|
|
45
|
+
/**
|
|
46
|
+
* Get the auto mine status of the underlying chain
|
|
47
|
+
* @returns True if automine is on, false otherwise
|
|
48
|
+
*/
|
|
49
|
+
isAutoMining(): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Get the current blocknumber
|
|
52
|
+
* @returns The current block number
|
|
53
|
+
*/
|
|
54
|
+
blockNumber(): Promise<number>;
|
|
55
|
+
/**
|
|
56
|
+
* Get the current chainId
|
|
57
|
+
* @returns The current chainId
|
|
58
|
+
*/
|
|
59
|
+
chainId(): Promise<number>;
|
|
60
|
+
/**
|
|
61
|
+
* Get the timestamp of the latest mined L1 block.
|
|
62
|
+
* Note: this is NOT the current time — it's the discrete timestamp of the last block.
|
|
63
|
+
* Between blocks, the actual chain time advances but no new block reflects it.
|
|
64
|
+
* @returns The latest block timestamp in seconds
|
|
65
|
+
*/
|
|
66
|
+
lastBlockTimestamp(): Promise<number>;
|
|
67
|
+
/**
|
|
68
|
+
* Get the timestamp of the pending L1 block — the block that anvil will mine next.
|
|
69
|
+
* Reflects any prior `setNextBlockTimestamp` call or the configured block interval.
|
|
70
|
+
* @returns The pending block timestamp in seconds.
|
|
71
|
+
*/
|
|
72
|
+
nextBlockTimestamp(): Promise<number>;
|
|
73
|
+
/**
|
|
74
|
+
* Advance the chain by a number of blocks
|
|
75
|
+
* @param numberOfBlocks - The number of blocks to mine
|
|
76
|
+
*/
|
|
77
|
+
mine(numberOfBlocks?: number | bigint): Promise<void>;
|
|
78
|
+
private doMine;
|
|
79
|
+
/**
|
|
80
|
+
* Mines a single block with evm_mine
|
|
81
|
+
*/
|
|
82
|
+
evmMine(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Set the balance of an account
|
|
85
|
+
* @param account - The account to set the balance for
|
|
86
|
+
* @param balance - The balance to set
|
|
87
|
+
*/
|
|
88
|
+
setBalance(account: EthAddress | Hex, balance: bigint): Promise<void>;
|
|
89
|
+
getBalance(account: EthAddress | Hex): Promise<bigint>;
|
|
90
|
+
/**
|
|
91
|
+
* Set the interval between successive blocks (block time). This does NOT enable interval mining.
|
|
92
|
+
* @param interval - The interval to use between blocks
|
|
93
|
+
*/
|
|
94
|
+
setBlockInterval(interval: number): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Set the next block base fee per gas
|
|
97
|
+
* @param baseFee - The base fee to set
|
|
98
|
+
*/
|
|
99
|
+
setNextBlockBaseFeePerGas(baseFee: bigint | number): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Get interval mining if set.
|
|
102
|
+
* @param seconds - The interval to use between blocks
|
|
103
|
+
*/
|
|
104
|
+
getIntervalMining(): Promise<number | null>;
|
|
105
|
+
/**
|
|
106
|
+
* Enable interval mining at the given interval (block time)
|
|
107
|
+
* @param seconds - The interval to use between blocks
|
|
108
|
+
*/
|
|
109
|
+
setIntervalMining(seconds: number, opts?: {
|
|
110
|
+
silent?: boolean;
|
|
111
|
+
}): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Starts interval mining from a freshly mined block and syncs the date provider to the block timestamp.
|
|
114
|
+
*/
|
|
115
|
+
startIntervalMiningWithFreshBlock(seconds: number): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Set the automine status of the underlying anvil chain
|
|
118
|
+
* @param automine - The automine status to set
|
|
119
|
+
*/
|
|
120
|
+
setAutomine(automine: boolean, opts?: {
|
|
121
|
+
silent?: boolean;
|
|
122
|
+
}): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Drop a transaction from the mempool
|
|
125
|
+
* @param txHash - The transaction hash
|
|
126
|
+
*/
|
|
127
|
+
dropTransaction(txHash: Hex): Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Set the next block timestamp
|
|
130
|
+
* @param timestamp - The timestamp to set the next block to
|
|
131
|
+
*/
|
|
132
|
+
setNextBlockTimestamp(timestamp: number | Date): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Set the next block timestamp and mines the block.
|
|
135
|
+
* Optionally resets interval mining so the next block is mined in `blockInterval` seconds from now.
|
|
136
|
+
* Always updates the injected date provider to follow L1 time.
|
|
137
|
+
* @param timestamp - The timestamp to set the next block to
|
|
138
|
+
*/
|
|
139
|
+
warp(timestamp: number | bigint, opts?: {
|
|
140
|
+
silent?: boolean;
|
|
141
|
+
resetBlockInterval?: boolean;
|
|
142
|
+
}): Promise<void>;
|
|
143
|
+
/**
|
|
144
|
+
* Load the value at a storage slot of a contract address on eth
|
|
145
|
+
* @param contract - The contract address
|
|
146
|
+
* @param slot - The storage slot
|
|
147
|
+
* @returns - The value at the storage slot
|
|
148
|
+
*/
|
|
149
|
+
load(contract: EthAddress, slot: bigint): Promise<bigint>;
|
|
150
|
+
/**
|
|
151
|
+
* Set the value at a storage slot of a contract address on eth
|
|
152
|
+
* @param contract - The contract address
|
|
153
|
+
* @param slot - The storage slot
|
|
154
|
+
* @param value - The value to set the storage slot to
|
|
155
|
+
*/
|
|
156
|
+
store(contract: EthAddress, slot: bigint, value: bigint, opts?: {
|
|
157
|
+
silent?: boolean;
|
|
158
|
+
}): Promise<void>;
|
|
159
|
+
/**
|
|
160
|
+
* Computes the slot value for a given map and key.
|
|
161
|
+
* @param baseSlot - The base slot of the map (specified in Aztec.nr contract)
|
|
162
|
+
* @param key - The key to lookup in the map
|
|
163
|
+
* @returns The storage slot of the value in the map
|
|
164
|
+
*/
|
|
165
|
+
keccak256(baseSlot: bigint, key: bigint): bigint;
|
|
166
|
+
/**
|
|
167
|
+
* Send transactions impersonating an externally owned account or contract.
|
|
168
|
+
* @param who - The address to impersonate
|
|
169
|
+
*/
|
|
170
|
+
startImpersonating(who: EthAddress | Hex): Promise<void>;
|
|
171
|
+
/**
|
|
172
|
+
* Stop impersonating an account that you are currently impersonating.
|
|
173
|
+
* @param who - The address to stop impersonating
|
|
174
|
+
*/
|
|
175
|
+
stopImpersonating(who: EthAddress | Hex): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Set the bytecode for a contract
|
|
178
|
+
* @param contract - The contract address
|
|
179
|
+
* @param bytecode - The bytecode to set
|
|
180
|
+
*/
|
|
181
|
+
etch(contract: EthAddress, bytecode: `0x${string}`): Promise<void>;
|
|
182
|
+
/**
|
|
183
|
+
* Get the bytecode for a contract
|
|
184
|
+
* @param contract - The contract address
|
|
185
|
+
* @returns The bytecode for the contract
|
|
186
|
+
*/
|
|
187
|
+
getBytecode(contract: EthAddress): Promise<`0x${string}`>;
|
|
188
|
+
/**
|
|
189
|
+
* Get the raw transaction object for a given transaction hash
|
|
190
|
+
* @param txHash - The transaction hash
|
|
191
|
+
* @returns The raw transaction
|
|
192
|
+
*/
|
|
193
|
+
getRawTransaction(txHash: Hex): Promise<`0x${string}`>;
|
|
194
|
+
/**
|
|
195
|
+
* Get the trace for a given transaction hash
|
|
196
|
+
* @param txHash - The transaction hash
|
|
197
|
+
* @returns The trace
|
|
198
|
+
*/
|
|
199
|
+
debugTraceTransaction(txHash: Hex): Promise<any>;
|
|
200
|
+
/**
|
|
201
|
+
* Triggers a reorg of the given depth, removing those blocks from the chain.
|
|
202
|
+
* @param depth - The depth of the reorg
|
|
203
|
+
*/
|
|
204
|
+
reorg(depth: number): Promise<void>;
|
|
205
|
+
/**
|
|
206
|
+
* Causes Anvil to reorg until the given block number is the new tip
|
|
207
|
+
* @param blockNumber - The block number that's going to be the new tip
|
|
208
|
+
*/
|
|
209
|
+
reorgTo(blockNumber: number): Promise<void>;
|
|
210
|
+
/**
|
|
211
|
+
* Triggers a reorg of the given depth, optionally replacing it with new blocks.
|
|
212
|
+
* The resulting block height will be the same as the original chain.
|
|
213
|
+
* @param depth - The depth of the reorg
|
|
214
|
+
* @param newBlocks - The blocks to replace the old ones with, each represented as a list of txs.
|
|
215
|
+
*/
|
|
216
|
+
reorgWithReplacement(depth: number, newBlocks?: (Hex | {
|
|
217
|
+
to: EthAddress | Hex;
|
|
218
|
+
input?: Hex;
|
|
219
|
+
from?: EthAddress | Hex;
|
|
220
|
+
value?: number | bigint;
|
|
221
|
+
})[][]): Promise<void>;
|
|
222
|
+
traceTransaction(txHash: Hex): Promise<any>;
|
|
223
|
+
getTxPoolStatus(): Promise<{
|
|
224
|
+
pending: number;
|
|
225
|
+
queued: number;
|
|
226
|
+
}>;
|
|
227
|
+
getTxPoolContents(): Promise<TxPoolTransaction[]>;
|
|
228
|
+
/**
|
|
229
|
+
* Mines empty blocks while leaving any pending transactions untouched in the mempool.
|
|
230
|
+
*
|
|
231
|
+
* Never manipulates the mempool, so it is immune to the race that dropping and re-adding txs has against a
|
|
232
|
+
* concurrent publisher that is monitoring and re-broadcasting the same in-flight tx (with that approach the
|
|
233
|
+
* in-flight tx could reappear in the pool and be swept into the "empty" block, mining a proposal the caller
|
|
234
|
+
* expected to stay pending). Works in two steps: first the block gas limit is temporarily lowered below the
|
|
235
|
+
* intrinsic cost of any transaction (21000 gas) and the blocks are mined, so no pending tx is includable;
|
|
236
|
+
* then those blocks are reorged out and replaced with empty blocks mined at the restored gas limit. The
|
|
237
|
+
* reorg is needed because anvil applies a new gas limit only to future blocks: without it the just-mined
|
|
238
|
+
* blocks would keep the tiny gas limit, and an `eth_call` against `latest` (whose gas is capped by the
|
|
239
|
+
* block gas limit) would revert with "intrinsic gas too high".
|
|
240
|
+
*
|
|
241
|
+
* The replacement blocks advance L1 time. `anvil_reorg` stamps each replacement as `parent + N*interval`,
|
|
242
|
+
* so on its own it would freeze L1 time at the parent timestamp; callers that measure elapsed L1 time
|
|
243
|
+
* (L1TxUtils stall/timeout detection, `syncDateProvider`-driven slot advancement) rely on it moving
|
|
244
|
+
* forward. We reproduce the wall-clock advance the mine step just made (at least 1s per block) via a
|
|
245
|
+
* temporary block-timestamp interval, then restore any pre-existing interval.
|
|
246
|
+
*/
|
|
247
|
+
mineEmptyBlock(blockCount?: number): Promise<void>;
|
|
248
|
+
/** Returns the gas limit of the latest mined L1 block. */
|
|
249
|
+
getBlockGasLimit(): Promise<bigint>;
|
|
250
|
+
/** Sets the block gas limit applied to subsequently mined L1 blocks. */
|
|
251
|
+
setBlockGasLimit(gasLimit: bigint): Promise<void>;
|
|
252
|
+
execWithPausedAnvil<T>(fn: () => Promise<T>): Promise<T>;
|
|
253
|
+
syncDateProvider(): Promise<void>;
|
|
254
|
+
}
|
|
255
|
+
type TxPoolState = 'pending' | 'queued';
|
|
256
|
+
export type TxPoolTransaction = Transaction & {
|
|
257
|
+
poolState: TxPoolState;
|
|
258
|
+
};
|
|
259
|
+
export {};
|
|
260
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoX2NoZWF0X2NvZGVzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC9ldGhfY2hlYXRfY29kZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBSWhFLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ25GLE9BQU8sRUFBRSxLQUFLLEtBQUssRUFBRSxLQUFLLEdBQUcsRUFBRSxLQUFLLFdBQVcsRUFBbUQsTUFBTSxNQUFNLENBQUM7QUFHL0csT0FBTyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFcEQ7O0dBRUc7QUFDSCxxQkFBYSxhQUFhO0lBR3RCOztPQUVHO0lBQ0ksT0FBTyxFQUFFLE1BQU0sRUFBRTtJQUN4Qjs7T0FFRztJQUNJLFlBQVksRUFBRSxZQUFZLEdBQUcsZ0JBQWdCO0lBQ3BEOztPQUVHO0lBQ0ksTUFBTTtJQUNiOztPQUVHO0lBQ0ksS0FBSyxFQUFFLEtBQUs7SUFqQnJCLFNBQWdCLFlBQVksRUFBRSxnQkFBZ0IsQ0FBQztJQUMvQztJQUNFOztPQUVHO0lBQ0ksT0FBTyxFQUFFLE1BQU0sRUFBRTtJQUN4Qjs7T0FFRztJQUNJLFlBQVksRUFBRSxZQUFZLEdBQUcsZ0JBQWdCO0lBQ3BEOztPQUVHO0lBQ0ksTUFBTSw4Q0FBdUM7SUFDcEQ7O09BRUc7SUFDSSxLQUFLLEdBQUUsS0FBZSxFQU05QjtJQUVNLE9BQU8sQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsZ0JBRzNDO1lBRWEsU0FBUztJQU92Qjs7O09BR0c7SUFDVSxZQUFZLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQVE1QztJQUVEOzs7T0FHRztJQUNVLFdBQVcsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLENBRzFDO0lBRUQ7OztPQUdHO0lB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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eth_cheat_codes.d.ts","sourceRoot":"","sources":["../../src/test/eth_cheat_codes.ts"],"names":[],"mappings":"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"}
|