@aztec/ethereum 0.73.0 → 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2

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 (87) hide show
  1. package/dest/chain.js +17 -18
  2. package/dest/client.js +5 -9
  3. package/dest/config.js +13 -14
  4. package/dest/constants.js +0 -1
  5. package/dest/contracts/empire_base.js +11 -0
  6. package/dest/contracts/forwarder.js +67 -32
  7. package/dest/contracts/governance.js +11 -6
  8. package/dest/contracts/governance_proposer.js +79 -37
  9. package/dest/contracts/index.js +2 -2
  10. package/dest/contracts/rollup.js +271 -234
  11. package/dest/contracts/slashing_proposer.js +32 -4
  12. package/dest/deploy_l1_contracts.js +203 -124
  13. package/dest/eth_cheat_codes.js +144 -127
  14. package/dest/index.js +0 -1
  15. package/dest/l1_contract_addresses.js +17 -19
  16. package/dest/l1_reader.js +6 -7
  17. package/dest/l1_tx_utils.js +229 -199
  18. package/dest/l1_tx_utils_with_blobs.js +25 -22
  19. package/dest/queries.js +6 -9
  20. package/dest/test/delayed_tx_utils.js +3 -3
  21. package/dest/test/eth_cheat_codes_with_state.js +10 -12
  22. package/dest/test/index.js +0 -1
  23. package/dest/test/start_anvil.js +17 -9
  24. package/dest/test/tx_delayer.js +77 -74
  25. package/dest/types.js +1 -2
  26. package/dest/utils.js +58 -38
  27. package/package.json +5 -4
  28. package/src/contracts/empire_base.ts +19 -0
  29. package/src/contracts/forwarder.ts +37 -14
  30. package/src/contracts/governance_proposer.ts +54 -4
  31. package/src/contracts/index.ts +2 -1
  32. package/src/contracts/rollup.ts +21 -9
  33. package/src/contracts/slashing_proposer.ts +29 -2
  34. package/src/deploy_l1_contracts.ts +6 -0
  35. package/src/l1_tx_utils.ts +9 -19
  36. package/src/l1_tx_utils_with_blobs.ts +1 -1
  37. package/src/utils.ts +29 -3
  38. package/dest/chain.d.ts +0 -25
  39. package/dest/chain.d.ts.map +0 -1
  40. package/dest/client.d.ts +0 -16
  41. package/dest/client.d.ts.map +0 -1
  42. package/dest/config.d.ts +0 -38
  43. package/dest/config.d.ts.map +0 -1
  44. package/dest/constants.d.ts +0 -4
  45. package/dest/constants.d.ts.map +0 -1
  46. package/dest/contracts/forwarder.d.ts +0 -23
  47. package/dest/contracts/forwarder.d.ts.map +0 -1
  48. package/dest/contracts/governance.d.ts +0 -14
  49. package/dest/contracts/governance.d.ts.map +0 -1
  50. package/dest/contracts/governance_proposer.d.ts +0 -13
  51. package/dest/contracts/governance_proposer.d.ts.map +0 -1
  52. package/dest/contracts/index.d.ts +0 -6
  53. package/dest/contracts/index.d.ts.map +0 -1
  54. package/dest/contracts/rollup.d.ts +0 -113
  55. package/dest/contracts/rollup.d.ts.map +0 -1
  56. package/dest/contracts/slashing_proposer.d.ts +0 -11
  57. package/dest/contracts/slashing_proposer.d.ts.map +0 -1
  58. package/dest/deploy_l1_contracts.d.ts +0 -19873
  59. package/dest/deploy_l1_contracts.d.ts.map +0 -1
  60. package/dest/eth_cheat_codes.d.ts +0 -146
  61. package/dest/eth_cheat_codes.d.ts.map +0 -1
  62. package/dest/index.d.ts +0 -15
  63. package/dest/index.d.ts.map +0 -1
  64. package/dest/l1_contract_addresses.d.ts +0 -55
  65. package/dest/l1_contract_addresses.d.ts.map +0 -1
  66. package/dest/l1_reader.d.ts +0 -16
  67. package/dest/l1_reader.d.ts.map +0 -1
  68. package/dest/l1_tx_utils.d.ts +0 -193
  69. package/dest/l1_tx_utils.d.ts.map +0 -1
  70. package/dest/l1_tx_utils_with_blobs.d.ts +0 -12
  71. package/dest/l1_tx_utils_with_blobs.d.ts.map +0 -1
  72. package/dest/queries.d.ts +0 -15
  73. package/dest/queries.d.ts.map +0 -1
  74. package/dest/test/delayed_tx_utils.d.ts +0 -8
  75. package/dest/test/delayed_tx_utils.d.ts.map +0 -1
  76. package/dest/test/eth_cheat_codes_with_state.d.ts +0 -18
  77. package/dest/test/eth_cheat_codes_with_state.d.ts.map +0 -1
  78. package/dest/test/index.d.ts +0 -5
  79. package/dest/test/index.d.ts.map +0 -1
  80. package/dest/test/start_anvil.d.ts +0 -9
  81. package/dest/test/start_anvil.d.ts.map +0 -1
  82. package/dest/test/tx_delayer.d.ts +0 -24
  83. package/dest/test/tx_delayer.d.ts.map +0 -1
  84. package/dest/types.d.ts +0 -12
  85. package/dest/types.d.ts.map +0 -1
  86. package/dest/utils.d.ts +0 -24
  87. package/dest/utils.d.ts.map +0 -1
package/dest/utils.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { ErrorsAbi } from '@aztec/l1-artifacts';
2
- import { BaseError, ContractFunctionRevertedError, decodeErrorResult, decodeEventLog, } from 'viem';
2
+ import { BaseError, ContractFunctionRevertedError, decodeErrorResult, decodeEventLog } from 'viem';
3
3
  export class FormattedViemError extends Error {
4
- constructor(message, metaMessages) {
4
+ metaMessages;
5
+ constructor(message, metaMessages){
5
6
  super(message);
6
7
  this.name = 'FormattedViemError';
7
8
  this.metaMessages = metaMessages;
@@ -15,18 +16,20 @@ export function extractEvent(logs, address, abi, eventName, filter, logger) {
15
16
  return event;
16
17
  }
17
18
  function tryExtractEvent(logs, address, abi, eventName, filter, logger) {
18
- for (const log of logs) {
19
+ for (const log of logs){
19
20
  if (log.address.toLowerCase() === address.toLowerCase()) {
20
21
  try {
21
- const decodedEvent = decodeEventLog({ abi, ...log });
22
+ const decodedEvent = decodeEventLog({
23
+ abi,
24
+ ...log
25
+ });
22
26
  if (decodedEvent.eventName === eventName) {
23
27
  const matchingEvent = decodedEvent;
24
28
  if (!filter || filter(matchingEvent)) {
25
29
  return matchingEvent;
26
30
  }
27
31
  }
28
- }
29
- catch (err) {
32
+ } catch (err) {
30
33
  logger?.warn(`Failed to decode event log for contract ${address}: ${err}`);
31
34
  }
32
35
  }
@@ -34,7 +37,7 @@ function tryExtractEvent(logs, address, abi, eventName, filter, logger) {
34
37
  }
35
38
  export function prettyLogViemErrorMsg(err) {
36
39
  if (err instanceof BaseError) {
37
- const revertError = err.walk(err => err instanceof ContractFunctionRevertedError);
40
+ const revertError = err.walk((err)=>err instanceof ContractFunctionRevertedError);
38
41
  if (revertError instanceof ContractFunctionRevertedError) {
39
42
  const errorName = revertError.data?.errorName ?? '';
40
43
  const args = revertError.metaMessages && revertError.metaMessages?.length > 1 ? revertError.metaMessages[1].trimStart() : '';
@@ -43,24 +46,44 @@ export function prettyLogViemErrorMsg(err) {
43
46
  }
44
47
  return err?.message ?? err;
45
48
  }
49
+ function getNestedErrorData(error) {
50
+ // If nothing, bail
51
+ if (!error) {
52
+ return undefined;
53
+ }
54
+ // If it's an object with a `data` property, return it
55
+ // (Remember to check TS type-safely or cast as needed)
56
+ if (typeof error === 'object' && error !== null && 'data' in error) {
57
+ const possibleData = error.data;
58
+ if (typeof possibleData === 'string' && possibleData.startsWith('0x')) {
59
+ return possibleData;
60
+ }
61
+ }
62
+ // If it has a `cause`, recurse
63
+ if (typeof error === 'object' && error !== null && 'cause' in error) {
64
+ return getNestedErrorData(error.cause);
65
+ }
66
+ // Not found
67
+ return undefined;
68
+ }
46
69
  /**
47
70
  * Formats a Viem error into a FormattedViemError instance.
48
71
  * @param error - The error to format.
49
72
  * @param abi - The ABI to use for decoding.
50
73
  * @returns A FormattedViemError instance.
51
- */
52
- export function formatViemError(error, abi = ErrorsAbi) {
74
+ */ export function formatViemError(error, abi = ErrorsAbi) {
53
75
  // If error is already a FormattedViemError, return it as is
54
76
  if (error instanceof FormattedViemError) {
55
77
  return error;
56
78
  }
57
79
  // First try to decode as a custom error using the ABI
58
80
  try {
59
- if (error?.data) {
81
+ const data = getNestedErrorData(error);
82
+ if (data) {
60
83
  // Try to decode the error data using the ABI
61
84
  const decoded = decodeErrorResult({
62
85
  abi,
63
- data: error.data,
86
+ data: data
64
87
  });
65
88
  if (decoded) {
66
89
  return new FormattedViemError(`${decoded.errorName}(${decoded.args?.join(', ') ?? ''})`, error?.metaMessages);
@@ -68,28 +91,25 @@ export function formatViemError(error, abi = ErrorsAbi) {
68
91
  }
69
92
  // If it's a BaseError, try to get the custom error through ContractFunctionRevertedError
70
93
  if (error instanceof BaseError) {
71
- const revertError = error.walk(err => err instanceof ContractFunctionRevertedError);
94
+ const revertError = error.walk((err)=>err instanceof ContractFunctionRevertedError);
72
95
  if (revertError instanceof ContractFunctionRevertedError) {
73
96
  let errorName = revertError.data?.errorName;
74
97
  if (!errorName) {
75
98
  errorName = revertError.signature ?? '';
76
99
  }
77
- const args = revertError.metaMessages && revertError.metaMessages?.length > 1
78
- ? revertError.metaMessages[1].trimStart()
79
- : '';
100
+ const args = revertError.metaMessages && revertError.metaMessages?.length > 1 ? revertError.metaMessages[1].trimStart() : '';
80
101
  return new FormattedViemError(`${errorName}${args}`, error?.metaMessages);
81
102
  }
82
103
  }
83
- }
84
- catch (decodeErr) {
85
- // If decoding fails, we fall back to the original formatting
104
+ } catch (decodeErr) {
105
+ // If decoding fails, we fall back to the original formatting
86
106
  }
87
107
  // If it's a regular Error instance, return it with its message
88
108
  if (error instanceof Error) {
89
- return new FormattedViemError(error.message);
109
+ return error;
90
110
  }
91
111
  // Original formatting logic for non-custom errors
92
- const truncateHex = (hex, length = 100) => {
112
+ const truncateHex = (hex, length = 100)=>{
93
113
  if (!hex || typeof hex !== 'string') {
94
114
  return hex;
95
115
  }
@@ -101,17 +121,17 @@ export function formatViemError(error, abi = ErrorsAbi) {
101
121
  }
102
122
  return `${hex.slice(0, length)}...${hex.slice(-length)}`;
103
123
  };
104
- const formatRequestBody = (body) => {
124
+ const formatRequestBody = (body)=>{
105
125
  try {
106
126
  const parsed = JSON.parse(body);
107
127
  // Recursively process all parameters that might contain hex strings
108
- const processParams = (obj) => {
128
+ const processParams = (obj)=>{
109
129
  if (Array.isArray(obj)) {
110
- return obj.map(item => processParams(item));
130
+ return obj.map((item)=>processParams(item));
111
131
  }
112
132
  if (typeof obj === 'object' && obj !== null) {
113
133
  const result = {};
114
- for (const [key, value] of Object.entries(obj)) {
134
+ for (const [key, value] of Object.entries(obj)){
115
135
  result[key] = processParams(value);
116
136
  }
117
137
  return result;
@@ -126,35 +146,37 @@ export function formatViemError(error, abi = ErrorsAbi) {
126
146
  // Process the entire request body
127
147
  const processed = processParams(parsed);
128
148
  return JSON.stringify(processed, null, 2);
129
- }
130
- catch {
149
+ } catch {
131
150
  return body;
132
151
  }
133
152
  };
134
- const truncateHexStringsInText = (text) => {
153
+ const truncateHexStringsInText = (text)=>{
135
154
  const hexRegex = /\b0x[a-fA-F0-9]{10,}/g;
136
- return text.replace(hexRegex, hex => truncateHex(hex));
155
+ return text.replace(hexRegex, (hex)=>truncateHex(hex));
137
156
  };
138
- const extractAndFormatRequestBody = (message) => {
157
+ const extractAndFormatRequestBody = (message)=>{
139
158
  // First handle Request body JSON
140
159
  const requestBodyRegex = /Request body: ({[\s\S]*?})\n/g;
141
- let result = message.replace(requestBodyRegex, (match, body) => {
160
+ let result = message.replace(requestBodyRegex, (match, body)=>{
142
161
  return `Request body: ${formatRequestBody(body)}\n`;
143
162
  });
144
163
  // Then handle Arguments section
145
164
  const argsRegex = /((?:Request |Estimate Gas )?Arguments:[\s\S]*?(?=\n\n|$))/g;
146
- result = result.replace(argsRegex, section => {
165
+ result = result.replace(argsRegex, (section)=>{
147
166
  const lines = section.split('\n');
148
- const processedLines = lines.map(line => {
167
+ const processedLines = lines.map((line)=>{
149
168
  // Check if line contains a colon followed by content
150
169
  const colonIndex = line.indexOf(':');
151
170
  if (colonIndex !== -1) {
152
- const [prefix, content] = [line.slice(0, colonIndex + 1), line.slice(colonIndex + 1).trim()];
171
+ const [prefix, content] = [
172
+ line.slice(0, colonIndex + 1),
173
+ line.slice(colonIndex + 1).trim()
174
+ ];
153
175
  // If content contains a hex string, truncate it
154
176
  if (content.includes('0x')) {
155
177
  const hexMatches = content.match(/0x[a-fA-F0-9]+/g) || [];
156
178
  let processedContent = content;
157
- hexMatches.forEach(hex => {
179
+ hexMatches.forEach((hex)=>{
158
180
  processedContent = processedContent.replace(hex, truncateHex(hex));
159
181
  });
160
182
  return `${prefix} ${processedContent}`;
@@ -176,14 +198,12 @@ export function tryGetCustomErrorName(err) {
176
198
  // See https://viem.sh/docs/contract/simulateContract#handling-custom-errors
177
199
  if (err.name === 'ViemError' || err.name === 'ContractFunctionExecutionError') {
178
200
  const baseError = err;
179
- const revertError = baseError.walk(err => err.name === 'ContractFunctionRevertedError');
201
+ const revertError = baseError.walk((err)=>err.name === 'ContractFunctionRevertedError');
180
202
  if (revertError) {
181
203
  return revertError.data?.errorName;
182
204
  }
183
205
  }
184
- }
185
- catch (_e) {
206
+ } catch (_e) {
186
207
  return undefined;
187
208
  }
188
209
  }
189
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRWhELE9BQU8sRUFFTCxTQUFTLEVBRVQsNkJBQTZCLEVBSTdCLGlCQUFpQixFQUNqQixjQUFjLEdBQ2YsTUFBTSxNQUFNLENBQUM7QUFTZCxNQUFNLE9BQU8sa0JBQW1CLFNBQVEsS0FBSztJQUczQyxZQUFZLE9BQWUsRUFBRSxZQUFvQjtRQUMvQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLG9CQUFvQixDQUFDO1FBQ2pDLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO0lBQ25DLENBQUM7Q0FDRjtBQUVELE1BQU0sVUFBVSxZQUFZLENBSzFCLElBQVcsRUFDWCxPQUFZLEVBQ1osR0FBUyxFQUNULFNBQXFCLEVBQ3JCLE1BQXFDLEVBQ3JDLE1BQWU7SUFFZixNQUFNLEtBQUssR0FBRyxlQUFlLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM3RSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxTQUFTLGlCQUFpQixPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FLdEIsSUFBVyxFQUNYLE9BQVksRUFDWixHQUFTLEVBQ1QsU0FBcUIsRUFDckIsTUFBcUMsRUFDckMsTUFBZTtJQUVmLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDdkIsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxLQUFLLE9BQU8sQ0FBQyxXQUFXLEVBQUUs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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/ethereum",
3
- "version": "0.73.0",
3
+ "version": "0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -26,14 +26,15 @@
26
26
  "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
27
27
  "start:dev": "tsc-watch -p tsconfig.json --onSuccess 'yarn start'",
28
28
  "start": "node ./dest/index.js",
29
- "test": "HARDWARE_CONCURRENCY=${HARDWARE_CONCURRENCY:-16} RAYON_NUM_THREADS=${RAYON_NUM_THREADS:-4} NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
29
+ "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
30
30
  },
31
31
  "inherits": [
32
32
  "../package.common.json"
33
33
  ],
34
34
  "dependencies": {
35
- "@aztec/foundation": "0.73.0",
36
- "@aztec/l1-artifacts": "0.73.0",
35
+ "@aztec/blob-lib": "0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2",
36
+ "@aztec/foundation": "0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2",
37
+ "@aztec/l1-artifacts": "0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2",
37
38
  "@viem/anvil": "^0.0.10",
38
39
  "dotenv": "^16.0.3",
39
40
  "tslib": "^2.4.0",
@@ -0,0 +1,19 @@
1
+ import { EmpireBaseAbi } from '@aztec/l1-artifacts/EmpireBaseAbi';
2
+
3
+ import { type Hex, encodeFunctionData } from 'viem';
4
+
5
+ import { type L1TxRequest } from '../l1_tx_utils.js';
6
+
7
+ export interface IEmpireBase {
8
+ getRoundInfo(rollupAddress: Hex, round: bigint): Promise<{ lastVote: bigint; leader: Hex; executed: boolean }>;
9
+ computeRound(slot: bigint): Promise<bigint>;
10
+ createVoteRequest(payload: Hex): L1TxRequest;
11
+ }
12
+
13
+ export function encodeVote(payload: Hex): Hex {
14
+ return encodeFunctionData({
15
+ abi: EmpireBaseAbi,
16
+ functionName: 'vote',
17
+ args: [payload],
18
+ });
19
+ }
@@ -1,9 +1,11 @@
1
+ import { toHex } from '@aztec/foundation/bigint-buffer';
1
2
  import { type Logger } from '@aztec/foundation/log';
2
3
  import { ForwarderAbi, ForwarderBytecode } from '@aztec/l1-artifacts';
3
4
 
4
5
  import {
5
6
  type Account,
6
7
  type Chain,
8
+ type EncodeFunctionDataParameters,
7
9
  type GetContractReturnType,
8
10
  type Hex,
9
11
  type HttpTransport,
@@ -15,11 +17,12 @@ import {
15
17
 
16
18
  import { type L1Clients, deployL1Contract } from '../deploy_l1_contracts.js';
17
19
  import { type L1BlobInputs, type L1GasConfig, type L1TxRequest, type L1TxUtils } from '../l1_tx_utils.js';
20
+ import { RollupContract } from './rollup.js';
18
21
 
19
22
  export class ForwarderContract {
20
23
  private readonly forwarder: GetContractReturnType<typeof ForwarderAbi, PublicClient<HttpTransport, Chain>>;
21
24
 
22
- constructor(public readonly client: L1Clients['publicClient'], address: Hex) {
25
+ constructor(public readonly client: L1Clients['publicClient'], address: Hex, public readonly rollupAddress: Hex) {
23
26
  this.forwarder = getContract({ address, abi: ForwarderAbi, client });
24
27
  }
25
28
 
@@ -28,6 +31,7 @@ export class ForwarderContract {
28
31
  walletClient: WalletClient<HttpTransport, Chain, Account>,
29
32
  publicClient: PublicClient<HttpTransport, Chain>,
30
33
  logger: Logger,
34
+ rollupAddress: Hex,
31
35
  ) {
32
36
  logger.info('Deploying forwarder contract');
33
37
 
@@ -48,7 +52,7 @@ export class ForwarderContract {
48
52
 
49
53
  logger.info(`Forwarder contract deployed at ${address} with owner ${owner}`);
50
54
 
51
- return new ForwarderContract(publicClient, address.toString());
55
+ return new ForwarderContract(publicClient, address.toString(), rollupAddress);
52
56
  }
53
57
 
54
58
  public getAddress() {
@@ -60,20 +64,22 @@ export class ForwarderContract {
60
64
  l1TxUtils: L1TxUtils,
61
65
  gasConfig: L1GasConfig | undefined,
62
66
  blobConfig: L1BlobInputs | undefined,
67
+ logger: Logger,
63
68
  ) {
64
69
  requests = requests.filter(request => request.to !== null);
65
70
  const toArgs = requests.map(request => request.to!);
66
71
  const dataArgs = requests.map(request => request.data!);
67
- const data = encodeFunctionData({
72
+ const forwarderFunctionData: EncodeFunctionDataParameters<typeof ForwarderAbi, 'forward'> = {
68
73
  abi: ForwarderAbi,
69
74
  functionName: 'forward',
70
75
  args: [toArgs, dataArgs],
71
- });
76
+ };
77
+ const encodedForwarderData = encodeFunctionData(forwarderFunctionData);
72
78
 
73
79
  const { receipt, gasPrice } = await l1TxUtils.sendAndMonitorTransaction(
74
80
  {
75
81
  to: this.forwarder.address,
76
- data,
82
+ data: encodedForwarderData,
77
83
  },
78
84
  gasConfig,
79
85
  blobConfig,
@@ -83,10 +89,10 @@ export class ForwarderContract {
83
89
  const stats = await l1TxUtils.getTransactionStats(receipt.transactionHash);
84
90
  return { receipt, gasPrice, stats };
85
91
  } else {
92
+ logger.error('Forwarder transaction failed', undefined, { receipt });
93
+
86
94
  const args = {
87
- args: [toArgs, dataArgs],
88
- functionName: 'forward',
89
- abi: ForwarderAbi,
95
+ ...forwarderFunctionData,
90
96
  address: this.forwarder.address,
91
97
  };
92
98
 
@@ -97,14 +103,31 @@ export class ForwarderContract {
97
103
  if (maxFeePerBlobGas === undefined) {
98
104
  errorMsg = 'maxFeePerBlobGas is required to get the error message';
99
105
  } else {
100
- errorMsg = await l1TxUtils.tryGetErrorFromRevertedTx(data, args, {
101
- blobs: blobConfig.blobs,
102
- kzg: blobConfig.kzg,
103
- maxFeePerBlobGas,
104
- });
106
+ logger.debug('Trying to get error from reverted tx with blob config');
107
+ errorMsg = await l1TxUtils.tryGetErrorFromRevertedTx(
108
+ encodedForwarderData,
109
+ args,
110
+ {
111
+ blobs: blobConfig.blobs,
112
+ kzg: blobConfig.kzg,
113
+ maxFeePerBlobGas,
114
+ },
115
+ [
116
+ {
117
+ address: this.rollupAddress,
118
+ stateDiff: [
119
+ {
120
+ slot: toHex(RollupContract.checkBlobStorageSlot, true),
121
+ value: toHex(0n, true),
122
+ },
123
+ ],
124
+ },
125
+ ],
126
+ );
105
127
  }
106
128
  } else {
107
- errorMsg = await l1TxUtils.tryGetErrorFromRevertedTx(data, args);
129
+ logger.debug('Trying to get error from reverted tx without blob config');
130
+ errorMsg = await l1TxUtils.tryGetErrorFromRevertedTx(encodedForwarderData, args, undefined, []);
108
131
  }
109
132
 
110
133
  return { receipt, gasPrice, errorMsg };
@@ -8,13 +8,19 @@ import {
8
8
  type Hex,
9
9
  type HttpTransport,
10
10
  type PublicClient,
11
+ type TransactionReceipt,
12
+ encodeFunctionData,
11
13
  getContract,
12
14
  } from 'viem';
13
15
 
14
- export class GovernanceProposerContract {
16
+ import type { L1Clients } from '../deploy_l1_contracts.js';
17
+ import type { GasPrice, L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
18
+ import { type IEmpireBase, encodeVote } from './empire_base.js';
19
+
20
+ export class GovernanceProposerContract implements IEmpireBase {
15
21
  private readonly proposer: GetContractReturnType<typeof GovernanceProposerAbi, PublicClient<HttpTransport, Chain>>;
16
22
 
17
- constructor(public readonly client: PublicClient<HttpTransport, Chain>, address: Hex) {
23
+ constructor(public readonly client: L1Clients['publicClient'], address: Hex) {
18
24
  this.proposer = getContract({ address, abi: GovernanceProposerAbi, client });
19
25
  }
20
26
 
@@ -31,11 +37,55 @@ export class GovernanceProposerContract {
31
37
  return EthAddress.fromString(await this.proposer.read.REGISTRY());
32
38
  }
33
39
 
34
- public getQuorumSize() {
40
+ public getQuorumSize(): Promise<bigint> {
35
41
  return this.proposer.read.N();
36
42
  }
37
43
 
38
- public getRoundSize() {
44
+ public getRoundSize(): Promise<bigint> {
39
45
  return this.proposer.read.M();
40
46
  }
47
+
48
+ public computeRound(slot: bigint): Promise<bigint> {
49
+ return this.proposer.read.computeRound([slot]);
50
+ }
51
+
52
+ public async getRoundInfo(
53
+ rollupAddress: Hex,
54
+ round: bigint,
55
+ ): Promise<{ lastVote: bigint; leader: Hex; executed: boolean }> {
56
+ const roundInfo = await this.proposer.read.rounds([rollupAddress, round]);
57
+ return {
58
+ lastVote: roundInfo[0],
59
+ leader: roundInfo[1],
60
+ executed: roundInfo[2],
61
+ };
62
+ }
63
+
64
+ public getProposalVotes(rollupAddress: Hex, round: bigint, proposal: Hex): Promise<bigint> {
65
+ return this.proposer.read.yeaCount([rollupAddress, round, proposal]);
66
+ }
67
+
68
+ public createVoteRequest(payload: Hex): L1TxRequest {
69
+ return {
70
+ to: this.address.toString(),
71
+ data: encodeVote(payload),
72
+ };
73
+ }
74
+
75
+ public executeProposal(
76
+ round: bigint,
77
+ l1TxUtils: L1TxUtils,
78
+ ): Promise<{
79
+ receipt: TransactionReceipt;
80
+ gasPrice: GasPrice;
81
+ }> {
82
+ return l1TxUtils.sendAndMonitorTransaction({
83
+ to: this.address.toString(),
84
+ data: encodeFunctionData({
85
+ abi: this.proposer.abi,
86
+ functionName: 'executeProposal',
87
+ args: [round],
88
+ }),
89
+ });
90
+ }
41
91
  }
@@ -1,5 +1,6 @@
1
+ export * from './empire_base.js';
1
2
  export * from './forwarder.js';
2
- export * from './rollup.js';
3
3
  export * from './governance.js';
4
4
  export * from './governance_proposer.js';
5
+ export * from './rollup.js';
5
6
  export * from './slashing_proposer.js';
@@ -1,7 +1,7 @@
1
1
  import { memoize } from '@aztec/foundation/decorators';
2
2
  import { EthAddress } from '@aztec/foundation/eth-address';
3
3
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
4
- import { RollupAbi, SlasherAbi } from '@aztec/l1-artifacts';
4
+ import { RollupAbi, RollupStorage, SlasherAbi } from '@aztec/l1-artifacts';
5
5
 
6
6
  import {
7
7
  type Account,
@@ -45,6 +45,14 @@ export type EpochProofQuoteViemArgs = {
45
45
  export class RollupContract {
46
46
  private readonly rollup: GetContractReturnType<typeof RollupAbi, PublicClient<HttpTransport, Chain>>;
47
47
 
48
+ static get checkBlobStorageSlot(): bigint {
49
+ const asString = RollupStorage.find(storage => storage.label === 'checkBlob')?.slot;
50
+ if (asString === undefined) {
51
+ throw new Error('checkBlobStorageSlot not found');
52
+ }
53
+ return BigInt(asString);
54
+ }
55
+
48
56
  static getFromL1ContractsValues(deployL1ContractsValues: DeployL1Contracts) {
49
57
  const {
50
58
  publicClient,
@@ -72,7 +80,7 @@ export class RollupContract {
72
80
 
73
81
  @memoize
74
82
  public async getSlashingProposer() {
75
- const slasherAddress = await this.rollup.read.SLASHER();
83
+ const slasherAddress = await this.rollup.read.getSlasher();
76
84
  const slasher = getContract({ address: slasherAddress, abi: SlasherAbi, client: this.client });
77
85
  const proposerAddress = await slasher.read.PROPOSER();
78
86
  return new SlashingProposerContract(this.client, proposerAddress);
@@ -85,7 +93,7 @@ export class RollupContract {
85
93
 
86
94
  @memoize
87
95
  getL1GenesisTime() {
88
- return this.rollup.read.GENESIS_TIME();
96
+ return this.rollup.read.getGenesisTime();
89
97
  }
90
98
 
91
99
  @memoize
@@ -95,26 +103,26 @@ export class RollupContract {
95
103
 
96
104
  @memoize
97
105
  getEpochDuration() {
98
- return this.rollup.read.EPOCH_DURATION();
106
+ return this.rollup.read.getEpochDuration();
99
107
  }
100
108
 
101
109
  @memoize
102
110
  getSlotDuration() {
103
- return this.rollup.read.SLOT_DURATION();
111
+ return this.rollup.read.getSlotDuration();
104
112
  }
105
113
 
106
114
  @memoize
107
115
  getTargetCommitteeSize() {
108
- return this.rollup.read.TARGET_COMMITTEE_SIZE();
116
+ return this.rollup.read.getTargetCommitteeSize();
109
117
  }
110
118
 
111
119
  @memoize
112
120
  getMinimumStake() {
113
- return this.rollup.read.MINIMUM_STAKE();
121
+ return this.rollup.read.getMinimumStake();
114
122
  }
115
123
 
116
124
  public async getSlashingProposerAddress() {
117
- const slasherAddress = await this.rollup.read.SLASHER();
125
+ const slasherAddress = await this.rollup.read.getSlasher();
118
126
  const slasher = getContract({
119
127
  address: getAddress(slasherAddress.toString()),
120
128
  abi: SlasherAbi,
@@ -171,6 +179,10 @@ export class RollupContract {
171
179
  return this.rollup.read.getTips();
172
180
  }
173
181
 
182
+ getTimestampForSlot(slot: bigint) {
183
+ return this.rollup.read.getTimestampForSlot([slot]);
184
+ }
185
+
174
186
  async getEpochNumber(blockNumber?: bigint) {
175
187
  blockNumber ??= await this.getBlockNumber();
176
188
  return this.rollup.read.getEpochForBlock([BigInt(blockNumber)]);
@@ -191,7 +203,7 @@ export class RollupContract {
191
203
  this.rollup.read.FEE_JUICE_PORTAL(),
192
204
  this.rollup.read.REWARD_DISTRIBUTOR(),
193
205
  this.rollup.read.ASSET(),
194
- this.rollup.read.STAKING_ASSET(),
206
+ this.rollup.read.getStakingAsset(),
195
207
  ] as const)
196
208
  ).map(EthAddress.fromString);
197
209
 
@@ -10,10 +10,14 @@ import {
10
10
  getContract,
11
11
  } from 'viem';
12
12
 
13
- export class SlashingProposerContract {
13
+ import type { L1Clients } from '../deploy_l1_contracts.js';
14
+ import type { L1TxRequest } from '../l1_tx_utils.js';
15
+ import { type IEmpireBase, encodeVote } from './empire_base.js';
16
+
17
+ export class SlashingProposerContract implements IEmpireBase {
14
18
  private readonly proposer: GetContractReturnType<typeof SlashingProposerAbi, PublicClient<HttpTransport, Chain>>;
15
19
 
16
- constructor(public readonly client: PublicClient<HttpTransport, Chain>, address: Hex) {
20
+ constructor(public readonly client: L1Clients['publicClient'], address: Hex) {
17
21
  this.proposer = getContract({ address, abi: SlashingProposerAbi, client });
18
22
  }
19
23
 
@@ -28,4 +32,27 @@ export class SlashingProposerContract {
28
32
  public getRoundSize() {
29
33
  return this.proposer.read.M();
30
34
  }
35
+
36
+ public computeRound(slot: bigint): Promise<bigint> {
37
+ return this.proposer.read.computeRound([slot]);
38
+ }
39
+
40
+ public async getRoundInfo(
41
+ rollupAddress: Hex,
42
+ round: bigint,
43
+ ): Promise<{ lastVote: bigint; leader: Hex; executed: boolean }> {
44
+ const roundInfo = await this.proposer.read.rounds([rollupAddress, round]);
45
+ return {
46
+ lastVote: roundInfo[0],
47
+ leader: roundInfo[1],
48
+ executed: roundInfo[2],
49
+ };
50
+ }
51
+
52
+ public createVoteRequest(payload: Hex): L1TxRequest {
53
+ return {
54
+ to: this.address.toString(),
55
+ data: encodeVote(payload),
56
+ };
57
+ }
31
58
  }
@@ -28,6 +28,8 @@ import {
28
28
  RollupLinkReferences,
29
29
  SlashFactoryAbi,
30
30
  SlashFactoryBytecode,
31
+ StakingLibAbi,
32
+ StakingLibBytecode,
31
33
  TestERC20Abi,
32
34
  TestERC20Bytecode,
33
35
  ValidatorSelectionLibAbi,
@@ -146,6 +148,10 @@ export const l1Artifacts = {
146
148
  contractAbi: ExtRollupLibAbi,
147
149
  contractBytecode: ExtRollupLibBytecode as Hex,
148
150
  },
151
+ StakingLib: {
152
+ contractAbi: StakingLibAbi,
153
+ contractBytecode: StakingLibBytecode as Hex,
154
+ },
149
155
  },
150
156
  },
151
157
  },