@aztec/ethereum 0.0.1-commit.f2ce05ee → 0.0.1-commit.f5a9928

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 (181) hide show
  1. package/dest/client.d.ts +27 -3
  2. package/dest/client.d.ts.map +1 -1
  3. package/dest/client.js +63 -8
  4. package/dest/config.d.ts +17 -6
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +38 -10
  7. package/dest/contracts/chain_state_override.d.ts +78 -0
  8. package/dest/contracts/chain_state_override.d.ts.map +1 -0
  9. package/dest/contracts/chain_state_override.js +137 -0
  10. package/dest/contracts/fee_asset_price_oracle.d.ts +105 -0
  11. package/dest/contracts/fee_asset_price_oracle.d.ts.map +1 -0
  12. package/dest/contracts/fee_asset_price_oracle.js +656 -0
  13. package/dest/contracts/governance.d.ts +135 -35
  14. package/dest/contracts/governance.d.ts.map +1 -1
  15. package/dest/contracts/governance.js +229 -18
  16. package/dest/contracts/governance_proposer.d.ts +33 -2
  17. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  18. package/dest/contracts/governance_proposer.js +54 -6
  19. package/dest/contracts/gse.d.ts +4 -2
  20. package/dest/contracts/gse.d.ts.map +1 -1
  21. package/dest/contracts/gse.js +2 -2
  22. package/dest/contracts/inbox.d.ts +3 -3
  23. package/dest/contracts/inbox.d.ts.map +1 -1
  24. package/dest/contracts/inbox.js +12 -7
  25. package/dest/contracts/index.d.ts +4 -3
  26. package/dest/contracts/index.d.ts.map +1 -1
  27. package/dest/contracts/index.js +3 -2
  28. package/dest/contracts/multicall.d.ts +127 -12
  29. package/dest/contracts/multicall.d.ts.map +1 -1
  30. package/dest/contracts/multicall.js +201 -94
  31. package/dest/contracts/outbox.d.ts +27 -4
  32. package/dest/contracts/outbox.d.ts.map +1 -1
  33. package/dest/contracts/outbox.js +34 -7
  34. package/dest/contracts/registry.d.ts +3 -1
  35. package/dest/contracts/registry.d.ts.map +1 -1
  36. package/dest/contracts/registry.js +30 -1
  37. package/dest/contracts/rollup.d.ts +5437 -34
  38. package/dest/contracts/rollup.d.ts.map +1 -1
  39. package/dest/contracts/rollup.js +448 -104
  40. package/dest/contracts/slashing_proposer.d.ts +171 -0
  41. package/dest/contracts/slashing_proposer.d.ts.map +1 -0
  42. package/dest/contracts/slashing_proposer.js +753 -0
  43. package/dest/contracts/watch_event.d.ts +36 -0
  44. package/dest/contracts/watch_event.d.ts.map +1 -0
  45. package/dest/contracts/watch_event.js +66 -0
  46. package/dest/deploy_aztec_l1_contracts.d.ts +5 -9
  47. package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -1
  48. package/dest/deploy_aztec_l1_contracts.js +48 -27
  49. package/dest/deploy_l1_contract.js +3 -3
  50. package/dest/foundry_binary.d.ts +13 -0
  51. package/dest/foundry_binary.d.ts.map +1 -0
  52. package/dest/foundry_binary.js +52 -0
  53. package/dest/generated/l1-contracts-defaults.d.ts +3 -3
  54. package/dest/generated/l1-contracts-defaults.js +3 -3
  55. package/dest/l1_artifacts.d.ts +15524 -15847
  56. package/dest/l1_artifacts.d.ts.map +1 -1
  57. package/dest/l1_artifacts.js +9 -24
  58. package/dest/l1_contract_addresses.d.ts +61 -65
  59. package/dest/l1_contract_addresses.d.ts.map +1 -1
  60. package/dest/l1_contract_addresses.js +101 -82
  61. package/dest/l1_reader.d.ts +5 -5
  62. package/dest/l1_reader.d.ts.map +1 -1
  63. package/dest/l1_reader.js +9 -7
  64. package/dest/l1_tx_utils/config.d.ts +7 -1
  65. package/dest/l1_tx_utils/config.d.ts.map +1 -1
  66. package/dest/l1_tx_utils/config.js +17 -4
  67. package/dest/l1_tx_utils/factory.d.ts +18 -10
  68. package/dest/l1_tx_utils/factory.d.ts.map +1 -1
  69. package/dest/l1_tx_utils/factory.js +17 -7
  70. package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +1 -1
  71. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +1 -1
  72. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +15 -15
  73. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -1
  74. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +9 -15
  75. package/dest/l1_tx_utils/index-blobs.d.ts +3 -3
  76. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -1
  77. package/dest/l1_tx_utils/index-blobs.js +2 -2
  78. package/dest/l1_tx_utils/index.d.ts +2 -1
  79. package/dest/l1_tx_utils/index.d.ts.map +1 -1
  80. package/dest/l1_tx_utils/index.js +1 -0
  81. package/dest/l1_tx_utils/l1_tx_utils.d.ts +26 -7
  82. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
  83. package/dest/l1_tx_utils/l1_tx_utils.js +156 -79
  84. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +1 -1
  85. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
  86. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +57 -23
  87. package/dest/l1_tx_utils/tx_delayer.d.ts +58 -0
  88. package/dest/l1_tx_utils/tx_delayer.d.ts.map +1 -0
  89. package/dest/{test → l1_tx_utils}/tx_delayer.js +67 -37
  90. package/dest/publisher_manager.d.ts +34 -8
  91. package/dest/publisher_manager.d.ts.map +1 -1
  92. package/dest/publisher_manager.js +119 -8
  93. package/dest/queries.d.ts +13 -2
  94. package/dest/queries.d.ts.map +1 -1
  95. package/dest/queries.js +62 -3
  96. package/dest/test/blob_kzg_warmup.d.ts +19 -0
  97. package/dest/test/blob_kzg_warmup.d.ts.map +1 -0
  98. package/dest/test/blob_kzg_warmup.js +64 -0
  99. package/dest/test/chain_monitor.d.ts +55 -4
  100. package/dest/test/chain_monitor.d.ts.map +1 -1
  101. package/dest/test/chain_monitor.js +104 -3
  102. package/dest/test/eth_cheat_codes.d.ts +31 -6
  103. package/dest/test/eth_cheat_codes.d.ts.map +1 -1
  104. package/dest/test/eth_cheat_codes.js +67 -44
  105. package/dest/test/index.d.ts +2 -3
  106. package/dest/test/index.d.ts.map +1 -1
  107. package/dest/test/index.js +1 -2
  108. package/dest/test/recording_rpc_server.d.ts +18 -0
  109. package/dest/test/recording_rpc_server.d.ts.map +1 -0
  110. package/dest/test/recording_rpc_server.js +68 -0
  111. package/dest/test/rollup_cheat_codes.d.ts +60 -3
  112. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  113. package/dest/test/rollup_cheat_codes.js +86 -7
  114. package/dest/test/start_anvil.d.ts +23 -3
  115. package/dest/test/start_anvil.d.ts.map +1 -1
  116. package/dest/test/start_anvil.js +182 -32
  117. package/dest/test/upgrade_utils.js +2 -2
  118. package/dest/utils.d.ts +9 -2
  119. package/dest/utils.d.ts.map +1 -1
  120. package/dest/utils.js +59 -24
  121. package/package.json +6 -8
  122. package/src/client.ts +72 -2
  123. package/src/config.ts +58 -14
  124. package/src/contracts/chain_state_override.ts +200 -0
  125. package/src/contracts/fee_asset_price_oracle.ts +285 -0
  126. package/src/contracts/governance.ts +313 -13
  127. package/src/contracts/governance_proposer.ts +58 -9
  128. package/src/contracts/gse.ts +7 -2
  129. package/src/contracts/inbox.ts +13 -5
  130. package/src/contracts/index.ts +3 -2
  131. package/src/contracts/multicall.ts +243 -105
  132. package/src/contracts/outbox.ts +42 -8
  133. package/src/contracts/registry.ts +31 -1
  134. package/src/contracts/rollup.ts +507 -109
  135. package/src/contracts/{tally_slashing_proposer.ts → slashing_proposer.ts} +119 -45
  136. package/src/contracts/watch_event.ts +110 -0
  137. package/src/deploy_aztec_l1_contracts.ts +75 -39
  138. package/src/deploy_l1_contract.ts +3 -3
  139. package/src/foundry_binary.ts +57 -0
  140. package/src/generated/l1-contracts-defaults.ts +3 -3
  141. package/src/l1_artifacts.ts +12 -35
  142. package/src/l1_contract_addresses.ts +120 -94
  143. package/src/l1_reader.ts +17 -10
  144. package/src/l1_tx_utils/config.ts +23 -3
  145. package/src/l1_tx_utils/factory.ts +31 -31
  146. package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +1 -1
  147. package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +1 -1
  148. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +43 -54
  149. package/src/l1_tx_utils/index-blobs.ts +2 -2
  150. package/src/l1_tx_utils/index.ts +1 -0
  151. package/src/l1_tx_utils/l1_tx_utils.ts +149 -64
  152. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +57 -17
  153. package/src/{test → l1_tx_utils}/tx_delayer.ts +93 -56
  154. package/src/publisher_manager.ts +143 -12
  155. package/src/queries.ts +70 -4
  156. package/src/test/blob_kzg_warmup.ts +65 -0
  157. package/src/test/chain_monitor.ts +148 -3
  158. package/src/test/eth_cheat_codes.ts +63 -47
  159. package/src/test/index.ts +1 -2
  160. package/src/test/recording_rpc_server.ts +69 -0
  161. package/src/test/rollup_cheat_codes.ts +115 -6
  162. package/src/test/start_anvil.ts +212 -32
  163. package/src/test/upgrade_utils.ts +2 -2
  164. package/src/utils.ts +56 -29
  165. package/dest/contracts/empire_slashing_proposer.d.ts +0 -67
  166. package/dest/contracts/empire_slashing_proposer.d.ts.map +0 -1
  167. package/dest/contracts/empire_slashing_proposer.js +0 -207
  168. package/dest/contracts/tally_slashing_proposer.d.ts +0 -140
  169. package/dest/contracts/tally_slashing_proposer.d.ts.map +0 -1
  170. package/dest/contracts/tally_slashing_proposer.js +0 -320
  171. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +0 -26
  172. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +0 -1
  173. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +0 -26
  174. package/dest/test/delayed_tx_utils.d.ts +0 -13
  175. package/dest/test/delayed_tx_utils.d.ts.map +0 -1
  176. package/dest/test/delayed_tx_utils.js +0 -28
  177. package/dest/test/tx_delayer.d.ts +0 -36
  178. package/dest/test/tx_delayer.d.ts.map +0 -1
  179. package/src/contracts/empire_slashing_proposer.ts +0 -259
  180. package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +0 -77
  181. package/src/test/delayed_tx_utils.ts +0 -52
@@ -1,207 +0,0 @@
1
- import { SlotNumber } from '@aztec/foundation/branded-types';
2
- import { EthAddress } from '@aztec/foundation/eth-address';
3
- import { createLogger } from '@aztec/foundation/log';
4
- import { retryUntil } from '@aztec/foundation/retry';
5
- import { EmpireSlashingProposerAbi } from '@aztec/l1-artifacts/EmpireSlashingProposerAbi';
6
- import EventEmitter from 'events';
7
- import { encodeFunctionData, getContract } from 'viem';
8
- import { FormattedViemError, tryExtractEvent } from '../utils.js';
9
- import { encodeSignal, encodeSignalWithSignature, signSignalWithSig } from './empire_base.js';
10
- export class ProposalAlreadyExecutedError extends Error {
11
- constructor(round){
12
- super(`Proposal already executed: ${round}`);
13
- }
14
- }
15
- export class EmpireSlashingProposerContract extends EventEmitter {
16
- client;
17
- logger;
18
- proposer;
19
- type;
20
- constructor(client, address){
21
- super(), this.client = client, this.logger = createLogger('ethereum:contracts:empire_slashing_proposer'), this.type = 'empire';
22
- this.proposer = getContract({
23
- address: typeof address === 'string' ? address : address.toString(),
24
- abi: EmpireSlashingProposerAbi,
25
- client
26
- });
27
- }
28
- get address() {
29
- return EthAddress.fromString(this.proposer.address);
30
- }
31
- getQuorumSize() {
32
- return this.proposer.read.QUORUM_SIZE();
33
- }
34
- getRoundSize() {
35
- return this.proposer.read.ROUND_SIZE();
36
- }
37
- getLifetimeInRounds() {
38
- return this.proposer.read.LIFETIME_IN_ROUNDS();
39
- }
40
- getExecutionDelayInRounds() {
41
- return this.proposer.read.EXECUTION_DELAY_IN_ROUNDS();
42
- }
43
- getCurrentRound() {
44
- return this.proposer.read.getCurrentRound();
45
- }
46
- computeRound(slot) {
47
- return this.proposer.read.computeRound([
48
- BigInt(slot)
49
- ]);
50
- }
51
- getInstance() {
52
- return this.proposer.read.getInstance();
53
- }
54
- async getRoundInfo(rollupAddress, round) {
55
- const result = await this.proposer.read.getRoundData([
56
- rollupAddress,
57
- round
58
- ]);
59
- const [signalCount, quorum] = await Promise.all([
60
- this.proposer.read.signalCount([
61
- rollupAddress,
62
- round,
63
- result.payloadWithMostSignals
64
- ]),
65
- this.getQuorumSize()
66
- ]);
67
- return {
68
- lastSignalSlot: SlotNumber.fromBigInt(result.lastSignalSlot),
69
- payloadWithMostSignals: result.payloadWithMostSignals,
70
- quorumReached: signalCount >= quorum,
71
- executed: result.executed
72
- };
73
- }
74
- getPayloadSignals(rollupAddress, round, payload) {
75
- return this.proposer.read.signalCount([
76
- rollupAddress,
77
- round,
78
- payload
79
- ]);
80
- }
81
- createSignalRequest(payload) {
82
- return {
83
- to: this.address.toString(),
84
- abi: EmpireSlashingProposerAbi,
85
- data: encodeSignal(payload)
86
- };
87
- }
88
- async createSignalRequestWithSignature(payload, slot, chainId, signerAddress, signer) {
89
- const signature = await signSignalWithSig(signer, payload, slot, await this.getInstance(), this.address.toString(), chainId);
90
- return {
91
- to: this.address.toString(),
92
- abi: EmpireSlashingProposerAbi,
93
- data: encodeSignalWithSignature(payload, signature)
94
- };
95
- }
96
- listenToSubmittablePayloads(callback) {
97
- return this.proposer.watchEvent.PayloadSubmittable({}, {
98
- strict: true,
99
- onLogs: (logs)=>{
100
- for (const log of logs){
101
- const { payload, round } = log.args;
102
- if (payload && round) {
103
- callback({
104
- payload,
105
- round
106
- });
107
- }
108
- }
109
- }
110
- });
111
- }
112
- listenToPayloadSubmitted(callback) {
113
- return this.proposer.watchEvent.PayloadSubmitted({}, {
114
- onLogs: (logs)=>{
115
- for (const log of logs){
116
- const { payload, round } = log.args;
117
- if (round && payload) {
118
- callback({
119
- round,
120
- payload
121
- });
122
- }
123
- }
124
- }
125
- });
126
- }
127
- listenToSignalCasted(callback) {
128
- return this.proposer.watchEvent.SignalCast({}, {
129
- onLogs: (logs)=>{
130
- for (const log of logs){
131
- const { round, payload, signaler } = log.args;
132
- if (round && payload && signaler) {
133
- callback({
134
- round,
135
- payload,
136
- signaler
137
- });
138
- }
139
- }
140
- }
141
- });
142
- }
143
- /** Creates an L1TxRequest to submit the round winner for the given round. */ buildExecuteRoundRequest(round) {
144
- return {
145
- to: this.address.toString(),
146
- abi: EmpireSlashingProposerAbi,
147
- data: encodeFunctionData({
148
- abi: EmpireSlashingProposerAbi,
149
- functionName: 'submitRoundWinner',
150
- args: [
151
- round
152
- ]
153
- })
154
- };
155
- }
156
- /** Tries to extract a PayloadSubmitted event from the given logs. */ tryExtractPayloadSubmittedEvent(logs) {
157
- return tryExtractEvent(logs, this.address.toString(), EmpireSlashingProposerAbi, 'PayloadSubmitted');
158
- }
159
- /**
160
- * Wait for a round to be reached.
161
- *
162
- * @param round - The round to wait for.
163
- * @param pollingIntervalSeconds - The interval in seconds to poll for the round.
164
- * @returns True if the round was reached, false otherwise.
165
- */ waitForRound(round, pollingIntervalSeconds = 1) {
166
- return retryUntil(async ()=>{
167
- const currentRound = await this.proposer.read.getCurrentRound().catch((e)=>{
168
- this.logger.error('Error getting current round', e);
169
- return undefined;
170
- });
171
- return currentRound !== undefined && currentRound >= round;
172
- }, `Waiting for round ${round} to be reached`, 0, pollingIntervalSeconds).catch(()=>false);
173
- }
174
- async executeRound(txUtils, round) {
175
- if (typeof round === 'number') {
176
- round = BigInt(round);
177
- }
178
- const request = this.buildExecuteRoundRequest(round);
179
- const response = await txUtils.sendAndMonitorTransaction(request, {
180
- // Gas estimation is way off for this, likely because we are creating the contract/selector to call
181
- // for the actual slashing dynamically.
182
- gasLimitBufferPercentage: 50
183
- }).catch((err)=>{
184
- if (err instanceof FormattedViemError && err.message.includes('ProposalAlreadyExecuted')) {
185
- throw new ProposalAlreadyExecutedError(round);
186
- }
187
- throw err;
188
- });
189
- if (response.receipt.status === 'reverted') {
190
- const args = {
191
- abi: EmpireSlashingProposerAbi,
192
- functionName: 'submitRoundWinner',
193
- args: [
194
- round
195
- ],
196
- address: this.address.toString()
197
- };
198
- const error = await txUtils.tryGetErrorFromRevertedTx(request.data, args, undefined, []);
199
- if (error?.includes('ProposalAlreadyExecuted')) {
200
- throw new ProposalAlreadyExecutedError(round);
201
- }
202
- const errorMessage = `Failed to execute round ${round}, TxHash: ${response.receipt.transactionHash}, Error: ${error ?? 'Unknown error'}`;
203
- throw new Error(errorMessage);
204
- }
205
- return response;
206
- }
207
- }
@@ -1,140 +0,0 @@
1
- import type { L1TxRequest } from '@aztec/ethereum/l1-tx-utils';
2
- import type { ViemClient } from '@aztec/ethereum/types';
3
- import { SlotNumber } from '@aztec/foundation/branded-types';
4
- import { Buffer32 } from '@aztec/foundation/buffer';
5
- import { EthAddress } from '@aztec/foundation/eth-address';
6
- import { type Hex, type Log, type TypedDataDefinition } from 'viem';
7
- /**
8
- * Wrapper around the TallySlashingProposer contract that provides
9
- * a TypeScript interface for interacting with the consensus-based slashing system.
10
- */
11
- export declare class TallySlashingProposerContract {
12
- readonly client: ViemClient;
13
- private readonly contract;
14
- readonly type: "tally";
15
- constructor(client: ViemClient, address: Hex | EthAddress);
16
- get address(): EthAddress;
17
- getQuorumSize(): Promise<bigint>;
18
- getRoundSize(): Promise<bigint>;
19
- getCommitteeSize(): Promise<bigint>;
20
- getRoundSizeInEpochs(): Promise<bigint>;
21
- getLifetimeInRounds(): Promise<bigint>;
22
- getExecutionDelayInRounds(): Promise<bigint>;
23
- getSlashingAmounts(): Promise<[bigint, bigint, bigint]>;
24
- getSlashOffsetInRounds(): Promise<bigint>;
25
- getCurrentRound(): Promise<bigint>;
26
- /**
27
- * Get round information
28
- * @param round - The round number to query
29
- * @returns Round status information
30
- */
31
- getRound(round: bigint): Promise<{
32
- isExecuted: boolean;
33
- voteCount: bigint;
34
- }>;
35
- /**
36
- * Check if a round is ready to execute at a given slot
37
- * @param round - The round number to check
38
- * @param slot - The slot number to check at
39
- * @returns Whether the round is ready to execute
40
- */
41
- isRoundReadyToExecute(round: bigint, slot: SlotNumber): Promise<boolean>;
42
- /** Returns the slash actions and payload address for a given round (zero if no slash actions) */
43
- getPayload(round: bigint): Promise<{
44
- actions: {
45
- slashAmount: bigint;
46
- validator: EthAddress;
47
- }[];
48
- address: EthAddress;
49
- }>;
50
- /** Returns the slash actions to be executed for a given round based on votes */
51
- getTally(round: bigint): Promise<{
52
- actions: {
53
- slashAmount: bigint;
54
- validator: EthAddress;
55
- }[];
56
- committees: EthAddress[][];
57
- }>;
58
- private mapSlashActions;
59
- /** Tries to extract a VoteCast event from the given logs. */
60
- tryExtractVoteCastEvent(logs: Log[]): {
61
- eventName: "VoteCast";
62
- args: {
63
- proposer: `0x${string}`;
64
- round: bigint;
65
- slot: bigint;
66
- };
67
- } | undefined;
68
- /** Tries to extract a RoundExecuted event from the given logs. */
69
- tryExtractRoundExecutedEvent(logs: Log[]): {
70
- eventName: "RoundExecuted";
71
- args: {
72
- round: bigint;
73
- slashCount: bigint;
74
- };
75
- } | undefined;
76
- /**
77
- * Create a transaction to vote for slashing offenses
78
- * @param votes - The encoded votes for slashing
79
- * @param slot - The slot number for the vote
80
- * @param signer - The signer to produce the signature
81
- * @returns L1 transaction request
82
- */
83
- buildVoteRequestFromSigner(votes: Hex, slot: SlotNumber, signer: (msg: TypedDataDefinition) => Promise<Hex>): Promise<L1TxRequest>;
84
- /** Returns the typed data definition to EIP712-sign for voting */
85
- buildVoteTypedData(votes: Hex, slot: SlotNumber): TypedDataDefinition;
86
- /** Gets the digest to sign for voting directly from the contract */
87
- getVoteDataDigest(votes: Hex, slot: SlotNumber): Promise<Buffer32>;
88
- /**
89
- * Create a transaction to vote for slashing offenses
90
- * @param votes - The encoded votes for slashing
91
- * @param signature - The signature from the current proposer
92
- * @returns L1 transaction request
93
- */
94
- buildVoteRequestWithSignature(votes: Hex, signature: {
95
- v: number;
96
- r: Hex;
97
- s: Hex;
98
- }): L1TxRequest;
99
- /**
100
- * Create a transaction to execute a slashing round
101
- * @param round - The round number to execute
102
- * @param committees - The committees for each epoch in the round
103
- * @returns L1 transaction request
104
- */
105
- buildExecuteRoundRequest(round: bigint, committees: EthAddress[][]): L1TxRequest;
106
- /** Returns the last vote emitted for a given round */
107
- getLastVote(round: bigint): Promise<{
108
- validator: EthAddress;
109
- slashAmount: bigint;
110
- }[]>;
111
- /**
112
- * Listen for VoteCast events
113
- * @param callback - Callback function to handle vote cast events
114
- * @returns Unwatch function
115
- */
116
- listenToVoteCast(callback: (args: {
117
- round: bigint;
118
- proposer: string;
119
- }) => void): () => void;
120
- /**
121
- * Listen for RoundExecuted events
122
- * @param callback - Callback function to handle round executed events
123
- * @returns Unwatch function
124
- */
125
- listenToRoundExecuted(callback: (args: {
126
- round: bigint;
127
- slashCount: bigint;
128
- l1BlockHash: Hex;
129
- }) => void): () => void;
130
- }
131
- /**
132
- * Decodes a Buffer containing slash votes back into an array of numbers.
133
- * Each vote is represented as a 2-bit value (0, 1, 2, or 3) representing slashing units.
134
- * @dev This should live in stdlib next to encodeSlashConsensusVotes but is here since we
135
- * do not have a dependency to stdlib from the ethereum package. We need a larger refactor to fix this.
136
- * @param buffer - The Buffer containing encoded slash votes
137
- * @returns An array of numbers representing the slash votes
138
- */
139
- export declare function decodeSlashConsensusVotes(buffer: Buffer): number[];
140
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFsbHlfc2xhc2hpbmdfcHJvcG9zZXIuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb250cmFjdHMvdGFsbHlfc2xhc2hpbmdfcHJvcG9zZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDL0QsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFeEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzdELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFNM0QsT0FBTyxFQUVMLEtBQUssR0FBRyxFQUNSLEtBQUssR0FBRyxFQUNSLEtBQUssbUJBQW1CLEVBR3pCLE1BQU0sTUFBTSxDQUFDO0FBRWQ7OztHQUdHO0FBQ0gscUJBQWEsNkJBQTZCO2FBTXRCLE1BQU0sRUFBRSxVQUFVO0lBTHBDLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFxRTtJQUU5RixTQUFnQixJQUFJLFVBQW9CO0lBRXhDLFlBQ2tCLE1BQU0sRUFBRSxVQUFVLEVBQ2xDLE9BQU8sRUFBRSxHQUFHLEdBQUcsVUFBVSxFQU8xQjtJQUVELElBQVcsT0FBTyxlQUVqQjtJQUVNLGFBQWEsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLENBRXRDO0lBRU0sWUFBWSxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FFckM7SUFFTSxnQkFBZ0IsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLENBRXpDO0lBRU0sb0JBQW9CLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUU3QztJQUVNLG1CQUFtQixJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FFNUM7SUFFTSx5QkFBeUIsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLENB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
@@ -1 +0,0 @@
1
- {"version":3,"file":"tally_slashing_proposer.d.ts","sourceRoot":"","sources":["../../src/contracts/tally_slashing_proposer.ts"],"names":[],"mappings":"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"}
@@ -1,320 +0,0 @@
1
- import { mergeAbis, tryExtractEvent } from '@aztec/ethereum/utils';
2
- import { Buffer32 } from '@aztec/foundation/buffer';
3
- import { EthAddress } from '@aztec/foundation/eth-address';
4
- import { Signature } from '@aztec/foundation/eth-signature';
5
- import { hexToBuffer } from '@aztec/foundation/string';
6
- import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
7
- import { TallySlashingProposerAbi } from '@aztec/l1-artifacts/TallySlashingProposerAbi';
8
- import { encodeFunctionData, getContract } from 'viem';
9
- /**
10
- * Wrapper around the TallySlashingProposer contract that provides
11
- * a TypeScript interface for interacting with the consensus-based slashing system.
12
- */ export class TallySlashingProposerContract {
13
- client;
14
- contract;
15
- type;
16
- constructor(client, address){
17
- this.client = client;
18
- this.type = 'tally';
19
- this.contract = getContract({
20
- address: typeof address === 'string' ? address : address.toString(),
21
- abi: TallySlashingProposerAbi,
22
- client
23
- });
24
- }
25
- get address() {
26
- return EthAddress.fromString(this.contract.address);
27
- }
28
- getQuorumSize() {
29
- return this.contract.read.QUORUM();
30
- }
31
- getRoundSize() {
32
- return this.contract.read.ROUND_SIZE();
33
- }
34
- getCommitteeSize() {
35
- return this.contract.read.COMMITTEE_SIZE();
36
- }
37
- getRoundSizeInEpochs() {
38
- return this.contract.read.ROUND_SIZE_IN_EPOCHS();
39
- }
40
- getLifetimeInRounds() {
41
- return this.contract.read.LIFETIME_IN_ROUNDS();
42
- }
43
- getExecutionDelayInRounds() {
44
- return this.contract.read.EXECUTION_DELAY_IN_ROUNDS();
45
- }
46
- getSlashingAmounts() {
47
- return Promise.all([
48
- this.contract.read.SLASH_AMOUNT_SMALL(),
49
- this.contract.read.SLASH_AMOUNT_MEDIUM(),
50
- this.contract.read.SLASH_AMOUNT_LARGE()
51
- ]);
52
- }
53
- getSlashOffsetInRounds() {
54
- return this.contract.read.SLASH_OFFSET_IN_ROUNDS();
55
- }
56
- getCurrentRound() {
57
- return this.contract.read.getCurrentRound();
58
- }
59
- /**
60
- * Get round information
61
- * @param round - The round number to query
62
- * @returns Round status information
63
- */ async getRound(round) {
64
- const [isExecuted, voteCount] = await this.contract.read.getRound([
65
- round
66
- ]);
67
- return {
68
- isExecuted,
69
- voteCount
70
- };
71
- }
72
- /**
73
- * Check if a round is ready to execute at a given slot
74
- * @param round - The round number to check
75
- * @param slot - The slot number to check at
76
- * @returns Whether the round is ready to execute
77
- */ async isRoundReadyToExecute(round, slot) {
78
- return await this.contract.read.isRoundReadyToExecute([
79
- round,
80
- BigInt(slot)
81
- ]);
82
- }
83
- /** Returns the slash actions and payload address for a given round (zero if no slash actions) */ async getPayload(round) {
84
- const { result: committees } = await this.contract.simulate.getSlashTargetCommittees([
85
- round
86
- ]);
87
- const tally = await this.contract.read.getTally([
88
- round,
89
- committees
90
- ]);
91
- const address = await this.contract.read.getPayloadAddress([
92
- round,
93
- tally
94
- ]);
95
- const actions = this.mapSlashActions(tally);
96
- return {
97
- actions,
98
- address: EthAddress.fromString(address)
99
- };
100
- }
101
- /** Returns the slash actions to be executed for a given round based on votes */ async getTally(round) {
102
- const { result: committees } = await this.contract.simulate.getSlashTargetCommittees([
103
- round
104
- ]);
105
- const tally = await this.contract.read.getTally([
106
- round,
107
- committees
108
- ]);
109
- return {
110
- actions: this.mapSlashActions(tally),
111
- committees: committees.map((c)=>c.map(EthAddress.fromString))
112
- };
113
- }
114
- mapSlashActions(actions) {
115
- return actions.map(({ validator, slashAmount })=>({
116
- validator: EthAddress.fromString(validator),
117
- slashAmount
118
- }));
119
- }
120
- /** Tries to extract a VoteCast event from the given logs. */ tryExtractVoteCastEvent(logs) {
121
- return tryExtractEvent(logs, this.address.toString(), TallySlashingProposerAbi, 'VoteCast');
122
- }
123
- /** Tries to extract a RoundExecuted event from the given logs. */ tryExtractRoundExecutedEvent(logs) {
124
- return tryExtractEvent(logs, this.address.toString(), TallySlashingProposerAbi, 'RoundExecuted');
125
- }
126
- /**
127
- * Create a transaction to vote for slashing offenses
128
- * @param votes - The encoded votes for slashing
129
- * @param slot - The slot number for the vote
130
- * @param signer - The signer to produce the signature
131
- * @returns L1 transaction request
132
- */ async buildVoteRequestFromSigner(votes, slot, signer) {
133
- const typedData = this.buildVoteTypedData(votes, slot);
134
- const signature = Signature.fromString(await signer(typedData));
135
- return {
136
- to: this.contract.address,
137
- abi: TallySlashingProposerAbi,
138
- data: encodeFunctionData({
139
- abi: TallySlashingProposerAbi,
140
- functionName: 'vote',
141
- args: [
142
- votes,
143
- signature.toViemSignature()
144
- ]
145
- })
146
- };
147
- }
148
- /** Returns the typed data definition to EIP712-sign for voting */ buildVoteTypedData(votes, slot) {
149
- const domain = {
150
- name: 'TallySlashingProposer',
151
- version: '1',
152
- chainId: this.client.chain.id,
153
- verifyingContract: this.contract.address
154
- };
155
- const types = {
156
- EIP712Domain: [
157
- {
158
- name: 'name',
159
- type: 'string'
160
- },
161
- {
162
- name: 'version',
163
- type: 'string'
164
- },
165
- {
166
- name: 'chainId',
167
- type: 'uint256'
168
- },
169
- {
170
- name: 'verifyingContract',
171
- type: 'address'
172
- }
173
- ],
174
- Vote: [
175
- {
176
- name: 'votes',
177
- type: 'bytes'
178
- },
179
- {
180
- name: 'slot',
181
- type: 'uint256'
182
- }
183
- ]
184
- };
185
- return {
186
- domain,
187
- types,
188
- primaryType: 'Vote',
189
- message: {
190
- votes,
191
- slot: BigInt(slot)
192
- }
193
- };
194
- }
195
- /** Gets the digest to sign for voting directly from the contract */ async getVoteDataDigest(votes, slot) {
196
- return Buffer32.fromString(await this.contract.read.getVoteSignatureDigest([
197
- votes,
198
- BigInt(slot)
199
- ]));
200
- }
201
- /**
202
- * Create a transaction to vote for slashing offenses
203
- * @param votes - The encoded votes for slashing
204
- * @param signature - The signature from the current proposer
205
- * @returns L1 transaction request
206
- */ buildVoteRequestWithSignature(votes, signature) {
207
- return {
208
- to: this.contract.address,
209
- abi: TallySlashingProposerAbi,
210
- data: encodeFunctionData({
211
- abi: TallySlashingProposerAbi,
212
- functionName: 'vote',
213
- args: [
214
- votes,
215
- signature
216
- ]
217
- })
218
- };
219
- }
220
- /**
221
- * Create a transaction to execute a slashing round
222
- * @param round - The round number to execute
223
- * @param committees - The committees for each epoch in the round
224
- * @returns L1 transaction request
225
- */ buildExecuteRoundRequest(round, committees) {
226
- return {
227
- to: this.contract.address,
228
- abi: mergeAbis([
229
- TallySlashingProposerAbi,
230
- SlasherAbi
231
- ]),
232
- data: encodeFunctionData({
233
- abi: TallySlashingProposerAbi,
234
- functionName: 'executeRound',
235
- args: [
236
- round,
237
- committees.map((c)=>c.map((addr)=>addr.toString()))
238
- ]
239
- })
240
- };
241
- }
242
- /** Returns the last vote emitted for a given round */ async getLastVote(round) {
243
- const { voteCount } = await this.getRound(round);
244
- const validators = (await this.contract.simulate.getSlashTargetCommittees([
245
- round
246
- ])).result.flat();
247
- const vote = await this.contract.read.getVotes([
248
- round,
249
- voteCount - 1n
250
- ]);
251
- const decoded = decodeSlashConsensusVotes(hexToBuffer(vote));
252
- const slashAmounts = await this.getSlashingAmounts();
253
- return decoded.map((units, i)=>({
254
- validator: EthAddress.fromString(validators[i]),
255
- slashAmount: slashAmounts[units - 1] ?? 0n
256
- })).filter((v)=>v.slashAmount > 0n);
257
- }
258
- /**
259
- * Listen for VoteCast events
260
- * @param callback - Callback function to handle vote cast events
261
- * @returns Unwatch function
262
- */ listenToVoteCast(callback) {
263
- return this.contract.watchEvent.VoteCast({}, {
264
- onLogs: (logs)=>{
265
- for (const log of logs){
266
- const { round, proposer } = log.args;
267
- if (round !== undefined && proposer) {
268
- callback({
269
- round,
270
- proposer
271
- });
272
- }
273
- }
274
- }
275
- });
276
- }
277
- /**
278
- * Listen for RoundExecuted events
279
- * @param callback - Callback function to handle round executed events
280
- * @returns Unwatch function
281
- */ listenToRoundExecuted(callback) {
282
- return this.contract.watchEvent.RoundExecuted({}, {
283
- onLogs: (logs)=>{
284
- for (const log of logs){
285
- const { round, slashCount } = log.args;
286
- if (round !== undefined && slashCount !== undefined) {
287
- callback({
288
- round,
289
- slashCount,
290
- l1BlockHash: log.blockHash
291
- });
292
- }
293
- }
294
- }
295
- });
296
- }
297
- }
298
- /**
299
- * Decodes a Buffer containing slash votes back into an array of numbers.
300
- * Each vote is represented as a 2-bit value (0, 1, 2, or 3) representing slashing units.
301
- * @dev This should live in stdlib next to encodeSlashConsensusVotes but is here since we
302
- * do not have a dependency to stdlib from the ethereum package. We need a larger refactor to fix this.
303
- * @param buffer - The Buffer containing encoded slash votes
304
- * @returns An array of numbers representing the slash votes
305
- */ export function decodeSlashConsensusVotes(buffer) {
306
- const votes = [];
307
- for(let i = 0; i < buffer.length; i++){
308
- const voteByte = buffer.readUInt8(i);
309
- // Decode votes from Solidity's bit order (LSB to MSB)
310
- // Bits 0-1: validator at index i*4
311
- // Bits 2-3: validator at index i*4+1
312
- // Bits 4-5: validator at index i*4+2
313
- // Bits 6-7: validator at index i*4+3
314
- votes.push(voteByte >> 0 & 0x03);
315
- votes.push(voteByte >> 2 & 0x03);
316
- votes.push(voteByte >> 4 & 0x03);
317
- votes.push(voteByte >> 6 & 0x03);
318
- }
319
- return votes;
320
- }