@aztec/ethereum 3.0.0-nightly.20250908 → 3.0.0-nightly.20250911
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/config.d.ts +3 -4
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +88 -44
- package/dest/contracts/empire_slashing_proposer.d.ts +1 -1
- package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/empire_slashing_proposer.js +1 -1
- package/dest/contracts/rollup.d.ts +6 -11
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +26 -83
- package/dest/deploy_l1_contracts.d.ts.map +1 -1
- package/dest/deploy_l1_contracts.js +7 -7
- package/dest/l1_artifacts.d.ts +864 -261
- package/dest/l1_artifacts.d.ts.map +1 -1
- package/dest/l1_tx_utils.d.ts +4 -2
- package/dest/l1_tx_utils.d.ts.map +1 -1
- package/dest/l1_tx_utils.js +17 -12
- package/dest/l1_tx_utils_with_blobs.d.ts +2 -1
- package/dest/l1_tx_utils_with_blobs.d.ts.map +1 -1
- package/dest/l1_tx_utils_with_blobs.js +7 -5
- package/dest/queries.d.ts.map +1 -1
- package/dest/queries.js +6 -11
- package/package.json +5 -5
- package/src/config.ts +98 -47
- package/src/contracts/empire_slashing_proposer.ts +6 -2
- package/src/contracts/rollup.ts +26 -97
- package/src/deploy_l1_contracts.ts +5 -7
- package/src/l1_tx_utils.ts +17 -7
- package/src/l1_tx_utils_with_blobs.ts +8 -2
- package/src/queries.ts +6 -7
package/dest/queries.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
-
import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
|
|
3
|
-
import { getContract } from 'viem';
|
|
4
2
|
import { ReadOnlyGovernanceContract } from './contracts/governance.js';
|
|
5
3
|
import { GovernanceProposerContract } from './contracts/governance_proposer.js';
|
|
6
4
|
import { RollupContract } from './contracts/rollup.js';
|
|
@@ -11,13 +9,8 @@ import { RollupContract } from './contracts/rollup.js';
|
|
|
11
9
|
const rollupAddress = addresses.rollupAddress ?? await governanceProposer.getRollupAddress();
|
|
12
10
|
const rollup = new RollupContract(publicClient, rollupAddress.toString());
|
|
13
11
|
const slasherProposer = await rollup.getSlashingProposer();
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
address: slasherAddress,
|
|
17
|
-
abi: SlasherAbi,
|
|
18
|
-
client: publicClient
|
|
19
|
-
});
|
|
20
|
-
const [l1StartBlock, l1GenesisTime, aztecEpochDuration, aztecSlotDuration, aztecProofSubmissionEpochs, aztecTargetCommitteeSize, activationThreshold, ejectionThreshold, governanceProposerQuorum, governanceProposerRoundSize, slashingQuorum, slashingRoundSize, slashingLifetimeInRounds, slashingExecutionDelayInRounds, slashingOffsetInRounds, slashingAmounts, slashingVetoer, manaTarget, provingCostPerMana, rollupVersion, genesisArchiveTreeRoot, exitDelay] = await Promise.all([
|
|
12
|
+
const slasher = await rollup.getSlasherContract();
|
|
13
|
+
const [l1StartBlock, l1GenesisTime, aztecEpochDuration, aztecSlotDuration, aztecProofSubmissionEpochs, aztecTargetCommitteeSize, activationThreshold, ejectionThreshold, localEjectionThreshold, governanceProposerQuorum, governanceProposerRoundSize, slashingQuorum, slashingRoundSize, slashingLifetimeInRounds, slashingExecutionDelayInRounds, slashingOffsetInRounds, slashingAmounts, slashingVetoer, manaTarget, provingCostPerMana, rollupVersion, genesisArchiveTreeRoot, exitDelay] = await Promise.all([
|
|
21
14
|
rollup.getL1StartBlock(),
|
|
22
15
|
rollup.getL1GenesisTime(),
|
|
23
16
|
rollup.getEpochDuration(),
|
|
@@ -26,6 +19,7 @@ import { RollupContract } from './contracts/rollup.js';
|
|
|
26
19
|
rollup.getTargetCommitteeSize(),
|
|
27
20
|
rollup.getActivationThreshold(),
|
|
28
21
|
rollup.getEjectionThreshold(),
|
|
22
|
+
rollup.getLocalEjectionThreshold(),
|
|
29
23
|
governanceProposer.getQuorumSize(),
|
|
30
24
|
governanceProposer.getRoundSize(),
|
|
31
25
|
slasherProposer?.getQuorumSize() ?? 0n,
|
|
@@ -38,7 +32,7 @@ import { RollupContract } from './contracts/rollup.js';
|
|
|
38
32
|
0n,
|
|
39
33
|
0n
|
|
40
34
|
],
|
|
41
|
-
slasher
|
|
35
|
+
slasher?.getVetoer() ?? EthAddress.ZERO,
|
|
42
36
|
rollup.getManaTarget(),
|
|
43
37
|
rollup.getProvingCostPerMana(),
|
|
44
38
|
rollup.getVersion(),
|
|
@@ -56,11 +50,12 @@ import { RollupContract } from './contracts/rollup.js';
|
|
|
56
50
|
governanceProposerRoundSize: Number(governanceProposerRoundSize),
|
|
57
51
|
activationThreshold,
|
|
58
52
|
ejectionThreshold,
|
|
53
|
+
localEjectionThreshold,
|
|
59
54
|
slashingQuorum: Number(slashingQuorum),
|
|
60
55
|
slashingRoundSizeInEpochs: Number(slashingRoundSize / aztecEpochDuration),
|
|
61
56
|
slashingLifetimeInRounds: Number(slashingLifetimeInRounds),
|
|
62
57
|
slashingExecutionDelayInRounds: Number(slashingExecutionDelayInRounds),
|
|
63
|
-
slashingVetoer
|
|
58
|
+
slashingVetoer,
|
|
64
59
|
manaTarget: manaTarget,
|
|
65
60
|
provingCostPerMana: provingCostPerMana,
|
|
66
61
|
rollupVersion: Number(rollupVersion),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/ethereum",
|
|
3
|
-
"version": "3.0.0-nightly.
|
|
3
|
+
"version": "3.0.0-nightly.20250911",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"../package.common.json"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@aztec/blob-lib": "3.0.0-nightly.
|
|
35
|
-
"@aztec/constants": "3.0.0-nightly.
|
|
36
|
-
"@aztec/foundation": "3.0.0-nightly.
|
|
37
|
-
"@aztec/l1-artifacts": "3.0.0-nightly.
|
|
34
|
+
"@aztec/blob-lib": "3.0.0-nightly.20250911",
|
|
35
|
+
"@aztec/constants": "3.0.0-nightly.20250911",
|
|
36
|
+
"@aztec/foundation": "3.0.0-nightly.20250911",
|
|
37
|
+
"@aztec/l1-artifacts": "3.0.0-nightly.20250911",
|
|
38
38
|
"@viem/anvil": "^0.0.10",
|
|
39
39
|
"dotenv": "^16.0.3",
|
|
40
40
|
"lodash.chunk": "^4.2.0",
|
package/src/config.ts
CHANGED
|
@@ -34,6 +34,8 @@ export type L1ContractsConfig = {
|
|
|
34
34
|
activationThreshold: bigint;
|
|
35
35
|
/** The minimum stake for a validator. */
|
|
36
36
|
ejectionThreshold: bigint;
|
|
37
|
+
/** The local ejection threshold for a validator. Stricter than ejectionThreshold but local to a specific rollup */
|
|
38
|
+
localEjectionThreshold: bigint;
|
|
37
39
|
/** The slashing quorum, i.e. how many slots must signal for the same payload in a round for it to be submittable to the Slasher (defaults to slashRoundSize / 2 + 1) */
|
|
38
40
|
slashingQuorum?: number;
|
|
39
41
|
/** The slashing round size, i.e. how many epochs are in a slashing round */
|
|
@@ -74,6 +76,7 @@ export const DefaultL1ContractsConfig = {
|
|
|
74
76
|
aztecProofSubmissionEpochs: 1, // you have a full epoch to submit a proof after the epoch to prove ends
|
|
75
77
|
activationThreshold: BigInt(100e18),
|
|
76
78
|
ejectionThreshold: BigInt(50e18),
|
|
79
|
+
localEjectionThreshold: BigInt(98e18),
|
|
77
80
|
slashAmountSmall: BigInt(10e18),
|
|
78
81
|
slashAmountMedium: BigInt(20e18),
|
|
79
82
|
slashAmountLarge: BigInt(50e18),
|
|
@@ -103,6 +106,20 @@ const LocalGovernanceConfiguration = {
|
|
|
103
106
|
minimumVotes: 400n * 10n ** 18n,
|
|
104
107
|
};
|
|
105
108
|
|
|
109
|
+
const StagingPublicGovernanceConfiguration = {
|
|
110
|
+
proposeConfig: {
|
|
111
|
+
lockDelay: 60n * 60n * 24n * 30n,
|
|
112
|
+
lockAmount: DefaultL1ContractsConfig.activationThreshold * 100n,
|
|
113
|
+
},
|
|
114
|
+
votingDelay: 60n,
|
|
115
|
+
votingDuration: 60n * 60n,
|
|
116
|
+
executionDelay: 60n,
|
|
117
|
+
gracePeriod: 60n * 60n * 24n * 7n,
|
|
118
|
+
quorum: 3n * 10n ** 17n, // 30%
|
|
119
|
+
requiredYeaMargin: 4n * 10n ** 16n, // 4%
|
|
120
|
+
minimumVotes: DefaultL1ContractsConfig.ejectionThreshold * 200n, // >= 200 validators must vote
|
|
121
|
+
};
|
|
122
|
+
|
|
106
123
|
const TestnetGovernanceConfiguration = {
|
|
107
124
|
proposeConfig: {
|
|
108
125
|
lockDelay: 60n * 60n * 24n,
|
|
@@ -117,51 +134,41 @@ const TestnetGovernanceConfiguration = {
|
|
|
117
134
|
minimumVotes: DefaultL1ContractsConfig.ejectionThreshold * 200n,
|
|
118
135
|
};
|
|
119
136
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
case 'local':
|
|
126
|
-
return LocalGovernanceConfiguration;
|
|
127
|
-
default:
|
|
128
|
-
throw new Error('Unrecognized network name: ' + networkName);
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const TestnetGSEConfiguration = {
|
|
133
|
-
activationThreshold: BigInt(100e18),
|
|
134
|
-
ejectionThreshold: BigInt(50e18),
|
|
135
|
-
};
|
|
137
|
+
const StagingIgnitionGovernanceConfiguration = {
|
|
138
|
+
proposeConfig: {
|
|
139
|
+
lockDelay: 60n * 60n * 24n * 30n, // 30 days
|
|
140
|
+
lockAmount: DefaultL1ContractsConfig.activationThreshold * 100n,
|
|
141
|
+
},
|
|
136
142
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
143
|
+
votingDelay: 60n,
|
|
144
|
+
votingDuration: 60n * 60n,
|
|
145
|
+
executionDelay: 60n,
|
|
146
|
+
gracePeriod: 60n * 60n * 24n * 7n,
|
|
147
|
+
quorum: 3n * 10n ** 17n, // 30%
|
|
148
|
+
requiredYeaMargin: 4n * 10n ** 16n, // 4%
|
|
149
|
+
minimumVotes: DefaultL1ContractsConfig.ejectionThreshold * 200n, // >= 200 validators must vote
|
|
140
150
|
};
|
|
141
151
|
|
|
142
|
-
export const
|
|
152
|
+
export const getGovernanceConfiguration = (networkName: NetworkNames) => {
|
|
143
153
|
switch (networkName) {
|
|
144
|
-
case 'alpha-testnet':
|
|
145
|
-
case 'testnet':
|
|
146
|
-
return TestnetGSEConfiguration;
|
|
147
154
|
case 'local':
|
|
148
|
-
return
|
|
155
|
+
return LocalGovernanceConfiguration;
|
|
156
|
+
case 'staging-public':
|
|
157
|
+
return StagingPublicGovernanceConfiguration;
|
|
158
|
+
case 'testnet':
|
|
159
|
+
return TestnetGovernanceConfiguration;
|
|
160
|
+
case 'staging-ignition':
|
|
161
|
+
return StagingIgnitionGovernanceConfiguration;
|
|
149
162
|
default:
|
|
150
|
-
throw new Error(
|
|
163
|
+
throw new Error(`Unrecognized network name: ${networkName}`);
|
|
151
164
|
}
|
|
152
165
|
};
|
|
153
166
|
|
|
154
167
|
// Making a default config here as we are only using it thought the deployment
|
|
155
168
|
// and do not expect to be using different setups, so having environment variables
|
|
156
169
|
// for it seems overkill
|
|
157
|
-
const LocalRewardConfig = {
|
|
158
|
-
sequencerBps: 5000,
|
|
159
|
-
rewardDistributor: EthAddress.ZERO.toString(),
|
|
160
|
-
booster: EthAddress.ZERO.toString(),
|
|
161
|
-
blockReward: BigInt(50e18),
|
|
162
|
-
};
|
|
163
170
|
|
|
164
|
-
const
|
|
171
|
+
const DefaultRewardConfig = {
|
|
165
172
|
sequencerBps: 5000,
|
|
166
173
|
rewardDistributor: EthAddress.ZERO.toString(),
|
|
167
174
|
booster: EthAddress.ZERO.toString(),
|
|
@@ -170,13 +177,13 @@ const TestnetRewardConfig = {
|
|
|
170
177
|
|
|
171
178
|
export const getRewardConfig = (networkName: NetworkNames) => {
|
|
172
179
|
switch (networkName) {
|
|
173
|
-
case 'alpha-testnet':
|
|
174
|
-
case 'testnet':
|
|
175
|
-
return TestnetRewardConfig;
|
|
176
180
|
case 'local':
|
|
177
|
-
|
|
181
|
+
case 'staging-public':
|
|
182
|
+
case 'testnet':
|
|
183
|
+
case 'staging-ignition':
|
|
184
|
+
return DefaultRewardConfig;
|
|
178
185
|
default:
|
|
179
|
-
throw new Error(
|
|
186
|
+
throw new Error(`Unrecognized network name: ${networkName}`);
|
|
180
187
|
}
|
|
181
188
|
};
|
|
182
189
|
|
|
@@ -188,6 +195,14 @@ const LocalRewardBoostConfig = {
|
|
|
188
195
|
minimum: 100000,
|
|
189
196
|
};
|
|
190
197
|
|
|
198
|
+
const StagingPublicRewardBoostConfig = {
|
|
199
|
+
increment: 200000,
|
|
200
|
+
maxScore: 5000000,
|
|
201
|
+
a: 5000,
|
|
202
|
+
k: 1000000,
|
|
203
|
+
minimum: 100000,
|
|
204
|
+
};
|
|
205
|
+
|
|
191
206
|
const TestnetRewardBoostConfig = {
|
|
192
207
|
increment: 125000,
|
|
193
208
|
maxScore: 15000000,
|
|
@@ -196,15 +211,26 @@ const TestnetRewardBoostConfig = {
|
|
|
196
211
|
minimum: 100000,
|
|
197
212
|
};
|
|
198
213
|
|
|
214
|
+
const StagingIgnitionRewardBoostConfig = {
|
|
215
|
+
increment: 200000,
|
|
216
|
+
maxScore: 5000000,
|
|
217
|
+
a: 5000,
|
|
218
|
+
k: 1000000,
|
|
219
|
+
minimum: 100000,
|
|
220
|
+
};
|
|
221
|
+
|
|
199
222
|
export const getRewardBoostConfig = (networkName: NetworkNames) => {
|
|
200
223
|
switch (networkName) {
|
|
201
|
-
case 'alpha-testnet':
|
|
202
|
-
case 'testnet':
|
|
203
|
-
return TestnetRewardBoostConfig;
|
|
204
224
|
case 'local':
|
|
205
225
|
return LocalRewardBoostConfig;
|
|
226
|
+
case 'staging-public':
|
|
227
|
+
return StagingPublicRewardBoostConfig;
|
|
228
|
+
case 'testnet':
|
|
229
|
+
return TestnetRewardBoostConfig;
|
|
230
|
+
case 'staging-ignition':
|
|
231
|
+
return StagingIgnitionRewardBoostConfig;
|
|
206
232
|
default:
|
|
207
|
-
throw new Error(
|
|
233
|
+
throw new Error(`Unrecognized network name: ${networkName}`);
|
|
208
234
|
}
|
|
209
235
|
};
|
|
210
236
|
|
|
@@ -214,12 +240,28 @@ const LocalEntryQueueConfig = {
|
|
|
214
240
|
bootstrapFlushSize: 0n,
|
|
215
241
|
normalFlushSizeMin: 48n, // will effectively be bounded by maxQueueFlushSize
|
|
216
242
|
normalFlushSizeQuotient: 2n,
|
|
217
|
-
maxQueueFlushSize:
|
|
243
|
+
maxQueueFlushSize: 32n,
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const StagingPublicEntryQueueConfig = {
|
|
247
|
+
bootstrapValidatorSetSize: 48n,
|
|
248
|
+
bootstrapFlushSize: 48n, // will effectively be bounded by maxQueueFlushSize
|
|
249
|
+
normalFlushSizeMin: 1n,
|
|
250
|
+
normalFlushSizeQuotient: 2475n,
|
|
251
|
+
maxQueueFlushSize: 32n, // Limited to 32 so flush cost are kept below 15M gas.
|
|
218
252
|
};
|
|
219
253
|
|
|
220
254
|
const TestnetEntryQueueConfig = {
|
|
221
255
|
bootstrapValidatorSetSize: 750n,
|
|
222
|
-
bootstrapFlushSize:
|
|
256
|
+
bootstrapFlushSize: 48n, // will effectively be bounded by maxQueueFlushSize
|
|
257
|
+
normalFlushSizeMin: 1n,
|
|
258
|
+
normalFlushSizeQuotient: 2475n,
|
|
259
|
+
maxQueueFlushSize: 32n, // Limited to 32 so flush cost are kept below 15M gas.
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const StagingIgnitionEntryQueueConfig = {
|
|
263
|
+
bootstrapValidatorSetSize: 750n,
|
|
264
|
+
bootstrapFlushSize: 48n, // will effectively be bounded by maxQueueFlushSize
|
|
223
265
|
normalFlushSizeMin: 1n,
|
|
224
266
|
normalFlushSizeQuotient: 2475n,
|
|
225
267
|
maxQueueFlushSize: 32n, // Limited to 32 so flush cost are kept below 15M gas.
|
|
@@ -227,13 +269,16 @@ const TestnetEntryQueueConfig = {
|
|
|
227
269
|
|
|
228
270
|
export const getEntryQueueConfig = (networkName: NetworkNames) => {
|
|
229
271
|
switch (networkName) {
|
|
230
|
-
case 'alpha-testnet':
|
|
231
|
-
case 'testnet':
|
|
232
|
-
return TestnetEntryQueueConfig;
|
|
233
272
|
case 'local':
|
|
234
273
|
return LocalEntryQueueConfig;
|
|
274
|
+
case 'staging-public':
|
|
275
|
+
return StagingPublicEntryQueueConfig;
|
|
276
|
+
case 'testnet':
|
|
277
|
+
return TestnetEntryQueueConfig;
|
|
278
|
+
case 'staging-ignition':
|
|
279
|
+
return StagingIgnitionEntryQueueConfig;
|
|
235
280
|
default:
|
|
236
|
-
throw new Error(
|
|
281
|
+
throw new Error(`Unrecognized network name: ${networkName}`);
|
|
237
282
|
}
|
|
238
283
|
};
|
|
239
284
|
|
|
@@ -273,6 +318,12 @@ export const l1ContractsConfigMappings: ConfigMappingsType<L1ContractsConfig> =
|
|
|
273
318
|
description: 'The minimum stake for a validator.',
|
|
274
319
|
...bigintConfigHelper(DefaultL1ContractsConfig.ejectionThreshold),
|
|
275
320
|
},
|
|
321
|
+
localEjectionThreshold: {
|
|
322
|
+
env: 'AZTEC_LOCAL_EJECTION_THRESHOLD',
|
|
323
|
+
description:
|
|
324
|
+
'The local ejection threshold for a validator. Stricter than ejectionThreshold but local to a specific rollup',
|
|
325
|
+
...bigintConfigHelper(DefaultL1ContractsConfig.localEjectionThreshold),
|
|
326
|
+
},
|
|
276
327
|
slashingOffsetInRounds: {
|
|
277
328
|
env: 'AZTEC_SLASHING_OFFSET_IN_ROUNDS',
|
|
278
329
|
description:
|
|
@@ -33,10 +33,14 @@ export class EmpireSlashingProposerContract extends EventEmitter implements IEmp
|
|
|
33
33
|
|
|
34
34
|
constructor(
|
|
35
35
|
public readonly client: ViemClient,
|
|
36
|
-
address: Hex,
|
|
36
|
+
address: Hex | EthAddress,
|
|
37
37
|
) {
|
|
38
38
|
super();
|
|
39
|
-
this.proposer = getContract({
|
|
39
|
+
this.proposer = getContract({
|
|
40
|
+
address: typeof address === 'string' ? address : address.toString(),
|
|
41
|
+
abi: EmpireSlashingProposerAbi,
|
|
42
|
+
client,
|
|
43
|
+
});
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
public get address() {
|
package/src/contracts/rollup.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
3
3
|
import type { ViemSignature } from '@aztec/foundation/eth-signature';
|
|
4
4
|
import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
|
|
5
5
|
import { RollupStorage } from '@aztec/l1-artifacts/RollupStorage';
|
|
6
|
-
import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
|
|
7
6
|
|
|
8
7
|
import chunk from 'lodash.chunk';
|
|
9
8
|
import {
|
|
@@ -12,7 +11,6 @@ import {
|
|
|
12
11
|
type Hex,
|
|
13
12
|
type StateOverride,
|
|
14
13
|
encodeFunctionData,
|
|
15
|
-
getAddress,
|
|
16
14
|
getContract,
|
|
17
15
|
hexToBigInt,
|
|
18
16
|
keccak256,
|
|
@@ -160,13 +158,12 @@ export class RollupContract {
|
|
|
160
158
|
public async getSlashingProposer(): Promise<
|
|
161
159
|
EmpireSlashingProposerContract | TallySlashingProposerContract | undefined
|
|
162
160
|
> {
|
|
163
|
-
const
|
|
164
|
-
if (
|
|
161
|
+
const slasher = await this.getSlasherContract();
|
|
162
|
+
if (!slasher) {
|
|
165
163
|
return undefined;
|
|
166
164
|
}
|
|
167
165
|
|
|
168
|
-
const
|
|
169
|
-
const proposerAddress = await slasher.read.PROPOSER();
|
|
166
|
+
const proposerAddress = await slasher.getProposer();
|
|
170
167
|
const proposerAbi = [
|
|
171
168
|
{
|
|
172
169
|
type: 'function',
|
|
@@ -177,7 +174,7 @@ export class RollupContract {
|
|
|
177
174
|
},
|
|
178
175
|
] as const;
|
|
179
176
|
|
|
180
|
-
const proposer = getContract({ address: proposerAddress, abi: proposerAbi, client: this.client });
|
|
177
|
+
const proposer = getContract({ address: proposerAddress.toString(), abi: proposerAbi, client: this.client });
|
|
181
178
|
const proposerType = await proposer.read.SLASHING_PROPOSER_TYPE();
|
|
182
179
|
if (proposerType === SlashingProposerType.Tally.valueOf()) {
|
|
183
180
|
return new TallySlashingProposerContract(this.client, proposerAddress);
|
|
@@ -223,6 +220,11 @@ export class RollupContract {
|
|
|
223
220
|
return this.rollup.read.getEjectionThreshold();
|
|
224
221
|
}
|
|
225
222
|
|
|
223
|
+
@memoize
|
|
224
|
+
getLocalEjectionThreshold() {
|
|
225
|
+
return this.rollup.read.getLocalEjectionThreshold();
|
|
226
|
+
}
|
|
227
|
+
|
|
226
228
|
@memoize
|
|
227
229
|
getActivationThreshold() {
|
|
228
230
|
return this.rollup.read.getActivationThreshold();
|
|
@@ -293,16 +295,19 @@ export class RollupContract {
|
|
|
293
295
|
};
|
|
294
296
|
}
|
|
295
297
|
|
|
296
|
-
|
|
298
|
+
getSlasherAddress() {
|
|
297
299
|
return this.rollup.read.getSlasher();
|
|
298
300
|
}
|
|
299
301
|
|
|
300
302
|
/**
|
|
301
303
|
* Returns a SlasherContract instance for interacting with the slasher contract.
|
|
302
304
|
*/
|
|
303
|
-
async getSlasherContract(): Promise<SlasherContract> {
|
|
304
|
-
const slasherAddress = await this.
|
|
305
|
-
|
|
305
|
+
async getSlasherContract(): Promise<SlasherContract | undefined> {
|
|
306
|
+
const slasherAddress = EthAddress.fromString(await this.getSlasherAddress());
|
|
307
|
+
if (slasherAddress.isZero()) {
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
310
|
+
return new SlasherContract(this.client, slasherAddress);
|
|
306
311
|
}
|
|
307
312
|
|
|
308
313
|
getOwner() {
|
|
@@ -314,13 +319,11 @@ export class RollupContract {
|
|
|
314
319
|
}
|
|
315
320
|
|
|
316
321
|
public async getSlashingProposerAddress() {
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
});
|
|
323
|
-
return EthAddress.fromString(await slasher.read.PROPOSER());
|
|
322
|
+
const slasher = await this.getSlasherContract();
|
|
323
|
+
if (!slasher) {
|
|
324
|
+
return EthAddress.ZERO;
|
|
325
|
+
}
|
|
326
|
+
return await slasher.getProposer();
|
|
324
327
|
}
|
|
325
328
|
|
|
326
329
|
getBlockReward() {
|
|
@@ -490,6 +493,7 @@ export class RollupContract {
|
|
|
490
493
|
ViemHeader,
|
|
491
494
|
ViemCommitteeAttestations,
|
|
492
495
|
`0x${string}`[],
|
|
496
|
+
ViemSignature,
|
|
493
497
|
`0x${string}`,
|
|
494
498
|
`0x${string}`,
|
|
495
499
|
{
|
|
@@ -512,77 +516,6 @@ export class RollupContract {
|
|
|
512
516
|
}
|
|
513
517
|
}
|
|
514
518
|
|
|
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
519
|
/**
|
|
587
520
|
* @notice Calls `canProposeAtTime` with the time of the next Ethereum block and the sender address
|
|
588
521
|
*
|
|
@@ -647,7 +580,7 @@ export class RollupContract {
|
|
|
647
580
|
/** Creates a request to Rollup#invalidateBadAttestation to be simulated or sent */
|
|
648
581
|
public buildInvalidateBadAttestationRequest(
|
|
649
582
|
blockNumber: number,
|
|
650
|
-
|
|
583
|
+
attestationsAndSigners: ViemCommitteeAttestations,
|
|
651
584
|
committee: EthAddress[],
|
|
652
585
|
invalidIndex: number,
|
|
653
586
|
): L1TxRequest {
|
|
@@ -658,7 +591,7 @@ export class RollupContract {
|
|
|
658
591
|
functionName: 'invalidateBadAttestation',
|
|
659
592
|
args: [
|
|
660
593
|
BigInt(blockNumber),
|
|
661
|
-
|
|
594
|
+
attestationsAndSigners,
|
|
662
595
|
committee.map(addr => addr.toString()),
|
|
663
596
|
BigInt(invalidIndex),
|
|
664
597
|
],
|
|
@@ -669,7 +602,7 @@ export class RollupContract {
|
|
|
669
602
|
/** Creates a request to Rollup#invalidateInsufficientAttestations to be simulated or sent */
|
|
670
603
|
public buildInvalidateInsufficientAttestationsRequest(
|
|
671
604
|
blockNumber: number,
|
|
672
|
-
|
|
605
|
+
attestationsAndSigners: ViemCommitteeAttestations,
|
|
673
606
|
committee: EthAddress[],
|
|
674
607
|
): L1TxRequest {
|
|
675
608
|
return {
|
|
@@ -677,11 +610,7 @@ export class RollupContract {
|
|
|
677
610
|
data: encodeFunctionData({
|
|
678
611
|
abi: RollupAbi,
|
|
679
612
|
functionName: 'invalidateInsufficientAttestations',
|
|
680
|
-
args: [
|
|
681
|
-
BigInt(blockNumber),
|
|
682
|
-
RollupContract.packAttestations(attestations),
|
|
683
|
-
committee.map(addr => addr.toString()),
|
|
684
|
-
],
|
|
613
|
+
args: [BigInt(blockNumber), attestationsAndSigners, committee.map(addr => addr.toString())],
|
|
685
614
|
}),
|
|
686
615
|
};
|
|
687
616
|
}
|
|
@@ -33,7 +33,6 @@ import { createExtendedL1Client } from './client.js';
|
|
|
33
33
|
import {
|
|
34
34
|
type L1ContractsConfig,
|
|
35
35
|
getEntryQueueConfig,
|
|
36
|
-
getGSEConfiguration,
|
|
37
36
|
getGovernanceConfiguration,
|
|
38
37
|
getRewardBoostConfig,
|
|
39
38
|
getRewardConfig,
|
|
@@ -183,7 +182,7 @@ export const deploySharedContracts = async (
|
|
|
183
182
|
args: DeployL1ContractsArgs,
|
|
184
183
|
logger: Logger,
|
|
185
184
|
) => {
|
|
186
|
-
logger.info(`Deploying shared contracts for network
|
|
185
|
+
logger.info(`Deploying shared contracts for network configuration: ${networkName}`);
|
|
187
186
|
|
|
188
187
|
const txHashes: Hex[] = [];
|
|
189
188
|
|
|
@@ -193,13 +192,11 @@ export const deploySharedContracts = async (
|
|
|
193
192
|
const stakingAssetAddress = await deployer.deploy(StakingAssetArtifact, ['Staking', 'STK', l1Client.account.address]);
|
|
194
193
|
logger.verbose(`Deployed Staking Asset at ${stakingAssetAddress}`);
|
|
195
194
|
|
|
196
|
-
const gseConfiguration = getGSEConfiguration(networkName);
|
|
197
|
-
|
|
198
195
|
const gseAddress = await deployer.deploy(GSEArtifact, [
|
|
199
196
|
l1Client.account.address,
|
|
200
197
|
stakingAssetAddress.toString(),
|
|
201
|
-
|
|
202
|
-
|
|
198
|
+
args.activationThreshold,
|
|
199
|
+
args.ejectionThreshold,
|
|
203
200
|
]);
|
|
204
201
|
logger.verbose(`Deployed GSE at ${gseAddress}`);
|
|
205
202
|
|
|
@@ -549,6 +546,7 @@ export const deployRollup = async (
|
|
|
549
546
|
slasherFlavor: slasherFlavorToSolidityEnum(args.slasherFlavor),
|
|
550
547
|
slashingOffsetInRounds: BigInt(args.slashingOffsetInRounds),
|
|
551
548
|
slashAmounts: [args.slashAmountSmall, args.slashAmountMedium, args.slashAmountLarge],
|
|
549
|
+
localEjectionThreshold: args.localEjectionThreshold,
|
|
552
550
|
};
|
|
553
551
|
|
|
554
552
|
const genesisStateArgs = {
|
|
@@ -1145,7 +1143,7 @@ export const deployL1Contracts = async (
|
|
|
1145
1143
|
|
|
1146
1144
|
// Include Slasher and SlashingProposer (if deployed) in verification data
|
|
1147
1145
|
try {
|
|
1148
|
-
const slasherAddrHex = await rollup.
|
|
1146
|
+
const slasherAddrHex = await rollup.getSlasherAddress();
|
|
1149
1147
|
const slasherAddr = EthAddress.fromString(slasherAddrHex);
|
|
1150
1148
|
if (!slasherAddr.isZero()) {
|
|
1151
1149
|
// Slasher constructor: (address _vetoer, address _governance)
|