Skip to content

Commit

Permalink
refactor(evm): tests for evm events upgraded
Browse files Browse the repository at this point in the history
  • Loading branch information
onikonychev committed Sep 27, 2024
1 parent 19e8815 commit 1919734
Show file tree
Hide file tree
Showing 21 changed files with 412 additions and 710 deletions.
12 changes: 8 additions & 4 deletions app/evmante/evmante_emit_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,14 @@ func (eeed EthEmitEventDecorator) AnteHandle(
msg, (*evm.MsgEthereumTx)(nil),
)
}
_ = ctx.EventManager().EmitTypedEvent(&evm.EventPendingEthereumTx{
EthHash: msgEthTx.Hash,
Index: strconv.FormatUint(txIndex+uint64(i), 10),
})
// Untyped event: "message", used for tendermint subscription
ctx.EventManager().EmitEvent(
sdk.NewEvent(
evm.PendingEthereumTxEvent,
sdk.NewAttribute(evm.PendingEthereumTxEventAttrEthHash, msgEthTx.Hash),
sdk.NewAttribute(evm.PendingEthereumTxEventTxAttrIndex, strconv.FormatUint(txIndex+uint64(i), 10)),
),
)
}
return next(ctx, tx, simulate)
}
29 changes: 18 additions & 11 deletions app/evmante/evmante_emit_event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"

"github.com/NibiruChain/nibiru/v2/x/common/testutil"

"github.com/NibiruChain/nibiru/v2/app/evmante"
"github.com/NibiruChain/nibiru/v2/x/evm"

Expand Down Expand Up @@ -57,16 +55,25 @@ func (s *TestSuite) TestEthEmitEventDecorator() {
return
}
s.Require().NoError(err)
events := deps.Ctx.EventManager().Events()

txMsg := tx.(*evm.MsgEthereumTx)
testutil.RequireContainsTypedEvent(
s.T(),
deps.Ctx,
&evm.EventPendingEthereumTx{
EthHash: txMsg.Hash,
Index: "0",
},
)
s.Require().Greater(len(events), 0)
event := events[len(events)-1]
s.Require().Equal(evm.PendingEthereumTxEvent, event.Type)

// Convert tx to msg to get hash
txMsg, ok := tx.GetMsgs()[0].(*evm.MsgEthereumTx)
s.Require().True(ok)

// TX hash attr must present
attr, ok := event.GetAttribute(evm.PendingEthereumTxEventAttrEthHash)
s.Require().True(ok, "tx hash attribute not found")
s.Require().Equal(txMsg.Hash, attr.Value)

// TX index attr must present
attr, ok = event.GetAttribute(evm.PendingEthereumTxEventTxAttrIndex)
s.Require().True(ok, "tx index attribute not found")
s.Require().Equal("0", attr.Value)
})
}
}
4 changes: 2 additions & 2 deletions contrib/scripts/localnet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ sed -i $SEDOPTION '/\[json\-rpc\]/,+3 s/enable = false/enable = true/' $CHAIN_DI
echo_info "config/app.toml: Enabling debug evm api"
sed -i $SEDOPTION '/\[json\-rpc\]/,+13 s/api = "eth,net,web3"/api = "eth,net,web3,debug"/' $CHAIN_DIR/config/app.toml

echo_info "config/app.toml: Enabling evm indexer"
sed -i $SEDOPTION '/\[json\-rpc\]/,+51 s/enable-indexer = false/enable-indexer = true/' $CHAIN_DIR/config/app.toml
#echo_info "config/app.toml: Enabling evm indexer"
#sed -i $SEDOPTION '/\[json\-rpc\]/,+51 s/enable-indexer = false/enable-indexer = true/' $CHAIN_DIR/config/app.toml

# Enable Swagger Docs
echo_info "config/app.toml: Enabling Swagger Docs"
Expand Down
2 changes: 1 addition & 1 deletion eth/indexer/evm_tx_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func NewEVMTxIndexer(db dbm.DB, logger log.Logger, clientCtx client.Context) *EV
// - Iterates over all the Txs in Block
// - Parses eth Tx infos from cosmos-sdk events for every TxResult
// - Iterates over all the messages of the Tx
// - Builds and stores a indexer.TxResult based on parsed events for every message
// - Builds and stores indexer.TxResult based on parsed events for every message
func (indexer *EVMTxIndexer) IndexBlock(block *tmtypes.Block, txResults []*abci.ResponseDeliverTx) error {
height := block.Header.Height

Expand Down
85 changes: 43 additions & 42 deletions eth/indexer/evm_tx_indexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"math/big"
"testing"

"cosmossdk.io/simapp/params"
dbm "github.com/cometbft/cometbft-db"
abci "github.com/cometbft/cometbft/abci/types"
tmlog "github.com/cometbft/cometbft/libs/log"
Expand All @@ -17,7 +16,6 @@ import (
"github.com/NibiruChain/nibiru/v2/app"
"github.com/NibiruChain/nibiru/v2/eth"
"github.com/NibiruChain/nibiru/v2/eth/crypto/ethsecp256k1"
evmenc "github.com/NibiruChain/nibiru/v2/eth/encoding"
"github.com/NibiruChain/nibiru/v2/eth/indexer"
"github.com/NibiruChain/nibiru/v2/x/evm"
evmtest "github.com/NibiruChain/nibiru/v2/x/evm/evmtest"
Expand Down Expand Up @@ -50,16 +48,16 @@ func TestEVMTxIndexer(t *testing.T) {
WithCodec(encCfg.Codec)

// build cosmos-sdk wrapper tx
tmTx, err := tx.BuildTx(clientCtx.TxConfig.NewTxBuilder(), eth.EthBaseDenom)
validEVMTx, err := tx.BuildTx(clientCtx.TxConfig.NewTxBuilder(), eth.EthBaseDenom)
require.NoError(t, err)
txBz, err := clientCtx.TxConfig.TxEncoder()(tmTx)
validEVMTxBz, err := clientCtx.TxConfig.TxEncoder()(validEVMTx)
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)
invalidTx := builder.GetTx()
invalidTxBz, err := clientCtx.TxConfig.TxEncoder()(invalidTx)
require.NoError(t, err)

testCases := []struct {
Expand All @@ -69,50 +67,58 @@ func TestEVMTxIndexer(t *testing.T) {
expSuccess bool
}{
{
"success, format 1",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
"happy, only pending_ethereum_tx presents",
&tmtypes.Block{
Header: tmtypes.Header{Height: 1},
Data: tmtypes.Data{Txs: []tmtypes.Tx{validEVMTxBz}},
},
[]*abci.ResponseDeliverTx{
{
Code: 0,
Code: 0,
Events: []abci.Event{
//{Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
// {Key: "ethereumTxHash", Value: txHash.Hex()},
// {Key: "txIndex", Value: "0"},
// {Key: "amount", Value: "1000"},
// {Key: "txGasUsed", Value: "21000"},
// {Key: "txHash", Value: ""},
// {Key: "recipient", Value: "0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7"},
//}},
{
Type: evm.PendingEthereumTxEvent,
Attributes: []abci.EventAttribute{
{Key: evm.PendingEthereumTxEventAttrEthHash, Value: txHash.Hex()},
{Key: evm.PendingEthereumTxEventTxAttrIndex, Value: "0"},
},
},
},
},
},
true,
},
{
"success, format 2",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
"happy: code 0, pending_ethereum_tx and typed EventEthereumTx present",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{validEVMTxBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 0,
Events: []abci.Event{
{Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
{Key: "ethereumTxHash", Value: txHash.Hex()},
{Key: "txIndex", Value: "0"},
}},
{Type: evm.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
{Key: "amount", Value: "1000"},
{Key: "txGasUsed", Value: "21000"},
{Key: "txHash", Value: "14A84ED06282645EFBF080E0B7ED80D8D8D6A36337668A12B5F229F81CDD3F57"},
{Key: "recipient", Value: "0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7"},
}},
{
Type: evm.PendingEthereumTxEvent,
Attributes: []abci.EventAttribute{
{Key: evm.PendingEthereumTxEventAttrEthHash, Value: txHash.Hex()},
{Key: evm.PendingEthereumTxEventTxAttrIndex, Value: "0"},
},
},
{
Type: evm.TypeUrlEventEthereumTx,
Attributes: []abci.EventAttribute{
{Key: "amount", Value: `"1000"`},
{Key: "gas_used", Value: `"21000"`},
{Key: "index", Value: `"0"`},
{Key: "hash", Value: `"14A84ED06282645EFBF080E0B7ED80D8D8D6A36337668A12B5F229F81CDD3F57"`},
},
},
},
},
},
true,
},
{
"success, exceed block gas limit",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
"happy: code 11, exceed block gas limit",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{validEVMTxBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 11,
Expand All @@ -123,8 +129,8 @@ func TestEVMTxIndexer(t *testing.T) {
true,
},
{
"fail, failed eth tx",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
"sad: failed eth tx",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{validEVMTxBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 15,
Expand All @@ -135,8 +141,8 @@ func TestEVMTxIndexer(t *testing.T) {
false,
},
{
"fail, invalid events",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz}}},
"sad: invalid events",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{validEVMTxBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 0,
Expand All @@ -146,8 +152,8 @@ func TestEVMTxIndexer(t *testing.T) {
false,
},
{
"fail, not eth tx",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{txBz2}}},
"sad: not eth tx",
&tmtypes.Block{Header: tmtypes.Header{Height: 1}, Data: tmtypes.Data{Txs: []tmtypes.Tx{invalidTxBz}}},
[]*abci.ResponseDeliverTx{
{
Code: 0,
Expand Down Expand Up @@ -192,8 +198,3 @@ func TestEVMTxIndexer(t *testing.T) {
})
}
}

// MakeEncodingConfig creates the EncodingConfig
func MakeEncodingConfig() params.EncodingConfig {
return evmenc.MakeConfig(app.ModuleBasics)
}
2 changes: 1 addition & 1 deletion eth/rpc/backend/account_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func generateStorageKey(key gethcommon.Address, slot uint64) string {
// Concatenate key and slot
data := append(keyBytes, slotBytes...)

// Hash the data using Keccak256
// EthHash the data using Keccak256
hash := sha3.NewLegacyKeccak256()
hash.Write(data)
return gethcommon.BytesToHash(hash.Sum(nil)).Hex()
Expand Down
19 changes: 4 additions & 15 deletions eth/rpc/backend/tx_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"math/big"

errorsmod "cosmossdk.io/errors"
"github.com/cosmos/gogoproto/proto"

tmrpcclient "github.com/cometbft/cometbft/rpc/client"
tmrpctypes "github.com/cometbft/cometbft/rpc/core/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -308,12 +306,7 @@ func (b *Backend) GetTxByEthHash(hash gethcommon.Hash) (*eth.TxResult, error) {
}

// fallback to tendermint tx evmTxIndexer

//query := fmt.Sprintf("%s.%s='%s'", evm.TypeMsgEthereumTx, evm.AttributeKeyEthereumTxHash, hash.Hex())
eventEthereumTxType := proto.MessageName((*evm.EventEthereumTx)(nil))

// TODO: remove hardcoded eth_hash attr name
query := fmt.Sprintf("%s.%s='%s'", eventEthereumTxType, "eth_hash", hash.Hex())
query := fmt.Sprintf("%s.%s='%s'", evm.PendingEthereumTxEvent, evm.PendingEthereumTxEventAttrEthHash, hash.Hex())

txResult, err := b.queryTendermintTxIndexer(query, func(txs *rpc.ParsedTxs) *rpc.ParsedTx {
return txs.GetTxByHash(hash)
Expand All @@ -332,14 +325,10 @@ func (b *Backend) GetTxByTxIndex(height int64, index uint) (*eth.TxResult, error
}

// fallback to tendermint tx evmTxIndexer
//query := fmt.Sprintf("tx.height=%d AND %s.%s=%d",
// height, evm.TypeMsgEthereumTx,
// evm.AttributeKeyTxIndex, index,
//)
eventEthereumTxType := proto.MessageName((*evm.EventEthereumTx)(nil))
query := fmt.Sprintf("tx.height=%d AND %s.%s=%d",
height, eventEthereumTxType,
"index", index,
height, evm.PendingEthereumTxEventTxAttrIndex,
evm.PendingEthereumTxEventTxAttrIndex,
index,
)
txResult, err := b.queryTendermintTxIndexer(query, func(txs *rpc.ParsedTxs) *rpc.ParsedTx {
return txs.GetTxByTxIndex(int(index)) // #nosec G701 -- checked for int overflow already
Expand Down
19 changes: 9 additions & 10 deletions eth/rpc/tx_from_events.go → eth/rpc/events_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type ParsedTx struct {
MsgIndex int

// the following fields are parsed from events
Hash gethcommon.Hash
EthHash gethcommon.Hash

EthTxIndex int32 // -1 means uninitialized
GasUsed uint64
Expand All @@ -39,7 +39,7 @@ type ParsedTxs struct {

// ParseTxResult parses eth tx info from the ABCI events of Eth tx msgs
func ParseTxResult(result *abci.ResponseDeliverTx, tx sdk.Tx) (*ParsedTxs, error) {
eventTypePendingEthereumTx := proto.MessageName((*evm.EventPendingEthereumTx)(nil))
eventTypePendingEthereumTx := evm.PendingEthereumTxEvent
eventTypeEthereumTx := proto.MessageName((*evm.EventEthereumTx)(nil))

// Parsed txs is the structure being populated from the events
Expand All @@ -55,18 +55,17 @@ func ParseTxResult(result *abci.ResponseDeliverTx, tx sdk.Tx) (*ParsedTxs, error
// Pending tx event could be single if tx didn't succeed
if event.Type == eventTypePendingEthereumTx {
msgIndex++
eventPendingEthereumTx, err := evm.EventPendingEthereumTxFromABCIEvent(event)
ethHash, txIndex, err := evm.GetEthHashAndIndexFromPendingEthereumTxEvent(event)
if err != nil {
return nil, err
}
hash := gethcommon.HexToHash(eventPendingEthereumTx.EthHash)
pendingTx := ParsedTx{
MsgIndex: msgIndex,
EthTxIndex: -1,
Hash: hash,
EthTxIndex: txIndex,
EthHash: ethHash,
}
parsedTxs.Txs = append(parsedTxs.Txs, pendingTx)
parsedTxs.TxHashes[hash] = msgIndex
parsedTxs.TxHashes[ethHash] = msgIndex
} else if event.Type == eventTypeEthereumTx { // Full event replaces the pending tx
eventEthereumTx, err := evm.EventEthereumTxFromABCIEvent(event)
if err != nil {
Expand All @@ -83,16 +82,16 @@ func ParseTxResult(result *abci.ResponseDeliverTx, tx sdk.Tx) (*ParsedTxs, error
committedTx := ParsedTx{
MsgIndex: msgIndex,
EthTxIndex: int32(ethTxIndexFromEvent),
Hash: gethcommon.HexToHash(eventEthereumTx.EthHash),
EthHash: gethcommon.HexToHash(eventEthereumTx.EthHash),
GasUsed: gasUsed,
Failed: len(eventEthereumTx.EthTxFailed) > 0,
}
// replace pending tx with committed tx
if len(parsedTxs.Txs) == msgIndex+1 {
if msgIndex >= 0 && len(parsedTxs.Txs) == msgIndex+1 {
parsedTxs.Txs[msgIndex] = committedTx
} else {
// EventEthereumTx without EventPendingEthereumTx
return nil, errors.New("EventEthereumTx without EventPendingEthereumTx")
return nil, errors.New("EventEthereumTx without pending_ethereum_tx event")
}
}
}
Expand Down
Loading

0 comments on commit 1919734

Please sign in to comment.