@aztec/ethereum 4.0.0-nightly.20250907 → 4.0.0-nightly.20260108
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/client.js +6 -2
- package/dest/config.d.ts +18 -46
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +40 -285
- package/dest/constants.d.ts +1 -1
- package/dest/contracts/empire_base.d.ts +8 -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 +8 -6
- package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/empire_slashing_proposer.js +18 -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 +7 -6
- package/dest/contracts/governance_proposer.d.ts.map +1 -1
- package/dest/contracts/governance_proposer.js +400 -12
- package/dest/contracts/gse.d.ts +1 -1
- package/dest/contracts/gse.d.ts.map +1 -1
- package/dest/contracts/inbox.d.ts +7 -3
- package/dest/contracts/inbox.d.ts.map +1 -1
- package/dest/contracts/inbox.js +4 -0
- 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 +169 -118
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +714 -243
- 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 +15 -7
- package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/tally_slashing_proposer.js +15 -5
- package/dest/contracts/utils.d.ts +1 -1
- package/dest/deploy_aztec_l1_contracts.d.ts +247 -0
- package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -0
- package/dest/deploy_aztec_l1_contracts.js +336 -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 +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 +17733 -6280
- 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 +5 -4
- package/dest/l1_reader.d.ts +4 -2
- package/dest/l1_reader.d.ts.map +1 -1
- package/dest/l1_reader.js +7 -1
- 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 +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 +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/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 +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 +12 -0
- package/dest/l1_tx_utils/index.d.ts.map +1 -0
- package/dest/l1_tx_utils/index.js +12 -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 +233 -0
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -0
- package/dest/l1_tx_utils/l1_fee_analyzer.js +506 -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 +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 +323 -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 +20 -14
- package/dest/test/chain_monitor.d.ts +29 -22
- package/dest/test/chain_monitor.d.ts.map +1 -1
- package/dest/test/chain_monitor.js +81 -38
- 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 +126 -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 +82 -43
- package/dest/test/start_anvil.d.ts +4 -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 +4 -3
- 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 +15 -3
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +28 -161
- package/dest/zkPassportVerifierAddress.d.ts +1 -1
- package/dest/zkPassportVerifierAddress.js +1 -1
- package/package.json +33 -14
- package/src/client.ts +3 -3
- package/src/config.ts +49 -358
- package/src/contracts/empire_base.ts +7 -6
- package/src/contracts/empire_slashing_proposer.ts +23 -8
- package/src/contracts/fee_asset_handler.ts +1 -1
- package/src/contracts/governance.ts +3 -3
- package/src/contracts/governance_proposer.ts +19 -9
- package/src/contracts/inbox.ts +7 -2
- package/src/contracts/multicall.ts +12 -10
- package/src/contracts/rollup.ts +374 -236
- package/src/contracts/slasher_contract.ts +22 -0
- package/src/contracts/tally_slashing_proposer.ts +21 -9
- package/src/deploy_aztec_l1_contracts.ts +557 -0
- package/src/deploy_l1_contract.ts +362 -0
- package/src/forwarder_proxy.ts +108 -0
- package/src/l1_artifacts.ts +14 -6
- package/src/l1_contract_addresses.ts +24 -20
- package/src/l1_reader.ts +10 -2
- 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 +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 +163 -0
- package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +245 -0
- package/src/l1_tx_utils/fee-strategies/types.ts +56 -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 +14 -0
- package/src/l1_tx_utils/interfaces.ts +86 -0
- package/src/l1_tx_utils/l1_fee_analyzer.ts +803 -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 +419 -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 +24 -10
- package/src/test/chain_monitor.ts +102 -44
- package/src/test/delayed_tx_utils.ts +2 -2
- package/src/test/eth_cheat_codes.ts +150 -31
- package/src/test/rollup_cheat_codes.ts +95 -53
- package/src/test/start_anvil.ts +4 -0
- package/src/test/tx_delayer.ts +5 -3
- package/src/test/upgrade_utils.ts +3 -2
- package/src/types.ts +62 -0
- package/src/utils.ts +41 -184
- package/src/zkPassportVerifierAddress.ts +1 -1
- package/dest/deploy_l1_contracts.d.ts +0 -211
- package/dest/deploy_l1_contracts.d.ts.map +0 -1
- package/dest/deploy_l1_contracts.js +0 -1267
- 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/deploy_l1_contracts.ts +0 -1596
- package/src/index.ts +0 -17
- package/src/l1_tx_utils.ts +0 -1105
- package/src/l1_tx_utils_with_blobs.ts +0 -144
package/src/contracts/rollup.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
3
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
1
4
|
import { memoize } from '@aztec/foundation/decorators';
|
|
2
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
6
|
import type { ViemSignature } from '@aztec/foundation/eth-signature';
|
|
7
|
+
import { makeBackoff, retry } from '@aztec/foundation/retry';
|
|
4
8
|
import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
|
|
5
9
|
import { RollupStorage } from '@aztec/l1-artifacts/RollupStorage';
|
|
6
|
-
import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
|
|
7
10
|
|
|
8
11
|
import chunk from 'lodash.chunk';
|
|
9
12
|
import {
|
|
@@ -11,18 +14,18 @@ import {
|
|
|
11
14
|
type GetContractReturnType,
|
|
12
15
|
type Hex,
|
|
13
16
|
type StateOverride,
|
|
17
|
+
type WatchContractEventReturnType,
|
|
14
18
|
encodeFunctionData,
|
|
15
|
-
getAddress,
|
|
16
19
|
getContract,
|
|
17
20
|
hexToBigInt,
|
|
18
21
|
keccak256,
|
|
19
22
|
} from 'viem';
|
|
20
23
|
|
|
21
24
|
import { getPublicClient } from '../client.js';
|
|
22
|
-
import type {
|
|
25
|
+
import type { DeployAztecL1ContractsReturnType } from '../deploy_aztec_l1_contracts.js';
|
|
23
26
|
import type { L1ContractAddresses } from '../l1_contract_addresses.js';
|
|
24
27
|
import type { L1ReaderConfig } from '../l1_reader.js';
|
|
25
|
-
import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
|
|
28
|
+
import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js';
|
|
26
29
|
import type { ViemClient } from '../types.js';
|
|
27
30
|
import { formatViemError } from '../utils.js';
|
|
28
31
|
import { EmpireSlashingProposerContract } from './empire_slashing_proposer.js';
|
|
@@ -62,6 +65,7 @@ export type EpochProofPublicInputArgs = {
|
|
|
62
65
|
|
|
63
66
|
export type ViemHeader = {
|
|
64
67
|
lastArchiveRoot: `0x${string}`;
|
|
68
|
+
blockHeadersHash: `0x${string}`;
|
|
65
69
|
contentCommitment: ViemContentCommitment;
|
|
66
70
|
slotNumber: bigint;
|
|
67
71
|
timestamp: bigint;
|
|
@@ -82,27 +86,108 @@ export type ViemGasFees = {
|
|
|
82
86
|
feePerL2Gas: bigint;
|
|
83
87
|
};
|
|
84
88
|
|
|
85
|
-
export
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
export enum SlashingProposerType {
|
|
90
|
+
None = 0,
|
|
91
|
+
Tally = 1,
|
|
92
|
+
Empire = 2,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Status of a validator/attester in the staking system.
|
|
97
|
+
* Matches the Status enum in StakingLib.sol
|
|
98
|
+
*/
|
|
99
|
+
export enum AttesterStatus {
|
|
100
|
+
NONE = 0,
|
|
101
|
+
VALIDATING = 1,
|
|
102
|
+
ZOMBIE = 2,
|
|
103
|
+
EXITING = 3,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Fee header data for a checkpoint
|
|
108
|
+
*/
|
|
109
|
+
export type FeeHeader = {
|
|
110
|
+
excessMana: bigint;
|
|
111
|
+
manaUsed: bigint;
|
|
112
|
+
feeAssetPriceNumerator: bigint;
|
|
113
|
+
congestionCost: bigint;
|
|
114
|
+
proverCost: bigint;
|
|
88
115
|
};
|
|
89
116
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Checkpoint log data returned from the rollup contract
|
|
119
|
+
*/
|
|
120
|
+
export type CheckpointLog = {
|
|
121
|
+
archive: Fr;
|
|
122
|
+
headerHash: Buffer32;
|
|
123
|
+
blobCommitmentsHash: Buffer32;
|
|
124
|
+
attestationsHash: Buffer32;
|
|
125
|
+
payloadDigest: Buffer32;
|
|
126
|
+
slotNumber: SlotNumber;
|
|
127
|
+
feeHeader: FeeHeader;
|
|
94
128
|
};
|
|
95
129
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
130
|
+
/**
|
|
131
|
+
* L1 fee data (base fee and blob fee)
|
|
132
|
+
*/
|
|
133
|
+
export type L1FeeData = {
|
|
134
|
+
baseFee: bigint;
|
|
135
|
+
blobFee: bigint;
|
|
99
136
|
};
|
|
100
137
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Reward configuration for the rollup
|
|
140
|
+
*/
|
|
141
|
+
export type RewardConfig = {
|
|
142
|
+
rewardDistributor: EthAddress;
|
|
143
|
+
sequencerBps: bigint;
|
|
144
|
+
booster: EthAddress;
|
|
145
|
+
checkpointReward: bigint;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Exit information for a validator
|
|
150
|
+
*/
|
|
151
|
+
export type Exit = {
|
|
152
|
+
withdrawalId: bigint;
|
|
153
|
+
amount: bigint;
|
|
154
|
+
exitableAt: bigint;
|
|
155
|
+
recipientOrWithdrawer: EthAddress;
|
|
156
|
+
isRecipient: boolean;
|
|
157
|
+
exists: boolean;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Attester configuration including public key and withdrawer
|
|
162
|
+
*/
|
|
163
|
+
export type AttesterConfig = {
|
|
164
|
+
publicKey: {
|
|
165
|
+
x: bigint;
|
|
166
|
+
y: bigint;
|
|
167
|
+
};
|
|
168
|
+
withdrawer: EthAddress;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Complete view of an attester's state
|
|
173
|
+
*/
|
|
174
|
+
export type AttesterView = {
|
|
175
|
+
status: AttesterStatus;
|
|
176
|
+
effectiveBalance: bigint;
|
|
177
|
+
exit: Exit;
|
|
178
|
+
config: AttesterConfig;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Return for a status call
|
|
183
|
+
*/
|
|
184
|
+
export type RollupStatusResponse = {
|
|
185
|
+
provenCheckpointNumber: CheckpointNumber;
|
|
186
|
+
provenArchive: Fr;
|
|
187
|
+
pendingCheckpointNumber: CheckpointNumber;
|
|
188
|
+
pendingArchive: Fr;
|
|
189
|
+
archiveOfMyCheckpoint: Fr;
|
|
190
|
+
};
|
|
106
191
|
|
|
107
192
|
export class RollupContract {
|
|
108
193
|
private readonly rollup: GetContractReturnType<typeof RollupAbi, ViemClient>;
|
|
@@ -121,7 +206,7 @@ export class RollupContract {
|
|
|
121
206
|
return (RollupContract.cachedStfStorageSlot ??= keccak256(Buffer.from('aztec.stf.storage', 'utf-8')));
|
|
122
207
|
}
|
|
123
208
|
|
|
124
|
-
static getFromL1ContractsValues(deployL1ContractsValues:
|
|
209
|
+
static getFromL1ContractsValues(deployL1ContractsValues: DeployAztecL1ContractsReturnType) {
|
|
125
210
|
const {
|
|
126
211
|
l1Client,
|
|
127
212
|
l1ContractAddresses: { rollupAddress },
|
|
@@ -145,8 +230,8 @@ export class RollupContract {
|
|
|
145
230
|
this.rollup = getContract({ address, abi: RollupAbi, client });
|
|
146
231
|
}
|
|
147
232
|
|
|
148
|
-
getGSE() {
|
|
149
|
-
return this.rollup.read.getGSE();
|
|
233
|
+
async getGSE(): Promise<EthAddress> {
|
|
234
|
+
return EthAddress.fromString(await this.rollup.read.getGSE());
|
|
150
235
|
}
|
|
151
236
|
|
|
152
237
|
public get address() {
|
|
@@ -160,13 +245,12 @@ export class RollupContract {
|
|
|
160
245
|
public async getSlashingProposer(): Promise<
|
|
161
246
|
EmpireSlashingProposerContract | TallySlashingProposerContract | undefined
|
|
162
247
|
> {
|
|
163
|
-
const
|
|
164
|
-
if (
|
|
248
|
+
const slasher = await this.getSlasherContract();
|
|
249
|
+
if (!slasher) {
|
|
165
250
|
return undefined;
|
|
166
251
|
}
|
|
167
252
|
|
|
168
|
-
const
|
|
169
|
-
const proposerAddress = await slasher.read.PROPOSER();
|
|
253
|
+
const proposerAddress = await slasher.getProposer();
|
|
170
254
|
const proposerAbi = [
|
|
171
255
|
{
|
|
172
256
|
type: 'function',
|
|
@@ -177,7 +261,7 @@ export class RollupContract {
|
|
|
177
261
|
},
|
|
178
262
|
] as const;
|
|
179
263
|
|
|
180
|
-
const proposer = getContract({ address: proposerAddress, abi: proposerAbi, client: this.client });
|
|
264
|
+
const proposer = getContract({ address: proposerAddress.toString(), abi: proposerAbi, client: this.client });
|
|
181
265
|
const proposerType = await proposer.read.SLASHING_PROPOSER_TYPE();
|
|
182
266
|
if (proposerType === SlashingProposerType.Tally.valueOf()) {
|
|
183
267
|
return new TallySlashingProposerContract(this.client, proposerAddress);
|
|
@@ -189,79 +273,93 @@ export class RollupContract {
|
|
|
189
273
|
}
|
|
190
274
|
|
|
191
275
|
@memoize
|
|
192
|
-
getL1StartBlock() {
|
|
276
|
+
getL1StartBlock(): Promise<bigint> {
|
|
193
277
|
return this.rollup.read.L1_BLOCK_AT_GENESIS();
|
|
194
278
|
}
|
|
195
279
|
|
|
196
280
|
@memoize
|
|
197
|
-
getL1GenesisTime() {
|
|
281
|
+
getL1GenesisTime(): Promise<bigint> {
|
|
198
282
|
return this.rollup.read.getGenesisTime();
|
|
199
283
|
}
|
|
200
284
|
|
|
201
285
|
@memoize
|
|
202
|
-
getProofSubmissionEpochs() {
|
|
203
|
-
return this.rollup.read.getProofSubmissionEpochs();
|
|
286
|
+
async getProofSubmissionEpochs(): Promise<number> {
|
|
287
|
+
return Number(await this.rollup.read.getProofSubmissionEpochs());
|
|
204
288
|
}
|
|
205
289
|
|
|
206
290
|
@memoize
|
|
207
|
-
getEpochDuration() {
|
|
208
|
-
return this.rollup.read.getEpochDuration();
|
|
291
|
+
async getEpochDuration(): Promise<number> {
|
|
292
|
+
return Number(await this.rollup.read.getEpochDuration());
|
|
209
293
|
}
|
|
210
294
|
|
|
211
295
|
@memoize
|
|
212
|
-
getSlotDuration() {
|
|
213
|
-
return this.rollup.read.getSlotDuration();
|
|
296
|
+
async getSlotDuration(): Promise<number> {
|
|
297
|
+
return Number(await this.rollup.read.getSlotDuration());
|
|
214
298
|
}
|
|
215
299
|
|
|
216
300
|
@memoize
|
|
217
|
-
getTargetCommitteeSize() {
|
|
218
|
-
return this.rollup.read.getTargetCommitteeSize();
|
|
301
|
+
async getTargetCommitteeSize(): Promise<number> {
|
|
302
|
+
return Number(await this.rollup.read.getTargetCommitteeSize());
|
|
219
303
|
}
|
|
220
304
|
|
|
221
305
|
@memoize
|
|
222
|
-
getEjectionThreshold() {
|
|
306
|
+
getEjectionThreshold(): Promise<bigint> {
|
|
223
307
|
return this.rollup.read.getEjectionThreshold();
|
|
224
308
|
}
|
|
225
309
|
|
|
226
310
|
@memoize
|
|
227
|
-
|
|
311
|
+
getLocalEjectionThreshold(): Promise<bigint> {
|
|
312
|
+
return this.rollup.read.getLocalEjectionThreshold();
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
@memoize
|
|
316
|
+
async getLagInEpochsForValidatorSet(): Promise<number> {
|
|
317
|
+
return Number(await this.rollup.read.getLagInEpochsForValidatorSet());
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
@memoize
|
|
321
|
+
async getLagInEpochsForRandao(): Promise<number> {
|
|
322
|
+
return Number(await this.rollup.read.getLagInEpochsForRandao());
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
@memoize
|
|
326
|
+
getActivationThreshold(): Promise<bigint> {
|
|
228
327
|
return this.rollup.read.getActivationThreshold();
|
|
229
328
|
}
|
|
230
329
|
|
|
231
330
|
@memoize
|
|
232
|
-
getExitDelay() {
|
|
233
|
-
return this.rollup.read.getExitDelay();
|
|
331
|
+
async getExitDelay(): Promise<number> {
|
|
332
|
+
return Number(await this.rollup.read.getExitDelay());
|
|
234
333
|
}
|
|
235
334
|
|
|
236
335
|
@memoize
|
|
237
|
-
getManaTarget() {
|
|
336
|
+
getManaTarget(): Promise<bigint> {
|
|
238
337
|
return this.rollup.read.getManaTarget();
|
|
239
338
|
}
|
|
240
339
|
|
|
241
340
|
@memoize
|
|
242
|
-
getProvingCostPerMana() {
|
|
341
|
+
getProvingCostPerMana(): Promise<bigint> {
|
|
243
342
|
return this.rollup.read.getProvingCostPerManaInEth();
|
|
244
343
|
}
|
|
245
344
|
|
|
246
345
|
@memoize
|
|
247
|
-
getProvingCostPerManaInFeeAsset() {
|
|
346
|
+
getProvingCostPerManaInFeeAsset(): Promise<bigint> {
|
|
248
347
|
return this.rollup.read.getProvingCostPerManaInFeeAsset();
|
|
249
348
|
}
|
|
250
349
|
|
|
251
350
|
@memoize
|
|
252
|
-
getManaLimit() {
|
|
351
|
+
getManaLimit(): Promise<bigint> {
|
|
253
352
|
return this.rollup.read.getManaLimit();
|
|
254
353
|
}
|
|
255
354
|
|
|
256
355
|
@memoize
|
|
257
|
-
getVersion() {
|
|
356
|
+
getVersion(): Promise<bigint> {
|
|
258
357
|
return this.rollup.read.getVersion();
|
|
259
358
|
}
|
|
260
359
|
|
|
261
360
|
@memoize
|
|
262
|
-
async getGenesisArchiveTreeRoot(): Promise
|
|
263
|
-
|
|
264
|
-
return block.archive;
|
|
361
|
+
async getGenesisArchiveTreeRoot(): Promise<Fr> {
|
|
362
|
+
return Fr.fromString(await this.rollup.read.archiveAt([0n]));
|
|
265
363
|
}
|
|
266
364
|
|
|
267
365
|
/**
|
|
@@ -287,67 +385,72 @@ export class RollupContract {
|
|
|
287
385
|
return {
|
|
288
386
|
l1StartBlock,
|
|
289
387
|
l1GenesisTime,
|
|
290
|
-
slotDuration
|
|
388
|
+
slotDuration,
|
|
291
389
|
epochDuration: Number(epochDuration),
|
|
292
390
|
proofSubmissionEpochs: Number(proofSubmissionEpochs),
|
|
293
391
|
};
|
|
294
392
|
}
|
|
295
393
|
|
|
296
|
-
|
|
297
|
-
return this.rollup.read.getSlasher();
|
|
394
|
+
async getSlasherAddress(): Promise<EthAddress> {
|
|
395
|
+
return EthAddress.fromString(await this.rollup.read.getSlasher());
|
|
298
396
|
}
|
|
299
397
|
|
|
300
398
|
/**
|
|
301
399
|
* Returns a SlasherContract instance for interacting with the slasher contract.
|
|
302
400
|
*/
|
|
303
|
-
async getSlasherContract(): Promise<SlasherContract> {
|
|
304
|
-
const slasherAddress = await this.
|
|
305
|
-
|
|
401
|
+
async getSlasherContract(): Promise<SlasherContract | undefined> {
|
|
402
|
+
const slasherAddress = await this.getSlasherAddress();
|
|
403
|
+
if (slasherAddress.isZero()) {
|
|
404
|
+
return undefined;
|
|
405
|
+
}
|
|
406
|
+
return new SlasherContract(this.client, slasherAddress);
|
|
306
407
|
}
|
|
307
408
|
|
|
308
|
-
getOwner() {
|
|
309
|
-
return this.rollup.read.owner();
|
|
409
|
+
async getOwner(): Promise<EthAddress> {
|
|
410
|
+
return EthAddress.fromString(await this.rollup.read.owner());
|
|
310
411
|
}
|
|
311
412
|
|
|
312
|
-
getActiveAttesterCount() {
|
|
313
|
-
return this.rollup.read.getActiveAttesterCount();
|
|
413
|
+
async getActiveAttesterCount(): Promise<number> {
|
|
414
|
+
return Number(await this.rollup.read.getActiveAttesterCount());
|
|
314
415
|
}
|
|
315
416
|
|
|
316
417
|
public async getSlashingProposerAddress() {
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
});
|
|
323
|
-
return EthAddress.fromString(await slasher.read.PROPOSER());
|
|
418
|
+
const slasher = await this.getSlasherContract();
|
|
419
|
+
if (!slasher) {
|
|
420
|
+
return EthAddress.ZERO;
|
|
421
|
+
}
|
|
422
|
+
return await slasher.getProposer();
|
|
324
423
|
}
|
|
325
424
|
|
|
326
|
-
|
|
327
|
-
return this.rollup.read.
|
|
425
|
+
getCheckpointReward(): Promise<bigint> {
|
|
426
|
+
return this.rollup.read.getCheckpointReward();
|
|
328
427
|
}
|
|
329
428
|
|
|
330
|
-
|
|
331
|
-
return this.rollup.read.
|
|
429
|
+
async getCheckpointNumber(): Promise<CheckpointNumber> {
|
|
430
|
+
return CheckpointNumber.fromBigInt(await this.rollup.read.getPendingCheckpointNumber());
|
|
332
431
|
}
|
|
333
432
|
|
|
334
|
-
|
|
335
|
-
return this.rollup.read.
|
|
433
|
+
async getProvenCheckpointNumber(): Promise<CheckpointNumber> {
|
|
434
|
+
return CheckpointNumber.fromBigInt(await this.rollup.read.getProvenCheckpointNumber());
|
|
336
435
|
}
|
|
337
436
|
|
|
338
|
-
getSlotNumber() {
|
|
339
|
-
return this.rollup.read.getCurrentSlot();
|
|
437
|
+
async getSlotNumber(): Promise<SlotNumber> {
|
|
438
|
+
return SlotNumber.fromBigInt(await this.rollup.read.getCurrentSlot());
|
|
340
439
|
}
|
|
341
440
|
|
|
342
|
-
getL1FeesAt(timestamp: bigint) {
|
|
343
|
-
|
|
441
|
+
async getL1FeesAt(timestamp: bigint): Promise<L1FeeData> {
|
|
442
|
+
const result = await this.rollup.read.getL1FeesAt([timestamp]);
|
|
443
|
+
return {
|
|
444
|
+
baseFee: result.baseFee,
|
|
445
|
+
blobFee: result.blobFee,
|
|
446
|
+
};
|
|
344
447
|
}
|
|
345
448
|
|
|
346
|
-
getFeeAssetPerEth() {
|
|
449
|
+
getFeeAssetPerEth(): Promise<bigint> {
|
|
347
450
|
return this.rollup.read.getFeeAssetPerEth();
|
|
348
451
|
}
|
|
349
452
|
|
|
350
|
-
async getCommitteeAt(timestamp: bigint): Promise<
|
|
453
|
+
async getCommitteeAt(timestamp: bigint): Promise<EthAddress[] | undefined> {
|
|
351
454
|
const { result } = await this.client
|
|
352
455
|
.simulateContract({
|
|
353
456
|
address: this.address,
|
|
@@ -362,22 +465,22 @@ export class RollupContract {
|
|
|
362
465
|
throw e;
|
|
363
466
|
});
|
|
364
467
|
|
|
365
|
-
return result;
|
|
468
|
+
return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
|
|
366
469
|
}
|
|
367
470
|
|
|
368
|
-
getSampleSeedAt(timestamp: bigint) {
|
|
369
|
-
return this.rollup.read.getSampleSeedAt([timestamp]);
|
|
471
|
+
async getSampleSeedAt(timestamp: bigint): Promise<Buffer32> {
|
|
472
|
+
return Buffer32.fromBigInt(await this.rollup.read.getSampleSeedAt([timestamp]));
|
|
370
473
|
}
|
|
371
474
|
|
|
372
|
-
getCurrentSampleSeed() {
|
|
373
|
-
return this.rollup.read.getCurrentSampleSeed();
|
|
475
|
+
async getCurrentSampleSeed(): Promise<Buffer32> {
|
|
476
|
+
return Buffer32.fromBigInt(await this.rollup.read.getCurrentSampleSeed());
|
|
374
477
|
}
|
|
375
478
|
|
|
376
|
-
getCurrentEpoch() {
|
|
377
|
-
return this.rollup.read.getCurrentEpoch();
|
|
479
|
+
async getCurrentEpoch(): Promise<EpochNumber> {
|
|
480
|
+
return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
|
|
378
481
|
}
|
|
379
482
|
|
|
380
|
-
async getCurrentEpochCommittee(): Promise<
|
|
483
|
+
async getCurrentEpochCommittee(): Promise<EthAddress[] | undefined> {
|
|
381
484
|
const { result } = await this.client
|
|
382
485
|
.simulateContract({
|
|
383
486
|
address: this.address,
|
|
@@ -392,10 +495,10 @@ export class RollupContract {
|
|
|
392
495
|
throw e;
|
|
393
496
|
});
|
|
394
497
|
|
|
395
|
-
return result;
|
|
498
|
+
return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
|
|
396
499
|
}
|
|
397
500
|
|
|
398
|
-
async getCurrentProposer() {
|
|
501
|
+
async getCurrentProposer(): Promise<EthAddress> {
|
|
399
502
|
const { result } = await this.client.simulateContract({
|
|
400
503
|
address: this.address,
|
|
401
504
|
abi: RollupAbi,
|
|
@@ -403,10 +506,10 @@ export class RollupContract {
|
|
|
403
506
|
args: [],
|
|
404
507
|
});
|
|
405
508
|
|
|
406
|
-
return result;
|
|
509
|
+
return EthAddress.fromString(result);
|
|
407
510
|
}
|
|
408
511
|
|
|
409
|
-
async getProposerAt(timestamp: bigint) {
|
|
512
|
+
async getProposerAt(timestamp: bigint): Promise<EthAddress> {
|
|
410
513
|
const { result } = await this.client.simulateContract({
|
|
411
514
|
address: this.address,
|
|
412
515
|
abi: RollupAbi,
|
|
@@ -414,28 +517,73 @@ export class RollupContract {
|
|
|
414
517
|
args: [timestamp],
|
|
415
518
|
});
|
|
416
519
|
|
|
417
|
-
return result;
|
|
520
|
+
return EthAddress.fromString(result);
|
|
418
521
|
}
|
|
419
522
|
|
|
420
|
-
|
|
421
|
-
|
|
523
|
+
async getCheckpoint(checkpointNumber: CheckpointNumber): Promise<CheckpointLog> {
|
|
524
|
+
const result = await this.rollup.read.getCheckpoint([BigInt(checkpointNumber)]);
|
|
525
|
+
return {
|
|
526
|
+
archive: Fr.fromString(result.archive),
|
|
527
|
+
headerHash: Buffer32.fromString(result.headerHash),
|
|
528
|
+
blobCommitmentsHash: Buffer32.fromString(result.blobCommitmentsHash),
|
|
529
|
+
attestationsHash: Buffer32.fromString(result.attestationsHash),
|
|
530
|
+
payloadDigest: Buffer32.fromString(result.payloadDigest),
|
|
531
|
+
slotNumber: SlotNumber.fromBigInt(result.slotNumber),
|
|
532
|
+
feeHeader: {
|
|
533
|
+
excessMana: result.feeHeader.excessMana,
|
|
534
|
+
manaUsed: result.feeHeader.manaUsed,
|
|
535
|
+
feeAssetPriceNumerator: result.feeHeader.feeAssetPriceNumerator,
|
|
536
|
+
congestionCost: result.feeHeader.congestionCost,
|
|
537
|
+
proverCost: result.feeHeader.proverCost,
|
|
538
|
+
},
|
|
539
|
+
};
|
|
422
540
|
}
|
|
423
541
|
|
|
424
|
-
|
|
425
|
-
|
|
542
|
+
/** Returns the pending checkpoint from the rollup contract */
|
|
543
|
+
getPendingCheckpoint() {
|
|
544
|
+
// We retry because of race conditions during prunes: we may get a pending checkpoint number which is immediately
|
|
545
|
+
// reorged out due to a prune happening, causing the subsequent getCheckpoint call to fail. So we try again in that case.
|
|
546
|
+
return retry(
|
|
547
|
+
async () => {
|
|
548
|
+
const pendingCheckpointNumber = await this.getCheckpointNumber();
|
|
549
|
+
const pendingCheckpoint = await this.getCheckpoint(pendingCheckpointNumber);
|
|
550
|
+
return pendingCheckpoint;
|
|
551
|
+
},
|
|
552
|
+
'getting pending checkpoint',
|
|
553
|
+
makeBackoff([0.5, 0.5, 0.5]),
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
async getTips(): Promise<{ pending: CheckpointNumber; proven: CheckpointNumber }> {
|
|
558
|
+
const { pending, proven } = await this.rollup.read.getTips();
|
|
559
|
+
return {
|
|
560
|
+
pending: CheckpointNumber.fromBigInt(pending),
|
|
561
|
+
proven: CheckpointNumber.fromBigInt(proven),
|
|
562
|
+
};
|
|
426
563
|
}
|
|
427
564
|
|
|
428
|
-
getTimestampForSlot(slot:
|
|
429
|
-
return this.rollup.read.getTimestampForSlot([slot]);
|
|
565
|
+
getTimestampForSlot(slot: SlotNumber): Promise<bigint> {
|
|
566
|
+
return this.rollup.read.getTimestampForSlot([BigInt(slot)]);
|
|
430
567
|
}
|
|
431
568
|
|
|
432
|
-
getEntryQueueLength() {
|
|
433
|
-
return this.rollup.read.getEntryQueueLength();
|
|
569
|
+
async getEntryQueueLength(): Promise<number> {
|
|
570
|
+
return Number(await this.rollup.read.getEntryQueueLength());
|
|
434
571
|
}
|
|
435
572
|
|
|
436
|
-
async
|
|
437
|
-
|
|
438
|
-
|
|
573
|
+
async getAvailableValidatorFlushes(): Promise<number> {
|
|
574
|
+
return Number(await this.rollup.read.getAvailableValidatorFlushes());
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
async getNextFlushableEpoch(): Promise<EpochNumber> {
|
|
578
|
+
return EpochNumber.fromBigInt(await this.rollup.read.getNextFlushableEpoch());
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
async getCurrentEpochNumber(): Promise<EpochNumber> {
|
|
582
|
+
return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
async getEpochNumberForCheckpoint(checkpointNumber: CheckpointNumber): Promise<EpochNumber> {
|
|
586
|
+
return EpochNumber.fromBigInt(await this.rollup.read.getEpochForCheckpoint([BigInt(checkpointNumber)]));
|
|
439
587
|
}
|
|
440
588
|
|
|
441
589
|
async getRollupAddresses(): Promise<L1RollupContractAddresses> {
|
|
@@ -475,14 +623,15 @@ export class RollupContract {
|
|
|
475
623
|
return EthAddress.fromString(await this.rollup.read.getFeeAssetPortal());
|
|
476
624
|
}
|
|
477
625
|
|
|
478
|
-
public async getEpochNumberForSlotNumber(slotNumber:
|
|
479
|
-
return await this.rollup.read.getEpochAtSlot([slotNumber]);
|
|
626
|
+
public async getEpochNumberForSlotNumber(slotNumber: SlotNumber): Promise<EpochNumber> {
|
|
627
|
+
return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
|
|
480
628
|
}
|
|
481
629
|
|
|
482
|
-
getEpochProofPublicInputs(
|
|
630
|
+
async getEpochProofPublicInputs(
|
|
483
631
|
args: readonly [bigint, bigint, EpochProofPublicInputArgs, readonly `0x${string}`[], `0x${string}`],
|
|
484
|
-
) {
|
|
485
|
-
|
|
632
|
+
): Promise<Fr[]> {
|
|
633
|
+
const result = await this.rollup.read.getEpochProofPublicInputs(args);
|
|
634
|
+
return result.map(Fr.fromString);
|
|
486
635
|
}
|
|
487
636
|
|
|
488
637
|
public async validateHeader(
|
|
@@ -490,6 +639,7 @@ export class RollupContract {
|
|
|
490
639
|
ViemHeader,
|
|
491
640
|
ViemCommitteeAttestations,
|
|
492
641
|
`0x${string}`[],
|
|
642
|
+
ViemSignature,
|
|
493
643
|
`0x${string}`,
|
|
494
644
|
`0x${string}`,
|
|
495
645
|
{
|
|
@@ -512,130 +662,63 @@ export class RollupContract {
|
|
|
512
662
|
}
|
|
513
663
|
}
|
|
514
664
|
|
|
515
|
-
/**
|
|
516
|
-
* Packs an array of committee attestations into the format expected by the Solidity contract
|
|
517
|
-
*
|
|
518
|
-
* @param attestations - Array of committee attestations with addresses and signatures
|
|
519
|
-
* @returns Packed attestations with bitmap and tightly packed signature/address data
|
|
520
|
-
*/
|
|
521
|
-
static packAttestations(attestations: ViemCommitteeAttestation[]): ViemCommitteeAttestations {
|
|
522
|
-
const length = attestations.length;
|
|
523
|
-
|
|
524
|
-
// Calculate bitmap size (1 bit per attestation, rounded up to nearest byte)
|
|
525
|
-
const bitmapSize = Math.ceil(length / 8);
|
|
526
|
-
const signatureIndices = new Uint8Array(bitmapSize);
|
|
527
|
-
|
|
528
|
-
// Calculate total data size needed
|
|
529
|
-
let totalDataSize = 0;
|
|
530
|
-
for (let i = 0; i < length; i++) {
|
|
531
|
-
const signature = attestations[i].signature;
|
|
532
|
-
// Check if signature is empty (v = 0)
|
|
533
|
-
const isEmpty = signature.v === 0;
|
|
534
|
-
|
|
535
|
-
if (!isEmpty) {
|
|
536
|
-
totalDataSize += 65; // v (1) + r (32) + s (32)
|
|
537
|
-
} else {
|
|
538
|
-
totalDataSize += 20; // address only
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
const signaturesOrAddresses = new Uint8Array(totalDataSize);
|
|
543
|
-
let dataIndex = 0;
|
|
544
|
-
|
|
545
|
-
// Pack the data
|
|
546
|
-
for (let i = 0; i < length; i++) {
|
|
547
|
-
const attestation = attestations[i];
|
|
548
|
-
const signature = attestation.signature;
|
|
549
|
-
|
|
550
|
-
// Check if signature is empty
|
|
551
|
-
const isEmpty = signature.v === 0;
|
|
552
|
-
|
|
553
|
-
if (!isEmpty) {
|
|
554
|
-
// Set bit in bitmap (bit 7-0 in each byte, left to right)
|
|
555
|
-
const byteIndex = Math.floor(i / 8);
|
|
556
|
-
const bitIndex = 7 - (i % 8);
|
|
557
|
-
signatureIndices[byteIndex] |= 1 << bitIndex;
|
|
558
|
-
|
|
559
|
-
// Pack signature: v + r + s
|
|
560
|
-
signaturesOrAddresses[dataIndex] = signature.v;
|
|
561
|
-
dataIndex++;
|
|
562
|
-
|
|
563
|
-
// Pack r (32 bytes)
|
|
564
|
-
const rBytes = Buffer.from(signature.r.slice(2), 'hex');
|
|
565
|
-
signaturesOrAddresses.set(rBytes, dataIndex);
|
|
566
|
-
dataIndex += 32;
|
|
567
|
-
|
|
568
|
-
// Pack s (32 bytes)
|
|
569
|
-
const sBytes = Buffer.from(signature.s.slice(2), 'hex');
|
|
570
|
-
signaturesOrAddresses.set(sBytes, dataIndex);
|
|
571
|
-
dataIndex += 32;
|
|
572
|
-
} else {
|
|
573
|
-
// Pack address only (20 bytes)
|
|
574
|
-
const addrBytes = Buffer.from(attestation.addr.slice(2), 'hex');
|
|
575
|
-
signaturesOrAddresses.set(addrBytes, dataIndex);
|
|
576
|
-
dataIndex += 20;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
return {
|
|
581
|
-
signatureIndices: `0x${Buffer.from(signatureIndices).toString('hex')}`,
|
|
582
|
-
signaturesOrAddresses: `0x${Buffer.from(signaturesOrAddresses).toString('hex')}`,
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
|
|
586
665
|
/**
|
|
587
666
|
* @notice Calls `canProposeAtTime` with the time of the next Ethereum block and the sender address
|
|
588
667
|
*
|
|
589
668
|
* @dev Throws if unable to propose
|
|
590
669
|
*
|
|
591
670
|
* @param archive - The archive that we expect to be current state
|
|
592
|
-
* @return [slot,
|
|
671
|
+
* @return [slot, checkpointNumber, timeOfNextL1Slot] - If you can propose, the L2 slot number, checkpoint number and
|
|
672
|
+
* timestamp of the next L1 block
|
|
593
673
|
* @throws otherwise
|
|
594
674
|
*/
|
|
595
675
|
public async canProposeAtNextEthBlock(
|
|
596
676
|
archive: Buffer,
|
|
597
677
|
account: `0x${string}` | Account,
|
|
598
|
-
slotDuration:
|
|
599
|
-
opts: {
|
|
600
|
-
): Promise<{ slot:
|
|
601
|
-
if (typeof slotDuration === 'number') {
|
|
602
|
-
slotDuration = BigInt(slotDuration);
|
|
603
|
-
}
|
|
678
|
+
slotDuration: number,
|
|
679
|
+
opts: { forcePendingCheckpointNumber?: CheckpointNumber } = {},
|
|
680
|
+
): Promise<{ slot: SlotNumber; checkpointNumber: CheckpointNumber; timeOfNextL1Slot: bigint }> {
|
|
604
681
|
const latestBlock = await this.client.getBlock();
|
|
605
|
-
const timeOfNextL1Slot = latestBlock.timestamp + slotDuration;
|
|
682
|
+
const timeOfNextL1Slot = latestBlock.timestamp + BigInt(slotDuration);
|
|
606
683
|
const who = typeof account === 'string' ? account : account.address;
|
|
607
684
|
|
|
608
685
|
try {
|
|
609
686
|
const {
|
|
610
|
-
result: [slot,
|
|
687
|
+
result: [slot, checkpointNumber],
|
|
611
688
|
} = await this.client.simulateContract({
|
|
612
689
|
address: this.address,
|
|
613
690
|
abi: RollupAbi,
|
|
614
691
|
functionName: 'canProposeAtTime',
|
|
615
692
|
args: [timeOfNextL1Slot, `0x${archive.toString('hex')}`, who],
|
|
616
693
|
account,
|
|
617
|
-
stateOverride: await this.
|
|
694
|
+
stateOverride: await this.makePendingCheckpointNumberOverride(opts.forcePendingCheckpointNumber),
|
|
618
695
|
});
|
|
619
696
|
|
|
620
|
-
return {
|
|
697
|
+
return {
|
|
698
|
+
slot: SlotNumber.fromBigInt(slot),
|
|
699
|
+
checkpointNumber: CheckpointNumber.fromBigInt(checkpointNumber),
|
|
700
|
+
timeOfNextL1Slot,
|
|
701
|
+
};
|
|
621
702
|
} catch (err: unknown) {
|
|
622
703
|
throw formatViemError(err);
|
|
623
704
|
}
|
|
624
705
|
}
|
|
625
706
|
|
|
626
707
|
/**
|
|
627
|
-
* Returns a state override that sets the pending
|
|
628
|
-
* Requires querying the current state of the contract to get the current proven
|
|
708
|
+
* Returns a state override that sets the pending checkpoint number to the specified value. Useful for simulations.
|
|
709
|
+
* Requires querying the current state of the contract to get the current proven checkpoint number, as they are both
|
|
629
710
|
* stored in the same slot. If the argument is undefined, it returns an empty override.
|
|
630
711
|
*/
|
|
631
|
-
public async
|
|
632
|
-
|
|
712
|
+
public async makePendingCheckpointNumberOverride(
|
|
713
|
+
forcePendingCheckpointNumber: CheckpointNumber | undefined,
|
|
714
|
+
): Promise<StateOverride> {
|
|
715
|
+
if (forcePendingCheckpointNumber === undefined) {
|
|
633
716
|
return [];
|
|
634
717
|
}
|
|
635
718
|
const slot = RollupContract.stfStorageSlot;
|
|
636
719
|
const currentValue = await this.client.getStorageAt({ address: this.address, slot });
|
|
637
|
-
const
|
|
638
|
-
const newValue = (BigInt(
|
|
720
|
+
const currentProvenCheckpointNumber = currentValue ? hexToBigInt(currentValue) & ((1n << 128n) - 1n) : 0n;
|
|
721
|
+
const newValue = (BigInt(forcePendingCheckpointNumber) << 128n) | currentProvenCheckpointNumber;
|
|
639
722
|
return [
|
|
640
723
|
{
|
|
641
724
|
address: this.address,
|
|
@@ -646,8 +729,8 @@ export class RollupContract {
|
|
|
646
729
|
|
|
647
730
|
/** Creates a request to Rollup#invalidateBadAttestation to be simulated or sent */
|
|
648
731
|
public buildInvalidateBadAttestationRequest(
|
|
649
|
-
|
|
650
|
-
|
|
732
|
+
checkpointNumber: CheckpointNumber,
|
|
733
|
+
attestationsAndSigners: ViemCommitteeAttestations,
|
|
651
734
|
committee: EthAddress[],
|
|
652
735
|
invalidIndex: number,
|
|
653
736
|
): L1TxRequest {
|
|
@@ -657,8 +740,8 @@ export class RollupContract {
|
|
|
657
740
|
abi: RollupAbi,
|
|
658
741
|
functionName: 'invalidateBadAttestation',
|
|
659
742
|
args: [
|
|
660
|
-
BigInt(
|
|
661
|
-
|
|
743
|
+
BigInt(checkpointNumber),
|
|
744
|
+
attestationsAndSigners,
|
|
662
745
|
committee.map(addr => addr.toString()),
|
|
663
746
|
BigInt(invalidIndex),
|
|
664
747
|
],
|
|
@@ -668,8 +751,8 @@ export class RollupContract {
|
|
|
668
751
|
|
|
669
752
|
/** Creates a request to Rollup#invalidateInsufficientAttestations to be simulated or sent */
|
|
670
753
|
public buildInvalidateInsufficientAttestationsRequest(
|
|
671
|
-
|
|
672
|
-
|
|
754
|
+
checkpointNumber: CheckpointNumber,
|
|
755
|
+
attestationsAndSigners: ViemCommitteeAttestations,
|
|
673
756
|
committee: EthAddress[],
|
|
674
757
|
): L1TxRequest {
|
|
675
758
|
return {
|
|
@@ -677,98 +760,131 @@ export class RollupContract {
|
|
|
677
760
|
data: encodeFunctionData({
|
|
678
761
|
abi: RollupAbi,
|
|
679
762
|
functionName: 'invalidateInsufficientAttestations',
|
|
680
|
-
args: [
|
|
681
|
-
BigInt(blockNumber),
|
|
682
|
-
RollupContract.packAttestations(attestations),
|
|
683
|
-
committee.map(addr => addr.toString()),
|
|
684
|
-
],
|
|
763
|
+
args: [BigInt(checkpointNumber), attestationsAndSigners, committee.map(addr => addr.toString())],
|
|
685
764
|
}),
|
|
686
765
|
};
|
|
687
766
|
}
|
|
688
767
|
|
|
689
768
|
/** Calls getHasSubmitted directly. Returns whether the given prover has submitted a proof with the given length for the given epoch. */
|
|
690
|
-
public getHasSubmittedProof(epochNumber:
|
|
769
|
+
public getHasSubmittedProof(epochNumber: EpochNumber, numberOfCheckpointsInEpoch: number, prover: Hex | EthAddress) {
|
|
691
770
|
if (prover instanceof EthAddress) {
|
|
692
771
|
prover = prover.toString();
|
|
693
772
|
}
|
|
694
|
-
return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(
|
|
773
|
+
return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfCheckpointsInEpoch), prover]);
|
|
695
774
|
}
|
|
696
775
|
|
|
697
|
-
|
|
698
|
-
return this.rollup.read.
|
|
776
|
+
getManaMinFeeAt(timestamp: bigint, inFeeAsset: boolean): Promise<bigint> {
|
|
777
|
+
return this.rollup.read.getManaMinFeeAt([timestamp, inFeeAsset]);
|
|
699
778
|
}
|
|
700
779
|
|
|
701
|
-
getSlotAt(timestamp: bigint) {
|
|
702
|
-
return this.rollup.read.getSlotAt([timestamp]);
|
|
780
|
+
async getSlotAt(timestamp: bigint): Promise<SlotNumber> {
|
|
781
|
+
return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([timestamp]));
|
|
703
782
|
}
|
|
704
783
|
|
|
705
|
-
async status(
|
|
784
|
+
async status(checkpointNumber: CheckpointNumber, options?: { blockNumber?: bigint }): Promise<RollupStatusResponse> {
|
|
706
785
|
await checkBlockTag(options?.blockNumber, this.client);
|
|
707
|
-
|
|
786
|
+
const result = await this.rollup.read.status([BigInt(checkpointNumber)], options);
|
|
787
|
+
return {
|
|
788
|
+
provenCheckpointNumber: CheckpointNumber.fromBigInt(result[0]),
|
|
789
|
+
provenArchive: Fr.fromString(result[1]),
|
|
790
|
+
pendingCheckpointNumber: CheckpointNumber.fromBigInt(result[2]),
|
|
791
|
+
pendingArchive: Fr.fromString(result[3]),
|
|
792
|
+
archiveOfMyCheckpoint: Fr.fromString(result[4]),
|
|
793
|
+
};
|
|
708
794
|
}
|
|
709
795
|
|
|
710
|
-
async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }) {
|
|
796
|
+
async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }): Promise<boolean> {
|
|
711
797
|
await checkBlockTag(options?.blockNumber, this.client);
|
|
712
798
|
return this.rollup.read.canPruneAtTime([timestamp], options);
|
|
713
799
|
}
|
|
714
800
|
|
|
715
|
-
archive() {
|
|
716
|
-
return this.rollup.read.archive();
|
|
801
|
+
async archive(): Promise<Fr> {
|
|
802
|
+
return Fr.fromString(await this.rollup.read.archive());
|
|
717
803
|
}
|
|
718
804
|
|
|
719
|
-
archiveAt(
|
|
720
|
-
return this.rollup.read.archiveAt([
|
|
805
|
+
async archiveAt(checkpointNumber: CheckpointNumber): Promise<Fr> {
|
|
806
|
+
return Fr.fromString(await this.rollup.read.archiveAt([BigInt(checkpointNumber)]));
|
|
721
807
|
}
|
|
722
808
|
|
|
723
|
-
getSequencerRewards(address: Hex | EthAddress) {
|
|
809
|
+
getSequencerRewards(address: Hex | EthAddress): Promise<bigint> {
|
|
724
810
|
if (address instanceof EthAddress) {
|
|
725
811
|
address = address.toString();
|
|
726
812
|
}
|
|
727
813
|
return this.rollup.read.getSequencerRewards([address]);
|
|
728
814
|
}
|
|
729
815
|
|
|
730
|
-
getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress) {
|
|
816
|
+
getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress): Promise<bigint> {
|
|
731
817
|
if (prover instanceof EthAddress) {
|
|
732
818
|
prover = prover.toString();
|
|
733
819
|
}
|
|
734
820
|
return this.rollup.read.getSpecificProverRewardsForEpoch([epoch, prover]);
|
|
735
821
|
}
|
|
736
822
|
|
|
737
|
-
async getAttesters() {
|
|
823
|
+
async getAttesters(): Promise<EthAddress[]> {
|
|
738
824
|
const attesterSize = await this.getActiveAttesterCount();
|
|
739
825
|
const gse = new GSEContract(this.client, await this.getGSE());
|
|
740
826
|
const ts = (await this.client.getBlock()).timestamp;
|
|
741
827
|
|
|
742
|
-
const indices = Array.from({ length:
|
|
828
|
+
const indices = Array.from({ length: attesterSize }, (_, i) => BigInt(i));
|
|
743
829
|
const chunks = chunk(indices, 1000);
|
|
744
830
|
|
|
745
|
-
|
|
831
|
+
const results = await Promise.all(chunks.map(chunk => gse.getAttestersFromIndicesAtTime(this.address, ts, chunk)));
|
|
832
|
+
return results.flat().map(addr => EthAddress.fromString(addr));
|
|
746
833
|
}
|
|
747
834
|
|
|
748
|
-
getAttesterView(address: Hex | EthAddress) {
|
|
835
|
+
async getAttesterView(address: Hex | EthAddress): Promise<AttesterView> {
|
|
749
836
|
if (address instanceof EthAddress) {
|
|
750
837
|
address = address.toString();
|
|
751
838
|
}
|
|
752
|
-
|
|
839
|
+
const result = await this.rollup.read.getAttesterView([address]);
|
|
840
|
+
return {
|
|
841
|
+
status: result.status as AttesterStatus,
|
|
842
|
+
effectiveBalance: result.effectiveBalance,
|
|
843
|
+
exit: {
|
|
844
|
+
withdrawalId: result.exit.withdrawalId,
|
|
845
|
+
amount: result.exit.amount,
|
|
846
|
+
exitableAt: result.exit.exitableAt,
|
|
847
|
+
recipientOrWithdrawer: EthAddress.fromString(result.exit.recipientOrWithdrawer),
|
|
848
|
+
isRecipient: result.exit.isRecipient,
|
|
849
|
+
exists: result.exit.exists,
|
|
850
|
+
},
|
|
851
|
+
config: {
|
|
852
|
+
publicKey: {
|
|
853
|
+
x: result.config.publicKey.x,
|
|
854
|
+
y: result.config.publicKey.y,
|
|
855
|
+
},
|
|
856
|
+
withdrawer: EthAddress.fromString(result.config.withdrawer),
|
|
857
|
+
},
|
|
858
|
+
};
|
|
753
859
|
}
|
|
754
860
|
|
|
755
|
-
getStatus(address: Hex | EthAddress) {
|
|
861
|
+
async getStatus(address: Hex | EthAddress): Promise<AttesterStatus> {
|
|
756
862
|
if (address instanceof EthAddress) {
|
|
757
863
|
address = address.toString();
|
|
758
864
|
}
|
|
759
|
-
return this.rollup.read.getStatus([address]);
|
|
865
|
+
return (await this.rollup.read.getStatus([address])) as AttesterStatus;
|
|
760
866
|
}
|
|
761
867
|
|
|
762
|
-
getBlobCommitmentsHash(
|
|
763
|
-
return this.rollup.read.getBlobCommitmentsHash([
|
|
868
|
+
async getBlobCommitmentsHash(checkpointNumber: CheckpointNumber): Promise<Buffer32> {
|
|
869
|
+
return Buffer32.fromString(await this.rollup.read.getBlobCommitmentsHash([BigInt(checkpointNumber)]));
|
|
764
870
|
}
|
|
765
871
|
|
|
766
|
-
getCurrentBlobCommitmentsHash() {
|
|
767
|
-
return this.rollup.read.getCurrentBlobCommitmentsHash();
|
|
872
|
+
async getCurrentBlobCommitmentsHash(): Promise<Buffer32> {
|
|
873
|
+
return Buffer32.fromString(await this.rollup.read.getCurrentBlobCommitmentsHash());
|
|
768
874
|
}
|
|
769
875
|
|
|
770
|
-
getStakingAsset() {
|
|
771
|
-
return this.rollup.read.getStakingAsset();
|
|
876
|
+
async getStakingAsset(): Promise<EthAddress> {
|
|
877
|
+
return EthAddress.fromString(await this.rollup.read.getStakingAsset());
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
async getRewardConfig(): Promise<RewardConfig> {
|
|
881
|
+
const result = await this.rollup.read.getRewardConfig();
|
|
882
|
+
return {
|
|
883
|
+
rewardDistributor: EthAddress.fromString(result.rewardDistributor),
|
|
884
|
+
sequencerBps: BigInt(result.sequencerBps),
|
|
885
|
+
booster: EthAddress.fromString(result.booster),
|
|
886
|
+
checkpointReward: result.checkpointReward,
|
|
887
|
+
};
|
|
772
888
|
}
|
|
773
889
|
|
|
774
890
|
setupEpoch(l1TxUtils: L1TxUtils) {
|
|
@@ -793,7 +909,9 @@ export class RollupContract {
|
|
|
793
909
|
});
|
|
794
910
|
}
|
|
795
911
|
|
|
796
|
-
public listenToSlasherChanged(
|
|
912
|
+
public listenToSlasherChanged(
|
|
913
|
+
callback: (args: { oldSlasher: `0x${string}`; newSlasher: `0x${string}` }) => unknown,
|
|
914
|
+
): WatchContractEventReturnType {
|
|
797
915
|
return this.rollup.watchEvent.SlasherUpdated(
|
|
798
916
|
{},
|
|
799
917
|
{
|
|
@@ -809,6 +927,24 @@ export class RollupContract {
|
|
|
809
927
|
);
|
|
810
928
|
}
|
|
811
929
|
|
|
930
|
+
public listenToCheckpointInvalidated(
|
|
931
|
+
callback: (args: { checkpointNumber: CheckpointNumber }) => unknown,
|
|
932
|
+
): WatchContractEventReturnType {
|
|
933
|
+
return this.rollup.watchEvent.CheckpointInvalidated(
|
|
934
|
+
{},
|
|
935
|
+
{
|
|
936
|
+
onLogs: logs => {
|
|
937
|
+
for (const log of logs) {
|
|
938
|
+
const args = log.args;
|
|
939
|
+
if (args.checkpointNumber !== undefined) {
|
|
940
|
+
callback({ checkpointNumber: CheckpointNumber.fromBigInt(args.checkpointNumber) });
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
},
|
|
944
|
+
},
|
|
945
|
+
);
|
|
946
|
+
}
|
|
947
|
+
|
|
812
948
|
public async getSlashEvents(l1BlockHash: Hex): Promise<{ amount: bigint; attester: EthAddress }[]> {
|
|
813
949
|
const events = await this.rollup.getEvents.Slashed({}, { blockHash: l1BlockHash, strict: true });
|
|
814
950
|
return events.map(event => ({
|
|
@@ -817,7 +953,9 @@ export class RollupContract {
|
|
|
817
953
|
}));
|
|
818
954
|
}
|
|
819
955
|
|
|
820
|
-
public listenToSlash(
|
|
956
|
+
public listenToSlash(
|
|
957
|
+
callback: (args: { amount: bigint; attester: EthAddress }) => unknown,
|
|
958
|
+
): WatchContractEventReturnType {
|
|
821
959
|
return this.rollup.watchEvent.Slashed(
|
|
822
960
|
{},
|
|
823
961
|
{
|