Skip to content

Commit 45e4215

Browse files
committed
fix: stabilize e2e_bot test fees and fix L1 nonce races (backport #20962 #20992 #21148)
BEGIN_COMMIT_OVERRIDE fix: set wallet minFeePadding in BotFactory constructor (#20992) fix: increase minFeePadding in e2e_bot bridge resume tests and harden GasFees.mul() (#20962) fix: use dedicated L1 account for bot bridge resume tests to avoid nonce race (#21148) fix: remove stale fee snapshot from BotFactory account deployment END_COMMIT_OVERRIDE Backports three fixes from next and adds a fourth: 1. BotFactory constructor now calls wallet.setMinFeePadding() so all setup transactions (token deploy, minting) use the configured padding instead of the wallet default (0.5x). (#20992) 2. GasFees.mul() uses bigint arithmetic for integer scalars to avoid precision loss, and Math.ceil for non-integer scalars. (#20962) 3. Bridge resume tests use a dedicated L1 private key (index 7) instead of the default mnemonic shared with the sequencer, avoiding nonce races on approve/deposit calls. (#21148) 4. Remove explicit maxFeesPerGas snapshot from setupAccountWithPrivateKey. Let the wallet re-estimate fees at send() time via completeFeeOptions(), making the fee estimate fresh and 10x padding sufficient.
1 parent 7d4cfcd commit 45e4215

3 files changed

Lines changed: 26 additions & 14 deletions

File tree

yarn-project/bot/src/factory.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken';
2727
import { TokenContract } from '@aztec/noir-contracts.js/Token';
2828
import { TestContract } from '@aztec/noir-test-contracts.js/Test';
2929
import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
30-
import { GasSettings } from '@aztec/stdlib/gas';
3130
import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
3231
import { deriveSigningKey } from '@aztec/stdlib/keys';
3332
import { EmbeddedWallet } from '@aztec/wallets/embedded';
@@ -49,7 +48,11 @@ export class BotFactory {
4948
private readonly store: BotStore,
5049
private readonly aztecNode: AztecNode,
5150
private readonly aztecNodeAdmin?: AztecNodeAdmin,
52-
) {}
51+
) {
52+
// Set fee padding on the wallet so that all transactions during setup
53+
// (token deploy, minting, etc.) use the configured padding, not the default.
54+
this.wallet.setMinFeePadding(config.minFeePadding);
55+
}
5356

5457
/**
5558
* Initializes a new bot by setting up the sender account, registering the recipient,
@@ -218,13 +221,11 @@ export class BotFactory {
218221

219222
const paymentMethod = new FeeJuicePaymentMethodWithClaim(accountManager.address, claim);
220223
const deployMethod = await accountManager.getDeployMethod();
221-
const maxFeesPerGas = (await this.aztecNode.getCurrentMinFees()).mul(1 + this.config.minFeePadding);
222-
const gasSettings = GasSettings.default({ maxFeesPerGas });
223224

224225
await this.withNoMinTxsPerBlock(async () => {
225226
const { txHash } = await deployMethod.send({
226227
from: AztecAddress.ZERO,
227-
fee: { gasSettings, paymentMethod },
228+
fee: { paymentMethod },
228229
wait: NO_WAIT,
229230
});
230231
this.log.info(`Sent tx for account deployment with hash ${txHash.toString()}`);

yarn-project/end-to-end/src/e2e_bot.test.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ describe('e2e_bot', () => {
5252

5353
afterAll(() => teardown());
5454

55+
let privateKeyIndex = 10;
56+
const getPrivateKey = () => new SecretValue(bufferToHex(getPrivateKeyFromIndex(privateKeyIndex++)!));
57+
5558
describe('transaction-bot', () => {
5659
let bot: Bot;
5760
beforeAll(async () => {
@@ -131,10 +134,12 @@ describe('e2e_bot', () => {
131134

132135
l1RpcUrls,
133136
feePaymentMethod: 'fee_juice',
134-
// TODO: this should be taken from the `setup` call above
135-
l1Mnemonic: new SecretValue('test test test test test test test test test test test junk'),
137+
// Use a dedicated L1 account (index 7) for bridging. The default mnemonic account (index 0)
138+
// is shared with the sequencer which sends L1 block proposals, causing nonce races on the
139+
// approve/deposit calls in bridgeL1FeeJuice.
140+
l1PrivateKey: new SecretValue(bufferToHex(getPrivateKeyFromIndex(7)!)),
136141
flushSetupTransactions: true,
137-
// Increase fee headroom to handle fee volatility from rapid block building in tests
142+
// Fee headroom to handle fee volatility from rapid block building in tests.
138143
minFeePadding: 9,
139144
};
140145

@@ -171,10 +176,10 @@ describe('e2e_bot', () => {
171176

172177
l1RpcUrls,
173178
feePaymentMethod: 'fee_juice',
174-
// TODO: this should be taken from the `setup` call above
175-
l1Mnemonic: new SecretValue('test test test test test test test test test test test junk'),
179+
// Dedicated L1 account to avoid nonce races with the sequencer.
180+
l1PrivateKey: new SecretValue(bufferToHex(getPrivateKeyFromIndex(7)!)),
176181
flushSetupTransactions: true,
177-
// Increase fee headroom to handle fee volatility from rapid block building in tests
182+
// Fee headroom to handle fee volatility from rapid block building in tests.
178183
minFeePadding: 9,
179184
};
180185

@@ -235,7 +240,7 @@ describe('e2e_bot', () => {
235240
followChain: 'PROPOSED',
236241
botMode: 'transfer',
237242
senderPrivateKey: new SecretValue(Fr.random()),
238-
l1PrivateKey: new SecretValue(bufferToHex(getPrivateKeyFromIndex(8)!)),
243+
l1PrivateKey: getPrivateKey(),
239244
l1RpcUrls,
240245
flushSetupTransactions: true,
241246
};
@@ -258,7 +263,7 @@ describe('e2e_bot', () => {
258263
followChain: 'PROPOSED',
259264
botMode: 'crosschain',
260265
l1RpcUrls,
261-
l1PrivateKey: new SecretValue(bufferToHex(getPrivateKeyFromIndex(9)!)),
266+
l1PrivateKey: getPrivateKey(),
262267
flushSetupTransactions: true,
263268
l1ToL2SeedCount: 2,
264269
};

yarn-project/stdlib/src/gas/gas_fees.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,14 @@ export class GasFees {
5656
return this.clone();
5757
} else if (typeof scalar === 'bigint') {
5858
return new GasFees(this.feePerDaGas * scalar, this.feePerL2Gas * scalar);
59+
} else if (Number.isInteger(scalar)) {
60+
const s = BigInt(scalar);
61+
return new GasFees(this.feePerDaGas * s, this.feePerL2Gas * s);
5962
} else {
60-
return new GasFees(Number(this.feePerDaGas) * scalar, Number(this.feePerL2Gas) * scalar);
63+
return new GasFees(
64+
BigInt(Math.ceil(Number(this.feePerDaGas) * scalar)),
65+
BigInt(Math.ceil(Number(this.feePerL2Gas) * scalar)),
66+
);
6167
}
6268
}
6369

0 commit comments

Comments
 (0)