Skip to content

Commit

Permalink
chore: handle exceeding maximum inputs when funding a transaction (#2822
Browse files Browse the repository at this point in the history
)

* add check

* refactoring

* move if

* allocate method in other place

* add test

* remove .only

* remove console.log

* add error docs

* Update .changeset/honest-fishes-mix.md

Co-authored-by: Peter Smith <[email protected]>

---------

Co-authored-by: Peter Smith <[email protected]>
  • Loading branch information
mvares and petertonysmith94 authored Aug 7, 2024
1 parent 896add9 commit 0110fd8
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .changeset/honest-fishes-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fuel-ts/account": patch
"@fuel-ts/errors": patch
---

chore: handle exceeding maximum inputs when funding a transaction
4 changes: 4 additions & 0 deletions apps/docs/src/guide/errors/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,7 @@ The purpose of the lock function is to provide a way to ensure that the implemen
In cases where the error hasn't been mapped yet, this code will be used.

If you believe you found a bug, please report the [issue](https://github.com/FuelLabs/fuels-ts/issues/new/choose) to the team.

### `MAX_INPUTS_EXCEEDED`

When the number of transaction inputs exceeds the maximum limit allowed by the blockchain.
58 changes: 56 additions & 2 deletions packages/account/src/providers/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { BN, bn } from '@fuel-ts/math';
import type { Receipt } from '@fuel-ts/transactions';
import { InputType, ReceiptType, TransactionType } from '@fuel-ts/transactions';
import { DateTime, arrayify, sleep } from '@fuel-ts/utils';
import { ASSET_A } from '@fuel-ts/utils/test-utils';
import { ASSET_A, ASSET_B } from '@fuel-ts/utils/test-utils';
import { versions } from '@fuel-ts/versions';
import * as fuelTsVersionsMod from '@fuel-ts/versions';

Expand All @@ -26,14 +26,15 @@ import {
import { Wallet } from '../wallet';

import type { Coin } from './coin';
import { coinQuantityfy } from './coin-quantity';
import type { ChainInfo, CursorPaginationArgs, NodeInfo } from './provider';
import Provider, {
BLOCKS_PAGE_SIZE_LIMIT,
DEFAULT_UTXOS_CACHE_TTL,
RESOURCES_PAGE_SIZE_LIMIT,
} from './provider';
import type { CoinTransactionRequestInput } from './transaction-request';
import { ScriptTransactionRequest, CreateTransactionRequest } from './transaction-request';
import { CreateTransactionRequest, ScriptTransactionRequest } from './transaction-request';
import { TransactionResponse } from './transaction-response';
import type { SubmittedStatus } from './transaction-summary/types';
import * as gasMod from './utils/gas';
Expand Down Expand Up @@ -541,6 +542,59 @@ describe('Provider', () => {
});
});

it('should throws if max of inputs was exceeded', async () => {
const maxInputs = 2;
using launched = await setupTestProviderAndWallets({
nodeOptions: {
snapshotConfig: {
chainConfig: {
consensus_parameters: {
V1: {
tx_params: {
V1: {
max_inputs: maxInputs,
},
},
},
},
},
},
},
walletsConfig: {
amountPerCoin: 500_000,
},
});

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

const request = new ScriptTransactionRequest();

const quantities = [coinQuantityfy([1000, ASSET_A]), coinQuantityfy([500, ASSET_B])];
const resources = await sender.getResourcesToSpend(quantities);

request.addCoinOutput(receiver.address, 500, provider.getBaseAssetId());

const txCost = await sender.getTransactionCost(request);

request.gasLimit = txCost.gasUsed;
request.maxFee = txCost.maxFee;

request.addResources(resources);

await sender.fund(request, txCost);

await expectToThrowFuelError(
() => sender.sendTransaction(request),
new FuelError(
ErrorCode.MAX_INPUTS_EXCEEDED,
'The transaction exceeds the maximum allowed number of inputs for funding.'
)
);
});

it('can getBlocks', async () => {
using launched = await setupTestProviderAndWallets();
const blocksLenght = 5;
Expand Down
13 changes: 13 additions & 0 deletions packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,15 @@ Supported fuel-core version: ${supportedVersion}.`
});
}

private validateTransaction(tx: TransactionRequest, consensusParameters: ConsensusParameters) {
if (bn(tx.inputs.length).gt(consensusParameters.txParameters.maxInputs)) {
throw new FuelError(
ErrorCode.MAX_INPUTS_EXCEEDED,
'The transaction exceeds the maximum allowed number of inputs for funding.'
);
}
}

/**
* Submits a transaction to the chain to be executed.
*
Expand All @@ -716,6 +725,10 @@ Supported fuel-core version: ${supportedVersion}.`
}
// #endregion Provider-sendTransaction

const { consensusParameters } = this.getChain();

this.validateTransaction(transactionRequest, consensusParameters);

const encodedTransaction = hexlify(transactionRequest.toTransactionBytes());

let abis: JsonAbisFromAllCalls | undefined;
Expand Down
1 change: 1 addition & 0 deletions packages/errors/src/error-codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export enum ErrorCode {
DUPLICATED_POLICY = 'duplicated-policy',
TRANSACTION_SQUEEZED_OUT = 'transaction-squeezed-out',
CONTRACT_SIZE_EXCEEDS_LIMIT = 'contract-size-exceeds-limit',
MAX_INPUTS_EXCEEDED = 'max-inputs-exceeded',

// receipt
INVALID_RECEIPT_TYPE = 'invalid-receipt-type',
Expand Down

0 comments on commit 0110fd8

Please sign in to comment.