diff --git a/rpc/backend/backend.go b/rpc/backend/backend.go index e0db76be..7a241da0 100644 --- a/rpc/backend/backend.go +++ b/rpc/backend/backend.go @@ -4,6 +4,8 @@ package backend import ( "context" + "fmt" + tmrpcclient "github.com/cometbft/cometbft/rpc/client" "math/big" "time" @@ -28,19 +30,9 @@ import ( // BackendI implements the Cosmos and EVM backend. type BackendI interface { //nolint: revive - CosmosBackend EVMBackend } -// CosmosBackend implements the functionality shared within cosmos namespaces -// as defined by Wallet Connect V2: https://docs.walletconnect.com/2.0/json-rpc/cosmos. -// Implemented by Backend. -type CosmosBackend interface { // TODO: define - // GetAccounts() - // SignDirect() - // SignAmino() -} - // EVMBackend implements the functionality shared within ethereum namespaces // as defined by EIP-1474: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1474.md // Implemented by Backend. @@ -71,7 +63,6 @@ type EVMBackend interface { GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint TendermintBlockByNumber(blockNum rpctypes.BlockNumber) (*tmrpctypes.ResultBlock, error) - TendermintBlockResultByNumber(height *int64) (*tmrpctypes.ResultBlockResults, error) TendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error) BlockNumberFromTendermint(blockNrOrHash rpctypes.BlockNumberOrHash) (rpctypes.BlockNumber, error) BlockNumberFromTendermintByHash(blockHash common.Hash) (*big.Int, error) @@ -107,6 +98,7 @@ type EVMBackend interface { GetTxByTxIndex(height int64, txIndex uint) (*evmostypes.TxResult, error) GetTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) + GetTransactionLogs(hash common.Hash) ([]*ethtypes.Log, error) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) @@ -134,6 +126,7 @@ var _ BackendI = (*Backend)(nil) type Backend struct { ctx context.Context clientCtx client.Context + rpcClient tmrpcclient.SignClient queryClient *rpctypes.QueryClient // gRPC query client logger log.Logger chainID *big.Int @@ -160,9 +153,15 @@ func NewBackend( panic(err) } + rpcClient, ok := clientCtx.Client.(tmrpcclient.SignClient) + if !ok { + panic(fmt.Sprintf("invalid rpc client, expected: tmrpcclient.SignClient, got: %T", clientCtx.Client)) + } + return &Backend{ ctx: context.Background(), clientCtx: clientCtx, + rpcClient: rpcClient, queryClient: rpctypes.NewQueryClient(clientCtx), logger: logger.With("module", "backend"), chainID: chainID, diff --git a/rpc/backend/backend_suite_test.go b/rpc/backend/backend_suite_test.go index 54f6fde1..46eb572b 100644 --- a/rpc/backend/backend_suite_test.go +++ b/rpc/backend/backend_suite_test.go @@ -76,7 +76,8 @@ func (suite *BackendTestSuite) SetupTest() { WithTxConfig(encodingConfig.TxConfig). WithKeyringDir(clientDir). WithKeyring(keyRing). - WithAccountRetriever(client.TestAccountRetriever{Accounts: accounts}) + WithAccountRetriever(client.TestAccountRetriever{Accounts: accounts}). + WithClient(mocks.NewClient(suite.T())) allowUnprotectedTxs := false idxer := indexer.NewKVIndexer(dbm.NewMemDB(), ctx.Logger, clientCtx) @@ -86,7 +87,6 @@ func (suite *BackendTestSuite) SetupTest() { suite.backend.cfg.JSONRPC.EVMTimeout = 0 suite.backend.cfg.JSONRPC.AllowInsecureUnlock = true suite.backend.queryClient.QueryClient = mocks.NewEVMQueryClient(suite.T()) - suite.backend.clientCtx.Client = mocks.NewClient(suite.T()) suite.backend.queryClient.FeeMarket = mocks.NewFeeMarketQueryClient(suite.T()) suite.backend.ctx = rpctypes.ContextWithHeight(1) diff --git a/rpc/backend/blocks.go b/rpc/backend/blocks.go index 6104221f..4d0038fa 100644 --- a/rpc/backend/blocks.go +++ b/rpc/backend/blocks.go @@ -8,7 +8,6 @@ import ( "math/big" "strconv" - tmrpcclient "github.com/cometbft/cometbft/rpc/client" tmrpctypes "github.com/cometbft/cometbft/rpc/core/types" sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" @@ -66,7 +65,7 @@ func (b *Backend) GetBlockByNumber(blockNum rpctypes.BlockNumber, fullTx bool) ( return nil, nil } - blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height) + blockRes, err := b.rpcClient.BlockResults(b.ctx, &resBlock.Block.Height) if err != nil { b.logger.Debug("failed to fetch block result from Tendermint", "height", blockNum, "error", err.Error()) return nil, nil @@ -94,7 +93,7 @@ func (b *Backend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]inte return nil, nil } - blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height) + blockRes, err := b.rpcClient.BlockResults(b.ctx, &resBlock.Block.Height) if err != nil { b.logger.Debug("failed to fetch block result from Tendermint", "block-hash", hash.String(), "error", err.Error()) return nil, nil @@ -112,12 +111,7 @@ func (b *Backend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]inte // GetBlockTransactionCountByHash returns the number of Ethereum transactions in // the block identified by hash. func (b *Backend) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint { - sc, ok := b.clientCtx.Client.(tmrpcclient.SignClient) - if !ok { - b.logger.Error("invalid rpc client") - } - - block, err := sc.BlockByHash(b.ctx, hash.Bytes()) + block, err := b.rpcClient.BlockByHash(b.ctx, hash.Bytes()) if err != nil { b.logger.Debug("block not found", "hash", hash.Hex(), "error", err.Error()) return nil @@ -151,7 +145,7 @@ func (b *Backend) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber // GetBlockTransactionCount returns the number of Ethereum transactions in a // given block. func (b *Backend) GetBlockTransactionCount(block *tmrpctypes.ResultBlock) *hexutil.Uint { - blockRes, err := b.TendermintBlockResultByNumber(&block.Block.Height) + blockRes, err := b.rpcClient.BlockResults(b.ctx, &block.Block.Height) if err != nil { return nil } @@ -173,7 +167,7 @@ func (b *Backend) TendermintBlockByNumber(blockNum rpctypes.BlockNumber) (*tmrpc } height = int64(n) //#nosec G115 -- checked for int overflow already } - resBlock, err := b.clientCtx.Client.Block(b.ctx, &height) + resBlock, err := b.rpcClient.Block(b.ctx, &height) if err != nil { b.logger.Debug("tendermint client failed to get block", "height", height, "error", err.Error()) return nil, err @@ -190,20 +184,12 @@ func (b *Backend) TendermintBlockByNumber(blockNum rpctypes.BlockNumber) (*tmrpc // TendermintBlockResultByNumber returns a Tendermint-formatted block result // by block number func (b *Backend) TendermintBlockResultByNumber(height *int64) (*tmrpctypes.ResultBlockResults, error) { - sc, ok := b.clientCtx.Client.(tmrpcclient.SignClient) - if !ok { - return nil, errors.New("invalid rpc client") - } - return sc.BlockResults(b.ctx, height) + return b.rpcClient.BlockResults(b.ctx, height) } // TendermintBlockByHash returns a Tendermint-formatted block by block number func (b *Backend) TendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error) { - sc, ok := b.clientCtx.Client.(tmrpcclient.SignClient) - if !ok { - return nil, errors.New("invalid rpc client") - } - resBlock, err := sc.BlockByHash(b.ctx, blockHash.Bytes()) + resBlock, err := b.rpcClient.BlockByHash(b.ctx, blockHash.Bytes()) if err != nil { b.logger.Debug("tendermint client failed to get block", "blockHash", blockHash.Hex(), "error", err.Error()) return nil, err @@ -237,14 +223,16 @@ func (b *Backend) BlockNumberFromTendermint(blockNrOrHash rpctypes.BlockNumberOr // BlockNumberFromTendermintByHash returns the block height of given block hash func (b *Backend) BlockNumberFromTendermintByHash(blockHash common.Hash) (*big.Int, error) { - resBlock, err := b.TendermintBlockByHash(blockHash) + resBlock, err := b.rpcClient.HeaderByHash(b.ctx, blockHash.Bytes()) if err != nil { return nil, err } + if resBlock == nil { return nil, errors.Errorf("block not found for hash %s", blockHash.Hex()) } - return big.NewInt(resBlock.Block.Height), nil + + return big.NewInt(resBlock.Header.Height), nil } // EthMsgsFromTendermintBlock returns all real MsgEthereumTxs from a @@ -300,9 +288,9 @@ func (b *Backend) HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Heade return nil, errors.Errorf("block not found for height %d", blockNum) } - blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height) + blockRes, err := b.rpcClient.BlockResults(b.ctx, &resBlock.Block.Height) if err != nil { - return nil, fmt.Errorf("block result not found for height %d. %w", resBlock.Block.Height, err) + return nil, errors.Errorf("block result not found for height %d", resBlock.Block.Height) } bloom, err := b.BlockBloom(blockRes) @@ -322,31 +310,34 @@ func (b *Backend) HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Heade // HeaderByHash returns the block header identified by hash. func (b *Backend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) { - resBlock, err := b.TendermintBlockByHash(blockHash) + resHeader, err := b.rpcClient.HeaderByHash(b.ctx, blockHash.Bytes()) if err != nil { return nil, err } - if resBlock == nil { - return nil, errors.Errorf("block not found for hash %s", blockHash.Hex()) + + if resHeader == nil { + return nil, errors.Errorf("header not found for hash %s", blockHash.Hex()) } - blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height) + height := resHeader.Header.Height + + blockRes, err := b.rpcClient.BlockResults(b.ctx, &resHeader.Header.Height) if err != nil { - return nil, errors.Errorf("block result not found for height %d", resBlock.Block.Height) + return nil, errors.Errorf("block result not found for height %d", height) } bloom, err := b.BlockBloom(blockRes) if err != nil { - b.logger.Debug("HeaderByHash BlockBloom failed", "height", resBlock.Block.Height) + b.logger.Debug("HeaderByHash BlockBloom failed", "height", height) } baseFee, err := b.BaseFee(blockRes) if err != nil { // handle the error for pruned node. - b.logger.Error("failed to fetch Base Fee from prunned block. Check node prunning configuration", "height", resBlock.Block.Height, "error", err) + b.logger.Error("failed to fetch Base Fee from prunned block. Check node prunning configuration", "height", height, "error", err) } - ethHeader := rpctypes.EthHeaderFromTendermint(resBlock.Block.Header, bloom, baseFee) + ethHeader := rpctypes.EthHeaderFromTendermint(*resHeader.Header, bloom, baseFee) return ethHeader, nil } @@ -469,12 +460,13 @@ func (b *Backend) EthBlockByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Blo if err != nil { return nil, err } + if resBlock == nil { // block not found return nil, fmt.Errorf("block not found for height %d", blockNum) } - blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height) + blockRes, err := b.rpcClient.BlockResults(b.ctx, &resBlock.Block.Height) if err != nil { return nil, fmt.Errorf("block result not found for height %d", resBlock.Block.Height) } diff --git a/rpc/backend/blocks_test.go b/rpc/backend/blocks_test.go index 51877268..504644fc 100644 --- a/rpc/backend/blocks_test.go +++ b/rpc/backend/blocks_test.go @@ -671,7 +671,8 @@ func (suite *BackendTestSuite) TestTendermintBlockResultByNumber() { suite.SetupTest() // reset test and queries tc.registerMock(tc.blockNumber) - blockRes, err := suite.backend.TendermintBlockResultByNumber(&tc.blockNumber) //#nosec G601 -- fine for tests + client := suite.backend.clientCtx.Client.(*mocks.Client) + blockRes, err := client.BlockResults(suite.backend.ctx, &tc.blockNumber) //#nosec G601 -- fine for tests if tc.expPass { suite.Require().NoError(err) @@ -684,7 +685,7 @@ func (suite *BackendTestSuite) TestTendermintBlockResultByNumber() { } func (suite *BackendTestSuite) TestBlockNumberFromTendermint() { - var resBlock *cmtrpctypes.ResultBlock + var resHeader *cmtrpctypes.ResultHeader _, bz := suite.buildEthereumTx() block := cmttypes.MakeBlock(1, []cmttypes.Tx{bz}, nil, nil) @@ -711,7 +712,7 @@ func (suite *BackendTestSuite) TestBlockNumberFromTendermint() { &blockHash, func(hash *common.Hash) { client := suite.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, *hash, bz) + RegisterHeaderByHashError(client, *hash, bz) }, false, }, @@ -721,7 +722,7 @@ func (suite *BackendTestSuite) TestBlockNumberFromTendermint() { &blockHash, func(hash *common.Hash) { client := suite.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockByHash(client, *hash, bz) + resHeader, _ = RegisterHeaderByHash(client, *hash, bz) }, true, }, @@ -750,7 +751,7 @@ func (suite *BackendTestSuite) TestBlockNumberFromTendermint() { if tc.hash == nil { suite.Require().Equal(*tc.blockNum, blockNum) } else { - expHeight := ethrpc.NewBlockNumber(big.NewInt(resBlock.Block.Height)) + expHeight := ethrpc.NewBlockNumber(big.NewInt(resHeader.Header.Height)) suite.Require().Equal(expHeight, blockNum) } } else { @@ -761,7 +762,7 @@ func (suite *BackendTestSuite) TestBlockNumberFromTendermint() { } func (suite *BackendTestSuite) TestBlockNumberFromTendermintByHash() { - var resBlock *cmtrpctypes.ResultBlock + var resHeader *cmtrpctypes.ResultHeader _, bz := suite.buildEthereumTx() block := cmttypes.MakeBlock(1, []cmttypes.Tx{bz}, nil, nil) @@ -778,7 +779,7 @@ func (suite *BackendTestSuite) TestBlockNumberFromTendermintByHash() { common.BytesToHash(block.Hash()), func(hash common.Hash) { client := suite.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, hash, bz) + RegisterHeaderByHashError(client, hash, bz) }, false, }, @@ -787,7 +788,7 @@ func (suite *BackendTestSuite) TestBlockNumberFromTendermintByHash() { common.BytesToHash(emptyBlock.Hash()), func(hash common.Hash) { client := suite.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockByHash(client, hash, bz) + resHeader, _ = RegisterHeaderByHash(client, hash, bz) }, true, }, @@ -796,7 +797,7 @@ func (suite *BackendTestSuite) TestBlockNumberFromTendermintByHash() { common.BytesToHash(block.Hash()), func(hash common.Hash) { client := suite.backend.clientCtx.Client.(*mocks.Client) - resBlock, _ = RegisterBlockByHash(client, hash, bz) + resHeader, _ = RegisterHeaderByHash(client, hash, bz) }, true, }, @@ -808,7 +809,7 @@ func (suite *BackendTestSuite) TestBlockNumberFromTendermintByHash() { tc.registerMock(tc.hash) blockNum, err := suite.backend.BlockNumberFromTendermintByHash(tc.hash) if tc.expPass { - expHeight := big.NewInt(resBlock.Block.Height) + expHeight := big.NewInt(resHeader.Header.Height) suite.Require().NoError(err) suite.Require().Equal(expHeight, blockNum) } else { @@ -1306,7 +1307,7 @@ func (suite *BackendTestSuite) TestHeaderByNumber() { } func (suite *BackendTestSuite) TestHeaderByHash() { - var expResultBlock *cmtrpctypes.ResultBlock + var expResultHeader *cmtrpctypes.ResultHeader _, bz := suite.buildEthereumTx() block := cmttypes.MakeBlock(1, []cmttypes.Tx{bz}, nil, nil) @@ -1325,7 +1326,7 @@ func (suite *BackendTestSuite) TestHeaderByHash() { math.NewInt(1).BigInt(), func(hash common.Hash, _ math.Int) { client := suite.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashError(client, hash, bz) + RegisterHeaderByHashError(client, hash, bz) }, false, }, @@ -1335,7 +1336,7 @@ func (suite *BackendTestSuite) TestHeaderByHash() { math.NewInt(1).BigInt(), func(hash common.Hash, _ math.Int) { client := suite.backend.clientCtx.Client.(*mocks.Client) - RegisterBlockByHashNotFound(client, hash, bz) + RegisterHeaderByHashNotFound(client, hash, bz) }, false, }, @@ -1346,7 +1347,7 @@ func (suite *BackendTestSuite) TestHeaderByHash() { func(hash common.Hash, _ math.Int) { height := int64(1) client := suite.backend.clientCtx.Client.(*mocks.Client) - _, err := RegisterBlockByHash(client, hash, bz) + _, err := RegisterHeaderByHash(client, hash, bz) suite.Require().NoError(err) RegisterBlockResultsError(client, height) }, @@ -1359,7 +1360,7 @@ func (suite *BackendTestSuite) TestHeaderByHash() { func(hash common.Hash, _ math.Int) { height := int64(1) client := suite.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlockByHash(client, hash, bz) + expResultHeader, _ = RegisterHeaderByHash(client, hash, bz) _, err := RegisterBlockResults(client, height) suite.Require().NoError(err) queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) @@ -1374,7 +1375,7 @@ func (suite *BackendTestSuite) TestHeaderByHash() { func(hash common.Hash, baseFee math.Int) { height := int64(1) client := suite.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlockByHash(client, hash, nil) + expResultHeader, _ = RegisterHeaderByHash(client, hash, nil) _, err := RegisterBlockResults(client, height) suite.Require().NoError(err) queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) @@ -1389,7 +1390,7 @@ func (suite *BackendTestSuite) TestHeaderByHash() { func(hash common.Hash, baseFee math.Int) { height := int64(1) client := suite.backend.clientCtx.Client.(*mocks.Client) - expResultBlock, _ = RegisterBlockByHash(client, hash, bz) + expResultHeader, _ = RegisterHeaderByHash(client, hash, bz) _, err := RegisterBlockResults(client, height) suite.Require().NoError(err) queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient) @@ -1406,7 +1407,7 @@ func (suite *BackendTestSuite) TestHeaderByHash() { header, err := suite.backend.HeaderByHash(tc.hash) if tc.expPass { - expHeader := ethrpc.EthHeaderFromTendermint(expResultBlock.Block.Header, ethtypes.Bloom{}, tc.baseFee) + expHeader := ethrpc.EthHeaderFromTendermint(*expResultHeader.Header, ethtypes.Bloom{}, tc.baseFee) suite.Require().NoError(err) suite.Require().Equal(expHeader, header) } else { diff --git a/rpc/backend/chain_info.go b/rpc/backend/chain_info.go index 67373c6f..f8ab01b0 100644 --- a/rpc/backend/chain_info.go +++ b/rpc/backend/chain_info.go @@ -208,7 +208,7 @@ func (b *Backend) FeeHistory( } // tendermint block result - tendermintBlockResult, err := b.TendermintBlockResultByNumber(&tendermintblock.Block.Height) + tendermintBlockResult, err := b.rpcClient.BlockResults(b.ctx, &tendermintblock.Block.Height) if tendermintBlockResult == nil { b.logger.Debug("block result not found", "height", tendermintblock.Block.Height, "error", err.Error()) return nil, err diff --git a/rpc/backend/client_test.go b/rpc/backend/client_test.go index f1feb816..5a21b80f 100644 --- a/rpc/backend/client_test.go +++ b/rpc/backend/client_test.go @@ -6,9 +6,11 @@ import ( abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/bytes" + cmtversion "github.com/cometbft/cometbft/proto/tendermint/version" cmtrpcclient "github.com/cometbft/cometbft/rpc/client" cmtrpctypes "github.com/cometbft/cometbft/rpc/core/types" "github.com/cometbft/cometbft/types" + "github.com/cometbft/cometbft/version" "github.com/cosmos/cosmos-sdk/client" codectypes "github.com/cosmos/cosmos-sdk/codec/types" errortypes "github.com/cosmos/cosmos-sdk/types/errors" @@ -254,6 +256,36 @@ func RegisterBlockByHashNotFound(client *mocks.Client, _ common.Hash, _ []byte) Return(nil, nil) } +// HeaderByHash +func RegisterHeaderByHash( + client *mocks.Client, + _ common.Hash, + _ []byte, +) (*cmtrpctypes.ResultHeader, error) { + header := &types.Header{ + Version: cmtversion.Consensus{Block: version.BlockProtocol, App: 0}, + Height: 1, + } + resHeader := &cmtrpctypes.ResultHeader{ + Header: header, + } + + client.On("HeaderByHash", rpc.ContextWithHeight(1), bytes.HexBytes{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}). + Return(resHeader, nil) + return resHeader, nil +} + +func RegisterHeaderByHashError(client *mocks.Client, _ common.Hash, _ []byte) { + client.On("HeaderByHash", rpc.ContextWithHeight(1), bytes.HexBytes{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}). + Return(nil, errortypes.ErrInvalidRequest) +} + +func RegisterHeaderByHashNotFound(client *mocks.Client, _ common.Hash, _ []byte) { + client.On("HeaderByHash", rpc.ContextWithHeight(1), bytes.HexBytes{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}). + Return(nil, nil) +} + + func RegisterABCIQueryWithOptions(client *mocks.Client, height int64, path string, data bytes.HexBytes, opts cmtrpcclient.ABCIQueryOptions) { client.On("ABCIQueryWithOptions", context.Background(), path, data, opts). Return(&cmtrpctypes.ResultABCIQuery{ diff --git a/rpc/backend/filters.go b/rpc/backend/filters.go index 71cc805f..abb08f44 100644 --- a/rpc/backend/filters.go +++ b/rpc/backend/filters.go @@ -23,7 +23,7 @@ func (b *Backend) GetLogs(hash common.Hash) ([][]*ethtypes.Log, error) { // GetLogsByHeight returns all the logs from all the ethereum transactions in a block. func (b *Backend) GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error) { // NOTE: we query the state in case the tx result logs are not persisted after an upgrade. - blockRes, err := b.TendermintBlockResultByNumber(height) + blockRes, err := b.rpcClient.BlockResults(b.ctx, height) if err != nil { return nil, err } diff --git a/rpc/backend/tx_info.go b/rpc/backend/tx_info.go index 3339f199..a5abfb71 100644 --- a/rpc/backend/tx_info.go +++ b/rpc/backend/tx_info.go @@ -47,7 +47,7 @@ func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransac return nil, errors.New("invalid ethereum tx") } - blockRes, err := b.TendermintBlockResultByNumber(&block.Block.Height) + blockRes, err := b.rpcClient.BlockResults(b.ctx, &block.Block.Height) if err != nil { b.logger.Debug("block result not found", "height", block.Block.Height, "error", err.Error()) return nil, nil @@ -148,16 +148,19 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ b.logger.Debug("tx not found", "hash", hexTx, "error", err.Error()) return nil, nil } + resBlock, err := b.TendermintBlockByNumber(rpctypes.BlockNumber(res.Height)) if err != nil { b.logger.Debug("block not found", "height", res.Height, "error", err.Error()) return nil, nil } + tx, err := b.clientCtx.TxConfig.TxDecoder()(resBlock.Block.Txs[res.TxIndex]) if err != nil { b.logger.Debug("decoding failed", "error", err.Error()) return nil, fmt.Errorf("failed to decode tx: %w", err) } + ethMsg := tx.GetMsgs()[res.MsgIndex].(*evmtypes.MsgEthereumTx) txData, err := evmtypes.UnpackTxData(ethMsg.Data) @@ -167,14 +170,16 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ } cumulativeGasUsed := uint64(0) - blockRes, err := b.TendermintBlockResultByNumber(&res.Height) + blockRes, err := b.rpcClient.BlockResults(b.ctx, &res.Height) if err != nil { b.logger.Debug("failed to retrieve block results", "height", res.Height, "error", err.Error()) return nil, nil } + for _, txResult := range blockRes.TxsResults[0:res.TxIndex] { cumulativeGasUsed += uint64(txResult.GasUsed) // #nosec G115 -- checked for int overflow already } + cumulativeGasUsed += res.CumulativeGasUsed var status hexutil.Uint @@ -183,6 +188,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ } else { status = hexutil.Uint(ethtypes.ReceiptStatusSuccessful) } + chainID, err := b.ChainID() if err != nil { return nil, err @@ -262,6 +268,32 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ return receipt, nil } +// GetTransactionLogs returns the transaction logs identified by hash. +func (b *Backend) GetTransactionLogs(hash common.Hash) ([]*ethtypes.Log, error) { + hexTx := hash.Hex() + + res, err := b.GetTxByEthHash(hash) + if err != nil { + b.logger.Debug("tx not found", "hash", hexTx, "error", err.Error()) + return nil, nil + } + + if res.Failed { + // failed, return empty logs + return nil, nil + } + + resBlockResult, err := b.rpcClient.BlockResults(b.ctx, &res.Height) + if err != nil { + b.logger.Debug("block result not found", "number", res.Height, "error", err.Error()) + return nil, nil + } + + // parse tx logs from events + index := int(res.MsgIndex) // #nosec G701 + return TxLogsFromEvents(resBlockResult.TxsResults[res.TxIndex].Events, index) +} + // GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index. func (b *Backend) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { b.logger.Debug("eth_getTransactionByBlockHashAndIndex", "hash", hash.Hex(), "index", idx) @@ -370,7 +402,7 @@ func (b *Backend) queryTendermintTxIndexer(query string, txGetter func(*rpctypes // GetTransactionByBlockAndIndex is the common code shared by `GetTransactionByBlockNumberAndIndex` and `GetTransactionByBlockHashAndIndex`. func (b *Backend) GetTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { - blockRes, err := b.TendermintBlockResultByNumber(&block.Block.Height) + blockRes, err := b.rpcClient.BlockResults(b.ctx, &block.Block.Height) if err != nil { return nil, nil } diff --git a/rpc/namespaces/ethereum/eth/api.go b/rpc/namespaces/ethereum/eth/api.go index 895350a2..2fb3eaf1 100644 --- a/rpc/namespaces/ethereum/eth/api.go +++ b/rpc/namespaces/ethereum/eth/api.go @@ -412,27 +412,7 @@ func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.By func (e *PublicAPI) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) { e.logger.Debug("eth_getTransactionLogs", "hash", txHash) - hexTx := txHash.Hex() - res, err := e.backend.GetTxByEthHash(txHash) - if err != nil { - e.logger.Debug("tx not found", "hash", hexTx, "error", err.Error()) - return nil, nil - } - - if res.Failed { - // failed, return empty logs - return nil, nil - } - - resBlockResult, err := e.backend.TendermintBlockResultByNumber(&res.Height) - if err != nil { - e.logger.Debug("block result not found", "number", res.Height, "error", err.Error()) - return nil, nil - } - - // parse tx logs from events - index := int(res.MsgIndex) // #nosec G115 - return backend.TxLogsFromEvents(resBlockResult.TxsResults[res.TxIndex].Events, index) + return e.backend.GetTransactionLogs(txHash) } // SignTypedData signs EIP-712 conformant typed data @@ -486,6 +466,13 @@ func (e *PublicAPI) GetPendingTransactions() ([]*rpctypes.RPCTransaction, error) return nil, err } + chainIDHex, err := e.backend.ChainID() + if err != nil { + return nil, err + } + + chainID := chainIDHex.ToInt() + result := make([]*rpctypes.RPCTransaction, 0, len(txs)) for _, tx := range txs { for _, msg := range (*tx).GetMsgs() { @@ -501,7 +488,7 @@ func (e *PublicAPI) GetPendingTransactions() ([]*rpctypes.RPCTransaction, error) uint64(0), uint64(0), nil, - e.backend.ChainConfig().ChainID, + chainID, ) if err != nil { return nil, err diff --git a/rpc/types/utils.go b/rpc/types/utils.go index 16a2cafc..eb98a20e 100644 --- a/rpc/types/utils.go +++ b/rpc/types/utils.go @@ -165,7 +165,11 @@ func NewTransactionFromMsg( // NewTransactionFromData returns a transaction that will serialize to the RPC // representation, with the given location metadata set (if available). func NewRPCTransaction( - tx *ethtypes.Transaction, blockHash common.Hash, blockNumber, index uint64, baseFee *big.Int, + tx *ethtypes.Transaction, + blockHash common.Hash, + blockNumber, + index uint64, + baseFee, chainID *big.Int, ) (*RPCTransaction, error) { // Determine the signer. For replay-protected transactions, use the most permissive @@ -220,6 +224,7 @@ func NewRPCTransaction( result.GasPrice = (*hexutil.Big)(tx.GasFeeCap()) } } + return result, nil }