laconicd-deprecated/rpc/backend/tracing_test.go
2023-03-13 12:34:10 +05:30

251 lines
8.3 KiB
Go

package backend
import (
"fmt"
"github.com/cerc-io/laconicd/crypto/ethsecp256k1"
"github.com/cerc-io/laconicd/indexer"
"github.com/cerc-io/laconicd/rpc/backend/mocks"
evmtypes "github.com/cerc-io/laconicd/x/evm/types"
"github.com/cosmos/cosmos-sdk/crypto"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/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, ChainID: ChainID}, 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)
suite.Require().NoError(err)
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)
emptyBlock.ChainID = ChainID
filledBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{bz}, nil, nil)
filledBlock.ChainID = ChainID
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)
}
})
}
}