Merge pull request #470 from cosmos/aditya/ante-test

- AnteHandler unit tests
- Transaction Amino registration in types
This commit is contained in:
Alexander Bezobchuk 2018-08-31 21:42:38 -04:00 committed by GitHub
commit c06a3f9d8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 309 additions and 52 deletions

28
Gopkg.lock generated
View File

@ -3,11 +3,11 @@
[[projects]]
branch = "master"
digest = "1:79b02529d2120af44eaad5f7fee9ff7e003739d469e2c2767008b797d290e9fd"
digest = "1:60d3b49df18861c92ac49cce49e49f61b3ec927e5b7f39c5ae1128ec5c197b98"
name = "github.com/aristanetworks/goarista"
packages = ["monotime"]
pruneopts = "T"
revision = "18b896026201d8e1758468d9c5d5a558c69c5e9b"
revision = "fb622b9b46608fdb39d36447f4d8ef52fe37fc3d"
[[projects]]
branch = "master"
@ -138,12 +138,12 @@
version = "v0.3.0"
[[projects]]
digest = "1:c4a2528ccbcabf90f9f3c464a5fc9e302d592861bbfd0b7135a7de8a943d0406"
digest = "1:586ea76dbd0374d6fb649a91d70d652b7fe0ccffb8910a77468e7702e7901f3d"
name = "github.com/go-stack/stack"
packages = ["."]
pruneopts = "T"
revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
version = "v1.7.0"
revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a"
version = "v1.8.0"
[[projects]]
digest = "1:da39f4a22829ca95e63566208e0ea42d6f055f41dff1b14fdab88d88f62df653"
@ -274,12 +274,12 @@
version = "v1.0.0"
[[projects]]
digest = "1:6afc433cbb471b1d32de92131245fb1f76000c9d88940265df4a512572a51b51"
digest = "1:602081d2a289d1f76ea90b806b0c61c19038d76504e9005ccb969864dbaee339"
name = "github.com/rjeczalik/notify"
packages = ["."]
pruneopts = "T"
revision = "52ae50d8490436622a8941bd70c3dbe0acdd4bbf"
version = "v0.9.0"
revision = "0f065fa99b48b842c3fd3e2c8b194c6f2b69f6b8"
version = "v0.9.1"
[[projects]]
digest = "1:6cae6970d70fc5fe75bf83c48ee33e9c4c561a62d0b033254bee8dd5942b815a"
@ -401,7 +401,7 @@
"ssh/terminal",
]
pruneopts = "T"
revision = "614d502a4dac94afa3a6ce146bd1736da82514c6"
revision = "182538f80094b6a8efaade63a8fd8e0d9d5843dd"
[[projects]]
digest = "1:5fdc7adede42f80d6201258355d478d856778e21d735f14972abd8ff793fdbf7"
@ -424,14 +424,14 @@
[[projects]]
branch = "master"
digest = "1:7560b3b54e7e9d901c46cd919d77da3c4373652ee2b0a13b15b80ea02ad94a56"
digest = "1:bfa444982d49ce4ca1360599270a94de12a573ccd3bf04493c79bee09da3170b"
name = "golang.org/x/sys"
packages = [
"unix",
"windows",
]
pruneopts = "T"
revision = "d99a578cf41bfccdeaf48b0845c823a4b8b0ad5e"
revision = "fa5fdf94c78965f1aa8423f0cc50b8b8d728b05a"
[[projects]]
digest = "1:6164911cb5e94e8d8d5131d646613ff82c14f5a8ce869de2f6d80d9889df8c5a"
@ -470,11 +470,11 @@
[[projects]]
branch = "master"
digest = "1:960f1fa3f12667fe595c15c12523718ed8b1b5428c83d70da54bb014da9a4c1a"
digest = "1:e43f1cb3f488a0c2be85939c2a594636f60b442a12a196c778bd2d6c9aca3df7"
name = "google.golang.org/genproto"
packages = ["googleapis/rpc/status"]
pruneopts = "T"
revision = "c66870c02cf823ceb633bcd05be3c7cda29976f4"
revision = "11092d34479b07829b72e10713b159248caf5dad"
[[projects]]
digest = "1:adafc60b1d4688759f3fc8f9089e71dd17abd123f4729de6b913bf08c9143770"
@ -548,6 +548,7 @@
"github.com/cosmos/cosmos-sdk/x/params",
"github.com/cosmos/cosmos-sdk/x/slashing",
"github.com/cosmos/cosmos-sdk/x/stake",
"github.com/cosmos/cosmos-sdk/x/stake/types",
"github.com/ethereum/go-ethereum/common",
"github.com/ethereum/go-ethereum/common/hexutil",
"github.com/ethereum/go-ethereum/common/math",
@ -568,6 +569,7 @@
"github.com/ethereum/go-ethereum/trie",
"github.com/hashicorp/golang-lru",
"github.com/pkg/errors",
"github.com/stretchr/testify/assert",
"github.com/stretchr/testify/require",
"github.com/stretchr/testify/suite",
"github.com/tendermint/tendermint/abci/types",

View File

@ -21,18 +21,18 @@ const (
// must implementing. Internal ante handlers will be dependant upon the
// transaction type.
type internalAnteHandler func(
sdkCtx sdk.Context, tx sdk.Tx, am auth.AccountMapper,
sdkCtx sdk.Context, tx sdk.Tx, accMapper auth.AccountMapper,
) (newCtx sdk.Context, res sdk.Result, abort bool)
// AnteHandler is responsible for attempting to route an Ethereum or SDK
// transaction to an internal ante handler for performing transaction-level
// processing (e.g. fee payment, signature verification) before being passed
// onto it's respective handler.
func AnteHandler(am auth.AccountMapper, _ auth.FeeCollectionKeeper) sdk.AnteHandler {
func AnteHandler(accMapper auth.AccountMapper, _ auth.FeeCollectionKeeper) sdk.AnteHandler {
return func(sdkCtx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
var (
gasLimit int64
handler internalAnteHandler
gasLimit int64
)
switch tx := tx.(type) {
@ -67,7 +67,7 @@ func AnteHandler(am auth.AccountMapper, _ auth.FeeCollectionKeeper) sdk.AnteHand
}
}()
return handler(newCtx, tx, am)
return handler(newCtx, tx, accMapper)
}
}
@ -76,7 +76,7 @@ func AnteHandler(am auth.AccountMapper, _ auth.FeeCollectionKeeper) sdk.AnteHand
//
// TODO: Do we need to do any further validation or account manipulation
// (e.g. increment nonce)?
func handleEthTx(sdkCtx sdk.Context, tx sdk.Tx, am auth.AccountMapper) (sdk.Context, sdk.Result, bool) {
func handleEthTx(sdkCtx sdk.Context, tx sdk.Tx, accMapper auth.AccountMapper) (sdk.Context, sdk.Result, bool) {
ethTx, ok := tx.(types.Transaction)
if !ok {
return sdkCtx, sdk.ErrInternal(fmt.Sprintf("invalid transaction: %T", tx)).Result(), true
@ -96,7 +96,7 @@ func handleEthTx(sdkCtx sdk.Context, tx sdk.Tx, am auth.AccountMapper) (sdk.Cont
return sdkCtx, sdk.ErrUnauthorized("signature verification failed").Result(), true
}
acc := am.GetAccount(sdkCtx, addr.Bytes())
acc := accMapper.GetAccount(sdkCtx, addr.Bytes())
// validate the account nonce (referred to as sequence in the AccountMapper)
seq := acc.GetSequence()
@ -109,13 +109,13 @@ func handleEthTx(sdkCtx sdk.Context, tx sdk.Tx, am auth.AccountMapper) (sdk.Cont
return sdkCtx, sdk.ErrInternal(err.Error()).Result(), true
}
am.SetAccount(sdkCtx, acc)
accMapper.SetAccount(sdkCtx, acc)
return sdkCtx, sdk.Result{GasWanted: int64(ethTx.Data().GasLimit)}, false
}
// handleEmbeddedTx implements an ante handler for an SDK transaction. It
// validates the signature and if valid returns an OK result.
func handleEmbeddedTx(sdkCtx sdk.Context, tx sdk.Tx, am auth.AccountMapper) (sdk.Context, sdk.Result, bool) {
func handleEmbeddedTx(sdkCtx sdk.Context, tx sdk.Tx, accMapper auth.AccountMapper) (sdk.Context, sdk.Result, bool) {
stdTx, ok := tx.(auth.StdTx)
if !ok {
return sdkCtx, sdk.ErrInternal(fmt.Sprintf("invalid transaction: %T", tx)).Result(), true
@ -132,14 +132,15 @@ func handleEmbeddedTx(sdkCtx sdk.Context, tx sdk.Tx, am auth.AccountMapper) (sdk
for i, sig := range stdTx.Signatures {
signer := ethcmn.BytesToAddress(signerAddrs[i].Bytes())
acc, err := validateSignature(sdkCtx, stdTx, signer, sig, am)
if err.Code() != sdk.CodeOK {
acc, err := validateSignature(sdkCtx, stdTx, signer, sig, accMapper)
// err.Code() != sdk.CodeOK
if err != nil {
return sdkCtx, err.Result(), true
}
// TODO: Fees!
am.SetAccount(sdkCtx, acc)
accMapper.SetAccount(sdkCtx, acc)
signerAccs[i] = acc
}
@ -166,12 +167,12 @@ func validateStdTxBasic(stdTx auth.StdTx) (err sdk.Error) {
func validateSignature(
sdkCtx sdk.Context, stdTx auth.StdTx, signer ethcmn.Address,
sig auth.StdSignature, am auth.AccountMapper,
sig auth.StdSignature, accMapper auth.AccountMapper,
) (acc auth.Account, sdkErr sdk.Error) {
chainID := sdkCtx.ChainID()
acc = am.GetAccount(sdkCtx, signer.Bytes())
acc = accMapper.GetAccount(sdkCtx, signer.Bytes())
if acc == nil {
return nil, sdk.ErrUnknownAddress(fmt.Sprintf("no account with address %s found", signer))
}

256
handlers/ante_test.go Normal file
View File

@ -0,0 +1,256 @@
package handlers
import (
"crypto/ecdsa"
"fmt"
"math/big"
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/ethermint/types"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
)
func TestEthTxBadSig(t *testing.T) {
tx := types.NewTransaction(uint64(0), types.TestAddr1, big.NewInt(10), 1000, big.NewInt(100), []byte{})
// create bad signature
tx.Sign(big.NewInt(100), types.TestPrivKey2)
ms, key := createTestMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
_, res, abort := handler(ctx, *tx)
require.True(t, abort, "expected ante handler to abort")
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
}
func TestEthTxInsufficientGas(t *testing.T) {
tx := types.NewTransaction(uint64(0), types.TestAddr1, big.NewInt(0), 0, big.NewInt(0), []byte{})
tx.Sign(types.TestChainID, types.TestPrivKey1)
ms, key := createTestMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
_, res, abort := handler(ctx, *tx)
require.True(t, abort, "expected ante handler to abort")
require.Equal(t, sdk.ABCICodeType(0x1000c), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
}
func TestEthTxIncorrectNonce(t *testing.T) {
// create transaction with wrong nonce 12
tx := types.NewTransaction(12, types.TestAddr2, big.NewInt(50), 1000, big.NewInt(1000), []byte("test_bytes"))
tx.Sign(types.TestChainID, types.TestPrivKey1)
ms, key := createTestMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, log.NewNopLogger())
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
// set account in accountMapper
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
accMapper.SetAccount(ctx, acc)
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
_, res, abort := handler(ctx, *tx)
require.True(t, abort, "expected ante handler to abort")
require.Equal(t, sdk.ABCICodeType(0x10003), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
}
func TestEthTxValidTx(t *testing.T) {
tx := types.NewTransaction(0, types.TestAddr1, big.NewInt(50), 1000, big.NewInt(1000), []byte{})
tx.Sign(types.TestChainID, types.TestPrivKey1)
ms, key := createTestMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
// set account in accountMapper
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
accMapper.SetAccount(ctx, acc)
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
_, res, abort := handler(ctx, *tx)
require.False(t, abort, "expected ante handler to not abort")
require.True(t, res.IsOK(), fmt.Sprintf("result not OK on valid Tx: %s", res.Log))
// ensure account state updated correctly
seq, _ := accMapper.GetSequence(ctx, types.TestAddr1[:])
require.Equal(t, int64(1), seq, "account nonce did not increment correctly")
}
func TestEmbeddedTxBadSig(t *testing.T) {
testCodec := types.NewTestCodec()
testFee := types.NewTestStdFee()
msgs := []sdk.Msg{sdk.NewTestMsg()}
tx := types.NewTestStdTx(
types.TestChainID, msgs, []int64{0}, []int64{0}, []*ecdsa.PrivateKey{types.TestPrivKey1}, testFee,
)
// create bad signature
signBytes := types.GetStdTxSignBytes(big.NewInt(100).String(), 1, 1, testFee, msgs, "")
sig, _ := ethcrypto.Sign(signBytes, types.TestPrivKey1)
(tx.(auth.StdTx)).Signatures[0].Signature = sig
ms, key := createTestMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
accMapper := auth.NewAccountMapper(testCodec, key, auth.ProtoBaseAccount)
// set account in accountMapper
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
accMapper.SetAccount(ctx, acc)
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
_, res, abort := handler(ctx, tx)
require.True(t, abort, "expected ante handler to abort")
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
}
func TestEmbeddedTxInvalidMultiMsg(t *testing.T) {
testCodec := types.NewTestCodec()
testCodec.RegisterConcrete(stake.MsgDelegate{}, "test/MsgDelegate", nil)
msgs := []sdk.Msg{
stake.NewMsgDelegate(types.TestAddr1.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
stake.NewMsgDelegate(types.TestAddr2.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
}
// create transaction with only one signer
tx := types.NewTestStdTx(
types.TestChainID, msgs, []int64{0}, []int64{0}, []*ecdsa.PrivateKey{types.TestPrivKey1}, types.NewTestStdFee(),
)
ms, key := createTestMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
accMapper := auth.NewAccountMapper(testCodec, key, auth.ProtoBaseAccount)
// set accounts in accountMapper
acc1 := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
accMapper.SetAccount(ctx, acc1)
acc2 := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
accMapper.SetAccount(ctx, acc2)
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
_, res, abort := handler(ctx, tx)
require.True(t, abort, "expected ante handler to abort")
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
}
func TestEmbeddedTxInvalidAccountNumber(t *testing.T) {
testCodec := types.NewTestCodec()
testCodec.RegisterConcrete(stake.MsgDelegate{}, "test/MsgDelegate", nil)
msgs := []sdk.Msg{
stake.NewMsgDelegate(types.TestAddr1.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
}
// create a transaction with an invalid account number
tx := types.NewTestStdTx(
types.TestChainID, msgs, []int64{3}, []int64{0}, []*ecdsa.PrivateKey{types.TestPrivKey1}, types.NewTestStdFee(),
)
ms, key := createTestMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
accMapper := auth.NewAccountMapper(testCodec, key, auth.ProtoBaseAccount)
// set account in accountMapper
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
acc.SetAccountNumber(4)
accMapper.SetAccount(ctx, acc)
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
_, res, abort := handler(ctx, tx)
require.True(t, abort, "expected ante handler to abort")
require.Equal(t, sdk.ABCICodeType(0x10003), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
}
func TestEmbeddedTxInvalidSequence(t *testing.T) {
testCodec := types.NewTestCodec()
testCodec.RegisterConcrete(stake.MsgDelegate{}, "test/MsgDelegate", nil)
msgs := []sdk.Msg{
stake.NewMsgDelegate(types.TestAddr1.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
}
// create transaction with an invalid sequence (nonce)
tx := types.NewTestStdTx(
types.TestChainID, msgs, []int64{4}, []int64{2}, []*ecdsa.PrivateKey{types.TestPrivKey1}, types.NewTestStdFee(),
)
ms, key := createTestMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
// set account in accountMapper
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
acc.SetAccountNumber(4)
acc.SetSequence(3)
accMapper.SetAccount(ctx, acc)
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
_, res, abort := handler(ctx, tx)
require.True(t, abort, "expected ante handler to abort")
require.Equal(t, sdk.ABCICodeType(0x10003), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
}
func TestEmbeddedTxValid(t *testing.T) {
testCodec := types.NewTestCodec()
testCodec.RegisterConcrete(stake.MsgDelegate{}, "test/MsgDelegate", nil)
msgs := []sdk.Msg{
stake.NewMsgDelegate(types.TestAddr1.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
stake.NewMsgDelegate(types.TestAddr2.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
}
// create a valid transaction
tx := types.NewTestStdTx(
types.TestChainID, msgs, []int64{4, 5}, []int64{3, 1},
[]*ecdsa.PrivateKey{types.TestPrivKey1, types.TestPrivKey2}, types.NewTestStdFee(),
)
ms, key := createTestMultiStore()
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
// set accounts in the accountMapper
acc1 := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
acc1.SetAccountNumber(4)
acc1.SetSequence(3)
accMapper.SetAccount(ctx, acc1)
acc2 := accMapper.NewAccountWithAddress(ctx, types.TestAddr2.Bytes())
acc2.SetAccountNumber(5)
acc2.SetSequence(1)
accMapper.SetAccount(ctx, acc2)
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
_, res, abort := handler(ctx, tx)
require.False(t, abort, "expected ante handler to not abort")
require.True(t, res.IsOK(), fmt.Sprintf("result not OK on valid Tx: %s", res.Log))
// Ensure account state updated correctly
seq1, _ := accMapper.GetSequence(ctx, types.TestAddr1.Bytes())
seq2, _ := accMapper.GetSequence(ctx, types.TestAddr2.Bytes())
require.Equal(t, int64(4), seq1, "account nonce did not increment correctly")
require.Equal(t, int64(2), seq2, "account nonce did not increment correctly")
}

18
handlers/test_common.go Normal file
View File

@ -0,0 +1,18 @@
package handlers
import (
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
dbm "github.com/tendermint/tendermint/libs/db"
)
func createTestMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) {
db := dbm.NewMemDB()
capKey := sdk.NewKVStoreKey("capkey")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.LoadLatestVersion()
return ms, capKey
}

View File

@ -40,7 +40,7 @@ func NewTestStdFee() auth.StdFee {
}
func NewTestStdTx(
chainID *big.Int, msgs []sdk.Msg, accNums []int64, seqs []int64, pKeys []*ecdsa.PrivateKey, fee auth.StdFee,
chainID *big.Int, msgs []sdk.Msg, accNums, seqs []int64, pKeys []*ecdsa.PrivateKey, fee auth.StdFee,
) sdk.Tx {
sigs := make([]auth.StdSignature, len(pKeys))
@ -100,22 +100,3 @@ func NewTestEthTxs(
return txs
}
func NewTestSDKTxs(
codec *wire.Codec, chainID *big.Int, to ethcmn.Address, msgs []sdk.Msg,
accNums []int64, seqs []int64, pKeys []*ecdsa.PrivateKey, fee auth.StdFee,
) []*Transaction {
txs := make([]*Transaction, len(pKeys))
stdTx := NewTestStdTx(chainID, msgs, accNums, seqs, pKeys, fee)
payload := codec.MustMarshalBinary(stdTx)
for i, privKey := range pKeys {
ethTx := NewTransaction(uint64(seqs[i]), to, big.NewInt(10), 1000, big.NewInt(100), payload)
ethTx.Sign(chainID, privKey)
txs[i] = ethTx
}
return txs
}

View File

@ -120,16 +120,14 @@ func TestTxDecoder(t *testing.T) {
require.Equal(t, txs[0].data, (decodedTx.(Transaction)).data)
// create a SDK (auth.StdTx) transaction and encode
txs = NewTestSDKTxs(
testCodec, TestChainID, TestSDKAddr, msgs, []int64{0}, []int64{0},
[]*ecdsa.PrivateKey{TestPrivKey1}, NewTestStdFee(),
)
stdTx := NewTestStdTx(TestChainID, msgs, []int64{0}, []int64{0}, []*ecdsa.PrivateKey{TestPrivKey1}, NewTestStdFee())
payload := testCodec.MustMarshalBinary(stdTx)
tx := NewTransaction(0, TestSDKAddr, big.NewInt(10), 1000, big.NewInt(100), payload)
txBytes, err = rlp.EncodeToBytes(txs[0])
txBytes, err = rlp.EncodeToBytes(tx)
require.NoError(t, err)
// require the transaction to properly decode into a Transaction
stdTx := NewTestStdTx(TestChainID, msgs, []int64{0}, []int64{0}, []*ecdsa.PrivateKey{TestPrivKey1}, NewTestStdFee())
decodedTx, err = txDecoder(txBytes)
require.NoError(t, err)
require.IsType(t, auth.StdTx{}, decodedTx)

View File

@ -15,5 +15,6 @@ func init() {
// codec.
func RegisterWire(codec *wire.Codec) {
sdk.RegisterWire(codec)
codec.RegisterConcrete(&Transaction{}, "types/Transaction", nil)
codec.RegisterConcrete(&Account{}, "types/Account", nil)
}