Skip to content

Commit

Permalink
chore!: limit TX pagination number for getTransactionsSummaries (#3400
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Torres-ssf authored Nov 15, 2024
1 parent bdf0ebe commit efdc721
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 53 deletions.
5 changes: 5 additions & 0 deletions .changeset/odd-bears-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/account": minor
---

chore!: limit TX pagination number for `getTransactionsSummaries`
55 changes: 5 additions & 50 deletions packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import {
import type { RetryOptions } from './utils/auto-retry-fetch';
import { autoRetryFetch } from './utils/auto-retry-fetch';
import { handleGqlErrorMessage } from './utils/handle-gql-error-message';
import { validatePaginationArgs } from './utils/validate-pagination-args';

const MAX_RETRIES = 10;

Expand Down Expand Up @@ -1407,7 +1408,7 @@ Supported fuel-core version: ${supportedVersion}.`
const {
coins: { edges, pageInfo },
} = await this.operations.getCoins({
...this.validatePaginationArgs({
...validatePaginationArgs({
paginationLimit: RESOURCES_PAGE_SIZE_LIMIT,
inputArgs: paginationArgs,
}),
Expand Down Expand Up @@ -1575,7 +1576,7 @@ Supported fuel-core version: ${supportedVersion}.`
const {
blocks: { edges, pageInfo },
} = await this.operations.getBlocks({
...this.validatePaginationArgs({
...validatePaginationArgs({
paginationLimit: BLOCKS_PAGE_SIZE_LIMIT,
inputArgs: params,
}),
Expand Down Expand Up @@ -1686,7 +1687,7 @@ Supported fuel-core version: ${supportedVersion}.`
const {
transactions: { edges, pageInfo },
} = await this.operations.getTransactions({
...this.validatePaginationArgs({
...validatePaginationArgs({
inputArgs: paginationArgs,
paginationLimit: TRANSACTIONS_PAGE_SIZE_LIMIT,
}),
Expand Down Expand Up @@ -1806,7 +1807,7 @@ Supported fuel-core version: ${supportedVersion}.`
const {
messages: { edges, pageInfo },
} = await this.operations.getMessages({
...this.validatePaginationArgs({
...validatePaginationArgs({
inputArgs: paginationArgs,
paginationLimit: RESOURCES_PAGE_SIZE_LIMIT,
}),
Expand Down Expand Up @@ -2103,52 +2104,6 @@ Supported fuel-core version: ${supportedVersion}.`
return relayedTransactionStatus;
}

/**
* @hidden
*/
private validatePaginationArgs(params: {
inputArgs?: CursorPaginationArgs;
paginationLimit: number;
}): CursorPaginationArgs {
const { paginationLimit, inputArgs = {} } = params;
const { first, last, after, before } = inputArgs;

if (after && before) {
throw new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
'Pagination arguments "after" and "before" cannot be used together'
);
}

if ((first || 0) > paginationLimit || (last || 0) > paginationLimit) {
throw new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
`Pagination limit for this query cannot exceed ${paginationLimit} items`
);
}

if (first && before) {
throw new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
'The use of pagination argument "first" with "before" is not supported'
);
}

if (last && after) {
throw new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
'The use of pagination argument "last" with "after" is not supported'
);
}

// If neither first nor last is provided, set a default first value
if (!first && !last) {
inputArgs.first = paginationLimit;
}

return inputArgs;
}

/**
* @hidden
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import type {
GqlReceiptFragment,
} from '../__generated__/operations';
import type Provider from '../provider';
import type { PageInfo } from '../provider';
import { TRANSACTIONS_PAGE_SIZE_LIMIT, type PageInfo } from '../provider';
import type { TransactionRequest } from '../transaction-request';
import type { TransactionResult } from '../transaction-response';
import { validatePaginationArgs } from '../utils/validate-pagination-args';

import { assembleTransactionSummary } from './assemble-transaction-summary';
import { processGqlReceipt } from './receipt';
Expand Down Expand Up @@ -142,7 +143,17 @@ export async function getTransactionsSummaries(
): Promise<GetTransactionsSummariesReturns> {
const { filters, provider, abiMap } = params;

const { transactionsByOwner } = await provider.operations.getTransactionsByOwner(filters);
const { owner, ...inputArgs } = filters;

const validPaginationParams = validatePaginationArgs({
inputArgs,
paginationLimit: TRANSACTIONS_PAGE_SIZE_LIMIT,
});

const { transactionsByOwner } = await provider.operations.getTransactionsByOwner({
...validPaginationParams,
owner,
});

const { edges, pageInfo } = transactionsByOwner;

Expand Down
49 changes: 49 additions & 0 deletions packages/account/src/providers/utils/validate-pagination-args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { FuelError, ErrorCode } from '@fuel-ts/errors';

import type { CursorPaginationArgs } from '../provider';

/**
* @hidden
*/
export const validatePaginationArgs = (params: {
inputArgs?: CursorPaginationArgs;
paginationLimit: number;
}): CursorPaginationArgs => {
const { paginationLimit, inputArgs = {} } = params;
const { first, last, after, before } = inputArgs;

if (after && before) {
throw new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
'Pagination arguments "after" and "before" cannot be used together'
);
}

if ((first || 0) > paginationLimit || (last || 0) > paginationLimit) {
throw new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
`Pagination limit for this query cannot exceed ${paginationLimit} items`
);
}

if (first && before) {
throw new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
'The use of pagination argument "first" with "before" is not supported'
);
}

if (last && after) {
throw new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
'The use of pagination argument "last" with "after" is not supported'
);
}

// If neither first nor last is provided, set a default first value
if (!first && !last) {
inputArgs.first = paginationLimit;
}

return inputArgs;
};
61 changes: 60 additions & 1 deletion packages/fuel-gauge/src/transaction-summary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,17 @@ import {
ChainName,
bn,
OutputType,
TRANSACTIONS_PAGE_SIZE_LIMIT,
FuelError,
ErrorCode,
} from 'fuels';
import { ASSET_A, ASSET_B, launchTestNode, TestMessage } from 'fuels/test-utils';
import {
ASSET_A,
ASSET_B,
expectToThrowFuelError,
launchTestNode,
TestMessage,
} from 'fuels/test-utils';

import { MultiTokenContractFactory, TokenContractFactory } from '../test/typegen';
import type { ContractIdInput, TransferParamsInput } from '../test/typegen/contracts/TokenContract';
Expand Down Expand Up @@ -164,6 +173,56 @@ describe('TransactionSummary', () => {
});
});

it('should ensure getTransactionsSummaries limits TX pagination number', async () => {
using launched = await launchTestNode();

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

await expectToThrowFuelError(
() =>
getTransactionsSummaries({
provider,
filters: {
first: TRANSACTIONS_PAGE_SIZE_LIMIT + 1,
owner: sender.address.toB256(),
},
}),
new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
'Pagination limit for this query cannot exceed 60 items'
)
);

await expectToThrowFuelError(
() =>
getTransactionsSummaries({
provider,
filters: {
last: TRANSACTIONS_PAGE_SIZE_LIMIT + 1,
owner: sender.address.toB256(),
},
}),
new FuelError(
ErrorCode.INVALID_INPUT_PARAMETERS,
'Pagination limit for this query cannot exceed 60 items'
)
);

// When using limit it should work
await expect(
getTransactionsSummaries({
provider,
filters: {
last: TRANSACTIONS_PAGE_SIZE_LIMIT,
owner: sender.address.toB256(),
},
})
).resolves.toBeDefined();
});

it('should ensure getTransactionSummaryFromRequest executes just fine [TX REQUEST]', async () => {
using launched = await launchTestNode();

Expand Down

0 comments on commit efdc721

Please sign in to comment.