Skip to content

Commit

Permalink
chore: avoid re-estimate gasPrice at estimateTxDependencies (#3461)
Browse files Browse the repository at this point in the history
  • Loading branch information
Torres-ssf authored Dec 9, 2024
1 parent 560664d commit 3a178b0
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/mean-sheep-occur.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/account": patch
---

chore: avoid re-estimate `gasPrice` at `estimateTxDependencies`
1 change: 1 addition & 0 deletions packages/account/src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ export class Account extends AbstractAccount {

const { maxFee } = await this.provider.estimateTxGasAndFee({
transactionRequest: requestToReestimate,
gasPrice,
});

request.maxFee = maxFee;
Expand Down
4 changes: 3 additions & 1 deletion packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,7 @@ Supported fuel-core version: ${supportedVersion}.`
} = await this.operations.dryRun({
encodedTransactions: [hexlify(transactionRequest.toTransactionBytes())],
utxoValidation: false,
gasPrice: '0',
});

receipts = rawReceipts.map(processGqlReceipt);
Expand All @@ -1032,6 +1033,7 @@ Supported fuel-core version: ${supportedVersion}.`

const { maxFee } = await this.estimateTxGasAndFee({
transactionRequest,
gasPrice: bn(0),
});

// eslint-disable-next-line no-param-reassign
Expand Down Expand Up @@ -1204,7 +1206,7 @@ Supported fuel-core version: ${supportedVersion}.`
const { gasPriceFactor, maxGasPerTx } = this.getGasConfig();

const minGas = transactionRequest.calculateMinGas(chainInfo);
if (!gasPrice) {
if (!isDefined(gasPrice)) {
gasPrice = await this.estimateGasPrice(10);
}

Expand Down
79 changes: 79 additions & 0 deletions packages/fuel-gauge/src/fee.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
InputMessageCoder,
ScriptTransactionRequest,
Wallet,
getMintedAssetId,
getRandomB256,
hexlify,
isCoin,
Expand Down Expand Up @@ -40,6 +41,8 @@ describe('Fee', () => {
}
};

const SUB_ID = '0x4a778acfad1abc155a009dc976d2cf0db6197d3d360194d74b1fb92b96986b00';

it('should ensure fee is properly calculated when minting and burning coins', async () => {
using launched = await launchTestNode({
contractsConfigs: [
Expand Down Expand Up @@ -431,5 +434,81 @@ describe('Fee', () => {

expect(cost.dryRunStatus?.type).toBe('DryRunSuccessStatus');
});

it('should not run estimateGasPrice in between estimateTxDependencies dry run attempts', async () => {
using launched = await launchTestNode({
contractsConfigs: [
{
factory: MultiTokenContractFactory,
},
],
});

const {
contracts: [contract],
wallets: [wallet],
provider,
} = launched;

const assetId = getMintedAssetId(contract.id.toB256(), SUB_ID);

// Minting coins first
const mintCall = await contract.functions.mint_coins(SUB_ID, 10_000).call();
await mintCall.waitForResult();

const estimateGasPrice = vi.spyOn(provider, 'estimateGasPrice');
const dryRun = vi.spyOn(provider.operations, 'dryRun');

/**
* Sway transfer without adding `OutputVariable` which will result in
* 2 dry runs at the `Provider.estimateTxDependencies` method:
* - 1st dry run will fail due to missing `OutputVariable`
* - 2nd dry run will succeed
*/
const transferCall = await contract.functions
.transfer_to_address({ bits: wallet.address.toB256() }, { bits: assetId }, 10_000)
.call();

await transferCall.waitForResult();

expect(estimateGasPrice).toHaveBeenCalledOnce();
expect(dryRun).toHaveBeenCalledTimes(2);
});

it('should ensure estimateGasPrice runs only once when funding a transaction.', async () => {
const amountPerCoin = 100;

using launched = await launchTestNode({
walletsConfig: {
amountPerCoin, // Funding with multiple UTXOs so the fee will change after funding the TX.
coinsPerAsset: 250,
},
contractsConfigs: [
{
factory: MultiTokenContractFactory,
},
],
});

const {
wallets: [wallet],
provider,
} = launched;

const fund = vi.spyOn(wallet, 'fund');
const estimateGasPrice = vi.spyOn(provider, 'estimateGasPrice');

const tx = await wallet.transfer(
wallet.address,
amountPerCoin * 20,
provider.getBaseAssetId()
);
const { isStatusSuccess } = await tx.waitForResult();

expect(fund).toHaveBeenCalledOnce();
expect(estimateGasPrice).toHaveBeenCalledOnce();

expect(isStatusSuccess).toBeTruthy();
});
});
});

0 comments on commit 3a178b0

Please sign in to comment.