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

Commit

Permalink
rpc: geth v1.10.9 changes (#624)
Browse files Browse the repository at this point in the history
* rpc: geth v1.10.9 changes

* updates

* suggestGasTipCap

* update gRPC

* resend

* fixes

* rm unused func

* address TODO
  • Loading branch information
fedekunze authored Oct 6, 2021
1 parent 202bc5f commit bcdb982
Show file tree
Hide file tree
Showing 17 changed files with 427 additions and 221 deletions.
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

0 comments on commit bcdb982

Please sign in to comment.