From 343f775099c643013542decd16ce4a784ea5f900 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 26 Jul 2021 14:49:07 +0200 Subject: [PATCH] Let makeAuthInfoBytes support different sequences for signers --- CHANGELOG.md | 2 ++ .../src/cosmwasmclient.searchtx.spec.ts | 2 +- .../src/cosmwasmclient.spec.ts | 4 ++-- .../src/signingcosmwasmclient.ts | 5 ++--- .../cosmwasm-stargate/src/testutils.spec.ts | 9 ++++---- .../src/directsecp256k1hdwallet.spec.ts | 2 +- .../src/directsecp256k1wallet.spec.ts | 2 +- packages/proto-signing/src/signing.ts | 21 +++++++++++++------ .../stargate/src/signingstargateclient.ts | 5 ++--- .../src/stargateclient.searchtx.spec.ts | 2 +- packages/stargate/src/stargateclient.spec.ts | 8 +++---- packages/stargate/src/testutils.spec.ts | 9 ++++---- 12 files changed, 41 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00d536e0..04645cf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,8 @@ and this project adheres to - @cosmjs/tendermint-rpc: Make `tendermint34.Header.lastBlockId` and `tendermint34.Block.lastCommit` optional to better handle the case of height 1 where there is no previous block. +- @cosmjs/proto-signing: `makeAuthInfoBytes` now takes an array of pubkey + sequence pairs in order to support different sequences for different signers. ### Removed diff --git a/packages/cosmwasm-stargate/src/cosmwasmclient.searchtx.spec.ts b/packages/cosmwasm-stargate/src/cosmwasmclient.searchtx.spec.ts index 065013fc..bddacdd8 100644 --- a/packages/cosmwasm-stargate/src/cosmwasmclient.searchtx.spec.ts +++ b/packages/cosmwasm-stargate/src/cosmwasmclient.searchtx.spec.ts @@ -79,7 +79,7 @@ async function sendTokens( }, ]; const gasLimit = 200000; - const authInfoBytes = makeAuthInfoBytes([pubkey], feeAmount, gasLimit, sequence); + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], feeAmount, gasLimit); const chainId = await client.getChainId(); const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); diff --git a/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts b/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts index 18674f7e..e325382c 100644 --- a/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts +++ b/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts @@ -193,7 +193,7 @@ describe("CosmWasmClient", () => { const sequenceResponse = await client.getSequence(alice.address0); assert(sequenceResponse); const { accountNumber, sequence } = sequenceResponse; - const pubkeyAny = encodePubkey(alice.pubkey0); + const pubkey = encodePubkey(alice.pubkey0); const txBody: TxBodyEncodeObject = { typeUrl: "/cosmos.tx.v1beta1.TxBody", value: { @@ -203,7 +203,7 @@ describe("CosmWasmClient", () => { }; const txBodyBytes = registry.encode(txBody); const gasLimit = Int53.fromString(fee.gas).toNumber(); - const authInfoBytes = makeAuthInfoBytes([pubkeyAny], fee.amount, gasLimit, sequence); + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], fee.amount, gasLimit); const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); const { signed, signature } = await wallet.signDirect(alice.address0, signDoc); const txRaw = TxRaw.fromPartial({ diff --git a/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts b/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts index f02a4f84..2139296d 100644 --- a/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts +++ b/packages/cosmwasm-stargate/src/signingcosmwasmclient.ts @@ -527,10 +527,9 @@ export class SigningCosmWasmClient extends CosmWasmClient { const signedGasLimit = Int53.fromString(signed.fee.gas).toNumber(); const signedSequence = Int53.fromString(signed.sequence).toNumber(); const signedAuthInfoBytes = makeAuthInfoBytes( - [pubkey], + [{ pubkey, sequence: signedSequence }], signed.fee.amount, signedGasLimit, - signedSequence, signMode, ); return TxRaw.fromPartial({ @@ -564,7 +563,7 @@ export class SigningCosmWasmClient extends CosmWasmClient { }; const txBodyBytes = this.registry.encode(txBody); const gasLimit = Int53.fromString(fee.gas).toNumber(); - const authInfoBytes = makeAuthInfoBytes([pubkey], fee.amount, gasLimit, sequence); + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], fee.amount, gasLimit); const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); const { signature, signed } = await this.signer.signDirect(signerAddress, signDoc); return TxRaw.fromPartial({ diff --git a/packages/cosmwasm-stargate/src/testutils.spec.ts b/packages/cosmwasm-stargate/src/testutils.spec.ts index 66aba2c3..d2c48771 100644 --- a/packages/cosmwasm-stargate/src/testutils.spec.ts +++ b/packages/cosmwasm-stargate/src/testutils.spec.ts @@ -252,18 +252,19 @@ export class ModifyingDirectSecp256k1HdWallet extends DirectSecp256k1HdWallet { memo: "This was modified", }); const authInfo = AuthInfo.decode(signDoc.authInfoBytes); - const pubkeys = authInfo.signerInfos.map((signerInfo) => signerInfo.publicKey!); - const sequence = authInfo.signerInfos[0].sequence.toNumber(); + const signers = authInfo.signerInfos.map((signerInfo) => ({ + pubkey: signerInfo.publicKey!, + sequence: signerInfo.sequence.toNumber(), + })); const modifiedFeeAmount = coins(3000, "ucosm"); const modifiedGasLimit = 333333; const modifiedSignDoc = { ...signDoc, bodyBytes: Uint8Array.from(TxBody.encode(modifiedTxBody).finish()), authInfoBytes: makeAuthInfoBytes( - pubkeys, + signers, modifiedFeeAmount, modifiedGasLimit, - sequence, SignMode.SIGN_MODE_DIRECT, ), }; diff --git a/packages/proto-signing/src/directsecp256k1hdwallet.spec.ts b/packages/proto-signing/src/directsecp256k1hdwallet.spec.ts index 2800ec97..0b9122f3 100644 --- a/packages/proto-signing/src/directsecp256k1hdwallet.spec.ts +++ b/packages/proto-signing/src/directsecp256k1hdwallet.spec.ts @@ -264,7 +264,7 @@ describe("DirectSecp256k1HdWallet", () => { const chainId = "simd-testing"; const signDoc = makeSignDoc( fromHex(bodyBytes), - makeAuthInfoBytes([pubkey], fee, gasLimit, sequence), + makeAuthInfoBytes([{ pubkey, sequence }], fee, gasLimit), chainId, accountNumber, ); diff --git a/packages/proto-signing/src/directsecp256k1wallet.spec.ts b/packages/proto-signing/src/directsecp256k1wallet.spec.ts index 933403e8..ab42c726 100644 --- a/packages/proto-signing/src/directsecp256k1wallet.spec.ts +++ b/packages/proto-signing/src/directsecp256k1wallet.spec.ts @@ -46,7 +46,7 @@ describe("DirectSecp256k1Wallet", () => { const chainId = "simd-testing"; const signDoc = makeSignDoc( fromHex(bodyBytes), - makeAuthInfoBytes([pubkey], fee, gasLimit, sequence), + makeAuthInfoBytes([{ pubkey, sequence }], fee, gasLimit), chainId, accountNumber, ); diff --git a/packages/proto-signing/src/signing.ts b/packages/proto-signing/src/signing.ts index 849f7639..73dec600 100644 --- a/packages/proto-signing/src/signing.ts +++ b/packages/proto-signing/src/signing.ts @@ -5,9 +5,17 @@ import { AuthInfo, SignDoc, SignerInfo } from "cosmjs-types/cosmos/tx/v1beta1/tx import { Any } from "cosmjs-types/google/protobuf/any"; import Long from "long"; -function makeSignerInfos(pubkeys: readonly Any[], sequence: number, signMode: SignMode): SignerInfo[] { - return pubkeys.map( - (pubkey): SignerInfo => ({ +/** + * Create signer infos from the provided signers. + * + * This implementation does not support different signing modes for the different signers. + */ +function makeSignerInfos( + signers: ReadonlyArray<{ readonly pubkey: Any; readonly sequence: number }>, + signMode: SignMode, +): SignerInfo[] { + return signers.map( + ({ pubkey, sequence }): SignerInfo => ({ publicKey: pubkey, modeInfo: { single: { mode: signMode }, @@ -19,16 +27,17 @@ function makeSignerInfos(pubkeys: readonly Any[], sequence: number, signMode: Si /** * Creates and serializes an AuthInfo document. + * + * This implementation does not support different signing modes for the different signers. */ export function makeAuthInfoBytes( - pubkeys: readonly Any[], + signers: ReadonlyArray<{ readonly pubkey: Any; readonly sequence: number }>, feeAmount: readonly Coin[], gasLimit: number, - sequence: number, signMode = SignMode.SIGN_MODE_DIRECT, ): Uint8Array { const authInfo = { - signerInfos: makeSignerInfos(pubkeys, sequence, signMode), + signerInfos: makeSignerInfos(signers, signMode), fee: { amount: [...feeAmount], gasLimit: Long.fromNumber(gasLimit), diff --git a/packages/stargate/src/signingstargateclient.ts b/packages/stargate/src/signingstargateclient.ts index 9010372a..e1853d4c 100644 --- a/packages/stargate/src/signingstargateclient.ts +++ b/packages/stargate/src/signingstargateclient.ts @@ -354,10 +354,9 @@ export class SigningStargateClient extends StargateClient { const signedGasLimit = Int53.fromString(signed.fee.gas).toNumber(); const signedSequence = Int53.fromString(signed.sequence).toNumber(); const signedAuthInfoBytes = makeAuthInfoBytes( - [pubkey], + [{ pubkey, sequence: signedSequence }], signed.fee.amount, signedGasLimit, - signedSequence, signMode, ); return TxRaw.fromPartial({ @@ -391,7 +390,7 @@ export class SigningStargateClient extends StargateClient { }; const txBodyBytes = this.registry.encode(txBodyEncodeObject); const gasLimit = Int53.fromString(fee.gas).toNumber(); - const authInfoBytes = makeAuthInfoBytes([pubkey], fee.amount, gasLimit, sequence); + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], fee.amount, gasLimit); const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); const { signature, signed } = await this.signer.signDirect(signerAddress, signDoc); return TxRaw.fromPartial({ diff --git a/packages/stargate/src/stargateclient.searchtx.spec.ts b/packages/stargate/src/stargateclient.searchtx.spec.ts index 229b0d97..50b4b110 100644 --- a/packages/stargate/src/stargateclient.searchtx.spec.ts +++ b/packages/stargate/src/stargateclient.searchtx.spec.ts @@ -78,7 +78,7 @@ async function sendTokens( }, ]; const gasLimit = 200000; - const authInfoBytes = makeAuthInfoBytes([pubkey], feeAmount, gasLimit, sequence); + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], feeAmount, gasLimit); const chainId = await client.getChainId(); const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); diff --git a/packages/stargate/src/stargateclient.spec.ts b/packages/stargate/src/stargateclient.spec.ts index 5ae8cf53..54455e9a 100644 --- a/packages/stargate/src/stargateclient.spec.ts +++ b/packages/stargate/src/stargateclient.spec.ts @@ -315,7 +315,7 @@ describe("StargateClient", () => { const { accountNumber, sequence } = (await client.getSequence(address))!; const feeAmount = coins(2000, "ucosm"); const gasLimit = 200000; - const authInfoBytes = makeAuthInfoBytes([pubkey], feeAmount, gasLimit, sequence); + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], feeAmount, gasLimit); const chainId = await client.getChainId(); const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); @@ -372,7 +372,7 @@ describe("StargateClient", () => { const { accountNumber, sequence } = (await client.getSequence(address))!; const feeAmount = coins(2000, "ucosm"); const gasLimit = 200000; - const authInfoBytes = makeAuthInfoBytes([pubkey], feeAmount, gasLimit, sequence); + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], feeAmount, gasLimit, sequence); const chainId = await client.getChainId(); const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); @@ -425,7 +425,7 @@ describe("StargateClient", () => { const gasLimit = 200000; const { accountNumber: accountNumber1, sequence: sequence1 } = (await client.getSequence(address))!; - const authInfoBytes1 = makeAuthInfoBytes([pubkey], feeAmount, gasLimit, sequence1); + const authInfoBytes1 = makeAuthInfoBytes([{ pubkey, sequence: sequence1 }], feeAmount, gasLimit); const signDoc1 = makeSignDoc(txBodyBytes, authInfoBytes1, chainId, accountNumber1); const { signature: signature1 } = await wallet.signDirect(address, signDoc1); const txRaw1 = TxRaw.fromPartial({ @@ -439,7 +439,7 @@ describe("StargateClient", () => { assertIsBroadcastTxSuccess(txResult); const { accountNumber: accountNumber2, sequence: sequence2 } = (await client.getSequence(address))!; - const authInfoBytes2 = makeAuthInfoBytes([pubkey], feeAmount, gasLimit, sequence2); + const authInfoBytes2 = makeAuthInfoBytes([{ pubkey, sequence: sequence2 }], feeAmount, gasLimit); const signDoc2 = makeSignDoc(txBodyBytes, authInfoBytes2, chainId, accountNumber2); const { signature: signature2 } = await wallet.signDirect(address, signDoc2); const txRaw2 = TxRaw.fromPartial({ diff --git a/packages/stargate/src/testutils.spec.ts b/packages/stargate/src/testutils.spec.ts index dc7e973b..1a463115 100644 --- a/packages/stargate/src/testutils.spec.ts +++ b/packages/stargate/src/testutils.spec.ts @@ -199,18 +199,19 @@ export class ModifyingDirectSecp256k1HdWallet extends DirectSecp256k1HdWallet { memo: "This was modified", }); const authInfo = AuthInfo.decode(signDoc.authInfoBytes); - const pubkeys = authInfo.signerInfos.map((signerInfo) => signerInfo.publicKey!); - const sequence = authInfo.signerInfos[0].sequence.toNumber(); + const signers = authInfo.signerInfos.map((signerInfo) => ({ + pubkey: signerInfo.publicKey!, + sequence: signerInfo.sequence.toNumber(), + })); const modifiedFeeAmount = coins(3000, "ucosm"); const modifiedGasLimit = 333333; const modifiedSignDoc = { ...signDoc, bodyBytes: Uint8Array.from(TxBody.encode(modifiedTxBody).finish()), authInfoBytes: makeAuthInfoBytes( - pubkeys, + signers, modifiedFeeAmount, modifiedGasLimit, - sequence, SignMode.SIGN_MODE_DIRECT, ), };