Skip to content

Commit f2ad4af

Browse files
crypto-facsfedekunze
authored andcommitted
cherry-pick (tharsis#741)
Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
1 parent 79c4de3 commit f2ad4af

2 files changed

Lines changed: 82 additions & 46 deletions

File tree

rpc/ethereum/backend/backend.go

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ type Backend interface {
6464
ChainConfig() *params.ChainConfig
6565
SuggestGasTipCap() (*big.Int, error)
6666
GetFilteredBlocks(from int64, to int64, filter [][]filters.BloomIV, filterAddresses bool) ([]int64, error)
67+
GetEthereumMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock) []*evmtypes.MsgEthereumTx
6768
}
6869

6970
var _ Backend = (*EVMBackend)(nil)
@@ -260,6 +261,14 @@ func (e *EVMBackend) EthBlockFromTendermint(
260261
}
261262

262263
hash := ethMsg.AsTransaction().Hash()
264+
265+
// check tx exists on EVM and it has the correct block height
266+
tx, err := e.GetTxByEthHash(hash)
267+
if err != nil || tx.Height != block.Height {
268+
e.logger.Debug("failed to query eth tx", "hash", hash)
269+
continue
270+
}
271+
263272
if !fullTx {
264273
ethRPCTxs = append(ethRPCTxs, hash)
265274
continue
@@ -532,11 +541,12 @@ func (e *EVMBackend) GetCoinbase() (sdk.AccAddress, error) {
532541
// GetTransactionByHash returns the Ethereum format transaction identified by Ethereum transaction hash
533542
func (e *EVMBackend) GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error) {
534543
res, err := e.GetTxByEthHash(txHash)
544+
hexTx := txHash.Hex()
535545
if err != nil {
536546
// try to find tx in mempool
537547
txs, err := e.PendingTransactions()
538548
if err != nil {
539-
e.logger.Debug("tx not found", "hash", txHash.Hex(), "error", err.Error())
549+
e.logger.Debug("tx not found", "hash", hexTx, "error", err.Error())
540550
return nil, nil
541551
}
542552

@@ -547,7 +557,7 @@ func (e *EVMBackend) GetTransactionByHash(txHash common.Hash) (*types.RPCTransac
547557
continue
548558
}
549559

550-
if msg.Hash == txHash.Hex() {
560+
if msg.Hash == hexTx {
551561
rpctx, err := types.NewTransactionFromMsg(
552562
msg,
553563
common.Hash{},
@@ -562,7 +572,7 @@ func (e *EVMBackend) GetTransactionByHash(txHash common.Hash) (*types.RPCTransac
562572
}
563573
}
564574

565-
e.logger.Debug("tx not found", "hash", txHash.Hex())
575+
e.logger.Debug("tx not found", "hash", hexTx)
566576
return nil, nil
567577
}
568578

@@ -572,23 +582,23 @@ func (e *EVMBackend) GetTransactionByHash(txHash common.Hash) (*types.RPCTransac
572582
return nil, nil
573583
}
574584

575-
tx, err := e.clientCtx.TxConfig.TxDecoder()(res.Tx)
576-
if err != nil {
577-
e.logger.Debug("decoding failed", "error", err.Error())
578-
return nil, fmt.Errorf("failed to decode tx: %w", err)
579-
}
585+
var txIndex uint64
586+
msgs := e.GetEthereumMsgsFromTendermintBlock(resBlock)
580587

581-
msg, err := evmtypes.UnwrapEthereumMsg(&tx)
582-
if err != nil {
583-
e.logger.Debug("invalid tx", "error", err.Error())
584-
return nil, err
588+
for i := range msgs {
589+
if msgs[i].Hash == hexTx {
590+
txIndex = uint64(i)
591+
break
592+
}
585593
}
586594

595+
msg := msgs[txIndex]
596+
587597
return types.NewTransactionFromMsg(
588598
msg,
589599
common.BytesToHash(resBlock.Block.Hash()),
590600
uint64(res.Height),
591-
uint64(res.Index),
601+
txIndex,
592602
e.chainID,
593603
)
594604
}
@@ -845,6 +855,39 @@ BLOCKS:
845855
return matchedBlocks, nil
846856
}
847857

858+
// GetEthereumMsgsFromTendermintBlock returns all real MsgEthereumTxs from a Tendermint block.
859+
// It also ensures consistency over the correct txs indexes across RPC endpoints
860+
func (e *EVMBackend) GetEthereumMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock) []*evmtypes.MsgEthereumTx {
861+
var result []*evmtypes.MsgEthereumTx
862+
863+
for _, tx := range block.Block.Txs {
864+
tx, err := e.clientCtx.TxConfig.TxDecoder()(tx)
865+
if err != nil {
866+
e.logger.Debug("failed to decode transaction in block", "height", block.Block.Height, "error", err.Error())
867+
continue
868+
}
869+
870+
for _, msg := range tx.GetMsgs() {
871+
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
872+
if !ok {
873+
continue
874+
}
875+
876+
hash := ethMsg.AsTransaction().Hash()
877+
// check tx exists on EVM and has the correct block height
878+
ethTx, err := e.GetTxByEthHash(hash)
879+
if err != nil || ethTx.Height != block.Block.Height {
880+
e.logger.Debug("failed to query eth tx hash", "hash", hash.Hex())
881+
continue
882+
}
883+
884+
result = append(result, ethMsg)
885+
}
886+
}
887+
888+
return result
889+
}
890+
848891
// checkMatches revised the function from
849892
// https://github.com/ethereum/go-ethereum/blob/401354976bb44f0ad4455ca1e0b5c0dc31d9a5f5/core/types/bloom9.go#L88
850893
func checkMatches(bloom ethtypes.Bloom, filter []filters.BloomIV) bool {

rpc/ethereum/namespaces/eth/api.go

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ func (e *PublicAPI) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Ui
268268
return nil
269269
}
270270

271-
n := hexutil.Uint(len(resBlock.Block.Txs))
271+
ethMsgs := e.backend.GetEthereumMsgsFromTendermintBlock(resBlock)
272+
n := hexutil.Uint(len(ethMsgs))
272273
return &n
273274
}
274275

@@ -286,7 +287,8 @@ func (e *PublicAPI) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumb
286287
return nil
287288
}
288289

289-
n := hexutil.Uint(len(resBlock.Block.Txs))
290+
ethMsgs := e.backend.GetEthereumMsgsFromTendermintBlock(resBlock)
291+
n := hexutil.Uint(len(ethMsgs))
290292
return &n
291293
}
292294

@@ -526,23 +528,13 @@ func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexu
526528
}
527529

528530
i := int(idx)
529-
if i >= len(resBlock.Block.Txs) {
531+
ethMsgs := e.backend.GetEthereumMsgsFromTendermintBlock(resBlock)
532+
if i >= len(ethMsgs) {
530533
e.logger.Debug("block txs index out of bound", "index", i)
531534
return nil, nil
532535
}
533536

534-
txBz := resBlock.Block.Txs[i]
535-
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
536-
if err != nil {
537-
e.logger.Debug("decoding failed", "error", err.Error())
538-
return nil, fmt.Errorf("failed to decode tx: %w", err)
539-
}
540-
541-
msg, err := evmtypes.UnwrapEthereumMsg(&tx)
542-
if err != nil {
543-
e.logger.Debug("invalid tx", "error", err.Error())
544-
return nil, err
545-
}
537+
msg := ethMsgs[i]
546538

547539
return rpctypes.NewTransactionFromMsg(
548540
msg,
@@ -569,23 +561,13 @@ func (e *PublicAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockN
569561
}
570562

571563
i := int(idx)
572-
if i >= len(resBlock.Block.Txs) {
564+
ethMsgs := e.backend.GetEthereumMsgsFromTendermintBlock(resBlock)
565+
if i >= len(ethMsgs) {
573566
e.logger.Debug("block txs index out of bound", "index", i)
574567
return nil, nil
575568
}
576569

577-
txBz := resBlock.Block.Txs[i]
578-
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
579-
if err != nil {
580-
e.logger.Debug("decoding failed", "error", err.Error())
581-
return nil, fmt.Errorf("failed to decode tx: %w", err)
582-
}
583-
584-
msg, err := evmtypes.UnwrapEthereumMsg(&tx)
585-
if err != nil {
586-
e.logger.Debug("invalid tx", "error", err.Error())
587-
return nil, err
588-
}
570+
msg := ethMsgs[i]
589571

590572
return rpctypes.NewTransactionFromMsg(
591573
msg,
@@ -598,11 +580,12 @@ func (e *PublicAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockN
598580

599581
// GetTransactionReceipt returns the transaction receipt identified by hash.
600582
func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) {
601-
e.logger.Debug("eth_getTransactionReceipt", "hash", hash.Hex())
583+
hexTx := hash.Hex()
584+
e.logger.Debug("eth_getTransactionReceipt", "hash", hexTx)
602585

603586
res, err := e.backend.GetTxByEthHash(hash)
604587
if err != nil {
605-
e.logger.Debug("tx not found", "hash", hash.Hex(), "error", err.Error())
588+
e.logger.Debug("tx not found", "hash", hexTx, "error", err.Error())
606589
return nil, nil
607590
}
608591

@@ -656,7 +639,17 @@ func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interfac
656639

657640
logs, err := e.backend.GetTransactionLogs(hash)
658641
if err != nil {
659-
e.logger.Debug("logs not found", "hash", hash.Hex(), "error", err.Error())
642+
e.logger.Debug("logs not found", "hash", hexTx, "error", err.Error())
643+
}
644+
645+
// get eth index based on block's txs
646+
var txIndex uint64
647+
msgs := e.backend.GetEthereumMsgsFromTendermintBlock(resBlock)
648+
for i := range msgs {
649+
if msgs[i].Hash == hexTx {
650+
txIndex = uint64(i)
651+
break
652+
}
660653
}
661654

662655
receipt := map[string]interface{}{
@@ -677,7 +670,7 @@ func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interfac
677670
// transaction corresponding to this receipt.
678671
"blockHash": common.BytesToHash(resBlock.Block.Header.Hash()).Hex(),
679672
"blockNumber": hexutil.Uint64(res.Height),
680-
"transactionIndex": hexutil.Uint64(res.Index),
673+
"transactionIndex": hexutil.Uint64(txIndex),
681674

682675
// sender and receiver (contract or EOA) addreses
683676
"from": from,
@@ -696,7 +689,7 @@ func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interfac
696689
return receipt, nil
697690
}
698691

699-
// PendingTransactions returns the transactions that are in the transaction pool
692+
// GetPendingTransactions returns the transactions that are in the transaction pool
700693
// and have a from address that is one of the accounts this node manages.
701694
func (e *PublicAPI) GetPendingTransactions() ([]*rpctypes.RPCTransaction, error) {
702695
e.logger.Debug("eth_getPendingTransactions")

0 commit comments

Comments
 (0)