@aztec/ethereum 3.0.0-nightly.20250910 → 3.0.0-nightly.20250912

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.
Files changed (37) hide show
  1. package/dest/config.d.ts +6 -4
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +12 -30
  4. package/dest/contracts/empire_slashing_proposer.d.ts +1 -1
  5. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  6. package/dest/contracts/empire_slashing_proposer.js +1 -1
  7. package/dest/contracts/rollup.d.ts +13 -6
  8. package/dest/contracts/rollup.d.ts.map +1 -1
  9. package/dest/contracts/rollup.js +49 -23
  10. package/dest/deploy_l1_contracts.d.ts +4 -4
  11. package/dest/deploy_l1_contracts.d.ts.map +1 -1
  12. package/dest/deploy_l1_contracts.js +51 -25
  13. package/dest/l1_artifacts.d.ts +689 -62
  14. package/dest/l1_artifacts.d.ts.map +1 -1
  15. package/dest/l1_tx_utils.d.ts +4 -2
  16. package/dest/l1_tx_utils.d.ts.map +1 -1
  17. package/dest/l1_tx_utils.js +21 -13
  18. package/dest/l1_tx_utils_with_blobs.d.ts +2 -1
  19. package/dest/l1_tx_utils_with_blobs.d.ts.map +1 -1
  20. package/dest/l1_tx_utils_with_blobs.js +7 -5
  21. package/dest/queries.d.ts.map +1 -1
  22. package/dest/queries.js +8 -11
  23. package/dest/test/chain_monitor.d.ts +4 -0
  24. package/dest/test/chain_monitor.d.ts.map +1 -1
  25. package/dest/test/chain_monitor.js +57 -11
  26. package/dest/utils.d.ts.map +1 -1
  27. package/dest/utils.js +10 -161
  28. package/package.json +5 -5
  29. package/src/config.ts +17 -35
  30. package/src/contracts/empire_slashing_proposer.ts +6 -2
  31. package/src/contracts/rollup.ts +58 -22
  32. package/src/deploy_l1_contracts.ts +65 -22
  33. package/src/l1_tx_utils.ts +28 -9
  34. package/src/l1_tx_utils_with_blobs.ts +8 -2
  35. package/src/queries.ts +9 -7
  36. package/src/test/chain_monitor.ts +64 -8
  37. package/src/utils.ts +13 -185
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,21 +9,18 @@ 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 slasherAddress = await rollup.getSlasher();
15
- const slasher = getContract({
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, lagInEpochs, 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(),
24
17
  rollup.getSlotDuration(),
25
18
  rollup.getProofSubmissionEpochs(),
26
19
  rollup.getTargetCommitteeSize(),
20
+ rollup.getLagInEpochs(),
27
21
  rollup.getActivationThreshold(),
28
22
  rollup.getEjectionThreshold(),
23
+ rollup.getLocalEjectionThreshold(),
29
24
  governanceProposer.getQuorumSize(),
30
25
  governanceProposer.getRoundSize(),
31
26
  slasherProposer?.getQuorumSize() ?? 0n,
@@ -38,7 +33,7 @@ import { RollupContract } from './contracts/rollup.js';
38
33
  0n,
39
34
  0n
40
35
  ],
41
- slasher.read.VETOER(),
36
+ slasher?.getVetoer() ?? EthAddress.ZERO,
42
37
  rollup.getManaTarget(),
43
38
  rollup.getProvingCostPerMana(),
44
39
  rollup.getVersion(),
@@ -52,15 +47,17 @@ import { RollupContract } from './contracts/rollup.js';
52
47
  aztecSlotDuration: Number(aztecSlotDuration),
53
48
  aztecProofSubmissionEpochs: Number(aztecProofSubmissionEpochs),
54
49
  aztecTargetCommitteeSize: Number(aztecTargetCommitteeSize),
50
+ lagInEpochs: Number(lagInEpochs),
55
51
  governanceProposerQuorum: Number(governanceProposerQuorum),
56
52
  governanceProposerRoundSize: Number(governanceProposerRoundSize),
57
53
  activationThreshold,
58
54
  ejectionThreshold,
55
+ localEjectionThreshold,
59
56
  slashingQuorum: Number(slashingQuorum),
60
57
  slashingRoundSizeInEpochs: Number(slashingRoundSize / aztecEpochDuration),
61
58
  slashingLifetimeInRounds: Number(slashingLifetimeInRounds),
62
59
  slashingExecutionDelayInRounds: Number(slashingExecutionDelayInRounds),
63
- slashingVetoer: EthAddress.fromString(slashingVetoer),
60
+ slashingVetoer,
64
61
  manaTarget: manaTarget,
65
62
  provingCostPerMana: provingCostPerMana,
66
63
  rollupVersion: Number(rollupVersion),
@@ -10,6 +10,7 @@ export type ChainMonitorEventMap = {
10
10
  'l2-block': [{
11
11
  l2BlockNumber: number;
12
12
  l1BlockNumber: number;
13
+ l2SlotNumber: number;
13
14
  timestamp: bigint;
14
15
  }];
15
16
  'l2-block-proven': [{
@@ -64,5 +65,8 @@ export declare class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
64
65
  protected safeRun(): void;
65
66
  run(force?: boolean): Promise<this>;
66
67
  waitUntilL2Slot(slot: number | bigint): Promise<void>;
68
+ waitUntilL1Block(block: number | bigint): Promise<void>;
69
+ waitUntilL1Timestamp(timestamp: number | bigint): Promise<void>;
70
+ waitUntilL2Block(l2BlockNumber: number | bigint): Promise<void>;
67
71
  }
68
72
  //# sourceMappingURL=chain_monitor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chain_monitor.d.ts","sourceRoot":"","sources":["../../src/test/chain_monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,UAAU,EAAE,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClF,iBAAiB,EAAE,CAAC;QAAE,mBAAmB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/F,aAAa,EAAE,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,UAAU,EAAE,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,UAAU,EAAE,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IAChG,SAAS,EAAE,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D,CAAC;AAEF,8GAA8G;AAC9G,qBAAa,YAAa,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAyBhE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IA3B7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IACtC,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,MAAM,CAA6B;IAE3C,OAAO,CAAC,OAAO,CAAiC;IAEhD,8BAA8B;IACvB,aAAa,EAAG,MAAM,CAAC;IAC9B,8BAA8B;IACvB,aAAa,EAAG,MAAM,CAAC;IAC9B,qCAAqC;IAC9B,mBAAmB,EAAG,MAAM,CAAC;IACpC,4CAA4C;IACrC,gBAAgB,EAAG,MAAM,CAAC;IACjC,2CAA2C;IACpC,sBAAsB,EAAG,MAAM,CAAC;IACvC,wDAAwD;IACjD,eAAe,EAAE,MAAM,CAAK;IACnC,8BAA8B;IACvB,aAAa,EAAG,MAAM,CAAC;IAC9B,6BAA6B;IACtB,YAAY,EAAG,MAAM,CAAC;gBAGV,MAAM,EAAE,cAAc,EACtB,YAAY,GAAE,YAAiC,EAC/C,MAAM,yCAA8C,EACpD,UAAU,SAAM;IAMnC,KAAK;IAQC,IAAI;YAaI,QAAQ;IAQtB,SAAS,CAAC,OAAO;IAcX,GAAG,CAAC,KAAK,UAAQ;IA0EhB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAe7D"}
1
+ {"version":3,"file":"chain_monitor.d.ts","sourceRoot":"","sources":["../../src/test/chain_monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,UAAU,EAAE,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxG,iBAAiB,EAAE,CAAC;QAAE,mBAAmB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/F,aAAa,EAAE,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,UAAU,EAAE,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,UAAU,EAAE,GAAG,SAAS,CAAA;KAAE,CAAC,CAAC;IAChG,SAAS,EAAE,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D,CAAC;AAEF,8GAA8G;AAC9G,qBAAa,YAAa,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAyBhE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IA3B7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IACtC,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,MAAM,CAA6B;IAE3C,OAAO,CAAC,OAAO,CAAiC;IAEhD,8BAA8B;IACvB,aAAa,EAAG,MAAM,CAAC;IAC9B,8BAA8B;IACvB,aAAa,EAAG,MAAM,CAAC;IAC9B,qCAAqC;IAC9B,mBAAmB,EAAG,MAAM,CAAC;IACpC,4CAA4C;IACrC,gBAAgB,EAAG,MAAM,CAAC;IACjC,2CAA2C;IACpC,sBAAsB,EAAG,MAAM,CAAC;IACvC,wDAAwD;IACjD,eAAe,EAAE,MAAM,CAAK;IACnC,8BAA8B;IACvB,aAAa,EAAG,MAAM,CAAC;IAC9B,6BAA6B;IACtB,YAAY,EAAG,MAAM,CAAC;gBAGV,MAAM,EAAE,cAAc,EACtB,YAAY,GAAE,YAAiC,EAC/C,MAAM,yCAA8C,EACpD,UAAU,SAAM;IAMnC,KAAK;IAQC,IAAI;YAaI,QAAQ;IAQtB,SAAS,CAAC,OAAO;IAcX,GAAG,CAAC,KAAK,UAAQ;IAkFhB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBrD,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvD,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB/D,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAevE"}
@@ -72,11 +72,15 @@ import { EventEmitter } from 'events';
72
72
  return this;
73
73
  }
74
74
  this.l1BlockNumber = newL1BlockNumber;
75
- const block = await this.l1Client.getBlock({
76
- blockNumber: BigInt(newL1BlockNumber),
77
- includeTransactions: false
78
- });
79
- const timestamp = block.timestamp;
75
+ const [l2SlotNumber, l2Epoch, l1block] = await Promise.all([
76
+ this.rollup.getSlotNumber(),
77
+ this.rollup.getCurrentEpoch(),
78
+ this.l1Client.getBlock({
79
+ blockNumber: BigInt(newL1BlockNumber),
80
+ includeTransactions: false
81
+ })
82
+ ]);
83
+ const timestamp = l1block.timestamp;
80
84
  const timestampString = new Date(Number(timestamp) * 1000).toTimeString().split(' ')[0];
81
85
  this.emit('l1-block', {
82
86
  l1BlockNumber: newL1BlockNumber,
@@ -85,19 +89,20 @@ import { EventEmitter } from 'events';
85
89
  let msg = `L1 block ${newL1BlockNumber} mined at ${timestampString}`;
86
90
  const newL2BlockNumber = Number(await this.rollup.getBlockNumber());
87
91
  if (this.l2BlockNumber !== newL2BlockNumber) {
88
- const epochNumber = await this.rollup.getEpochNumber(BigInt(newL2BlockNumber));
92
+ const epochNumber = await this.rollup.getEpochNumberForBlock(BigInt(newL2BlockNumber));
89
93
  msg += ` with new L2 block ${newL2BlockNumber} for epoch ${epochNumber}`;
90
94
  this.l2BlockNumber = newL2BlockNumber;
91
95
  this.l2BlockTimestamp = timestamp;
92
96
  this.emit('l2-block', {
93
97
  l2BlockNumber: newL2BlockNumber,
94
98
  l1BlockNumber: newL1BlockNumber,
99
+ l2SlotNumber: Number(l2SlotNumber),
95
100
  timestamp
96
101
  });
97
102
  }
98
103
  const newL2ProvenBlockNumber = Number(await this.rollup.getProvenBlockNumber());
99
104
  if (this.l2ProvenBlockNumber !== newL2ProvenBlockNumber) {
100
- const epochNumber = await this.rollup.getEpochNumber(BigInt(newL2ProvenBlockNumber));
105
+ const epochNumber = await this.rollup.getEpochNumberForBlock(BigInt(newL2ProvenBlockNumber));
101
106
  msg += ` with proof up to L2 block ${newL2ProvenBlockNumber} for epoch ${epochNumber}`;
102
107
  this.l2ProvenBlockNumber = newL2ProvenBlockNumber;
103
108
  this.l2ProvenBlockTimestamp = timestamp;
@@ -117,10 +122,6 @@ import { EventEmitter } from 'events';
117
122
  l1BlockNumber: newL1BlockNumber
118
123
  });
119
124
  }
120
- const [l2SlotNumber, l2Epoch] = await Promise.all([
121
- this.rollup.getSlotNumber(),
122
- this.rollup.getCurrentEpoch()
123
- ]);
124
125
  let committee;
125
126
  if (l2Epoch !== this.l2EpochNumber) {
126
127
  this.l2EpochNumber = l2Epoch;
@@ -167,4 +168,49 @@ import { EventEmitter } from 'events';
167
168
  this.on('l2-slot', listener);
168
169
  });
169
170
  }
171
+ waitUntilL1Block(block) {
172
+ const targetBlock = typeof block === 'bigint' ? block.valueOf() : block;
173
+ if (this.l1BlockNumber >= targetBlock) {
174
+ return Promise.resolve();
175
+ }
176
+ return new Promise((resolve)=>{
177
+ const listener = (data)=>{
178
+ if (data.l1BlockNumber >= targetBlock) {
179
+ this.off('l1-block', listener);
180
+ resolve();
181
+ }
182
+ };
183
+ this.on('l1-block', listener);
184
+ });
185
+ }
186
+ waitUntilL1Timestamp(timestamp) {
187
+ const targetTimestamp = typeof timestamp === 'bigint' ? timestamp.valueOf() : timestamp;
188
+ if (this.l1BlockNumber >= targetTimestamp) {
189
+ return Promise.resolve();
190
+ }
191
+ return new Promise((resolve)=>{
192
+ const listener = (data)=>{
193
+ if (data.timestamp >= targetTimestamp) {
194
+ this.off('l1-block', listener);
195
+ resolve();
196
+ }
197
+ };
198
+ this.on('l1-block', listener);
199
+ });
200
+ }
201
+ waitUntilL2Block(l2BlockNumber) {
202
+ const targetBlock = typeof l2BlockNumber === 'bigint' ? l2BlockNumber.valueOf() : l2BlockNumber;
203
+ if (this.l2BlockNumber >= targetBlock) {
204
+ return Promise.resolve();
205
+ }
206
+ return new Promise((resolve)=>{
207
+ const listener = (data)=>{
208
+ if (data.l2BlockNumber >= targetBlock) {
209
+ this.off('l2-block', listener);
210
+ resolve();
211
+ }
212
+ };
213
+ this.on('l2-block', listener);
214
+ });
215
+ }
170
216
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACL,KAAK,GAAG,EAER,KAAK,iBAAiB,EAEtB,KAAK,wBAAwB,EAC7B,KAAK,GAAG,EACR,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;gBAET,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE;CAKlD;AAED,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAMZ;AAED,wBAAgB,eAAe,CAC7B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,GAAG,SAAS,CAgBxB;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,OAW7C;AA0BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAE,GAAe,GAAG,kBAAkB,CA8FpF;AA+KD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,sBAa7C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACL,KAAK,GAAG,EAER,KAAK,iBAAiB,EAEtB,KAAK,wBAAwB,EAC7B,KAAK,GAAG,EACR,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;gBAET,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE;CAKlD;AAED,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAMZ;AAED,wBAAgB,eAAe,CAC7B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,GAAG,SAAS,CAgBxB;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,OAW7C;AA0BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAE,GAAe,GAAG,kBAAkB,CAwEpF;AAyBD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,sBAa7C"}
package/dest/utils.js CHANGED
@@ -118,34 +118,16 @@ function getNestedErrorData(error) {
118
118
  if (error instanceof Error) {
119
119
  return new FormattedViemError(error.message, error?.metaMessages);
120
120
  }
121
- // Extract the actual error message and highlight it for clarity
122
- let formattedRes = extractAndFormatRequestBody(error?.message || String(error));
123
- let errorDetail = '';
124
- // Look for specific details in known locations
125
- if (error) {
126
- // Check for details property which often has the most specific error message
127
- if (typeof error.details === 'string' && error.details) {
128
- errorDetail = error.details;
129
- } else if (typeof error.shortMessage === 'string' && error.shortMessage) {
130
- errorDetail = error.shortMessage;
131
- }
132
- }
133
- // If we found a specific error detail, format it clearly
134
- if (errorDetail) {
135
- // Look for key sections of the formatted result to replace with highlighted error
136
- let replaced = false;
137
- // Try to find the Details: section
138
- const detailsMatch = formattedRes.match(/Details: ([^\n]+)/);
139
- if (detailsMatch) {
140
- formattedRes = formattedRes.replace(detailsMatch[0], `Details: *${errorDetail}*`);
141
- replaced = true;
142
- }
143
- // If we didn't find a Details section, add the error at the beginning
144
- if (!replaced) {
145
- formattedRes = `Error: *${errorDetail}*\n\n${formattedRes}`;
146
- }
147
- }
148
- return new FormattedViemError(formattedRes.replace(/\\n/g, '\n'), error?.metaMessages);
121
+ const body = String(error);
122
+ const length = body.length;
123
+ // LogExplorer can only render up to 2500 characters in it's summary view. Try to keep the whole message below this number
124
+ // Limit the error to 2000 chacaters in order to allow code higher up to decorate this error with extra details (up to 500 characters)
125
+ if (length > 2000) {
126
+ const chunk = 950;
127
+ const truncated = length - 2 * chunk;
128
+ return new FormattedViemError(body.slice(0, chunk) + `...${truncated} characters truncated...` + body.slice(-1 * chunk));
129
+ }
130
+ return new FormattedViemError(body);
149
131
  }
150
132
  function stripAbis(obj) {
151
133
  if (!obj || typeof obj !== 'object') {
@@ -166,139 +148,6 @@ function stripAbis(obj) {
166
148
  }
167
149
  });
168
150
  }
169
- function extractAndFormatRequestBody(message) {
170
- // First check if message is extremely large and contains very large hex strings
171
- if (message.length > 50000) {
172
- message = replaceHexStrings(message, {
173
- minLength: 10000,
174
- truncateLength: 200
175
- });
176
- }
177
- // Add a specific check for RPC calls with large params
178
- if (message.includes('"method":"eth_sendRawTransaction"')) {
179
- message = replaceHexStrings(message, {
180
- pattern: /"params":\s*\[\s*"(0x[a-fA-F0-9]{1000,})"\s*\]/g,
181
- transform: (hex)=>`"params":["${truncateHex(hex, 200)}"]`
182
- });
183
- }
184
- // First handle Request body JSON
185
- const requestBodyRegex = /Request body: ({[\s\S]*?})\n/g;
186
- let result = message.replace(requestBodyRegex, (match, body)=>{
187
- return `Request body: ${formatRequestBody(body)}\n`;
188
- });
189
- // Then handle Arguments section
190
- const argsRegex = /((?:Request |Estimate Gas )?Arguments:[\s\S]*?(?=\n\n|$))/g;
191
- result = result.replace(argsRegex, (section)=>{
192
- const lines = section.split('\n');
193
- const processedLines = lines.map((line)=>{
194
- // Check if line contains a colon followed by content
195
- const colonIndex = line.indexOf(':');
196
- if (colonIndex !== -1) {
197
- const [prefix, content] = [
198
- line.slice(0, colonIndex + 1),
199
- line.slice(colonIndex + 1).trim()
200
- ];
201
- // If content contains a hex string, truncate it
202
- if (content.includes('0x')) {
203
- const processedContent = replaceHexStrings(content);
204
- return `${prefix} ${processedContent}`;
205
- }
206
- }
207
- return line;
208
- });
209
- return processedLines.join('\n');
210
- });
211
- // Finally, catch any remaining hex strings in the message
212
- result = replaceHexStrings(result);
213
- return result;
214
- }
215
- function truncateHex(hex, length = 100) {
216
- if (!hex || typeof hex !== 'string') {
217
- return hex;
218
- }
219
- if (!hex.startsWith('0x')) {
220
- return hex;
221
- }
222
- if (hex.length <= length * 2) {
223
- return hex;
224
- }
225
- // For extremely large hex strings, use more aggressive truncation
226
- if (hex.length > 10000) {
227
- return `${hex.slice(0, length)}...<${hex.length - length * 2} chars omitted>...${hex.slice(-length)}`;
228
- }
229
- return `${hex.slice(0, length)}...${hex.slice(-length)}`;
230
- }
231
- function replaceHexStrings(text, options = {}) {
232
- const { minLength = 10, maxLength = Infinity, truncateLength = 100, pattern, transform = (hex)=>truncateHex(hex, truncateLength) } = options;
233
- const hexRegex = pattern ?? new RegExp(`(0x[a-fA-F0-9]{${minLength},${maxLength}})`, 'g');
234
- return text.replace(hexRegex, (match)=>transform(match));
235
- }
236
- function formatRequestBody(body) {
237
- try {
238
- // Special handling for eth_sendRawTransaction
239
- if (body.includes('"method":"eth_sendRawTransaction"')) {
240
- try {
241
- const parsed = JSON.parse(body);
242
- if (parsed.params && Array.isArray(parsed.params) && parsed.params.length > 0) {
243
- // These are likely large transaction hex strings
244
- parsed.params = parsed.params.map((param)=>{
245
- if (typeof param === 'string' && param.startsWith('0x') && param.length > 1000) {
246
- return truncateHex(param, 200);
247
- }
248
- return param;
249
- });
250
- }
251
- return JSON.stringify(parsed, null, 2);
252
- } catch {
253
- // If specific parsing fails, fall back to regex-based truncation
254
- return replaceHexStrings(body, {
255
- pattern: /"params":\s*\[\s*"(0x[a-fA-F0-9]{1000,})"\s*\]/g,
256
- transform: (hex)=>`"params":["${truncateHex(hex, 200)}"]`
257
- });
258
- }
259
- }
260
- // For extremely large request bodies, use simple truncation instead of parsing
261
- if (body.length > 50000) {
262
- const jsonStart = body.indexOf('{');
263
- const jsonEnd = body.lastIndexOf('}');
264
- if (jsonStart >= 0 && jsonEnd > jsonStart) {
265
- return replaceHexStrings(body, {
266
- minLength: 10000,
267
- truncateLength: 200
268
- });
269
- }
270
- }
271
- const parsed = JSON.parse(body);
272
- // Process the entire request body
273
- const processed = processParams(parsed);
274
- return JSON.stringify(processed, null, 2);
275
- } catch {
276
- // If JSON parsing fails, do a simple truncation of any large hex strings
277
- return replaceHexStrings(body, {
278
- minLength: 1000,
279
- truncateLength: 150
280
- });
281
- }
282
- }
283
- // Recursively process all parameters that might contain hex strings
284
- function processParams(obj) {
285
- if (Array.isArray(obj)) {
286
- return obj.map((item)=>processParams(item));
287
- }
288
- if (typeof obj === 'object' && obj !== null) {
289
- const result = {};
290
- for (const [key, value] of Object.entries(obj)){
291
- result[key] = processParams(value);
292
- }
293
- return result;
294
- }
295
- if (typeof obj === 'string') {
296
- if (obj.startsWith('0x')) {
297
- return truncateHex(obj);
298
- }
299
- }
300
- return obj;
301
- }
302
151
  export function tryGetCustomErrorName(err) {
303
152
  try {
304
153
  // See https://viem.sh/docs/contract/simulateContract#handling-custom-errors
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/ethereum",
3
- "version": "3.0.0-nightly.20250910",
3
+ "version": "3.0.0-nightly.20250912",
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.20250910",
35
- "@aztec/constants": "3.0.0-nightly.20250910",
36
- "@aztec/foundation": "3.0.0-nightly.20250910",
37
- "@aztec/l1-artifacts": "3.0.0-nightly.20250910",
34
+ "@aztec/blob-lib": "3.0.0-nightly.20250912",
35
+ "@aztec/constants": "3.0.0-nightly.20250912",
36
+ "@aztec/foundation": "3.0.0-nightly.20250912",
37
+ "@aztec/l1-artifacts": "3.0.0-nightly.20250912",
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
@@ -28,12 +28,16 @@ export type L1ContractsConfig = {
28
28
  aztecEpochDuration: number;
29
29
  /** The target validator committee size. */
30
30
  aztecTargetCommitteeSize: number;
31
+ /** The number of epochs to lag behind the current epoch for validator selection. */
32
+ lagInEpochs: number;
31
33
  /** The number of epochs after an epoch ends that proofs are still accepted. */
32
34
  aztecProofSubmissionEpochs: number;
33
35
  /** The deposit amount for a validator */
34
36
  activationThreshold: bigint;
35
37
  /** The minimum stake for a validator. */
36
38
  ejectionThreshold: bigint;
39
+ /** The local ejection threshold for a validator. Stricter than ejectionThreshold but local to a specific rollup */
40
+ localEjectionThreshold: bigint;
37
41
  /** 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
42
  slashingQuorum?: number;
39
43
  /** The slashing round size, i.e. how many epochs are in a slashing round */
@@ -71,9 +75,11 @@ export const DefaultL1ContractsConfig = {
71
75
  aztecSlotDuration: 36,
72
76
  aztecEpochDuration: 32,
73
77
  aztecTargetCommitteeSize: 48,
78
+ lagInEpochs: 2,
74
79
  aztecProofSubmissionEpochs: 1, // you have a full epoch to submit a proof after the epoch to prove ends
75
80
  activationThreshold: BigInt(100e18),
76
81
  ejectionThreshold: BigInt(50e18),
82
+ localEjectionThreshold: BigInt(98e18),
77
83
  slashAmountSmall: BigInt(10e18),
78
84
  slashAmountMedium: BigInt(20e18),
79
85
  slashAmountLarge: BigInt(50e18),
@@ -161,41 +167,6 @@ export const getGovernanceConfiguration = (networkName: NetworkNames) => {
161
167
  }
162
168
  };
163
169
 
164
- const LocalGSEConfiguration = {
165
- activationThreshold: BigInt(100e18),
166
- ejectionThreshold: BigInt(50e18),
167
- };
168
-
169
- const StagingPublicGSEConfiguration = {
170
- activationThreshold: DefaultL1ContractsConfig.activationThreshold,
171
- ejectionThreshold: DefaultL1ContractsConfig.ejectionThreshold,
172
- };
173
-
174
- const TestnetGSEConfiguration = {
175
- activationThreshold: BigInt(100e18),
176
- ejectionThreshold: BigInt(50e18),
177
- };
178
-
179
- const StagingIgnitionGSEConfiguration = {
180
- activationThreshold: DefaultL1ContractsConfig.activationThreshold,
181
- ejectionThreshold: DefaultL1ContractsConfig.ejectionThreshold,
182
- };
183
-
184
- export const getGSEConfiguration = (networkName: NetworkNames) => {
185
- switch (networkName) {
186
- case 'local':
187
- return LocalGSEConfiguration;
188
- case 'staging-public':
189
- return StagingPublicGSEConfiguration;
190
- case 'testnet':
191
- return TestnetGSEConfiguration;
192
- case 'staging-ignition':
193
- return StagingIgnitionGSEConfiguration;
194
- default:
195
- throw new Error(`Unrecognized network name: ${networkName}`);
196
- }
197
- };
198
-
199
170
  // Making a default config here as we are only using it thought the deployment
200
171
  // and do not expect to be using different setups, so having environment variables
201
172
  // for it seems overkill
@@ -335,6 +306,11 @@ export const l1ContractsConfigMappings: ConfigMappingsType<L1ContractsConfig> =
335
306
  description: 'The target validator committee size.',
336
307
  ...numberConfigHelper(DefaultL1ContractsConfig.aztecTargetCommitteeSize),
337
308
  },
309
+ lagInEpochs: {
310
+ env: 'AZTEC_LAG_IN_EPOCHS',
311
+ description: 'The number of epochs to lag behind the current epoch for validator selection.',
312
+ ...numberConfigHelper(DefaultL1ContractsConfig.lagInEpochs),
313
+ },
338
314
  aztecProofSubmissionEpochs: {
339
315
  env: 'AZTEC_PROOF_SUBMISSION_EPOCHS',
340
316
  description: 'The number of epochs after an epoch ends that proofs are still accepted.',
@@ -350,6 +326,12 @@ export const l1ContractsConfigMappings: ConfigMappingsType<L1ContractsConfig> =
350
326
  description: 'The minimum stake for a validator.',
351
327
  ...bigintConfigHelper(DefaultL1ContractsConfig.ejectionThreshold),
352
328
  },
329
+ localEjectionThreshold: {
330
+ env: 'AZTEC_LOCAL_EJECTION_THRESHOLD',
331
+ description:
332
+ 'The local ejection threshold for a validator. Stricter than ejectionThreshold but local to a specific rollup',
333
+ ...bigintConfigHelper(DefaultL1ContractsConfig.localEjectionThreshold),
334
+ },
353
335
  slashingOffsetInRounds: {
354
336
  env: 'AZTEC_SLASHING_OFFSET_IN_ROUNDS',
355
337
  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({ address, abi: EmpireSlashingProposerAbi, client });
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() {