tests(rpc): add backend blocks tests (#1296)

* wip

* rename GetTendermintBlockByNumber to TendermintBlockByNumber

* rename GetTendermintBlockResultByNumber to TendermintBlockResultByNumber

* rename GetTendermintBlockByHash to TendermintBlockByHash

* rename BlockByNumber to EthBlockByNumber

* rename BlockByHash to EthBlockByHash

* rename GetBlockNumberByHash to BlockNumberFromTendermintByHash

* rename GetBlockNumber to BlockNumberFromTendermint

* rename GetEthereumMsgsFromTendermintBlock to EthMsgsFromTendermintBlock

* rename GetEthBlockFromTendermint to BlockFromTendermintBlock

* rename EthBlockFromTendermint to EthBlockFromTendermintBlock

* add TestEthBlockFromTendermintBlock with no transactions. Note that this endpoint is breaking when querying a block with transactions

* add block transaction count tests

* add TendermintBlockByHash test'

* add TestBlockNumberFromTendermint tests

* add HeaderByHash and HeaderByNumber tests

* add EthBlockFromTendermintBlock test

* add TestEthBlockByNumber tests

* Specificy that the endpoints are getting Etherum transactions in comments

* Refactor shared logic into GetBlockTransactionCount

* rename BlockFromTendermintBlock to RPCBlockFromTendermintBlock

* add CHangelog
This commit is contained in:
Daniel Burckhardt 2022-09-05 16:07:56 +02:00 committed by GitHub
parent 7bef408068
commit 9f03ca713d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1143 additions and 395 deletions

View File

@ -61,6 +61,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (cli) [#1230](https://github.com/evmos/ethermint/pull/1230) Remove redundant positional height parameter from feemarket's query cli. * (cli) [#1230](https://github.com/evmos/ethermint/pull/1230) Remove redundant positional height parameter from feemarket's query cli.
* (ante) [#1289](https://github.com/evmos/ethermint/pull/1289) Change the fallback tx priority mechanism to be based on gas price. * (ante) [#1289](https://github.com/evmos/ethermint/pull/1289) Change the fallback tx priority mechanism to be based on gas price.
* (test) [#1311](https://github.com/evmos/ethermint/pull/1311) add integration test for the rollback cmd * (test) [#1311](https://github.com/evmos/ethermint/pull/1311) add integration test for the rollback cmd
* (rpc) [#1296](https://github.com/evmos/ethermint/pull/1296) add backend blocks.go unit tests.
### Bug Fixes ### Bug Fixes

View File

@ -17,7 +17,7 @@ import (
// GetCode returns the contract code at the given address and block number. // GetCode returns the contract code at the given address and block number.
func (b *Backend) GetCode(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) { func (b *Backend) GetCode(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) {
blockNum, err := b.GetBlockNumber(blockNrOrHash) blockNum, err := b.BlockNumberFromTendermint(blockNrOrHash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -35,17 +35,14 @@ func (b *Backend) GetCode(address common.Address, blockNrOrHash rpctypes.BlockNu
} }
// GetProof returns an account object with proof and any storage proofs // GetProof returns an account object with proof and any storage proofs
func (b *Backend) GetProof(address common.Address, func (b *Backend) GetProof(address common.Address, storageKeys []string, blockNrOrHash rpctypes.BlockNumberOrHash) (*rpctypes.AccountResult, error) {
storageKeys []string, blockNum, err := b.BlockNumberFromTendermint(blockNrOrHash)
blockNrOrHash rpctypes.BlockNumberOrHash,
) (*rpctypes.AccountResult, error) {
blockNum, err := b.GetBlockNumber(blockNrOrHash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
height := blockNum.Int64() height := blockNum.Int64()
_, err = b.GetTendermintBlockByNumber(blockNum) _, err = b.TendermintBlockByNumber(blockNum)
if err != nil { if err != nil {
// the error message imitates geth behavior // the error message imitates geth behavior
return nil, errors.New("header not found") return nil, errors.New("header not found")
@ -132,7 +129,7 @@ func (b *Backend) GetProof(address common.Address,
// GetStorageAt returns the contract storage at the given address, block number, and key. // GetStorageAt returns the contract storage at the given address, block number, and key.
func (b *Backend) GetStorageAt(address common.Address, key string, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) { func (b *Backend) GetStorageAt(address common.Address, key string, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) {
blockNum, err := b.GetBlockNumber(blockNrOrHash) blockNum, err := b.BlockNumberFromTendermint(blockNrOrHash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -153,7 +150,7 @@ func (b *Backend) GetStorageAt(address common.Address, key string, blockNrOrHash
// GetBalance returns the provided account's balance up to the provided block number. // GetBalance returns the provided account's balance up to the provided block number.
func (b *Backend) GetBalance(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Big, error) { func (b *Backend) GetBalance(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Big, error) {
blockNum, err := b.GetBlockNumber(blockNrOrHash) blockNum, err := b.BlockNumberFromTendermint(blockNrOrHash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -162,7 +159,7 @@ func (b *Backend) GetBalance(address common.Address, blockNrOrHash rpctypes.Bloc
Address: address.String(), Address: address.String(),
} }
_, err = b.GetTendermintBlockByNumber(blockNum) _, err = b.TendermintBlockByNumber(blockNum)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -67,22 +67,21 @@ type EVMBackend interface {
// Blocks Info // Blocks Info
BlockNumber() (hexutil.Uint64, error) BlockNumber() (hexutil.Uint64, error)
GetBlockByNumber(blockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error) GetBlockByNumber(blockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error)
GetTendermintBlockByNumber(blockNum rpctypes.BlockNumber) (*tmrpctypes.ResultBlock, error)
GetTendermintBlockResultByNumber(height *int64) (*tmrpctypes.ResultBlockResults, error)
GetTendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error)
GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
BlockByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Block, error)
BlockByHash(blockHash common.Hash) (*ethtypes.Block, error)
GetBlockNumberByHash(blockHash common.Hash) (*big.Int, error)
GetBlockNumber(blockNrOrHash rpctypes.BlockNumberOrHash) (rpctypes.BlockNumber, error)
GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint
GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *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)
EthMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults) []*evmtypes.MsgEthereumTx
BlockBloom(blockRes *tmrpctypes.ResultBlockResults) (ethtypes.Bloom, error) BlockBloom(blockRes *tmrpctypes.ResultBlockResults) (ethtypes.Bloom, error)
GetEthereumMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults) []*evmtypes.MsgEthereumTx
HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Header, error) HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Header, error)
HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
EthBlockFromTendermint(resBlock *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults, fullTx bool) (map[string]interface{}, error) RPCBlockFromTendermintBlock(resBlock *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults, fullTx bool) (map[string]interface{}, error)
EthBlockFromTm(resBlock *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults) (*ethtypes.Block, error) EthBlockByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Block, error)
EthBlockFromTendermintBlock(resBlock *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults) (*ethtypes.Block, error)
// Account Info // Account Info
GetCode(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error) GetCode(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (hexutil.Bytes, error)
@ -117,6 +116,7 @@ type EVMBackend interface {
SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error)
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rpctypes.BlockNumber) (hexutil.Uint64, error) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rpctypes.BlockNumber) (hexutil.Uint64, error)
DoCall(args evmtypes.TransactionArgs, blockNr rpctypes.BlockNumber) (*evmtypes.MsgEthereumTxResponse, error) DoCall(args evmtypes.TransactionArgs, blockNr rpctypes.BlockNumber) (*evmtypes.MsgEthereumTxResponse, error)
GasPrice() (*hexutil.Big, error)
// Filter API // Filter API
GetLogs(hash common.Hash) ([][]*ethtypes.Log, error) GetLogs(hash common.Hash) ([][]*ethtypes.Log, error)

View File

@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/trie"
rpctypes "github.com/evmos/ethermint/rpc/types" rpctypes "github.com/evmos/ethermint/rpc/types"
evmtypes "github.com/evmos/ethermint/x/evm/types" evmtypes "github.com/evmos/ethermint/x/evm/types"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -19,16 +20,10 @@ import (
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
) )
// Getting Blocks // BlockNumber returns the current block number in abci app state. Because abci
// // app state could lag behind from tendermint latest block, it's more stable for
// Retrieves information from a particular block in the blockchain. // the client to use the latest block number in abci app state than tendermint
// BlockNumber() (hexutil.Uint64, error) // rpc.
// GetBlockByNumber(ethBlockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error)
// GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
// BlockNumber returns the current block number in abci app state.
// Because abci app state could lag behind from tendermint latest block, it's more stable
// for the client to use the latest block number in abci app state than tendermint rpc.
func (b *Backend) BlockNumber() (hexutil.Uint64, error) { func (b *Backend) BlockNumber() (hexutil.Uint64, error) {
// do any grpc query, ignore the response and use the returned block height // do any grpc query, ignore the response and use the returned block height
var header metadata.MD var header metadata.MD
@ -50,9 +45,11 @@ func (b *Backend) BlockNumber() (hexutil.Uint64, error) {
return hexutil.Uint64(height), nil return hexutil.Uint64(height), nil
} }
// GetBlockByNumber returns the block identified by number. // GetBlockByNumber returns the JSON-RPC compatible Ethereum block identified by
// block number. Depending on fullTx it either returns the full transaction
// objects or if false only the hashes of the transactions.
func (b *Backend) GetBlockByNumber(blockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error) { func (b *Backend) GetBlockByNumber(blockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error) {
resBlock, err := b.GetTendermintBlockByNumber(blockNum) resBlock, err := b.TendermintBlockByNumber(blockNum)
if err != nil { if err != nil {
return nil, nil return nil, nil
} }
@ -62,24 +59,25 @@ func (b *Backend) GetBlockByNumber(blockNum rpctypes.BlockNumber, fullTx bool) (
return nil, nil return nil, nil
} }
blockRes, err := b.GetTendermintBlockResultByNumber(&resBlock.Block.Height) blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height)
if err != nil { if err != nil {
b.logger.Debug("failed to fetch block result from Tendermint", "height", blockNum, "error", err.Error()) b.logger.Debug("failed to fetch block result from Tendermint", "height", blockNum, "error", err.Error())
return nil, nil return nil, nil
} }
res, err := b.EthBlockFromTendermint(resBlock, blockRes, fullTx) res, err := b.RPCBlockFromTendermintBlock(resBlock, blockRes, fullTx)
if err != nil { if err != nil {
b.logger.Debug("EthBlockFromTendermint failed", "height", blockNum, "error", err.Error()) b.logger.Debug("GetEthBlockFromTendermint failed", "height", blockNum, "error", err.Error())
return nil, err return nil, err
} }
return res, nil return res, nil
} }
// GetBlockByHash returns the block identified by hash. // GetBlockByHash returns the JSON-RPC compatible Ethereum block identified by
// hash.
func (b *Backend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) { func (b *Backend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) {
resBlock, err := b.GetTendermintBlockByHash(hash) resBlock, err := b.TendermintBlockByHash(hash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -89,24 +87,71 @@ func (b *Backend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]inte
return nil, nil return nil, nil
} }
blockRes, err := b.GetTendermintBlockResultByNumber(&resBlock.Block.Height) blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height)
if err != nil { if err != nil {
b.logger.Debug("failed to fetch block result from Tendermint", "block-hash", hash.String(), "error", err.Error()) b.logger.Debug("failed to fetch block result from Tendermint", "block-hash", hash.String(), "error", err.Error())
return nil, nil return nil, nil
} }
res, err := b.EthBlockFromTendermint(resBlock, blockRes, fullTx) res, err := b.RPCBlockFromTendermintBlock(resBlock, blockRes, fullTx)
if err != nil { if err != nil {
b.logger.Debug("EthBlockFromTendermint failed", "hash", hash, "error", err.Error()) b.logger.Debug("GetEthBlockFromTendermint failed", "hash", hash, "error", err.Error())
return nil, err return nil, err
} }
return res, nil return res, nil
} }
// GetTendermintBlockByNumber returns a Tendermint formatted block for a given // GetBlockTransactionCountByHash returns the number of Ethereum transactions in
// the block identified by hash.
func (b *Backend) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint {
block, err := b.clientCtx.Client.BlockByHash(b.ctx, hash.Bytes())
if err != nil {
b.logger.Debug("block not found", "hash", hash.Hex(), "error", err.Error())
return nil
}
if block.Block == nil {
b.logger.Debug("block not found", "hash", hash.Hex())
return nil
}
return b.GetBlockTransactionCount(block)
}
// GetBlockTransactionCountByNumber returns the number of Ethereum transactions
// in the block identified by number.
func (b *Backend) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint {
block, err := b.TendermintBlockByNumber(blockNum)
if err != nil {
b.logger.Debug("block not found", "height", blockNum.Int64(), "error", err.Error())
return nil
}
if block.Block == nil {
b.logger.Debug("block not found", "height", blockNum.Int64())
return nil
}
return b.GetBlockTransactionCount(block)
}
// 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)
if err != nil {
return nil
}
ethMsgs := b.EthMsgsFromTendermintBlock(block, blockRes)
n := hexutil.Uint(len(ethMsgs))
return &n
}
// TendermintBlockByNumber returns a Tendermint-formatted block for a given
// block number // block number
func (b *Backend) GetTendermintBlockByNumber(blockNum rpctypes.BlockNumber) (*tmrpctypes.ResultBlock, error) { func (b *Backend) TendermintBlockByNumber(blockNum rpctypes.BlockNumber) (*tmrpctypes.ResultBlock, error) {
height := blockNum.Int64() height := blockNum.Int64()
if height <= 0 { if height <= 0 {
// fetch the latest block number from the app state, more accurate than the tendermint block store state. // fetch the latest block number from the app state, more accurate than the tendermint block store state.
@ -123,36 +168,21 @@ func (b *Backend) GetTendermintBlockByNumber(blockNum rpctypes.BlockNumber) (*tm
} }
if resBlock.Block == nil { if resBlock.Block == nil {
b.logger.Debug("GetTendermintBlockByNumber block not found", "height", height) b.logger.Debug("TendermintBlockByNumber block not found", "height", height)
return nil, nil return nil, nil
} }
return resBlock, nil return resBlock, nil
} }
// BlockBloom query block bloom filter from block results // TendermintBlockResultByNumber returns a Tendermint-formatted block result
func (b *Backend) BlockBloom(blockRes *tmrpctypes.ResultBlockResults) (ethtypes.Bloom, error) { // by block number
for _, event := range blockRes.EndBlockEvents { func (b *Backend) TendermintBlockResultByNumber(height *int64) (*tmrpctypes.ResultBlockResults, error) {
if event.Type != evmtypes.EventTypeBlockBloom {
continue
}
for _, attr := range event.Attributes {
if bytes.Equal(attr.Key, bAttributeKeyEthereumBloom) {
return ethtypes.BytesToBloom(attr.Value), nil
}
}
}
return ethtypes.Bloom{}, errors.New("block bloom event is not found")
}
// GetTendermintBlockResultByNumber returns a Tendermint-formatted block result by block number
func (b *Backend) GetTendermintBlockResultByNumber(height *int64) (*tmrpctypes.ResultBlockResults, error) {
return b.clientCtx.Client.BlockResults(b.ctx, height) return b.clientCtx.Client.BlockResults(b.ctx, height)
} }
// GetTendermintBlockByHash returns a Tendermint format block by block number // TendermintBlockByHash returns a Tendermint-formatted block by block number
func (b *Backend) GetTendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error) { func (b *Backend) TendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error) {
resBlock, err := b.clientCtx.Client.BlockByHash(b.ctx, blockHash.Bytes()) resBlock, err := b.clientCtx.Client.BlockByHash(b.ctx, blockHash.Bytes())
if err != nil { if err != nil {
b.logger.Debug("tendermint client failed to get block", "blockHash", blockHash.Hex(), "error", err.Error()) b.logger.Debug("tendermint client failed to get block", "blockHash", blockHash.Hex(), "error", err.Error())
@ -160,70 +190,20 @@ func (b *Backend) GetTendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.R
} }
if resBlock == nil || resBlock.Block == nil { if resBlock == nil || resBlock.Block == nil {
b.logger.Debug("GetTendermintBlockByHash block not found", "blockHash", blockHash.Hex()) b.logger.Debug("TendermintBlockByHash block not found", "blockHash", blockHash.Hex())
return nil, nil return nil, nil
} }
return resBlock, nil return resBlock, nil
} }
// BlockByNumber returns the block identified by number. // BlockNumberFromTendermint returns the BlockNumber from BlockNumberOrHash
func (b *Backend) BlockByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Block, error) { func (b *Backend) BlockNumberFromTendermint(blockNrOrHash rpctypes.BlockNumberOrHash) (rpctypes.BlockNumber, error) {
resBlock, err := b.GetTendermintBlockByNumber(blockNum)
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.GetTendermintBlockResultByNumber(&resBlock.Block.Height)
if err != nil {
return nil, fmt.Errorf("block result not found for height %d", resBlock.Block.Height)
}
return b.EthBlockFromTm(resBlock, blockRes)
}
// BlockByHash returns the block identified by hash.
func (b *Backend) BlockByHash(hash common.Hash) (*ethtypes.Block, error) {
resBlock, err := b.GetTendermintBlockByHash(hash)
if err != nil {
return nil, err
}
if resBlock == nil || resBlock.Block == nil {
return nil, fmt.Errorf("block not found for hash %s", hash)
}
blockRes, err := b.GetTendermintBlockResultByNumber(&resBlock.Block.Height)
if err != nil {
return nil, fmt.Errorf("block result not found for hash %s", hash)
}
return b.EthBlockFromTm(resBlock, blockRes)
}
// GetBlockNumberByHash returns the block height of given block hash
func (b *Backend) GetBlockNumberByHash(blockHash common.Hash) (*big.Int, error) {
resBlock, err := b.GetTendermintBlockByHash(blockHash)
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
}
// getBlockNumber returns the BlockNumber from BlockNumberOrHash
func (b *Backend) GetBlockNumber(blockNrOrHash rpctypes.BlockNumberOrHash) (rpctypes.BlockNumber, error) {
switch { switch {
case blockNrOrHash.BlockHash == nil && blockNrOrHash.BlockNumber == nil: case blockNrOrHash.BlockHash == nil && blockNrOrHash.BlockNumber == nil:
return rpctypes.EthEarliestBlockNumber, fmt.Errorf("types BlockHash and BlockNumber cannot be both nil") return rpctypes.EthEarliestBlockNumber, fmt.Errorf("types BlockHash and BlockNumber cannot be both nil")
case blockNrOrHash.BlockHash != nil: case blockNrOrHash.BlockHash != nil:
blockNumber, err := b.GetBlockNumberByHash(*blockNrOrHash.BlockHash) blockNumber, err := b.BlockNumberFromTendermintByHash(*blockNrOrHash.BlockHash)
if err != nil { if err != nil {
return rpctypes.EthEarliestBlockNumber, err return rpctypes.EthEarliestBlockNumber, err
} }
@ -235,56 +215,22 @@ func (b *Backend) GetBlockNumber(blockNrOrHash rpctypes.BlockNumberOrHash) (rpct
} }
} }
// GetBlockTransactionCountByHash returns the number of transactions in the block identified by hash. // BlockNumberFromTendermintByHash returns the block height of given block hash
func (b *Backend) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint { func (b *Backend) BlockNumberFromTendermintByHash(blockHash common.Hash) (*big.Int, error) {
block, err := b.clientCtx.Client.BlockByHash(b.ctx, hash.Bytes()) resBlock, err := b.TendermintBlockByHash(blockHash)
if err != nil { if err != nil {
b.logger.Debug("block not found", "hash", hash.Hex(), "error", err.Error()) return nil, err
return nil
} }
if resBlock == nil {
if block.Block == nil { return nil, errors.Errorf("block not found for hash %s", blockHash.Hex())
b.logger.Debug("block not found", "hash", hash.Hex())
return nil
} }
return big.NewInt(resBlock.Block.Height), nil
blockRes, err := b.GetTendermintBlockResultByNumber(&block.Block.Height)
if err != nil {
return nil
}
ethMsgs := b.GetEthereumMsgsFromTendermintBlock(block, blockRes)
n := hexutil.Uint(len(ethMsgs))
return &n
} }
// GetBlockTransactionCountByNumber returns the number of transactions in the block identified by number. // EthMsgsFromTendermintBlock returns all real MsgEthereumTxs from a
func (b *Backend) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint {
block, err := b.GetTendermintBlockByNumber(blockNum)
if err != nil {
b.logger.Debug("block not found", "height", blockNum.Int64(), "error", err.Error())
return nil
}
if block.Block == nil {
b.logger.Debug("block not found", "height", blockNum.Int64())
return nil
}
blockRes, err := b.GetTendermintBlockResultByNumber(&block.Block.Height)
if err != nil {
return nil
}
ethMsgs := b.GetEthereumMsgsFromTendermintBlock(block, blockRes)
n := hexutil.Uint(len(ethMsgs))
return &n
}
// GetEthereumMsgsFromTendermintBlock returns all real MsgEthereumTxs from a
// Tendermint block. It also ensures consistency over the correct txs indexes // Tendermint block. It also ensures consistency over the correct txs indexes
// across RPC endpoints // across RPC endpoints
func (b *Backend) GetEthereumMsgsFromTendermintBlock( func (b *Backend) EthMsgsFromTendermintBlock(
resBlock *tmrpctypes.ResultBlock, resBlock *tmrpctypes.ResultBlock,
blockRes *tmrpctypes.ResultBlockResults, blockRes *tmrpctypes.ResultBlockResults,
) []*evmtypes.MsgEthereumTx { ) []*evmtypes.MsgEthereumTx {
@ -324,7 +270,7 @@ func (b *Backend) GetEthereumMsgsFromTendermintBlock(
// HeaderByNumber returns the block header identified by height. // HeaderByNumber returns the block header identified by height.
func (b *Backend) HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Header, error) { func (b *Backend) HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Header, error) {
resBlock, err := b.GetTendermintBlockByNumber(blockNum) resBlock, err := b.TendermintBlockByNumber(blockNum)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -333,7 +279,7 @@ func (b *Backend) HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Heade
return nil, errors.Errorf("block not found for height %d", blockNum) return nil, errors.Errorf("block not found for height %d", blockNum)
} }
blockRes, err := b.GetTendermintBlockResultByNumber(&resBlock.Block.Height) blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height)
if err != nil { if err != nil {
return nil, fmt.Errorf("block result not found for height %d", resBlock.Block.Height) return nil, fmt.Errorf("block result not found for height %d", resBlock.Block.Height)
} }
@ -355,7 +301,7 @@ func (b *Backend) HeaderByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Heade
// HeaderByHash returns the block header identified by hash. // HeaderByHash returns the block header identified by hash.
func (b *Backend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) { func (b *Backend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) {
resBlock, err := b.GetTendermintBlockByHash(blockHash) resBlock, err := b.TendermintBlockByHash(blockHash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -363,7 +309,7 @@ func (b *Backend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
return nil, errors.Errorf("block not found for hash %s", blockHash.Hex()) return nil, errors.Errorf("block not found for hash %s", blockHash.Hex())
} }
blockRes, err := b.GetTendermintBlockResultByNumber(&resBlock.Block.Height) blockRes, err := b.TendermintBlockResultByNumber(&resBlock.Block.Height)
if err != nil { 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", resBlock.Block.Height)
} }
@ -383,9 +329,25 @@ func (b *Backend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
return ethHeader, nil return ethHeader, nil
} }
// EthBlockFromTendermint returns a JSON-RPC compatible Ethereum block from a // BlockBloom query block bloom filter from block results
func (b *Backend) BlockBloom(blockRes *tmrpctypes.ResultBlockResults) (ethtypes.Bloom, error) {
for _, event := range blockRes.EndBlockEvents {
if event.Type != evmtypes.EventTypeBlockBloom {
continue
}
for _, attr := range event.Attributes {
if bytes.Equal(attr.Key, bAttributeKeyEthereumBloom) {
return ethtypes.BytesToBloom(attr.Value), nil
}
}
}
return ethtypes.Bloom{}, errors.New("block bloom event is not found")
}
// RPCBlockFromTendermintBlock returns a JSON-RPC compatible Ethereum block from a
// given Tendermint block and its block result. // given Tendermint block and its block result.
func (b *Backend) EthBlockFromTendermint( func (b *Backend) RPCBlockFromTendermintBlock(
resBlock *tmrpctypes.ResultBlock, resBlock *tmrpctypes.ResultBlock,
blockRes *tmrpctypes.ResultBlockResults, blockRes *tmrpctypes.ResultBlockResults,
fullTx bool, fullTx bool,
@ -399,7 +361,7 @@ func (b *Backend) EthBlockFromTendermint(
b.logger.Error("failed to fetch Base Fee from prunned block. Check node prunning configuration", "height", block.Height, "error", err) b.logger.Error("failed to fetch Base Fee from prunned block. Check node prunning configuration", "height", block.Height, "error", err)
} }
msgs := b.GetEthereumMsgsFromTendermintBlock(resBlock, blockRes) msgs := b.EthMsgsFromTendermintBlock(resBlock, blockRes)
for txIndex, ethMsg := range msgs { for txIndex, ethMsg := range msgs {
if !fullTx { if !fullTx {
hash := common.HexToHash(ethMsg.Hash) hash := common.HexToHash(ethMsg.Hash)
@ -477,8 +439,31 @@ func (b *Backend) EthBlockFromTendermint(
return formattedBlock, nil return formattedBlock, nil
} }
// Returns and Ethereum Block type from Tendermint block // EthBlockByNumber returns the Ethereum Block identified by number.
func (b *Backend) EthBlockFromTm(resBlock *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults) (*ethtypes.Block, error) { func (b *Backend) EthBlockByNumber(blockNum rpctypes.BlockNumber) (*ethtypes.Block, error) {
resBlock, err := b.TendermintBlockByNumber(blockNum)
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)
if err != nil {
return nil, fmt.Errorf("block result not found for height %d", resBlock.Block.Height)
}
return b.EthBlockFromTendermintBlock(resBlock, blockRes)
}
// EthBlockFromTendermintBlock returns an Ethereum Block type from Tendermint block
// EthBlockFromTendermintBlock
func (b *Backend) EthBlockFromTendermintBlock(
resBlock *tmrpctypes.ResultBlock,
blockRes *tmrpctypes.ResultBlockResults,
) (*ethtypes.Block, error) {
block := resBlock.Block block := resBlock.Block
height := block.Height height := block.Height
bloom, err := b.BlockBloom(blockRes) bloom, err := b.BlockBloom(blockRes)
@ -493,13 +478,7 @@ func (b *Backend) EthBlockFromTm(resBlock *tmrpctypes.ResultBlock, blockRes *tmr
} }
ethHeader := rpctypes.EthHeaderFromTendermint(block.Header, bloom, baseFee) ethHeader := rpctypes.EthHeaderFromTendermint(block.Header, bloom, baseFee)
msgs := b.EthMsgsFromTendermintBlock(resBlock, blockRes)
resBlockResult, err := b.GetTendermintBlockResultByNumber(&block.Height)
if err != nil {
return nil, err
}
msgs := b.GetEthereumMsgsFromTendermintBlock(resBlock, resBlockResult)
txs := make([]*ethtypes.Transaction, len(msgs)) txs := make([]*ethtypes.Transaction, len(msgs))
for i, ethMsg := range msgs { for i, ethMsg := range msgs {
@ -507,6 +486,6 @@ func (b *Backend) EthBlockFromTm(resBlock *tmrpctypes.ResultBlock, blockRes *tmr
} }
// TODO: add tx receipts // TODO: add tx receipts
ethBlock := ethtypes.NewBlock(ethHeader, txs, nil, nil, nil) ethBlock := ethtypes.NewBlock(ethHeader, txs, nil, nil, trie.NewStackTrie(nil))
return ethBlock, nil return ethBlock, nil
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/trie"
"github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/abci/types"
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
@ -17,7 +18,6 @@ import (
ethrpc "github.com/evmos/ethermint/rpc/types" ethrpc "github.com/evmos/ethermint/rpc/types"
"github.com/evmos/ethermint/tests" "github.com/evmos/ethermint/tests"
evmtypes "github.com/evmos/ethermint/x/evm/types" evmtypes "github.com/evmos/ethermint/x/evm/types"
feemarkettypes "github.com/evmos/ethermint/x/feemarket/types"
) )
func (suite *BackendTestSuite) TestBlockNumber() { func (suite *BackendTestSuite) TestBlockNumber() {
@ -242,6 +242,54 @@ func (suite *BackendTestSuite) TestGetBlockByHash() {
expNoop bool expNoop bool
expPass bool expPass bool
}{ }{
{
"fail - tendermint failed to get block",
common.BytesToHash(block.Hash()),
true,
sdk.NewInt(1).BigInt(),
sdk.AccAddress(tests.GenerateAddress().Bytes()),
nil,
nil,
func(hash common.Hash, baseFee sdk.Int, validator sdk.AccAddress, txBz []byte) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHashError(client, hash, txBz)
},
false,
false,
},
{
"noop - tendermint blockres not found",
common.BytesToHash(block.Hash()),
true,
sdk.NewInt(1).BigInt(),
sdk.AccAddress(tests.GenerateAddress().Bytes()),
nil,
nil,
func(hash common.Hash, baseFee sdk.Int, validator sdk.AccAddress, txBz []byte) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHashNotFound(client, hash, txBz)
},
true,
true,
},
{
"noop - tendermint failed to fetch block result",
common.BytesToHash(block.Hash()),
true,
sdk.NewInt(1).BigInt(),
sdk.AccAddress(tests.GenerateAddress().Bytes()),
nil,
nil,
func(hash common.Hash, baseFee sdk.Int, validator sdk.AccAddress, txBz []byte) {
height := int64(1)
client := suite.backend.clientCtx.Client.(*mocks.Client)
resBlock, _ = RegisterBlockByHash(client, hash, txBz)
RegisterBlockResultsError(client, height)
},
true,
true,
},
{ {
"pass - without tx", "pass - without tx",
common.BytesToHash(block.Hash()), common.BytesToHash(block.Hash()),
@ -319,7 +367,156 @@ func (suite *BackendTestSuite) TestGetBlockByHash() {
} }
} }
func (suite *BackendTestSuite) TestGetTendermintBlockByNumber() { func (suite *BackendTestSuite) TestGetBlockTransactionCountByHash() {
_, bz := suite.buildEthereumTx()
block := tmtypes.MakeBlock(1, []tmtypes.Tx{bz}, nil, nil)
emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{}, nil, nil)
testCases := []struct {
name string
hash common.Hash
registerMock func(common.Hash)
expCount hexutil.Uint
expPass bool
}{
{
"fail - block not found",
common.BytesToHash(emptyBlock.Hash()),
func(hash common.Hash) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHashError(client, hash, nil)
},
hexutil.Uint(0),
false,
},
{
"fail - tendermint client failed to get block result",
common.BytesToHash(emptyBlock.Hash()),
func(hash common.Hash) {
height := int64(1)
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHash(client, hash, nil)
RegisterBlockResultsError(client, height)
},
hexutil.Uint(0),
false,
},
{
"pass - block without tx",
common.BytesToHash(emptyBlock.Hash()),
func(hash common.Hash) {
height := int64(1)
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHash(client, hash, nil)
RegisterBlockResults(client, height)
},
hexutil.Uint(0),
true,
},
{
"pass - block with tx",
common.BytesToHash(block.Hash()),
func(hash common.Hash) {
height := int64(1)
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHash(client, hash, bz)
RegisterBlockResults(client, height)
},
hexutil.Uint(1),
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
tc.registerMock(tc.hash)
count := suite.backend.GetBlockTransactionCountByHash(tc.hash)
if tc.expPass {
suite.Require().Equal(tc.expCount, *count)
} else {
suite.Require().Nil(count)
}
})
}
}
func (suite *BackendTestSuite) TestGetBlockTransactionCountByNumber() {
_, bz := suite.buildEthereumTx()
block := tmtypes.MakeBlock(1, []tmtypes.Tx{bz}, nil, nil)
emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{}, nil, nil)
testCases := []struct {
name string
blockNum ethrpc.BlockNumber
registerMock func(ethrpc.BlockNumber)
expCount hexutil.Uint
expPass bool
}{
{
"fail - block not found",
ethrpc.BlockNumber(emptyBlock.Height),
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockError(client, height)
},
hexutil.Uint(0),
false,
},
{
"fail - tendermint client failed to get block result",
ethrpc.BlockNumber(emptyBlock.Height),
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, nil)
RegisterBlockResultsError(client, height)
},
hexutil.Uint(0),
false,
},
{
"pass - block without tx",
ethrpc.BlockNumber(emptyBlock.Height),
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, nil)
RegisterBlockResults(client, height)
},
hexutil.Uint(0),
true,
},
{
"pass - block with tx",
ethrpc.BlockNumber(block.Height),
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, bz)
RegisterBlockResults(client, height)
},
hexutil.Uint(1),
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
tc.registerMock(tc.blockNum)
count := suite.backend.GetBlockTransactionCountByNumber(tc.blockNum)
if tc.expPass {
suite.Require().Equal(tc.expCount, *count)
} else {
suite.Require().Nil(count)
}
})
}
}
func (suite *BackendTestSuite) TestTendermintBlockByNumber() {
var expResultBlock *tmrpctypes.ResultBlock var expResultBlock *tmrpctypes.ResultBlock
testCases := []struct { testCases := []struct {
@ -407,7 +604,7 @@ func (suite *BackendTestSuite) TestGetTendermintBlockByNumber() {
suite.SetupTest() // reset test and queries suite.SetupTest() // reset test and queries
tc.registerMock(tc.blockNumber) tc.registerMock(tc.blockNumber)
resultBlock, err := suite.backend.GetTendermintBlockByNumber(tc.blockNumber) resultBlock, err := suite.backend.TendermintBlockByNumber(tc.blockNumber)
if tc.expPass { if tc.expPass {
suite.Require().NoError(err) suite.Require().NoError(err)
@ -425,7 +622,7 @@ func (suite *BackendTestSuite) TestGetTendermintBlockByNumber() {
} }
} }
func (suite *BackendTestSuite) TestGetTendermintBlockResultByNumber() { func (suite *BackendTestSuite) TestTendermintBlockResultByNumber() {
var expBlockRes *tmrpctypes.ResultBlockResults var expBlockRes *tmrpctypes.ResultBlockResults
testCases := []struct { testCases := []struct {
@ -463,7 +660,7 @@ func (suite *BackendTestSuite) TestGetTendermintBlockResultByNumber() {
suite.SetupTest() // reset test and queries suite.SetupTest() // reset test and queries
tc.registerMock(tc.blockNumber) tc.registerMock(tc.blockNumber)
blockRes, err := suite.backend.GetTendermintBlockResultByNumber(&tc.blockNumber) blockRes, err := suite.backend.TendermintBlockResultByNumber(&tc.blockNumber)
if tc.expPass { if tc.expPass {
suite.Require().NoError(err) suite.Require().NoError(err)
@ -475,6 +672,141 @@ func (suite *BackendTestSuite) TestGetTendermintBlockResultByNumber() {
} }
} }
func (suite *BackendTestSuite) TestBlockNumberFromTendermint() {
var resBlock *tmrpctypes.ResultBlock
_, bz := suite.buildEthereumTx()
block := tmtypes.MakeBlock(1, []tmtypes.Tx{bz}, nil, nil)
blockNum := ethrpc.NewBlockNumber(big.NewInt(block.Height))
blockHash := common.BytesToHash(block.Hash())
testCases := []struct {
name string
blockNum *ethrpc.BlockNumber
hash *common.Hash
registerMock func(*common.Hash)
expPass bool
}{
{
"error - without blockHash or blockNum",
nil,
nil,
func(hash *common.Hash) {},
false,
},
{
"error - with blockHash, tendermint client failed to get block",
nil,
&blockHash,
func(hash *common.Hash) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHashError(client, *hash, bz)
},
false,
},
{
"pass - with blockHash",
nil,
&blockHash,
func(hash *common.Hash) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
resBlock, _ = RegisterBlockByHash(client, *hash, bz)
},
true,
},
{
"pass - without blockHash & with blockNumber",
&blockNum,
nil,
func(hash *common.Hash) {},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
blockNrOrHash := ethrpc.BlockNumberOrHash{
BlockNumber: tc.blockNum,
BlockHash: tc.hash,
}
tc.registerMock(tc.hash)
blockNum, err := suite.backend.BlockNumberFromTendermint(blockNrOrHash)
if tc.expPass {
suite.Require().NoError(err)
if tc.hash == nil {
suite.Require().Equal(*tc.blockNum, blockNum)
} else {
expHeight := ethrpc.NewBlockNumber(big.NewInt(resBlock.Block.Height))
suite.Require().Equal(expHeight, blockNum)
}
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *BackendTestSuite) TestBlockNumberFromTendermintByHash() {
var resBlock *tmrpctypes.ResultBlock
_, bz := suite.buildEthereumTx()
block := tmtypes.MakeBlock(1, []tmtypes.Tx{bz}, nil, nil)
emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{}, nil, nil)
testCases := []struct {
name string
hash common.Hash
registerMock func(common.Hash)
expPass bool
}{
{
"fail - tendermint client failed to get block",
common.BytesToHash(block.Hash()),
func(hash common.Hash) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHashError(client, hash, bz)
},
false,
},
{
"pass - block without tx",
common.BytesToHash(emptyBlock.Hash()),
func(hash common.Hash) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
resBlock, _ = RegisterBlockByHash(client, hash, bz)
},
true,
},
{
"pass - block with tx",
common.BytesToHash(block.Hash()),
func(hash common.Hash) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
resBlock, _ = RegisterBlockByHash(client, hash, bz)
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
tc.registerMock(tc.hash)
blockNum, err := suite.backend.BlockNumberFromTendermintByHash(tc.hash)
if tc.expPass {
expHeight := big.NewInt(resBlock.Block.Height)
suite.Require().NoError(err)
suite.Require().Equal(expHeight, blockNum)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *BackendTestSuite) TestBlockBloom() { func (suite *BackendTestSuite) TestBlockBloom() {
testCases := []struct { testCases := []struct {
name string name string
@ -512,7 +844,7 @@ func (suite *BackendTestSuite) TestBlockBloom() {
false, false,
}, },
{ {
"pass - nonblock bloom attribute key", "pass - block bloom attribute key",
&tmrpctypes.ResultBlockResults{ &tmrpctypes.ResultBlockResults{
EndBlockEvents: []types.Event{ EndBlockEvents: []types.Event{
{ {
@ -541,7 +873,7 @@ func (suite *BackendTestSuite) TestBlockBloom() {
} }
} }
func (suite *BackendTestSuite) TestEthBlockFromTendermint() { func (suite *BackendTestSuite) TestGetEthBlockFromTendermint() {
msgEthereumTx, bz := suite.buildEthereumTx() msgEthereumTx, bz := suite.buildEthereumTx()
emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{}, nil, nil) emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{}, nil, nil)
@ -735,7 +1067,7 @@ func (suite *BackendTestSuite) TestEthBlockFromTendermint() {
suite.SetupTest() // reset test and queries suite.SetupTest() // reset test and queries
tc.registerMock(sdk.NewIntFromBigInt(tc.baseFee), tc.validator, tc.height) tc.registerMock(sdk.NewIntFromBigInt(tc.baseFee), tc.validator, tc.height)
block, err := suite.backend.EthBlockFromTendermint(tc.resBlock, tc.blockRes, tc.fullTx) block, err := suite.backend.RPCBlockFromTendermintBlock(tc.resBlock, tc.blockRes, tc.fullTx)
var expBlock map[string]interface{} var expBlock map[string]interface{}
header := tc.resBlock.Block.Header header := tc.resBlock.Block.Header
@ -785,139 +1117,7 @@ func (suite *BackendTestSuite) TestEthBlockFromTendermint() {
} }
} }
func (suite *BackendTestSuite) TestBaseFee() { func (suite *BackendTestSuite) TestEthMsgsFromTendermintBlock() {
baseFee := sdk.NewInt(1)
testCases := []struct {
name string
blockRes *tmrpctypes.ResultBlockResults
registerMock func()
expBaseFee *big.Int
expPass bool
}{
{
"fail - grpc BaseFee error",
&tmrpctypes.ResultBlockResults{Height: 1},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
nil,
false,
},
{
"fail - grpc BaseFee error - with non feemarket block event",
&tmrpctypes.ResultBlockResults{
Height: 1,
BeginBlockEvents: []types.Event{
{
Type: evmtypes.EventTypeBlockBloom,
},
},
},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
nil,
false,
},
{
"fail - grpc BaseFee error - with feemarket block event",
&tmrpctypes.ResultBlockResults{
Height: 1,
BeginBlockEvents: []types.Event{
{
Type: feemarkettypes.EventTypeFeeMarket,
},
},
},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
nil,
false,
},
{
"fail - grpc BaseFee error - with feemarket block event with wrong attribute value",
&tmrpctypes.ResultBlockResults{
Height: 1,
BeginBlockEvents: []types.Event{
{
Type: feemarkettypes.EventTypeFeeMarket,
Attributes: []types.EventAttribute{
{Value: []byte{0x1}},
},
},
},
},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
nil,
false,
},
{
"fail - grpc baseFee error - with feemarket block event with baseFee attribute value",
&tmrpctypes.ResultBlockResults{
Height: 1,
BeginBlockEvents: []types.Event{
{
Type: feemarkettypes.EventTypeFeeMarket,
Attributes: []types.EventAttribute{
{Value: []byte(baseFee.String())},
},
},
},
},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
baseFee.BigInt(),
true,
},
{
"fail - base fee or london fork not enabled",
&tmrpctypes.ResultBlockResults{Height: 1},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeDisabled(queryClient)
},
nil,
true,
},
{
"pass",
&tmrpctypes.ResultBlockResults{Height: 1},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFee(queryClient, baseFee)
},
baseFee.BigInt(),
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
tc.registerMock()
baseFee, err := suite.backend.BaseFee(tc.blockRes)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(tc.expBaseFee, baseFee)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *BackendTestSuite) TestGetEthereumMsgsFromTendermintBlock() {
msgEthereumTx, bz := suite.buildEthereumTx() msgEthereumTx, bz := suite.buildEthereumTx()
testCases := []struct { testCases := []struct {
@ -975,8 +1175,437 @@ func (suite *BackendTestSuite) TestGetEthereumMsgsFromTendermintBlock() {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() { suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries suite.SetupTest() // reset test and queries
msgs := suite.backend.GetEthereumMsgsFromTendermintBlock(tc.resBlock, tc.blockRes) msgs := suite.backend.EthMsgsFromTendermintBlock(tc.resBlock, tc.blockRes)
suite.Require().Equal(tc.expMsgs, msgs) suite.Require().Equal(tc.expMsgs, msgs)
}) })
} }
} }
func (suite *BackendTestSuite) TestHeaderByNumber() {
var expResultBlock *tmrpctypes.ResultBlock
_, bz := suite.buildEthereumTx()
testCases := []struct {
name string
blockNumber ethrpc.BlockNumber
baseFee *big.Int
registerMock func(ethrpc.BlockNumber, sdk.Int)
expPass bool
}{
{
"fail - tendermint client failed to get block",
ethrpc.BlockNumber(1),
sdk.NewInt(1).BigInt(),
func(blockNum ethrpc.BlockNumber, baseFee sdk.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockError(client, height)
},
false,
},
{
"fail - block not found for height",
ethrpc.BlockNumber(1),
sdk.NewInt(1).BigInt(),
func(blockNum ethrpc.BlockNumber, baseFee sdk.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockNotFound(client, height)
},
false,
},
{
"fail - block not found for height",
ethrpc.BlockNumber(1),
sdk.NewInt(1).BigInt(),
func(blockNum ethrpc.BlockNumber, baseFee sdk.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, nil)
RegisterBlockResultsError(client, height)
},
false,
},
{
"pass - without Base Fee, failed to fetch from prunned block",
ethrpc.BlockNumber(1),
nil,
func(blockNum ethrpc.BlockNumber, baseFee sdk.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlock(client, height, nil)
RegisterBlockResults(client, height)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
true,
},
{
"pass - blockNum = 1, without tx",
ethrpc.BlockNumber(1),
sdk.NewInt(1).BigInt(),
func(blockNum ethrpc.BlockNumber, baseFee sdk.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlock(client, height, nil)
RegisterBlockResults(client, height)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFee(queryClient, baseFee)
},
true,
},
{
"pass - blockNum = 1, with tx",
ethrpc.BlockNumber(1),
sdk.NewInt(1).BigInt(),
func(blockNum ethrpc.BlockNumber, baseFee sdk.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlock(client, height, bz)
RegisterBlockResults(client, height)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFee(queryClient, baseFee)
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
tc.registerMock(tc.blockNumber, sdk.NewIntFromBigInt(tc.baseFee))
header, err := suite.backend.HeaderByNumber(tc.blockNumber)
if tc.expPass {
expHeader := ethrpc.EthHeaderFromTendermint(expResultBlock.Block.Header, ethtypes.Bloom{}, tc.baseFee)
suite.Require().NoError(err)
suite.Require().Equal(expHeader, header)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *BackendTestSuite) TestHeaderByHash() {
var expResultBlock *tmrpctypes.ResultBlock
_, bz := suite.buildEthereumTx()
block := tmtypes.MakeBlock(1, []tmtypes.Tx{bz}, nil, nil)
emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{}, nil, nil)
testCases := []struct {
name string
hash common.Hash
baseFee *big.Int
registerMock func(common.Hash, sdk.Int)
expPass bool
}{
{
"fail - tendermint client failed to get block",
common.BytesToHash(block.Hash()),
sdk.NewInt(1).BigInt(),
func(hash common.Hash, baseFee sdk.Int) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHashError(client, hash, bz)
},
false,
},
{
"fail - block not found for height",
common.BytesToHash(block.Hash()),
sdk.NewInt(1).BigInt(),
func(hash common.Hash, baseFee sdk.Int) {
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHashNotFound(client, hash, bz)
},
false,
},
{
"fail - block not found for height",
common.BytesToHash(block.Hash()),
sdk.NewInt(1).BigInt(),
func(hash common.Hash, baseFee sdk.Int) {
height := int64(1)
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockByHash(client, hash, bz)
RegisterBlockResultsError(client, height)
},
false,
},
{
"pass - without Base Fee, failed to fetch from prunned block",
common.BytesToHash(block.Hash()),
nil,
func(hash common.Hash, baseFee sdk.Int) {
height := int64(1)
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlockByHash(client, hash, bz)
RegisterBlockResults(client, height)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
true,
},
{
"pass - blockNum = 1, without tx",
common.BytesToHash(emptyBlock.Hash()),
sdk.NewInt(1).BigInt(),
func(hash common.Hash, baseFee sdk.Int) {
height := int64(1)
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlockByHash(client, hash, nil)
RegisterBlockResults(client, height)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFee(queryClient, baseFee)
},
true,
},
{
"pass - with tx",
common.BytesToHash(block.Hash()),
sdk.NewInt(1).BigInt(),
func(hash common.Hash, baseFee sdk.Int) {
height := int64(1)
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlockByHash(client, hash, bz)
RegisterBlockResults(client, height)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFee(queryClient, baseFee)
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
tc.registerMock(tc.hash, sdk.NewIntFromBigInt(tc.baseFee))
header, err := suite.backend.HeaderByHash(tc.hash)
if tc.expPass {
expHeader := ethrpc.EthHeaderFromTendermint(expResultBlock.Block.Header, ethtypes.Bloom{}, tc.baseFee)
suite.Require().NoError(err)
suite.Require().Equal(expHeader, header)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *BackendTestSuite) TestEthBlockByNumber() {
msgEthereumTx, bz := suite.buildEthereumTx()
emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{}, nil, nil)
testCases := []struct {
name string
blockNumber ethrpc.BlockNumber
registerMock func(ethrpc.BlockNumber)
expEthBlock *ethtypes.Block
expPass bool
}{
{
"fail - tendermint client failed to get block",
ethrpc.BlockNumber(1),
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlockError(client, height)
},
nil,
false,
},
{
"fail - block result not found for height",
ethrpc.BlockNumber(1),
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, nil)
RegisterBlockResultsError(client, blockNum.Int64())
},
nil,
false,
},
{
"pass - block without tx",
ethrpc.BlockNumber(1),
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, nil)
RegisterBlockResults(client, blockNum.Int64())
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
baseFee := sdk.NewInt(1)
RegisterBaseFee(queryClient, baseFee)
},
ethtypes.NewBlock(
ethrpc.EthHeaderFromTendermint(
emptyBlock.Header,
ethtypes.Bloom{},
sdk.NewInt(1).BigInt(),
),
[]*ethtypes.Transaction{},
nil,
nil,
nil,
),
true,
},
{
"pass - block with tx",
ethrpc.BlockNumber(1),
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, bz)
RegisterBlockResults(client, blockNum.Int64())
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
baseFee := sdk.NewInt(1)
RegisterBaseFee(queryClient, baseFee)
},
ethtypes.NewBlock(
ethrpc.EthHeaderFromTendermint(
emptyBlock.Header,
ethtypes.Bloom{},
sdk.NewInt(1).BigInt(),
),
[]*ethtypes.Transaction{msgEthereumTx.AsTransaction()},
nil,
nil,
trie.NewStackTrie(nil),
),
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
tc.registerMock(tc.blockNumber)
ethBlock, err := suite.backend.EthBlockByNumber(tc.blockNumber)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(tc.expEthBlock.Header(), ethBlock.Header())
suite.Require().Equal(tc.expEthBlock.Uncles(), ethBlock.Uncles())
suite.Require().Equal(tc.expEthBlock.ReceiptHash(), ethBlock.ReceiptHash())
for i, tx := range tc.expEthBlock.Transactions() {
suite.Require().Equal(tx.Data(), ethBlock.Transactions()[i].Data())
}
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *BackendTestSuite) TestEthBlockFromTendermintBlock() {
msgEthereumTx, bz := suite.buildEthereumTx()
emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{}, nil, nil)
testCases := []struct {
name string
baseFee *big.Int
resBlock *tmrpctypes.ResultBlock
blockRes *tmrpctypes.ResultBlockResults
registerMock func(sdk.Int, int64)
expEthBlock *ethtypes.Block
expPass bool
}{
{
"pass - block without tx",
sdk.NewInt(1).BigInt(),
&tmrpctypes.ResultBlock{
Block: emptyBlock,
},
&tmrpctypes.ResultBlockResults{
Height: 1,
TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}},
},
func(baseFee sdk.Int, blockNum int64) {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFee(queryClient, baseFee)
},
ethtypes.NewBlock(
ethrpc.EthHeaderFromTendermint(
emptyBlock.Header,
ethtypes.Bloom{},
sdk.NewInt(1).BigInt(),
),
[]*ethtypes.Transaction{},
nil,
nil,
nil,
),
true,
},
{
"pass - block with tx",
sdk.NewInt(1).BigInt(),
&tmrpctypes.ResultBlock{
Block: tmtypes.MakeBlock(1, []tmtypes.Tx{bz}, nil, nil),
},
&tmrpctypes.ResultBlockResults{
Height: 1,
TxsResults: []*types.ResponseDeliverTx{{Code: 0, GasUsed: 0}},
EndBlockEvents: []types.Event{
{
Type: evmtypes.EventTypeBlockBloom,
Attributes: []types.EventAttribute{
{Key: []byte(bAttributeKeyEthereumBloom)},
},
},
},
},
func(baseFee sdk.Int, blockNum int64) {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFee(queryClient, baseFee)
},
ethtypes.NewBlock(
ethrpc.EthHeaderFromTendermint(
emptyBlock.Header,
ethtypes.Bloom{},
sdk.NewInt(1).BigInt(),
),
[]*ethtypes.Transaction{msgEthereumTx.AsTransaction()},
nil,
nil,
trie.NewStackTrie(nil),
),
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
tc.registerMock(sdk.NewIntFromBigInt(tc.baseFee), tc.blockRes.Height)
ethBlock, err := suite.backend.EthBlockFromTendermintBlock(tc.resBlock, tc.blockRes)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(tc.expEthBlock.Header(), ethBlock.Header())
suite.Require().Equal(tc.expEthBlock.Uncles(), ethBlock.Uncles())
suite.Require().Equal(tc.expEthBlock.ReceiptHash(), ethBlock.ReceiptHash())
for i, tx := range tc.expEthBlock.Transactions() {
suite.Require().Equal(tx.Data(), ethBlock.Transactions()[i].Data())
}
} else {
suite.Require().Error(err)
}
})
}
}

View File

@ -361,3 +361,32 @@ func (b *Backend) DoCall(
return res, nil return res, nil
} }
// GasPrice returns the current gas price based on Ethermint's gas price oracle.
func (b *Backend) GasPrice() (*hexutil.Big, error) {
var (
result *big.Int
err error
)
if head := b.CurrentHeader(); head.BaseFee != nil {
result, err = b.SuggestGasTipCap(head.BaseFee)
if err != nil {
return nil, err
}
result = result.Add(result, head.BaseFee)
} else {
result = big.NewInt(b.RPCMinGasPrice())
}
// return at least GlobalMinGasPrice from FeeMarket module
minGasPrice, err := b.GlobalMinGasPrice()
if err != nil {
return nil, err
}
minGasPriceInt := minGasPrice.TruncateInt().BigInt()
if result.Cmp(minGasPriceInt) < 0 {
result = minGasPriceInt
}
return (*hexutil.Big)(result), nil
}

View File

@ -183,7 +183,7 @@ func (b *Backend) FeeHistory(
for blockID := blockStart; blockID < blockEnd; blockID++ { for blockID := blockStart; blockID < blockEnd; blockID++ {
index := int32(blockID - blockStart) index := int32(blockID - blockStart)
// tendermint block // tendermint block
tendermintblock, err := b.GetTendermintBlockByNumber(rpctypes.BlockNumber(blockID)) tendermintblock, err := b.TendermintBlockByNumber(rpctypes.BlockNumber(blockID))
if tendermintblock == nil { if tendermintblock == nil {
return nil, err return nil, err
} }
@ -195,7 +195,7 @@ func (b *Backend) FeeHistory(
} }
// tendermint block result // tendermint block result
tendermintBlockResult, err := b.GetTendermintBlockResultByNumber(&tendermintblock.Block.Height) tendermintBlockResult, err := b.TendermintBlockResultByNumber(&tendermintblock.Block.Height)
if tendermintBlockResult == nil { if tendermintBlockResult == nil {
b.logger.Debug("block result not found", "height", tendermintblock.Block.Height, "error", err.Error()) b.logger.Debug("block result not found", "height", tendermintblock.Block.Height, "error", err.Error())
return nil, err return nil, err

View File

@ -0,0 +1,146 @@
package backend
import (
"fmt"
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/tendermint/tendermint/abci/types"
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/evmos/ethermint/rpc/backend/mocks"
evmtypes "github.com/evmos/ethermint/x/evm/types"
feemarkettypes "github.com/evmos/ethermint/x/feemarket/types"
)
func (suite *BackendTestSuite) TestBaseFee() {
baseFee := sdk.NewInt(1)
testCases := []struct {
name string
blockRes *tmrpctypes.ResultBlockResults
registerMock func()
expBaseFee *big.Int
expPass bool
}{
{
"fail - grpc BaseFee error",
&tmrpctypes.ResultBlockResults{Height: 1},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
nil,
false,
},
{
"fail - grpc BaseFee error - with non feemarket block event",
&tmrpctypes.ResultBlockResults{
Height: 1,
BeginBlockEvents: []types.Event{
{
Type: evmtypes.EventTypeBlockBloom,
},
},
},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
nil,
false,
},
{
"fail - grpc BaseFee error - with feemarket block event",
&tmrpctypes.ResultBlockResults{
Height: 1,
BeginBlockEvents: []types.Event{
{
Type: feemarkettypes.EventTypeFeeMarket,
},
},
},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
nil,
false,
},
{
"fail - grpc BaseFee error - with feemarket block event with wrong attribute value",
&tmrpctypes.ResultBlockResults{
Height: 1,
BeginBlockEvents: []types.Event{
{
Type: feemarkettypes.EventTypeFeeMarket,
Attributes: []types.EventAttribute{
{Value: []byte{0x1}},
},
},
},
},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
nil,
false,
},
{
"fail - grpc baseFee error - with feemarket block event with baseFee attribute value",
&tmrpctypes.ResultBlockResults{
Height: 1,
BeginBlockEvents: []types.Event{
{
Type: feemarkettypes.EventTypeFeeMarket,
Attributes: []types.EventAttribute{
{Value: []byte(baseFee.String())},
},
},
},
},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeError(queryClient)
},
baseFee.BigInt(),
true,
},
{
"fail - base fee or london fork not enabled",
&tmrpctypes.ResultBlockResults{Height: 1},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFeeDisabled(queryClient)
},
nil,
true,
},
{
"pass",
&tmrpctypes.ResultBlockResults{Height: 1},
func() {
queryClient := suite.backend.queryClient.QueryClient.(*mocks.QueryClient)
RegisterBaseFee(queryClient, baseFee)
},
baseFee.BigInt(),
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset test and queries
tc.registerMock()
baseFee, err := suite.backend.BaseFee(tc.blockRes)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(tc.expBaseFee, baseFee)
} else {
suite.Require().Error(err)
}
})
}
}

View File

@ -145,3 +145,13 @@ func RegisterBlockByHash(
Return(resBlock, nil) Return(resBlock, nil)
return resBlock, nil return resBlock, nil
} }
func RegisterBlockByHashError(client *mocks.Client, hash common.Hash, tx []byte) {
client.On("BlockByHash", rpc.ContextWithHeight(1), []byte{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, sdkerrors.ErrInvalidRequest)
}
func RegisterBlockByHashNotFound(client *mocks.Client, hash common.Hash, tx []byte) {
client.On("BlockByHash", rpc.ContextWithHeight(1), []byte{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)
}

View File

@ -8,7 +8,7 @@ import (
// GetLogs returns all the logs from all the ethereum transactions in a block. // GetLogs returns all the logs from all the ethereum transactions in a block.
func (b *Backend) GetLogs(hash common.Hash) ([][]*ethtypes.Log, error) { func (b *Backend) GetLogs(hash common.Hash) ([][]*ethtypes.Log, error) {
resBlock, err := b.GetTendermintBlockByHash(hash) resBlock, err := b.TendermintBlockByHash(hash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -22,7 +22,7 @@ func (b *Backend) GetLogs(hash common.Hash) ([][]*ethtypes.Log, error) {
// GetLogsByHeight returns all the logs from all the ethereum transactions in a block. // GetLogsByHeight returns all the logs from all the ethereum transactions in a block.
func (b *Backend) GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error) { 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. // NOTE: we query the state in case the tx result logs are not persisted after an upgrade.
blockRes, err := b.GetTendermintBlockResultByNumber(height) blockRes, err := b.TendermintBlockResultByNumber(height)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -26,7 +26,7 @@ func (b *Backend) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfi
return nil, errors.New("genesis is not traceable") return nil, errors.New("genesis is not traceable")
} }
blk, err := b.GetTendermintBlockByNumber(rpctypes.BlockNumber(transaction.Height)) blk, err := b.TendermintBlockByNumber(rpctypes.BlockNumber(transaction.Height))
if err != nil { if err != nil {
b.logger.Debug("block not found", "height", transaction.Height) b.logger.Debug("block not found", "height", transaction.Height)
return nil, err return nil, err

View File

@ -25,7 +25,7 @@ func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransac
return b.getTransactionByHashPending(txHash) return b.getTransactionByHashPending(txHash)
} }
block, err := b.GetTendermintBlockByNumber(rpctypes.BlockNumber(res.Height)) block, err := b.TendermintBlockByNumber(rpctypes.BlockNumber(res.Height))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -41,7 +41,7 @@ func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransac
return nil, errors.New("invalid ethereum tx") return nil, errors.New("invalid ethereum tx")
} }
blockRes, err := b.GetTendermintBlockResultByNumber(&block.Block.Height) blockRes, err := b.TendermintBlockResultByNumber(&block.Block.Height)
if err != nil { if err != nil {
b.logger.Debug("block result not found", "height", block.Block.Height, "error", err.Error()) b.logger.Debug("block result not found", "height", block.Block.Height, "error", err.Error())
return nil, nil return nil, nil
@ -49,7 +49,7 @@ func (b *Backend) GetTransactionByHash(txHash common.Hash) (*rpctypes.RPCTransac
if res.EthTxIndex == -1 { if res.EthTxIndex == -1 {
// Fallback to find tx index by iterating all valid eth transactions // Fallback to find tx index by iterating all valid eth transactions
msgs := b.GetEthereumMsgsFromTendermintBlock(block, blockRes) msgs := b.EthMsgsFromTendermintBlock(block, blockRes)
for i := range msgs { for i := range msgs {
if msgs[i].Hash == hexTx { if msgs[i].Hash == hexTx {
res.EthTxIndex = int32(i) res.EthTxIndex = int32(i)
@ -125,7 +125,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{
return nil, nil return nil, nil
} }
resBlock, err := b.GetTendermintBlockByNumber(rpctypes.BlockNumber(res.Height)) resBlock, err := b.TendermintBlockByNumber(rpctypes.BlockNumber(res.Height))
if err != nil { if err != nil {
b.logger.Debug("block not found", "height", res.Height, "error", err.Error()) b.logger.Debug("block not found", "height", res.Height, "error", err.Error())
return nil, nil return nil, nil
@ -144,7 +144,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{
} }
cumulativeGasUsed := uint64(0) cumulativeGasUsed := uint64(0)
blockRes, err := b.GetTendermintBlockResultByNumber(&res.Height) blockRes, err := b.TendermintBlockResultByNumber(&res.Height)
if err != nil { if err != nil {
b.logger.Debug("failed to retrieve block results", "height", res.Height, "error", err.Error()) b.logger.Debug("failed to retrieve block results", "height", res.Height, "error", err.Error())
return nil, nil return nil, nil
@ -179,7 +179,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{
if res.EthTxIndex == -1 { if res.EthTxIndex == -1 {
// Fallback to find tx index by iterating all valid eth transactions // Fallback to find tx index by iterating all valid eth transactions
msgs := b.GetEthereumMsgsFromTendermintBlock(resBlock, blockRes) msgs := b.EthMsgsFromTendermintBlock(resBlock, blockRes)
for i := range msgs { for i := range msgs {
if msgs[i].Hash == hexTx { if msgs[i].Hash == hexTx {
res.EthTxIndex = int32(i) res.EthTxIndex = int32(i)
@ -260,7 +260,7 @@ func (b *Backend) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexuti
func (b *Backend) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { func (b *Backend) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) {
b.logger.Debug("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx) b.logger.Debug("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx)
block, err := b.GetTendermintBlockByNumber(blockNum) block, err := b.TendermintBlockByNumber(blockNum)
if err != nil { if err != nil {
b.logger.Debug("block not found", "height", blockNum.Int64(), "error", err.Error()) b.logger.Debug("block not found", "height", blockNum.Int64(), "error", err.Error())
return nil, nil return nil, nil
@ -341,7 +341,7 @@ func (b *Backend) queryTendermintTxIndexer(query string, txGetter func(*rpctypes
// getTransactionByBlockAndIndex is the common code shared by `GetTransactionByBlockNumberAndIndex` and `GetTransactionByBlockHashAndIndex`. // getTransactionByBlockAndIndex is the common code shared by `GetTransactionByBlockNumberAndIndex` and `GetTransactionByBlockHashAndIndex`.
func (b *Backend) GetTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { func (b *Backend) GetTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) {
blockRes, err := b.GetTendermintBlockResultByNumber(&block.Block.Height) blockRes, err := b.TendermintBlockResultByNumber(&block.Block.Height)
if err != nil { if err != nil {
return nil, nil return nil, nil
} }
@ -365,7 +365,7 @@ func (b *Backend) GetTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock, i
} }
} else { } else {
i := int(idx) i := int(idx)
ethMsgs := b.GetEthereumMsgsFromTendermintBlock(block, blockRes) ethMsgs := b.EthMsgsFromTendermintBlock(block, blockRes)
if i >= len(ethMsgs) { if i >= len(ethMsgs) {
b.logger.Debug("block txs index out of bound", "index", i) b.logger.Debug("block txs index out of bound", "index", i)
return nil, nil return nil, nil

View File

@ -74,7 +74,7 @@ func (a *API) TraceBlockByNumber(height rpctypes.BlockNumber, config *evmtypes.T
return nil, errors.New("genesis is not traceable") return nil, errors.New("genesis is not traceable")
} }
// Get Tendermint Block // Get Tendermint Block
resBlock, err := a.backend.GetTendermintBlockByNumber(height) resBlock, err := a.backend.TendermintBlockByNumber(height)
if err != nil { if err != nil {
a.logger.Debug("get block failed", "height", height, "error", err.Error()) a.logger.Debug("get block failed", "height", height, "error", err.Error())
return nil, err return nil, err
@ -88,7 +88,7 @@ func (a *API) TraceBlockByNumber(height rpctypes.BlockNumber, config *evmtypes.T
func (a *API) TraceBlockByHash(hash common.Hash, config *evmtypes.TraceConfig) ([]*evmtypes.TxTraceResult, error) { func (a *API) TraceBlockByHash(hash common.Hash, config *evmtypes.TraceConfig) ([]*evmtypes.TxTraceResult, error) {
a.logger.Debug("debug_traceBlockByHash", "hash", hash) a.logger.Debug("debug_traceBlockByHash", "hash", hash)
// Get Tendermint Block // Get Tendermint Block
resBlock, err := a.backend.GetTendermintBlockByHash(hash) resBlock, err := a.backend.TendermintBlockByHash(hash)
if err != nil { if err != nil {
a.logger.Debug("get block failed", "hash", hash.Hex(), "error", err.Error()) a.logger.Debug("get block failed", "hash", hash.Hex(), "error", err.Error())
return nil, err return nil, err
@ -298,7 +298,7 @@ func (a *API) GetHeaderRlp(number uint64) (hexutil.Bytes, error) {
// GetBlockRlp retrieves the RLP encoded for of a single block. // GetBlockRlp retrieves the RLP encoded for of a single block.
func (a *API) GetBlockRlp(number uint64) (hexutil.Bytes, error) { func (a *API) GetBlockRlp(number uint64) (hexutil.Bytes, error) {
block, err := a.backend.BlockByNumber(rpctypes.BlockNumber(number)) block, err := a.backend.EthBlockByNumber(rpctypes.BlockNumber(number))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -308,7 +308,7 @@ func (a *API) GetBlockRlp(number uint64) (hexutil.Bytes, error) {
// PrintBlock retrieves a block and returns its pretty printed form. // PrintBlock retrieves a block and returns its pretty printed form.
func (a *API) PrintBlock(number uint64) (string, error) { func (a *API) PrintBlock(number uint64) (string, error) {
block, err := a.backend.BlockByNumber(rpctypes.BlockNumber(number)) block, err := a.backend.EthBlockByNumber(rpctypes.BlockNumber(number))
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -2,7 +2,6 @@ package eth
import ( import (
"context" "context"
"math/big"
"github.com/ethereum/go-ethereum/signer/core/apitypes" "github.com/ethereum/go-ethereum/signer/core/apitypes"
@ -34,6 +33,8 @@ type EthereumAPI interface {
BlockNumber() (hexutil.Uint64, error) BlockNumber() (hexutil.Uint64, error)
GetBlockByNumber(ethBlockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error) GetBlockByNumber(ethBlockNum rpctypes.BlockNumber, fullTx bool) (map[string]interface{}, error)
GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint
GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint
// Reading Transactions // Reading Transactions
// //
@ -42,8 +43,6 @@ type EthereumAPI interface {
GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransaction, error) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransaction, error)
GetTransactionCount(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Uint64, error) GetTransactionCount(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Uint64, error)
GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error)
GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint
GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint
GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error)
GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error)
// eth_getBlockReceipts // eth_getBlockReceipts
@ -123,10 +122,7 @@ type PublicAPI struct {
} }
// NewPublicAPI creates an instance of the public ETH Web3 API. // NewPublicAPI creates an instance of the public ETH Web3 API.
func NewPublicAPI( func NewPublicAPI(logger log.Logger, backend backend.EVMBackend) *PublicAPI {
logger log.Logger,
backend backend.EVMBackend,
) *PublicAPI {
api := &PublicAPI{ api := &PublicAPI{
ctx: context.Background(), ctx: context.Background(),
logger: logger.With("client", "json-rpc"), logger: logger.With("client", "json-rpc"),
@ -171,7 +167,7 @@ func (e *PublicAPI) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransac
// GetTransactionCount returns the number of transactions at the given address up to the given block number. // GetTransactionCount returns the number of transactions at the given address up to the given block number.
func (e *PublicAPI) GetTransactionCount(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Uint64, error) { func (e *PublicAPI) GetTransactionCount(address common.Address, blockNrOrHash rpctypes.BlockNumberOrHash) (*hexutil.Uint64, error) {
e.logger.Debug("eth_getTransactionCount", "address", address.Hex(), "block number or hash", blockNrOrHash) e.logger.Debug("eth_getTransactionCount", "address", address.Hex(), "block number or hash", blockNrOrHash)
blockNum, err := e.backend.GetBlockNumber(blockNrOrHash) blockNum, err := e.backend.BlockNumberFromTendermint(blockNrOrHash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -182,21 +178,18 @@ func (e *PublicAPI) GetTransactionCount(address common.Address, blockNrOrHash rp
func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) { func (e *PublicAPI) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) {
hexTx := hash.Hex() hexTx := hash.Hex()
e.logger.Debug("eth_getTransactionReceipt", "hash", hexTx) e.logger.Debug("eth_getTransactionReceipt", "hash", hexTx)
return e.backend.GetTransactionReceipt(hash) return e.backend.GetTransactionReceipt(hash)
} }
// GetBlockTransactionCountByHash returns the number of transactions in the block identified by hash. // GetBlockTransactionCountByHash returns the number of transactions in the block identified by hash.
func (e *PublicAPI) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint { func (e *PublicAPI) GetBlockTransactionCountByHash(hash common.Hash) *hexutil.Uint {
e.logger.Debug("eth_getBlockTransactionCountByHash", "hash", hash.Hex()) e.logger.Debug("eth_getBlockTransactionCountByHash", "hash", hash.Hex())
return e.backend.GetBlockTransactionCountByHash(hash) return e.backend.GetBlockTransactionCountByHash(hash)
} }
// GetBlockTransactionCountByNumber returns the number of transactions in the block identified by number. // GetBlockTransactionCountByNumber returns the number of transactions in the block identified by number.
func (e *PublicAPI) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint { func (e *PublicAPI) GetBlockTransactionCountByNumber(blockNum rpctypes.BlockNumber) *hexutil.Uint {
e.logger.Debug("eth_getBlockTransactionCountByNumber", "height", blockNum.Int64()) e.logger.Debug("eth_getBlockTransactionCountByNumber", "height", blockNum.Int64())
return e.backend.GetBlockTransactionCountByNumber(blockNum) return e.backend.GetBlockTransactionCountByNumber(blockNum)
} }
@ -209,19 +202,7 @@ func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexu
// GetTransactionByBlockNumberAndIndex returns the transaction identified by number and index. // GetTransactionByBlockNumberAndIndex returns the transaction identified by number and index.
func (e *PublicAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { func (e *PublicAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) {
e.logger.Debug("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx) e.logger.Debug("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx)
return e.backend.GetTransactionByBlockNumberAndIndex(blockNum, idx)
block, err := e.backend.GetTendermintBlockByNumber(blockNum)
if err != nil {
e.logger.Debug("block not found", "height", blockNum.Int64(), "error", err.Error())
return nil, nil
}
if block.Block == nil {
e.logger.Debug("block not found", "height", blockNum.Int64())
return nil, nil
}
return e.backend.GetTransactionByBlockAndIndex(block, idx)
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -288,7 +269,7 @@ func (e *PublicAPI) Call(args evmtypes.TransactionArgs,
) (hexutil.Bytes, error) { ) (hexutil.Bytes, error) {
e.logger.Debug("eth_call", "args", args.String(), "block number or hash", blockNrOrHash) e.logger.Debug("eth_call", "args", args.String(), "block number or hash", blockNrOrHash)
blockNum, err := e.backend.GetBlockNumber(blockNrOrHash) blockNum, err := e.backend.BlockNumberFromTendermint(blockNrOrHash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -303,10 +284,10 @@ func (e *PublicAPI) Call(args evmtypes.TransactionArgs,
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Event Logs /// /// Event Logs ///
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// FILTER API // FILTER API at ./filters/api.go
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Chain Information /// /// Chain Information ///
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// ProtocolVersion returns the supported Ethereum protocol version. // ProtocolVersion returns the supported Ethereum protocol version.
@ -318,31 +299,7 @@ func (e *PublicAPI) ProtocolVersion() hexutil.Uint {
// GasPrice returns the current gas price based on Ethermint's gas price oracle. // GasPrice returns the current gas price based on Ethermint's gas price oracle.
func (e *PublicAPI) GasPrice() (*hexutil.Big, error) { func (e *PublicAPI) GasPrice() (*hexutil.Big, error) {
e.logger.Debug("eth_gasPrice") e.logger.Debug("eth_gasPrice")
var ( return e.backend.GasPrice()
result *big.Int
err error
)
if head := e.backend.CurrentHeader(); head.BaseFee != nil {
result, err = e.backend.SuggestGasTipCap(head.BaseFee)
if err != nil {
return nil, err
}
result = result.Add(result, head.BaseFee)
} else {
result = big.NewInt(e.backend.RPCMinGasPrice())
}
// return at least GlobalMinGasPrice from FeeMarket module
minGasPrice, err := e.backend.GlobalMinGasPrice()
if err != nil {
return nil, err
}
minGasPriceInt := minGasPrice.TruncateInt().BigInt()
if result.Cmp(minGasPriceInt) < 0 {
result = minGasPriceInt
}
return (*hexutil.Big)(result), nil
} }
// EstimateGas returns an estimate of gas usage for the given smart contract call. // EstimateGas returns an estimate of gas usage for the given smart contract call.
@ -466,7 +423,7 @@ func (e *PublicAPI) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, err
return nil, nil return nil, nil
} }
resBlockResult, err := e.backend.GetTendermintBlockResultByNumber(&res.Height) resBlockResult, err := e.backend.TendermintBlockResultByNumber(&res.Height)
if err != nil { if err != nil {
e.logger.Debug("block result not found", "number", res.Height, "error", err.Error()) e.logger.Debug("block result not found", "number", res.Height, "error", err.Error())
return nil, nil return nil, nil

View File

@ -39,8 +39,8 @@ type Backend interface {
GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error) GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error)
HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error)
HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
GetTendermintBlockByHash(hash common.Hash) (*coretypes.ResultBlock, error) TendermintBlockByHash(hash common.Hash) (*coretypes.ResultBlock, error)
GetTendermintBlockResultByNumber(height *int64) (*coretypes.ResultBlockResults, error) TendermintBlockResultByNumber(height *int64) (*coretypes.ResultBlockResults, error)
GetLogs(blockHash common.Hash) ([][]*ethtypes.Log, error) GetLogs(blockHash common.Hash) ([][]*ethtypes.Log, error)
GetLogsByHeight(*int64) ([][]*ethtypes.Log, error) GetLogsByHeight(*int64) ([][]*ethtypes.Log, error)
BlockBloom(blockRes *coretypes.ResultBlockResults) (ethtypes.Bloom, error) BlockBloom(blockRes *coretypes.ResultBlockResults) (ethtypes.Bloom, error)

View File

@ -98,12 +98,12 @@ func (f *Filter) Logs(ctx context.Context, logLimit int, blockLimit int64) ([]*e
// If we're doing singleton block filtering, execute and return // If we're doing singleton block filtering, execute and return
if f.criteria.BlockHash != nil && *f.criteria.BlockHash != (common.Hash{}) { if f.criteria.BlockHash != nil && *f.criteria.BlockHash != (common.Hash{}) {
resBlock, err := f.backend.GetTendermintBlockByHash(*f.criteria.BlockHash) resBlock, err := f.backend.TendermintBlockByHash(*f.criteria.BlockHash)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch header by hash %s: %w", f.criteria.BlockHash, err) return nil, fmt.Errorf("failed to fetch header by hash %s: %w", f.criteria.BlockHash, err)
} }
blockRes, err := f.backend.GetTendermintBlockResultByNumber(&resBlock.Block.Height) blockRes, err := f.backend.TendermintBlockResultByNumber(&resBlock.Block.Height)
if err != nil { if err != nil {
f.logger.Debug("failed to fetch block result from Tendermint", "height", resBlock.Block.Height, "error", err.Error()) f.logger.Debug("failed to fetch block result from Tendermint", "height", resBlock.Block.Height, "error", err.Error())
return nil, nil return nil, nil
@ -155,7 +155,7 @@ func (f *Filter) Logs(ctx context.Context, logLimit int, blockLimit int64) ([]*e
to := f.criteria.ToBlock.Int64() to := f.criteria.ToBlock.Int64()
for height := from; height <= to; height++ { for height := from; height <= to; height++ {
blockRes, err := f.backend.GetTendermintBlockResultByNumber(&height) blockRes, err := f.backend.TendermintBlockResultByNumber(&height)
if err != nil { if err != nil {
f.logger.Debug("failed to fetch block result from Tendermint", "height", height, "error", err.Error()) f.logger.Debug("failed to fetch block result from Tendermint", "height", height, "error", err.Error())
return nil, nil return nil, nil