laconicd/indexer/kv_indexer_test.go
2022-10-10 16:08:33 +05:30

190 lines
5.5 KiB
Go

package indexer_test
import (
"math/big"
"testing"
"github.com/cerc-io/laconicd/app"
"github.com/cerc-io/laconicd/crypto/ethsecp256k1"
evmenc "github.com/cerc-io/laconicd/encoding"
"github.com/cerc-io/laconicd/indexer"
"github.com/cerc-io/laconicd/tests"
"github.com/cerc-io/laconicd/x/evm/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/simapp/params"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
tmlog "github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db"
)
func TestKVIndexer(t *testing.T) {
priv, err := ethsecp256k1.GenerateKey()
require.NoError(t, err)
from := common.BytesToAddress(priv.PubKey().Address().Bytes())
signer := tests.NewSigner(priv)
ethSigner := ethtypes.LatestSignerForChainID(nil)
to := common.BigToAddress(big.NewInt(1))
tx := types.NewTx(
nil, 0, &to, big.NewInt(1000), 21000, nil, nil, nil, nil, nil,
)
tx.From = from.Hex()
require.NoError(t, tx.Sign(ethSigner, signer))
txHash := tx.AsTransaction().Hash()
encodingConfig := MakeEncodingConfig()
clientCtx := client.Context{}.WithTxConfig(encodingConfig.TxConfig).WithCodec(encodingConfig.Codec)
// build cosmos-sdk wrapper tx
tmTx, err := tx.BuildTx(clientCtx.TxConfig.NewTxBuilder(), "aphoton")
require.NoError(t, err)
txBz, err := clientCtx.TxConfig.TxEncoder()(tmTx)
require.NoError(t, err)
// build an invalid wrapper tx
builder := clientCtx.TxConfig.NewTxBuilder()
require.NoError(t, builder.SetMsgs(tx))
tmTx2 := builder.GetTx()
txBz2, err := clientCtx.TxConfig.TxEncoder()(tmTx2)
require.NoError(t, err)
testCases := []struct {
name string
block *tmtypes.Block
blockResult []*abci.ResponseDeliverTx
expSuccess bool
}{
{
"success, format 1",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 0,
Events: []abci.Event{
{Type: types.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")},
}},
},
},
},
true,
},
{
"success, format 2",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 0,
Events: []abci.Event{
{Type: types.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
{Key: []byte("ethereumTxHash"), Value: []byte(txHash.Hex())},
{Key: []byte("txIndex"), Value: []byte("0")},
}},
{Type: types.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
{Key: []byte("amount"), Value: []byte("1000")},
{Key: []byte("txGasUsed"), Value: []byte("21000")},
{Key: []byte("txHash"), Value: []byte("14A84ED06282645EFBF080E0B7ED80D8D8D6A36337668A12B5F229F81CDD3F57")},
{Key: []byte("recipient"), Value: []byte("0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7")},
}},
},
},
},
true,
},
{
"success, exceed block gas limit",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 11,
Log: "out of gas in location: block gas meter; gasWanted: 21000",
Events: []abci.Event{},
},
},
true,
},
{
"fail, failed eth tx",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 15,
Log: "nonce mismatch",
Events: []abci.Event{},
},
},
false,
},
{
"fail, invalid events",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 0,
Events: []abci.Event{},
},
},
false,
},
{
"fail, not eth tx",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz2}}},
[]*abci.ResponseDeliverTx{
{
Code: 0,
Events: []abci.Event{},
},
},
false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
db := dbm.NewMemDB()
idxer := indexer.NewKVIndexer(db, tmlog.NewNopLogger(), clientCtx)
err = idxer.IndexBlock(tc.block, tc.blockResult)
require.NoError(t, err)
if !tc.expSuccess {
first, err := idxer.FirstIndexedBlock()
require.NoError(t, err)
require.Equal(t, int64(-1), first)
last, err := idxer.LastIndexedBlock()
require.NoError(t, err)
require.Equal(t, int64(-1), last)
} else {
first, err := idxer.FirstIndexedBlock()
require.NoError(t, err)
require.Equal(t, tc.block.Header.Height, first)
last, err := idxer.LastIndexedBlock()
require.NoError(t, err)
require.Equal(t, tc.block.Header.Height, last)
res1, err := idxer.GetByTxHash(txHash)
require.NoError(t, err)
require.NotNil(t, res1)
res2, err := idxer.GetByBlockAndIndex(1, 0)
require.NoError(t, err)
require.Equal(t, res1, res2)
}
})
}
}
// MakeEncodingConfig creates the EncodingConfig
func MakeEncodingConfig() params.EncodingConfig {
return evmenc.MakeConfig(app.ModuleBasics)
}