Skip to content

Commit

Permalink
feat: improve transaction summary (FuelLabs#1200)
Browse files Browse the repository at this point in the history
  • Loading branch information
Torres-ssf authored Aug 23, 2023
1 parent a8234c3 commit ff8c4df
Show file tree
Hide file tree
Showing 21 changed files with 257 additions and 151 deletions.
5 changes: 5 additions & 0 deletions .changeset/great-lamps-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/providers": minor
---

improvements to transaction summary functions
23 changes: 16 additions & 7 deletions packages/fuel-gauge/src/transaction-summary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
BaseAssetId,
Provider,
ScriptTransactionRequest,
TransactionTypeNameEnum,
TransactionTypeName,
Wallet,
} from 'fuels';

Expand All @@ -37,7 +37,7 @@ describe('TransactionSummary', () => {
expect(transaction.fee).toStrictEqual(expect.any(BN));
expect(transaction.gasUsed).toStrictEqual(expect.any(BN));
expect(transaction.operations).toStrictEqual(expect.any(Array<Operation>));
expect(transaction.type).toEqual(TransactionTypeNameEnum.Script);
expect(transaction.type).toEqual(TransactionTypeName.Script);
expect(transaction.receipts).toStrictEqual(expect.any(Array<TransactionResultReceipt>));
expect(transaction.isTypeMint).toBe(false);
expect(transaction.isTypeCreate).toBe(false);
Expand Down Expand Up @@ -76,7 +76,10 @@ describe('TransactionSummary', () => {

const transactionResponse = await tx.waitForResult();

const transactionSummary = await getTransactionSummary(tx.id, provider);
const transactionSummary = await getTransactionSummary({
id: tx.id,
provider,
});

verifyTransactionSummary({
transaction: transactionSummary,
Expand All @@ -99,9 +102,12 @@ describe('TransactionSummary', () => {
const tx2 = await sender.transfer(destination.address, amountToTransfer);
const transactionResponse2 = await tx2.waitForResult();

const { transactions } = await getTransactionsSummaries(provider, {
first: 2,
owner: sender.address.toB256(),
const { transactions } = await getTransactionsSummaries({
provider,
filters: {
first: 2,
owner: sender.address.toB256(),
},
});

expect(transactions.length).toBe(2);
Expand Down Expand Up @@ -132,7 +138,10 @@ describe('TransactionSummary', () => {

const transactionRequest = await wallet.populateTransactionWitnessesSignature(request);

const transactionSummary = await getTransactionSummaryFromRequest(transactionRequest, provider);
const transactionSummary = await getTransactionSummaryFromRequest({
provider,
transactionRequest,
});
verifyTransactionSummary({
transaction: transactionSummary,
isRequest: true,
Expand Down
19 changes: 6 additions & 13 deletions packages/providers/src/operations.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,18 @@ fragment transactionFragment on Transaction {
}
}

fragment contractFragment on Contract {
id
bytecode
}

fragment receiptFragment on Receipt {
contract {
...contractFragment
id
bytecode
salt
}
pc
is
to {
...contractFragment
id
bytecode
salt
}
toAddress
amount
Expand Down Expand Up @@ -246,12 +245,6 @@ query getTransactionWithReceipts($transactionId: TransactionId!) {
...receiptFragment
}
}
chain {
consensusParameters {
gasPerByte
gasPriceFactor
}
}
}

query getTransactions(
Expand Down
26 changes: 15 additions & 11 deletions packages/providers/src/transaction-response/transaction-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type {
TransactionSummary,
FailureStatus,
GqlTransaction,
AbiMap,
} from '../transaction-summary/types';
import { sleep } from '../utils';

Expand Down Expand Up @@ -136,13 +137,10 @@ export class TransactionResponse {
*
* @returns The completed transaction result
*/
async waitForResult<TTransactionType = void>(): Promise<TransactionResult<TTransactionType>> {
const {
transaction: gqlTransaction,
chain: {
consensusParameters: { gasPerByte, gasPriceFactor },
},
} = await this.fetch();
async waitForResult<TTransactionType = void>(
contractsAbiMap?: AbiMap
): Promise<TransactionResult<TTransactionType>> {
const { transaction: gqlTransaction } = await this.fetch();

const nullResponse = !gqlTransaction?.status?.type;
const isStatusSubmitted = gqlTransaction?.status?.type === 'SubmittedStatus';
Expand All @@ -158,7 +156,7 @@ export class TransactionResponse {
await sleep(
Math.min(STATUS_POLLING_INTERVAL_MIN_MS * this.attempts, STATUS_POLLING_INTERVAL_MAX_MS)
);
return this.waitForResult();
return this.waitForResult(contractsAbiMap);
}

const decodedTransaction = this.decodeTransaction<TTransactionType>(
Expand All @@ -167,15 +165,19 @@ export class TransactionResponse {

const receipts = gqlTransaction.receipts?.map(processGqlReceipt) || [];

const {
consensusParameters: { gasPerByte, gasPriceFactor },
} = await this.provider.getChain();

const transactionSummary = assembleTransactionSummary<TTransactionType>({
id: this.id,
gasPrice: bn(gqlTransaction.gasPrice),
receipts,
transaction: decodedTransaction,
transactionBytes: arrayify(gqlTransaction.rawPayload),
gqlTransactionStatus: gqlTransaction.status,
gasPerByte: bn(gasPerByte),
gasPriceFactor: bn(gasPriceFactor),
abiMap: contractsAbiMap,
});

const transactionResult: TransactionResult<TTransactionType> = {
Expand All @@ -191,8 +193,10 @@ export class TransactionResponse {
*
* @returns The completed transaction.
*/
async wait<TTransactionType = void>(): Promise<TransactionResult<TTransactionType>> {
const result = await this.waitForResult<TTransactionType>();
async wait<TTransactionType = void>(
contractsAbiMap?: AbiMap
): Promise<TransactionResult<TTransactionType>> {
const result = await this.waitForResult<TTransactionType>(contractsAbiMap);

if (result.isStatusFailure) {
throw new Error(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { type Operation } from './types';

describe('TransactionSummary', () => {
const id = '0x2bfbebca58da94ba3ee258698c9be5884e2874688bdffa29cb535cf05d665215';
const gasPrice = bn(1);
const gasPerByte = bn(2);
const gasPriceFactor = bn(3);
const transaction = MOCK_TRANSACTION;
Expand All @@ -38,7 +37,6 @@ describe('TransactionSummary', () => {
const runTest = (status: GraphqlTransactionStatus, expected: Record<string, unknown>) => {
const transactionSummary = assembleTransactionSummary({
id,
gasPrice,
gasPerByte,
gasPriceFactor,
transaction,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { hexlify } from '@ethersproject/bytes';
import type { BN } from '@fuel-ts/math';
import { bn, type BN } from '@fuel-ts/math';
import { type Transaction } from '@fuel-ts/transactions';

import type { TransactionResultReceipt } from '../transaction-response';
Expand All @@ -14,44 +14,44 @@ import {
} from './operations';
import { extractBurnedAssetsFromReceipts, extractMintedAssetsFromReceipts } from './receipt';
import { processGraphqlStatus } from './status';
import type { AbiParam, GraphqlTransactionStatus, TransactionSummary } from './types';
import type { AbiMap, GraphqlTransactionStatus, TransactionSummary } from './types';

interface IAssembleTransactionSummaryParams {
export interface AssembleTransactionSummaryParams {
id?: string;
gasPrice: BN;
gasPerByte?: BN;
gasPriceFactor?: BN;
transaction: Transaction;
transactionBytes: Uint8Array;
gqlTransactionStatus?: GraphqlTransactionStatus;
receipts: TransactionResultReceipt[];
abiParam?: AbiParam;
abiMap?: AbiMap;
}

/** @hidden */
export function assembleTransactionSummary<TTransactionType = void>(
params: IAssembleTransactionSummaryParams
params: AssembleTransactionSummaryParams
) {
const {
receipts,
gasPerByte,
gasPrice,
gasPriceFactor,
transaction,
transactionBytes,
id,
gqlTransactionStatus,
abiParam,
abiMap = {},
} = params;

const { fee, gasUsed } = calculateTransactionFee({
const gasPrice = bn(transaction.gasPrice);

const { gasUsed, fee } = calculateTransactionFee({
receipts,
gasPrice,
transactionBytes,
transactionWitnesses: transaction?.witnesses || [],
gasPerByte,
gasPriceFactor,
transactionType: transaction.type,
receipts,
});

const operations = getOperations({
Expand All @@ -60,7 +60,7 @@ export function assembleTransactionSummary<TTransactionType = void>(
outputs: transaction.outputs || [],
receipts,
rawPayload: hexlify(transactionBytes),
abiMap: abiParam?.abiMap,
abiMap,
});

const typeName = getTransactionTypeName(transaction.type);
Expand Down
Loading

0 comments on commit ff8c4df

Please sign in to comment.