forked from cerc-io/laconicd-deprecated
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:
parent
7bef408068
commit
9f03ca713d
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
return nil, errors.Errorf("block not found for hash %s", blockHash.Hex())
|
||||||
|
}
|
||||||
|
return big.NewInt(resBlock.Block.Height), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if block.Block == nil {
|
// EthMsgsFromTendermintBlock returns all real MsgEthereumTxs from a
|
||||||
b.logger.Debug("block not found", "hash", hash.Hex())
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBlockTransactionCountByNumber returns the number of transactions in the block identified by number.
|
|
||||||
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
|
||||||
}
|
}
|
@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
146
rpc/backend/chain_info_test.go
Normal file
146
rpc/backend/chain_info_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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,7 +284,7 @@ func (e *PublicAPI) Call(args evmtypes.TransactionArgs,
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
/// Event Logs ///
|
/// Event Logs ///
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// FILTER API
|
// FILTER API at ./filters/api.go
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
/// Chain Information ///
|
/// Chain Information ///
|
||||||
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user