@aztec/ethereum 3.0.0-nightly.20250908 → 3.0.0-nightly.20250911

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -706,12 +706,14 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
706
706
  * Monitors a transaction until completion, handling speed-ups if needed
707
707
  * @param request - Original transaction request (needed for speed-ups)
708
708
  * @param initialTxHash - Hash of the initial transaction
709
+ * @param allVersions - Hashes of all transactions submitted under the same nonce (any of them could mine)
709
710
  * @param params - Parameters used in the initial transaction
710
711
  * @param gasConfig - Optional gas configuration
711
712
  */
712
713
  public async monitorTransaction(
713
714
  request: L1TxRequest,
714
715
  initialTxHash: Hex,
716
+ allVersions: Set<Hex>,
715
717
  params: { gasLimit: bigint },
716
718
  _gasConfig?: Partial<L1TxUtilsConfig> & { txTimeoutAt?: Date },
717
719
  _blobInputs?: L1BlobInputs,
@@ -743,7 +745,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
743
745
  }
744
746
  const nonce = tx.nonce;
745
747
 
746
- const txHashes = new Set<Hex>([initialTxHash]);
748
+ allVersions.add(initialTxHash);
747
749
  let currentTxHash = initialTxHash;
748
750
  let attempts = 0;
749
751
  let lastAttemptSent = this.dateProvider.now();
@@ -776,8 +778,9 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
776
778
  }));
777
779
 
778
780
  const currentNonce = await this.client.getTransactionCount({ address: account });
781
+ // If the current nonce on our account is greater than our transaction's nonce then a tx with the same nonce has been mined.
779
782
  if (currentNonce > nonce) {
780
- for (const hash of txHashes) {
783
+ for (const hash of allVersions) {
781
784
  try {
782
785
  const receipt = await this.client.getTransactionReceipt({ hash });
783
786
  if (receipt) {
@@ -796,6 +799,10 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
796
799
  }
797
800
  }
798
801
  }
802
+ // If we get here then we have checked all of our tx versions and not found anything.
803
+ // We should consider the nonce as MINED
804
+ this.state = TxUtilsState.MINED;
805
+ throw new Error(`Nonce ${nonce} is MINED but not by one of our expected transactions`);
799
806
  }
800
807
 
801
808
  this.logger?.trace(`Tx timeout check for ${currentTxHash}: ${isTimedOut()}`, {
@@ -882,7 +889,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
882
889
 
883
890
  currentTxHash = newHash;
884
891
 
885
- txHashes.add(currentTxHash);
892
+ allVersions.add(currentTxHash);
886
893
  lastAttemptSent = this.dateProvider.now();
887
894
  }
888
895
  await sleep(gasConfig.checkIntervalMs!);
@@ -904,7 +911,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
904
911
  this.state = TxUtilsState.NOT_MINED;
905
912
  } else if (gasConfig.cancelTxOnTimeout) {
906
913
  // Fire cancellation without awaiting to avoid blocking the main thread
907
- this.attemptTxCancellation(currentTxHash, nonce, isBlobTx, lastGasPrice, attempts).catch(err => {
914
+ this.attemptTxCancellation(currentTxHash, nonce, allVersions, isBlobTx, lastGasPrice, attempts).catch(err => {
908
915
  const viemError = formatViemError(err);
909
916
  this.logger?.error(`Failed to send cancellation for timed out tx ${currentTxHash}:`, viemError.message, {
910
917
  metaMessages: viemError.metaMessages,
@@ -938,7 +945,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
938
945
  blobInputs?: L1BlobInputs,
939
946
  ): Promise<{ receipt: TransactionReceipt; gasPrice: GasPrice }> {
940
947
  const { txHash, gasLimit, gasPrice } = await this.sendTransaction(request, gasConfig, blobInputs);
941
- const receipt = await this.monitorTransaction(request, txHash, { gasLimit }, gasConfig, blobInputs);
948
+ const receipt = await this.monitorTransaction(request, txHash, new Set(), { gasLimit }, gasConfig, blobInputs);
942
949
  return { receipt, gasPrice };
943
950
  }
944
951
 
@@ -973,6 +980,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
973
980
  /**
974
981
  * Attempts to cancel a transaction by sending a 0-value tx to self with same nonce but higher gas prices
975
982
  * @param nonce - The nonce of the transaction to cancel
983
+ * @param allVersions - Hashes of all transactions submitted under the same nonce (any of them could mine)
976
984
  * @param previousGasPrice - The gas price of the previous transaction
977
985
  * @param attempts - The number of attempts to cancel the transaction
978
986
  * @returns The hash of the cancellation transaction
@@ -980,6 +988,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
980
988
  protected async attemptTxCancellation(
981
989
  currentTxHash: Hex,
982
990
  nonce: number,
991
+ allVersions: Set<Hex>,
983
992
  isBlobTx = false,
984
993
  previousGasPrice?: GasPrice,
985
994
  attempts = 0,
@@ -1000,7 +1009,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
1000
1009
  previousGasPrice,
1001
1010
  );
1002
1011
 
1003
- this.logger?.debug(`Attempting to cancel L1 transaction ${currentTxHash} with nonce ${nonce}`, {
1012
+ this.logger?.info(`Attempting to cancel L1 transaction ${currentTxHash} with nonce ${nonce}`, {
1004
1013
  maxFeePerGas: formatGwei(cancelGasPrice.maxFeePerGas),
1005
1014
  maxPriorityFeePerGas: formatGwei(cancelGasPrice.maxPriorityFeePerGas),
1006
1015
  });
@@ -1022,11 +1031,12 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
1022
1031
 
1023
1032
  this.state = TxUtilsState.CANCELLED;
1024
1033
 
1025
- this.logger?.debug(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`, { nonce });
1034
+ this.logger?.info(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`, { nonce });
1026
1035
 
1027
1036
  const receipt = await this.monitorTransaction(
1028
1037
  request,
1029
1038
  cancelTxHash,
1039
+ allVersions,
1030
1040
  { gasLimit: 21_000n },
1031
1041
  undefined,
1032
1042
  undefined,
@@ -19,6 +19,7 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
19
19
  /**
20
20
  * Attempts to cancel a transaction by sending a 0-value tx to self with same nonce but higher gas prices
21
21
  * @param nonce - The nonce of the transaction to cancel
22
+ * @param allVersions - Hashes of all transactions submitted under the same nonce (any of them could mine)
22
23
  * @param previousGasPrice - The gas price of the previous transaction
23
24
  * @param attempts - The number of attempts to cancel the transaction
24
25
  * @returns The hash of the cancellation transaction
@@ -26,6 +27,7 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
26
27
  override async attemptTxCancellation(
27
28
  currentTxHash: Hex,
28
29
  nonce: number,
30
+ allVersions: Set<Hex>,
29
31
  isBlobTx = false,
30
32
  previousGasPrice?: GasPrice,
31
33
  attempts = 0,
@@ -42,7 +44,7 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
42
44
  previousGasPrice,
43
45
  );
44
46
 
45
- this.logger?.debug(`Attempting to cancel blob L1 transaction ${currentTxHash} with nonce ${nonce}`, {
47
+ this.logger?.info(`Attempting to cancel blob L1 transaction ${currentTxHash} with nonce ${nonce}`, {
46
48
  maxFeePerGas: formatGwei(cancelGasPrice.maxFeePerGas),
47
49
  maxPriorityFeePerGas: formatGwei(cancelGasPrice.maxPriorityFeePerGas),
48
50
  maxFeePerBlobGas:
@@ -65,9 +67,12 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
65
67
  const signedRequest = await this.prepareSignedTransaction(txData);
66
68
  const cancelTxHash = await this.client.sendRawTransaction({ serializedTransaction: signedRequest });
67
69
 
70
+ this.logger?.info(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`);
71
+
68
72
  const receipt = await this.monitorTransaction(
69
73
  request,
70
74
  cancelTxHash,
75
+ allVersions,
71
76
  { gasLimit: 21_000n },
72
77
  undefined,
73
78
  undefined,
@@ -94,11 +99,12 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
94
99
  const signedRequest = await this.prepareSignedTransaction(txData);
95
100
  const cancelTxHash = await this.client.sendRawTransaction({ serializedTransaction: signedRequest });
96
101
 
97
- this.logger?.debug(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`);
102
+ this.logger?.info(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`);
98
103
 
99
104
  const receipt = await this.monitorTransaction(
100
105
  request,
101
106
  cancelTxHash,
107
+ allVersions,
102
108
  { gasLimit: 21_000n },
103
109
  undefined,
104
110
  blobInputs,
package/src/queries.ts CHANGED
@@ -1,7 +1,4 @@
1
1
  import { EthAddress } from '@aztec/foundation/eth-address';
2
- import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
3
-
4
- import { getContract } from 'viem';
5
2
 
6
3
  import type { L1ContractsConfig } from './config.js';
7
4
  import { ReadOnlyGovernanceContract } from './contracts/governance.js';
@@ -27,8 +24,7 @@ export async function getL1ContractsConfig(
27
24
  const rollupAddress = addresses.rollupAddress ?? (await governanceProposer.getRollupAddress());
28
25
  const rollup = new RollupContract(publicClient, rollupAddress.toString());
29
26
  const slasherProposer = await rollup.getSlashingProposer();
30
- const slasherAddress = await rollup.getSlasher();
31
- const slasher = getContract({ address: slasherAddress, abi: SlasherAbi, client: publicClient });
27
+ const slasher = await rollup.getSlasherContract();
32
28
 
33
29
  const [
34
30
  l1StartBlock,
@@ -39,6 +35,7 @@ export async function getL1ContractsConfig(
39
35
  aztecTargetCommitteeSize,
40
36
  activationThreshold,
41
37
  ejectionThreshold,
38
+ localEjectionThreshold,
42
39
  governanceProposerQuorum,
43
40
  governanceProposerRoundSize,
44
41
  slashingQuorum,
@@ -62,6 +59,7 @@ export async function getL1ContractsConfig(
62
59
  rollup.getTargetCommitteeSize(),
63
60
  rollup.getActivationThreshold(),
64
61
  rollup.getEjectionThreshold(),
62
+ rollup.getLocalEjectionThreshold(),
65
63
  governanceProposer.getQuorumSize(),
66
64
  governanceProposer.getRoundSize(),
67
65
  slasherProposer?.getQuorumSize() ?? 0n,
@@ -70,7 +68,7 @@ export async function getL1ContractsConfig(
70
68
  slasherProposer?.getExecutionDelayInRounds() ?? 0n,
71
69
  slasherProposer?.type === 'tally' ? slasherProposer.getSlashOffsetInRounds() : 0n,
72
70
  slasherProposer?.type === 'tally' ? slasherProposer.getSlashingAmounts() : [0n, 0n, 0n],
73
- slasher.read.VETOER(),
71
+ slasher?.getVetoer() ?? EthAddress.ZERO,
74
72
  rollup.getManaTarget(),
75
73
  rollup.getProvingCostPerMana(),
76
74
  rollup.getVersion(),
@@ -89,11 +87,12 @@ export async function getL1ContractsConfig(
89
87
  governanceProposerRoundSize: Number(governanceProposerRoundSize),
90
88
  activationThreshold,
91
89
  ejectionThreshold,
90
+ localEjectionThreshold,
92
91
  slashingQuorum: Number(slashingQuorum),
93
92
  slashingRoundSizeInEpochs: Number(slashingRoundSize / aztecEpochDuration),
94
93
  slashingLifetimeInRounds: Number(slashingLifetimeInRounds),
95
94
  slashingExecutionDelayInRounds: Number(slashingExecutionDelayInRounds),
96
- slashingVetoer: EthAddress.fromString(slashingVetoer),
95
+ slashingVetoer,
97
96
  manaTarget: manaTarget,
98
97
  provingCostPerMana: provingCostPerMana,
99
98
  rollupVersion: Number(rollupVersion),