Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

rpc: geth v1.10.9 changes #624

Merged
merged 8 commits into from
Oct 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (evm) [tharsis#613](https://github.com/tharsis/ethermint/pull/613) Refactor `traceTx`
* (deps) [tharsis#610](https://github.com/tharsis/ethermint/pull/610) Bump Cosmos SDK to [v0.44.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.1).

### Features

* (rpc) [tharsis#624](https://github.com/tharsis/ethermint/pull/624) Implement new JSON-RPC endpoints from latest geth version

### Bug Fixes

* (evm) [tharsis#616](https://github.com/tharsis/ethermint/issues/616) Fix halt on deeply nested stack of cache context. Stack is now flattened before iterating over the tx logs.
Expand Down
2 changes: 1 addition & 1 deletion client/docs/statik/statik.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ require (
github.com/tyler-smith/go-bip39 v1.1.0
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e
google.golang.org/grpc v1.41.0
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.4.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1759,8 +1759,8 @@ google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKr
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9 h1:eF1wcrhdz56Vugf8qNX5dD93ItkrhothojQyHXqloe0=
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e h1:Im71rbA1N3CbIag/PumYhQcNR8bLNmuOtRIyOnnLsT8=
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
Expand Down
3 changes: 1 addition & 2 deletions proto/ethermint/feemarket/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ message QueryBaseFeeRequest {}
// BaseFeeResponse returns the EIP1559 base fee.
message QueryBaseFeeResponse {
string base_fee = 1 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int"
];
}

Expand Down
144 changes: 95 additions & 49 deletions rpc/ethereum/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,37 @@ import (
// Backend implements the functionality shared within namespaces.
// Implemented by EVMBackend.
type Backend interface {
// General Ethereum API
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
RPCMinGasPrice() int64
SuggestGasTipCap() (*big.Int, error)

// Blockchain API
BlockNumber() (hexutil.Uint64, error)
GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error)
GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error)
GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
CurrentHeader() *ethtypes.Header
GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error)
HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error)
HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
PendingTransactions() ([]*sdk.Tx, error)
GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error)
GetTransactionCount(address common.Address, blockNum types.BlockNumber) (*hexutil.Uint64, error)
SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error)
GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error)
GetLogs(hash common.Hash) ([][]*ethtypes.Log, error)
BloomStatus() (uint64, uint64)
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)
RPCGasCap() uint64
RPCMinGasPrice() int64
ChainConfig() *params.ChainConfig
SuggestGasTipCap() (*big.Int, error)
BaseFee() (*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)
}

var _ Backend = (*EVMBackend)(nil)
Expand Down Expand Up @@ -228,6 +236,14 @@ func (e *EVMBackend) EthBlockFromTendermint(
) (map[string]interface{}, error) {
ethRPCTxs := []interface{}{}

ctx := types.ContextWithHeight(block.Height)

bfRes, err := e.queryClient.FeeMarket.BaseFee(ctx, &feemarkettypes.QueryBaseFeeRequest{})
if err != nil {
e.logger.Debug("failed to base fee", "height", block.Height, "error", err.Error())
return nil, err
}

for i, txBz := range block.Txs {
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil {
Expand All @@ -237,43 +253,30 @@ func (e *EVMBackend) EthBlockFromTendermint(

for _, msg := range tx.GetMsgs() {
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)

if !ok {
continue
}

hash := ethMsg.AsTransaction().Hash()
tx := ethMsg.AsTransaction()

if !fullTx {
hash := tx.Hash()
ethRPCTxs = append(ethRPCTxs, hash)
continue
}

// get full transaction from message data
from, err := ethMsg.GetSender(e.chainID)
if err != nil {
e.logger.Debug("failed to get sender from already included transaction", "hash", hash.Hex(), "error", err.Error())
from = common.HexToAddress(ethMsg.From)
}

txData, err := evmtypes.UnpackTxData(ethMsg.Data)
if err != nil {
e.logger.Debug("decoding failed", "error", err.Error())
return nil, fmt.Errorf("failed to unpack tx data: %w", err)
}

ethTx, err := types.NewTransactionFromData(
txData,
from,
hash,
rpcTx, err := types.NewRPCTransaction(
tx,
common.BytesToHash(block.Hash()),
uint64(block.Height),
uint64(i),
bfRes.BaseFee.BigInt(),
)
if err != nil {
e.logger.Debug("NewTransactionFromData for receipt failed", "hash", hash.Hex(), "error", err.Error())
e.logger.Debug("NewTransactionFromData for receipt failed", "hash", tx.Hash().Hex(), "error", err.Error())
continue
}
ethRPCTxs = append(ethRPCTxs, ethTx)
ethRPCTxs = append(ethRPCTxs, rpcTx)
}
}

Expand All @@ -286,8 +289,6 @@ func (e *EVMBackend) EthBlockFromTendermint(
ConsAddress: sdk.ConsAddress(block.Header.ProposerAddress).String(),
}

ctx := types.ContextWithHeight(block.Height)

res, err := e.queryClient.ValidatorAccount(ctx, req)
if err != nil {
e.logger.Debug(
Expand All @@ -306,12 +307,6 @@ func (e *EVMBackend) EthBlockFromTendermint(

validatorAddr := common.BytesToAddress(addr)

bfRes, err := e.queryClient.FeeMarket.BaseFee(ctx, &feemarkettypes.QueryBaseFeeRequest{})
if err != nil {
e.logger.Debug("failed to base fee", "height", block.Height, "error", err.Error())
return nil, err
}

gasLimit, err := types.BlockMaxGasFromConsensusParams(ctx, e.clientCtx)
if err != nil {
e.logger.Error("failed to query consensus params", "error", err.Error())
Expand Down Expand Up @@ -376,7 +371,13 @@ func (e *EVMBackend) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Heade
e.logger.Debug("HeaderByNumber BlockBloom failed", "height", resBlock.Block.Height)
}

ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header)
baseFee, err := e.BaseFee()
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, baseFee)
ethHeader.Bloom = bloom
return ethHeader, nil
}
Expand All @@ -398,7 +399,13 @@ func (e *EVMBackend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, erro
e.logger.Debug("HeaderByHash BlockBloom failed", "height", resBlock.Block.Height)
}

ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header)
baseFee, err := e.BaseFee()
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, baseFee)
ethHeader.Bloom = bloom
return ethHeader, nil
}
Expand Down Expand Up @@ -607,20 +614,24 @@ func (e *EVMBackend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash
return common.Hash{}, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error())
}

args, err = e.setTxDefaults(args)
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
}

// TODO: get from chain config
signer := ethtypes.LatestSignerForChainID(args.ChainID.ToInt())
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 {
Expand All @@ -641,8 +652,7 @@ func (e *EVMBackend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash
}

builder.SetExtensionOptions(option)
err = builder.SetMsgs(msg)
if err != nil {
if err = builder.SetMsgs(msg); err != nil {
e.logger.Error("builder.SetMsgs failed", "error", err.Error())
}

Expand Down Expand Up @@ -701,7 +711,22 @@ func (e *EVMBackend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional
return 0, err
}

req := evmtypes.EthCallRequest{Args: bz, GasCap: e.RPCGasCap()}
baseFee, err := e.BaseFee()
if err != nil {
return 0, err
}

var bf *sdk.Int
if baseFee != nil {
aux := sdk.NewIntFromBigInt(baseFee)
bf = &aux
}

req := evmtypes.EthCallRequest{
Args: bz,
GasCap: e.RPCGasCap(),
BaseFee: bf,
}

// From ContextWithHeight: if the provided height is 0,
// it will return an empty context and the gRPC query will use
Expand Down Expand Up @@ -745,7 +770,7 @@ func (e *EVMBackend) RPCGasCap() uint64 {
// the node config. If set value is 0, it will default to 20.

func (e *EVMBackend) RPCMinGasPrice() int64 {
evmParams, err := e.queryClient.Params(context.Background(), &evmtypes.QueryParamsRequest{})
evmParams, err := e.queryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{})
if err != nil {
return ethermint.DefaultGasPrice
}
Expand All @@ -771,8 +796,29 @@ func (e *EVMBackend) ChainConfig() *params.ChainConfig {

// SuggestGasTipCap returns the suggested tip cap
func (e *EVMBackend) SuggestGasTipCap() (*big.Int, error) {
// TODO: implement
return big.NewInt(1), nil
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.
func (e *EVMBackend) BaseFee() (*big.Int, error) {
res, err := e.queryClient.FeeMarket.BaseFee(e.ctx, &feemarkettypes.QueryBaseFeeRequest{})
if err != nil {
return nil, err
}

if res.BaseFee != nil {
return res.BaseFee.BigInt(), nil
}

resParams, err := e.queryClient.FeeMarket.Params(e.ctx, &feemarkettypes.QueryParamsRequest{})
if err != nil {
return nil, err
}

baseFee := big.NewInt(resParams.Params.InitialBaseFee)
return baseFee, nil
}

// GetFilteredBlocks returns the block height list match the given bloom filters.
Expand Down
4 changes: 2 additions & 2 deletions rpc/ethereum/backend/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import (
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)

// setTxDefaults populates tx message with default values in case they are not
// SetTxDefaults populates tx message with default values in case they are not
// provided on the args
func (e *EVMBackend) setTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error) {
func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error) {
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
return args, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
}
Expand Down
Loading