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:
parent
9e7f504da9
commit
f5afdd0117
|
@ -6,28 +6,28 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
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/signing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConvertTxToStdTx converts a transaction to the legacy StdTx format
|
// ConvertTxToStdTx converts a transaction to the legacy StdTx format
|
||||||
func ConvertTxToStdTx(codec *codec.LegacyAmino, tx signing.Tx) (types.StdTx, error) {
|
func ConvertTxToStdTx(codec *codec.LegacyAmino, tx signing.Tx) (legacytx.StdTx, error) {
|
||||||
if stdTx, ok := tx.(types.StdTx); ok {
|
if stdTx, ok := tx.(legacytx.StdTx); ok {
|
||||||
return stdTx, nil
|
return stdTx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
aminoTxConfig := types.StdTxConfig{Cdc: codec}
|
aminoTxConfig := legacytx.StdTxConfig{Cdc: codec}
|
||||||
builder := aminoTxConfig.NewTxBuilder()
|
builder := aminoTxConfig.NewTxBuilder()
|
||||||
|
|
||||||
err := CopyTx(tx, builder)
|
err := CopyTx(tx, builder)
|
||||||
if err != nil {
|
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 {
|
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
|
return stdTx, nil
|
||||||
|
@ -58,13 +58,13 @@ func CopyTx(tx signing.Tx, builder client.TxBuilder) error {
|
||||||
return nil
|
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()
|
builder := txConfig.NewTxBuilder()
|
||||||
|
|
||||||
var theTx sdk.Tx
|
var theTx sdk.Tx
|
||||||
|
|
||||||
// check if we need a StdTx anyway, in that case don't copy
|
// 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
|
theTx = stdTx
|
||||||
} else {
|
} else {
|
||||||
err := CopyTx(stdTx, builder)
|
err := CopyTx(stdTx, builder)
|
||||||
|
|
|
@ -14,10 +14,10 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||||
"github.com/cosmos/cosmos-sdk/types"
|
"github.com/cosmos/cosmos-sdk/types"
|
||||||
signing2 "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
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/signing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||||
types3 "github.com/cosmos/cosmos-sdk/x/auth/types"
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
types2 "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -29,7 +29,7 @@ var (
|
||||||
fee = types.NewCoins(types.NewInt64Coin("bam", 100))
|
fee = types.NewCoins(types.NewInt64Coin("bam", 100))
|
||||||
_, pub1, addr1 = testdata.KeyTestPubAddr()
|
_, pub1, addr1 = testdata.KeyTestPubAddr()
|
||||||
_, _, addr2 = 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{
|
sig = signing2.SignatureV2{
|
||||||
PubKey: pub1,
|
PubKey: pub1,
|
||||||
Data: &signing2.SingleSignatureData{
|
Data: &signing2.SingleSignatureData{
|
||||||
|
@ -60,7 +60,7 @@ func (s *TestSuite) SetupSuite() {
|
||||||
encCfg := simapp.MakeEncodingConfig()
|
encCfg := simapp.MakeEncodingConfig()
|
||||||
s.encCfg = encCfg
|
s.encCfg = encCfg
|
||||||
s.protoCfg = tx.NewTxConfig(codec.NewProtoCodec(encCfg.InterfaceRegistry), tx.DefaultSignModes)
|
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() {
|
func (s *TestSuite) TestCopyTx() {
|
||||||
|
@ -111,7 +111,7 @@ func (s *TestSuite) TestConvertTxToStdTx() {
|
||||||
// std tx
|
// std tx
|
||||||
aminoBuilder := s.aminoCfg.NewTxBuilder()
|
aminoBuilder := s.aminoCfg.NewTxBuilder()
|
||||||
buildTestTx(s.T(), aminoBuilder)
|
buildTestTx(s.T(), aminoBuilder)
|
||||||
stdTx = aminoBuilder.GetTx().(types3.StdTx)
|
stdTx = aminoBuilder.GetTx().(legacytx.StdTx)
|
||||||
stdTx2, err := tx2.ConvertTxToStdTx(s.encCfg.Amino, stdTx)
|
stdTx2, err := tx2.ConvertTxToStdTx(s.encCfg.Amino, stdTx)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().Equal(stdTx, stdTx2)
|
s.Require().Equal(stdTx, stdTx2)
|
||||||
|
@ -121,7 +121,7 @@ func (s *TestSuite) TestConvertAndEncodeStdTx() {
|
||||||
// convert amino -> proto -> amino
|
// convert amino -> proto -> amino
|
||||||
aminoBuilder := s.aminoCfg.NewTxBuilder()
|
aminoBuilder := s.aminoCfg.NewTxBuilder()
|
||||||
buildTestTx(s.T(), aminoBuilder)
|
buildTestTx(s.T(), aminoBuilder)
|
||||||
stdTx := aminoBuilder.GetTx().(types3.StdTx)
|
stdTx := aminoBuilder.GetTx().(legacytx.StdTx)
|
||||||
txBz, err := tx2.ConvertAndEncodeStdTx(s.protoCfg, stdTx)
|
txBz, err := tx2.ConvertAndEncodeStdTx(s.protoCfg, stdTx)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
decodedTx, err := s.protoCfg.TxDecoder()(txBz)
|
decodedTx, err := s.protoCfg.TxDecoder()(txBz)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
crypto "github.com/cosmos/cosmos-sdk/crypto/types"
|
crypto "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
|
"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"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
@ -262,8 +262,8 @@ func TestMultiSigMigration(t *testing.T) {
|
||||||
err := multisig.AddSignatureFromPubKey(multisignature, sigs[0], pkSet[0], pkSet)
|
err := multisig.AddSignatureFromPubKey(multisignature, sigs[0], pkSet[0], pkSet)
|
||||||
|
|
||||||
// create a StdSignature for msg, and convert it to sigV2
|
// create a StdSignature for msg, and convert it to sigV2
|
||||||
sig := authtypes.StdSignature{PubKey: pkSet[1], Signature: msg}
|
sig := legacytx.StdSignature{PubKey: pkSet[1], Signature: msg}
|
||||||
sigV2, err := authtypes.StdSignatureToSignatureV2(cdc, sig)
|
sigV2, err := legacytx.StdSignatureToSignatureV2(cdc, sig)
|
||||||
require.NoError(t, multisig.AddSignatureV2(multisignature, sigV2, pkSet))
|
require.NoError(t, multisig.AddSignatureV2(multisignature, sigV2, pkSet))
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -5,7 +5,7 @@ package params
|
||||||
import (
|
import (
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
"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.
|
// MakeEncodingConfig creates an EncodingConfig for an amino based test configuration.
|
||||||
|
@ -17,7 +17,7 @@ func MakeEncodingConfig() EncodingConfig {
|
||||||
return EncodingConfig{
|
return EncodingConfig{
|
||||||
InterfaceRegistry: interfaceRegistry,
|
InterfaceRegistry: interfaceRegistry,
|
||||||
Marshaler: marshaler,
|
Marshaler: marshaler,
|
||||||
TxConfig: authtypes.StdTxConfig{Cdc: cdc},
|
TxConfig: legacytx.StdTxConfig{Cdc: cdc},
|
||||||
Amino: cdc,
|
Amino: cdc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -954,7 +954,7 @@ func TestCountSubkeys(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(T *testing.T) {
|
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))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,8 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
"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"
|
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.
|
// 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
|
// CONTRACT: If simulate=true, then signatures must either be completely filled
|
||||||
// in or empty.
|
// in or empty.
|
||||||
// CONTRACT: To use this decorator, signatures of transaction must be represented
|
// 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 {
|
type ConsumeTxSizeGasDecorator struct {
|
||||||
ak AccountKeeper
|
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
|
// 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[:],
|
Signature: simSecp256k1Sig[:],
|
||||||
PubKey: pubkey,
|
PubKey: pubkey,
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,6 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
"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
|
// MempoolFeeDecorator will check if the transaction's fee is at least as large
|
||||||
// as the local validator's minimum gasFee (defined in validator config).
|
// 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.
|
// If fee is too low, decorator returns error and tx is rejected from mempool.
|
||||||
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
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 (
|
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
|
// GasTx defines a Tx with a GetGas() method which is needed to use SetUpContextDecorator
|
||||||
|
|
|
@ -5,13 +5,16 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tendermint/tendermint/crypto"
|
||||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
"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/keys/secp256k1"
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
|
"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
"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"
|
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
)
|
)
|
||||||
|
@ -22,7 +25,7 @@ var (
|
||||||
simSecp256k1Pubkey = &secp256k1.PubKey{Key: key}
|
simSecp256k1Pubkey = &secp256k1.PubKey{Key: key}
|
||||||
simSecp256k1Sig [64]byte
|
simSecp256k1Sig [64]byte
|
||||||
|
|
||||||
_ authsigning.SigVerifiableTx = (*types.StdTx)(nil) // assert StdTx implements SigVerifiableTx
|
_ authsigning.SigVerifiableTx = (*legacytx.StdTx)(nil) // assert StdTx implements SigVerifiableTx
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -340,7 +343,7 @@ func (vscd ValidateSigCountDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim
|
||||||
|
|
||||||
sigCount := 0
|
sigCount := 0
|
||||||
for _, pk := range pubKeys {
|
for _, pk := range pubKeys {
|
||||||
sigCount += types.CountSubKeys(pk)
|
sigCount += CountSubKeys(pk)
|
||||||
if uint64(sigCount) > params.TxSigLimit {
|
if uint64(sigCount) > params.TxSigLimit {
|
||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrTooManySignatures,
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrTooManySignatures,
|
||||||
"signatures: %d, limit: %d", sigCount, params.TxSigLimit)
|
"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)
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
"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"
|
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (suite *AnteTestSuite) TestSetPubKey() {
|
func (suite *AnteTestSuite) TestSetPubKey() {
|
||||||
|
@ -75,8 +75,8 @@ func (suite *AnteTestSuite) TestConsumeSignatureVerificationGas() {
|
||||||
multisignature1 := multisig.NewMultisig(len(pkSet1))
|
multisignature1 := multisig.NewMultisig(len(pkSet1))
|
||||||
expectedCost1 := expectedGasCostByKeys(pkSet1)
|
expectedCost1 := expectedGasCostByKeys(pkSet1)
|
||||||
for i := 0; i < len(pkSet1); i++ {
|
for i := 0; i < len(pkSet1); i++ {
|
||||||
stdSig := types.StdSignature{PubKey: pkSet1[i], Signature: sigSet1[i]}
|
stdSig := legacytx.StdSignature{PubKey: pkSet1[i], Signature: sigSet1[i]}
|
||||||
sigV2, err := types.StdSignatureToSignatureV2(cdc, stdSig)
|
sigV2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
err = multisig.AddSignatureV2(multisignature1, sigV2, pkSet1)
|
err = multisig.AddSignatureV2(multisignature1, sigV2, pkSet1)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
@ -196,7 +196,7 @@ func (suite *AnteTestSuite) TestSigVerification_ExplicitAmino() {
|
||||||
// Set up TxConfig.
|
// Set up TxConfig.
|
||||||
aminoCdc := codec.NewLegacyAmino()
|
aminoCdc := codec.NewLegacyAmino()
|
||||||
// We're using TestMsg amino encoding in some tests, so register it here.
|
// 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{}.
|
suite.clientCtx = client.Context{}.
|
||||||
WithTxConfig(txConfig)
|
WithTxConfig(txConfig)
|
||||||
|
|
|
@ -8,12 +8,12 @@ import (
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
"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.
|
// BroadcastReq defines a tx broadcasting request.
|
||||||
type BroadcastReq struct {
|
type BroadcastReq struct {
|
||||||
Tx types.StdTx `json:"tx" yaml:"tx"`
|
Tx legacytx.StdTx `json:"tx" yaml:"tx"`
|
||||||
Mode string `json:"mode" yaml:"mode"`
|
Mode string `json:"mode" yaml:"mode"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
|
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
|
||||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
"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 (
|
type (
|
||||||
|
@ -21,7 +21,7 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeResp defines a tx decoding response.
|
// DecodeResp defines a tx decoding response.
|
||||||
DecodeResp authtypes.StdTx
|
DecodeResp legacytx.StdTx
|
||||||
)
|
)
|
||||||
|
|
||||||
// DecodeTxRequestHandlerFn returns the decode tx REST handler. In particular,
|
// 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
|
// convertToStdTx converts tx proto binary bytes retrieved from Tendermint into
|
||||||
// a StdTx. Returns the StdTx, as well as a flag denoting if the function
|
// a StdTx. Returns the StdTx, as well as a flag denoting if the function
|
||||||
// successfully converted or not.
|
// 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)
|
txI, err := clientCtx.TxConfig.TxDecoder()(txBytes)
|
||||||
if rest.CheckBadRequestError(w, err) {
|
if rest.CheckBadRequestError(w, err) {
|
||||||
return authtypes.StdTx{}, false
|
return legacytx.StdTx{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
tx, ok := txI.(signing.Tx)
|
tx, ok := txI.(signing.Tx)
|
||||||
if !ok {
|
if !ok {
|
||||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("%+v is not backwards compatible with %T", tx, authtypes.StdTx{}))
|
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("%+v is not backwards compatible with %T", tx, legacytx.StdTx{}))
|
||||||
return authtypes.StdTx{}, false
|
return legacytx.StdTx{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
stdTx, err := clienttx.ConvertTxToStdTx(clientCtx.LegacyAmino, tx)
|
stdTx, err := clienttx.ConvertTxToStdTx(clientCtx.LegacyAmino, tx)
|
||||||
if rest.CheckBadRequestError(w, err) {
|
if rest.CheckBadRequestError(w, err) {
|
||||||
return authtypes.StdTx{}, false
|
return legacytx.StdTx{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return stdTx, true
|
return stdTx, true
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
"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.
|
// EncodeResp defines a tx encoding response.
|
||||||
|
@ -22,7 +22,7 @@ type EncodeResp struct {
|
||||||
// and responds with base64-encoded bytes.
|
// and responds with base64-encoded bytes.
|
||||||
func EncodeTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
func EncodeTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var req types.StdTx
|
var req legacytx.StdTx
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
if rest.CheckBadRequestError(w, err) {
|
if rest.CheckBadRequestError(w, err) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||||
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
||||||
rest2 "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
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"
|
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,57 +44,53 @@ func (s *IntegrationTestSuite) TearDownSuite() {
|
||||||
s.network.Cleanup()
|
s.network.Cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationTestSuite) TestEncodeDecode() {
|
func mkTx() legacytx.StdTx {
|
||||||
val := s.network.Validators[0]
|
|
||||||
|
|
||||||
// NOTE: this uses StdTx explicitly, don't migrate it!
|
// NOTE: this uses StdTx explicitly, don't migrate it!
|
||||||
stdTx := authtypes.StdTx{
|
return legacytx.StdTx{
|
||||||
Msgs: []sdk.Msg{&types.MsgSend{}},
|
Msgs: []sdk.Msg{&types.MsgSend{}},
|
||||||
Fee: authtypes.StdFee{
|
Fee: legacytx.StdFee{
|
||||||
Amount: sdk.Coins{sdk.NewInt64Coin("foo", 10)},
|
Amount: sdk.Coins{sdk.NewInt64Coin("foo", 10)},
|
||||||
Gas: 10000,
|
Gas: 10000,
|
||||||
},
|
},
|
||||||
Memo: "FOOBAR",
|
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!
|
// NOTE: this uses amino explicitly, don't migrate it!
|
||||||
cdc := val.ClientCtx.LegacyAmino
|
cdc := val.ClientCtx.LegacyAmino
|
||||||
|
|
||||||
bz, err := cdc.MarshalJSON(stdTx)
|
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)
|
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
|
var encodeResp rest2.EncodeResp
|
||||||
err = cdc.UnmarshalJSON(res, &encodeResp)
|
err = cdc.UnmarshalJSON(res, &encodeResp)
|
||||||
s.Require().NoError(err)
|
require.NoError(err)
|
||||||
|
|
||||||
bz, err = cdc.MarshalJSON(rest2.DecodeReq{Tx: encodeResp.Tx})
|
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)
|
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
|
var respWithHeight rest.ResponseWithHeight
|
||||||
err = cdc.UnmarshalJSON(res, &respWithHeight)
|
err = cdc.UnmarshalJSON(res, &respWithHeight)
|
||||||
s.Require().NoError(err)
|
require.NoError(err)
|
||||||
var decodeResp rest2.DecodeResp
|
var decodeResp rest2.DecodeResp
|
||||||
err = cdc.UnmarshalJSON(respWithHeight.Result, &decodeResp)
|
err = cdc.UnmarshalJSON(respWithHeight.Result, &decodeResp)
|
||||||
s.Require().NoError(err)
|
require.NoError(err)
|
||||||
s.Require().Equal(stdTx, authtypes.StdTx(decodeResp))
|
require.Equal(stdTx, legacytx.StdTx(decodeResp))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationTestSuite) TestBroadcastTxRequest() {
|
func (s *IntegrationTestSuite) TestBroadcastTxRequest() {
|
||||||
// NOTE: this uses StdTx explicitly, don't migrate it!
|
stdTx := mkTx()
|
||||||
stdTx := authtypes.StdTx{
|
|
||||||
Msgs: []sdk.Msg{&types.MsgSend{}},
|
|
||||||
Fee: authtypes.StdFee{
|
|
||||||
Amount: sdk.Coins{sdk.NewInt64Coin("foo", 10)},
|
|
||||||
Gas: 10000,
|
|
||||||
},
|
|
||||||
Memo: "FOOBAR",
|
|
||||||
}
|
|
||||||
|
|
||||||
// we just test with async mode because this tx will fail - all we care about is that it got encoded and broadcast correctly
|
// 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")
|
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 {
|
func (s *IntegrationTestSuite) createTestStdTx(val *network.Validator, sequence uint64) legacytx.StdTx {
|
||||||
txConfig := authtypes.StdTxConfig{Cdc: s.cfg.LegacyAmino}
|
txConfig := legacytx.StdTxConfig{Cdc: s.cfg.LegacyAmino}
|
||||||
|
|
||||||
msg := &types.MsgSend{
|
msg := &types.MsgSend{
|
||||||
FromAddress: val.Address,
|
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)
|
err := authclient.SignTx(txFactory, val.ClientCtx, val.Moniker, txBuilder, true)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
stdTx := txBuilder.GetTx().(authtypes.StdTx)
|
stdTx := txBuilder.GetTx().(legacytx.StdTx)
|
||||||
|
|
||||||
return 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]
|
val := s.network.Validators[0]
|
||||||
|
|
||||||
// NOTE: this uses amino explicitly, don't migrate it!
|
// NOTE: this uses amino explicitly, don't migrate it!
|
||||||
cdc := val.ClientCtx.LegacyAmino
|
cdc := val.ClientCtx.LegacyAmino
|
||||||
|
|
||||||
req := rest2.BroadcastReq{
|
req := rest2.BroadcastReq{
|
||||||
Tx: stdTx,
|
Tx: stdTx,
|
||||||
Mode: mode,
|
Mode: mode,
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
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
|
// 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) {
|
func GetTxEncoder(cdc *codec.LegacyAmino) (encoder sdk.TxEncoder) {
|
||||||
encoder = sdk.GetConfig().GetTxEncoder()
|
encoder = sdk.GetConfig().GetTxEncoder()
|
||||||
if encoder == nil {
|
if encoder == nil {
|
||||||
encoder = authtypes.DefaultTxEncoder(cdc)
|
encoder = legacytx.DefaultTxEncoder(cdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return encoder
|
return encoder
|
||||||
|
|
|
@ -5,20 +5,18 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
"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/simapp"
|
||||||
"github.com/cosmos/cosmos-sdk/testutil"
|
"github.com/cosmos/cosmos-sdk/testutil"
|
||||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
"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"
|
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"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,7 +47,7 @@ func TestParseQueryResponse(t *testing.T) {
|
||||||
func TestDefaultTxEncoder(t *testing.T) {
|
func TestDefaultTxEncoder(t *testing.T) {
|
||||||
cdc := makeCodec()
|
cdc := makeCodec()
|
||||||
|
|
||||||
defaultEncoder := authtypes.DefaultTxEncoder(cdc)
|
defaultEncoder := legacytx.DefaultTxEncoder(cdc)
|
||||||
encoder := authclient.GetTxEncoder(cdc)
|
encoder := authclient.GetTxEncoder(cdc)
|
||||||
|
|
||||||
compareEncoders(t, defaultEncoder, encoder)
|
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) {
|
func compareEncoders(t *testing.T, expected sdk.TxEncoder, actual sdk.TxEncoder) {
|
||||||
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
|
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)
|
defaultEncoderBytes, err := expected(tx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package types
|
package legacytx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -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)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package types_test
|
package legacytx_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -9,8 +9,8 @@ import (
|
||||||
cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec"
|
cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
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/testutil"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func testCodec() *codec.LegacyAmino {
|
func testCodec() *codec.LegacyAmino {
|
||||||
|
@ -23,6 +23,6 @@ func testCodec() *codec.LegacyAmino {
|
||||||
|
|
||||||
func TestStdTxConfig(t *testing.T) {
|
func TestStdTxConfig(t *testing.T) {
|
||||||
cdc := testCodec()
|
cdc := testCodec()
|
||||||
txGen := types.StdTxConfig{Cdc: cdc}
|
txGen := legacytx.StdTxConfig{Cdc: cdc}
|
||||||
suite.Run(t, testutil.NewTxConfigTestSuite(txGen))
|
suite.Run(t, testutil.NewTxConfigTestSuite(txGen))
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package types
|
package legacytx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
"github.com/cosmos/cosmos-sdk/codec/types"
|
|
@ -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
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package types
|
package legacytx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
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/types/tx/signing"
|
||||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||||
)
|
)
|
||||||
|
@ -18,6 +19,7 @@ type StdTxBuilder struct {
|
||||||
cdc *codec.LegacyAmino
|
cdc *codec.LegacyAmino
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensure interface implementation
|
||||||
var _ client.TxBuilder = &StdTxBuilder{}
|
var _ client.TxBuilder = &StdTxBuilder{}
|
||||||
|
|
||||||
// GetTx implements TxBuilder.GetTx
|
// GetTx implements TxBuilder.GetTx
|
||||||
|
@ -34,14 +36,12 @@ func (s *StdTxBuilder) SetMsgs(msgs ...sdk.Msg) error {
|
||||||
// SetSignatures implements TxBuilder.SetSignatures.
|
// SetSignatures implements TxBuilder.SetSignatures.
|
||||||
func (s *StdTxBuilder) SetSignatures(signatures ...signing.SignatureV2) error {
|
func (s *StdTxBuilder) SetSignatures(signatures ...signing.SignatureV2) error {
|
||||||
sigs := make([]StdSignature, len(signatures))
|
sigs := make([]StdSignature, len(signatures))
|
||||||
|
var err error
|
||||||
for i, sig := range signatures {
|
for i, sig := range signatures {
|
||||||
stdSig, err := SignatureV2ToStdSignature(s.cdc, sig)
|
sigs[i], err = SignatureV2ToStdSignature(s.cdc, sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
sigs[i] = stdSig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Signatures = sigs
|
s.Signatures = sigs
|
||||||
|
@ -85,7 +85,7 @@ func (s StdTxConfig) NewTxBuilder() client.TxBuilder {
|
||||||
func (s StdTxConfig) WrapTxBuilder(newTx sdk.Tx) (client.TxBuilder, error) {
|
func (s StdTxConfig) WrapTxBuilder(newTx sdk.Tx) (client.TxBuilder, error) {
|
||||||
stdTx, ok := newTx.(StdTx)
|
stdTx, ok := newTx.(StdTx)
|
||||||
if !ok {
|
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
|
return &StdTxBuilder{StdTx: stdTx, cdc: s.Cdc}, nil
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func (s StdTxConfig) TxEncoder() sdk.TxEncoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StdTxConfig) TxDecoder() sdk.TxDecoder {
|
func (s StdTxConfig) TxDecoder() sdk.TxDecoder {
|
||||||
return DefaultTxDecoder(s.Cdc)
|
return mkDecoder(s.Cdc.UnmarshalBinaryBare)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StdTxConfig) TxJSONEncoder() sdk.TxEncoder {
|
func (s StdTxConfig) TxJSONEncoder() sdk.TxEncoder {
|
||||||
|
@ -106,7 +106,7 @@ func (s StdTxConfig) TxJSONEncoder() sdk.TxEncoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StdTxConfig) TxJSONDecoder() sdk.TxDecoder {
|
func (s StdTxConfig) TxJSONDecoder() sdk.TxDecoder {
|
||||||
return DefaultJSONTxDecoder(s.Cdc)
|
return mkDecoder(s.Cdc.UnmarshalJSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StdTxConfig) MarshalSignatureJSON(sigs []signing.SignatureV2) ([]byte, error) {
|
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 {
|
func (s StdTxConfig) SignModeHandler() authsigning.SignModeHandler {
|
||||||
return stdTxSignModeHandler{}
|
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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package types
|
package legacytx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -26,6 +26,11 @@ var (
|
||||||
addr = sdk.AccAddress(priv.PubKey().Address())
|
addr = sdk.AccAddress(priv.PubKey().Address())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var amino = codec.NewLegacyAmino()
|
||||||
|
RegisterLegacyAminoCodec(amino)
|
||||||
|
}
|
||||||
|
|
||||||
// Deprecated, use fee amount and gas limit separately on TxBuilder.
|
// Deprecated, use fee amount and gas limit separately on TxBuilder.
|
||||||
func NewTestStdFee() StdFee {
|
func NewTestStdFee() StdFee {
|
||||||
return NewStdFee(100000,
|
return NewStdFee(100000,
|
||||||
|
@ -156,7 +161,6 @@ func TestTxValidateBasic(t *testing.T) {
|
||||||
func TestDefaultTxEncoder(t *testing.T) {
|
func TestDefaultTxEncoder(t *testing.T) {
|
||||||
cdc := codec.NewLegacyAmino()
|
cdc := codec.NewLegacyAmino()
|
||||||
sdk.RegisterLegacyAminoCodec(cdc)
|
sdk.RegisterLegacyAminoCodec(cdc)
|
||||||
RegisterLegacyAminoCodec(cdc)
|
|
||||||
cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil)
|
cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil)
|
||||||
encoder := DefaultTxEncoder(cdc)
|
encoder := DefaultTxEncoder(cdc)
|
||||||
|
|
||||||
|
@ -207,7 +211,6 @@ func TestSignatureV2Conversions(t *testing.T) {
|
||||||
_, pubKey, _ := testdata.KeyTestPubAddr()
|
_, pubKey, _ := testdata.KeyTestPubAddr()
|
||||||
cdc := codec.NewLegacyAmino()
|
cdc := codec.NewLegacyAmino()
|
||||||
sdk.RegisterLegacyAminoCodec(cdc)
|
sdk.RegisterLegacyAminoCodec(cdc)
|
||||||
RegisterLegacyAminoCodec(cdc)
|
|
||||||
dummy := []byte("dummySig")
|
dummy := []byte("dummySig")
|
||||||
sig := StdSignature{PubKey: pubKey, Signature: dummy}
|
sig := StdSignature{PubKey: pubKey, Signature: dummy}
|
||||||
|
|
||||||
|
@ -265,7 +268,6 @@ func TestGetSignaturesV2(t *testing.T) {
|
||||||
cdc := codec.NewLegacyAmino()
|
cdc := codec.NewLegacyAmino()
|
||||||
sdk.RegisterLegacyAminoCodec(cdc)
|
sdk.RegisterLegacyAminoCodec(cdc)
|
||||||
cryptocodec.RegisterCrypto(cdc)
|
cryptocodec.RegisterCrypto(cdc)
|
||||||
RegisterLegacyAminoCodec(cdc)
|
|
||||||
|
|
||||||
fee := NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)})
|
fee := NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)})
|
||||||
sig := StdSignature{PubKey: pubKey, Signature: dummy}
|
sig := StdSignature{PubKey: pubKey, Signature: dummy}
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
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/signing"
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
||||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ func MakeTestHandlerMap() signing.SignModeHandler {
|
||||||
return signing.NewSignModeHandlerMap(
|
return signing.NewSignModeHandlerMap(
|
||||||
signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
|
||||||
[]signing.SignModeHandler{
|
[]signing.SignModeHandler{
|
||||||
authtypes.NewStdTxSignModeHandler(),
|
legacytx.NewStdTxSignModeHandler(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ func TestHandlerMap_GetSignBytes(t *testing.T) {
|
||||||
|
|
||||||
coins := sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}
|
coins := sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}
|
||||||
|
|
||||||
fee := authtypes.StdFee{
|
fee := legacytx.StdFee{
|
||||||
Amount: coins,
|
Amount: coins,
|
||||||
Gas: 10000,
|
Gas: 10000,
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ func TestHandlerMap_GetSignBytes(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
tx := authtypes.StdTx{
|
tx := legacytx.StdTx{
|
||||||
Msgs: msgs,
|
Msgs: msgs,
|
||||||
Fee: fee,
|
Fee: fee,
|
||||||
Signatures: nil,
|
Signatures: nil,
|
||||||
|
@ -57,7 +57,7 @@ func TestHandlerMap_GetSignBytes(t *testing.T) {
|
||||||
)
|
)
|
||||||
|
|
||||||
handler := MakeTestHandlerMap()
|
handler := MakeTestHandlerMap()
|
||||||
aminoJSONHandler := authtypes.NewStdTxSignModeHandler()
|
aminoJSONHandler := legacytx.NewStdTxSignModeHandler()
|
||||||
|
|
||||||
signingData := signing.SignerData{
|
signingData := signing.SignerData{
|
||||||
ChainID: chainId,
|
ChainID: chainId,
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
"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/signing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
"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))
|
require.NoError(t, app.BankKeeper.SetBalances(ctx, addr, balances))
|
||||||
|
|
||||||
msgs := []sdk.Msg{testdata.NewTestMsg(addr)}
|
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{
|
signerData := signing.SignerData{
|
||||||
ChainID: chainId,
|
ChainID: chainId,
|
||||||
AccountNumber: acc.GetAccountNumber(),
|
AccountNumber: acc.GetAccountNumber(),
|
||||||
Sequence: acc.GetSequence(),
|
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)
|
signature, err := priv.Sign(signBytes)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
stdSig := types.StdSignature{PubKey: pubKey, Signature: signature}
|
stdSig := legacytx.StdSignature{PubKey: pubKey, Signature: signature}
|
||||||
sigV2, err := types.StdSignatureToSignatureV2(cdc, stdSig)
|
sigV2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
handler := MakeTestHandlerMap()
|
handler := MakeTestHandlerMap()
|
||||||
stdTx := types.NewStdTx(msgs, fee, []types.StdSignature{stdSig}, memo)
|
stdTx := legacytx.NewStdTx(msgs, fee, []legacytx.StdSignature{stdSig}, memo)
|
||||||
stdTx.TimeoutHeight = 10
|
stdTx.TimeoutHeight = 10
|
||||||
err = signing.VerifySignature(pubKey, signerData, sigV2.Data, handler, stdTx)
|
err = signing.VerifySignature(pubKey, signerData, sigV2.Data, handler, stdTx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -68,18 +69,18 @@ func TestVerifySignature(t *testing.T) {
|
||||||
multisigKey := kmultisig.NewLegacyAminoPubKey(2, pkSet)
|
multisigKey := kmultisig.NewLegacyAminoPubKey(2, pkSet)
|
||||||
multisignature := multisig.NewMultisig(2)
|
multisignature := multisig.NewMultisig(2)
|
||||||
msgs = []sdk.Msg{testdata.NewTestMsg(addr, addr1)}
|
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)
|
sig1, err := priv.Sign(multiSignBytes)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
stdSig1 := types.StdSignature{PubKey: pubKey, Signature: sig1}
|
stdSig1 := legacytx.StdSignature{PubKey: pubKey, Signature: sig1}
|
||||||
sig1V2, err := types.StdSignatureToSignatureV2(cdc, stdSig1)
|
sig1V2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
sig2, err := priv1.Sign(multiSignBytes)
|
sig2, err := priv1.Sign(multiSignBytes)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
stdSig2 := types.StdSignature{PubKey: pubKey, Signature: sig2}
|
stdSig2 := legacytx.StdSignature{PubKey: pubKey, Signature: sig2}
|
||||||
sig2V2, err := types.StdSignatureToSignatureV2(cdc, stdSig2)
|
sig2V2, err := legacytx.StdSignatureToSignatureV2(cdc, stdSig2)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = multisig.AddSignatureFromPubKey(multisignature, sig1V2.Data, pkSet[0], pkSet)
|
err = multisig.AddSignatureFromPubKey(multisignature, sig1V2.Data, pkSet[0], pkSet)
|
||||||
|
|
|
@ -226,6 +226,7 @@ func sigDataEquals(data1, data2 signingtypes.SignatureData) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TxConfigTestSuite) TestTxEncodeDecode() {
|
func (s *TxConfigTestSuite) TestTxEncodeDecode() {
|
||||||
|
log := s.T().Log
|
||||||
_, pubkey, addr := testdata.KeyTestPubAddr()
|
_, pubkey, addr := testdata.KeyTestPubAddr()
|
||||||
feeAmount := sdk.Coins{sdk.NewInt64Coin("atom", 150)}
|
feeAmount := sdk.Coins{sdk.NewInt64Coin("atom", 150)}
|
||||||
gasLimit := uint64(50000)
|
gasLimit := uint64(50000)
|
||||||
|
@ -250,13 +251,13 @@ func (s *TxConfigTestSuite) TestTxEncodeDecode() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
tx := txBuilder.GetTx()
|
tx := txBuilder.GetTx()
|
||||||
|
|
||||||
s.T().Log("encode transaction")
|
log("encode transaction")
|
||||||
txBytes, err := s.TxConfig.TxEncoder()(tx)
|
txBytes, err := s.TxConfig.TxEncoder()(tx)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NotNil(txBytes)
|
s.Require().NotNil(txBytes)
|
||||||
|
log("decode transaction", s.TxConfig)
|
||||||
s.T().Log("decode transaction")
|
|
||||||
tx2, err := s.TxConfig.TxDecoder()(txBytes)
|
tx2, err := s.TxConfig.TxDecoder()(txBytes)
|
||||||
|
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
tx3, ok := tx2.(signing.Tx)
|
tx3, ok := tx2.(signing.Tx)
|
||||||
s.Require().True(ok)
|
s.Require().True(ok)
|
||||||
|
@ -269,12 +270,12 @@ func (s *TxConfigTestSuite) TestTxEncodeDecode() {
|
||||||
s.Require().Equal([]signingtypes.SignatureV2{sig}, tx3Sigs)
|
s.Require().Equal([]signingtypes.SignatureV2{sig}, tx3Sigs)
|
||||||
s.Require().Equal([]crypto.PubKey{pubkey}, tx3.GetPubKeys())
|
s.Require().Equal([]crypto.PubKey{pubkey}, tx3.GetPubKeys())
|
||||||
|
|
||||||
s.T().Log("JSON encode transaction")
|
log("JSON encode transaction")
|
||||||
jsonTxBytes, err := s.TxConfig.TxJSONEncoder()(tx)
|
jsonTxBytes, err := s.TxConfig.TxJSONEncoder()(tx)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NotNil(jsonTxBytes)
|
s.Require().NotNil(jsonTxBytes)
|
||||||
|
|
||||||
s.T().Log("JSON decode transaction")
|
log("JSON decode transaction")
|
||||||
tx2, err = s.TxConfig.TxJSONDecoder()(jsonTxBytes)
|
tx2, err = s.TxConfig.TxJSONDecoder()(jsonTxBytes)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
tx3, ok = tx2.(signing.Tx)
|
tx3, ok = tx2.(signing.Tx)
|
||||||
|
|
|
@ -3,11 +3,10 @@ package tx
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/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"
|
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/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.")
|
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "SIGN_MODE_LEGACY_AMINO_JSON does not support protobuf extension options.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: staticcheck
|
return legacytx.StdSignBytes(
|
||||||
return types.StdSignBytes(
|
|
||||||
data.ChainID, data.AccountNumber, data.Sequence, protoTx.GetTimeoutHeight(),
|
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(),
|
tx.GetMsgs(), protoTx.GetMemo(),
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
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/signing"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -52,7 +52,7 @@ func TestLegacyAminoJSONHandler_GetSignBytes(t *testing.T) {
|
||||||
signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
|
signBz, err := handler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signingData, tx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
expectedSignBz := types.StdSignBytes(chainId, accNum, seqNum, timeout, types.StdFee{
|
expectedSignBz := legacytx.StdSignBytes(chainId, accNum, seqNum, timeout, legacytx.StdFee{
|
||||||
Amount: coins,
|
Amount: coins,
|
||||||
Gas: gas,
|
Gas: gas,
|
||||||
}, []sdk.Msg{msg}, memo)
|
}, []sdk.Msg{msg}, memo)
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
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
|
// 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.RegisterInterface((*AccountI)(nil), nil)
|
||||||
cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil)
|
cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil)
|
||||||
cdc.RegisterConcrete(&ModuleAccount{}, "cosmos-sdk/ModuleAccount", nil)
|
cdc.RegisterConcrete(&ModuleAccount{}, "cosmos-sdk/ModuleAccount", nil)
|
||||||
cdc.RegisterConcrete(StdTx{}, "cosmos-sdk/StdTx", nil)
|
|
||||||
|
legacytx.RegisterLegacyAminoCodec(cdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterInterface associates protoName with AccountI interface
|
// 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 (
|
var (
|
||||||
amino = codec.NewLegacyAmino()
|
amino = codec.NewLegacyAmino()
|
||||||
|
|
||||||
ModuleCdc = codec.NewAminoCodec(amino)
|
ModuleCdc = codec.NewAminoCodec(amino)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/types/errors"
|
"github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||||
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
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"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
bankrest "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
|
bankrest "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
|
||||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
|
@ -43,25 +44,25 @@ func (s *IntegrationTestSuite) TestCoinSend() {
|
||||||
}, stdTx.GetMsgs())
|
}, 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)
|
url := fmt.Sprintf("%s/bank/accounts/%s/transfers", val.APIAddress, val.Address)
|
||||||
|
|
||||||
// NOTE: this uses amino explicitly, don't migrate it!
|
// NOTE: this uses amino explicitly, don't migrate it!
|
||||||
bz, err := val.ClientCtx.LegacyAmino.MarshalJSON(req)
|
bz, err := val.ClientCtx.LegacyAmino.MarshalJSON(req)
|
||||||
if err != nil {
|
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)
|
res, err := rest.PostRequest(url, "application/json", bz)
|
||||||
if err != nil {
|
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!
|
// NOTE: this uses amino explicitly, don't migrate it!
|
||||||
err = val.ClientCtx.LegacyAmino.UnmarshalJSON(res, &tx)
|
err = val.ClientCtx.LegacyAmino.UnmarshalJSON(res, &tx)
|
||||||
if err != nil {
|
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
|
return tx, nil
|
||||||
|
|
Loading…
Reference in New Issue