forked from cerc-io/laconicd-deprecated
9e5f4aaa73
* test: add preliminary unit tests and additional mocks for chain_info, account_info and filters * tests: added additional mocked client calls * tests: bumped coverage of call_tx to 56% and chain_info to 77% * tests: bumped call_tx coverage to 70.2% and added additional mock client calls * tests: tx_info preliminary tests added for debugging. * tests: added test coverage for sign_tx and additional mocks * tests: tx_info test coverage bumped to 60.3% * test: coverage for tracing_tests now at 72% * tests: added fee makert query client mocks and bumped chain_info to 87.6% coverage. * tests: failing Cosmos auth module account query. * tests: added FeeMarket Params mock to call_tx_test * cleanup some unused code * tests: added helper function to test suite for signing a Tx and bumped coverage of tx_info to 71.2% * test: commented GetAccount error case and bumped chain_info to 90.3% coverage * test: cleanup of tests in node_info, sign_tx and account_info * Clean up print Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Apply suggestions from code review * fix import issues Co-authored-by: Vladislav Varadinov <vlad@evmos.org> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Freddy Caceres <facs95@gmail.com>
248 lines
8.2 KiB
Go
248 lines
8.2 KiB
Go
package backend
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/cosmos/cosmos-sdk/crypto"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
|
"github.com/evmos/ethermint/crypto/ethsecp256k1"
|
|
"github.com/evmos/ethermint/indexer"
|
|
"github.com/evmos/ethermint/rpc/backend/mocks"
|
|
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
tmlog "github.com/tendermint/tendermint/libs/log"
|
|
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
|
|
"github.com/tendermint/tendermint/types"
|
|
tmtypes "github.com/tendermint/tendermint/types"
|
|
dbm "github.com/tendermint/tm-db"
|
|
)
|
|
|
|
func (suite *BackendTestSuite) TestTraceTransaction() {
|
|
msgEthereumTx, _ := suite.buildEthereumTx()
|
|
msgEthereumTx2, _ := suite.buildEthereumTx()
|
|
|
|
txHash := msgEthereumTx.AsTransaction().Hash()
|
|
txHash2 := msgEthereumTx2.AsTransaction().Hash()
|
|
|
|
priv, _ := ethsecp256k1.GenerateKey()
|
|
from := common.BytesToAddress(priv.PubKey().Address().Bytes())
|
|
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterParamsWithoutHeader(queryClient, 1)
|
|
|
|
armor := crypto.EncryptArmorPrivKey(priv, "", "eth_secp256k1")
|
|
suite.backend.clientCtx.Keyring.ImportPrivKey("test_key", armor, "")
|
|
ethSigner := ethtypes.LatestSigner(suite.backend.ChainConfig())
|
|
|
|
txEncoder := suite.backend.clientCtx.TxConfig.TxEncoder()
|
|
|
|
msgEthereumTx.From = from.String()
|
|
msgEthereumTx.Sign(ethSigner, suite.signer)
|
|
tx, _ := msgEthereumTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton")
|
|
txBz, _ := txEncoder(tx)
|
|
|
|
msgEthereumTx2.From = from.String()
|
|
msgEthereumTx2.Sign(ethSigner, suite.signer)
|
|
tx2, _ := msgEthereumTx.BuildTx(suite.backend.clientCtx.TxConfig.NewTxBuilder(), "aphoton")
|
|
txBz2, _ := txEncoder(tx2)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
registerMock func()
|
|
block *types.Block
|
|
responseBlock []*abci.ResponseDeliverTx
|
|
expResult interface{}
|
|
expPass bool
|
|
}{
|
|
{
|
|
"fail - tx not found",
|
|
func() {},
|
|
&types.Block{Header: types.Header{Height: 1}, Data: types.Data{Txs: []types.Tx{}}},
|
|
[]*abci.ResponseDeliverTx{
|
|
{
|
|
Code: 0,
|
|
Events: []abci.Event{
|
|
{Type: evmtypes.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
|
|
{Key: []byte("ethereumTxHash"), Value: []byte(txHash.Hex())},
|
|
{Key: []byte("txIndex"), Value: []byte("0")},
|
|
{Key: []byte("amount"), Value: []byte("1000")},
|
|
{Key: []byte("txGasUsed"), Value: []byte("21000")},
|
|
{Key: []byte("txHash"), Value: []byte("")},
|
|
{Key: []byte("recipient"), Value: []byte("0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7")},
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
false,
|
|
},
|
|
{
|
|
"fail - block not found",
|
|
func() {
|
|
//var header metadata.MD
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
RegisterBlockError(client, 1)
|
|
},
|
|
&types.Block{Header: types.Header{Height: 1}, Data: types.Data{Txs: []types.Tx{txBz}}},
|
|
[]*abci.ResponseDeliverTx{
|
|
{
|
|
Code: 0,
|
|
Events: []abci.Event{
|
|
{Type: evmtypes.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
|
|
{Key: []byte("ethereumTxHash"), Value: []byte(txHash.Hex())},
|
|
{Key: []byte("txIndex"), Value: []byte("0")},
|
|
{Key: []byte("amount"), Value: []byte("1000")},
|
|
{Key: []byte("txGasUsed"), Value: []byte("21000")},
|
|
{Key: []byte("txHash"), Value: []byte("")},
|
|
{Key: []byte("recipient"), Value: []byte("0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7")},
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
map[string]interface{}{"test": "hello"},
|
|
false,
|
|
},
|
|
{
|
|
"pass - transaction found in a block with multiple transactions",
|
|
func() {
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
RegisterBlockMultipleTxs(client, 1, []types.Tx{txBz, txBz2})
|
|
RegisterTraceTransactionWithPredecessors(queryClient, msgEthereumTx, []*evmtypes.MsgEthereumTx{msgEthereumTx})
|
|
},
|
|
&types.Block{Header: types.Header{Height: 1}, Data: types.Data{Txs: []types.Tx{txBz, txBz2}}},
|
|
[]*abci.ResponseDeliverTx{
|
|
{
|
|
Code: 0,
|
|
Events: []abci.Event{
|
|
{Type: evmtypes.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
|
|
{Key: []byte("ethereumTxHash"), Value: []byte(txHash.Hex())},
|
|
{Key: []byte("txIndex"), Value: []byte("0")},
|
|
{Key: []byte("amount"), Value: []byte("1000")},
|
|
{Key: []byte("txGasUsed"), Value: []byte("21000")},
|
|
{Key: []byte("txHash"), Value: []byte("")},
|
|
{Key: []byte("recipient"), Value: []byte("0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7")},
|
|
}},
|
|
},
|
|
},
|
|
{
|
|
Code: 0,
|
|
Events: []abci.Event{
|
|
{Type: evmtypes.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
|
|
{Key: []byte("ethereumTxHash"), Value: []byte(txHash2.Hex())},
|
|
{Key: []byte("txIndex"), Value: []byte("1")},
|
|
{Key: []byte("amount"), Value: []byte("1000")},
|
|
{Key: []byte("txGasUsed"), Value: []byte("21000")},
|
|
{Key: []byte("txHash"), Value: []byte("")},
|
|
{Key: []byte("recipient"), Value: []byte("0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7")},
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
map[string]interface{}{"test": "hello"},
|
|
true,
|
|
},
|
|
{
|
|
"pass - transaction found",
|
|
func() {
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
|
RegisterBlock(client, 1, txBz)
|
|
RegisterTraceTransaction(queryClient, msgEthereumTx)
|
|
},
|
|
&types.Block{Header: types.Header{Height: 1}, Data: types.Data{Txs: []types.Tx{txBz}}},
|
|
[]*abci.ResponseDeliverTx{
|
|
{
|
|
Code: 0,
|
|
Events: []abci.Event{
|
|
{Type: evmtypes.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
|
|
{Key: []byte("ethereumTxHash"), Value: []byte(txHash.Hex())},
|
|
{Key: []byte("txIndex"), Value: []byte("0")},
|
|
{Key: []byte("amount"), Value: []byte("1000")},
|
|
{Key: []byte("txGasUsed"), Value: []byte("21000")},
|
|
{Key: []byte("txHash"), Value: []byte("")},
|
|
{Key: []byte("recipient"), Value: []byte("0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7")},
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
map[string]interface{}{"test": "hello"},
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
suite.Run(fmt.Sprintf("case %s", tc.name), func() {
|
|
suite.SetupTest() // reset test and queries
|
|
tc.registerMock()
|
|
|
|
db := dbm.NewMemDB()
|
|
suite.backend.indexer = indexer.NewKVIndexer(db, tmlog.NewNopLogger(), suite.backend.clientCtx)
|
|
|
|
err := suite.backend.indexer.IndexBlock(tc.block, tc.responseBlock)
|
|
txResult, err := suite.backend.TraceTransaction(txHash, nil)
|
|
|
|
if tc.expPass {
|
|
suite.Require().NoError(err)
|
|
suite.Require().Equal(tc.expResult, txResult)
|
|
} else {
|
|
suite.Require().Error(err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *BackendTestSuite) TestTraceBlock() {
|
|
msgEthTx, bz := suite.buildEthereumTx()
|
|
emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{}, nil, nil)
|
|
filledBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{bz}, nil, nil)
|
|
resBlockEmpty := tmrpctypes.ResultBlock{Block: emptyBlock, BlockID: emptyBlock.LastBlockID}
|
|
resBlockFilled := tmrpctypes.ResultBlock{Block: filledBlock, BlockID: filledBlock.LastBlockID}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
registerMock func()
|
|
expTraceResults []*evmtypes.TxTraceResult
|
|
resBlock *tmrpctypes.ResultBlock
|
|
config *evmtypes.TraceConfig
|
|
expPass bool
|
|
}{
|
|
{
|
|
"pass - no transaction returning empty array",
|
|
func() {},
|
|
[]*evmtypes.TxTraceResult{},
|
|
&resBlockEmpty,
|
|
&evmtypes.TraceConfig{},
|
|
true,
|
|
},
|
|
{
|
|
"fail - cannot unmarshal data",
|
|
func() {
|
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
|
RegisterTraceBlock(queryClient, []*evmtypes.MsgEthereumTx{msgEthTx})
|
|
|
|
},
|
|
[]*evmtypes.TxTraceResult{},
|
|
&resBlockFilled,
|
|
&evmtypes.TraceConfig{},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
suite.Run(fmt.Sprintf("case %s", tc.name), func() {
|
|
suite.SetupTest() // reset test and queries
|
|
tc.registerMock()
|
|
|
|
traceResults, err := suite.backend.TraceBlock(1, tc.config, tc.resBlock)
|
|
|
|
if tc.expPass {
|
|
suite.Require().NoError(err)
|
|
suite.Require().Equal(tc.expTraceResults, traceResults)
|
|
} else {
|
|
suite.Require().Error(err)
|
|
}
|
|
})
|
|
}
|
|
}
|