Skip to content

Commit

Permalink
feat: waitForTransaction Sequencer reworked with execution and finali…
Browse files Browse the repository at this point in the history
…ty status, 5s steps, not_rec
  • Loading branch information
tabaktoni committed Jul 26, 2023
1 parent 384db9f commit f4e414f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 27 deletions.
9 changes: 2 additions & 7 deletions __tests__/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
Contract,
DeclareDeployUDCResponse,
Provider,
TransactionStatus,
TransactionType,
cairo,
contractClassResponseToLegacyCompiledContract,
Expand Down Expand Up @@ -338,9 +337,7 @@ describe('deploy and test Wallet', () => {
calldata: [erc20.address, '10', '0'],
});

await provider.waitForTransaction(transaction_hash, {
successStates: [TransactionStatus.ACCEPTED_ON_L2],
});
await provider.waitForTransaction(transaction_hash);
});

test('read balance of wallet after transfer', async () => {
Expand Down Expand Up @@ -379,9 +376,7 @@ describe('deploy and test Wallet', () => {
},
]);

await provider.waitForTransaction(transaction_hash, {
successStates: [TransactionStatus.ACCEPTED_ON_L2],
});
await provider.waitForTransaction(transaction_hash);

const response = await dapp.get_number(account.address);
expect(toBigInt(response.number as string).toString()).toStrictEqual('57');
Expand Down
13 changes: 7 additions & 6 deletions src/provider/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,15 @@ export class RpcProvider implements ProviderInterface {
}

public async waitForTransaction(txHash: string, options?: waitForTransactionOptions) {
const errorStates = [TransactionStatus.REJECTED, TransactionStatus.NOT_RECEIVED];
let { retries } = this;
let onchain = false;
let txReceipt: any = {};

const retryInterval = options?.retryInterval ?? 8000;
const successStates = options?.successStates ?? [
const retryInterval = options?.retryInterval ?? 5000;
const errorStates: any = options?.errorStates ?? [
TransactionStatus.REJECTED,
TransactionStatus.NOT_RECEIVED,
];
const successStates: any = options?.successStates ?? [
TransactionStatus.ACCEPTED_ON_L1,
TransactionStatus.ACCEPTED_ON_L2,
];
Expand All @@ -451,9 +453,8 @@ export class RpcProvider implements ProviderInterface {
try {
// eslint-disable-next-line no-await-in-loop
txReceipt = await this.getTransactionReceipt(txHash);

if (!('status' in txReceipt)) {
const error = new Error('transaction status');
const error = new Error('waiting for transaction status');
throw error;
}

Expand Down
46 changes: 33 additions & 13 deletions src/provider/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import {
SequencerProviderOptions,
SimulateTransactionResponse,
StateUpdateResponse,
TransactionStatus,
TransactionExecutionStatus,
TransactionFinalityStatus,
TransactionType,
getEstimateFeeBulkOptions,
getSimulateTransactionOptions,
Expand Down Expand Up @@ -489,27 +490,46 @@ export class SequencerProvider implements ProviderInterface {
}

public async waitForTransaction(txHash: BigNumberish, options?: waitForTransactionOptions) {
const errorStates = [TransactionStatus.REJECTED, TransactionStatus.NOT_RECEIVED];
let onchain = false;
let res;
const retryInterval = options?.retryInterval ?? 8000;
let completed = false;
let retries = 0;
const retryInterval = options?.retryInterval ?? 5000;
const errorStates = options?.errorStates ?? [
TransactionExecutionStatus.REJECTED,
TransactionFinalityStatus.NOT_RECEIVED,
TransactionExecutionStatus.REVERTED,
];
const successStates = options?.successStates ?? [
TransactionStatus.ACCEPTED_ON_L1,
TransactionStatus.ACCEPTED_ON_L2,
TransactionExecutionStatus.SUCCEEDED,
TransactionFinalityStatus.ACCEPTED_ON_L1,
TransactionFinalityStatus.ACCEPTED_ON_L2,
];

while (!onchain) {
while (!completed) {
// eslint-disable-next-line no-await-in-loop
await wait(retryInterval);
// eslint-disable-next-line no-await-in-loop
res = await this.getTransactionStatus(txHash);

if (successStates.includes(res.tx_status)) {
onchain = true;
} else if (errorStates.includes(res.tx_status)) {
const message = res.tx_failure_reason
? `${res.tx_status}: ${res.tx_failure_reason.code}\n${res.tx_failure_reason.error_message}`
: res.tx_status;
if (TransactionFinalityStatus.NOT_RECEIVED === res.finality_status && retries < 3) {
retries += 1;
} else if (
successStates.includes(res.finality_status) ||
successStates.includes(res.execution_status)
) {
completed = true;
} else if (
errorStates.includes(res.finality_status) ||
errorStates.includes(res.execution_status)
) {
let message;
if (res.tx_failure_reason) {
message = `${res.tx_status}: ${res.tx_failure_reason.code}\n${res.tx_failure_reason.error_message}`;
} else if (res.tx_revert_reason) {
message = `${res.tx_status}: ${res.tx_revert_reason}`;
} else {
message = res.tx_status;
}
const error = new Error(message) as Error & { response: GetTransactionStatusResponse };
error.response = res;
throw error;
Expand Down
5 changes: 5 additions & 0 deletions src/types/api/sequencer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,23 @@ import {
ContractClass,
EntryPointType,
RawCalldata,
TransactionExecutionStatus,
TransactionFinalityStatus,
TransactionStatus,
TransactionType,
} from '../lib';

// #region | originally not included in the namespace
export type GetTransactionStatusResponse = {
tx_status: TransactionStatus;
execution_status: TransactionExecutionStatus;
finality_status: TransactionFinalityStatus;
block_hash?: string;
tx_failure_reason?: {
code: string;
error_message: string;
};
tx_revert_reason?: string;
};

export type GetContractAddressesResponse = {
Expand Down
21 changes: 20 additions & 1 deletion src/types/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,30 @@ export enum TransactionType {
INVOKE = 'INVOKE_FUNCTION',
}

/**
* new statuses are defined by props: finality_status and execution_status
* to be #deprecated
*/
export enum TransactionStatus {
NOT_RECEIVED = 'NOT_RECEIVED',
RECEIVED = 'RECEIVED',
ACCEPTED_ON_L2 = 'ACCEPTED_ON_L2',
ACCEPTED_ON_L1 = 'ACCEPTED_ON_L1',
REJECTED = 'REJECTED',
REVERTED = 'REVERTED',
}

export enum TransactionFinalityStatus {
NOT_RECEIVED = 'NOT_RECEIVED',
RECEIVED = 'RECEIVED',
ACCEPTED_ON_L2 = 'ACCEPTED_ON_L2',
ACCEPTED_ON_L1 = 'ACCEPTED_ON_L1',
}

export enum TransactionExecutionStatus {
REJECTED = 'REJECTED',
REVERTED = 'REVERTED',
SUCCEEDED = 'SUCCEEDED',
}

export enum BlockStatus {
Expand Down Expand Up @@ -200,7 +218,8 @@ export type ParsedStruct = {

export type waitForTransactionOptions = {
retryInterval?: number;
successStates?: Array<TransactionStatus>;
successStates?: Array<TransactionFinalityStatus | TransactionExecutionStatus>;
errorStates?: Array<TransactionFinalityStatus | TransactionExecutionStatus>;
};

export type getSimulateTransactionOptions = {
Expand Down

0 comments on commit f4e414f

Please sign in to comment.