refactor!: remove some legacy amino stuff needed for #11275 (#15299)

This commit is contained in:
Aaron Craelius 2023-03-15 16:10:23 -04:00 committed by GitHub
parent 988a71b5ea
commit ecc685d428
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 13 additions and 1171 deletions

View File

@ -140,6 +140,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (crypto) [#15070](https://github.com/cosmos/cosmos-sdk/pull/15070) `GenerateFromPassword` and `Cost` from `bcrypt.go` now take a `uint32` instead of a `int` type.
* (client) [#15123](https://github.com/cosmos/cosmos-sdk/pull/15123) `NewFactoryCLI` now returns an error, in addition to the `Factory`.
* (x/capability) [#15344](https://github.com/cosmos/cosmos-sdk/pull/15344) Capability module was removed and is now housed in [IBC-GO](https://github.com/cosmos/ibc-go).
* [#15299](https://github.com/cosmos/cosmos-sdk/pull/15299) remove `StdTx` transaction and signing APIs. No SDK version has actually supported `StdTx` since before Stargate.
### Client Breaking Changes
@ -152,6 +153,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (x/gov) [#14880](https://github.com/cosmos/cosmos-sdk/pull/14880) Remove `<app> tx gov submit-legacy-proposal cancel-software-upgrade` and `software-upgrade` commands. These commands are now in the `x/upgrade` module and using gov v1. Use `tx upgrade software-upgrade` instead.
* (grpc-web) [#14652](https://github.com/cosmos/cosmos-sdk/pull/14652) Remove `grpc-web.address` flag.
* (client) [#14342](https://github.com/cosmos/cosmos-sdk/pull/14342) `<app> config` command is now a sub-command. Use `<app> config --help` to learn more.
* (cli) [#15299](https://github.com/cosmos/cosmos-sdk/pull/15299) remove `--amino` flag from `sign` and `multi-sign` commands. Amino `StdTx` has been deprecated for a while. Amino JSON signing still works as expected.
### Bug Fixes

View File

@ -1,65 +0,0 @@
package tx
import (
"fmt"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
// ConvertTxToStdTx converts a transaction to the legacy StdTx format
func ConvertTxToStdTx(codec *codec.LegacyAmino, tx signing.Tx) (legacytx.StdTx, error) {
if stdTx, ok := tx.(legacytx.StdTx); ok {
return stdTx, nil
}
aminoTxConfig := legacytx.StdTxConfig{Cdc: codec}
builder := aminoTxConfig.NewTxBuilder()
err := CopyTx(tx, builder, true)
if err != nil {
return legacytx.StdTx{}, err
}
stdTx, ok := builder.GetTx().(legacytx.StdTx)
if !ok {
return legacytx.StdTx{}, fmt.Errorf("expected %T, got %+v", legacytx.StdTx{}, builder.GetTx())
}
return stdTx, nil
}
// CopyTx copies a Tx to a new TxBuilder, allowing conversion between
// different transaction formats. If ignoreSignatureError is true, copying will continue
// tx even if the signature cannot be set in the target builder resulting in an unsigned tx.
func CopyTx(tx signing.Tx, builder client.TxBuilder, ignoreSignatureError bool) error {
err := builder.SetMsgs(tx.GetMsgs()...)
if err != nil {
return err
}
sigs, err := tx.GetSignaturesV2()
if err != nil {
return err
}
err = builder.SetSignatures(sigs...)
if err != nil {
if ignoreSignatureError {
// we call SetSignatures() agan with no args to clear any signatures in case the
// previous call to SetSignatures() had any partial side-effects
_ = builder.SetSignatures()
} else {
return err
}
}
builder.SetMemo(tx.GetMemo())
builder.SetFeeAmount(tx.GetFee())
builder.SetGasLimit(tx.GetGas())
builder.SetTimeoutHeight(tx.GetTimeoutHeight())
return nil
}

View File

@ -1,164 +1,23 @@
package tx_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"cosmossdk.io/depinject"
"github.com/cosmos/cosmos-sdk/client"
clienttestutil "github.com/cosmos/cosmos-sdk/client/testutil"
tx2 "github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
"github.com/cosmos/cosmos-sdk/types"
typestx "github.com/cosmos/cosmos-sdk/types/tx"
signing2 "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
const (
memo = "waboom"
gas = uint64(10000)
timeoutHeight = uint64(5)
)
var (
fee = types.NewCoins(types.NewInt64Coin("bam", 100))
_, pub1, addr1 = testdata.KeyTestPubAddr()
_, _, addr2 = testdata.KeyTestPubAddr()
rawSig = []byte("dummy")
sig = signing2.SignatureV2{
PubKey: pub1,
Data: &signing2.SingleSignatureData{
SignMode: signing2.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
Signature: rawSig,
},
}
msg0 = banktypes.NewMsgSend(addr1, addr2, types.NewCoins(types.NewInt64Coin("wack", 1)))
msg1 = banktypes.NewMsgSend(addr1, addr2, types.NewCoins(types.NewInt64Coin("wack", 2)))
msg1 = banktypes.NewMsgSend(addr1, addr2, types.NewCoins(types.NewInt64Coin("wack", 2)))
chainID = "test-chain"
tip = &typestx.Tip{Tipper: addr1.String(), Amount: testdata.NewTestFeeAmount()}
)
func buildTestTx(t *testing.T, builder client.TxBuilder) {
builder.SetMemo(memo)
builder.SetGasLimit(gas)
builder.SetFeeAmount(fee)
err := builder.SetMsgs(msg0, msg1)
require.NoError(t, err)
err = builder.SetSignatures(sig)
require.NoError(t, err)
builder.SetTimeoutHeight(timeoutHeight)
}
type TestSuite struct {
suite.Suite
amino *codec.LegacyAmino
protoCfg client.TxConfig
aminoCfg client.TxConfig
}
func (s *TestSuite) SetupSuite() {
var (
reg codectypes.InterfaceRegistry
amino *codec.LegacyAmino
)
err := depinject.Inject(clienttestutil.TestConfig, &reg, &amino)
require.NoError(s.T(), err)
s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(reg), tx.DefaultSignModes)
s.aminoCfg = legacytx.StdTxConfig{Cdc: amino}
}
func (s *TestSuite) TestCopyTx() {
// proto -> amino -> proto
protoBuilder := s.protoCfg.NewTxBuilder()
buildTestTx(s.T(), protoBuilder)
aminoBuilder := s.aminoCfg.NewTxBuilder()
err := tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder, false)
s.Require().NoError(err)
protoBuilder2 := s.protoCfg.NewTxBuilder()
err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder2, false)
s.Require().NoError(err)
// Check sigs, signers and msgs.
sigsV2_1, err := protoBuilder.GetTx().GetSignaturesV2()
s.Require().NoError(err)
sigsV2_2, err := protoBuilder2.GetTx().GetSignaturesV2()
s.Require().NoError(err)
s.Require().Equal(sigsV2_1, sigsV2_2)
s.Require().Equal(protoBuilder.GetTx().GetSigners(), protoBuilder2.GetTx().GetSigners())
s.Require().Equal(protoBuilder.GetTx().GetMsgs()[0], protoBuilder2.GetTx().GetMsgs()[0])
s.Require().Equal(protoBuilder.GetTx().GetMsgs()[1], protoBuilder2.GetTx().GetMsgs()[1])
// amino -> proto -> amino
aminoBuilder = s.aminoCfg.NewTxBuilder()
buildTestTx(s.T(), aminoBuilder)
protoBuilder = s.protoCfg.NewTxBuilder()
err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder, false)
s.Require().NoError(err)
aminoBuilder2 := s.aminoCfg.NewTxBuilder()
err = tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder2, false)
s.Require().NoError(err)
// Check sigs, signers, and msgs
sigsV2_1, err = aminoBuilder.GetTx().GetSignaturesV2()
s.Require().NoError(err)
sigsV2_2, err = aminoBuilder2.GetTx().GetSignaturesV2()
s.Require().NoError(err)
s.Require().Equal(sigsV2_1, sigsV2_2)
s.Require().Equal(aminoBuilder.GetTx().GetSigners(), aminoBuilder2.GetTx().GetSigners())
s.Require().Equal(aminoBuilder.GetTx().GetMsgs()[0], aminoBuilder2.GetTx().GetMsgs()[0])
s.Require().Equal(aminoBuilder.GetTx().GetMsgs()[1], aminoBuilder2.GetTx().GetMsgs()[1])
}
func (s *TestSuite) TestConvertTxToStdTx() {
// proto tx
protoBuilder := s.protoCfg.NewTxBuilder()
buildTestTx(s.T(), protoBuilder)
stdTx, err := tx2.ConvertTxToStdTx(s.amino, protoBuilder.GetTx())
s.Require().NoError(err)
s.Require().Equal(memo, stdTx.Memo)
s.Require().Equal(gas, stdTx.Fee.Gas)
s.Require().Equal(fee, stdTx.Fee.Amount)
s.Require().Equal(msg0, stdTx.Msgs[0])
s.Require().Equal(msg1, stdTx.Msgs[1])
s.Require().Equal(timeoutHeight, stdTx.TimeoutHeight)
s.Require().Equal(sig.PubKey, stdTx.Signatures[0].PubKey)
s.Require().Equal(sig.Data.(*signing2.SingleSignatureData).Signature, stdTx.Signatures[0].Signature)
// SIGN_MODE_DIRECT should fall back to an unsigned tx
err = protoBuilder.SetSignatures(signing2.SignatureV2{
PubKey: pub1,
Data: &signing2.SingleSignatureData{
SignMode: signing2.SignMode_SIGN_MODE_DIRECT,
Signature: []byte("dummy"),
},
})
s.Require().NoError(err)
stdTx, err = tx2.ConvertTxToStdTx(s.amino, protoBuilder.GetTx())
s.Require().NoError(err)
s.Require().Equal(memo, stdTx.Memo)
s.Require().Equal(gas, stdTx.Fee.Gas)
s.Require().Equal(fee, stdTx.Fee.Amount)
s.Require().Equal(msg0, stdTx.Msgs[0])
s.Require().Equal(msg1, stdTx.Msgs[1])
s.Require().Equal(timeoutHeight, stdTx.TimeoutHeight)
s.Require().Empty(stdTx.Signatures)
// std tx
aminoBuilder := s.aminoCfg.NewTxBuilder()
buildTestTx(s.T(), aminoBuilder)
stdTx = aminoBuilder.GetTx().(legacytx.StdTx)
stdTx2, err := tx2.ConvertTxToStdTx(s.amino, stdTx)
s.Require().NoError(err)
s.Require().Equal(stdTx, stdTx2)
}
func TestTestSuite(t *testing.T) {
suite.Run(t, new(TestSuite))
}

View File

@ -7,15 +7,9 @@ import (
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
"github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/client/cli"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
"github.com/cosmos/cosmos-sdk/x/staking"
)
func createTestCodec() *codec.LegacyAmino {
@ -120,25 +114,3 @@ func TestAminoCodecUnpackAnyFails(t *testing.T) {
require.Error(t, err)
require.Equal(t, err, errors.New("AminoCodec can't handle unpack protobuf Any's"))
}
func TestAminoCodecFullDecodeAndEncode(t *testing.T) {
// This tx comes from https://github.com/cosmos/cosmos-sdk/issues/8117.
txSigned := `{"type":"cosmos-sdk/StdTx","value":{"msg":[{"type":"cosmos-sdk/MsgCreateValidator","value":{"description":{"moniker":"fulltest","identity":"satoshi","website":"example.com","details":"example inc"},"commission":{"rate":"0.500000000000000000","max_rate":"1.000000000000000000","max_change_rate":"0.200000000000000000"},"min_self_delegation":"1000000","delegator_address":"cosmos14pt0q5cwf38zt08uu0n6yrstf3rndzr5057jys","validator_address":"cosmosvaloper14pt0q5cwf38zt08uu0n6yrstf3rndzr52q28gr","pubkey":{"type":"tendermint/PubKeyEd25519","value":"CYrOiM3HtS7uv1B1OAkknZnFYSRpQYSYII8AtMMtev0="},"value":{"denom":"umuon","amount":"700000000"}}}],"fee":{"amount":[{"denom":"umuon","amount":"6000"}],"gas":"160000"},"signatures":[{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"AwAOXeWgNf1FjMaayrSnrOOKz+Fivr6DiI/i0x0sZCHw"},"signature":"RcnfS/u2yl7uIShTrSUlDWvsXo2p2dYu6WJC8VDVHMBLEQZWc8bsINSCjOnlsIVkUNNe1q/WCA9n3Gy1+0zhYA=="}],"memo":"","timeout_height":"0"}}`
legacyCdc := testutil.MakeTestEncodingConfig(staking.AppModuleBasic{}, auth.AppModuleBasic{}).Amino
var tx legacytx.StdTx
err := legacyCdc.UnmarshalJSON([]byte(txSigned), &tx)
require.NoError(t, err)
// Marshalling/unmarshalling the tx should work.
marshaledTx, err := legacyCdc.MarshalJSON(tx)
require.NoError(t, err)
require.Equal(t, txSigned, string(marshaledTx))
// Marshalling/unmarshalling the tx wrapped in a struct should work.
txRequest := &cli.BroadcastReq{
Mode: flags.BroadcastSync,
Tx: tx,
}
_, err = legacyCdc.MarshalJSON(txRequest)
require.NoError(t, err)
}

View File

@ -3,10 +3,7 @@ package auth
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"testing"
@ -371,108 +368,6 @@ func (s *E2ETestSuite) TestCliGetAccountAddressByID() {
}
}
func (s *E2ETestSuite) TestCLISignAminoJSON() {
require := s.Require()
val1 := s.network.Validators[0]
txCfg := val1.ClientCtx.TxConfig
sendTokens := sdk.NewCoins(
sdk.NewCoin(fmt.Sprintf("%stoken", val1.Moniker), sdk.NewInt(10)),
sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)),
)
txBz, err := s.createBankMsg(val1, val1.Address,
sendTokens, fmt.Sprintf("--%s=true", flags.FlagGenerateOnly))
require.NoError(err)
fileUnsigned := testutil.WriteToNewTempFile(s.T(), txBz.String())
defer fileUnsigned.Close()
chainFlag := fmt.Sprintf("--%s=%s", flags.FlagChainID, val1.ClientCtx.ChainID)
sigOnlyFlag := "--signature-only"
signModeAminoFlag := "--sign-mode=amino-json"
// SIC! validators have same key names and same addresses as those registered in the keyring,
// BUT the keys are different!
valRecord, err := val1.ClientCtx.Keyring.Key(val1.Moniker)
require.NoError(err)
// query account info
queryResJSON, err := authclitestutil.QueryAccountExec(val1.ClientCtx, val1.Address)
require.NoError(err)
var account sdk.AccountI
require.NoError(val1.ClientCtx.Codec.UnmarshalInterfaceJSON(queryResJSON.Bytes(), &account))
/**** test signature-only ****/
res, err := authclitestutil.TxSignExec(val1.ClientCtx, val1.Address, fileUnsigned.Name(), chainFlag,
sigOnlyFlag, signModeAminoFlag)
require.NoError(err)
pub, err := valRecord.GetPubKey()
require.NoError(err)
checkSignatures(require, txCfg, res.Bytes(), pub)
sigs, err := txCfg.UnmarshalSignatureJSON(res.Bytes())
require.NoError(err)
require.Equal(1, len(sigs))
require.Equal(account.GetSequence(), sigs[0].Sequence)
/**** test full output ****/
res, err = authclitestutil.TxSignExec(val1.ClientCtx, val1.Address, fileUnsigned.Name(), chainFlag, signModeAminoFlag)
require.NoError(err)
// txCfg.UnmarshalSignatureJSON can't unmarshal a fragment of the signature, so we create this structure.
type txFragment struct {
Signatures []json.RawMessage
}
var txOut txFragment
err = json.Unmarshal(res.Bytes(), &txOut)
require.NoError(err)
require.Len(txOut.Signatures, 1)
/**** test file output ****/
filenameSigned := filepath.Join(s.T().TempDir(), "test_sign_out.json")
fileFlag := fmt.Sprintf("--%s=%s", flags.FlagOutputDocument, filenameSigned)
_, err = authclitestutil.TxSignExec(val1.ClientCtx, val1.Address, fileUnsigned.Name(), chainFlag, fileFlag, signModeAminoFlag)
require.NoError(err)
fContent, err := os.ReadFile(filenameSigned)
require.NoError(err)
require.Equal(res.String(), string(fContent))
/**** try to append to the previously signed transaction ****/
res, err = authclitestutil.TxSignExec(val1.ClientCtx, val1.Address, filenameSigned, chainFlag,
sigOnlyFlag, signModeAminoFlag)
require.NoError(err)
checkSignatures(require, txCfg, res.Bytes(), pub, pub)
/**** try to overwrite the previously signed transaction ****/
// We can't sign with other address, because the bank send message supports only one signer for a simple
// account. Changing the file is too much hacking, because TxDecoder returns sdk.Tx, which doesn't
// provide functionality to check / manage `auth_info`.
// Cases with different keys are are covered in unit tests of `tx.Sign`.
res, err = authclitestutil.TxSignExec(val1.ClientCtx, val1.Address, filenameSigned, chainFlag,
sigOnlyFlag, "--overwrite", signModeAminoFlag)
require.NoError(err)
checkSignatures(require, txCfg, res.Bytes(), pub)
/**** test flagAmino ****/
res, err = authclitestutil.TxSignExec(val1.ClientCtx, val1.Address, filenameSigned, chainFlag,
"--amino=true", signModeAminoFlag)
require.NoError(err)
var txAmino authcli.BroadcastReq
err = val1.ClientCtx.LegacyAmino.UnmarshalJSON(res.Bytes(), &txAmino)
require.NoError(err)
require.Len(txAmino.Tx.Signatures, 2)
require.Equal(txAmino.Tx.Signatures[0].PubKey, pub)
require.Equal(txAmino.Tx.Signatures[1].PubKey, pub)
}
func checkSignatures(require *require.Assertions, txCfg client.TxConfig, output []byte, pks ...cryptotypes.PubKey) {
sigs, err := txCfg.UnmarshalSignatureJSON(output)
require.NoError(err, string(output))
require.Len(sigs, len(pks))
for i := range pks {
require.True(sigs[i].PubKey.Equals(pks[i]), "Pub key doesn't match. Got: %s, expected: %s, idx: %d", sigs[i].PubKey, pks[i], i)
require.NotEmpty(sigs[i].Data)
}
}
func (s *E2ETestSuite) TestCLIQueryTxCmdByHash() {
val := s.network.Validators[0]

View File

@ -9,11 +9,8 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
)
var _ GasTx = (*legacytx.StdTx)(nil) // assert StdTx implements GasTx
// GasTx defines a Tx with a GetGas() method which is needed to use SetUpContextDecorator
type GasTx interface {
sdk.Tx

View File

@ -18,7 +18,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
@ -28,8 +27,6 @@ var (
key = make([]byte, secp256k1.PubKeySize)
simSecp256k1Pubkey = &secp256k1.PubKey{Key: key}
simSecp256k1Sig [64]byte
_ authsigning.SigVerifiableTx = (*legacytx.StdTx)(nil) // assert StdTx implements SigVerifiableTx
)
func init() {

View File

@ -9,7 +9,6 @@ import (
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
@ -228,100 +227,6 @@ func TestSigVerification(t *testing.T) {
}
}
// This test is exactly like the one above, but we set the codec explicitly to
// Amino.
// Once https://github.com/cosmos/cosmos-sdk/issues/6190 is in, we can remove
// this, since it'll be handled by the test matrix.
// In the meantime, we want to make double-sure amino compatibility works.
// ref: https://github.com/cosmos/cosmos-sdk/issues/7229
func TestSigVerification_ExplicitAmino(t *testing.T) {
suite := SetupTestSuite(t, true)
// Set up TxConfig.
aminoCdc := codec.NewLegacyAmino()
// We're using TestMsg amino encoding in some tests, so register it here.
txConfig := legacytx.StdTxConfig{Cdc: aminoCdc}
suite.clientCtx = client.Context{}.
WithTxConfig(txConfig)
anteHandler, err := ante.NewAnteHandler(
ante.HandlerOptions{
AccountKeeper: suite.accountKeeper,
BankKeeper: suite.bankKeeper,
FeegrantKeeper: suite.feeGrantKeeper,
SignModeHandler: txConfig.SignModeHandler(),
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
},
)
require.NoError(t, err)
suite.anteHandler = anteHandler
suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
// make block height non-zero to ensure account numbers part of signBytes
suite.ctx = suite.ctx.WithBlockHeight(1)
// keys and addresses
priv1, _, addr1 := testdata.KeyTestPubAddr()
priv2, _, addr2 := testdata.KeyTestPubAddr()
priv3, _, addr3 := testdata.KeyTestPubAddr()
addrs := []sdk.AccAddress{addr1, addr2, addr3}
msgs := make([]sdk.Msg, len(addrs))
// set accounts and create msg for each address
for i, addr := range addrs {
acc := suite.accountKeeper.NewAccountWithAddress(suite.ctx, addr)
require.NoError(t, acc.SetAccountNumber(uint64(i)))
suite.accountKeeper.SetAccount(suite.ctx, acc)
msgs[i] = testdata.NewTestMsg(addr)
}
feeAmount := testdata.NewTestFeeAmount()
gasLimit := testdata.NewTestGasLimit()
spkd := ante.NewSetPubKeyDecorator(suite.accountKeeper)
svd := ante.NewSigVerificationDecorator(suite.accountKeeper, suite.clientCtx.TxConfig.SignModeHandler())
antehandler := sdk.ChainAnteDecorators(spkd, svd)
type testCase struct {
name string
privs []cryptotypes.PrivKey
accNums []uint64
accSeqs []uint64
recheck bool
shouldErr bool
}
testCases := []testCase{
{"no signers", []cryptotypes.PrivKey{}, []uint64{}, []uint64{}, false, true},
{"not enough signers", []cryptotypes.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0}, false, true},
{"wrong order signers", []cryptotypes.PrivKey{priv3, priv2, priv1}, []uint64{2, 1, 0}, []uint64{0, 0, 0}, false, true},
{"wrong accnums", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{7, 8, 9}, []uint64{0, 0, 0}, false, true},
{"wrong sequences", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{3, 4, 5}, false, true},
{"valid tx", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0}, false, false},
{"no err on recheck", []cryptotypes.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{0, 0, 0}, true, false},
}
for i, tc := range testCases {
suite.ctx = suite.ctx.WithIsReCheckTx(tc.recheck)
suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() // Create new txBuilder for each test
require.NoError(t, suite.txBuilder.SetMsgs(msgs...))
suite.txBuilder.SetFeeAmount(feeAmount)
suite.txBuilder.SetGasLimit(gasLimit)
tx, err := suite.CreateTestTx(suite.ctx, tc.privs, tc.accNums, tc.accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
require.NoError(t, err)
_, err = antehandler(suite.ctx, tx, false)
if tc.shouldErr {
require.NotNil(t, err, "TestCase %d: %s did not error as expected", i, tc.name)
} else {
require.Nil(t, err, "TestCase %d: %s errored unexpectedly. Err: %v", i, tc.name, err)
}
}
}
func TestSigIntegration(t *testing.T) {
// generate private keys
privs := []cryptotypes.PrivKey{

View File

@ -21,16 +21,9 @@ import (
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/version"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
// BroadcastReq defines a tx broadcasting request.
type BroadcastReq struct {
Tx legacytx.StdTx `json:"tx" yaml:"tx"`
Mode string `json:"mode" yaml:"mode"`
}
// GetMultiSignCommand returns the multi-sign command
func GetMultiSignCommand() *cobra.Command {
cmd := &cobra.Command{
@ -65,7 +58,6 @@ The SIGN_MODE_DIRECT sign mode is not supported.'
cmd.Flags().Bool(flagSigOnly, false, "Print only the generated signature, then exit")
cmd.Flags().String(flags.FlagOutputDocument, "", "The document is written to the given file instead of STDOUT")
cmd.Flags().Bool(flagAmino, false, "Generate Amino-encoded JSON suitable for submitting to the txs REST endpoint")
flags.AddTxFlagsToCmd(cmd)
return cmd
@ -167,28 +159,10 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) (err error) {
sigOnly, _ := cmd.Flags().GetBool(flagSigOnly)
aminoJSON, _ := cmd.Flags().GetBool(flagAmino)
var json []byte
if aminoJSON {
stdTx, err := tx.ConvertTxToStdTx(clientCtx.LegacyAmino, txBuilder.GetTx())
if err != nil {
return err
}
req := BroadcastReq{
Tx: stdTx,
Mode: "sync|async",
}
json, _ = clientCtx.LegacyAmino.MarshalJSON(req)
} else {
json, err = marshalSignatureJSON(txCfg, txBuilder, sigOnly)
if err != nil {
return err
}
json, err = marshalSignatureJSON(txCfg, txBuilder, sigOnly)
if err != nil {
return err
}
outputDoc, _ := cmd.Flags().GetString(flags.FlagOutputDocument)
@ -355,28 +329,10 @@ func makeBatchMultisignCmd() func(cmd *cobra.Command, args []string) error {
}
sigOnly, _ := cmd.Flags().GetBool(flagSigOnly)
aminoJSON, _ := cmd.Flags().GetBool(flagAmino)
var json []byte
if aminoJSON {
stdTx, err := tx.ConvertTxToStdTx(clientCtx.LegacyAmino, txBldr.GetTx())
if err != nil {
return err
}
req := BroadcastReq{
Tx: stdTx,
Mode: "sync|async",
}
json, _ = clientCtx.LegacyAmino.MarshalJSON(req)
} else {
json, err = marshalSignatureJSON(txCfg, txBldr, sigOnly)
if err != nil {
return err
}
json, err = marshalSignatureJSON(txCfg, txBldr, sigOnly)
if err != nil {
return err
}
err = clientCtx.PrintString(fmt.Sprintf("%s\n", json))

View File

@ -19,7 +19,6 @@ const (
flagMultisig = "multisig"
flagOverwrite = "overwrite"
flagSigOnly = "signature-only"
flagAmino = "amino"
flagNoAutoIncrement = "no-auto-increment"
flagAppend = "append"
)
@ -284,7 +283,6 @@ be generated via the 'multisign' command.
cmd.Flags().Bool(flagOverwrite, false, "Overwrite existing signatures with a new one. If disabled, new signature will be appended")
cmd.Flags().Bool(flagSigOnly, false, "Print only the signatures")
cmd.Flags().String(flags.FlagOutputDocument, "", "The document will be written to the given file instead of STDOUT")
cmd.Flags().Bool(flagAmino, false, "Generate Amino encoded JSON suitable for submiting to the txs REST endpoint")
flags.AddTxFlagsToCmd(cmd)
cmd.MarkFlagRequired(flags.FlagFrom)
@ -399,16 +397,6 @@ func signTx(cmd *cobra.Command, clientCtx client.Context, txF tx.Factory, newTx
return err
}
aminoJSON, err := f.GetBool(flagAmino)
if err != nil {
return err
}
bMode, err := f.GetString(flags.FlagBroadcastMode)
if err != nil {
return err
}
// set output
closeFunc, err := setOutputFile(cmd)
if err != nil {
@ -419,24 +407,9 @@ func signTx(cmd *cobra.Command, clientCtx client.Context, txF tx.Factory, newTx
clientCtx.WithOutput(cmd.OutOrStdout())
var json []byte
if aminoJSON {
stdTx, err := tx.ConvertTxToStdTx(clientCtx.LegacyAmino, txBuilder.GetTx())
if err != nil {
return err
}
req := BroadcastReq{
Tx: stdTx,
Mode: bMode,
}
json, err = clientCtx.LegacyAmino.MarshalJSON(req)
if err != nil {
return err
}
} else {
json, err = marshalSignatureJSON(txCfg, txBuilder, printSignatureOnly)
if err != nil {
return err
}
json, err = marshalSignatureJSON(txCfg, txBuilder, printSignatureOnly)
if err != nil {
return err
}
cmd.Printf("%s\n", json)

View File

@ -14,12 +14,10 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
)
// GasEstimateResponse defines a response definition for tx gas estimation.
@ -185,17 +183,6 @@ func populateAccountFromState(
return txBldr.WithAccountNumber(num).WithSequence(seq), nil
}
// GetTxEncoder return tx encoder from global sdk configuration if ones is defined.
// Otherwise returns encoder with default logic.
func GetTxEncoder(cdc *codec.LegacyAmino) (encoder sdk.TxEncoder) {
encoder = sdk.GetConfig().GetTxEncoder()
if encoder == nil {
encoder = legacytx.DefaultTxEncoder(cdc)
}
return encoder
}
func ParseQueryResponse(bz []byte) (sdk.SimulationResponse, error) {
var simRes sdk.SimulationResponse
if err := jsonpb.Unmarshal(strings.NewReader(string(bz)), &simRes); err != nil {

View File

@ -8,23 +8,14 @@ import (
"github.com/stretchr/testify/require"
"cosmossdk.io/depinject"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
authtestutil "github.com/cosmos/cosmos-sdk/x/auth/testutil"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
var (
priv = ed25519.GenPrivKey()
addr = sdk.AccAddress(priv.PubKey().Address())
)
func TestParseQueryResponse(t *testing.T) {
@ -45,16 +36,6 @@ func TestParseQueryResponse(t *testing.T) {
require.Error(t, err)
}
// TODO: remove this and authclient.GetTxEncoder after the proto tx migration is complete
func TestDefaultTxEncoder(t *testing.T) {
cdc := makeCodec()
defaultEncoder := legacytx.DefaultTxEncoder(cdc)
encoder := authclient.GetTxEncoder(cdc)
compareEncoders(t, defaultEncoder, encoder)
}
func TestReadTxFromFile(t *testing.T) {
t.Parallel()
var (
@ -150,23 +131,3 @@ func TestBatchScanner_Scan(t *testing.T) {
})
}
}
func compareEncoders(t *testing.T, expected sdk.TxEncoder, actual sdk.TxEncoder) {
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
tx := legacytx.NewStdTx(msgs, legacytx.StdFee{}, []legacytx.StdSignature{}, "") //nolint:staticcheck // SA1019: legacytx.StdFee is deprecated: use FeeTx interface instead
defaultEncoderBytes, err := expected(tx)
require.NoError(t, err)
encoderBytes, err := actual(tx)
require.NoError(t, err)
require.Equal(t, defaultEncoderBytes, encoderBytes)
}
func makeCodec() *codec.LegacyAmino {
cdc := codec.NewLegacyAmino()
sdk.RegisterLegacyAminoCodec(cdc)
cryptocodec.RegisterCrypto(cdc)
authtypes.RegisterLegacyAminoCodec(cdc)
cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil)
return cdc
}

View File

@ -7,47 +7,9 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
sdk "github.com/cosmos/cosmos-sdk/types"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
// stdTxSignModeHandler is a SignModeHandler that handles SIGN_MODE_LEGACY_AMINO_JSON
type stdTxSignModeHandler struct{}
func NewStdTxSignModeHandler() signing.SignModeHandler {
return &stdTxSignModeHandler{}
}
// assert interface implementation
var _ signing.SignModeHandler = stdTxSignModeHandler{}
// DefaultMode implements SignModeHandler.DefaultMode
func (h stdTxSignModeHandler) DefaultMode() signingtypes.SignMode {
return signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON
}
// Modes implements SignModeHandler.Modes
func (stdTxSignModeHandler) Modes() []signingtypes.SignMode {
return []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON}
}
// DefaultMode implements SignModeHandler.GetSignBytes
func (stdTxSignModeHandler) GetSignBytes(mode signingtypes.SignMode, data signing.SignerData, tx sdk.Tx) ([]byte, error) {
if mode != signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON {
return nil, fmt.Errorf("expected %s, got %s", signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, mode)
}
stdTx, ok := tx.(StdTx)
if !ok {
return nil, fmt.Errorf("expected %T, got %T", StdTx{}, tx)
}
return StdSignBytes(
data.ChainID, data.AccountNumber, data.Sequence, stdTx.GetTimeoutHeight(), StdFee{Amount: stdTx.GetFee(), Gas: stdTx.GetGas()}, tx.GetMsgs(), stdTx.GetMemo(), nil,
), nil
}
// SignatureDataToAminoSignature converts a SignatureData to amino-encoded signature bytes.
// Only SIGN_MODE_LEGACY_AMINO_JSON is supported.
func SignatureDataToAminoSignature(cdc *codec.LegacyAmino, data signingtypes.SignatureData) ([]byte, error) {

View File

@ -1,75 +0,0 @@
package legacytx
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) {
priv1 := secp256k1.GenPrivKey()
addr1 := sdk.AccAddress(priv1.PubKey().Address())
priv2 := secp256k1.GenPrivKey()
addr2 := sdk.AccAddress(priv2.PubKey().Address())
coins := sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}
fee := StdFee{
Amount: coins,
Gas: 10000,
}
memo := "foo"
msgs := []sdk.Msg{
testdata.NewTestMsg(addr1, addr2),
}
var (
chainID = "test-chain"
accNum uint64 = 7
seqNum uint64 = 7
timeoutHeight uint64 = 10
)
tx := StdTx{
Msgs: msgs,
Fee: fee,
Signatures: nil,
Memo: memo,
TimeoutHeight: timeoutHeight,
}
handler := stdTxSignModeHandler{}
signingData := signing.SignerData{
Address: addr1.String(),
ChainID: chainID,
AccountNumber: accNum,
Sequence: seqNum,
PubKey: priv1.PubKey(),
}
signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
require.NoError(t, err)
expectedSignBz := StdSignBytes(chainID, accNum, seqNum, timeoutHeight, fee, msgs, memo, nil)
require.Equal(t, expectedSignBz, signBz)
// expect error with wrong sign mode
_, err = handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx)
require.Error(t, err)
}
func TestLegacyAminoJSONHandler_DefaultMode(t *testing.T) {
handler := stdTxSignModeHandler{}
require.Equal(t, signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, handler.DefaultMode())
}
func TestLegacyAminoJSONHandler_Modes(t *testing.T) {
handler := stdTxSignModeHandler{}
require.Equal(t, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON}, handler.Modes())
}

View File

@ -1,28 +0,0 @@
package legacytx_test
import (
"testing"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/codec"
cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
txtestutil "github.com/cosmos/cosmos-sdk/x/auth/tx/testutil"
)
func testCodec() *codec.LegacyAmino {
cdc := codec.NewLegacyAmino()
sdk.RegisterLegacyAminoCodec(cdc)
cryptoAmino.RegisterCrypto(cdc)
cdc.RegisterConcrete(&testdata.TestMsg{}, "cosmos-sdk/Test", nil)
return cdc
}
func TestStdTxConfig(t *testing.T) {
cdc := testCodec()
txGen := legacytx.StdTxConfig{Cdc: cdc}
suite.Run(t, txtestutil.NewTxConfigTestSuite(txGen))
}

View File

@ -8,17 +8,12 @@ import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
)
// Interface implementation checks
var (
_ sdk.Tx = (*StdTx)(nil)
_ sdk.TxWithMemo = (*StdTx)(nil)
_ sdk.FeeTx = (*StdTx)(nil)
_ tx.TipTx = (*StdTx)(nil)
_ codectypes.UnpackInterfacesMessage = (*StdTx)(nil)
_ codectypes.UnpackInterfacesMessage = (*StdSignature)(nil)
@ -107,38 +102,6 @@ func NewStdTx(msgs []sdk.Msg, fee StdFee, sigs []StdSignature, memo string) StdT
// GetMsgs returns the all the transaction's messages.
func (tx StdTx) GetMsgs() []sdk.Msg { return tx.Msgs }
// ValidateBasic does a simple and lightweight validation check that doesn't
// require access to any other information.
//
//nolint:revive // we need to change the receiver name here, because otherwise we conflict with tx.MaxGasWanted.
func (stdTx StdTx) ValidateBasic() error {
stdSigs := stdTx.GetSignatures()
if stdTx.Fee.Gas > tx.MaxGasWanted {
return errorsmod.Wrapf(
sdkerrors.ErrInvalidRequest,
"invalid gas supplied; %d > %d", stdTx.Fee.Gas, tx.MaxGasWanted,
)
}
if stdTx.Fee.Amount.IsAnyNegative() {
return errorsmod.Wrapf(
sdkerrors.ErrInsufficientFee,
"invalid fee provided: %s", stdTx.Fee.Amount,
)
}
if len(stdSigs) == 0 {
return sdkerrors.ErrNoSignatures
}
if len(stdSigs) != len(stdTx.GetSigners()) {
return errorsmod.Wrapf(
sdkerrors.ErrUnauthorized,
"wrong number of signers; expected %d, got %d", len(stdTx.GetSigners()), len(stdSigs),
)
}
return nil
}
// Deprecated: AsAny implements intoAny. It doesn't work for protobuf serialization,
// so it can't be saved into protobuf configured storage. We are using it only for API
// compatibility.
@ -146,27 +109,6 @@ func (tx *StdTx) AsAny() *codectypes.Any {
return codectypes.UnsafePackAny(tx)
}
// GetSigners returns the addresses that must sign the transaction.
// Addresses are returned in a deterministic order.
// They are accumulated from the GetSigners method for each Msg
// in the order they appear in tx.GetMsgs().
// Duplicate addresses will be omitted.
func (tx StdTx) GetSigners() []sdk.AccAddress {
var signers []sdk.AccAddress
seen := map[string]bool{}
for _, msg := range tx.GetMsgs() {
for _, addr := range msg.GetSigners() {
if !seen[addr.String()] {
signers = append(signers, addr)
seen[addr.String()] = true
}
}
}
return signers
}
// GetMemo returns the memo
func (tx StdTx) GetMemo() string { return tx.Memo }
@ -223,16 +165,6 @@ func (tx StdTx) GetGas() uint64 { return tx.Fee.Gas }
// GetFee returns the FeeAmount in StdFee
func (tx StdTx) GetFee() sdk.Coins { return tx.Fee.Amount }
// FeePayer returns the address that is responsible for paying fee
// StdTx returns the first signer as the fee payer
// If no signers for tx, return empty address
func (tx StdTx) FeePayer() sdk.AccAddress {
if tx.GetSigners() != nil {
return tx.GetSigners()[0]
}
return sdk.AccAddress{}
}
// FeeGranter always returns nil for StdTx
func (tx StdTx) FeeGranter() sdk.AccAddress {
return nil

View File

@ -1,17 +1,11 @@
package legacytx
import (
"fmt"
errorsmod "cosmossdk.io/errors"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx"
"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.
@ -22,14 +16,6 @@ type StdTxBuilder struct {
cdc *codec.LegacyAmino
}
// ensure interface implementation
var _ client.TxBuilder = &StdTxBuilder{}
// GetTx implements TxBuilder.GetTx
func (s *StdTxBuilder) GetTx() authsigning.Tx {
return s.StdTx
}
// SetMsgs implements TxBuilder.SetMsgs
func (s *StdTxBuilder) SetMsgs(msgs ...sdk.Msg) error {
s.Msgs = msgs
@ -89,44 +75,17 @@ type StdTxConfig struct {
Cdc *codec.LegacyAmino
}
var _ client.TxConfig = StdTxConfig{}
// NewTxBuilder implements TxConfig.NewTxBuilder
func (s StdTxConfig) NewTxBuilder() client.TxBuilder {
return &StdTxBuilder{
StdTx: StdTx{},
cdc: s.Cdc,
}
}
// WrapTxBuilder returns a StdTxBuilder from provided transaction
func (s StdTxConfig) WrapTxBuilder(newTx sdk.Tx) (client.TxBuilder, error) {
stdTx, ok := newTx.(StdTx)
if !ok {
return nil, fmt.Errorf("wrong type, expected %T, got %T", stdTx, newTx)
}
return &StdTxBuilder{StdTx: stdTx, cdc: s.Cdc}, nil
}
// MarshalTx implements TxConfig.MarshalTx
func (s StdTxConfig) TxEncoder() sdk.TxEncoder {
return DefaultTxEncoder(s.Cdc)
}
func (s StdTxConfig) TxDecoder() sdk.TxDecoder {
return mkDecoder(s.Cdc.Unmarshal)
}
func (s StdTxConfig) TxJSONEncoder() sdk.TxEncoder {
return func(tx sdk.Tx) ([]byte, error) {
return s.Cdc.MarshalJSON(tx)
}
}
func (s StdTxConfig) TxJSONDecoder() sdk.TxDecoder {
return mkDecoder(s.Cdc.UnmarshalJSON)
}
func (s StdTxConfig) MarshalSignatureJSON(sigs []signing.SignatureV2) ([]byte, error) {
stdSigs := make([]StdSignature, len(sigs))
for i, sig := range sigs {
@ -159,10 +118,6 @@ func (s StdTxConfig) UnmarshalSignatureJSON(bz []byte) ([]signing.SignatureV2, e
return sigs, nil
}
func (s StdTxConfig) SignModeHandler() authsigning.SignModeHandler {
return stdTxSignModeHandler{}
}
// SignatureV2ToStdSignature converts a SignatureV2 to a StdSignature
// [Deprecated]
func SignatureV2ToStdSignature(cdc *codec.LegacyAmino, sig signing.SignatureV2) (StdSignature, error) {
@ -187,22 +142,6 @@ func SignatureV2ToStdSignature(cdc *codec.LegacyAmino, sig signing.SignatureV2)
// Unmarshaler is a generic type for Unmarshal functions
type Unmarshaler func(bytes []byte, ptr interface{}) error
func mkDecoder(unmarshaler Unmarshaler) sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, error) {
if len(txBytes) == 0 {
return nil, errorsmod.Wrap(sdkerrors.ErrTxDecode, "tx bytes are empty")
}
tx := StdTx{}
// StdTx.Msg is an interface. The concrete types
// are registered by MakeTxCodec
err := unmarshaler(txBytes, &tx)
if err != nil {
return nil, errorsmod.Wrap(sdkerrors.ErrTxDecode, err.Error())
}
return tx, nil
}
}
// DefaultTxEncoder logic for standard transaction encoding
func DefaultTxEncoder(cdc *codec.LegacyAmino) sdk.TxEncoder {
return func(tx sdk.Tx) ([]byte, error) {

View File

@ -4,11 +4,8 @@ import (
"fmt"
"testing"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/stretchr/testify/require"
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/log"
"github.com/cosmos/cosmos-sdk/codec"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
@ -16,7 +13,6 @@ import (
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
)
@ -38,40 +34,6 @@ func NewTestStdFee() StdFee {
)
}
// Deprecated: use TxBuilder.
func NewTestTx(ctx sdk.Context, msgs []sdk.Msg, privs []cryptotypes.PrivKey, accNums []uint64, seqs []uint64, timeout uint64, fee StdFee) sdk.Tx {
sigs := make([]StdSignature, len(privs))
for i, priv := range privs {
signBytes := StdSignBytes(ctx.ChainID(), accNums[i], seqs[i], timeout, fee, msgs, "", nil)
sig, err := priv.Sign(signBytes)
if err != nil {
panic(err)
}
sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: sig}
}
tx := NewStdTx(msgs, fee, sigs, "")
return tx
}
func TestStdTx(t *testing.T) {
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
fee := NewTestStdFee()
sigs := []StdSignature{}
tx := NewStdTx(msgs, fee, sigs, "")
require.Equal(t, msgs, tx.GetMsgs())
require.Equal(t, sigs, tx.Signatures)
feePayer := tx.GetSigners()[0]
require.Equal(t, addr, feePayer)
feeGranter := tx.FeeGranter()
require.Empty(t, feeGranter)
}
func TestStdSignBytes(t *testing.T) {
type args struct {
chainID string
@ -150,86 +112,6 @@ func TestStdSignBytes(t *testing.T) {
}
}
func TestTxValidateBasic(t *testing.T) {
ctx := sdk.NewContext(nil, cmtproto.Header{ChainID: "mychainid"}, false, log.NewNopLogger())
// keys and addresses
priv1, _, addr1 := testdata.KeyTestPubAddr()
priv2, _, addr2 := testdata.KeyTestPubAddr()
// msg and signatures
msg1 := testdata.NewTestMsg(addr1, addr2)
fee := NewTestStdFee()
msgs := []sdk.Msg{msg1}
// require to fail validation upon invalid fee
badFee := NewTestStdFee()
badFee.Amount[0].Amount = sdk.NewInt(-5)
tx := NewTestTx(ctx, nil, nil, nil, nil, 0, badFee)
err := tx.ValidateBasic()
require.Error(t, err)
_, code, _ := errorsmod.ABCIInfo(err, false)
require.Equal(t, sdkerrors.ErrInsufficientFee.ABCICode(), code)
// require to fail validation when no signatures exist
privs, accNums, seqs := []cryptotypes.PrivKey{}, []uint64{}, []uint64{}
tx = NewTestTx(ctx, msgs, privs, accNums, seqs, 0, fee)
err = tx.ValidateBasic()
require.Error(t, err)
_, code, _ = errorsmod.ABCIInfo(err, false)
require.Equal(t, sdkerrors.ErrNoSignatures.ABCICode(), code)
// require to fail validation when signatures do not match expected signers
privs, accNums, seqs = []cryptotypes.PrivKey{priv1}, []uint64{0, 1}, []uint64{0, 0}
tx = NewTestTx(ctx, msgs, privs, accNums, seqs, 0, fee)
err = tx.ValidateBasic()
require.Error(t, err)
_, code, _ = errorsmod.ABCIInfo(err, false)
require.Equal(t, sdkerrors.ErrUnauthorized.ABCICode(), code)
// require to fail with invalid gas supplied
badFee = NewTestStdFee()
badFee.Gas = 9223372036854775808
tx = NewTestTx(ctx, nil, nil, nil, nil, 0, badFee)
err = tx.ValidateBasic()
require.Error(t, err)
_, code, _ = errorsmod.ABCIInfo(err, false)
require.Equal(t, sdkerrors.ErrInvalidRequest.ABCICode(), code)
// require to pass when above criteria are matched
privs, accNums, seqs = []cryptotypes.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{0, 0}
tx = NewTestTx(ctx, msgs, privs, accNums, seqs, 0, fee)
err = tx.ValidateBasic()
require.NoError(t, err)
}
func TestDefaultTxEncoder(t *testing.T) {
cdc := codec.NewLegacyAmino()
sdk.RegisterLegacyAminoCodec(cdc)
cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil)
encoder := DefaultTxEncoder(cdc)
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
fee := NewTestStdFee()
sigs := []StdSignature{}
tx := NewStdTx(msgs, fee, sigs, "")
cdcBytes, err := cdc.Marshal(tx)
require.NoError(t, err)
encoderBytes, err := encoder(tx)
require.NoError(t, err)
require.Equal(t, cdcBytes, encoderBytes)
}
func TestSignatureV2Conversions(t *testing.T) {
_, pubKey, _ := testdata.KeyTestPubAddr()
cdc := codec.NewLegacyAmino()

View File

@ -1,92 +0,0 @@
package signing_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
sdk "github.com/cosmos/cosmos-sdk/types"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
func MakeTestHandlerMap() signing.SignModeHandler {
return signing.NewSignModeHandlerMap(
signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
[]signing.SignModeHandler{
legacytx.NewStdTxSignModeHandler(),
},
)
}
func TestHandlerMap_GetSignBytes(t *testing.T) {
priv1 := secp256k1.GenPrivKey()
addr1 := sdk.AccAddress(priv1.PubKey().Address())
priv2 := secp256k1.GenPrivKey()
addr2 := sdk.AccAddress(priv2.PubKey().Address())
coins := sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}
fee := legacytx.StdFee{
Amount: coins,
Gas: 10000,
}
memo := "foo"
msgs := []sdk.Msg{
&banktypes.MsgSend{
FromAddress: addr1.String(),
ToAddress: addr2.String(),
Amount: coins,
},
}
tx := legacytx.StdTx{
Msgs: msgs,
Fee: fee,
Signatures: nil,
Memo: memo,
}
var (
chainID = "test-chain"
accNum uint64 = 7
seqNum uint64 = 7
)
handler := MakeTestHandlerMap()
aminoJSONHandler := legacytx.NewStdTxSignModeHandler()
signingData := signing.SignerData{
Address: addr1.String(),
ChainID: chainID,
AccountNumber: accNum,
Sequence: seqNum,
PubKey: priv1.PubKey(),
}
signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
require.NoError(t, err)
expectedSignBz, err := aminoJSONHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
require.NoError(t, err)
require.Equal(t, expectedSignBz, signBz)
// expect error with wrong sign mode
_, err = aminoJSONHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, tx)
require.Error(t, err)
}
func TestHandlerMap_DefaultMode(t *testing.T) {
handler := MakeTestHandlerMap()
require.Equal(t, signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, handler.DefaultMode())
}
func TestHandlerMap_Modes(t *testing.T) {
handler := MakeTestHandlerMap()
modes := handler.Modes()
require.Contains(t, modes, signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
require.Len(t, modes, 1)
}

View File

@ -1,117 +0,0 @@
package signing_test
import (
"testing"
"github.com/stretchr/testify/require"
storetypes "cosmossdk.io/store/types"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/keeper"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
func TestVerifySignature(t *testing.T) {
priv, pubKey, addr := testdata.KeyTestPubAddr()
priv1, pubKey1, addr1 := testdata.KeyTestPubAddr()
const (
memo = "testmemo"
chainID = "test-chain"
)
encCfg := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{})
key := storetypes.NewKVStoreKey(types.StoreKey)
maccPerms := map[string][]string{
"fee_collector": nil,
"mint": {"minter"},
"bonded_tokens_pool": {"burner", "staking"},
"not_bonded_tokens_pool": {"burner", "staking"},
"multiPerm": {"burner", "minter", "staking"},
"random": {"random"},
}
accountKeeper := keeper.NewAccountKeeper(
encCfg.Codec,
key,
types.ProtoBaseAccount,
maccPerms,
"cosmos",
types.NewModuleAddress("gov").String(),
)
testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{})
encCfg.Amino.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil)
acc1 := accountKeeper.NewAccountWithAddress(ctx, addr)
_ = accountKeeper.NewAccountWithAddress(ctx, addr1)
accountKeeper.SetAccount(ctx, acc1)
acc, err := ante.GetSignerAcc(ctx, accountKeeper, addr)
require.NoError(t, err)
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
fee := legacytx.NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)}) //nolint:staticcheck // SA1019: legacytx.StdFee is deprecated: use StdFeeV2
signerData := signing.SignerData{
Address: addr.String(),
ChainID: chainID,
AccountNumber: acc.GetAccountNumber(),
Sequence: acc.GetSequence(),
PubKey: pubKey,
}
signBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo, nil)
signature, err := priv.Sign(signBytes)
require.NoError(t, err)
stdSig := legacytx.StdSignature{PubKey: pubKey, Signature: signature} //nolint:staticcheck // SA1019: legacytx.StdSignature is deprecated: use SignatureV2
sigV2, err := legacytx.StdSignatureToSignatureV2(encCfg.Amino, stdSig)
require.NoError(t, err)
handler := MakeTestHandlerMap()
stdTx := legacytx.NewStdTx(msgs, fee, []legacytx.StdSignature{stdSig}, memo) //nolint:staticcheck // SA1019: legacytx.StdSignature is deprecated: use SignatureV2
stdTx.TimeoutHeight = 10
err = signing.VerifySignature(nil, pubKey, signerData, sigV2.Data, handler, stdTx) //nolint:staticcheck // SA1019: legacytx.StdSignature is deprecated: use SignatureV2
require.NoError(t, err)
pkSet := []cryptotypes.PubKey{pubKey, pubKey1}
multisigKey := kmultisig.NewLegacyAminoPubKey(2, pkSet)
multisignature := multisig.NewMultisig(2)
msgs = []sdk.Msg{testdata.NewTestMsg(addr, addr1)}
multiSignBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo, nil)
sig1, err := priv.Sign(multiSignBytes)
require.NoError(t, err)
stdSig1 := legacytx.StdSignature{PubKey: pubKey, Signature: sig1} //nolint:staticcheck // SA1019: legacytx.StdSignature is deprecated: use SignatureV2
sig1V2, err := legacytx.StdSignatureToSignatureV2(encCfg.Amino, stdSig1)
require.NoError(t, err)
sig2, err := priv1.Sign(multiSignBytes)
require.NoError(t, err)
stdSig2 := legacytx.StdSignature{PubKey: pubKey, Signature: sig2} //nolint:staticcheck // SA1019: legacytx.StdSignature is deprecated: use SignatureV2
sig2V2, err := legacytx.StdSignatureToSignatureV2(encCfg.Amino, stdSig2)
require.NoError(t, err)
err = multisig.AddSignatureFromPubKey(multisignature, sig1V2.Data, pkSet[0], pkSet)
require.NoError(t, err)
err = multisig.AddSignatureFromPubKey(multisignature, sig2V2.Data, pkSet[1], pkSet)
require.NoError(t, err)
stdTx = legacytx.NewStdTx(msgs, fee, []legacytx.StdSignature{stdSig1, stdSig2}, memo) //nolint:staticcheck // SA1019: legacytx.StdSignature is deprecated: use SignatureV2
stdTx.TimeoutHeight = 10
err = signing.VerifySignature(nil, multisigKey, signerData, multisignature, handler, stdTx) //nolint:staticcheck // SA1019: legacytx.StdSignature is deprecated: use SignatureV2
require.NoError(t, err)
}