laconicd-deprecated/handlers/ante_test.go
2018-08-31 16:44:34 -04:00

257 lines
9.9 KiB
Go

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")
}