Update TxBuilder to use SignatureV2 (#6443)
* Update TxBuilder to use SignatureV2 * Fix unit tests * Lint * lint * Cleanup * Address review feedback * Add Sign tests * Add more cases for sign tests * Fix lint * Fix gofmt * Deprecate StdTx * Undeprecate StdTx, but leave a comment to use the protobuf Tx * Address review comment Co-authored-by: anilCSE <anil@vitwit.com>
This commit is contained in:
parent
c134e8974e
commit
c13809062a
|
@ -123,6 +123,7 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa
|
|||
* (modules) [\#6326](https://github.com/cosmos/cosmos-sdk/pull/6326) `AppModuleBasic.GetQueryCmd` now takes a single `CLIContext` parameter.
|
||||
* (modules) [\#6336](https://github.com/cosmos/cosmos-sdk/pull/6336) `AppModuleBasic.RegisterQueryService` method was added to support gRPC queries, and `QuerierRoute` and `NewQuerierHandler` were deprecated.
|
||||
* (modules) [\#6311](https://github.com/cosmos/cosmos-sdk/issues/6311) Remove `alias.go` usage
|
||||
* (x/auth) [\#6443](https://github.com/cosmos/cosmos-sdk/issues/6443) Move `FeeTx` and `TxWithMemo` interfaces from `x/auth/ante` to `types`.
|
||||
|
||||
Migration guide:
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ const (
|
|||
FlagKeyringBackend = "keyring-backend"
|
||||
FlagPage = "page"
|
||||
FlagLimit = "limit"
|
||||
FlagSignMode = "sign-mode"
|
||||
)
|
||||
|
||||
// LineBreak can be included in a command list to provide a blank line
|
||||
|
@ -116,6 +117,7 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command {
|
|||
c.Flags().Bool(FlagOffline, false, "Offline mode (does not allow any online functionality")
|
||||
c.Flags().BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")
|
||||
c.Flags().String(FlagKeyringBackend, DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)")
|
||||
c.Flags().String(FlagSignMode, "", "Choose sign mode (direct|amino-json), this is an advanced feature")
|
||||
|
||||
// --gas can accept integers and "simulate"
|
||||
c.Flags().Var(&GasFlagVar, "gas", fmt.Sprintf(
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
)
|
||||
|
||||
// Factory defines a client transaction factory that facilitates generating and
|
||||
|
@ -21,13 +22,19 @@ type Factory struct {
|
|||
sequence uint64
|
||||
gas uint64
|
||||
gasAdjustment float64
|
||||
simulateAndExecute bool
|
||||
chainID string
|
||||
memo string
|
||||
fees sdk.Coins
|
||||
gasPrices sdk.DecCoins
|
||||
signMode signing.SignMode
|
||||
simulateAndExecute bool
|
||||
}
|
||||
|
||||
const (
|
||||
signModeDirect = "direct"
|
||||
signModeAminoJSON = "amino-json"
|
||||
)
|
||||
|
||||
func NewFactoryFromCLI(input io.Reader) Factory {
|
||||
kb, err := keyring.New(
|
||||
sdk.KeyringServiceName(),
|
||||
|
@ -39,6 +46,15 @@ func NewFactoryFromCLI(input io.Reader) Factory {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
signModeStr := viper.GetString(flags.FlagSignMode)
|
||||
signMode := signing.SignMode_SIGN_MODE_UNSPECIFIED
|
||||
switch signModeStr {
|
||||
case signModeDirect:
|
||||
signMode = signing.SignMode_SIGN_MODE_DIRECT
|
||||
case signModeAminoJSON:
|
||||
signMode = signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON
|
||||
}
|
||||
|
||||
f := Factory{
|
||||
keybase: kb,
|
||||
accountNumber: viper.GetUint64(flags.FlagAccountNumber),
|
||||
|
@ -48,6 +64,7 @@ func NewFactoryFromCLI(input io.Reader) Factory {
|
|||
simulateAndExecute: flags.GasFlagVar.Simulate,
|
||||
chainID: viper.GetString(flags.FlagChainID),
|
||||
memo: viper.GetString(flags.FlagMemo),
|
||||
signMode: signMode,
|
||||
}
|
||||
|
||||
f = f.WithFees(viper.GetString(flags.FlagFees))
|
||||
|
|
|
@ -13,10 +13,11 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
)
|
||||
|
||||
// GenerateOrBroadcastTx will either generate and print and unsigned transaction
|
||||
|
@ -108,7 +109,12 @@ func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error {
|
|||
}
|
||||
}
|
||||
|
||||
txBytes, err := Sign(txf, clientCtx.GetFromName(), clientkeys.DefaultKeyPass, tx)
|
||||
err = Sign(txf, clientCtx.GetFromName(), tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txBytes, err := clientCtx.TxGenerator.MarshalTx(tx.GetTx())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -209,24 +215,14 @@ func BuildUnsignedTx(txf Factory, msgs ...sdk.Msg) (client.TxBuilder, error) {
|
|||
}
|
||||
}
|
||||
|
||||
clientFee := txf.txGenerator.NewFee()
|
||||
clientFee.SetAmount(fees)
|
||||
clientFee.SetGas(txf.gas)
|
||||
|
||||
tx := txf.txGenerator.NewTx()
|
||||
tx.SetMemo(txf.memo)
|
||||
|
||||
if err := tx.SetFee(clientFee); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := tx.SetSignatures(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tx := txf.txGenerator.NewTxBuilder()
|
||||
|
||||
if err := tx.SetMsgs(msgs...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tx.SetMemo(txf.memo)
|
||||
tx.SetFeeAmount(fees)
|
||||
tx.SetGasLimit(txf.gas)
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
|
@ -242,7 +238,7 @@ func BuildSimTx(txf Factory, msgs ...sdk.Msg) ([]byte, error) {
|
|||
|
||||
// Create an empty signature literal as the ante handler will populate with a
|
||||
// sentinel pubkey.
|
||||
sig := txf.txGenerator.NewSignature()
|
||||
sig := signing.SignatureV2{}
|
||||
|
||||
if err := tx.SetSignatures(sig); err != nil {
|
||||
return nil, err
|
||||
|
@ -312,33 +308,60 @@ func PrepareFactory(clientCtx client.Context, txf Factory) (Factory, error) {
|
|||
//
|
||||
// Note, It is assumed the Factory has the necessary fields set that are required
|
||||
// by the CanonicalSignBytes call.
|
||||
func Sign(txf Factory, name, passphrase string, tx client.TxBuilder) ([]byte, error) {
|
||||
func Sign(txf Factory, name string, tx client.TxBuilder) error {
|
||||
if txf.keybase == nil {
|
||||
return nil, errors.New("keybase must be set prior to signing a transaction")
|
||||
return errors.New("keybase must be set prior to signing a transaction")
|
||||
}
|
||||
|
||||
signBytes, err := tx.CanonicalSignBytes(txf.chainID, txf.accountNumber, txf.sequence)
|
||||
signMode := txf.signMode
|
||||
if signMode == signing.SignMode_SIGN_MODE_UNSPECIFIED {
|
||||
// use the SignModeHandler's default mode if unspecified
|
||||
signMode = txf.txGenerator.SignModeHandler().DefaultMode()
|
||||
}
|
||||
|
||||
key, err := txf.keybase.Key(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
sigBytes, pubkey, err := txf.keybase.Sign(name, signBytes)
|
||||
pubKey := key.GetPubKey()
|
||||
sigData := &signing.SingleSignatureData{
|
||||
SignMode: signMode,
|
||||
Signature: nil,
|
||||
}
|
||||
sig := signing.SignatureV2{
|
||||
PubKey: pubKey,
|
||||
Data: sigData,
|
||||
}
|
||||
err = tx.SetSignatures(sig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
sig := txf.txGenerator.NewSignature()
|
||||
sig.SetSignature(sigBytes)
|
||||
|
||||
if err := sig.SetPubKey(pubkey); err != nil {
|
||||
return nil, err
|
||||
signBytes, err := txf.txGenerator.SignModeHandler().GetSignBytes(
|
||||
signMode,
|
||||
authsigning.SignerData{
|
||||
ChainID: txf.chainID,
|
||||
AccountNumber: txf.accountNumber,
|
||||
AccountSequence: txf.sequence,
|
||||
}, tx.GetTx(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.SetSignatures(sig); err != nil {
|
||||
return nil, err
|
||||
sigBytes, _, err := txf.keybase.Sign(name, signBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return txf.txGenerator.MarshalTx(tx.GetTx())
|
||||
sigData.Signature = sigBytes
|
||||
sig = signing.SignatureV2{
|
||||
PubKey: pubKey,
|
||||
Data: sigData,
|
||||
}
|
||||
|
||||
return tx.SetSignatures(sig)
|
||||
}
|
||||
|
||||
// GasEstimateResponse defines a response definition for tx gas estimation.
|
||||
|
|
|
@ -4,6 +4,12 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
|
@ -105,5 +111,56 @@ func TestBuildUnsignedTx(t *testing.T) {
|
|||
tx, err := tx.BuildUnsignedTx(txf, msg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, tx)
|
||||
require.Equal(t, []sdk.Signature{}, tx.GetSignatures())
|
||||
require.Empty(t, tx.GetTx().(ante.SigVerifiableTx).GetSignatures())
|
||||
}
|
||||
|
||||
func TestSign(t *testing.T) {
|
||||
dir, clean := tests.NewTestCaseDir(t)
|
||||
t.Cleanup(clean)
|
||||
|
||||
path := hd.CreateHDPath(118, 0, 0).String()
|
||||
kr, err := keyring.New(t.Name(), "test", dir, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
var from = "test_sign"
|
||||
|
||||
_, seed, err := kr.NewMnemonic(from, keyring.English, path, hd.Secp256k1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, kr.Delete(from))
|
||||
|
||||
info, err := kr.NewAccount(from, seed, "", path, hd.Secp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
txf := tx.Factory{}.
|
||||
WithTxGenerator(NewTestTxGenerator()).
|
||||
WithAccountNumber(50).
|
||||
WithSequence(23).
|
||||
WithFees("50stake").
|
||||
WithMemo("memo").
|
||||
WithChainID("test-chain")
|
||||
|
||||
msg := banktypes.NewMsgSend(info.GetAddress(), sdk.AccAddress("to"), nil)
|
||||
txn, err := tx.BuildUnsignedTx(txf, msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Log("should failed if txf without keyring")
|
||||
err = tx.Sign(txf, from, txn)
|
||||
require.Error(t, err)
|
||||
|
||||
txf = tx.Factory{}.
|
||||
WithKeybase(kr).
|
||||
WithTxGenerator(NewTestTxGenerator()).
|
||||
WithAccountNumber(50).
|
||||
WithSequence(23).
|
||||
WithFees("50stake").
|
||||
WithMemo("memo").
|
||||
WithChainID("test-chain")
|
||||
|
||||
t.Log("should succeed if txf with keyring")
|
||||
err = tx.Sign(txf, from, txn)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Log("should fail for non existing key")
|
||||
err = tx.Sign(txf, "non_existing_key", txn)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -11,22 +11,9 @@ type (
|
|||
// application-defined concrete transaction type. The type returned must
|
||||
// implement TxBuilder.
|
||||
TxGenerator interface {
|
||||
NewTx() TxBuilder
|
||||
NewFee() Fee
|
||||
NewSignature() Signature
|
||||
MarshalTx(tx types.Tx) ([]byte, error)
|
||||
}
|
||||
|
||||
Fee interface {
|
||||
types.Fee
|
||||
SetGas(uint64)
|
||||
SetAmount(types.Coins)
|
||||
}
|
||||
|
||||
Signature interface {
|
||||
types.Signature
|
||||
SetPubKey(crypto.PubKey) error
|
||||
SetSignature([]byte)
|
||||
NewTxBuilder() TxBuilder
|
||||
SignModeHandler() signing.SignModeHandler
|
||||
MarshalTx(tx sdk.Tx) ([]byte, error)
|
||||
}
|
||||
|
||||
// TxBuilder defines an interface which an application-defined concrete transaction
|
||||
|
@ -34,18 +21,12 @@ type (
|
|||
// signatures, and provide canonical bytes to sign over. The transaction must
|
||||
// also know how to encode itself.
|
||||
TxBuilder interface {
|
||||
GetTx() types.Tx
|
||||
GetTx() sdk.Tx
|
||||
|
||||
SetMsgs(...types.Msg) error
|
||||
GetSignatures() []types.Signature
|
||||
SetSignatures(...Signature) error
|
||||
GetFee() types.Fee
|
||||
SetFee(Fee) error
|
||||
GetMemo() string
|
||||
SetMemo(string)
|
||||
|
||||
// CanonicalSignBytes returns the canonical sign bytes to sign over, given a
|
||||
// chain ID, along with an account and sequence number.
|
||||
CanonicalSignBytes(cid string, num, seq uint64) ([]byte, error)
|
||||
SetMsgs(msgs ...sdk.Msg) error
|
||||
SetSignatures(signatures ...signingtypes.SignatureV2) error
|
||||
SetMemo(memo string)
|
||||
SetFeeAmount(amount sdk.Coins)
|
||||
SetGasLimit(limit uint64)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -57,6 +57,20 @@ type (
|
|||
// require access to any other information.
|
||||
ValidateBasic() error
|
||||
}
|
||||
|
||||
// FeeTx defines the interface to be implemented by Tx to use the FeeDecorators
|
||||
FeeTx interface {
|
||||
Tx
|
||||
GetGas() uint64
|
||||
GetFee() Coins
|
||||
FeePayer() AccAddress
|
||||
}
|
||||
|
||||
// Tx must have GetMemo() method to use ValidateMemoDecorator
|
||||
TxWithMemo interface {
|
||||
Tx
|
||||
GetMemo() string
|
||||
}
|
||||
)
|
||||
|
||||
// TxDecoder unmarshals transaction bytes
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
_ TxWithMemo = (*types.StdTx)(nil) // assert StdTx implements TxWithMemo
|
||||
_ sdk.TxWithMemo = (*types.StdTx)(nil) // assert StdTx implements TxWithMemo
|
||||
)
|
||||
|
||||
// ValidateBasicDecorator will call tx.ValidateBasic and return any non-nil error.
|
||||
|
@ -37,12 +37,6 @@ func (vbd ValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulat
|
|||
return next(ctx, tx, simulate)
|
||||
}
|
||||
|
||||
// Tx must have GetMemo() method to use ValidateMemoDecorator
|
||||
type TxWithMemo interface {
|
||||
sdk.Tx
|
||||
GetMemo() string
|
||||
}
|
||||
|
||||
// ValidateMemoDecorator will validate memo given the parameters passed in
|
||||
// If memo is too large decorator returns with error, otherwise call next AnteHandler
|
||||
// CONTRACT: Tx must implement TxWithMemo interface
|
||||
|
@ -57,7 +51,7 @@ func NewValidateMemoDecorator(ak AccountKeeper) ValidateMemoDecorator {
|
|||
}
|
||||
|
||||
func (vmd ValidateMemoDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
||||
memoTx, ok := tx.(TxWithMemo)
|
||||
memoTx, ok := tx.(sdk.TxWithMemo)
|
||||
if !ok {
|
||||
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type")
|
||||
}
|
||||
|
|
|
@ -9,17 +9,9 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
_ FeeTx = (*types.StdTx)(nil) // assert StdTx implements FeeTx
|
||||
_ sdk.FeeTx = (*types.StdTx)(nil) // assert StdTx implements FeeTx
|
||||
)
|
||||
|
||||
// FeeTx defines the interface to be implemented by Tx to use the FeeDecorators
|
||||
type FeeTx interface {
|
||||
sdk.Tx
|
||||
GetGas() uint64
|
||||
GetFee() sdk.Coins
|
||||
FeePayer() sdk.AccAddress
|
||||
}
|
||||
|
||||
// MempoolFeeDecorator will check if the transaction's fee is at least as large
|
||||
// as the local validator's minimum gasFee (defined in validator config).
|
||||
// If fee is too low, decorator returns error and tx is rejected from mempool.
|
||||
|
@ -33,7 +25,7 @@ func NewMempoolFeeDecorator() MempoolFeeDecorator {
|
|||
}
|
||||
|
||||
func (mfd MempoolFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||
feeTx, ok := tx.(FeeTx)
|
||||
feeTx, ok := tx.(sdk.FeeTx)
|
||||
if !ok {
|
||||
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
|
||||
}
|
||||
|
@ -82,7 +74,7 @@ func NewDeductFeeDecorator(ak AccountKeeper, bk types.BankKeeper) DeductFeeDecor
|
|||
}
|
||||
|
||||
func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||
feeTx, ok := tx.(FeeTx)
|
||||
feeTx, ok := tx.(sdk.FeeTx)
|
||||
if !ok {
|
||||
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing/amino"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
@ -19,7 +18,7 @@ func MakeTestHandlerMap() signing.SignModeHandler {
|
|||
return signing.NewSignModeHandlerMap(
|
||||
signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||
[]signing.SignModeHandler{
|
||||
amino.LegacyAminoJSONHandler{},
|
||||
authtypes.LegacyAminoJSONHandler{},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -59,7 +58,7 @@ func TestHandlerMap_GetSignBytes(t *testing.T) {
|
|||
)
|
||||
|
||||
handler := MakeTestHandlerMap()
|
||||
aminoJSONHandler := amino.LegacyAminoJSONHandler{}
|
||||
aminoJSONHandler := authtypes.LegacyAminoJSONHandler{}
|
||||
|
||||
signingData := signing.SignerData{
|
||||
ChainID: chainId,
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
package amino
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
|
||||
// LegacyAminoJSONHandler is a SignModeHandler that handles SIGN_MODE_LEGACY_AMINO_JSON
|
||||
|
@ -31,17 +29,17 @@ func (LegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode, data sign
|
|||
return nil, fmt.Errorf("expected %s, got %s", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, mode)
|
||||
}
|
||||
|
||||
feeTx, ok := tx.(ante.FeeTx)
|
||||
feeTx, ok := tx.(sdk.FeeTx)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected FeeTx, got %T", tx)
|
||||
}
|
||||
|
||||
memoTx, ok := tx.(ante.TxWithMemo)
|
||||
memoTx, ok := tx.(sdk.TxWithMemo)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected TxWithMemo, got %T", tx)
|
||||
}
|
||||
|
||||
return authtypes.StdSignBytes(
|
||||
data.ChainID, data.AccountNumber, data.AccountSequence, authtypes.StdFee{Amount: feeTx.GetFee(), Gas: feeTx.GetGas()}, tx.GetMsgs(), memoTx.GetMemo(), // nolint:staticcheck // SA1019: authtypes.StdFee is deprecated, will be removed once proto migration is completed
|
||||
return StdSignBytes(
|
||||
data.ChainID, data.AccountNumber, data.AccountSequence, StdFee{Amount: feeTx.GetFee(), Gas: feeTx.GetGas()}, tx.GetMsgs(), memoTx.GetMemo(),
|
||||
), nil
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
package amino_test
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
@ -11,7 +13,6 @@ import (
|
|||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing/amino"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
|
@ -49,7 +50,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) {
|
|||
seqNum uint64 = 7
|
||||
)
|
||||
|
||||
handler := amino.LegacyAminoJSONHandler{}
|
||||
handler := types.LegacyAminoJSONHandler{}
|
||||
signingData := signing.SignerData{
|
||||
ChainID: chainId,
|
||||
AccountNumber: accNum,
|
||||
|
@ -68,11 +69,11 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLegacyAminoJSONHandler_DefaultMode(t *testing.T) {
|
||||
handler := amino.LegacyAminoJSONHandler{}
|
||||
handler := types.LegacyAminoJSONHandler{}
|
||||
require.Equal(t, signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, handler.DefaultMode())
|
||||
}
|
||||
|
||||
func TestLegacyAminoJSONHandler_Modes(t *testing.T) {
|
||||
handler := amino.LegacyAminoJSONHandler{}
|
||||
handler := types.LegacyAminoJSONHandler{}
|
||||
require.Equal(t, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON}, handler.Modes())
|
||||
}
|
|
@ -1,16 +1,20 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
)
|
||||
|
||||
// StdTxBuilder wraps StdTx to implement to the context.TxBuilder interface
|
||||
// StdTxBuilder wraps StdTx to implement to the context.TxBuilder interface.
|
||||
// Note that this type just exists for backwards compatibility with amino StdTx
|
||||
// and will not work for protobuf transactions.
|
||||
type StdTxBuilder struct {
|
||||
StdTx
|
||||
cdc *codec.Codec
|
||||
}
|
||||
|
||||
var _ client.TxBuilder = &StdTxBuilder{}
|
||||
|
@ -26,42 +30,40 @@ func (s *StdTxBuilder) SetMsgs(msgs ...sdk.Msg) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetSignatures implements TxBuilder.GetSignatures
|
||||
func (s StdTxBuilder) GetSignatures() []sdk.Signature {
|
||||
res := make([]sdk.Signature, len(s.Signatures))
|
||||
for i, sig := range s.Signatures {
|
||||
res[i] = sig
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// SetSignatures implements TxBuilder.SetSignatures
|
||||
func (s *StdTxBuilder) SetSignatures(signatures ...client.Signature) error {
|
||||
func (s *StdTxBuilder) SetSignatures(signatures ...signing.SignatureV2) error {
|
||||
sigs := make([]StdSignature, len(signatures))
|
||||
for i, sig := range signatures {
|
||||
pubKey := sig.GetPubKey()
|
||||
pubKey := sig.PubKey
|
||||
var pubKeyBz []byte
|
||||
if pubKey != nil {
|
||||
pubKeyBz = pubKey.Bytes()
|
||||
}
|
||||
|
||||
var sigBz []byte
|
||||
var err error
|
||||
if sig.Data != nil {
|
||||
sigBz, err = SignatureDataToAminoSignature(legacy.Cdc, sig.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
sigs[i] = StdSignature{
|
||||
PubKey: pubKeyBz,
|
||||
Signature: sig.GetSignature(),
|
||||
Signature: sigBz,
|
||||
}
|
||||
}
|
||||
s.Signatures = sigs
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFee implements TxBuilder.GetFee
|
||||
func (s StdTxBuilder) GetFee() sdk.Fee {
|
||||
return s.Fee
|
||||
func (s *StdTxBuilder) SetFeeAmount(amount sdk.Coins) {
|
||||
s.StdTx.Fee.Amount = amount
|
||||
}
|
||||
|
||||
// SetFee implements TxBuilder.SetFee
|
||||
func (s *StdTxBuilder) SetFee(fee client.Fee) error {
|
||||
s.Fee = StdFee{Amount: fee.GetAmount(), Gas: fee.GetGas()}
|
||||
return nil
|
||||
func (s *StdTxBuilder) SetGasLimit(limit uint64) {
|
||||
s.StdTx.Fee.Gas = limit
|
||||
}
|
||||
|
||||
// SetMemo implements TxBuilder.SetMemo
|
||||
|
@ -69,11 +71,6 @@ func (s *StdTxBuilder) SetMemo(memo string) {
|
|||
s.Memo = memo
|
||||
}
|
||||
|
||||
// CanonicalSignBytes implements TxBuilder.CanonicalSignBytes
|
||||
func (s StdTxBuilder) CanonicalSignBytes(cid string, num, seq uint64) ([]byte, error) {
|
||||
return StdSignBytes(cid, num, seq, s.Fee, s.Msgs, s.Memo), nil
|
||||
}
|
||||
|
||||
// StdTxGenerator is a context.TxGenerator for StdTx
|
||||
type StdTxGenerator struct {
|
||||
Cdc *codec.Codec
|
||||
|
@ -81,19 +78,12 @@ type StdTxGenerator struct {
|
|||
|
||||
var _ client.TxGenerator = StdTxGenerator{}
|
||||
|
||||
// NewTx implements TxGenerator.NewTx
|
||||
func (s StdTxGenerator) NewTx() client.TxBuilder {
|
||||
return &StdTxBuilder{}
|
||||
}
|
||||
|
||||
// NewFee implements TxGenerator.NewFee
|
||||
func (s StdTxGenerator) NewFee() client.Fee {
|
||||
return &StdFee{}
|
||||
}
|
||||
|
||||
// NewSignature implements TxGenerator.NewSignature
|
||||
func (s StdTxGenerator) NewSignature() client.Signature {
|
||||
return &StdSignature{}
|
||||
// NewTxBuilder implements TxGenerator.NewTxBuilder
|
||||
func (s StdTxGenerator) NewTxBuilder() client.TxBuilder {
|
||||
return &StdTxBuilder{
|
||||
StdTx: StdTx{},
|
||||
cdc: s.Cdc,
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalTx implements TxGenerator.MarshalTx
|
||||
|
@ -101,27 +91,6 @@ func (s StdTxGenerator) MarshalTx(tx sdk.Tx) ([]byte, error) {
|
|||
return DefaultTxEncoder(s.Cdc)(tx)
|
||||
}
|
||||
|
||||
var _ client.Fee = &StdFee{}
|
||||
|
||||
// SetGas implements Fee.SetGas
|
||||
func (fee *StdFee) SetGas(gas uint64) {
|
||||
fee.Gas = gas
|
||||
}
|
||||
|
||||
// SetAmount implements Fee.SetAmount
|
||||
func (fee *StdFee) SetAmount(coins sdk.Coins) {
|
||||
fee.Amount = coins
|
||||
}
|
||||
|
||||
var _ client.Signature = &StdSignature{}
|
||||
|
||||
// SetPubKey implements Signature.SetPubKey
|
||||
func (ss *StdSignature) SetPubKey(key crypto.PubKey) error {
|
||||
ss.PubKey = key.Bytes()
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSignature implements Signature.SetSignature
|
||||
func (ss *StdSignature) SetSignature(bytes []byte) {
|
||||
ss.Signature = bytes
|
||||
func (s StdTxGenerator) SignModeHandler() authsigning.SignModeHandler {
|
||||
return LegacyAminoJSONHandler{}
|
||||
}
|
||||
|
|
|
@ -145,7 +145,8 @@ func CountSubKeys(pub crypto.PubKey) int {
|
|||
|
||||
var _ sdk.Tx = (*StdTx)(nil)
|
||||
|
||||
// StdTx is a standard way to wrap a Msg with Fee and Signatures.
|
||||
// StdTx is the legacy transaction format for wrapping a Msg with Fee and Signatures.
|
||||
// It only works with Amino, please prefer the new protobuf Tx in types/tx.
|
||||
// NOTE: the first signature is the fee payer (Signatures must not be nil).
|
||||
type StdTx struct {
|
||||
Msgs []sdk.Msg `json:"msg" yaml:"msg"`
|
||||
|
@ -154,6 +155,7 @@ type StdTx struct {
|
|||
Memo string `json:"memo" yaml:"memo"`
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
func NewStdTx(msgs []sdk.Msg, fee StdFee, sigs []StdSignature, memo string) StdTx {
|
||||
return StdTx{
|
||||
Msgs: msgs,
|
||||
|
|
Loading…
Reference in New Issue