From c6b292392eb404f8a66338abac7d010082d1d590 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 13 Apr 2021 18:55:10 +0200 Subject: [PATCH 1/2] cosmwasm-stargate: Use sync mode in CosmWasmClient.broadcastTx --- .../cosmwasm-stargate/src/cosmwasmclient.ts | 73 +++++++++++-------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/packages/cosmwasm-stargate/src/cosmwasmclient.ts b/packages/cosmwasm-stargate/src/cosmwasmclient.ts index cb440e6844..80f33b380b 100644 --- a/packages/cosmwasm-stargate/src/cosmwasmclient.ts +++ b/packages/cosmwasm-stargate/src/cosmwasmclient.ts @@ -26,14 +26,10 @@ import { SequenceResponse, setupAuthExtension, setupBankExtension, + TimeoutError, } from "@cosmjs/stargate"; -import { TxMsgData } from "@cosmjs/stargate/build/codec/cosmos/base/abci/v1beta1/abci"; -import { - broadcastTxCommitSuccess, - Tendermint34Client, - toRfc3339WithNanoseconds, -} from "@cosmjs/tendermint-rpc"; -import { assert } from "@cosmjs/utils"; +import { Tendermint34Client, toRfc3339WithNanoseconds } from "@cosmjs/tendermint-rpc"; +import { assert, sleep } from "@cosmjs/utils"; import { CodeInfoResponse } from "./codec/x/wasm/internal/types/query"; import { ContractCodeHistoryOperationType } from "./codec/x/wasm/internal/types/types"; @@ -201,31 +197,44 @@ export class CosmWasmClient { if (this.tmClient) this.tmClient.disconnect(); } - public async broadcastTx(tx: Uint8Array): Promise { - const response = await this.forceGetTmClient().broadcastTxCommit({ tx }); - if (broadcastTxCommitSuccess(response)) { - return { - height: response.height, - transactionHash: toHex(response.hash).toUpperCase(), - rawLog: response.deliverTx?.log, - data: response.deliverTx?.data ? TxMsgData.decode(response.deliverTx?.data).data : undefined, - }; - } - return response.checkTx.code !== 0 - ? { - height: response.height, - code: response.checkTx.code, - transactionHash: toHex(response.hash).toUpperCase(), - rawLog: response.checkTx.log, - data: response.checkTx.data ? TxMsgData.decode(response.checkTx.data).data : undefined, - } - : { - height: response.height, - code: response.deliverTx?.code, - transactionHash: toHex(response.hash).toUpperCase(), - rawLog: response.deliverTx?.log, - data: response.deliverTx?.data ? TxMsgData.decode(response.deliverTx?.data).data : undefined, - }; + // NOTE: This method is tested against slow chains and timeouts in the @cosmjs/stargate package. + // Make sure it is kept in sync! + public async broadcastTx( + tx: Uint8Array, + timeoutMs = 60_000, + pollIntervalMs = 3_000, + ): Promise { + let timedOut = false; + const txPollTimeout = setTimeout(() => { + timedOut = true; + }, timeoutMs); + + const pollForTx = async (txId: string): Promise => { + if (timedOut) { + throw new TimeoutError( + `Transaction with ID ${txId} was submitted but was not yet found on the chain. You might want to check later.`, + txId, + ); + } + await sleep(pollIntervalMs); + const result = await this.getTx(txId); + return result + ? { + code: result.code, + height: result.height, + rawLog: result.rawLog, + transactionHash: txId, + } + : pollForTx(txId); + }; + + return new Promise((resolve, reject) => + this.forceGetTmClient() + .broadcastTxSync({ tx }) + .then(({ hash }) => pollForTx(toHex(hash).toUpperCase())) + .then(resolve, reject) + .finally(() => clearTimeout(txPollTimeout)), + ); } public async getCodes(): Promise { From aed8b1ce70a484b4a4d9d218eee269ff3ddc9e16 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 13 Apr 2021 18:56:10 +0200 Subject: [PATCH 2/2] Update CHANGELOG for CosmWasmClient.broadcastTx --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 471f162938..de7e613a00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -116,6 +116,9 @@ and this project adheres to - @cosmjs/stargate: `StargateClient.broadcastTx` now uses sync mode and then polls for the transaction before resolving. The timeout and poll interval can be configured. +- @cosmjs/cosmwasm-stargate: `CosmWasmClient.broadcastTx` now uses sync mode and + then polls for the transaction before resolving. The timeout and poll interval + can be configured. ### Deprecated