Skip to content

Commit

Permalink
feat: using gas modifier at Provider.getTransactionCost (#3319)
Browse files Browse the repository at this point in the history
* using a gas used modifier

* refact code

* add test case

* add changeset

* update tests

* adjusting test

* adjust test

* add new BN helper

* validate max gas per tx

* fix changeset

* using modifier of 20%

* update test name

---------

Co-authored-by: Anderson Arboleya <[email protected]>
  • Loading branch information
Torres-ssf and arboleya authored Oct 14, 2024
1 parent eb3b6c9 commit 987aed3
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 6 deletions.
6 changes: 6 additions & 0 deletions .changeset/yellow-toes-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fuel-ts/account": patch
"@fuel-ts/math": patch
---

feat: using gas modifier at `Provider.getTransactionCost`
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('Script With Configurable', () => {
const tx = script.functions.main(argument);

// Set the call parameters
tx.callParams({ gasLimit: 1500 });
tx.callParams({ gasLimit: 1700 });

// Get the entire transaction request prior to
const txRequest = await tx.getTransactionRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const { contract } = await deploy.waitForResult();
// #region transaction-parameters-6
const txParams: TxParams = {
// #region transaction-parameters-1
gasLimit: bn(69242),
gasLimit: bn(70935),
// #endregion transaction-parameters-1
// #region transaction-parameters-2
maxFee: bn(69242),
Expand Down
22 changes: 22 additions & 0 deletions packages/account/src/providers/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import type { ChainInfo, CursorPaginationArgs, NodeInfo } from './provider';
import Provider, {
BLOCKS_PAGE_SIZE_LIMIT,
DEFAULT_RESOURCE_CACHE_TTL,
GAS_USED_MODIFIER,
RESOURCES_PAGE_SIZE_LIMIT,
} from './provider';
import type { ExcludeResourcesOption } from './resource';
Expand Down Expand Up @@ -1374,6 +1375,27 @@ Supported fuel-core version: ${mock.supportedVersion}.`
expect(minFee.eq(0)).not.toBeTruthy();
});

it('should ensure gas used has a modifier', async () => {
using launched = await setupTestProviderAndWallets();

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

const request = new ScriptTransactionRequest();
request.addCoinOutput(wallet.address, 1000, provider.getBaseAssetId());

const spyGetGasUsedFromReceipts = vi.spyOn(gasMod, 'getGasUsedFromReceipts');
const cost = await wallet.getTransactionCost(request);

const pristineGasUsed = spyGetGasUsedFromReceipts.mock.results[0].value;

expect(cost.gasUsed.toNumber()).toBe(
bn(pristineGasUsed.toNumber() * GAS_USED_MODIFIER).toNumber()
);
});

it('should accept string addresses in methods that require an address', async () => {
using launched = await setupTestProviderAndWallets();
const { provider } = launched;
Expand Down
6 changes: 5 additions & 1 deletion packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const RESOURCES_PAGE_SIZE_LIMIT = 512;
export const TRANSACTIONS_PAGE_SIZE_LIMIT = 60;
export const BLOCKS_PAGE_SIZE_LIMIT = 5;
export const DEFAULT_RESOURCE_CACHE_TTL = 20_000; // 20 seconds
export const GAS_USED_MODIFIER = 1.2;

export type DryRunFailureStatusFragment = GqlDryRunFailureStatusFragment;
export type DryRunSuccessStatusFragment = GqlDryRunSuccessStatusFragment;
Expand Down Expand Up @@ -1319,7 +1320,10 @@ Supported fuel-core version: ${supportedVersion}.`
throw this.extractDryRunError(txRequestClone, receipts, dryRunStatus);
}

gasUsed = getGasUsedFromReceipts(receipts);
const { maxGasPerTx } = this.getGasConfig();

const pristineGasUsed = getGasUsedFromReceipts(receipts);
gasUsed = bn(pristineGasUsed.muln(GAS_USED_MODIFIER)).max(maxGasPerTx.sub(minGas));
txRequestClone.gasLimit = gasUsed;

({ maxFee, maxGas, minFee, minGas, gasPrice } = await this.estimateTxGasAndFee({
Expand Down
10 changes: 7 additions & 3 deletions packages/fuel-gauge/src/min-gas.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getGasUsedFromReceipts,
BigNumberCoder,
ContractFactory,
GAS_USED_MODIFIER,
} from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

Expand Down Expand Up @@ -103,7 +104,8 @@ describe('Minimum gas tests', () => {
const { status, gasUsed: txGasUsed } = await result.wait();

expect(status).toBe(TransactionStatus.success);
expect(txCost.gasUsed.toString()).toBe(txGasUsed.toString());
// Final gas is less then the estimated in a normal scenario
expect(txCost.gasUsed.toNumber()).toBe(txGasUsed.muln(GAS_USED_MODIFIER).toNumber());
});

it('sets gas requirements (predicate)', async () => {
Expand Down Expand Up @@ -152,7 +154,8 @@ describe('Minimum gas tests', () => {
const gasUsedFromReceipts = getGasUsedFromReceipts(receipts);

expect(status).toBe(TransactionStatus.success);
expect(txCost.gasUsed.toString()).toBe(gasUsedFromReceipts.toString());
// Final gas is less then the estimated in a normal scenario
expect(txCost.gasUsed.toNumber()).toBe(gasUsedFromReceipts.muln(GAS_USED_MODIFIER).toNumber());
});

it('sets gas requirements (account and predicate with script)', async () => {
Expand Down Expand Up @@ -221,6 +224,7 @@ describe('Minimum gas tests', () => {
const txGasUsed = getGasUsedFromReceipts(receipts);

expect(status).toBe(TransactionStatus.success);
expect(txCost.gasUsed.toString()).toBe(txGasUsed.toString());
// Final gas is less then the estimated in a normal scenario
expect(txCost.gasUsed.toNumber()).toBe(txGasUsed.muln(GAS_USED_MODIFIER).toNumber());
});
});
14 changes: 14 additions & 0 deletions packages/math/src/bn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,20 @@ describe('Math - BN', () => {
expect(() => bn(over).toBytes(4)).toThrow();
});

it('should ensure max method works just like expected', () => {
// Using Number
const maxNumber = 100_000;
const exceedingNumber = maxNumber + 1;

let maxSafeNumber = bn(exceedingNumber).max(maxNumber);

expect(maxSafeNumber.toNumber()).toEqual(maxNumber);

// Using BN
maxSafeNumber = bn(maxNumber).add(1).max(bn(maxNumber));
expect(maxSafeNumber.toNumber()).toEqual(maxNumber);
});

it('should toHex break when value provided is bigger than bytePadding config', () => {
let maxBytes: Uint8Array;
let maxHex: string;
Expand Down
4 changes: 4 additions & 0 deletions packages/math/src/bn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ export class BN extends BnJs implements BNInputOverrides, BNHiddenTypes, BNHelpe
return this.gte(this.MAX_U64) ? new BN(this.MAX_U64) : this;
}

max(num: BNInput): BN {
return this.gte(num) ? new BN(num) : this;
}

normalizeZeroToOne(): BN {
return this.isZero() ? new BN(1) : this;
}
Expand Down

0 comments on commit 987aed3

Please sign in to comment.