Merge pull request #762 from cosmos/739-sync-cosmwasm

Use sync mode in CosmWasmClient.broadcastTx
This commit is contained in:
Simon Warta 2021-04-14 13:52:01 +02:00 committed by GitHub
commit 212318d2a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 32 deletions

View File

@ -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

View File

@ -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<BroadcastTxResponse> {
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,
};
// 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<BroadcastTxResponse> {
let timedOut = false;
const txPollTimeout = setTimeout(() => {
timedOut = true;
}, timeoutMs);
const pollForTx = async (txId: string): Promise<BroadcastTxResponse> => {
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,
);
}
return response.checkTx.code !== 0
await sleep(pollIntervalMs);
const result = await this.getTx(txId);
return result
? {
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,
code: result.code,
height: result.height,
rawLog: result.rawLog,
transactionHash: txId,
}
: {
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,
: 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<readonly Code[]> {