Robert/move amino stdtx (#7301)

* x/auth: move amino StdTx... to a legacy package

* legacytx: move RegisterLegacyAminoCodec from init to tests/init

* merge fixes

Co-authored-by: Aaron Craelius <aaron@regen.network>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
Robert Zaremba 2020-09-22 16:35:18 +02:00 committed by GitHub
parent 9e7f504da9
commit f5afdd0117
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 685 additions and 696 deletions

View File

@ -6,28 +6,28 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
// ConvertTxToStdTx converts a transaction to the legacy StdTx format
func ConvertTxToStdTx(codec *codec.LegacyAmino, tx signing.Tx) (types.StdTx, error) {
if stdTx, ok := tx.(types.StdTx); ok {
func ConvertTxToStdTx(codec *codec.LegacyAmino, tx signing.Tx) (legacytx.StdTx, error) {
if stdTx, ok := tx.(legacytx.StdTx); ok {
return stdTx, nil
}
aminoTxConfig := types.StdTxConfig{Cdc: codec}
aminoTxConfig := legacytx.StdTxConfig{Cdc: codec}
builder := aminoTxConfig.NewTxBuilder()
err := CopyTx(tx, builder)
if err != nil {
return types.StdTx{}, err
return legacytx.StdTx{}, err
}
stdTx, ok := builder.GetTx().(types.StdTx)
stdTx, ok := builder.GetTx().(legacytx.StdTx)
if !ok {
return types.StdTx{}, fmt.Errorf("expected %T, got %+v", types.StdTx{}, builder.GetTx())
return legacytx.StdTx{}, fmt.Errorf("expected %T, got %+v", legacytx.StdTx{}, builder.GetTx())
}
return stdTx, nil
@ -58,13 +58,13 @@ func CopyTx(tx signing.Tx, builder client.TxBuilder) error {
return nil
}
func ConvertAndEncodeStdTx(txConfig client.TxConfig, stdTx types.StdTx) ([]byte, error) {
func ConvertAndEncodeStdTx(txConfig client.TxConfig, stdTx legacytx.StdTx) ([]byte, error) {
builder := txConfig.NewTxBuilder()
var theTx sdk.Tx
// check if we need a StdTx anyway, in that case don't copy
if _, ok := builder.GetTx().(types.StdTx); ok {
if _, ok := builder.GetTx().(legacytx.StdTx); ok {
theTx = stdTx
} else {
err := CopyTx(stdTx, builder)

View File

@ -14,10 +14,10 @@ import (
"github.com/cosmos/cosmos-sdk/testutil/testdata"
"github.com/cosmos/cosmos-sdk/types"
signing2 "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
types3 "github.com/cosmos/cosmos-sdk/x/auth/types"
types2 "github.com/cosmos/cosmos-sdk/x/bank/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
const (
@ -29,7 +29,7 @@ var (
fee = types.NewCoins(types.NewInt64Coin("bam", 100))
_, pub1, addr1 = testdata.KeyTestPubAddr()
_, _, addr2 = testdata.KeyTestPubAddr()
msg = types2.NewMsgSend(addr1, addr2, types.NewCoins(types.NewInt64Coin("wack", 10000)))
msg = banktypes.NewMsgSend(addr1, addr2, types.NewCoins(types.NewInt64Coin("wack", 10000)))
sig = signing2.SignatureV2{
PubKey: pub1,
Data: &signing2.SingleSignatureData{
@ -60,7 +60,7 @@ func (s *TestSuite) SetupSuite() {
encCfg := simapp.MakeEncodingConfig()
s.encCfg = encCfg
s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(encCfg.InterfaceRegistry), tx.DefaultSignModes)
s.aminoCfg = types3.StdTxConfig{Cdc: encCfg.Amino}
s.aminoCfg = legacytx.StdTxConfig{Cdc: encCfg.Amino}
}
func (s *TestSuite) TestCopyTx() {
@ -111,7 +111,7 @@ func (s *TestSuite) TestConvertTxToStdTx() {
// std tx
aminoBuilder := s.aminoCfg.NewTxBuilder()
buildTestTx(s.T(), aminoBuilder)
stdTx = aminoBuilder.GetTx().(types3.StdTx)
stdTx = aminoBuilder.GetTx().(legacytx.StdTx)
stdTx2, err := tx2.ConvertTxToStdTx(s.encCfg.Amino, stdTx)
s.Require().NoError(err)
s.Require().Equal(stdTx, stdTx2)
@ -121,7 +121,7 @@ func (s *TestSuite) TestConvertAndEncodeStdTx() {
// convert amino -> proto -> amino
aminoBuilder := s.aminoCfg.NewTxBuilder()
buildTestTx(s.T(), aminoBuilder)
stdTx := aminoBuilder.GetTx().(types3.StdTx)
stdTx := aminoBuilder.GetTx().(legacytx.StdTx)
txBz, err := tx2.ConvertAndEncodeStdTx(s.protoCfg, stdTx)
s.Require().NoError(err)
decodedTx, err := s.protoCfg.TxDecoder()(txBz)

View File

@ -8,7 +8,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec/types"
crypto "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
"github.com/stretchr/testify/require"
@ -262,8 +262,8 @@ func TestMultiSigMigration(t *testing.T) {
err := multisig.AddSignatureFromPubKey(multisignature, sigs[0], pkSet[0], pkSet)
// create a StdSignature for msg, and convert it to sigV2
sig := authtypes.StdSignature{PubKey: pkSet[1], Signature: msg}
sigV2, err := authtypes.StdSignatureToSignatureV2(cdc, sig)
sig := legacytx.StdSignature{PubKey: pkSet[1], Signature: msg}
sigV2, err := legacytx.StdSignatureToSignatureV2(cdc, sig)
require.NoError(t, multisig.AddSignatureV2(multisignature, sigV2, pkSet))
require.NoError(t, err)

View File

@ -5,7 +5,7 @@ package params
import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
)
// MakeEncodingConfig creates an EncodingConfig for an amino based test configuration.
@ -17,7 +17,7 @@ func MakeEncodingConfig() EncodingConfig {
return EncodingConfig{
InterfaceRegistry: interfaceRegistry,
Marshaler: marshaler,
TxConfig: authtypes.StdTxConfig{Cdc: cdc},
TxConfig: legacytx.StdTxConfig{Cdc: cdc},
Amino: cdc,
}
}

View File

@ -954,7 +954,7 @@ func TestCountSubkeys(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.name, func(T *testing.T) {
require.Equal(t, tc.want, types.CountSubKeys(tc.args.pub))
require.Equal(t, tc.want, ante.CountSubKeys(tc.args.pub))
})
}
}

View File

@ -8,12 +8,8 @@ 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/legacy/legacytx"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
var (
_ sdk.TxWithMemo = (*types.StdTx)(nil) // assert StdTx implements TxWithMemo
)
// ValidateBasicDecorator will call tx.ValidateBasic and return any non-nil error.
@ -79,7 +75,7 @@ func (vmd ValidateMemoDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
// CONTRACT: If simulate=true, then signatures must either be completely filled
// in or empty.
// CONTRACT: To use this decorator, signatures of transaction must be represented
// as types.StdSignature otherwise simulate mode will incorrectly estimate gas cost.
// as legacytx.StdSignature otherwise simulate mode will incorrectly estimate gas cost.
type ConsumeTxSizeGasDecorator struct {
ak AccountKeeper
}
@ -126,7 +122,7 @@ func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim
}
// use stdsignature to mock the size of a full signature
simSig := types.StdSignature{ //nolint:staticcheck // this will be removed when proto is ready
simSig := legacytx.StdSignature{ //nolint:staticcheck // this will be removed when proto is ready
Signature: simSecp256k1Sig[:],
PubKey: pubkey,
}

View File

@ -8,10 +8,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
var (
_ sdk.FeeTx = (*types.StdTx)(nil) // assert StdTx implements FeeTx
)
// MempoolFeeDecorator will check if the transaction's fee is at least as large
// as the local validator's minimum gasFee (defined in validator config).
// If fee is too low, decorator returns error and tx is rejected from mempool.

View File

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

View File

@ -5,13 +5,16 @@ import (
"encoding/hex"
"fmt"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
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/legacy/legacytx"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
@ -22,7 +25,7 @@ var (
simSecp256k1Pubkey = &secp256k1.PubKey{Key: key}
simSecp256k1Sig [64]byte
_ authsigning.SigVerifiableTx = (*types.StdTx)(nil) // assert StdTx implements SigVerifiableTx
_ authsigning.SigVerifiableTx = (*legacytx.StdTx)(nil) // assert StdTx implements SigVerifiableTx
)
func init() {
@ -340,7 +343,7 @@ func (vscd ValidateSigCountDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim
sigCount := 0
for _, pk := range pubKeys {
sigCount += types.CountSubKeys(pk)
sigCount += CountSubKeys(pk)
if uint64(sigCount) > params.TxSigLimit {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrTooManySignatures,
"signatures: %d, limit: %d", sigCount, params.TxSigLimit)
@ -420,3 +423,18 @@ func GetSignerAcc(ctx sdk.Context, ak AccountKeeper, addr sdk.AccAddress) (types
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", addr)
}
// CountSubKeys counts the total number of keys for a multi-sig public key.
func CountSubKeys(pub crypto.PubKey) int {
v, ok := pub.(*kmultisig.LegacyAminoPubKey)
if !ok {
return 1
}
numKeys := 0
for _, subkey := range v.GetPubKeys() {
numKeys += CountSubKeys(subkey)
}
return numKeys
}

View File

@ -16,8 +16,8 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
func (suite *AnteTestSuite) TestSetPubKey() {
@ -75,8 +75,8 @@ func (suite *AnteTestSuite) TestConsumeSignatureVerificationGas() {
multisignature1 := multisig.NewMultisig(len(pkSet1))
expectedCost1 := expectedGasCostByKeys(pkSet1)
for i := 0; i < len(pkSet1); i++ {
stdSig := types.StdSignature{PubKey: pkSet1[i], Signature: sigSet1[i]}
sigV2, err := types.StdSignatureToSignatureV2(cdc, stdSig)
stdSig := legacytx.StdSignature{PubKey: pkSet1[i], Signature: sigSet1[i]}
sigV2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig)
suite.Require().NoError(err)
err = multisig.AddSignatureV2(multisignature1, sigV2, pkSet1)
suite.Require().NoError(err)
@ -196,7 +196,7 @@ func (suite *AnteTestSuite) TestSigVerification_ExplicitAmino() {
// Set up TxConfig.
aminoCdc := codec.NewLegacyAmino()
// We're using TestMsg amino encoding in some tests, so register it here.
txConfig := authtypes.StdTxConfig{Cdc: aminoCdc}
txConfig := legacytx.StdTxConfig{Cdc: aminoCdc}
suite.clientCtx = client.Context{}.
WithTxConfig(txConfig)

View File

@ -8,13 +8,13 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
)
// BroadcastReq defines a tx broadcasting request.
type BroadcastReq struct {
Tx types.StdTx `json:"tx" yaml:"tx"`
Mode string `json:"mode" yaml:"mode"`
Tx legacytx.StdTx `json:"tx" yaml:"tx"`
Mode string `json:"mode" yaml:"mode"`
}
// BroadcastTxRequest implements a tx broadcasting handler that is responsible

View File

@ -11,7 +11,7 @@ import (
"github.com/cosmos/cosmos-sdk/client"
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/types/rest"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
)
type (
@ -21,7 +21,7 @@ type (
}
// DecodeResp defines a tx decoding response.
DecodeResp authtypes.StdTx
DecodeResp legacytx.StdTx
)
// DecodeTxRequestHandlerFn returns the decode tx REST handler. In particular,
@ -61,21 +61,21 @@ func DecodeTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
// convertToStdTx converts tx proto binary bytes retrieved from Tendermint into
// a StdTx. Returns the StdTx, as well as a flag denoting if the function
// successfully converted or not.
func convertToStdTx(w http.ResponseWriter, clientCtx client.Context, txBytes []byte) (authtypes.StdTx, bool) {
func convertToStdTx(w http.ResponseWriter, clientCtx client.Context, txBytes []byte) (legacytx.StdTx, bool) {
txI, err := clientCtx.TxConfig.TxDecoder()(txBytes)
if rest.CheckBadRequestError(w, err) {
return authtypes.StdTx{}, false
return legacytx.StdTx{}, false
}
tx, ok := txI.(signing.Tx)
if !ok {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("%+v is not backwards compatible with %T", tx, authtypes.StdTx{}))
return authtypes.StdTx{}, false
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("%+v is not backwards compatible with %T", tx, legacytx.StdTx{}))
return legacytx.StdTx{}, false
}
stdTx, err := clienttx.ConvertTxToStdTx(clientCtx.LegacyAmino, tx)
if rest.CheckBadRequestError(w, err) {
return authtypes.StdTx{}, false
return legacytx.StdTx{}, false
}
return stdTx, true

View File

@ -9,7 +9,7 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
)
// EncodeResp defines a tx encoding response.
@ -22,7 +22,7 @@ type EncodeResp struct {
// and responds with base64-encoded bytes.
func EncodeTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.StdTx
var req legacytx.StdTx
body, err := ioutil.ReadAll(r.Body)
if rest.CheckBadRequestError(w, err) {

View File

@ -15,7 +15,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
rest2 "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
"github.com/cosmos/cosmos-sdk/x/bank/types"
)
@ -44,57 +44,53 @@ func (s *IntegrationTestSuite) TearDownSuite() {
s.network.Cleanup()
}
func (s *IntegrationTestSuite) TestEncodeDecode() {
val := s.network.Validators[0]
func mkTx() legacytx.StdTx {
// NOTE: this uses StdTx explicitly, don't migrate it!
stdTx := authtypes.StdTx{
return legacytx.StdTx{
Msgs: []sdk.Msg{&types.MsgSend{}},
Fee: authtypes.StdFee{
Fee: legacytx.StdFee{
Amount: sdk.Coins{sdk.NewInt64Coin("foo", 10)},
Gas: 10000,
},
Memo: "FOOBAR",
}
}
func (s *IntegrationTestSuite) TestEncodeDecode() {
var require = s.Require()
val := s.network.Validators[0]
stdTx := mkTx()
// NOTE: this uses amino explicitly, don't migrate it!
cdc := val.ClientCtx.LegacyAmino
bz, err := cdc.MarshalJSON(stdTx)
s.Require().NoError(err)
require.NoError(err)
res, err := rest.PostRequest(fmt.Sprintf("%s/txs/encode", val.APIAddress), "application/json", bz)
s.Require().NoError(err)
require.NoError(err)
var encodeResp rest2.EncodeResp
err = cdc.UnmarshalJSON(res, &encodeResp)
s.Require().NoError(err)
require.NoError(err)
bz, err = cdc.MarshalJSON(rest2.DecodeReq{Tx: encodeResp.Tx})
s.Require().NoError(err)
require.NoError(err)
res, err = rest.PostRequest(fmt.Sprintf("%s/txs/decode", val.APIAddress), "application/json", bz)
s.Require().NoError(err)
require.NoError(err)
var respWithHeight rest.ResponseWithHeight
err = cdc.UnmarshalJSON(res, &respWithHeight)
s.Require().NoError(err)
require.NoError(err)
var decodeResp rest2.DecodeResp
err = cdc.UnmarshalJSON(respWithHeight.Result, &decodeResp)
s.Require().NoError(err)
s.Require().Equal(stdTx, authtypes.StdTx(decodeResp))
require.NoError(err)
require.Equal(stdTx, legacytx.StdTx(decodeResp))
}
func (s *IntegrationTestSuite) TestBroadcastTxRequest() {
// NOTE: this uses StdTx explicitly, don't migrate it!
stdTx := authtypes.StdTx{
Msgs: []sdk.Msg{&types.MsgSend{}},
Fee: authtypes.StdFee{
Amount: sdk.Coins{sdk.NewInt64Coin("foo", 10)},
Gas: 10000,
},
Memo: "FOOBAR",
}
stdTx := mkTx()
// we just test with async mode because this tx will fail - all we care about is that it got encoded and broadcast correctly
res, err := s.broadcastReq(stdTx, "async")
@ -182,8 +178,8 @@ func (s *IntegrationTestSuite) TestMultipleSyncBroadcastTxRequests() {
}
}
func (s *IntegrationTestSuite) createTestStdTx(val *network.Validator, sequence uint64) authtypes.StdTx {
txConfig := authtypes.StdTxConfig{Cdc: s.cfg.LegacyAmino}
func (s *IntegrationTestSuite) createTestStdTx(val *network.Validator, sequence uint64) legacytx.StdTx {
txConfig := legacytx.StdTxConfig{Cdc: s.cfg.LegacyAmino}
msg := &types.MsgSend{
FromAddress: val.Address,
@ -212,17 +208,16 @@ func (s *IntegrationTestSuite) createTestStdTx(val *network.Validator, sequence
err := authclient.SignTx(txFactory, val.ClientCtx, val.Moniker, txBuilder, true)
s.Require().NoError(err)
stdTx := txBuilder.GetTx().(authtypes.StdTx)
stdTx := txBuilder.GetTx().(legacytx.StdTx)
return stdTx
}
func (s *IntegrationTestSuite) broadcastReq(stdTx authtypes.StdTx, mode string) ([]byte, error) {
func (s *IntegrationTestSuite) broadcastReq(stdTx legacytx.StdTx, mode string) ([]byte, error) {
val := s.network.Validators[0]
// NOTE: this uses amino explicitly, don't migrate it!
cdc := val.ClientCtx.LegacyAmino
req := rest2.BroadcastReq{
Tx: stdTx,
Mode: mode,

View File

@ -16,7 +16,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
)
// Codec defines the x/auth account codec to be used for use with the
@ -156,7 +156,7 @@ func populateAccountFromState(
func GetTxEncoder(cdc *codec.LegacyAmino) (encoder sdk.TxEncoder) {
encoder = sdk.GetConfig().GetTxEncoder()
if encoder == nil {
encoder = authtypes.DefaultTxEncoder(cdc)
encoder = legacytx.DefaultTxEncoder(cdc)
}
return encoder

View File

@ -5,20 +5,18 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
"github.com/cosmos/cosmos-sdk/client"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/codec"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
@ -49,7 +47,7 @@ func TestParseQueryResponse(t *testing.T) {
func TestDefaultTxEncoder(t *testing.T) {
cdc := makeCodec()
defaultEncoder := authtypes.DefaultTxEncoder(cdc)
defaultEncoder := legacytx.DefaultTxEncoder(cdc)
encoder := authclient.GetTxEncoder(cdc)
compareEncoders(t, defaultEncoder, encoder)
@ -142,7 +140,7 @@ func TestBatchScanner_Scan(t *testing.T) {
func compareEncoders(t *testing.T, expected sdk.TxEncoder, actual sdk.TxEncoder) {
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
tx := authtypes.NewStdTx(msgs, authtypes.StdFee{}, []authtypes.StdSignature{}, "")
tx := legacytx.NewStdTx(msgs, legacytx.StdFee{}, []legacytx.StdSignature{}, "")
defaultEncoderBytes, err := expected(tx)
require.NoError(t, err)

View File

@ -0,0 +1,91 @@
package legacytx
import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
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
}
// 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) {
switch data := data.(type) {
case *signingtypes.SingleSignatureData:
if data.SignMode != signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON {
return nil, fmt.Errorf("wrong SignMode. Expected %s, got %s",
signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, data.SignMode)
}
return data.Signature, nil
case *signingtypes.MultiSignatureData:
aminoMSig, err := MultiSignatureDataToAminoMultisignature(cdc, data)
if err != nil {
return nil, err
}
return cdc.MarshalBinaryBare(aminoMSig)
default:
return nil, fmt.Errorf("unexpected signature data %T", data)
}
}
// MultiSignatureDataToAminoMultisignature converts a MultiSignatureData to an AminoMultisignature.
// Only SIGN_MODE_LEGACY_AMINO_JSON is supported.
func MultiSignatureDataToAminoMultisignature(cdc *codec.LegacyAmino, mSig *signingtypes.MultiSignatureData) (multisig.AminoMultisignature, error) {
n := len(mSig.Signatures)
sigs := make([][]byte, n)
for i := 0; i < n; i++ {
var err error
sigs[i], err = SignatureDataToAminoSignature(cdc, mSig.Signatures[i])
if err != nil {
return multisig.AminoMultisignature{}, sdkerrors.Wrapf(err, "Unable to convert Signature Data to signature %d", i)
}
}
return multisig.AminoMultisignature{
BitArray: mSig.BitArray,
Sigs: sigs,
}, nil
}

View File

@ -1,4 +1,4 @@
package types
package legacytx
import (
"testing"

View File

@ -0,0 +1,9 @@
package legacytx
import (
"github.com/cosmos/cosmos-sdk/codec"
)
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(StdTx{}, "cosmos-sdk/StdTx", nil)
}

View File

@ -1,4 +1,4 @@
package types_test
package legacytx_test
import (
"testing"
@ -9,8 +9,8 @@ import (
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/legacy/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/testutil"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
func testCodec() *codec.LegacyAmino {
@ -23,6 +23,6 @@ func testCodec() *codec.LegacyAmino {
func TestStdTxConfig(t *testing.T) {
cdc := testCodec()
txGen := types.StdTxConfig{Cdc: cdc}
txGen := legacytx.StdTxConfig{Cdc: cdc}
suite.Run(t, testutil.NewTxConfigTestSuite(txGen))
}

View File

@ -0,0 +1,112 @@
package legacytx
import (
"encoding/json"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/legacy"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
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/tendermint/tendermint/crypto"
)
// Interface implementation checks
var _ codectypes.UnpackInterfacesMessage = StdTx{}
// StdSignDoc is replay-prevention structure.
// It includes the result of msg.GetSignBytes(),
// as well as the ChainID (prevent cross chain replay)
// and the Sequence numbers for each signature (prevent
// inchain replay and enforce tx ordering per account).
type StdSignDoc struct {
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
TimeoutHeight uint64 `json:"timeout_height,omitempty" yaml:"timeout_height"`
ChainID string `json:"chain_id" yaml:"chain_id"`
Memo string `json:"memo" yaml:"memo"`
Fee json.RawMessage `json:"fee" yaml:"fee"`
Msgs []json.RawMessage `json:"msgs" yaml:"msgs"`
}
// StdSignBytes returns the bytes to sign for a transaction.
func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, msgs []sdk.Msg, memo string) []byte {
msgsBytes := make([]json.RawMessage, 0, len(msgs))
for _, msg := range msgs {
msgsBytes = append(msgsBytes, json.RawMessage(msg.GetSignBytes()))
}
bz, err := legacy.Cdc.MarshalJSON(StdSignDoc{
AccountNumber: accnum,
ChainID: chainID,
Fee: json.RawMessage(fee.Bytes()),
Memo: memo,
Msgs: msgsBytes,
Sequence: sequence,
TimeoutHeight: timeout,
})
if err != nil {
panic(err)
}
return sdk.MustSortJSON(bz)
}
// Deprecated: StdSignature represents a sig
type StdSignature struct {
crypto.PubKey `json:"pub_key" yaml:"pub_key"` // optional
Signature []byte `json:"signature" yaml:"signature"`
}
// StdSignatureToSignatureV2 converts a StdSignature to a SignatureV2
func StdSignatureToSignatureV2(cdc *codec.LegacyAmino, sig StdSignature) (signing.SignatureV2, error) {
pk := sig.GetPubKey()
data, err := pubKeySigToSigData(cdc, pk, sig.Signature)
if err != nil {
return signing.SignatureV2{}, err
}
return signing.SignatureV2{
PubKey: pk,
Data: data,
}, nil
}
func pubKeySigToSigData(cdc *codec.LegacyAmino, key crypto.PubKey, sig []byte) (signing.SignatureData, error) {
multiPK, ok := key.(multisig.PubKey)
if !ok {
return &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
Signature: sig,
}, nil
}
var multiSig multisig.AminoMultisignature
err := cdc.UnmarshalBinaryBare(sig, &multiSig)
if err != nil {
return nil, err
}
sigs := multiSig.Sigs
sigDatas := make([]signing.SignatureData, len(sigs))
pubKeys := multiPK.GetPubKeys()
bitArray := multiSig.BitArray
n := multiSig.BitArray.Count()
signatures := multisig.NewMultisig(n)
sigIdx := 0
for i := 0; i < n; i++ {
if bitArray.GetIndex(i) {
data, err := pubKeySigToSigData(cdc, pubKeys[i], multiSig.Sigs[sigIdx])
if err != nil {
return nil, sdkerrors.Wrapf(err, "Unable to convert Signature to SigData %d", sigIdx)
}
sigDatas[sigIdx] = data
multisig.AddSignature(signatures, data, sigIdx)
sigIdx++
}
}
return signatures, nil
}

View File

@ -1,4 +1,4 @@
package types
package legacytx
import (
"github.com/cosmos/cosmos-sdk/codec/types"

View File

@ -0,0 +1,274 @@
package legacytx
import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec/legacy"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/tendermint/tendermint/crypto"
"gopkg.in/yaml.v2"
)
// Interface implementation checks
var (
_ sdk.Tx = (*StdTx)(nil)
_ codectypes.IntoAny = (*StdTx)(nil)
_ sdk.TxWithMemo = (*StdTx)(nil)
_ sdk.FeeTx = (*StdTx)(nil)
)
// StdFee includes the amount of coins paid in fees and the maximum
// gas to be used by the transaction. The ratio yields an effective "gasprice",
// which must be above some miminum to be accepted into the mempool.
// [Deprecated]
type StdFee struct {
Amount sdk.Coins `json:"amount" yaml:"amount"`
Gas uint64 `json:"gas" yaml:"gas"`
}
// Deprecated: NewStdFee returns a new instance of StdFee
func NewStdFee(gas uint64, amount sdk.Coins) StdFee {
return StdFee{
Amount: amount,
Gas: gas,
}
}
// GetGas returns the fee's (wanted) gas.
func (fee StdFee) GetGas() uint64 {
return fee.Gas
}
// GetAmount returns the fee's amount.
func (fee StdFee) GetAmount() sdk.Coins {
return fee.Amount
}
// Bytes returns the encoded bytes of a StdFee.
func (fee StdFee) Bytes() []byte {
if len(fee.Amount) == 0 {
fee.Amount = sdk.NewCoins()
}
bz, err := legacy.Cdc.MarshalJSON(fee)
if err != nil {
panic(err)
}
return bz
}
// GasPrices returns the gas prices for a StdFee.
//
// NOTE: The gas prices returned are not the true gas prices that were
// originally part of the submitted transaction because the fee is computed
// as fee = ceil(gasWanted * gasPrices).
func (fee StdFee) GasPrices() sdk.DecCoins {
return sdk.NewDecCoinsFromCoins(fee.Amount...).QuoDec(sdk.NewDec(int64(fee.Gas)))
}
// Deprecated
func NewStdSignature(pk crypto.PubKey, sig []byte) StdSignature {
return StdSignature{PubKey: pk, Signature: sig}
}
// GetSignature returns the raw signature bytes.
func (ss StdSignature) GetSignature() []byte {
return ss.Signature
}
// GetPubKey returns the public key of a signature as a crypto.PubKey using the
// Amino codec.
func (ss StdSignature) GetPubKey() crypto.PubKey {
return ss.PubKey
}
// MarshalYAML returns the YAML representation of the signature.
func (ss StdSignature) MarshalYAML() (interface{}, error) {
var (
bz []byte
pubkey string
err error
)
if ss.PubKey != nil {
pubkey, err = sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, ss.GetPubKey())
if err != nil {
return nil, err
}
}
bz, err = yaml.Marshal(struct {
PubKey string
Signature string
}{
PubKey: pubkey,
Signature: fmt.Sprintf("%X", ss.Signature),
})
if err != nil {
return nil, err
}
return string(bz), err
}
// StdTx is the legacy transaction format for wrapping a Msg with Fee and Signatures.
// It only works with Amino, please prefer the new protobuf Tx in types/tx.
// NOTE: the first signature is the fee payer (Signatures must not be nil).
// Deprecated
type StdTx struct {
Msgs []sdk.Msg `json:"msg" yaml:"msg"`
Fee StdFee `json:"fee" yaml:"fee"`
Signatures []StdSignature `json:"signatures" yaml:"signatures"`
Memo string `json:"memo" yaml:"memo"`
TimeoutHeight uint64 `json:"timeout_height" yaml:"timeout_height"`
}
// Deprecated
func NewStdTx(msgs []sdk.Msg, fee StdFee, sigs []StdSignature, memo string) StdTx {
return StdTx{
Msgs: msgs,
Fee: fee,
Signatures: sigs,
Memo: memo,
}
}
// 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.
func (tx StdTx) ValidateBasic() error {
stdSigs := tx.GetSignatures()
if tx.Fee.Gas > txtypes.MaxGasWanted {
return sdkerrors.Wrapf(
sdkerrors.ErrInvalidRequest,
"invalid gas supplied; %d > %d", tx.Fee.Gas, txtypes.MaxGasWanted,
)
}
if tx.Fee.Amount.IsAnyNegative() {
return sdkerrors.Wrapf(
sdkerrors.ErrInsufficientFee,
"invalid fee provided: %s", tx.Fee.Amount,
)
}
if len(stdSigs) == 0 {
return sdkerrors.ErrNoSignatures
}
if len(stdSigs) != len(tx.GetSigners()) {
return sdkerrors.Wrapf(
sdkerrors.ErrUnauthorized,
"wrong number of signers; expected %d, got %d", len(tx.GetSigners()), len(stdSigs),
)
}
return nil
}
// AsAny implements IntoAny.AsAny.
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 }
// GetTimeoutHeight returns the transaction's timeout height (if set).
func (tx StdTx) GetTimeoutHeight() uint64 {
return tx.TimeoutHeight
}
// GetSignatures returns the signature of signers who signed the Msg.
// CONTRACT: Length returned is same as length of
// pubkeys returned from MsgKeySigners, and the order
// matches.
// CONTRACT: If the signature is missing (ie the Msg is
// invalid), then the corresponding signature is
// .Empty().
func (tx StdTx) GetSignatures() [][]byte {
sigs := make([][]byte, len(tx.Signatures))
for i, stdSig := range tx.Signatures {
sigs[i] = stdSig.Signature
}
return sigs
}
// GetSignaturesV2 implements SigVerifiableTx.GetSignaturesV2
func (tx StdTx) GetSignaturesV2() ([]signing.SignatureV2, error) {
res := make([]signing.SignatureV2, len(tx.Signatures))
for i, sig := range tx.Signatures {
var err error
res[i], err = StdSignatureToSignatureV2(legacy.Cdc, sig)
if err != nil {
return nil, sdkerrors.Wrapf(err, "Unable to convert signature %v to V2", sig)
}
}
return res, nil
}
// GetPubkeys returns the pubkeys of signers if the pubkey is included in the signature
// If pubkey is not included in the signature, then nil is in the slice instead
func (tx StdTx) GetPubKeys() []crypto.PubKey {
pks := make([]crypto.PubKey, len(tx.Signatures))
for i, stdSig := range tx.Signatures {
pks[i] = stdSig.GetPubKey()
}
return pks
}
// GetGas returns the Gas in StdFee
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{}
}
func (tx StdTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
for _, m := range tx.Msgs {
err := codectypes.UnpackInterfaces(m, unpacker)
if err != nil {
return err
}
}
return nil
}

View File

@ -1,4 +1,4 @@
package types
package legacytx
import (
"fmt"
@ -6,6 +6,7 @@ import (
"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/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
)
@ -18,6 +19,7 @@ type StdTxBuilder struct {
cdc *codec.LegacyAmino
}
// ensure interface implementation
var _ client.TxBuilder = &StdTxBuilder{}
// GetTx implements TxBuilder.GetTx
@ -34,14 +36,12 @@ func (s *StdTxBuilder) SetMsgs(msgs ...sdk.Msg) error {
// SetSignatures implements TxBuilder.SetSignatures.
func (s *StdTxBuilder) SetSignatures(signatures ...signing.SignatureV2) error {
sigs := make([]StdSignature, len(signatures))
var err error
for i, sig := range signatures {
stdSig, err := SignatureV2ToStdSignature(s.cdc, sig)
sigs[i], err = SignatureV2ToStdSignature(s.cdc, sig)
if err != nil {
return err
}
sigs[i] = stdSig
}
s.Signatures = sigs
@ -85,7 +85,7 @@ func (s StdTxConfig) NewTxBuilder() client.TxBuilder {
func (s StdTxConfig) WrapTxBuilder(newTx sdk.Tx) (client.TxBuilder, error) {
stdTx, ok := newTx.(StdTx)
if !ok {
return nil, fmt.Errorf("expected %T, got %T", StdTx{}, newTx)
return nil, fmt.Errorf("wrong type, expected %T, got %T", stdTx, newTx)
}
return &StdTxBuilder{StdTx: stdTx, cdc: s.Cdc}, nil
}
@ -96,7 +96,7 @@ func (s StdTxConfig) TxEncoder() sdk.TxEncoder {
}
func (s StdTxConfig) TxDecoder() sdk.TxDecoder {
return DefaultTxDecoder(s.Cdc)
return mkDecoder(s.Cdc.UnmarshalBinaryBare)
}
func (s StdTxConfig) TxJSONEncoder() sdk.TxEncoder {
@ -106,7 +106,7 @@ func (s StdTxConfig) TxJSONEncoder() sdk.TxEncoder {
}
func (s StdTxConfig) TxJSONDecoder() sdk.TxDecoder {
return DefaultJSONTxDecoder(s.Cdc)
return mkDecoder(s.Cdc.UnmarshalJSON)
}
func (s StdTxConfig) MarshalSignatureJSON(sigs []signing.SignatureV2) ([]byte, error) {
@ -144,3 +144,50 @@ func (s StdTxConfig) UnmarshalSignatureJSON(bz []byte) ([]signing.SignatureV2, e
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) {
var (
sigBz []byte
err error
)
if sig.Data != nil {
sigBz, err = SignatureDataToAminoSignature(cdc, sig.Data)
if err != nil {
return StdSignature{}, err
}
}
return StdSignature{
PubKey: sig.PubKey,
Signature: sigBz,
}, nil
}
// 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, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx bytes are empty")
}
var tx = StdTx{}
// StdTx.Msg is an interface. The concrete types
// are registered by MakeTxCodec
err := unmarshaler(txBytes, &tx)
if err != nil {
return nil, sdkerrors.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) {
return cdc.MarshalBinaryBare(tx)
}
}

View File

@ -1,4 +1,4 @@
package types
package legacytx
import (
"fmt"
@ -26,6 +26,11 @@ var (
addr = sdk.AccAddress(priv.PubKey().Address())
)
func init() {
var amino = codec.NewLegacyAmino()
RegisterLegacyAminoCodec(amino)
}
// Deprecated, use fee amount and gas limit separately on TxBuilder.
func NewTestStdFee() StdFee {
return NewStdFee(100000,
@ -156,7 +161,6 @@ func TestTxValidateBasic(t *testing.T) {
func TestDefaultTxEncoder(t *testing.T) {
cdc := codec.NewLegacyAmino()
sdk.RegisterLegacyAminoCodec(cdc)
RegisterLegacyAminoCodec(cdc)
cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil)
encoder := DefaultTxEncoder(cdc)
@ -207,7 +211,6 @@ func TestSignatureV2Conversions(t *testing.T) {
_, pubKey, _ := testdata.KeyTestPubAddr()
cdc := codec.NewLegacyAmino()
sdk.RegisterLegacyAminoCodec(cdc)
RegisterLegacyAminoCodec(cdc)
dummy := []byte("dummySig")
sig := StdSignature{PubKey: pubKey, Signature: dummy}
@ -265,7 +268,6 @@ func TestGetSignaturesV2(t *testing.T) {
cdc := codec.NewLegacyAmino()
sdk.RegisterLegacyAminoCodec(cdc)
cryptocodec.RegisterCrypto(cdc)
RegisterLegacyAminoCodec(cdc)
fee := NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)})
sig := StdSignature{PubKey: pubKey, Signature: dummy}

View File

@ -8,8 +8,8 @@ import (
"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/legacy/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
@ -17,7 +17,7 @@ func MakeTestHandlerMap() signing.SignModeHandler {
return signing.NewSignModeHandlerMap(
signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
[]signing.SignModeHandler{
authtypes.NewStdTxSignModeHandler(),
legacytx.NewStdTxSignModeHandler(),
},
)
}
@ -30,7 +30,7 @@ func TestHandlerMap_GetSignBytes(t *testing.T) {
coins := sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}
fee := authtypes.StdFee{
fee := legacytx.StdFee{
Amount: coins,
Gas: 10000,
}
@ -43,7 +43,7 @@ func TestHandlerMap_GetSignBytes(t *testing.T) {
},
}
tx := authtypes.StdTx{
tx := legacytx.StdTx{
Msgs: msgs,
Fee: fee,
Signatures: nil,
@ -57,7 +57,7 @@ func TestHandlerMap_GetSignBytes(t *testing.T) {
)
handler := MakeTestHandlerMap()
aminoJSONHandler := authtypes.NewStdTxSignModeHandler()
aminoJSONHandler := legacytx.NewStdTxSignModeHandler()
signingData := signing.SignerData{
ChainID: chainId,

View File

@ -14,6 +14,7 @@ import (
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
@ -44,22 +45,22 @@ func TestVerifySignature(t *testing.T) {
require.NoError(t, app.BankKeeper.SetBalances(ctx, addr, balances))
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
fee := types.NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)})
fee := legacytx.NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)})
signerData := signing.SignerData{
ChainID: chainId,
AccountNumber: acc.GetAccountNumber(),
Sequence: acc.GetSequence(),
}
signBytes := types.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo)
signBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo)
signature, err := priv.Sign(signBytes)
require.NoError(t, err)
stdSig := types.StdSignature{PubKey: pubKey, Signature: signature}
sigV2, err := types.StdSignatureToSignatureV2(cdc, stdSig)
stdSig := legacytx.StdSignature{PubKey: pubKey, Signature: signature}
sigV2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig)
require.NoError(t, err)
handler := MakeTestHandlerMap()
stdTx := types.NewStdTx(msgs, fee, []types.StdSignature{stdSig}, memo)
stdTx := legacytx.NewStdTx(msgs, fee, []legacytx.StdSignature{stdSig}, memo)
stdTx.TimeoutHeight = 10
err = signing.VerifySignature(pubKey, signerData, sigV2.Data, handler, stdTx)
require.NoError(t, err)
@ -68,18 +69,18 @@ func TestVerifySignature(t *testing.T) {
multisigKey := kmultisig.NewLegacyAminoPubKey(2, pkSet)
multisignature := multisig.NewMultisig(2)
msgs = []sdk.Msg{testdata.NewTestMsg(addr, addr1)}
multiSignBytes := types.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo)
multiSignBytes := legacytx.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.Sequence, 10, fee, msgs, memo)
sig1, err := priv.Sign(multiSignBytes)
require.NoError(t, err)
stdSig1 := types.StdSignature{PubKey: pubKey, Signature: sig1}
sig1V2, err := types.StdSignatureToSignatureV2(cdc, stdSig1)
stdSig1 := legacytx.StdSignature{PubKey: pubKey, Signature: sig1}
sig1V2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig1)
require.NoError(t, err)
sig2, err := priv1.Sign(multiSignBytes)
require.NoError(t, err)
stdSig2 := types.StdSignature{PubKey: pubKey, Signature: sig2}
sig2V2, err := types.StdSignatureToSignatureV2(cdc, stdSig2)
stdSig2 := legacytx.StdSignature{PubKey: pubKey, Signature: sig2}
sig2V2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig2)
require.NoError(t, err)
err = multisig.AddSignatureFromPubKey(multisignature, sig1V2.Data, pkSet[0], pkSet)

View File

@ -226,6 +226,7 @@ func sigDataEquals(data1, data2 signingtypes.SignatureData) bool {
}
func (s *TxConfigTestSuite) TestTxEncodeDecode() {
log := s.T().Log
_, pubkey, addr := testdata.KeyTestPubAddr()
feeAmount := sdk.Coins{sdk.NewInt64Coin("atom", 150)}
gasLimit := uint64(50000)
@ -250,13 +251,13 @@ func (s *TxConfigTestSuite) TestTxEncodeDecode() {
s.Require().NoError(err)
tx := txBuilder.GetTx()
s.T().Log("encode transaction")
log("encode transaction")
txBytes, err := s.TxConfig.TxEncoder()(tx)
s.Require().NoError(err)
s.Require().NotNil(txBytes)
s.T().Log("decode transaction")
log("decode transaction", s.TxConfig)
tx2, err := s.TxConfig.TxDecoder()(txBytes)
s.Require().NoError(err)
tx3, ok := tx2.(signing.Tx)
s.Require().True(ok)
@ -269,12 +270,12 @@ func (s *TxConfigTestSuite) TestTxEncodeDecode() {
s.Require().Equal([]signingtypes.SignatureV2{sig}, tx3Sigs)
s.Require().Equal([]crypto.PubKey{pubkey}, tx3.GetPubKeys())
s.T().Log("JSON encode transaction")
log("JSON encode transaction")
jsonTxBytes, err := s.TxConfig.TxJSONEncoder()(tx)
s.Require().NoError(err)
s.Require().NotNil(jsonTxBytes)
s.T().Log("JSON decode transaction")
log("JSON decode transaction")
tx2, err = s.TxConfig.TxJSONDecoder()(jsonTxBytes)
s.Require().NoError(err)
tx3, ok = tx2.(signing.Tx)

View File

@ -3,11 +3,10 @@ package tx
import (
"fmt"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
@ -47,10 +46,9 @@ func (s signModeLegacyAminoJSONHandler) GetSignBytes(mode signingtypes.SignMode,
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "SIGN_MODE_LEGACY_AMINO_JSON does not support protobuf extension options.")
}
// nolint: staticcheck
return types.StdSignBytes(
return legacytx.StdSignBytes(
data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(),
types.StdFee{Amount: protoTx.GetFee(), Gas: protoTx.GetGas()},
legacytx.StdFee{Amount: protoTx.GetFee(), Gas: protoTx.GetGas()},
tx.GetMsgs(), protoTx.GetMemo(),
), nil
}

View File

@ -9,8 +9,8 @@ import (
"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/legacy/legacytx"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
var (
@ -52,7 +52,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) {
signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
require.NoError(t, err)
expectedSignBz := types.StdSignBytes(chainId, accNum, seqNum, timeout, types.StdFee{
expectedSignBz := legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{
Amount: coins,
Gas: gas,
}, []sdk.Msg{msg}, memo)

View File

@ -1,44 +0,0 @@
package types
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
// stdTxSignModeHandler is a SignModeHandler that handles SIGN_MODE_LEGACY_AMINO_JSON
type stdTxSignModeHandler struct{}
func NewStdTxSignModeHandler() signing.SignModeHandler {
return &stdTxSignModeHandler{}
}
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
}

View File

@ -4,6 +4,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
)
// RegisterLegacyAminoCodec registers the account interfaces and concrete types on the
@ -14,7 +15,8 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
cdc.RegisterInterface((*AccountI)(nil), nil)
cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil)
cdc.RegisterConcrete(&ModuleAccount{}, "cosmos-sdk/ModuleAccount", nil)
cdc.RegisterConcrete(StdTx{}, "cosmos-sdk/StdTx", nil)
legacytx.RegisterLegacyAminoCodec(cdc)
}
// RegisterInterface associates protoName with AccountI interface
@ -35,15 +37,8 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
)
}
// RegisterKeyTypeCodec registers an external concrete type defined in
// another module for the internal ModuleCdc.
func RegisterKeyTypeCodec(o interface{}, name string) {
amino.RegisterConcrete(o, name, nil)
}
var (
amino = codec.NewLegacyAmino()
amino = codec.NewLegacyAmino()
ModuleCdc = codec.NewAminoCodec(amino)
)

View File

@ -1,501 +0,0 @@
package types
import (
"encoding/json"
"fmt"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/tendermint/tendermint/crypto"
yaml "gopkg.in/yaml.v2"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/legacy"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
// MaxGasWanted defines the max gas allowed.
const MaxGasWanted = uint64((1 << 63) - 1)
// Deprecated: StdFee includes the amount of coins paid in fees and the maximum
// gas to be used by the transaction. The ratio yields an effective "gasprice",
// which must be above some miminum to be accepted into the mempool.
type StdFee struct {
Amount sdk.Coins `json:"amount" yaml:"amount"`
Gas uint64 `json:"gas" yaml:"gas"`
}
// Deprecated: NewStdFee returns a new instance of StdFee
func NewStdFee(gas uint64, amount sdk.Coins) StdFee {
return StdFee{
Amount: amount,
Gas: gas,
}
}
// GetGas returns the fee's (wanted) gas.
func (fee StdFee) GetGas() uint64 {
return fee.Gas
}
// GetAmount returns the fee's amount.
func (fee StdFee) GetAmount() sdk.Coins {
return fee.Amount
}
// Bytes returns the encoded bytes of a StdFee.
func (fee StdFee) Bytes() []byte {
if len(fee.Amount) == 0 {
fee.Amount = sdk.NewCoins()
}
bz, err := legacy.Cdc.MarshalJSON(fee)
if err != nil {
panic(err)
}
return bz
}
// GasPrices returns the gas prices for a StdFee.
//
// NOTE: The gas prices returned are not the true gas prices that were
// originally part of the submitted transaction because the fee is computed
// as fee = ceil(gasWanted * gasPrices).
func (fee StdFee) GasPrices() sdk.DecCoins {
return sdk.NewDecCoinsFromCoins(fee.Amount...).QuoDec(sdk.NewDec(int64(fee.Gas)))
}
// Deprecated
func NewStdSignature(pk crypto.PubKey, sig []byte) StdSignature {
return StdSignature{PubKey: pk, Signature: sig}
}
// GetSignature returns the raw signature bytes.
func (ss StdSignature) GetSignature() []byte {
return ss.Signature
}
// GetPubKey returns the public key of a signature as a crypto.PubKey using the
// Amino codec.
func (ss StdSignature) GetPubKey() crypto.PubKey {
return ss.PubKey
}
// MarshalYAML returns the YAML representation of the signature.
func (ss StdSignature) MarshalYAML() (interface{}, error) {
var (
bz []byte
pubkey string
err error
)
if ss.PubKey != nil {
pubkey, err = sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, ss.GetPubKey())
if err != nil {
return nil, err
}
}
bz, err = yaml.Marshal(struct {
PubKey string
Signature string
}{
PubKey: pubkey,
Signature: fmt.Sprintf("%X", ss.Signature),
})
if err != nil {
return nil, err
}
return string(bz), err
}
// CountSubKeys counts the total number of keys for a multi-sig public key.
func CountSubKeys(pub crypto.PubKey) int {
v, ok := pub.(*kmultisig.LegacyAminoPubKey)
if !ok {
return 1
}
numKeys := 0
for _, subkey := range v.GetPubKeys() {
numKeys += CountSubKeys(subkey)
}
return numKeys
}
// ---------------------------------------------------------------------------
// DEPRECATED
// ---------------------------------------------------------------------------
var (
_ sdk.Tx = (*StdTx)(nil)
_ codectypes.IntoAny = (*StdTx)(nil)
)
// StdTx is the legacy transaction format for wrapping a Msg with Fee and Signatures.
// It only works with Amino, please prefer the new protobuf Tx in types/tx.
// NOTE: the first signature is the fee payer (Signatures must not be nil).
type StdTx struct {
Msgs []sdk.Msg `json:"msg" yaml:"msg"`
Fee StdFee `json:"fee" yaml:"fee"`
Signatures []StdSignature `json:"signatures" yaml:"signatures"`
Memo string `json:"memo" yaml:"memo"`
TimeoutHeight uint64 `json:"timeout_height" yaml:"timeout_height"`
}
// Deprecated
func NewStdTx(msgs []sdk.Msg, fee StdFee, sigs []StdSignature, memo string) StdTx {
return StdTx{
Msgs: msgs,
Fee: fee,
Signatures: sigs,
Memo: memo,
}
}
// 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.
func (tx StdTx) ValidateBasic() error {
stdSigs := tx.GetSignatures()
if tx.Fee.Gas > MaxGasWanted {
return sdkerrors.Wrapf(
sdkerrors.ErrInvalidRequest,
"invalid gas supplied; %d > %d", tx.Fee.Gas, MaxGasWanted,
)
}
if tx.Fee.Amount.IsAnyNegative() {
return sdkerrors.Wrapf(
sdkerrors.ErrInsufficientFee,
"invalid fee provided: %s", tx.Fee.Amount,
)
}
if len(stdSigs) == 0 {
return sdkerrors.ErrNoSignatures
}
if len(stdSigs) != len(tx.GetSigners()) {
return sdkerrors.Wrapf(
sdkerrors.ErrUnauthorized,
"wrong number of signers; expected %d, got %d", len(tx.GetSigners()), len(stdSigs),
)
}
return nil
}
// AsAny implements IntoAny.AsAny.
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 }
// GetTimeoutHeight returns the transaction's timeout height (if set).
func (tx StdTx) GetTimeoutHeight() uint64 {
return tx.TimeoutHeight
}
// GetSignatures returns the signature of signers who signed the Msg.
// CONTRACT: Length returned is same as length of
// pubkeys returned from MsgKeySigners, and the order
// matches.
// CONTRACT: If the signature is missing (ie the Msg is
// invalid), then the corresponding signature is
// .Empty().
func (tx StdTx) GetSignatures() [][]byte {
sigs := make([][]byte, len(tx.Signatures))
for i, stdSig := range tx.Signatures {
sigs[i] = stdSig.Signature
}
return sigs
}
// GetSignaturesV2 implements SigVerifiableTx.GetSignaturesV2
func (tx StdTx) GetSignaturesV2() ([]signing.SignatureV2, error) {
res := make([]signing.SignatureV2, len(tx.Signatures))
for i, sig := range tx.Signatures {
var err error
res[i], err = StdSignatureToSignatureV2(legacy.Cdc, sig)
if err != nil {
return nil, sdkerrors.Wrapf(err, "Unable to convert signature %v to V2", sig)
}
}
return res, nil
}
// GetPubkeys returns the pubkeys of signers if the pubkey is included in the signature
// If pubkey is not included in the signature, then nil is in the slice instead
func (tx StdTx) GetPubKeys() []crypto.PubKey {
pks := make([]crypto.PubKey, len(tx.Signatures))
for i, stdSig := range tx.Signatures {
pks[i] = stdSig.GetPubKey()
}
return pks
}
// GetGas returns the Gas in StdFee
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{}
}
// StdSignDoc is replay-prevention structure.
// It includes the result of msg.GetSignBytes(),
// as well as the ChainID (prevent cross chain replay)
// and the Sequence numbers for each signature (prevent
// inchain replay and enforce tx ordering per account).
type StdSignDoc struct {
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
TimeoutHeight uint64 `json:"timeout_height,omitempty" yaml:"timeout_height"`
ChainID string `json:"chain_id" yaml:"chain_id"`
Memo string `json:"memo" yaml:"memo"`
Fee json.RawMessage `json:"fee" yaml:"fee"`
Msgs []json.RawMessage `json:"msgs" yaml:"msgs"`
}
// StdSignBytes returns the bytes to sign for a transaction.
func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, msgs []sdk.Msg, memo string) []byte {
msgsBytes := make([]json.RawMessage, 0, len(msgs))
for _, msg := range msgs {
msgsBytes = append(msgsBytes, json.RawMessage(msg.GetSignBytes()))
}
bz, err := legacy.Cdc.MarshalJSON(StdSignDoc{
AccountNumber: accnum,
ChainID: chainID,
Fee: json.RawMessage(fee.Bytes()),
Memo: memo,
Msgs: msgsBytes,
Sequence: sequence,
TimeoutHeight: timeout,
})
if err != nil {
panic(err)
}
return sdk.MustSortJSON(bz)
}
// Deprecated: StdSignature represents a sig
type StdSignature struct {
crypto.PubKey `json:"pub_key" yaml:"pub_key"` // optional
Signature []byte `json:"signature" yaml:"signature"`
}
// DefaultTxDecoder logic for standard transaction decoding
func DefaultTxDecoder(cdc *codec.LegacyAmino) sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, error) {
var tx = StdTx{}
if len(txBytes) == 0 {
return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx bytes are empty")
}
// StdTx.Msg is an interface. The concrete types
// are registered by MakeTxCodec
err := cdc.UnmarshalBinaryBare(txBytes, &tx)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, err.Error())
}
return tx, nil
}
}
func DefaultJSONTxDecoder(cdc *codec.LegacyAmino) sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, error) {
var tx = StdTx{}
if len(txBytes) == 0 {
return nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx bytes are empty")
}
// StdTx.Msg is an interface. The concrete types
// are registered by MakeTxCodec
err := cdc.UnmarshalJSON(txBytes, &tx)
if err != nil {
return nil, sdkerrors.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) {
return cdc.MarshalBinaryBare(tx)
}
}
var _ codectypes.UnpackInterfacesMessage = StdTx{}
func (tx StdTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
for _, m := range tx.Msgs {
err := codectypes.UnpackInterfaces(m, unpacker)
if err != nil {
return err
}
}
return nil
}
// StdSignatureToSignatureV2 converts a StdSignature to a SignatureV2
func StdSignatureToSignatureV2(cdc *codec.LegacyAmino, sig StdSignature) (signing.SignatureV2, error) {
pk := sig.GetPubKey()
data, err := pubKeySigToSigData(cdc, pk, sig.Signature)
if err != nil {
return signing.SignatureV2{}, err
}
return signing.SignatureV2{
PubKey: pk,
Data: data,
}, nil
}
// SignatureV2ToStdSignature converts a SignatureV2 to a StdSignature
func SignatureV2ToStdSignature(cdc *codec.LegacyAmino, sig signing.SignatureV2) (StdSignature, error) {
var (
sigBz []byte
err error
)
if sig.Data != nil {
sigBz, err = SignatureDataToAminoSignature(cdc, sig.Data)
if err != nil {
return StdSignature{}, err
}
}
return StdSignature{
PubKey: sig.PubKey,
Signature: sigBz,
}, nil
}
func pubKeySigToSigData(cdc *codec.LegacyAmino, key crypto.PubKey, sig []byte) (signing.SignatureData, error) {
multiPK, ok := key.(multisig.PubKey)
if !ok {
return &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
Signature: sig,
}, nil
}
var multiSig multisig.AminoMultisignature
err := cdc.UnmarshalBinaryBare(sig, &multiSig)
if err != nil {
return nil, err
}
sigs := multiSig.Sigs
sigDatas := make([]signing.SignatureData, len(sigs))
pubKeys := multiPK.GetPubKeys()
bitArray := multiSig.BitArray
n := multiSig.BitArray.Count()
signatures := multisig.NewMultisig(n)
sigIdx := 0
for i := 0; i < n; i++ {
if bitArray.GetIndex(i) {
data, err := pubKeySigToSigData(cdc, pubKeys[i], multiSig.Sigs[sigIdx])
if err != nil {
return nil, sdkerrors.Wrapf(err, "Unable to convert Signature to SigData %d", sigIdx)
}
sigDatas[sigIdx] = data
multisig.AddSignature(signatures, data, sigIdx)
sigIdx++
}
}
return signatures, nil
}
// MultiSignatureDataToAminoMultisignature converts a MultiSignatureData to an AminoMultisignature.
// Only SIGN_MODE_LEGACY_AMINO_JSON is supported.
func MultiSignatureDataToAminoMultisignature(cdc *codec.LegacyAmino, mSig *signing.MultiSignatureData) (multisig.AminoMultisignature, error) {
n := len(mSig.Signatures)
sigs := make([][]byte, n)
for i := 0; i < n; i++ {
var err error
sigs[i], err = SignatureDataToAminoSignature(cdc, mSig.Signatures[i])
if err != nil {
return multisig.AminoMultisignature{}, sdkerrors.Wrapf(err, "Unable to convert Signature Data to signature %d", i)
}
}
return multisig.AminoMultisignature{
BitArray: mSig.BitArray,
Sigs: sigs,
}, nil
}
// SignatureDataToAminoSignature converts a SignatureData to amino-encoded signature bytes.
// Only SIGN_MODE_LEGACY_AMINO_JSON is supported.
func SignatureDataToAminoSignature(cdc *codec.LegacyAmino, data signing.SignatureData) ([]byte, error) {
switch data := data.(type) {
case *signing.SingleSignatureData:
if data.SignMode != signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON {
return nil, fmt.Errorf("expected %s, got %s", signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, data.SignMode)
}
return data.Signature, nil
case *signing.MultiSignatureData:
aminoMSig, err := MultiSignatureDataToAminoMultisignature(cdc, data)
if err != nil {
return nil, err
}
return cdc.MarshalBinaryBare(aminoMSig)
default:
return nil, fmt.Errorf("unexpected signature data %T", data)
}
}

View File

@ -11,6 +11,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/rest"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankrest "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
@ -43,25 +44,25 @@ func (s *IntegrationTestSuite) TestCoinSend() {
}, stdTx.GetMsgs())
}
func submitSendReq(val *network.Validator, req bankrest.SendReq) (authtypes.StdTx, error) {
func submitSendReq(val *network.Validator, req bankrest.SendReq) (legacytx.StdTx, error) {
url := fmt.Sprintf("%s/bank/accounts/%s/transfers", val.APIAddress, val.Address)
// NOTE: this uses amino explicitly, don't migrate it!
bz, err := val.ClientCtx.LegacyAmino.MarshalJSON(req)
if err != nil {
return authtypes.StdTx{}, errors.Wrap(err, "error encoding SendReq to json")
return legacytx.StdTx{}, errors.Wrap(err, "error encoding SendReq to json")
}
res, err := rest.PostRequest(url, "application/json", bz)
if err != nil {
return authtypes.StdTx{}, err
return legacytx.StdTx{}, err
}
var tx authtypes.StdTx
var tx legacytx.StdTx
// NOTE: this uses amino explicitly, don't migrate it!
err = val.ClientCtx.LegacyAmino.UnmarshalJSON(res, &tx)
if err != nil {
return authtypes.StdTx{}, errors.Wrap(err, "error unmarshaling to StdTx SendReq response")
return legacytx.StdTx{}, errors.Wrap(err, "error unmarshaling to StdTx SendReq response")
}
return tx, nil