diff --git a/package-lock.json b/package-lock.json index 75f46ef8..a3f8de5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@multiversx/sdk-core", - "version": "15.3.2", + "version": "15.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@multiversx/sdk-core", - "version": "15.3.2", + "version": "15.4.0", "license": "MIT", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", diff --git a/package.json b/package.json index 612804a8..487e9377 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@multiversx/sdk-core", - "version": "15.3.2", + "version": "15.4.0", "description": "MultiversX SDK for JavaScript and TypeScript", "author": "MultiversX", "homepage": "https://multiversx.com", diff --git a/src/core/constants.ts b/src/core/constants.ts index a398c7ef..97700e11 100644 --- a/src/core/constants.ts +++ b/src/core/constants.ts @@ -30,3 +30,8 @@ export const UNKNOWN_SIGNER = "unknown"; export const EGLD_IDENTIFIER_FOR_MULTI_ESDTNFT_TRANSFER = "EGLD-000000"; export const EXTRA_GAS_LIMIT_FOR_GUARDED_TRANSACTIONS = 50_000; export const EXTRA_GAS_LIMIT_FOR_RELAYED_TRANSACTIONS = 50_000; + +export const DEFAULT_TRANSACTION_AWAITING_POLLING_TIMEOUT_IN_MILLISECONDS = 600; +export const DEFAULT_TRANSACTION_AWAITING_TIMEOUT_IN_MILLISECONDS = + 15 * DEFAULT_TRANSACTION_AWAITING_POLLING_TIMEOUT_IN_MILLISECONDS; +export const DEFAULT_TRANSACTION_AWAITING_PATIENCE_IN_MILLISECONDS = 0; diff --git a/src/core/transactionStatus.ts b/src/core/transactionStatus.ts index 797b6c70..e42c4eed 100644 --- a/src/core/transactionStatus.ts +++ b/src/core/transactionStatus.ts @@ -29,7 +29,7 @@ export class TransactionStatus { } /** - * Returns whether the transaction has been conpleted (not necessarily with success). + * Returns whether the transaction has been completed (not necessarily with success). */ isCompleted(): boolean { return this.isSuccessful() || this.isFailed() || this.isInvalid(); @@ -56,6 +56,13 @@ export class TransactionStatus { return this.status == "invalid"; } + /** + * Returns whether the transaction cannot be executed in the current block. + */ + isNotExecutableInBlock(): boolean { + return this.status == "not-executable-in-block"; + } + toString(): string { return this.status; } diff --git a/src/core/transactionWatcher.spec.ts b/src/core/transactionWatcher.spec.ts index 967be803..5281a003 100644 --- a/src/core/transactionWatcher.spec.ts +++ b/src/core/transactionWatcher.spec.ts @@ -62,4 +62,32 @@ describe("test transactionWatcher", () => { assert.isTrue((await provider.getTransactionStatus(hash)).isCompleted()); }); + + it("should await status == not-executable-in-block using transaction", async () => { + let hash = "abbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabba"; + let provider = new MockNetworkProvider(); + let watcher = new TransactionWatcher(provider, { + pollingIntervalMilliseconds: 42, + timeoutMilliseconds: 42 * 42, + }); + + provider.mockPutTransaction( + hash, + new TransactionOnNetwork({ + status: new TransactionStatus("unknown"), + }), + ); + + await Promise.all([ + provider.mockTransactionTimelineByHash(hash, [ + new Wait(40), + new TransactionStatus("pending"), + new Wait(40), + new TransactionStatus("not-executable-in-block"), + ]), + watcher.awaitOnCondition(hash, (tx) => tx.status.isNotExecutableInBlock()), + ]); + + assert.isTrue((await provider.getTransactionStatus(hash)).isNotExecutableInBlock()); + }); }); diff --git a/src/core/transactionWatcher.ts b/src/core/transactionWatcher.ts index 0f1826b8..e9e6e0ce 100644 --- a/src/core/transactionWatcher.ts +++ b/src/core/transactionWatcher.ts @@ -1,4 +1,9 @@ import { AsyncTimer } from "./asyncTimer"; +import { + DEFAULT_TRANSACTION_AWAITING_PATIENCE_IN_MILLISECONDS, + DEFAULT_TRANSACTION_AWAITING_POLLING_TIMEOUT_IN_MILLISECONDS, + DEFAULT_TRANSACTION_AWAITING_TIMEOUT_IN_MILLISECONDS, +} from "./constants"; import { Err, ErrExpectedTransactionEventsNotFound, @@ -17,9 +22,9 @@ export type PredicateIsAwaitedStatus = (status: TransactionStatus) => boolean; * TransactionWatcher allows one to continuously watch (monitor), by means of polling, the status of a given transaction. */ export class TransactionWatcher { - private static DefaultPollingInterval: number = 6000; - private static DefaultTimeout: number = TransactionWatcher.DefaultPollingInterval * 15; - private static DefaultPatience: number = 0; + private static DefaultPollingInterval: number = DEFAULT_TRANSACTION_AWAITING_POLLING_TIMEOUT_IN_MILLISECONDS; + private static DefaultTimeout: number = DEFAULT_TRANSACTION_AWAITING_TIMEOUT_IN_MILLISECONDS; + private static DefaultPatience: number = DEFAULT_TRANSACTION_AWAITING_PATIENCE_IN_MILLISECONDS; static NoopOnStatusReceived = (_: TransactionStatus) => {}; diff --git a/src/networkProviders/constants.ts b/src/networkProviders/constants.ts index f31aee78..345ea70b 100644 --- a/src/networkProviders/constants.ts +++ b/src/networkProviders/constants.ts @@ -6,7 +6,7 @@ export const EsdtContractAddress = new Address("erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqq export const BaseUserAgent = "multiversx-sdk"; export const UnknownClientName = "unknown"; -export const DEFAULT_ACCOUNT_AWAITING_POLLING_TIMEOUT_IN_MILLISECONDS = 6000; +export const DEFAULT_ACCOUNT_AWAITING_POLLING_TIMEOUT_IN_MILLISECONDS = 600; export const DEFAULT_ACCOUNT_AWAITING_TIMEOUT_IN_MILLISECONDS = 15 * DEFAULT_ACCOUNT_AWAITING_POLLING_TIMEOUT_IN_MILLISECONDS; export const DEFAULT_ACCOUNT_AWAITING_PATIENCE_IN_MILLISECONDS = 0; diff --git a/src/networkProviders/networkStatus.ts b/src/networkProviders/networkStatus.ts index 0988a170..3d83b664 100644 --- a/src/networkProviders/networkStatus.ts +++ b/src/networkProviders/networkStatus.ts @@ -9,6 +9,11 @@ export class NetworkStatus { */ public blockTimestamp: number; + /** + * The block timestamp in milliseconds. + */ + public blockTimestampMs: number; + /** * The block nonce. */ @@ -35,6 +40,7 @@ export class NetworkStatus { this.highestFinalNonce = 0n; this.blockNonce = 0n; this.blockTimestamp = 0; + this.blockTimestampMs = 0; } /** @@ -49,6 +55,7 @@ export class NetworkStatus { networkStatus.highestFinalNonce = BigInt(payload["erd_highest_final_nonce"]); networkStatus.blockNonce = BigInt(payload["erd_nonce"]); networkStatus.blockTimestamp = Number(payload["erd_block_timestamp"]); + networkStatus.blockTimestampMs = Number(payload["erd_block_timestamp_ms"]); return networkStatus; }