Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- [\#774](https://github.com/cosmos/evm/pull/774) Emit proper allowance amount in erc20 event.
- [\#790](https://github.com/cosmos/evm/pull/790) fix panic in historical query due to missing EvmCoinInfo.
- [\#800](https://github.com/cosmos/evm/pull/800) Fix denom exponent validation in virtual fee deduct in vm module.
- [\#812](https://github.com/cosmos/evm/pull/812) Patch evm tx index and log indexes, cleanup EmitTxHashEvent and ResetTransientGasUsed.
- [\#817](https://github.com/cosmos/evm/pull/817) Align GetCoinbaseAddress to handle empty proposer address in contexts like CheckTx where proposer doesn't exist.
- [\#816](https://github.com/cosmos/evm/pull/816) Avoid nil pointer when RPC requests execute before evmCoinInfo initialization in PreBlock with defaultEvmCoinInfo fallback.
- [\#828](https://github.com/cosmos/evm/pull/828) Validate decimals before conversion to prevent panic when coininfo is missing in historical queries.
Expand Down
25 changes: 0 additions & 25 deletions ante/evm/11_emit_event.go

This file was deleted.

3 changes: 0 additions & 3 deletions ante/evm/mono_decorator.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,6 @@ func (md MonoDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne
return ctx, err
}

// Emit event unconditionally - ctx.TxIndex() will be valid during block execution
EmitTxHashEvent(ctx, ethMsg, uint64(ctx.TxIndex())) // #nosec G115 -- no overlfow here

if err := CheckTxFee(txFeeInfo, decUtils.TxFee, decUtils.TxGasLimit); err != nil {
return ctx, err
}
Expand Down
21 changes: 19 additions & 2 deletions evmd/app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package evmd

import (
"context"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -73,6 +74,7 @@ import (
upgradetypes "cosmossdk.io/x/upgrade/types"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/baseapp/txnrunner"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/grpc/cmtservice"
Expand Down Expand Up @@ -201,6 +203,18 @@ type EVMD struct {
configurator module.Configurator
}

type customRunner struct {
*txnrunner.DefaultRunner
}

func (r *customRunner) Run(ctx context.Context, ms storetypes.MultiStore, txs [][]byte, deliverTx sdk.DeliverTxFunc) ([]*abci.ExecTxResult, error) {
results, err := r.DefaultRunner.Run(ctx, ms, txs, deliverTx)
if err != nil {
return nil, err
}
return evmtypes.PatchTxResponses(results), nil
}

// NewExampleApp returns a reference to an initialized EVMD.
func NewExampleApp(
logger log.Logger,
Expand All @@ -217,19 +231,22 @@ func NewExampleApp(
legacyAmino := encodingConfig.Amino
interfaceRegistry := encodingConfig.InterfaceRegistry
txConfig := encodingConfig.TxConfig

txDecoder := encodingConfig.TxConfig.TxDecoder()
bApp := baseapp.NewBaseApp(
appName,
logger,
db,
// use transaction decoder to support the sdk.Tx interface instead of sdk.StdTx
encodingConfig.TxConfig.TxDecoder(),
txDecoder,
baseAppOptions...,
)
bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetVersion(version.Version)
bApp.SetInterfaceRegistry(interfaceRegistry)
bApp.SetTxEncoder(txConfig.TxEncoder())
bApp.SetBlockSTMTxRunner(&customRunner{txnrunner.NewDefaultRunner(
txDecoder,
)})

keys := storetypes.NewKVStoreKeys(
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
Expand Down
1 change: 0 additions & 1 deletion local_node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ if [[ $overwrite == "y" || $overwrite == "Y" ]]; then
sed -i.bak 's/prometheus-retention-time = "0"/prometheus-retention-time = "1000000000000"/g' "$APP_TOML"
sed -i.bak 's/enabled = false/enabled = true/g' "$APP_TOML"
sed -i.bak 's/enable = false/enable = true/g' "$APP_TOML"
sed -i.bak 's/enable-indexer = false/enable-indexer = true/g' "$APP_TOML"

# --------- maybe generate additional users ---------
# start with provided/default list
Expand Down
8 changes: 8 additions & 0 deletions rpc/backend/comet_to_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ func (b *Backend) ReceiptsFromCometBlock(
return nil, fmt.Errorf("failed to convert tx result to eth receipt: %w", err)
}

if txResult.EthTxIndex == -1 {
var err error
txResult.EthTxIndex, err = FindEthTxIndexByHash(ethMsg.Hash(), resBlock, blockRes, b)
if err != nil {
return nil, err
}
}

bloom := ethtypes.CreateBloom(&ethtypes.Receipt{Logs: logs})

receipt := &ethtypes.Receipt{
Expand Down
19 changes: 4 additions & 15 deletions rpc/backend/tx_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package backend
import (
"encoding/json"
"fmt"
"math"
"math/big"
"time"

Expand Down Expand Up @@ -59,22 +58,12 @@ func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransac
}

if res.EthTxIndex == -1 {
// Fallback to find tx index by iterating all valid eth transactions
msgs := b.EthMsgsFromCometBlock(block, blockRes)
for i := range msgs {
if msgs[i].Hash() == txHash {
if i > math.MaxInt32 {
return nil, errors.New("tx index overflow")
}
res.EthTxIndex = int32(i) //#nosec G115 -- checked for int overflow already
break
}
var err error
res.EthTxIndex, err = FindEthTxIndexByHash(txHash, block, blockRes, b)
if err != nil {
return nil, err
}
}
// if we still unable to find the eth tx index, return error, shouldn't happen.
if res.EthTxIndex == -1 {
return nil, errors.New("can't find index of ethereum tx")
}

baseFee, err := b.BaseFee(blockRes)
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions rpc/backend/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,17 @@ func GetHexProofs(proof *crypto.ProofOps) []string {
}
return proofs
}

// FindEthTxIndexByHash finds tx index by iterating all valid eth transactions.
func FindEthTxIndexByHash(txHash common.Hash, block *cmtrpctypes.ResultBlock, blockRes *cmtrpctypes.ResultBlockResults, b *Backend) (int32, error) {
msgs := b.EthMsgsFromCometBlock(block, blockRes)
for i := range msgs {
if msgs[i].Hash() == txHash {
if i > math.MaxInt32 {
return -1, fmt.Errorf("tx index overflow")
}
return int32(i), nil //#nosec G115 -- checked for int overflow already
}
}
return -1, fmt.Errorf("can't find index of ethereum tx")
}
197 changes: 197 additions & 0 deletions tests/integration/rpc/backend/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ package backend
import (
"fmt"

"github.com/ethereum/go-ethereum/common"

abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/proto/tendermint/crypto"
cmtrpctypes "github.com/cometbft/cometbft/rpc/core/types"
"github.com/cometbft/cometbft/types"

backend2 "github.com/cosmos/evm/rpc/backend"
evmtypes "github.com/cosmos/evm/x/vm/types"
)

func mookProofs(num int, withData bool) *crypto.ProofOps {
Expand Down Expand Up @@ -52,3 +58,194 @@ func (s *TestSuite) TestGetHexProofs() {
})
}
}

func (s *TestSuite) TestFindEthTxIndexByHash() {
txHash := common.HexToHash("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef")
tx := evmtypes.NewTx(&evmtypes.EvmTxArgs{
ChainID: s.backend.EvmChainID,
Nonce: 0,
GasLimit: 100000,
})
tx.From = s.from.Bytes()
txEncoder := s.backend.ClientCtx.TxConfig.TxEncoder()
builder := s.backend.ClientCtx.TxConfig.NewTxBuilder()
err := builder.SetMsgs(tx)
s.Require().NoError(err)
txBz, err := txEncoder(builder.GetTx())
s.Require().NoError(err)

testCases := []struct {
name string
setupMock func() (*cmtrpctypes.ResultBlock, *cmtrpctypes.ResultBlockResults)
txHash common.Hash
expectError bool
errorMsg string
expectedIdx int32
}{
{
name: "tx found at index 0",
setupMock: func() (*cmtrpctypes.ResultBlock, *cmtrpctypes.ResultBlockResults) {
block := &cmtrpctypes.ResultBlock{
Block: &types.Block{
Header: types.Header{Height: 1},
Data: types.Data{
Txs: []types.Tx{txBz},
},
},
}
blockRes := &cmtrpctypes.ResultBlockResults{
TxsResults: []*abci.ExecTxResult{
{Code: 0, GasUsed: 21000},
},
}
return block, blockRes
},
txHash: tx.Hash(),
expectError: false,
expectedIdx: 0,
},
{
name: "tx not found",
setupMock: func() (*cmtrpctypes.ResultBlock, *cmtrpctypes.ResultBlockResults) {
otherTx := evmtypes.NewTx(&evmtypes.EvmTxArgs{
ChainID: s.backend.EvmChainID,
Nonce: 1,
GasLimit: 100000,
})
otherTx.From = s.from.Bytes()

builder := s.backend.ClientCtx.TxConfig.NewTxBuilder()
_ = builder.SetMsgs(otherTx)
otherTxBz, _ := txEncoder(builder.GetTx())

block := &cmtrpctypes.ResultBlock{
Block: &types.Block{
Header: types.Header{Height: 1},
Data: types.Data{
Txs: []types.Tx{otherTxBz},
},
},
}
blockRes := &cmtrpctypes.ResultBlockResults{
TxsResults: []*abci.ExecTxResult{
{Code: 0, GasUsed: 21000},
},
}
return block, blockRes
},
txHash: txHash, // Different hash
expectError: true,
errorMsg: "can't find index of ethereum tx",
},
{
name: "empty block",
setupMock: func() (*cmtrpctypes.ResultBlock, *cmtrpctypes.ResultBlockResults) {
block := &cmtrpctypes.ResultBlock{
Block: &types.Block{
Header: types.Header{Height: 1},
Data: types.Data{Txs: []types.Tx{}},
},
}
blockRes := &cmtrpctypes.ResultBlockResults{
TxsResults: []*abci.ExecTxResult{},
}
return block, blockRes
},
txHash: txHash,
expectError: true,
errorMsg: "can't find index of ethereum tx",
},
{
name: "tx with failed result code",
setupMock: func() (*cmtrpctypes.ResultBlock, *cmtrpctypes.ResultBlockResults) {
block := &cmtrpctypes.ResultBlock{
Block: &types.Block{
Header: types.Header{Height: 1},
Data: types.Data{
Txs: []types.Tx{txBz},
},
},
}
blockRes := &cmtrpctypes.ResultBlockResults{
TxsResults: []*abci.ExecTxResult{
{Code: 1, GasUsed: 21000, Log: "execution reverted"}, // Failed tx
},
}
return block, blockRes
},
txHash: tx.Hash(),
expectError: true,
errorMsg: "can't find index of ethereum tx", // Will be filtered out by EthMsgsFromCometBlock
},
{
name: "multiple txs, target at index 1",
setupMock: func() (*cmtrpctypes.ResultBlock, *cmtrpctypes.ResultBlockResults) {
tx1 := evmtypes.NewTx(&evmtypes.EvmTxArgs{
ChainID: s.backend.EvmChainID,
Nonce: 0,
GasLimit: 100000,
})
tx1.From = s.from.Bytes()

builder1 := s.backend.ClientCtx.TxConfig.NewTxBuilder()
_ = builder1.SetMsgs(tx1)
tx1Bz, _ := txEncoder(builder1.GetTx())

tx2 := evmtypes.NewTx(&evmtypes.EvmTxArgs{
ChainID: s.backend.EvmChainID,
Nonce: 1,
GasLimit: 100000,
})
tx2.From = s.from.Bytes()

builder2 := s.backend.ClientCtx.TxConfig.NewTxBuilder()
_ = builder2.SetMsgs(tx2)
tx2Bz, _ := txEncoder(builder2.GetTx())

block := &cmtrpctypes.ResultBlock{
Block: &types.Block{
Header: types.Header{Height: 1},
Data: types.Data{
Txs: []types.Tx{tx1Bz, tx2Bz},
},
},
}
blockRes := &cmtrpctypes.ResultBlockResults{
TxsResults: []*abci.ExecTxResult{
{Code: 0, GasUsed: 21000},
{Code: 0, GasUsed: 21000},
},
}
return block, blockRes
},
txHash: func() common.Hash {
tx2 := evmtypes.NewTx(&evmtypes.EvmTxArgs{
ChainID: s.backend.EvmChainID,
Nonce: 1,
GasLimit: 100000,
})
tx2.From = s.from.Bytes()
return tx2.Hash()
}(),
expectError: false,
expectedIdx: 1,
},
}

for _, tc := range testCases {
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
block, blockRes := tc.setupMock()

idx, err := backend2.FindEthTxIndexByHash(tc.txHash, block, blockRes, s.backend)

if tc.expectError {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.errorMsg)
s.Require().Equal(int32(-1), idx)
} else {
s.Require().NoError(err)
s.Require().Equal(tc.expectedIdx, idx)
}
})
}
}
1 change: 0 additions & 1 deletion x/vm/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func (k *Keeper) EndBlock(ctx sdk.Context) error {
}

k.CollectTxBloom(ctx)
k.ResetTransientGasUsed(ctx)

return nil
}
Loading
Loading