@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
package/src/queries.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
-
import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
|
|
3
|
-
|
|
4
|
-
import { getContract } from 'viem';
|
|
5
2
|
|
|
6
3
|
import type { L1ContractsConfig } from './config.js';
|
|
7
4
|
import { ReadOnlyGovernanceContract } from './contracts/governance.js';
|
|
@@ -27,8 +24,7 @@ export async function getL1ContractsConfig(
|
|
|
27
24
|
const rollupAddress = addresses.rollupAddress ?? (await governanceProposer.getRollupAddress());
|
|
28
25
|
const rollup = new RollupContract(publicClient, rollupAddress.toString());
|
|
29
26
|
const slasherProposer = await rollup.getSlashingProposer();
|
|
30
|
-
const
|
|
31
|
-
const slasher = getContract({ address: slasherAddress, abi: SlasherAbi, client: publicClient });
|
|
27
|
+
const slasher = await rollup.getSlasherContract();
|
|
32
28
|
|
|
33
29
|
const [
|
|
34
30
|
l1StartBlock,
|
|
@@ -37,8 +33,10 @@ export async function getL1ContractsConfig(
|
|
|
37
33
|
aztecSlotDuration,
|
|
38
34
|
aztecProofSubmissionEpochs,
|
|
39
35
|
aztecTargetCommitteeSize,
|
|
36
|
+
lagInEpochs,
|
|
40
37
|
activationThreshold,
|
|
41
38
|
ejectionThreshold,
|
|
39
|
+
localEjectionThreshold,
|
|
42
40
|
governanceProposerQuorum,
|
|
43
41
|
governanceProposerRoundSize,
|
|
44
42
|
slashingQuorum,
|
|
@@ -48,6 +46,7 @@ export async function getL1ContractsConfig(
|
|
|
48
46
|
slashingOffsetInRounds,
|
|
49
47
|
slashingAmounts,
|
|
50
48
|
slashingVetoer,
|
|
49
|
+
slashingDisableDuration,
|
|
51
50
|
manaTarget,
|
|
52
51
|
provingCostPerMana,
|
|
53
52
|
rollupVersion,
|
|
@@ -60,8 +59,10 @@ export async function getL1ContractsConfig(
|
|
|
60
59
|
rollup.getSlotDuration(),
|
|
61
60
|
rollup.getProofSubmissionEpochs(),
|
|
62
61
|
rollup.getTargetCommitteeSize(),
|
|
62
|
+
rollup.getLagInEpochs(),
|
|
63
63
|
rollup.getActivationThreshold(),
|
|
64
64
|
rollup.getEjectionThreshold(),
|
|
65
|
+
rollup.getLocalEjectionThreshold(),
|
|
65
66
|
governanceProposer.getQuorumSize(),
|
|
66
67
|
governanceProposer.getRoundSize(),
|
|
67
68
|
slasherProposer?.getQuorumSize() ?? 0n,
|
|
@@ -70,7 +71,8 @@ export async function getL1ContractsConfig(
|
|
|
70
71
|
slasherProposer?.getExecutionDelayInRounds() ?? 0n,
|
|
71
72
|
slasherProposer?.type === 'tally' ? slasherProposer.getSlashOffsetInRounds() : 0n,
|
|
72
73
|
slasherProposer?.type === 'tally' ? slasherProposer.getSlashingAmounts() : [0n, 0n, 0n],
|
|
73
|
-
slasher
|
|
74
|
+
slasher?.getVetoer() ?? EthAddress.ZERO,
|
|
75
|
+
slasher?.getSlashingDisableDuration() ?? 0,
|
|
74
76
|
rollup.getManaTarget(),
|
|
75
77
|
rollup.getProvingCostPerMana(),
|
|
76
78
|
rollup.getVersion(),
|
|
@@ -85,16 +87,19 @@ export async function getL1ContractsConfig(
|
|
|
85
87
|
aztecSlotDuration: Number(aztecSlotDuration),
|
|
86
88
|
aztecProofSubmissionEpochs: Number(aztecProofSubmissionEpochs),
|
|
87
89
|
aztecTargetCommitteeSize: Number(aztecTargetCommitteeSize),
|
|
90
|
+
lagInEpochs: Number(lagInEpochs),
|
|
88
91
|
governanceProposerQuorum: Number(governanceProposerQuorum),
|
|
89
92
|
governanceProposerRoundSize: Number(governanceProposerRoundSize),
|
|
90
93
|
activationThreshold,
|
|
91
94
|
ejectionThreshold,
|
|
95
|
+
localEjectionThreshold,
|
|
92
96
|
slashingQuorum: Number(slashingQuorum),
|
|
93
97
|
slashingRoundSizeInEpochs: Number(slashingRoundSize / aztecEpochDuration),
|
|
94
98
|
slashingLifetimeInRounds: Number(slashingLifetimeInRounds),
|
|
95
99
|
slashingExecutionDelayInRounds: Number(slashingExecutionDelayInRounds),
|
|
96
|
-
slashingVetoer
|
|
97
|
-
|
|
100
|
+
slashingVetoer,
|
|
101
|
+
slashingDisableDuration,
|
|
102
|
+
manaTarget,
|
|
98
103
|
provingCostPerMana: provingCostPerMana,
|
|
99
104
|
rollupVersion: Number(rollupVersion),
|
|
100
105
|
genesisArchiveTreeRoot,
|
|
@@ -10,10 +10,11 @@ import type { ViemClient } from '../types.js';
|
|
|
10
10
|
|
|
11
11
|
export type ChainMonitorEventMap = {
|
|
12
12
|
'l1-block': [{ l1BlockNumber: number; timestamp: bigint }];
|
|
13
|
-
'l2-block': [{ l2BlockNumber: number; l1BlockNumber: number; timestamp: bigint }];
|
|
13
|
+
'l2-block': [{ l2BlockNumber: number; l1BlockNumber: number; l2SlotNumber: number; timestamp: bigint }];
|
|
14
14
|
'l2-block-proven': [{ l2ProvenBlockNumber: number; l1BlockNumber: number; timestamp: bigint }];
|
|
15
15
|
'l2-messages': [{ totalL2Messages: number; l1BlockNumber: number }];
|
|
16
16
|
'l2-epoch': [{ l2EpochNumber: number; timestamp: bigint; committee: EthAddress[] | undefined }];
|
|
17
|
+
'l2-slot': [{ l2SlotNumber: number; timestamp: bigint }];
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
/** Utility class that polls the chain on quick intervals and logs new L1 blocks, L2 blocks, and L2 proofs. */
|
|
@@ -38,6 +39,8 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
|
|
|
38
39
|
public totalL2Messages: number = 0;
|
|
39
40
|
/** Current L2 epoch number */
|
|
40
41
|
public l2EpochNumber!: bigint;
|
|
42
|
+
/** Current L2 slot number */
|
|
43
|
+
public l2SlotNumber!: bigint;
|
|
41
44
|
|
|
42
45
|
constructor(
|
|
43
46
|
private readonly rollup: RollupContract,
|
|
@@ -99,8 +102,13 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
|
|
|
99
102
|
}
|
|
100
103
|
this.l1BlockNumber = newL1BlockNumber;
|
|
101
104
|
|
|
102
|
-
const
|
|
103
|
-
|
|
105
|
+
const [l2SlotNumber, l2Epoch, l1block] = await Promise.all([
|
|
106
|
+
this.rollup.getSlotNumber(),
|
|
107
|
+
this.rollup.getCurrentEpoch(),
|
|
108
|
+
this.l1Client.getBlock({ blockNumber: BigInt(newL1BlockNumber), includeTransactions: false }),
|
|
109
|
+
]);
|
|
110
|
+
|
|
111
|
+
const timestamp = l1block.timestamp;
|
|
104
112
|
const timestampString = new Date(Number(timestamp) * 1000).toTimeString().split(' ')[0];
|
|
105
113
|
|
|
106
114
|
this.emit('l1-block', { l1BlockNumber: newL1BlockNumber, timestamp });
|
|
@@ -108,16 +116,21 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
|
|
|
108
116
|
|
|
109
117
|
const newL2BlockNumber = Number(await this.rollup.getBlockNumber());
|
|
110
118
|
if (this.l2BlockNumber !== newL2BlockNumber) {
|
|
111
|
-
const epochNumber = await this.rollup.
|
|
119
|
+
const epochNumber = await this.rollup.getEpochNumberForBlock(BigInt(newL2BlockNumber));
|
|
112
120
|
msg += ` with new L2 block ${newL2BlockNumber} for epoch ${epochNumber}`;
|
|
113
121
|
this.l2BlockNumber = newL2BlockNumber;
|
|
114
122
|
this.l2BlockTimestamp = timestamp;
|
|
115
|
-
this.emit('l2-block', {
|
|
123
|
+
this.emit('l2-block', {
|
|
124
|
+
l2BlockNumber: newL2BlockNumber,
|
|
125
|
+
l1BlockNumber: newL1BlockNumber,
|
|
126
|
+
l2SlotNumber: Number(l2SlotNumber),
|
|
127
|
+
timestamp,
|
|
128
|
+
});
|
|
116
129
|
}
|
|
117
130
|
|
|
118
131
|
const newL2ProvenBlockNumber = Number(await this.rollup.getProvenBlockNumber());
|
|
119
132
|
if (this.l2ProvenBlockNumber !== newL2ProvenBlockNumber) {
|
|
120
|
-
const epochNumber = await this.rollup.
|
|
133
|
+
const epochNumber = await this.rollup.getEpochNumberForBlock(BigInt(newL2ProvenBlockNumber));
|
|
121
134
|
msg += ` with proof up to L2 block ${newL2ProvenBlockNumber} for epoch ${epochNumber}`;
|
|
122
135
|
this.l2ProvenBlockNumber = newL2ProvenBlockNumber;
|
|
123
136
|
this.l2ProvenBlockTimestamp = timestamp;
|
|
@@ -136,14 +149,17 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
|
|
|
136
149
|
this.emit('l2-messages', { totalL2Messages: newTotalL2Messages, l1BlockNumber: newL1BlockNumber });
|
|
137
150
|
}
|
|
138
151
|
|
|
139
|
-
const [l2SlotNumber, l2Epoch] = await Promise.all([this.rollup.getSlotNumber(), this.rollup.getCurrentEpoch()]);
|
|
140
|
-
|
|
141
152
|
let committee: EthAddress[] | undefined;
|
|
142
153
|
if (l2Epoch !== this.l2EpochNumber) {
|
|
143
154
|
this.l2EpochNumber = l2Epoch;
|
|
144
155
|
committee = (await this.rollup.getCurrentEpochCommittee())?.map(addr => EthAddress.fromString(addr));
|
|
145
156
|
this.emit('l2-epoch', { l2EpochNumber: Number(l2Epoch), timestamp, committee });
|
|
146
|
-
msg += ` starting new epoch ${this.l2EpochNumber}
|
|
157
|
+
msg += ` starting new epoch ${this.l2EpochNumber} `;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (l2SlotNumber !== this.l2SlotNumber) {
|
|
161
|
+
this.l2SlotNumber = l2SlotNumber;
|
|
162
|
+
this.emit('l2-slot', { l2SlotNumber: Number(l2SlotNumber), timestamp });
|
|
147
163
|
}
|
|
148
164
|
|
|
149
165
|
this.logger.info(msg, {
|
|
@@ -160,4 +176,68 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
|
|
|
160
176
|
|
|
161
177
|
return this;
|
|
162
178
|
}
|
|
179
|
+
|
|
180
|
+
public waitUntilL2Slot(slot: number | bigint): Promise<void> {
|
|
181
|
+
const targetSlot = typeof slot === 'bigint' ? slot.valueOf() : slot;
|
|
182
|
+
if (this.l2SlotNumber >= targetSlot) {
|
|
183
|
+
return Promise.resolve();
|
|
184
|
+
}
|
|
185
|
+
return new Promise(resolve => {
|
|
186
|
+
const listener = (data: { l2SlotNumber: number; timestamp: bigint }) => {
|
|
187
|
+
if (data.l2SlotNumber >= targetSlot) {
|
|
188
|
+
this.off('l2-slot', listener);
|
|
189
|
+
resolve();
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
this.on('l2-slot', listener);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
public waitUntilL1Block(block: number | bigint): Promise<void> {
|
|
197
|
+
const targetBlock = typeof block === 'bigint' ? block.valueOf() : block;
|
|
198
|
+
if (this.l1BlockNumber >= targetBlock) {
|
|
199
|
+
return Promise.resolve();
|
|
200
|
+
}
|
|
201
|
+
return new Promise(resolve => {
|
|
202
|
+
const listener = (data: { l1BlockNumber: number; timestamp: bigint }) => {
|
|
203
|
+
if (data.l1BlockNumber >= targetBlock) {
|
|
204
|
+
this.off('l1-block', listener);
|
|
205
|
+
resolve();
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
this.on('l1-block', listener);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public waitUntilL1Timestamp(timestamp: number | bigint): Promise<void> {
|
|
213
|
+
const targetTimestamp = typeof timestamp === 'bigint' ? timestamp.valueOf() : timestamp;
|
|
214
|
+
if (this.l1BlockNumber >= targetTimestamp) {
|
|
215
|
+
return Promise.resolve();
|
|
216
|
+
}
|
|
217
|
+
return new Promise(resolve => {
|
|
218
|
+
const listener = (data: { l1BlockNumber: number; timestamp: bigint }) => {
|
|
219
|
+
if (data.timestamp >= targetTimestamp) {
|
|
220
|
+
this.off('l1-block', listener);
|
|
221
|
+
resolve();
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
this.on('l1-block', listener);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
public waitUntilL2Block(l2BlockNumber: number | bigint): Promise<void> {
|
|
229
|
+
const targetBlock = typeof l2BlockNumber === 'bigint' ? l2BlockNumber.valueOf() : l2BlockNumber;
|
|
230
|
+
if (this.l2BlockNumber >= targetBlock) {
|
|
231
|
+
return Promise.resolve();
|
|
232
|
+
}
|
|
233
|
+
return new Promise(resolve => {
|
|
234
|
+
const listener = (data: { l2BlockNumber: number; timestamp: bigint }) => {
|
|
235
|
+
if (data.l2BlockNumber >= targetBlock) {
|
|
236
|
+
this.off('l2-block', listener);
|
|
237
|
+
resolve();
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
this.on('l2-block', listener);
|
|
241
|
+
});
|
|
242
|
+
}
|
|
163
243
|
}
|
|
@@ -2,8 +2,8 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
2
2
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
4
4
|
|
|
5
|
-
import { type L1TxUtilsConfig, createViemSigner } from '../l1_tx_utils.js';
|
|
6
|
-
import { L1TxUtilsWithBlobs } from '../l1_tx_utils_with_blobs.js';
|
|
5
|
+
import { type L1TxUtilsConfig, createViemSigner } from '../l1_tx_utils/index.js';
|
|
6
|
+
import { L1TxUtilsWithBlobs } from '../l1_tx_utils/l1_tx_utils_with_blobs.js';
|
|
7
7
|
import type { ExtendedViemWalletClient } from '../types.js';
|
|
8
8
|
import { type Delayer, withDelayer } from './tx_delayer.js';
|
|
9
9
|
|
|
@@ -3,9 +3,10 @@ import { keccak256 } from '@aztec/foundation/crypto';
|
|
|
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 Hex, type Transaction, createPublicClient, fallback, hexToNumber, http } from 'viem';
|
|
9
10
|
|
|
10
11
|
import type { ViemPublicClient } from '../types.js';
|
|
11
12
|
|
|
@@ -19,6 +20,10 @@ export class EthCheatCodes {
|
|
|
19
20
|
* The RPC URL to use for interacting with the chain
|
|
20
21
|
*/
|
|
21
22
|
public rpcUrls: string[],
|
|
23
|
+
/**
|
|
24
|
+
* The date provider to use for time operations
|
|
25
|
+
*/
|
|
26
|
+
public dateProvider: DateProvider | TestDateProvider,
|
|
22
27
|
/**
|
|
23
28
|
* The logger to use for the eth cheatcodes
|
|
24
29
|
*/
|
|
@@ -29,9 +34,12 @@ export class EthCheatCodes {
|
|
|
29
34
|
});
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.
|
|
37
|
+
public rpcCall(method: string, params: any[]) {
|
|
38
|
+
this.logger.debug(`Calling ${method} with params: ${jsonStringify(params)} on ${this.rpcUrls.join(', ')}`);
|
|
39
|
+
return this.doRpcCall(method, params);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private async doRpcCall(method: string, params: any[]) {
|
|
35
43
|
return (await this.publicClient.transport.request({
|
|
36
44
|
method,
|
|
37
45
|
params,
|
|
@@ -44,7 +52,7 @@ export class EthCheatCodes {
|
|
|
44
52
|
*/
|
|
45
53
|
public async isAutoMining(): Promise<boolean> {
|
|
46
54
|
try {
|
|
47
|
-
const res = await this.
|
|
55
|
+
const res = await this.doRpcCall('anvil_getAutomine', []);
|
|
48
56
|
return res;
|
|
49
57
|
} catch (err) {
|
|
50
58
|
this.logger.error(`Calling "anvil_getAutomine" failed with:`, err);
|
|
@@ -57,7 +65,7 @@ export class EthCheatCodes {
|
|
|
57
65
|
* @returns The current block number
|
|
58
66
|
*/
|
|
59
67
|
public async blockNumber(): Promise<number> {
|
|
60
|
-
const res = await this.
|
|
68
|
+
const res = await this.doRpcCall('eth_blockNumber', []);
|
|
61
69
|
return parseInt(res, 16);
|
|
62
70
|
}
|
|
63
71
|
|
|
@@ -66,7 +74,7 @@ export class EthCheatCodes {
|
|
|
66
74
|
* @returns The current chainId
|
|
67
75
|
*/
|
|
68
76
|
public async chainId(): Promise<number> {
|
|
69
|
-
const res = await this.
|
|
77
|
+
const res = await this.doRpcCall('eth_chainId', []);
|
|
70
78
|
return parseInt(res, 16);
|
|
71
79
|
}
|
|
72
80
|
|
|
@@ -75,7 +83,7 @@ export class EthCheatCodes {
|
|
|
75
83
|
* @returns The current timestamp
|
|
76
84
|
*/
|
|
77
85
|
public async timestamp(): Promise<number> {
|
|
78
|
-
const res = await this.
|
|
86
|
+
const res = await this.doRpcCall('eth_getBlockByNumber', ['latest', true]);
|
|
79
87
|
return parseInt(res.timestamp, 16);
|
|
80
88
|
}
|
|
81
89
|
|
|
@@ -90,7 +98,7 @@ export class EthCheatCodes {
|
|
|
90
98
|
|
|
91
99
|
private async doMine(numberOfBlocks = 1): Promise<void> {
|
|
92
100
|
try {
|
|
93
|
-
await this.
|
|
101
|
+
await this.doRpcCall('hardhat_mine', [numberOfBlocks]);
|
|
94
102
|
} catch (err) {
|
|
95
103
|
throw new Error(`Error mining: ${err}`);
|
|
96
104
|
}
|
|
@@ -101,7 +109,8 @@ export class EthCheatCodes {
|
|
|
101
109
|
*/
|
|
102
110
|
public async evmMine(): Promise<void> {
|
|
103
111
|
try {
|
|
104
|
-
await this.
|
|
112
|
+
await this.doRpcCall('evm_mine', []);
|
|
113
|
+
this.logger.warn(`Mined 1 L1 block with evm_mine`);
|
|
105
114
|
} catch (err) {
|
|
106
115
|
throw new Error(`Error mining: ${err}`);
|
|
107
116
|
}
|
|
@@ -122,7 +131,7 @@ export class EthCheatCodes {
|
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
public async getBalance(account: EthAddress | Hex): Promise<bigint> {
|
|
125
|
-
const res = await this.
|
|
134
|
+
const res = await this.doRpcCall('eth_getBalance', [account.toString(), 'latest']);
|
|
126
135
|
return BigInt(res);
|
|
127
136
|
}
|
|
128
137
|
|
|
@@ -158,7 +167,7 @@ export class EthCheatCodes {
|
|
|
158
167
|
*/
|
|
159
168
|
public getIntervalMining(): Promise<number | null> {
|
|
160
169
|
try {
|
|
161
|
-
return this.
|
|
170
|
+
return this.doRpcCall('anvil_getIntervalMining', []);
|
|
162
171
|
} catch (err) {
|
|
163
172
|
throw new Error(`Error getting interval mining: ${err}`);
|
|
164
173
|
}
|
|
@@ -225,12 +234,12 @@ export class EthCheatCodes {
|
|
|
225
234
|
/**
|
|
226
235
|
* Set the next block timestamp and mines the block.
|
|
227
236
|
* Optionally resets interval mining so the next block is mined in `blockInterval` seconds from now.
|
|
228
|
-
*
|
|
237
|
+
* Always updates the injected date provider to follow L1 time.
|
|
229
238
|
* @param timestamp - The timestamp to set the next block to
|
|
230
239
|
*/
|
|
231
240
|
public async warp(
|
|
232
241
|
timestamp: number | bigint,
|
|
233
|
-
opts: { silent?: boolean; resetBlockInterval?: boolean
|
|
242
|
+
opts: { silent?: boolean; resetBlockInterval?: boolean } = {},
|
|
234
243
|
): Promise<void> {
|
|
235
244
|
let blockInterval: number | null = null;
|
|
236
245
|
try {
|
|
@@ -245,8 +254,10 @@ export class EthCheatCodes {
|
|
|
245
254
|
await this.rpcCall('evm_setNextBlockTimestamp', [Number(timestamp)]);
|
|
246
255
|
// And mine a block so the timestamp goes into effect now
|
|
247
256
|
await this.doMine();
|
|
248
|
-
// Update the date provider
|
|
249
|
-
|
|
257
|
+
// Update the injected date provider so it follows L1 time
|
|
258
|
+
if ('setTime' in this.dateProvider) {
|
|
259
|
+
this.dateProvider.setTime(Number(timestamp) * 1000);
|
|
260
|
+
}
|
|
250
261
|
} catch (err) {
|
|
251
262
|
throw new Error(`Error warping: ${err}`);
|
|
252
263
|
} finally {
|
|
@@ -277,14 +288,21 @@ export class EthCheatCodes {
|
|
|
277
288
|
* @param slot - The storage slot
|
|
278
289
|
* @param value - The value to set the storage slot to
|
|
279
290
|
*/
|
|
280
|
-
public async store(
|
|
291
|
+
public async store(
|
|
292
|
+
contract: EthAddress,
|
|
293
|
+
slot: bigint,
|
|
294
|
+
value: bigint,
|
|
295
|
+
opts: { silent?: boolean } = {},
|
|
296
|
+
): Promise<void> {
|
|
281
297
|
// for the rpc call, we need to change value to be a 32 byte hex string.
|
|
282
298
|
try {
|
|
283
299
|
await this.rpcCall('hardhat_setStorageAt', [contract.toString(), toHex(slot), toHex(value, true)]);
|
|
284
300
|
} catch (err) {
|
|
285
301
|
throw new Error(`Error setting storage for contract ${contract} at ${slot}: ${err}`);
|
|
286
302
|
}
|
|
287
|
-
|
|
303
|
+
if (!opts.silent) {
|
|
304
|
+
this.logger.warn(`Set L1 storage for contract ${contract} at ${slot} to ${value}`);
|
|
305
|
+
}
|
|
288
306
|
}
|
|
289
307
|
|
|
290
308
|
/**
|
|
@@ -350,8 +368,7 @@ export class EthCheatCodes {
|
|
|
350
368
|
* @returns The bytecode for the contract
|
|
351
369
|
*/
|
|
352
370
|
public async getBytecode(contract: EthAddress): Promise<`0x${string}`> {
|
|
353
|
-
|
|
354
|
-
return res;
|
|
371
|
+
return await this.doRpcCall('eth_getCode', [contract.toString(), 'latest']);
|
|
355
372
|
}
|
|
356
373
|
|
|
357
374
|
/**
|
|
@@ -360,8 +377,7 @@ export class EthCheatCodes {
|
|
|
360
377
|
* @returns The raw transaction
|
|
361
378
|
*/
|
|
362
379
|
public async getRawTransaction(txHash: Hex): Promise<`0x${string}`> {
|
|
363
|
-
|
|
364
|
-
return res;
|
|
380
|
+
return await this.doRpcCall('debug_getRawTransaction', [txHash]);
|
|
365
381
|
}
|
|
366
382
|
|
|
367
383
|
/**
|
|
@@ -370,8 +386,7 @@ export class EthCheatCodes {
|
|
|
370
386
|
* @returns The trace
|
|
371
387
|
*/
|
|
372
388
|
public async debugTraceTransaction(txHash: Hex): Promise<any> {
|
|
373
|
-
|
|
374
|
-
return res;
|
|
389
|
+
return await this.doRpcCall('debug_traceTransaction', [txHash]);
|
|
375
390
|
}
|
|
376
391
|
|
|
377
392
|
/**
|
|
@@ -389,7 +404,6 @@ export class EthCheatCodes {
|
|
|
389
404
|
* @param blockNumber - The block number that's going to be the new tip
|
|
390
405
|
*/
|
|
391
406
|
public reorgTo(blockNumber: number): Promise<void> {
|
|
392
|
-
this.logger.info('reorgTo', { blockNumber });
|
|
393
407
|
if (blockNumber <= 0) {
|
|
394
408
|
throw new Error(`Can't reorg to block before genesis: ${blockNumber}`);
|
|
395
409
|
}
|
|
@@ -405,6 +419,7 @@ export class EthCheatCodes {
|
|
|
405
419
|
|
|
406
420
|
const depth = Number(currentTip - BigInt(blockNumber) + 1n);
|
|
407
421
|
await this.rpcCall('anvil_rollback', [depth]);
|
|
422
|
+
this.logger.warn(`Reorged L1 chain to block number ${blockNumber} (depth ${depth})`);
|
|
408
423
|
});
|
|
409
424
|
}
|
|
410
425
|
|
|
@@ -431,10 +446,73 @@ export class EthCheatCodes {
|
|
|
431
446
|
}
|
|
432
447
|
|
|
433
448
|
public traceTransaction(txHash: Hex): Promise<any> {
|
|
434
|
-
return this.
|
|
449
|
+
return this.doRpcCall('trace_transaction', [txHash]);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
public async getTxPoolStatus(): Promise<{ pending: number; queued: number }> {
|
|
453
|
+
const { pending, queued } = await this.doRpcCall('txpool_status', []);
|
|
454
|
+
return { pending: hexToNumber(pending), queued: hexToNumber(queued) };
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
public async getTxPoolContents(): Promise<TxPoolTransaction[]> {
|
|
458
|
+
const txpoolContent = await this.doRpcCall('txpool_content', []);
|
|
459
|
+
return mapTxPoolContent(txpoolContent);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Mines an empty block by temporarily removing all pending transactions from the mempool,
|
|
464
|
+
* mining a block, and then re-adding the transactions back to the pool.
|
|
465
|
+
*/
|
|
466
|
+
public async mineEmptyBlock(blockCount: number = 1): Promise<void> {
|
|
467
|
+
await this.execWithPausedAnvil(async () => {
|
|
468
|
+
// Get all pending and queued transactions from the pool
|
|
469
|
+
const txs = await this.getTxPoolContents();
|
|
470
|
+
|
|
471
|
+
this.logger.debug(`Found ${txs.length} transactions in pool`);
|
|
472
|
+
|
|
473
|
+
// Get raw transactions before dropping them
|
|
474
|
+
const rawTxs: Hex[] = [];
|
|
475
|
+
for (const tx of txs) {
|
|
476
|
+
try {
|
|
477
|
+
const rawTx = await this.doRpcCall('debug_getRawTransaction', [tx.hash]);
|
|
478
|
+
if (rawTx) {
|
|
479
|
+
rawTxs.push(rawTx);
|
|
480
|
+
this.logger.debug(`Got raw tx for ${tx.hash}`);
|
|
481
|
+
} else {
|
|
482
|
+
this.logger.warn(`No raw tx found for ${tx.hash}`);
|
|
483
|
+
}
|
|
484
|
+
} catch {
|
|
485
|
+
this.logger.warn(`Failed to get raw transaction for ${tx.hash}`);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
this.logger.debug(`Retrieved ${rawTxs.length} raw transactions`);
|
|
490
|
+
|
|
491
|
+
// Drop all transactions from the mempool
|
|
492
|
+
await this.doRpcCall('anvil_dropAllTransactions', []);
|
|
493
|
+
|
|
494
|
+
// Mine an empty block
|
|
495
|
+
await this.doMine(blockCount);
|
|
496
|
+
|
|
497
|
+
// Re-add the transactions to the pool
|
|
498
|
+
for (const rawTx of rawTxs) {
|
|
499
|
+
try {
|
|
500
|
+
const txHash = await this.doRpcCall('eth_sendRawTransaction', [rawTx]);
|
|
501
|
+
this.logger.debug(`Re-added transaction ${txHash}`);
|
|
502
|
+
} catch (err) {
|
|
503
|
+
this.logger.warn(`Failed to re-add transaction: ${err}`);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (rawTxs.length !== txs.length) {
|
|
508
|
+
this.logger.warn(`Failed to add all txs back: had ${txs.length} but re-added ${rawTxs.length}`);
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
this.logger.warn(`Mined ${blockCount} empty L1 ${pluralize('block', blockCount)}`);
|
|
435
513
|
}
|
|
436
514
|
|
|
437
|
-
public async execWithPausedAnvil(fn: () => Promise<
|
|
515
|
+
public async execWithPausedAnvil<T>(fn: () => Promise<T>): Promise<T> {
|
|
438
516
|
const [blockInterval, wasAutoMining] = await Promise.all([this.getIntervalMining(), this.isAutoMining()]);
|
|
439
517
|
try {
|
|
440
518
|
if (blockInterval !== null) {
|
|
@@ -445,7 +523,7 @@ export class EthCheatCodes {
|
|
|
445
523
|
await this.setAutomine(false, { silent: true });
|
|
446
524
|
}
|
|
447
525
|
|
|
448
|
-
await fn();
|
|
526
|
+
return await fn();
|
|
449
527
|
} finally {
|
|
450
528
|
try {
|
|
451
529
|
// restore automine if necessary
|
|
@@ -466,4 +544,39 @@ export class EthCheatCodes {
|
|
|
466
544
|
}
|
|
467
545
|
}
|
|
468
546
|
}
|
|
547
|
+
|
|
548
|
+
public async syncDateProvider() {
|
|
549
|
+
const timestamp = await this.timestamp();
|
|
550
|
+
if ('setTime' in this.dateProvider) {
|
|
551
|
+
this.dateProvider.setTime(timestamp * 1000);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
type TxPoolState = 'pending' | 'queued';
|
|
557
|
+
|
|
558
|
+
interface TxPoolContent {
|
|
559
|
+
pending: Record<Hex, Record<string, Transaction>>;
|
|
560
|
+
queued: Record<Hex, Record<string, Transaction>>;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
export type TxPoolTransaction = Transaction & {
|
|
564
|
+
poolState: TxPoolState;
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
function mapTxPoolContent(content: TxPoolContent): TxPoolTransaction[] {
|
|
568
|
+
const result: TxPoolTransaction[] = [];
|
|
569
|
+
|
|
570
|
+
const processPool = (pool: Record<Hex, Record<string, Transaction>>, poolState: TxPoolState) => {
|
|
571
|
+
for (const txsByNonce of Object.values(pool)) {
|
|
572
|
+
for (const tx of Object.values(txsByNonce)) {
|
|
573
|
+
result.push({ ...tx, poolState });
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
processPool(content.pending, 'pending');
|
|
579
|
+
processPool(content.queued, 'queued');
|
|
580
|
+
|
|
581
|
+
return result;
|
|
469
582
|
}
|
|
@@ -2,7 +2,7 @@ import { RollupContract, type ViemPublicClient } from '@aztec/ethereum';
|
|
|
2
2
|
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import type {
|
|
5
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
6
6
|
import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
|
|
7
7
|
|
|
8
8
|
import {
|
|
@@ -40,8 +40,12 @@ export class RollupCheatCodes {
|
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
static create(
|
|
44
|
-
|
|
43
|
+
static create(
|
|
44
|
+
rpcUrls: string[],
|
|
45
|
+
addresses: Pick<L1ContractAddresses, 'rollupAddress'>,
|
|
46
|
+
dateProvider: DateProvider,
|
|
47
|
+
): RollupCheatCodes {
|
|
48
|
+
const ethCheatCodes = new EthCheatCodes(rpcUrls, dateProvider);
|
|
45
49
|
return new RollupCheatCodes(ethCheatCodes, addresses);
|
|
46
50
|
}
|
|
47
51
|
|
|
@@ -112,14 +116,15 @@ export class RollupCheatCodes {
|
|
|
112
116
|
* @param opts - Options
|
|
113
117
|
*/
|
|
114
118
|
public async advanceToEpoch(
|
|
115
|
-
epoch: bigint,
|
|
119
|
+
epoch: bigint | number,
|
|
116
120
|
opts: {
|
|
117
|
-
/**
|
|
118
|
-
|
|
121
|
+
/** Offset in seconds */
|
|
122
|
+
offset?: number;
|
|
119
123
|
} = {},
|
|
120
124
|
) {
|
|
121
125
|
const { epochDuration: slotsInEpoch } = await this.getConfig();
|
|
122
|
-
const timestamp =
|
|
126
|
+
const timestamp =
|
|
127
|
+
(await this.rollup.read.getTimestampForSlot([BigInt(epoch) * slotsInEpoch])) + BigInt(opts.offset ?? 0);
|
|
123
128
|
try {
|
|
124
129
|
await this.ethCheatCodes.warp(Number(timestamp), { ...opts, silent: true, resetBlockInterval: true });
|
|
125
130
|
this.logger.warn(`Warped to epoch ${epoch}`);
|
|
@@ -130,19 +135,13 @@ export class RollupCheatCodes {
|
|
|
130
135
|
}
|
|
131
136
|
|
|
132
137
|
/** 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
|
-
) {
|
|
138
|
+
public async advanceToNextEpoch() {
|
|
139
139
|
const slot = await this.getSlot();
|
|
140
140
|
const { epochDuration, slotDuration } = await this.getConfig();
|
|
141
141
|
const slotsUntilNextEpoch = epochDuration - (slot % epochDuration) + 1n;
|
|
142
142
|
const timeToNextEpoch = slotsUntilNextEpoch * slotDuration;
|
|
143
143
|
const l1Timestamp = BigInt((await this.client.getBlock()).timestamp);
|
|
144
144
|
await this.ethCheatCodes.warp(Number(l1Timestamp + timeToNextEpoch), {
|
|
145
|
-
...opts,
|
|
146
145
|
silent: true,
|
|
147
146
|
resetBlockInterval: true,
|
|
148
147
|
});
|
|
@@ -208,6 +207,47 @@ export class RollupCheatCodes {
|
|
|
208
207
|
});
|
|
209
208
|
}
|
|
210
209
|
|
|
210
|
+
/**
|
|
211
|
+
* Overrides the inProgress field of the Inbox contract state
|
|
212
|
+
* @param howMuch - How many blocks to move it forward
|
|
213
|
+
*/
|
|
214
|
+
public advanceInboxInProgress(howMuch: number | bigint): Promise<bigint> {
|
|
215
|
+
return this.ethCheatCodes.execWithPausedAnvil(async () => {
|
|
216
|
+
// Storage slot 2 contains the InboxState struct
|
|
217
|
+
const inboxStateSlot = 2n;
|
|
218
|
+
|
|
219
|
+
// Get inbox and its current state values
|
|
220
|
+
const inboxAddress = await this.rollup.read.getInbox();
|
|
221
|
+
const currentStateValue = await this.ethCheatCodes.load(EthAddress.fromString(inboxAddress), inboxStateSlot);
|
|
222
|
+
|
|
223
|
+
// Extract current values from the packed storage slot
|
|
224
|
+
// Storage layout: rollingHash (128 bits) | totalMessagesInserted (64 bits) | inProgress (64 bits)
|
|
225
|
+
const currentRollingHash = currentStateValue & ((1n << 128n) - 1n);
|
|
226
|
+
const currentTotalMessages = (currentStateValue >> 128n) & ((1n << 64n) - 1n);
|
|
227
|
+
const currentInProgress = currentStateValue >> 192n;
|
|
228
|
+
const newInProgress = currentInProgress + BigInt(howMuch);
|
|
229
|
+
|
|
230
|
+
// Pack new values: rollingHash (low 128 bits) | totalMessages (middle 64 bits) | inProgress (high 64 bits)
|
|
231
|
+
const newValue = (BigInt(newInProgress) << 192n) | (currentTotalMessages << 128n) | currentRollingHash;
|
|
232
|
+
|
|
233
|
+
await this.ethCheatCodes.store(EthAddress.fromString(inboxAddress), inboxStateSlot, newValue, {
|
|
234
|
+
silent: true,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
this.logger.warn(`Inbox inProgress advanced from ${currentInProgress} to ${newInProgress}`, {
|
|
238
|
+
inbox: inboxAddress,
|
|
239
|
+
oldValue: '0x' + currentStateValue.toString(16),
|
|
240
|
+
newValue: '0x' + newValue.toString(16),
|
|
241
|
+
rollingHash: currentRollingHash,
|
|
242
|
+
totalMessages: currentTotalMessages,
|
|
243
|
+
oldInProgress: currentInProgress,
|
|
244
|
+
newInProgress,
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
return newInProgress;
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
211
251
|
/**
|
|
212
252
|
* Executes an action impersonated as the owner of the Rollup contract.
|
|
213
253
|
* @param action - The action to execute
|