parent
988a71b5ea
commit
ecc685d428
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
@ -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, ®, &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))
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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]
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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())
|
||||
}
|
||||
@ -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))
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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)
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user