Avoid unnecessary conversion to bytes in postTx

In Cosmos world, transactions are posted as JSON. Move the byte
representation into BCP.
This commit is contained in:
Simon Warta 2020-02-21 12:14:03 +01:00
parent 8f1f8d93be
commit 00801b2831
10 changed files with 30 additions and 33 deletions

View File

@ -257,7 +257,9 @@ export class CosmWasmConnection implements BlockchainConnection {
}
public async postTx(tx: PostableBytes): Promise<PostTxResponse> {
const { transactionHash, rawLog } = await this.cosmWasmClient.postTx(tx);
const txAsJson = JSON.parse(Encoding.fromUtf8(tx));
if (!types.isStdTx(txAsJson)) throw new Error("Postable bytes must contain a JSON encoded StdTx");
const { transactionHash, rawLog } = await this.cosmWasmClient.postTx(txAsJson);
const transactionId = transactionHash as TransactionId;
const firstEvent: BlockInfo = { state: TransactionState.Pending };
let blockInfoInterval: NodeJS.Timeout;

View File

@ -72,7 +72,7 @@ const signedTx: types.StdTx = {
memo: memo,
signatures: [signature],
}
const postResult = await client.postTx(marshalTx(signedTx));
const postResult = await client.postTx(signedTx);
```
## Extended helpers

View File

@ -47,7 +47,7 @@ const instantiateContract = async (initClient: RestClient, initPen: Secp256k1Pen
memo: memo,
signatures: [signature],
};
const result = await initClient.postTx(marshalTx(signedTx));
const result = await initClient.postTx(signedTx);
if (result.code) {
throw new Error(`Failed tx: (${result.code}): ${result.raw_log}`)
}
@ -78,7 +78,7 @@ const executeContract = async (execClient: RestClient, execPen: Secp256k1Pen, co
memo: memo,
signatures: [signature],
};
const result = await execClient.postTx(marshalTx(signedTx));
const result = await execClient.postTx(signedTx);
if (result.code) {
throw new Error(`Failed tx: (${result.code}): ${result.raw_log}`)
}

View File

@ -4,7 +4,7 @@ import { assert, sleep } from "@iov/utils";
import { ReadonlyDate } from "readonly-date";
import { CosmWasmClient } from "./cosmwasmclient";
import { makeSignBytes, marshalTx } from "./encoding";
import { makeSignBytes } from "./encoding";
import { findAttribute } from "./logs";
import { Secp256k1Pen } from "./pen";
import { RestClient } from "./restclient";
@ -198,7 +198,7 @@ describe("CosmWasmClient", () => {
memo: memo,
signatures: [signature],
};
const { logs, transactionHash } = await client.postTx(marshalTx(signedTx));
const { logs, transactionHash } = await client.postTx(signedTx);
const amountAttr = findAttribute(logs, "transfer", "amount");
expect(amountAttr.value).toEqual("1234567ucosm");
expect(transactionHash).toMatch(/^[0-9A-F]{64}$/);

View File

@ -3,7 +3,7 @@ import { Encoding } from "@iov/encoding";
import { Log, parseLogs } from "./logs";
import { BlockResponse, BroadcastMode, RestClient, TxsResponse } from "./restclient";
import { CosmosSdkAccount, CosmosSdkTx } from "./types";
import { CosmosSdkAccount, CosmosSdkTx, StdTx } from "./types";
export interface GetNonceResult {
readonly accountNumber: number;
@ -125,7 +125,7 @@ export class CosmWasmClient {
}
}
public async postTx(tx: Uint8Array): Promise<PostTxResult> {
public async postTx(tx: StdTx): Promise<PostTxResult> {
const result = await this.restClient.postTx(tx);
if (result.code) {
throw new Error(`Error when posting tx. Code: ${result.code}; Raw log: ${result.raw_log}`);

View File

@ -4,7 +4,7 @@ import { Encoding } from "@iov/encoding";
import { assert } from "@iov/utils";
import { ReadonlyDate } from "readonly-date";
import { makeSignBytes, marshalTx } from "./encoding";
import { makeSignBytes } from "./encoding";
import { findAttribute, parseLogs } from "./logs";
import { Pen, Secp256k1Pen } from "./pen";
import { encodeBech32Pubkey } from "./pubkey";
@ -87,7 +87,7 @@ async function uploadCustomContract(
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account_number, sequence);
const signature = await pen.sign(signBytes);
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
return client.postTx(marshalTx(signedTx));
return client.postTx(signedTx);
}
async function uploadContract(client: RestClient, pen: Pen): Promise<PostTxsResponse> {
@ -128,7 +128,7 @@ async function instantiateContract(
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account_number, sequence);
const signature = await pen.sign(signBytes);
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
return client.postTx(marshalTx(signedTx));
return client.postTx(signedTx);
}
async function executeContract(
@ -160,7 +160,7 @@ async function executeContract(
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account_number, sequence);
const signature = await pen.sign(signBytes);
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
return client.postTx(marshalTx(signedTx));
return client.postTx(signedTx);
}
describe("RestClient", () => {
@ -348,7 +348,7 @@ describe("RestClient", () => {
const signBytes = makeSignBytes([theMsg], fee, defaultNetworkId, memo, account_number, sequence);
const signature = await pen.sign(signBytes);
const signedTx = makeSignedTx(theMsg, fee, memo, signature);
const result = await client.postTx(marshalTx(signedTx));
const result = await client.postTx(signedTx);
// console.log("Raw log:", result.raw_log);
expect(result.code).toBeFalsy();
});

View File

@ -6,13 +6,13 @@ import {
ContractInfo,
CosmosSdkAccount,
CosmosSdkTx,
isStdTx,
Model,
parseWasmData,
StdTx,
WasmData,
} from "./types";
const { fromBase64, fromUtf8, toHex, toUtf8 } = Encoding;
const { fromBase64, toHex, toUtf8 } = Encoding;
interface NodeInfo {
readonly network: string;
@ -306,16 +306,11 @@ export class RestClient {
* Depending on the RestClient's broadcast mode, this might or might
* wait for checkTx or deliverTx to be executed before returning.
*
* @param tx must be JSON encoded StdTx (no wrapper)
* @param tx a signed transaction as StdTx (i.e. not wrapped in type/value container)
*/
public async postTx(tx: Uint8Array): Promise<PostTxsResponse> {
// TODO: check this is StdTx
const decoded = JSON.parse(fromUtf8(tx));
if (!isStdTx(decoded)) {
throw new Error("Must be json encoded StdTx");
}
public async postTx(tx: StdTx): Promise<PostTxsResponse> {
const params = {
tx: decoded,
tx: tx,
mode: this.mode,
};
const responseData = await this.post("/txs", params);

View File

@ -3,7 +3,7 @@ import { Encoding } from "@iov/encoding";
import pako from "pako";
import { CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient";
import { makeSignBytes, marshalTx } from "./encoding";
import { makeSignBytes } from "./encoding";
import { findAttribute, Log } from "./logs";
import { BroadcastMode } from "./restclient";
import {
@ -120,7 +120,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
signatures: [signature],
};
const result = await this.postTx(marshalTx(signedTx));
const result = await this.postTx(signedTx);
const codeIdAttr = findAttribute(result.logs, "message", "code_id");
return {
originalSize: wasmCode.length,
@ -162,7 +162,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
signatures: [signature],
};
const result = await this.postTx(marshalTx(signedTx));
const result = await this.postTx(signedTx);
const contractAddressAttr = findAttribute(result.logs, "message", "contract_address");
return contractAddressAttr.value;
}
@ -195,7 +195,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
signatures: [signature],
};
const result = await this.postTx(marshalTx(signedTx));
const result = await this.postTx(signedTx);
return {
logs: result.logs,
};
@ -228,6 +228,6 @@ export class SigningCosmWasmClient extends CosmWasmClient {
signatures: [signature],
};
return this.postTx(marshalTx(signedTx));
return this.postTx(signedTx);
}
}

View File

@ -1,6 +1,6 @@
import { Log } from "./logs";
import { BlockResponse, BroadcastMode, RestClient, TxsResponse } from "./restclient";
import { CosmosSdkAccount, CosmosSdkTx } from "./types";
import { CosmosSdkAccount, CosmosSdkTx, StdTx } from "./types";
export interface GetNonceResult {
readonly accountNumber: number;
readonly sequence: number;
@ -45,7 +45,7 @@ export declare class CosmWasmClient {
*/
getBlock(height?: number): Promise<BlockResponse>;
searchTx(query: SearchTxQuery): Promise<readonly TxsResponse[]>;
postTx(tx: Uint8Array): Promise<PostTxResult>;
postTx(tx: StdTx): Promise<PostTxResult>;
/**
* Returns the data at the key if present (raw contract dependent storage data)
* or null if no data at this key.

View File

@ -1,4 +1,4 @@
import { CodeInfo, ContractInfo, CosmosSdkAccount, CosmosSdkTx, Model } from "./types";
import { CodeInfo, ContractInfo, CosmosSdkAccount, CosmosSdkTx, Model, StdTx } from "./types";
interface NodeInfo {
readonly network: string;
}
@ -137,9 +137,9 @@ export declare class RestClient {
* Depending on the RestClient's broadcast mode, this might or might
* wait for checkTx or deliverTx to be executed before returning.
*
* @param tx must be JSON encoded StdTx (no wrapper)
* @param tx a signed transaction as StdTx (i.e. not wrapped in type/value container)
*/
postTx(tx: Uint8Array): Promise<PostTxsResponse>;
postTx(tx: StdTx): Promise<PostTxsResponse>;
listCodeInfo(): Promise<readonly CodeInfo[]>;
getCode(id: number): Promise<Uint8Array>;
listContractAddresses(): Promise<readonly string[]>;