Skip to content

Commit da1f81e

Browse files
authored
feat: Log the original transaction status (#566)
Signed-off-by: dan437 <[email protected]>
1 parent 1b14c3d commit da1f81e

File tree

4 files changed

+123
-2
lines changed

4 files changed

+123
-2
lines changed

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export {
2222
SmartTransactionMinedTx,
2323
SmartTransactionCancellationReason,
2424
SmartTransactionStatuses,
25+
OriginalTransactionStatus,
2526
ClientId,
2627
Feature,
2728
Kind,

src/types.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,29 @@ export enum ClientId {
7676
Extension = 'extension',
7777
}
7878

79+
export enum OriginalTransactionStatus {
80+
PENDING = 'PENDING',
81+
PENDING_CANCELLED = 'PENDING_CANCELLED',
82+
83+
VALIDATED = 'VALIDATED',
84+
REVERTED = 'REVERTED',
85+
NONCE_TOO_LOW = 'NONCE_TOO_LOW',
86+
CANCELLED = 'CANCELLED',
87+
88+
FAILED = 'FAILED',
89+
FAILED_WOULD_REVERT = 'FAILED_WOULD_REVERT',
90+
FAILED_INSUFFICIENT_FUNDS = 'FAILED_INSUFFICIENT_FUNDS',
91+
FAILED_UNKNOWN = 'FAILED_UNKNOWN',
92+
FAILED_TIMEOUT = 'FAILED_TIMEOUT',
93+
FAILED_GAS_TOO_LOW = 'FAILED_GAS_TOO_LOW',
94+
FAILED_NONCE_TOO_HIGH = 'FAILED_NONCE_TOO_HIGH',
95+
96+
LEAKED_VALIDATED = 'LEAKED_VALIDATED',
97+
LEAKED_REVERTED = 'LEAKED_REVERTED',
98+
CANCELLED_LEAKED_VALIDATED = 'CANCELLED_LEAKED_VALIDATED',
99+
CANCELLED_LEAKED_REVERTED = 'CANCELLED_LEAKED_REVERTED',
100+
}
101+
79102
export const cancellationReasonToStatusMap = {
80103
[SmartTransactionCancellationReason.WOULD_REVERT]:
81104
SmartTransactionStatuses.CANCELLED,
@@ -93,6 +116,7 @@ export type SmartTransactionsStatus = {
93116
error?: string;
94117
cancellationFeeWei: number;
95118
cancellationReason?: SmartTransactionCancellationReason;
119+
originalTransactionStatus?: OriginalTransactionStatus;
96120
deadlineRatio: number;
97121
minedHash: string;
98122
minedTx: SmartTransactionMinedTx;

src/utils.test.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
APIType,
1414
SmartTransactionStatuses,
1515
SmartTransactionCancellationReason,
16+
OriginalTransactionStatus,
1617
ClientId,
1718
} from './types';
1819
import * as utils from './utils';
@@ -578,6 +579,41 @@ describe('src/utils.js', () => {
578579
);
579580
});
580581

582+
it('includes originalTransactionStatus in error message when available', () => {
583+
const updateTransactionMock = jest.fn();
584+
const smartTransaction = {
585+
...createSmartTransaction(SmartTransactionStatuses.CANCELLED),
586+
statusMetadata: {
587+
cancellationFeeWei: 0,
588+
deadlineRatio: 0,
589+
minedHash: '',
590+
minedTx: SmartTransactionMinedTx.NOT_MINED,
591+
isSettled: false,
592+
originalTransactionStatus:
593+
OriginalTransactionStatus.FAILED_WOULD_REVERT,
594+
},
595+
};
596+
597+
utils.markRegularTransactionsAsFailed({
598+
smartTransaction,
599+
getRegularTransactions: () => [mockTransaction],
600+
updateTransaction: updateTransactionMock,
601+
});
602+
603+
expect(updateTransactionMock).toHaveBeenCalledWith(
604+
{
605+
...mockTransaction,
606+
status: TransactionStatus.failed,
607+
error: {
608+
name: 'SmartTransactionFailed',
609+
message:
610+
'Smart transaction failed with status: cancelled, originalTransactionStatus: FAILED_WOULD_REVERT',
611+
},
612+
},
613+
'Smart transaction status: cancelled',
614+
);
615+
});
616+
581617
it('throws error if original transaction cannot be found', () => {
582618
const updateTransactionMock = jest.fn();
583619
const getRegularTransactionsMock = jest.fn(() => []);
@@ -665,4 +701,57 @@ describe('src/utils.js', () => {
665701
);
666702
});
667703
});
704+
705+
describe('getSmartTransactionMetricsProperties', () => {
706+
it('includes stx_original_transaction_status from statusMetadata', () => {
707+
const smartTransaction = {
708+
uuid: 'test-uuid',
709+
status: SmartTransactionStatuses.SUCCESS,
710+
time: Date.now(),
711+
statusMetadata: {
712+
cancellationFeeWei: 0,
713+
deadlineRatio: 0.5,
714+
minedHash: '0xabc',
715+
minedTx: SmartTransactionMinedTx.SUCCESS,
716+
isSettled: true,
717+
duplicated: false,
718+
timedOut: false,
719+
proxied: false,
720+
originalTransactionStatus: OriginalTransactionStatus.VALIDATED,
721+
},
722+
};
723+
724+
const result =
725+
utils.getSmartTransactionMetricsProperties(smartTransaction);
726+
727+
expect(result).toStrictEqual(
728+
expect.objectContaining({
729+
stx_original_transaction_status: OriginalTransactionStatus.VALIDATED,
730+
stx_duplicated: false,
731+
stx_timed_out: false,
732+
stx_proxied: false,
733+
}),
734+
);
735+
});
736+
737+
it('returns undefined for stx_original_transaction_status when not in statusMetadata', () => {
738+
const smartTransaction = {
739+
uuid: 'test-uuid',
740+
status: SmartTransactionStatuses.PENDING,
741+
time: Date.now(),
742+
statusMetadata: {
743+
cancellationFeeWei: 0,
744+
deadlineRatio: 0,
745+
minedHash: '',
746+
minedTx: SmartTransactionMinedTx.NOT_MINED,
747+
isSettled: false,
748+
},
749+
};
750+
751+
const result =
752+
utils.getSmartTransactionMetricsProperties(smartTransaction);
753+
754+
expect(result.stx_original_transaction_status).toBeUndefined();
755+
});
756+
});
668757
});

src/utils.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ export const getSmartTransactionMetricsProperties = (
213213
stx_duplicated: smartTransactionStatusMetadata?.duplicated,
214214
stx_timed_out: smartTransactionStatusMetadata?.timedOut,
215215
stx_proxied: smartTransactionStatusMetadata?.proxied,
216+
stx_original_transaction_status:
217+
smartTransactionStatusMetadata?.originalTransactionStatus,
216218
};
217219
};
218220

@@ -275,7 +277,8 @@ export const markRegularTransactionsAsFailed = ({
275277
getRegularTransactions: TransactionControllerGetTransactionsAction['handler'];
276278
updateTransaction: TransactionControllerUpdateTransactionAction['handler'];
277279
}) => {
278-
const { transactionId, status, txHashes } = smartTransaction;
280+
const { transactionId, status, statusMetadata, txHashes } = smartTransaction;
281+
const originalTransactionStatus = statusMetadata?.originalTransactionStatus;
279282

280283
const transactionsToFail = getRegularTransactions().filter(
281284
(tx) => (tx.hash && txHashes?.includes(tx.hash)) || tx.id === transactionId,
@@ -285,6 +288,10 @@ export const markRegularTransactionsAsFailed = ({
285288
throw new Error('Cannot find regular transaction to mark it as failed');
286289
}
287290

291+
const errorMessage = originalTransactionStatus
292+
? `Smart transaction failed with status: ${status}, originalTransactionStatus: ${originalTransactionStatus}`
293+
: `Smart transaction failed with status: ${status}`;
294+
288295
for (const tx of transactionsToFail) {
289296
if (tx.status === TransactionStatus.failed) {
290297
continue; // Already marked as failed.
@@ -294,7 +301,7 @@ export const markRegularTransactionsAsFailed = ({
294301
status: TransactionStatus.failed,
295302
error: {
296303
name: 'SmartTransactionFailed',
297-
message: `Smart transaction failed with status: ${status}`,
304+
message: errorMessage,
298305
},
299306
};
300307

0 commit comments

Comments
 (0)