Update ante handler unit tests
This commit is contained in:
parent
e2c0645a10
commit
e83a2b97f9
@ -21,14 +21,14 @@ const (
|
|||||||
// must implementing. Internal ante handlers will be dependant upon the
|
// must implementing. Internal ante handlers will be dependant upon the
|
||||||
// transaction type.
|
// transaction type.
|
||||||
type internalAnteHandler func(
|
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)
|
) (newCtx sdk.Context, res sdk.Result, abort bool)
|
||||||
|
|
||||||
// AnteHandler is responsible for attempting to route an Ethereum or SDK
|
// AnteHandler is responsible for attempting to route an Ethereum or SDK
|
||||||
// transaction to an internal ante handler for performing transaction-level
|
// transaction to an internal ante handler for performing transaction-level
|
||||||
// processing (e.g. fee payment, signature verification) before being passed
|
// processing (e.g. fee payment, signature verification) before being passed
|
||||||
// onto it's respective handler.
|
// 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) {
|
return func(sdkCtx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||||
var (
|
var (
|
||||||
handler internalAnteHandler
|
handler internalAnteHandler
|
||||||
@ -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
|
// TODO: Do we need to do any further validation or account manipulation
|
||||||
// (e.g. increment nonce)?
|
// (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)
|
ethTx, ok := tx.(types.Transaction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return sdkCtx, sdk.ErrInternal(fmt.Sprintf("invalid transaction: %T", tx)).Result(), true
|
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
|
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)
|
// validate the account nonce (referred to as sequence in the AccountMapper)
|
||||||
seq := acc.GetSequence()
|
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
|
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
|
return sdkCtx, sdk.Result{GasWanted: int64(ethTx.Data().GasLimit)}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleEmbeddedTx implements an ante handler for an SDK transaction. It
|
// handleEmbeddedTx implements an ante handler for an SDK transaction. It
|
||||||
// validates the signature and if valid returns an OK result.
|
// 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)
|
stdTx, ok := tx.(auth.StdTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return sdkCtx, sdk.ErrInternal(fmt.Sprintf("invalid transaction: %T", tx)).Result(), true
|
return sdkCtx, sdk.ErrInternal(fmt.Sprintf("invalid transaction: %T", tx)).Result(), true
|
||||||
@ -132,7 +132,7 @@ func handleEmbeddedTx(sdkCtx sdk.Context, tx sdk.Tx, am auth.AccountMapper) (sdk
|
|||||||
for i, sig := range stdTx.Signatures {
|
for i, sig := range stdTx.Signatures {
|
||||||
signer := ethcmn.BytesToAddress(signerAddrs[i].Bytes())
|
signer := ethcmn.BytesToAddress(signerAddrs[i].Bytes())
|
||||||
|
|
||||||
acc, err := validateSignature(sdkCtx, stdTx, signer, sig, am)
|
acc, err := validateSignature(sdkCtx, stdTx, signer, sig, accMapper)
|
||||||
// err.Code() != sdk.CodeOK
|
// err.Code() != sdk.CodeOK
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sdkCtx, err.Result(), true
|
return sdkCtx, err.Result(), true
|
||||||
@ -140,7 +140,7 @@ func handleEmbeddedTx(sdkCtx sdk.Context, tx sdk.Tx, am auth.AccountMapper) (sdk
|
|||||||
|
|
||||||
// TODO: Fees!
|
// TODO: Fees!
|
||||||
|
|
||||||
am.SetAccount(sdkCtx, acc)
|
accMapper.SetAccount(sdkCtx, acc)
|
||||||
signerAccs[i] = acc
|
signerAccs[i] = acc
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,12 +167,12 @@ func validateStdTxBasic(stdTx auth.StdTx) (err sdk.Error) {
|
|||||||
|
|
||||||
func validateSignature(
|
func validateSignature(
|
||||||
sdkCtx sdk.Context, stdTx auth.StdTx, signer ethcmn.Address,
|
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) {
|
) (acc auth.Account, sdkErr sdk.Error) {
|
||||||
|
|
||||||
chainID := sdkCtx.ChainID()
|
chainID := sdkCtx.ChainID()
|
||||||
|
|
||||||
acc = am.GetAccount(sdkCtx, signer.Bytes())
|
acc = accMapper.GetAccount(sdkCtx, signer.Bytes())
|
||||||
if acc == nil {
|
if acc == nil {
|
||||||
return nil, sdk.ErrUnknownAddress(fmt.Sprintf("no account with address %s found", signer))
|
return nil, sdk.ErrUnknownAddress(fmt.Sprintf("no account with address %s found", signer))
|
||||||
}
|
}
|
||||||
|
@ -1,266 +1,256 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"math/big"
|
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/cosmos/ethermint/types"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
stake "github.com/cosmos/cosmos-sdk/x/stake/types"
|
"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"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
|
||||||
ethcmn "github.com/ethereum/go-ethereum/common"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test EthTx Antehandler
|
func TestEthTxBadSig(t *testing.T) {
|
||||||
// -----------------------------------------------------------------------------------------------------------------------------------
|
tx := types.NewTransaction(uint64(0), types.TestAddr1, big.NewInt(10), 1000, big.NewInt(100), []byte{})
|
||||||
|
|
||||||
func TestBadSig(t *testing.T) {
|
// create bad signature
|
||||||
tx := types.NewTestEthTxs(types.TestChainID, []*ecdsa.PrivateKey{types.TestPrivKey1}, []ethcmn.Address{types.TestAddr1})[0]
|
tx.Sign(big.NewInt(100), types.TestPrivKey2)
|
||||||
|
|
||||||
tx.Data.Signature = types.NewEthSignature(new(big.Int), new(big.Int), new(big.Int))
|
ms, key := createTestMultiStore()
|
||||||
|
|
||||||
ms, key := SetupMultiStore()
|
|
||||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
||||||
|
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
||||||
|
|
||||||
accountMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
|
||||||
handler := AnteHandler(accountMapper)
|
_, res, abort := handler(ctx, *tx)
|
||||||
|
|
||||||
_, res, abort := handler(ctx, tx)
|
|
||||||
|
|
||||||
assert.True(t, abort, "Antehandler did not abort")
|
|
||||||
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, fmt.Sprintf("Result has wrong code on bad tx: %s", res.Log))
|
|
||||||
|
|
||||||
|
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 TestInsufficientGas(t *testing.T) {
|
func TestEthTxInsufficientGas(t *testing.T) {
|
||||||
tx := types.NewTestEthTxs(types.TestChainID, []*ecdsa.PrivateKey{types.TestPrivKey1}, []ethcmn.Address{types.TestAddr1})[0]
|
tx := types.NewTransaction(uint64(0), types.TestAddr1, big.NewInt(0), 0, big.NewInt(0), []byte{})
|
||||||
|
|
||||||
tx.Data.GasLimit = 0
|
|
||||||
|
|
||||||
ms, key := SetupMultiStore()
|
|
||||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
|
||||||
|
|
||||||
accountMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
|
||||||
handler := AnteHandler(accountMapper)
|
|
||||||
|
|
||||||
_, res, abort := handler(ctx, tx)
|
|
||||||
|
|
||||||
assert.True(t, abort, "Antehandler did not abort")
|
|
||||||
require.Equal(t, sdk.ABCICodeType(0x1000c), res.Code, fmt.Sprintf("Result has wrong code on bad tx: %s", res.Log))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIncorrectNonce(t *testing.T) {
|
|
||||||
// Create transaction with wrong nonce 12
|
|
||||||
tx := types.NewTransaction(12, types.TestAddr2, sdk.NewInt(50), 1000, sdk.NewInt(1000), []byte("test_bytes"))
|
|
||||||
tx.Sign(types.TestChainID, types.TestPrivKey1)
|
tx.Sign(types.TestChainID, types.TestPrivKey1)
|
||||||
|
|
||||||
ms, key := SetupMultiStore()
|
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())
|
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, log.NewNopLogger())
|
||||||
|
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
||||||
|
|
||||||
accountMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
// set account in accountMapper
|
||||||
|
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
|
||||||
|
accMapper.SetAccount(ctx, acc)
|
||||||
|
|
||||||
// Set account in accountMapper
|
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
|
||||||
acc := accountMapper.NewAccountWithAddress(ctx, types.TestAddr1[:])
|
_, res, abort := handler(ctx, *tx)
|
||||||
accountMapper.SetAccount(ctx, acc)
|
|
||||||
|
|
||||||
handler := AnteHandler(accountMapper)
|
|
||||||
|
|
||||||
_, res, abort := handler(ctx, tx)
|
|
||||||
|
|
||||||
assert.True(t, abort, "Antehandler did not abort")
|
|
||||||
require.Equal(t, sdk.ABCICodeType(0x10003), res.Code, fmt.Sprintf("Result has wrong code on bad tx: %s", res.Log))
|
|
||||||
|
|
||||||
|
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 TestValidTx(t *testing.T) {
|
func TestEthTxValidTx(t *testing.T) {
|
||||||
tx := types.NewTestEthTxs(types.TestChainID, []*ecdsa.PrivateKey{types.TestPrivKey1}, []ethcmn.Address{types.TestAddr1})[0]
|
tx := types.NewTransaction(0, types.TestAddr1, big.NewInt(50), 1000, big.NewInt(1000), []byte{})
|
||||||
|
tx.Sign(types.TestChainID, types.TestPrivKey1)
|
||||||
|
|
||||||
ms, key := SetupMultiStore()
|
ms, key := createTestMultiStore()
|
||||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
||||||
|
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
||||||
|
|
||||||
accountMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
// set account in accountMapper
|
||||||
|
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
|
||||||
|
accMapper.SetAccount(ctx, acc)
|
||||||
|
|
||||||
// Set account in accountMapper
|
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
|
||||||
acc := accountMapper.NewAccountWithAddress(ctx, types.TestAddr1[:])
|
_, res, abort := handler(ctx, *tx)
|
||||||
accountMapper.SetAccount(ctx, acc)
|
|
||||||
|
|
||||||
handler := AnteHandler(accountMapper)
|
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))
|
||||||
|
|
||||||
_, res, abort := handler(ctx, tx)
|
// ensure account state updated correctly
|
||||||
|
seq, _ := accMapper.GetSequence(ctx, types.TestAddr1[:])
|
||||||
assert.False(t, abort, "Antehandler abort on valid tx")
|
require.Equal(t, int64(1), seq, "account nonce did not increment correctly")
|
||||||
require.True(t, res.IsOK(), fmt.Sprintf("Result not OK on valid Tx: %s", res.Log))
|
|
||||||
|
|
||||||
// Ensure account state updated correctly
|
|
||||||
seq, _ := accountMapper.GetSequence(ctx, types.TestAddr1[:])
|
|
||||||
require.Equal(t, int64(1), seq, "AccountNonce did not increment correctly")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test EmbeddedTx Antehandler
|
func TestEmbeddedTxBadSig(t *testing.T) {
|
||||||
// -----------------------------------------------------------------------------------------------------------------------------------
|
testCodec := types.NewTestCodec()
|
||||||
|
testFee := types.NewTestStdFee()
|
||||||
|
|
||||||
func TestInvalidSigEmbeddedTx(t *testing.T) {
|
msgs := []sdk.Msg{sdk.NewTestMsg()}
|
||||||
// Create msg to be embedded
|
tx := types.NewTestStdTx(
|
||||||
msgs := []sdk.Msg{stake.NewMsgDelegate(types.TestAddr1[:], types.TestAddr2[:], sdk.Coin{"steak", sdk.NewInt(50)})}
|
types.TestChainID, msgs, []int64{0}, []int64{0}, []*ecdsa.PrivateKey{types.TestPrivKey1}, testFee,
|
||||||
|
)
|
||||||
|
|
||||||
// Create transaction with incorrect signer
|
// create bad signature
|
||||||
tx := types.NewTestEmbeddedTx(types.TestChainID, msgs, []*ecdsa.PrivateKey{types.TestPrivKey2},
|
signBytes := types.GetStdTxSignBytes(big.NewInt(100).String(), 1, 1, testFee, msgs, "")
|
||||||
[]int64{0}, []int64{0}, types.NewStdFee())
|
sig, _ := ethcrypto.Sign(signBytes, types.TestPrivKey1)
|
||||||
|
(tx.(auth.StdTx)).Signatures[0].Signature = sig
|
||||||
|
|
||||||
ms, key := SetupMultiStore()
|
ms, key := createTestMultiStore()
|
||||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
||||||
|
accMapper := auth.NewAccountMapper(testCodec, key, auth.ProtoBaseAccount)
|
||||||
|
|
||||||
accountMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
// set account in accountMapper
|
||||||
|
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
|
||||||
// Set account in accountMapper
|
accMapper.SetAccount(ctx, acc)
|
||||||
acc := accountMapper.NewAccountWithAddress(ctx, types.TestAddr1[:])
|
|
||||||
accountMapper.SetAccount(ctx, acc)
|
|
||||||
|
|
||||||
handler := AnteHandler(accountMapper)
|
|
||||||
|
|
||||||
|
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
|
||||||
_, res, abort := handler(ctx, tx)
|
_, res, abort := handler(ctx, tx)
|
||||||
|
|
||||||
assert.True(t, abort, "Antehandler did not abort on invalid embedded tx")
|
require.True(t, abort, "expected ante handler to abort")
|
||||||
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, "Result is OK on bad tx")
|
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidMultiMsgEmbeddedTx(t *testing.T) {
|
func TestEmbeddedTxInvalidMultiMsg(t *testing.T) {
|
||||||
// Create msg to be embedded
|
testCodec := types.NewTestCodec()
|
||||||
|
testCodec.RegisterConcrete(stake.MsgDelegate{}, "test/MsgDelegate", nil)
|
||||||
|
|
||||||
msgs := []sdk.Msg{
|
msgs := []sdk.Msg{
|
||||||
stake.NewMsgDelegate(types.TestAddr1[:], types.TestAddr2[:], sdk.Coin{"steak", sdk.NewInt(50)}),
|
stake.NewMsgDelegate(types.TestAddr1.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
|
||||||
stake.NewMsgDelegate(types.TestAddr2[:], types.TestAddr2[:], sdk.Coin{"steak", sdk.NewInt(50)}),
|
stake.NewMsgDelegate(types.TestAddr2.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create transaction with only one signer
|
// create transaction with only one signer
|
||||||
tx := types.NewTestEmbeddedTx(types.TestChainID, msgs, []*ecdsa.PrivateKey{types.TestPrivKey1},
|
tx := types.NewTestStdTx(
|
||||||
[]int64{0}, []int64{0}, types.NewStdFee())
|
types.TestChainID, msgs, []int64{0}, []int64{0}, []*ecdsa.PrivateKey{types.TestPrivKey1}, types.NewTestStdFee(),
|
||||||
|
)
|
||||||
|
|
||||||
ms, key := SetupMultiStore()
|
ms, key := createTestMultiStore()
|
||||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
||||||
|
accMapper := auth.NewAccountMapper(testCodec, key, auth.ProtoBaseAccount)
|
||||||
|
|
||||||
accountMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
// set accounts in accountMapper
|
||||||
|
acc1 := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
|
||||||
|
accMapper.SetAccount(ctx, acc1)
|
||||||
|
|
||||||
// Set account in accountMapper
|
acc2 := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
|
||||||
acc1 := accountMapper.NewAccountWithAddress(ctx, types.TestAddr1[:])
|
accMapper.SetAccount(ctx, acc2)
|
||||||
accountMapper.SetAccount(ctx, acc1)
|
|
||||||
acc2 := accountMapper.NewAccountWithAddress(ctx, types.TestAddr1[:])
|
|
||||||
accountMapper.SetAccount(ctx, acc2)
|
|
||||||
|
|
||||||
handler := AnteHandler(accountMapper)
|
|
||||||
|
|
||||||
|
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
|
||||||
_, res, abort := handler(ctx, tx)
|
_, res, abort := handler(ctx, tx)
|
||||||
|
|
||||||
assert.True(t, abort, "Antehandler did not abort on invalid embedded tx")
|
require.True(t, abort, "expected ante handler to abort")
|
||||||
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, "Result is OK on bad tx")
|
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidAccountNumberEmbeddedTx(t *testing.T) {
|
func TestEmbeddedTxInvalidAccountNumber(t *testing.T) {
|
||||||
// Create msg to be embedded
|
testCodec := types.NewTestCodec()
|
||||||
|
testCodec.RegisterConcrete(stake.MsgDelegate{}, "test/MsgDelegate", nil)
|
||||||
|
|
||||||
msgs := []sdk.Msg{
|
msgs := []sdk.Msg{
|
||||||
stake.NewMsgDelegate(types.TestAddr1[:], types.TestAddr2[:], sdk.Coin{"steak", sdk.NewInt(50)}),
|
stake.NewMsgDelegate(types.TestAddr1.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create transaction with wrong account number
|
// create a transaction with an invalid account number
|
||||||
tx := types.NewTestEmbeddedTx(types.TestChainID, msgs, []*ecdsa.PrivateKey{types.TestPrivKey1},
|
tx := types.NewTestStdTx(
|
||||||
[]int64{3}, []int64{0}, types.NewStdFee())
|
types.TestChainID, msgs, []int64{3}, []int64{0}, []*ecdsa.PrivateKey{types.TestPrivKey1}, types.NewTestStdFee(),
|
||||||
|
)
|
||||||
|
|
||||||
ms, key := SetupMultiStore()
|
ms, key := createTestMultiStore()
|
||||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
||||||
|
accMapper := auth.NewAccountMapper(testCodec, key, auth.ProtoBaseAccount)
|
||||||
|
|
||||||
accountMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
// set account in accountMapper
|
||||||
|
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
|
||||||
// Set account in accountMapper
|
|
||||||
acc := accountMapper.NewAccountWithAddress(ctx, types.TestAddr1[:])
|
|
||||||
acc.SetAccountNumber(4)
|
acc.SetAccountNumber(4)
|
||||||
accountMapper.SetAccount(ctx, acc)
|
accMapper.SetAccount(ctx, acc)
|
||||||
|
|
||||||
handler := AnteHandler(accountMapper)
|
|
||||||
|
|
||||||
|
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
|
||||||
_, res, abort := handler(ctx, tx)
|
_, res, abort := handler(ctx, tx)
|
||||||
|
|
||||||
assert.True(t, abort, "Antehandler did not abort on invalid embedded tx")
|
require.True(t, abort, "expected ante handler to abort")
|
||||||
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, "Result is OK on bad tx")
|
require.Equal(t, sdk.ABCICodeType(0x10003), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidSequenceEmbeddedTx(t *testing.T) {
|
func TestEmbeddedTxInvalidSequence(t *testing.T) {
|
||||||
// Create msg to be embedded
|
testCodec := types.NewTestCodec()
|
||||||
|
testCodec.RegisterConcrete(stake.MsgDelegate{}, "test/MsgDelegate", nil)
|
||||||
|
|
||||||
msgs := []sdk.Msg{
|
msgs := []sdk.Msg{
|
||||||
stake.NewMsgDelegate(types.TestAddr1[:], types.TestAddr2[:], sdk.Coin{"steak", sdk.NewInt(50)}),
|
stake.NewMsgDelegate(types.TestAddr1.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create transaction with wrong account number
|
// create transaction with an invalid sequence (nonce)
|
||||||
tx := types.NewTestEmbeddedTx(types.TestChainID, msgs, []*ecdsa.PrivateKey{types.TestPrivKey1},
|
tx := types.NewTestStdTx(
|
||||||
[]int64{4}, []int64{2}, types.NewStdFee())
|
types.TestChainID, msgs, []int64{4}, []int64{2}, []*ecdsa.PrivateKey{types.TestPrivKey1}, types.NewTestStdFee(),
|
||||||
|
)
|
||||||
|
|
||||||
ms, key := SetupMultiStore()
|
ms, key := createTestMultiStore()
|
||||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
||||||
|
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
||||||
|
|
||||||
accountMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
// set account in accountMapper
|
||||||
|
acc := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
|
||||||
// Set account in accountMapper
|
|
||||||
acc := accountMapper.NewAccountWithAddress(ctx, types.TestAddr1[:])
|
|
||||||
acc.SetAccountNumber(4)
|
acc.SetAccountNumber(4)
|
||||||
acc.SetSequence(3)
|
acc.SetSequence(3)
|
||||||
accountMapper.SetAccount(ctx, acc)
|
accMapper.SetAccount(ctx, acc)
|
||||||
|
|
||||||
handler := AnteHandler(accountMapper)
|
|
||||||
|
|
||||||
|
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
|
||||||
_, res, abort := handler(ctx, tx)
|
_, res, abort := handler(ctx, tx)
|
||||||
|
|
||||||
assert.True(t, abort, "Antehandler did not abort on invalid embedded tx")
|
require.True(t, abort, "expected ante handler to abort")
|
||||||
require.Equal(t, sdk.ABCICodeType(0x10004), res.Code, "Result is OK on bad tx")
|
require.Equal(t, sdk.ABCICodeType(0x10003), res.Code, fmt.Sprintf("invalid code returned on bad tx: %s", res.Log))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidEmbeddedTx(t *testing.T) {
|
func TestEmbeddedTxValid(t *testing.T) {
|
||||||
// Create msg to be embedded
|
testCodec := types.NewTestCodec()
|
||||||
|
testCodec.RegisterConcrete(stake.MsgDelegate{}, "test/MsgDelegate", nil)
|
||||||
|
|
||||||
msgs := []sdk.Msg{
|
msgs := []sdk.Msg{
|
||||||
stake.NewMsgDelegate(types.TestAddr1[:], types.TestAddr2[:], sdk.Coin{"steak", sdk.NewInt(50)}),
|
stake.NewMsgDelegate(types.TestAddr1.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
|
||||||
stake.NewMsgDelegate(types.TestAddr2[:], types.TestAddr2[:], sdk.Coin{"steak", sdk.NewInt(50)}),
|
stake.NewMsgDelegate(types.TestAddr2.Bytes(), types.TestAddr2.Bytes(), sdk.NewCoin("steak", sdk.NewInt(50))),
|
||||||
}
|
}
|
||||||
|
|
||||||
tx := types.NewTestEmbeddedTx(types.TestChainID, msgs, []*ecdsa.PrivateKey{types.TestPrivKey1, types.TestPrivKey2},
|
// create a valid transaction
|
||||||
[]int64{4, 5}, []int64{3, 1}, types.NewStdFee())
|
tx := types.NewTestStdTx(
|
||||||
|
types.TestChainID, msgs, []int64{4, 5}, []int64{3, 1},
|
||||||
|
[]*ecdsa.PrivateKey{types.TestPrivKey1, types.TestPrivKey2}, types.NewTestStdFee(),
|
||||||
|
)
|
||||||
|
|
||||||
ms, key := SetupMultiStore()
|
ms, key := createTestMultiStore()
|
||||||
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
ctx := sdk.NewContext(ms, abci.Header{ChainID: types.TestChainID.String()}, false, nil)
|
||||||
|
accMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
||||||
|
|
||||||
accountMapper := auth.NewAccountMapper(types.NewTestCodec(), key, auth.ProtoBaseAccount)
|
// set accounts in the accountMapper
|
||||||
|
acc1 := accMapper.NewAccountWithAddress(ctx, types.TestAddr1.Bytes())
|
||||||
// Set account in accountMapper
|
|
||||||
acc1 := accountMapper.NewAccountWithAddress(ctx, types.TestAddr1[:])
|
|
||||||
acc1.SetAccountNumber(4)
|
acc1.SetAccountNumber(4)
|
||||||
acc1.SetSequence(3)
|
acc1.SetSequence(3)
|
||||||
accountMapper.SetAccount(ctx, acc1)
|
accMapper.SetAccount(ctx, acc1)
|
||||||
acc2 := accountMapper.NewAccountWithAddress(ctx, types.TestAddr2[:])
|
|
||||||
|
acc2 := accMapper.NewAccountWithAddress(ctx, types.TestAddr2.Bytes())
|
||||||
acc2.SetAccountNumber(5)
|
acc2.SetAccountNumber(5)
|
||||||
acc2.SetSequence(1)
|
acc2.SetSequence(1)
|
||||||
accountMapper.SetAccount(ctx, acc2)
|
accMapper.SetAccount(ctx, acc2)
|
||||||
|
|
||||||
handler := AnteHandler(accountMapper)
|
|
||||||
|
|
||||||
|
handler := AnteHandler(accMapper, auth.FeeCollectionKeeper{})
|
||||||
_, res, abort := handler(ctx, tx)
|
_, res, abort := handler(ctx, tx)
|
||||||
|
|
||||||
require.False(t, abort, "Antehandler abort on valid embedded 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))
|
require.True(t, res.IsOK(), fmt.Sprintf("result not OK on valid Tx: %s", res.Log))
|
||||||
|
|
||||||
// Ensure account state updated correctly
|
// Ensure account state updated correctly
|
||||||
seq1, _ := accountMapper.GetSequence(ctx, types.TestAddr1[:])
|
seq1, _ := accMapper.GetSequence(ctx, types.TestAddr1.Bytes())
|
||||||
seq2, _ := accountMapper.GetSequence(ctx, types.TestAddr2[:])
|
seq2, _ := accMapper.GetSequence(ctx, types.TestAddr2.Bytes())
|
||||||
|
|
||||||
assert.Equal(t, int64(4), seq1, "Sequence1 did not increment correctly")
|
|
||||||
assert.Equal(t, int64(2), seq2, "Sequence2 did not increment correctly")
|
|
||||||
|
|
||||||
|
require.Equal(t, int64(4), seq1, "account nonce did not increment correctly")
|
||||||
|
require.Equal(t, int64(2), seq2, "account nonce did not increment correctly")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,11 +6,13 @@ import (
|
|||||||
dbm "github.com/tendermint/tendermint/libs/db"
|
dbm "github.com/tendermint/tendermint/libs/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) {
|
func createTestMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) {
|
||||||
db := dbm.NewMemDB()
|
db := dbm.NewMemDB()
|
||||||
capKey := sdk.NewKVStoreKey("capkey")
|
capKey := sdk.NewKVStoreKey("capkey")
|
||||||
ms := store.NewCommitMultiStore(db)
|
ms := store.NewCommitMultiStore(db)
|
||||||
|
|
||||||
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
|
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
|
||||||
ms.LoadLatestVersion()
|
ms.LoadLatestVersion()
|
||||||
|
|
||||||
return ms, capKey
|
return ms, capKey
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func NewTestStdFee() auth.StdFee {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewTestStdTx(
|
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 {
|
) sdk.Tx {
|
||||||
|
|
||||||
sigs := make([]auth.StdSignature, len(pKeys))
|
sigs := make([]auth.StdSignature, len(pKeys))
|
||||||
@ -100,22 +100,3 @@ func NewTestEthTxs(
|
|||||||
|
|
||||||
return txs
|
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
|
|
||||||
}
|
|
||||||
|
@ -120,16 +120,14 @@ func TestTxDecoder(t *testing.T) {
|
|||||||
require.Equal(t, txs[0].data, (decodedTx.(Transaction)).data)
|
require.Equal(t, txs[0].data, (decodedTx.(Transaction)).data)
|
||||||
|
|
||||||
// create a SDK (auth.StdTx) transaction and encode
|
// create a SDK (auth.StdTx) transaction and encode
|
||||||
txs = NewTestSDKTxs(
|
stdTx := NewTestStdTx(TestChainID, msgs, []int64{0}, []int64{0}, []*ecdsa.PrivateKey{TestPrivKey1}, NewTestStdFee())
|
||||||
testCodec, TestChainID, TestSDKAddr, msgs, []int64{0}, []int64{0},
|
payload := testCodec.MustMarshalBinary(stdTx)
|
||||||
[]*ecdsa.PrivateKey{TestPrivKey1}, NewTestStdFee(),
|
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.NoError(t, err)
|
||||||
|
|
||||||
// require the transaction to properly decode into a Transaction
|
// 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)
|
decodedTx, err = txDecoder(txBytes)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.IsType(t, auth.StdTx{}, decodedTx)
|
require.IsType(t, auth.StdTx{}, decodedTx)
|
||||||
|
Loading…
Reference in New Issue
Block a user