laconicd/rpc/ethereum/backend/backend.go

1067 lines
32 KiB
Go
Raw Normal View History

package backend
2021-04-18 16:39:15 +00:00
import (
"bytes"
2021-04-18 16:39:15 +00:00
"context"
"encoding/json"
"fmt"
2021-04-18 16:39:15 +00:00
"math/big"
"strconv"
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
"time"
2021-04-18 16:39:15 +00:00
"github.com/cosmos/cosmos-sdk/client/flags"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/server"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/ethereum/go-ethereum/accounts/keystore"
2021-09-27 22:06:27 +00:00
"github.com/ethereum/go-ethereum/params"
rpc: `eth_feeHistory` (#734) * Problem: missing json rpc of eth_feeHistory #685 add oracle backend space ready structure ok refactoring return feehistory data flow ok basefee set gas used ratio computing reward add testing add gas used prepare data fill reward increase coin fixing api add mac add launch gas used ratio ok print element reward workes reward working fix panic value correct remove debugging log tidy up tidy up remove oracle tidy up fix handler crash add unit test tidy up add limit check reformat fix lint fix lint fix lint fix lint Update rpc/ethereum/backend/feebackend.go thanks Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go thanks Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> fix compile error split lines remove temporary string conversion return error if gaslimit is 0 move OneFeeHistory to types add comment only err check Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> tidy up add feehistory-cap * Apply suggestions from code review * changelog Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <federico.kunze94@gmail.com>
2021-11-17 11:58:52 +00:00
"github.com/ethereum/go-ethereum/rpc"
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
2021-04-18 16:39:15 +00:00
"github.com/pkg/errors"
"github.com/tendermint/tendermint/libs/log"
2021-04-18 16:39:15 +00:00
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
2021-04-18 16:39:15 +00:00
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/eth/filters"
"github.com/tharsis/ethermint/rpc/ethereum/types"
"github.com/tharsis/ethermint/server/config"
ethermint "github.com/tharsis/ethermint/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
2021-04-18 16:39:15 +00:00
)
// Backend implements the functionality shared within namespaces.
2021-04-18 16:39:15 +00:00
// Implemented by EVMBackend.
type Backend interface {
rpc: `eth_feeHistory` (#734) * Problem: missing json rpc of eth_feeHistory #685 add oracle backend space ready structure ok refactoring return feehistory data flow ok basefee set gas used ratio computing reward add testing add gas used prepare data fill reward increase coin fixing api add mac add launch gas used ratio ok print element reward workes reward working fix panic value correct remove debugging log tidy up tidy up remove oracle tidy up fix handler crash add unit test tidy up add limit check reformat fix lint fix lint fix lint fix lint Update rpc/ethereum/backend/feebackend.go thanks Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go thanks Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> fix compile error split lines remove temporary string conversion return error if gaslimit is 0 move OneFeeHistory to types add comment only err check Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> tidy up add feehistory-cap * Apply suggestions from code review * changelog Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <federico.kunze94@gmail.com>
2021-11-17 11:58:52 +00:00
// Fee API
FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*types.FeeHistoryResult, error)
// General Ethereum API
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection
RPCTxFeeCap() float64 // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for send-transaction variants. The unit is ether.
RPCMinGasPrice() int64
SuggestGasTipCap() (*big.Int, error)
// Blockchain API
2021-04-18 16:39:15 +00:00
BlockNumber() (hexutil.Uint64, error)
GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error)
GetTendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error)
2021-04-18 16:39:15 +00:00
GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error)
GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
BlockByNumber(blockNum types.BlockNumber) (*ethtypes.Block, error)
BlockByHash(blockHash common.Hash) (*ethtypes.Block, error)
2021-09-27 22:06:27 +00:00
CurrentHeader() *ethtypes.Header
HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error)
HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
PendingTransactions() ([]*sdk.Tx, error)
2021-04-18 16:39:15 +00:00
GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error)
GetTransactionCount(address common.Address, blockNum types.BlockNumber) (*hexutil.Uint64, error)
SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error)
rpc: `miner_` namespace (#377) * miner namespace * SetGasPrice call * Added note plus fixed error logging * Refactor to use the keyring in the miner namespace * Changed keyring function return * Added more detailed logs to unsupported functions * Reverted changes on ethapi and just using a refrence to it on miner * Creating a transaction * fix condition * Error string not capitalized * suggested changes to setEtherbase * change log level * minor changes * minor changes * Sending tx to test the endpoint * get tx nonce * Using aphoton const and changing the logger to debug * Using default RPC gas limit constant * Apply suggestions from code review Renames and log changes Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * pair programming session * get gas * Set gas prices note added * Setting fess and max gas * delete unnecessary log * Apply suggestions from code review return false in case of error Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Suggested changes applied * Updated changelog and json_rpc docs * Update CHANGELOG.md Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update ethereum/rpc/namespaces/miner/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update ethereum/rpc/namespaces/miner/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update ethereum/rpc/namespaces/miner/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update ethereum/rpc/namespaces/miner/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Using the same coin denom as the gas price for the fee Co-authored-by: ramacarlucho <ramirocarlucho@gmail.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-08-04 09:18:22 +00:00
GetCoinbase() (sdk.AccAddress, error)
GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error)
GetTxByEthHash(txHash common.Hash) (*tmrpctypes.ResultTx, error)
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
BaseFee(height int64) (*big.Int, error)
// Filter API
BloomStatus() (uint64, uint64)
GetLogs(hash common.Hash) ([][]*ethtypes.Log, error)
GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error)
GetFilteredBlocks(from int64, to int64, filter [][]filters.BloomIV, filterAddresses bool) ([]int64, error)
ChainConfig() *params.ChainConfig
SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error)
GetEthereumMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock) []*evmtypes.MsgEthereumTx
2021-04-18 16:39:15 +00:00
}
var _ Backend = (*EVMBackend)(nil)
var bAttributeKeyEthereumBloom = []byte(evmtypes.AttributeKeyEthereumBloom)
2021-04-19 10:49:55 +00:00
// EVMBackend implements the Backend interface
2021-04-18 16:39:15 +00:00
type EVMBackend struct {
ctx context.Context
clientCtx client.Context
queryClient *types.QueryClient // gRPC query client
logger log.Logger
chainID *big.Int
cfg config.Config
2021-04-18 16:39:15 +00:00
}
2021-04-19 10:49:55 +00:00
// NewEVMBackend creates a new EVMBackend instance
func NewEVMBackend(ctx *server.Context, logger log.Logger, clientCtx client.Context) *EVMBackend {
chainID, err := ethermint.ParseChainID(clientCtx.ChainID)
if err != nil {
panic(err)
}
appConf := config.GetConfig(ctx.Viper)
2021-04-18 16:39:15 +00:00
return &EVMBackend{
ctx: context.Background(),
clientCtx: clientCtx,
queryClient: types.NewQueryClient(clientCtx),
logger: logger.With("module", "evm-backend"),
chainID: chainID,
cfg: appConf,
2021-04-18 16:39:15 +00:00
}
}
// 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.
2021-04-18 16:39:15 +00:00
func (e *EVMBackend) BlockNumber() (hexutil.Uint64, error) {
// do any grpc query, ignore the response and use the returned block height
var header metadata.MD
_, err := e.queryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{}, grpc.Header(&header))
2021-04-18 16:39:15 +00:00
if err != nil {
return hexutil.Uint64(0), err
}
blockHeightHeader := header.Get(grpctypes.GRPCBlockHeightHeader)
if headerLen := len(blockHeightHeader); headerLen != 1 {
return 0, fmt.Errorf("unexpected '%s' gRPC header length; got %d, expected: %d", grpctypes.GRPCBlockHeightHeader, headerLen, 1)
}
height, err := strconv.ParseUint(blockHeightHeader[0], 10, 64)
if err != nil {
return 0, fmt.Errorf("failed to parse block height: %w", err)
}
return hexutil.Uint64(height), nil
2021-04-18 16:39:15 +00:00
}
// GetBlockByNumber returns the block identified by number.
func (e *EVMBackend) GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error) {
resBlock, err := e.GetTendermintBlockByNumber(blockNum)
if err != nil {
return nil, err
}
// return if requested block height is greater than the current one
if resBlock == nil || resBlock.Block == nil {
return nil, nil
}
res, err := e.EthBlockFromTendermint(resBlock.Block, fullTx)
if err != nil {
e.logger.Debug("EthBlockFromTendermint failed", "height", blockNum, "error", err.Error())
return nil, err
}
return res, nil
}
// GetBlockByHash returns the block identified by hash.
func (e *EVMBackend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) {
resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes())
if err != nil {
e.logger.Debug("BlockByHash block not found", "hash", hash.Hex(), "error", err.Error())
return nil, err
}
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
if resBlock == nil || resBlock.Block == nil {
e.logger.Debug("BlockByHash block not found", "hash", hash.Hex())
return nil, nil
}
return e.EthBlockFromTendermint(resBlock.Block, fullTx)
}
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
// BlockByNumber returns the block identified by number.
func (e *EVMBackend) BlockByNumber(blockNum types.BlockNumber) (*ethtypes.Block, error) {
height := blockNum.Int64()
switch blockNum {
case types.EthLatestBlockNumber:
currentBlockNumber, _ := e.BlockNumber()
if currentBlockNumber > 0 {
height = int64(currentBlockNumber)
}
case types.EthPendingBlockNumber:
currentBlockNumber, _ := e.BlockNumber()
if currentBlockNumber > 0 {
height = int64(currentBlockNumber)
}
case types.EthEarliestBlockNumber:
height = 1
default:
if blockNum < 0 {
return nil, errors.Errorf("incorrect block height: %d", height)
}
}
resBlock, err := e.clientCtx.Client.Block(e.ctx, &height)
if err != nil {
e.logger.Debug("HeaderByNumber failed", "height", height)
return nil, err
}
if resBlock == nil || resBlock.Block == nil {
return nil, errors.Errorf("block not found for height %d", height)
}
return e.EthBlockFromTm(resBlock.Block)
}
// BlockByHash returns the block identified by hash.
func (e *EVMBackend) BlockByHash(hash common.Hash) (*ethtypes.Block, error) {
resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes())
if err != nil {
e.logger.Debug("HeaderByHash failed", "hash", hash.Hex())
return nil, err
}
if resBlock == nil || resBlock.Block == nil {
return nil, errors.Errorf("block not found for hash %s", hash)
}
return e.EthBlockFromTm(resBlock.Block)
}
func (e *EVMBackend) EthBlockFromTm(block *tmtypes.Block) (*ethtypes.Block, error) {
height := block.Height
bloom, err := e.BlockBloom(&height)
if err != nil {
e.logger.Debug("HeaderByNumber BlockBloom failed", "height", height)
}
baseFee, err := e.BaseFee(height)
if err != nil {
e.logger.Debug("HeaderByNumber BaseFee failed", "height", height, "error", err.Error())
return nil, err
}
ethHeader := types.EthHeaderFromTendermint(block.Header, bloom, baseFee)
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
var txs []*ethtypes.Transaction
for _, txBz := range block.Txs {
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil {
e.logger.Debug("failed to decode transaction in block", "height", height, "error", err.Error())
continue
}
for _, msg := range tx.GetMsgs() {
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
continue
}
tx := ethMsg.AsTransaction()
txs = append(txs, tx)
}
}
// TODO: add tx receipts
ethBlock := ethtypes.NewBlock(ethHeader, txs, nil, nil, nil)
return ethBlock, nil
}
// GetTendermintBlockByNumber returns a Tendermint format block by block number
func (e *EVMBackend) GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error) {
2021-04-18 16:39:15 +00:00
height := blockNum.Int64()
currentBlockNumber, _ := e.BlockNumber()
switch blockNum {
case types.EthLatestBlockNumber:
if currentBlockNumber > 0 {
height = int64(currentBlockNumber)
2021-04-18 16:39:15 +00:00
}
case types.EthPendingBlockNumber:
if currentBlockNumber > 0 {
height = int64(currentBlockNumber)
}
case types.EthEarliestBlockNumber:
height = 1
default:
if blockNum < 0 {
return nil, errors.Errorf("cannot fetch a negative block height: %d", height)
}
if height > int64(currentBlockNumber) {
2021-04-18 16:39:15 +00:00
return nil, nil
}
}
resBlock, err := e.clientCtx.Client.Block(e.ctx, &height)
if err != nil {
if resBlock, err = e.clientCtx.Client.Block(e.ctx, nil); err != nil {
e.logger.Debug("tendermint client failed to get latest block", "height", height, "error", err.Error())
2021-04-18 16:39:15 +00:00
return nil, nil
}
}
if resBlock.Block == nil {
e.logger.Debug("GetBlockByNumber block not found", "height", height)
return nil, nil
}
return resBlock, nil
2021-04-18 16:39:15 +00:00
}
// GetTendermintBlockByHash returns a Tendermint format block by block number
func (e *EVMBackend) GetTendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error) {
resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, blockHash.Bytes())
if err != nil {
e.logger.Debug("tendermint client failed to get block", "blockHash", blockHash.Hex(), "error", err.Error())
}
if resBlock == nil || resBlock.Block == nil {
e.logger.Debug("GetBlockByNumber block not found", "blockHash", blockHash.Hex())
return nil, nil
}
return resBlock, nil
}
// BlockBloom query block bloom filter from block results
func (e *EVMBackend) BlockBloom(height *int64) (ethtypes.Bloom, error) {
result, err := e.clientCtx.Client.BlockResults(e.ctx, height)
if err != nil {
return ethtypes.Bloom{}, err
}
for _, event := range result.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")
}
// EthBlockFromTendermint returns a JSON-RPC compatible Ethereum block from a given Tendermint block and its block result.
2021-04-19 10:49:55 +00:00
func (e *EVMBackend) EthBlockFromTendermint(
2021-04-18 16:39:15 +00:00
block *tmtypes.Block,
fullTx bool,
) (map[string]interface{}, error) {
ethRPCTxs := []interface{}{}
2021-04-18 16:39:15 +00:00
ctx := types.ContextWithHeight(block.Height)
baseFee, err := e.BaseFee(block.Height)
if err != nil {
return nil, err
}
2021-11-26 18:10:40 +00:00
resBlockResult, err := e.clientCtx.Client.BlockResults(ctx, &block.Height)
if err != nil {
return nil, err
}
txResults := resBlockResult.TxsResults
for i, txBz := range block.Txs {
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil {
e.logger.Debug("failed to decode transaction in block", "height", block.Height, "error", err.Error())
continue
}
for _, msg := range tx.GetMsgs() {
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
continue
}
tx := ethMsg.AsTransaction()
2021-11-26 18:10:40 +00:00
// check tx exists on EVM by cross checking with blockResults
if txResults[i].Code != 0 {
e.logger.Debug("invalid tx result code", "hash", tx.Hash().Hex())
continue
}
if !fullTx {
hash := tx.Hash()
ethRPCTxs = append(ethRPCTxs, hash)
continue
}
rpcTx, err := types.NewRPCTransaction(
tx,
common.BytesToHash(block.Hash()),
uint64(block.Height),
uint64(i),
2021-10-06 15:20:34 +00:00
baseFee,
)
if err != nil {
e.logger.Debug("NewTransactionFromData for receipt failed", "hash", tx.Hash().Hex(), "error", err.Error())
continue
}
ethRPCTxs = append(ethRPCTxs, rpcTx)
}
2021-04-18 16:39:15 +00:00
}
bloom, err := e.BlockBloom(&block.Height)
2021-04-18 16:39:15 +00:00
if err != nil {
e.logger.Debug("failed to query BlockBloom", "height", block.Height, "error", err.Error())
2021-04-18 16:39:15 +00:00
}
req := &evmtypes.QueryValidatorAccountRequest{
ConsAddress: sdk.ConsAddress(block.Header.ProposerAddress).String(),
}
2021-09-27 22:06:27 +00:00
res, err := e.queryClient.ValidatorAccount(ctx, req)
if err != nil {
2021-09-27 22:06:27 +00:00
e.logger.Debug(
"failed to query validator operator address",
"height", block.Height,
"cons-address", req.ConsAddress,
"error", err.Error(),
)
return nil, err
}
addr, err := sdk.AccAddressFromBech32(res.AccountAddress)
if err != nil {
return nil, err
}
validatorAddr := common.BytesToAddress(addr)
gasLimit, err := types.BlockMaxGasFromConsensusParams(ctx, e.clientCtx, block.Height)
if err != nil {
e.logger.Error("failed to query consensus params", "error", err.Error())
}
gasUsed := uint64(0)
2021-11-26 18:10:40 +00:00
for _, txsResult := range txResults {
gasUsed += uint64(txsResult.GetGasUsed())
}
formattedBlock := types.FormatBlock(
block.Header, block.Size(),
gasLimit, new(big.Int).SetUint64(gasUsed),
2021-10-06 15:20:34 +00:00
ethRPCTxs, bloom, validatorAddr, baseFee,
)
2021-04-18 16:39:15 +00:00
return formattedBlock, nil
}
2021-09-27 22:06:27 +00:00
// CurrentHeader returns the latest block header
func (e *EVMBackend) CurrentHeader() *ethtypes.Header {
header, _ := e.HeaderByNumber(types.EthLatestBlockNumber)
return header
}
2021-04-18 16:39:15 +00:00
// HeaderByNumber returns the block header identified by height.
func (e *EVMBackend) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error) {
height := blockNum.Int64()
switch blockNum {
case types.EthLatestBlockNumber:
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
currentBlockNumber, _ := e.BlockNumber()
2021-04-18 16:39:15 +00:00
if currentBlockNumber > 0 {
height = int64(currentBlockNumber)
2021-04-18 16:39:15 +00:00
}
case types.EthPendingBlockNumber:
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
currentBlockNumber, _ := e.BlockNumber()
2021-04-18 16:39:15 +00:00
if currentBlockNumber > 0 {
height = int64(currentBlockNumber)
}
case types.EthEarliestBlockNumber:
height = 1
default:
if blockNum < 0 {
return nil, errors.Errorf("incorrect block height: %d", height)
2021-04-18 16:39:15 +00:00
}
}
resBlock, err := e.clientCtx.Client.Block(e.ctx, &height)
if err != nil {
e.logger.Debug("HeaderByNumber failed")
2021-04-18 16:39:15 +00:00
return nil, err
}
bloom, err := e.BlockBloom(&resBlock.Block.Height)
2021-04-18 16:39:15 +00:00
if err != nil {
e.logger.Debug("HeaderByNumber BlockBloom failed", "height", resBlock.Block.Height)
2021-04-18 16:39:15 +00:00
}
baseFee, err := e.BaseFee(resBlock.Block.Height)
if err != nil {
e.logger.Debug("HeaderByNumber BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
return nil, err
}
ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header, bloom, baseFee)
2021-04-18 16:39:15 +00:00
return ethHeader, nil
}
// HeaderByHash returns the block header identified by hash.
func (e *EVMBackend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) {
resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, blockHash.Bytes())
if err != nil {
e.logger.Debug("HeaderByHash failed", "hash", blockHash.Hex())
2021-04-18 16:39:15 +00:00
return nil, err
}
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
if resBlock == nil || resBlock.Block == nil {
return nil, errors.Errorf("block not found for hash %s", blockHash.Hex())
}
bloom, err := e.BlockBloom(&resBlock.Block.Height)
2021-04-18 16:39:15 +00:00
if err != nil {
e.logger.Debug("HeaderByHash BlockBloom failed", "height", resBlock.Block.Height)
2021-04-18 16:39:15 +00:00
}
baseFee, err := e.BaseFee(resBlock.Block.Height)
if err != nil {
e.logger.Debug("HeaderByHash BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
return nil, err
}
ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header, bloom, baseFee)
2021-04-18 16:39:15 +00:00
return ethHeader, nil
}
// GetTransactionLogs returns the logs given a transaction hash.
// It returns an error if there's an encoding error.
// If no logs are found for the tx hash, the error is nil.
func (e *EVMBackend) GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error) {
tx, err := e.GetTxByEthHash(txHash)
2021-04-18 16:39:15 +00:00
if err != nil {
return nil, err
}
return TxLogsFromEvents(tx.TxResult.Events)
2021-04-18 16:39:15 +00:00
}
// PendingTransactions returns the transactions that are in the transaction pool
// and have a from address that is one of the accounts this node manages.
func (e *EVMBackend) PendingTransactions() ([]*sdk.Tx, error) {
res, err := e.clientCtx.Client.UnconfirmedTxs(e.ctx, nil)
if err != nil {
return nil, err
}
result := make([]*sdk.Tx, 0, len(res.Txs))
for _, txBz := range res.Txs {
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil {
return nil, err
}
result = append(result, &tx)
}
return result, nil
2021-04-18 16:39:15 +00:00
}
// GetLogsByHeight returns all the logs from all the ethereum transactions in a block.
func (e *EVMBackend) GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error) {
2021-04-18 16:39:15 +00:00
// NOTE: we query the state in case the tx result logs are not persisted after an upgrade.
blockRes, err := e.clientCtx.Client.BlockResults(e.ctx, height)
2021-04-18 16:39:15 +00:00
if err != nil {
return nil, err
}
blockLogs := [][]*ethtypes.Log{}
for _, txResult := range blockRes.TxsResults {
logs, err := TxLogsFromEvents(txResult.Events)
if err != nil {
return nil, err
}
blockLogs = append(blockLogs, logs)
2021-04-18 16:39:15 +00:00
}
return blockLogs, nil
}
// GetLogs returns all the logs from all the ethereum transactions in a block.
func (e *EVMBackend) GetLogs(hash common.Hash) ([][]*ethtypes.Log, error) {
block, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes())
if err != nil {
return nil, err
}
return e.GetLogsByHeight(&block.Block.Header.Height)
}
2021-04-18 16:39:15 +00:00
func (e *EVMBackend) GetLogsByNumber(blockNum types.BlockNumber) ([][]*ethtypes.Log, error) {
height := blockNum.Int64()
switch blockNum {
case types.EthLatestBlockNumber:
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
currentBlockNumber, _ := e.BlockNumber()
2021-04-18 16:39:15 +00:00
if currentBlockNumber > 0 {
height = int64(currentBlockNumber)
2021-04-18 16:39:15 +00:00
}
case types.EthPendingBlockNumber:
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
currentBlockNumber, _ := e.BlockNumber()
2021-04-18 16:39:15 +00:00
if currentBlockNumber > 0 {
height = int64(currentBlockNumber)
}
case types.EthEarliestBlockNumber:
height = 1
default:
if blockNum < 0 {
return nil, errors.Errorf("incorrect block height: %d", height)
2021-04-18 16:39:15 +00:00
}
}
return e.GetLogsByHeight(&height)
2021-04-18 16:39:15 +00:00
}
// BloomStatus returns the BloomBitsBlocks and the number of processed sections maintained
// by the chain indexer.
func (e *EVMBackend) BloomStatus() (uint64, uint64) {
return 4096, 0
}
rpc: `miner_` namespace (#377) * miner namespace * SetGasPrice call * Added note plus fixed error logging * Refactor to use the keyring in the miner namespace * Changed keyring function return * Added more detailed logs to unsupported functions * Reverted changes on ethapi and just using a refrence to it on miner * Creating a transaction * fix condition * Error string not capitalized * suggested changes to setEtherbase * change log level * minor changes * minor changes * Sending tx to test the endpoint * get tx nonce * Using aphoton const and changing the logger to debug * Using default RPC gas limit constant * Apply suggestions from code review Renames and log changes Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * pair programming session * get gas * Set gas prices note added * Setting fess and max gas * delete unnecessary log * Apply suggestions from code review return false in case of error Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Suggested changes applied * Updated changelog and json_rpc docs * Update CHANGELOG.md Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update ethereum/rpc/namespaces/miner/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update ethereum/rpc/namespaces/miner/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update ethereum/rpc/namespaces/miner/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update ethereum/rpc/namespaces/miner/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Using the same coin denom as the gas price for the fee Co-authored-by: ramacarlucho <ramirocarlucho@gmail.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-08-04 09:18:22 +00:00
// GetCoinbase is the address that staking rewards will be send to (alias for Etherbase).
func (e *EVMBackend) GetCoinbase() (sdk.AccAddress, error) {
node, err := e.clientCtx.GetNode()
if err != nil {
return nil, err
}
status, err := node.Status(e.ctx)
if err != nil {
return nil, err
}
req := &evmtypes.QueryValidatorAccountRequest{
ConsAddress: sdk.ConsAddress(status.ValidatorInfo.Address).String(),
}
res, err := e.queryClient.ValidatorAccount(e.ctx, req)
if err != nil {
return nil, err
}
address, _ := sdk.AccAddressFromBech32(res.AccountAddress)
return address, nil
}
// GetTransactionByHash returns the Ethereum format transaction identified by Ethereum transaction hash
func (e *EVMBackend) GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error) {
res, err := e.GetTxByEthHash(txHash)
hexTx := txHash.Hex()
if err != nil {
// try to find tx in mempool
txs, err := e.PendingTransactions()
if err != nil {
e.logger.Debug("tx not found", "hash", hexTx, "error", err.Error())
return nil, nil
}
for _, tx := range txs {
msg, err := evmtypes.UnwrapEthereumMsg(tx)
if err != nil {
// not ethereum tx
continue
}
if msg.Hash == hexTx {
rpctx, err := types.NewTransactionFromMsg(
msg,
common.Hash{},
uint64(0),
uint64(0),
e.chainID,
)
if err != nil {
return nil, err
}
return rpctx, nil
}
}
e.logger.Debug("tx not found", "hash", hexTx)
return nil, nil
}
resBlock, err := e.clientCtx.Client.Block(e.ctx, &res.Height)
if err != nil {
e.logger.Debug("block not found", "height", res.Height, "error", err.Error())
return nil, nil
}
var txIndex uint64
msgs := e.GetEthereumMsgsFromTendermintBlock(resBlock)
for i := range msgs {
if msgs[i].Hash == hexTx {
txIndex = uint64(i)
break
}
}
msg := msgs[txIndex]
return types.NewTransactionFromMsg(
msg,
common.BytesToHash(resBlock.Block.Hash()),
uint64(res.Height),
txIndex,
e.chainID,
)
}
// GetTxByEthHash uses `/tx_query` to find transaction by ethereum tx hash
// TODO: Don't need to convert once hashing is fixed on Tendermint
// https://github.com/tendermint/tendermint/issues/6539
func (e *EVMBackend) GetTxByEthHash(hash common.Hash) (*tmrpctypes.ResultTx, error) {
query := fmt.Sprintf("%s.%s='%s'", evmtypes.TypeMsgEthereumTx, evmtypes.AttributeKeyEthereumTxHash, hash.Hex())
resTxs, err := e.clientCtx.Client.TxSearch(e.ctx, query, false, nil, nil, "")
if err != nil {
return nil, err
}
if len(resTxs.Txs) == 0 {
return nil, errors.Errorf("ethereum tx not found for hash %s", hash.Hex())
}
return resTxs.Txs[0], nil
}
func (e *EVMBackend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) {
// Look up the wallet containing the requested signer
_, err := e.clientCtx.Keyring.KeyByAddress(sdk.AccAddress(args.From.Bytes()))
if err != nil {
e.logger.Error("failed to find key in keyring", "address", args.From, "error", err.Error())
return common.Hash{}, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error())
}
args, err = e.SetTxDefaults(args)
if err != nil {
return common.Hash{}, err
}
msg := args.ToTransaction()
if err := msg.ValidateBasic(); err != nil {
e.logger.Debug("tx failed basic validation", "error", err.Error())
return common.Hash{}, err
}
bn, err := e.BlockNumber()
if err != nil {
e.logger.Debug("failed to fetch latest block number", "error", err.Error())
return common.Hash{}, err
}
signer := ethtypes.MakeSigner(e.ChainConfig(), new(big.Int).SetUint64(uint64(bn)))
// Sign transaction
if err := msg.Sign(signer, e.clientCtx.Keyring); err != nil {
e.logger.Debug("failed to sign tx", "error", err.Error())
return common.Hash{}, err
}
// Assemble transaction from fields
builder, ok := e.clientCtx.TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder)
if !ok {
e.logger.Error("clientCtx.TxConfig.NewTxBuilder returns unsupported builder", "error", err.Error())
}
option, err := codectypes.NewAnyWithValue(&evmtypes.ExtensionOptionsEthereumTx{})
if err != nil {
e.logger.Error("codectypes.NewAnyWithValue failed to pack an obvious value", "error", err.Error())
return common.Hash{}, err
}
builder.SetExtensionOptions(option)
if err = builder.SetMsgs(msg); err != nil {
e.logger.Error("builder.SetMsgs failed", "error", err.Error())
}
// Query params to use the EVM denomination
res, err := e.queryClient.QueryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{})
if err != nil {
e.logger.Error("failed to query evm params", "error", err.Error())
return common.Hash{}, err
}
txData, err := evmtypes.UnpackTxData(msg.Data)
if err != nil {
e.logger.Error("failed to unpack tx data", "error", err.Error())
return common.Hash{}, err
}
fees := sdk.Coins{sdk.NewCoin(res.Params.EvmDenom, sdk.NewIntFromBigInt(txData.Fee()))}
builder.SetFeeAmount(fees)
builder.SetGasLimit(msg.GetGas())
// Encode transaction by default Tx encoder
txEncoder := e.clientCtx.TxConfig.TxEncoder()
txBytes, err := txEncoder(builder.GetTx())
if err != nil {
e.logger.Error("failed to encode eth tx using default encoder", "error", err.Error())
return common.Hash{}, err
}
txHash := msg.AsTransaction().Hash()
// Broadcast transaction in sync mode (default)
// NOTE: If error is encountered on the node, the broadcast will not return an error
syncCtx := e.clientCtx.WithBroadcastMode(flags.BroadcastSync)
rsp, err := syncCtx.BroadcastTx(txBytes)
if rsp != nil && rsp.Code != 0 {
err = sdkerrors.ABCIError(rsp.Codespace, rsp.Code, rsp.RawLog)
}
if err != nil {
e.logger.Error("failed to broadcast tx", "error", err.Error())
return txHash, err
}
// Return transaction hash
return txHash, nil
}
// EstimateGas returns an estimate of gas usage for the given smart contract call.
func (e *EVMBackend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error) {
blockNr := types.EthPendingBlockNumber
if blockNrOptional != nil {
blockNr = *blockNrOptional
}
bz, err := json.Marshal(&args)
if err != nil {
return 0, err
}
req := evmtypes.EthCallRequest{
Args: bz,
GasCap: e.RPCGasCap(),
}
// From ContextWithHeight: if the provided height is 0,
// it will return an empty context and the gRPC query will use
// the latest block height for querying.
res, err := e.queryClient.EstimateGas(types.ContextWithHeight(blockNr.Int64()), &req)
if err != nil {
return 0, err
}
return hexutil.Uint64(res.Gas), nil
}
// GetTransactionCount returns the number of transactions at the given address up to the given block number.
func (e *EVMBackend) GetTransactionCount(address common.Address, blockNum types.BlockNumber) (*hexutil.Uint64, error) {
// Get nonce (sequence) from account
from := sdk.AccAddress(address.Bytes())
accRet := e.clientCtx.AccountRetriever
err := accRet.EnsureExists(e.clientCtx, from)
if err != nil {
// account doesn't exist yet, return 0
n := hexutil.Uint64(0)
return &n, nil
}
includePending := blockNum == types.EthPendingBlockNumber
nonce, err := e.getAccountNonce(address, includePending, blockNum.Int64(), e.logger)
if err != nil {
return nil, err
}
n := hexutil.Uint64(nonce)
return &n, nil
}
// RPCGasCap is the global gas cap for eth-call variants.
func (e *EVMBackend) RPCGasCap() uint64 {
return e.cfg.JSONRPC.GasCap
}
build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.11 (#676) * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ethereum/go-ethereum from 1.10.9 to 1.10.10 Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.10.9 to 1.10.10. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.10.9...v1.10.10) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix * rpc: RLP apis * tx fee cap fix * fix config * fix test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Kunze <federico.kunze94@gmail.com>
2021-10-25 15:01:04 +00:00
// RPCEVMTimeout is the global evm timeout for eth-call variants.
func (e *EVMBackend) RPCEVMTimeout() time.Duration {
return e.cfg.JSONRPC.EVMTimeout
}
// RPCGasCap is the global gas cap for eth-call variants.
func (e *EVMBackend) RPCTxFeeCap() float64 {
return e.cfg.JSONRPC.TxFeeCap
}
// RPCFilterCap is the limit for total number of filters that can be created
func (e *EVMBackend) RPCFilterCap() int32 {
return e.cfg.JSONRPC.FilterCap
}
rpc: `eth_feeHistory` (#734) * Problem: missing json rpc of eth_feeHistory #685 add oracle backend space ready structure ok refactoring return feehistory data flow ok basefee set gas used ratio computing reward add testing add gas used prepare data fill reward increase coin fixing api add mac add launch gas used ratio ok print element reward workes reward working fix panic value correct remove debugging log tidy up tidy up remove oracle tidy up fix handler crash add unit test tidy up add limit check reformat fix lint fix lint fix lint fix lint Update rpc/ethereum/backend/feebackend.go thanks Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go thanks Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> fix compile error split lines remove temporary string conversion return error if gaslimit is 0 move OneFeeHistory to types add comment only err check Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Update rpc/ethereum/backend/feebackend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> tidy up add feehistory-cap * Apply suggestions from code review * changelog Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <federico.kunze94@gmail.com>
2021-11-17 11:58:52 +00:00
// RPCFeeHistoryCap is the limit for total number of blocks that can be fetched
func (e *EVMBackend) RPCFeeHistoryCap() int32 {
return e.cfg.JSONRPC.FeeHistoryCap
}
2021-09-28 08:42:18 +00:00
// RPCMinGasPrice returns the minimum gas price for a transaction obtained from
// the node config. If set value is 0, it will default to 20.
func (e *EVMBackend) RPCMinGasPrice() int64 {
evmParams, err := e.queryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{})
2021-09-28 08:42:18 +00:00
if err != nil {
return ethermint.DefaultGasPrice
}
minGasPrice := e.cfg.GetMinGasPrices()
amt := minGasPrice.AmountOf(evmParams.Params.EvmDenom).TruncateInt64()
if amt == 0 {
return ethermint.DefaultGasPrice
}
2021-09-28 08:42:18 +00:00
return amt
}
2021-09-27 22:06:27 +00:00
// ChainConfig return the ethereum chain configuration
func (e *EVMBackend) ChainConfig() *params.ChainConfig {
params, err := e.queryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{})
if err != nil {
return nil
}
return params.Params.ChainConfig.EthereumConfig(e.chainID)
}
// SuggestGasTipCap returns the suggested tip cap
func (e *EVMBackend) SuggestGasTipCap() (*big.Int, error) {
out := new(big.Int).SetInt64(e.RPCMinGasPrice())
return out, nil
}
// BaseFee returns the base fee tracked by the Fee Market module. If the base fee is not enabled,
// it returns the initial base fee amount. Return nil if London is not activated.
func (e *EVMBackend) BaseFee(height int64) (*big.Int, error) {
cfg := e.ChainConfig()
if !cfg.IsLondon(new(big.Int).SetInt64(height)) {
return nil, nil
}
// Checks the feemarket param NoBaseFee settings, return 0 if it is enabled.
resParams, err := e.queryClient.FeeMarket.Params(types.ContextWithHeight(height), &feemarkettypes.QueryParamsRequest{})
if err != nil {
return nil, err
}
if resParams.Params.NoBaseFee {
return big.NewInt(0), nil
}
blockRes, err := e.clientCtx.Client.BlockResults(e.ctx, &height)
if err != nil {
return nil, err
}
baseFee := types.BaseFeeFromEvents(blockRes.EndBlockEvents)
if baseFee != nil {
return baseFee, nil
}
// If we cannot find in events, we tried to get it from the state.
// It will return feemarket.baseFee if london is activated but feemarket is not enable
res, err := e.queryClient.FeeMarket.BaseFee(types.ContextWithHeight(height), &feemarkettypes.QueryBaseFeeRequest{})
if err == nil && res.BaseFee != nil {
return res.BaseFee.BigInt(), nil
}
return nil, nil
2021-09-27 22:06:27 +00:00
}
// GetFilteredBlocks returns the block height list match the given bloom filters.
func (e *EVMBackend) GetFilteredBlocks(
from int64,
to int64,
filters [][]filters.BloomIV,
filterAddresses bool,
) ([]int64, error) {
matchedBlocks := make([]int64, 0)
BLOCKS:
for height := from; height <= to; height++ {
if err := e.ctx.Err(); err != nil {
e.logger.Error("EVMBackend context error", "err", err)
return nil, err
}
h := height
bloom, err := e.BlockBloom(&h)
if err != nil {
e.logger.Error("retrieve header failed", "blockHeight", height, "err", err)
return nil, err
}
for i, filter := range filters {
// filter the header bloom with the addresses
if filterAddresses && i == 0 {
if !checkMatches(bloom, filter) {
continue BLOCKS
}
// the filter doesn't have any topics
if len(filters) == 1 {
matchedBlocks = append(matchedBlocks, height)
continue BLOCKS
}
continue
}
// filter the bloom with topics
if len(filter) > 0 && !checkMatches(bloom, filter) {
continue BLOCKS
}
}
matchedBlocks = append(matchedBlocks, height)
}
return matchedBlocks, nil
}
// GetEthereumMsgsFromTendermintBlock returns all real MsgEthereumTxs from a Tendermint block.
// It also ensures consistency over the correct txs indexes across RPC endpoints
func (e *EVMBackend) GetEthereumMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock) []*evmtypes.MsgEthereumTx {
var result []*evmtypes.MsgEthereumTx
for _, tx := range block.Block.Txs {
tx, err := e.clientCtx.TxConfig.TxDecoder()(tx)
if err != nil {
e.logger.Debug("failed to decode transaction in block", "height", block.Block.Height, "error", err.Error())
continue
}
for _, msg := range tx.GetMsgs() {
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
continue
}
hash := ethMsg.AsTransaction().Hash()
// check tx exists on EVM and has the correct block height
ethTx, err := e.GetTxByEthHash(hash)
if err != nil || ethTx.Height != block.Block.Height {
e.logger.Debug("failed to query eth tx hash", "hash", hash.Hex())
continue
}
result = append(result, ethMsg)
}
}
return result
}
// checkMatches revised the function from
// https://github.com/ethereum/go-ethereum/blob/401354976bb44f0ad4455ca1e0b5c0dc31d9a5f5/core/types/bloom9.go#L88
func checkMatches(bloom ethtypes.Bloom, filter []filters.BloomIV) bool {
for _, bloomIV := range filter {
if bloomIV.V[0] == bloomIV.V[0]&bloom[bloomIV.I[0]] &&
bloomIV.V[1] == bloomIV.V[1]&bloom[bloomIV.I[1]] &&
bloomIV.V[2] == bloomIV.V[2]&bloom[bloomIV.I[2]] {
return true
}
}
return false
}