rpc: geth v1.10.9 changes (#624)

* rpc: geth v1.10.9 changes

* updates

* suggestGasTipCap

* update gRPC

* resend

* fixes

* rm unused func

* address TODO
This commit is contained in:
Federico Kunze Küllmer 2021-10-06 13:22:32 +02:00 committed by GitHub
parent 202bc5f1cd
commit bcdb982886
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 427 additions and 221 deletions

View File

@ -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.

File diff suppressed because one or more lines are too long

2
go.mod
View File

@ -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

4
go.sum
View File

@ -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=

View File

@ -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"
];
}

View File

@ -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)
@ -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 {
@ -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)
}
}
@ -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(
@ -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())
@ -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
}
@ -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
}
@ -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 {
@ -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())
}
@ -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
@ -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
}
@ -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.

View File

@ -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")
}

View File

@ -8,6 +8,7 @@ import (
"strings"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/rpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@ -45,6 +46,7 @@ type PublicAPI struct {
logger log.Logger
backend backend.Backend
nonceLock *rpctypes.AddrLocker
signer ethtypes.Signer
}
// NewPublicAPI creates an instance of the public ETH Web3 API.
@ -76,6 +78,10 @@ func NewPublicAPI(
clientCtx = clientCtx.WithKeyring(kr)
}
// The signer used by the API should always be the 'latest' known one because we expect
// signers to be backwards-compatible with old transactions.
signer := ethtypes.LatestSigner(backend.ChainConfig())
api := &PublicAPI{
ctx: context.Background(),
clientCtx: clientCtx,
@ -84,6 +90,7 @@ func NewPublicAPI(
logger: logger.With("client", "json-rpc"),
backend: backend,
nonceLock: nonceLock,
signer: signer,
}
return api
@ -108,14 +115,30 @@ func (e *PublicAPI) ProtocolVersion() hexutil.Uint {
return hexutil.Uint(ethermint.ProtocolVersion)
}
// ChainId returns the chain's identifier in hex format
func (e *PublicAPI) ChainId() (hexutil.Uint, error) { // nolint
// ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config.
func (e *PublicAPI) ChainId() (*hexutil.Big, error) { // nolint
e.logger.Debug("eth_chainId")
return hexutil.Uint(uint(e.chainIDEpoch.Uint64())), nil
// if current block is at or past the EIP-155 replay-protection fork block, return chainID from config
bn, err := e.backend.BlockNumber()
if err != nil {
e.logger.Debug("failed to fetch latest block number", "error", err.Error())
return (*hexutil.Big)(e.chainIDEpoch), nil
}
if config := e.backend.ChainConfig(); config.IsEIP155(new(big.Int).SetUint64(uint64(bn))) {
return (*hexutil.Big)(config.ChainID), nil
}
return nil, fmt.Errorf("chain not synced beyond EIP-155 replay-protection fork block")
}
// Syncing returns whether or not the current node is syncing with other peers. Returns false if not, or a struct
// outlining the state of the sync if it is.
// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not
// yet received the latest block headers from its pears. In case it is synchronizing:
// - startingBlock: block number this node started to synchronize from
// - currentBlock: block number this node is currently importing
// - highestBlock: block number of the highest block header this node has received from peers
// - pulledStates: number of state entries processed until now
// - knownStates: number of known state entries that still need to be pulled
func (e *PublicAPI) Syncing() (interface{}, error) {
e.logger.Debug("eth_syncing")
@ -129,8 +152,8 @@ func (e *PublicAPI) Syncing() (interface{}, error) {
}
return map[string]interface{}{
// "startingBlock": nil, // NA
"currentBlock": hexutil.Uint64(status.SyncInfo.LatestBlockHeight),
"startingBlock": hexutil.Uint64(status.SyncInfo.EarliestBlockHeight),
"currentBlock": hexutil.Uint64(status.SyncInfo.LatestBlockHeight),
// "highestBlock": nil, // NA
// "pulledStates": nil, // NA
// "knownStates": nil, // NA
@ -162,10 +185,35 @@ func (e *PublicAPI) Hashrate() hexutil.Uint64 {
}
// GasPrice returns the current gas price based on Ethermint's gas price oracle.
func (e *PublicAPI) GasPrice() *hexutil.Big {
func (e *PublicAPI) GasPrice() (*hexutil.Big, error) {
e.logger.Debug("eth_gasPrice")
out := new(big.Int).SetInt64(e.backend.RPCMinGasPrice())
return (*hexutil.Big)(out)
tipcap, err := e.backend.SuggestGasTipCap()
if err != nil {
return nil, err
}
if head := e.backend.CurrentHeader(); head.BaseFee != nil {
tipcap.Add(tipcap, head.BaseFee)
}
return (*hexutil.Big)(tipcap), nil
}
// MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions.
func (e *PublicAPI) MaxPriorityFeePerGas() (*hexutil.Big, error) {
e.logger.Debug("eth_maxPriorityFeePerGas")
tipcap, err := e.backend.SuggestGasTipCap()
if err != nil {
return nil, err
}
return (*hexutil.Big)(tipcap), nil
}
func (e *PublicAPI) FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*rpctypes.FeeHistoryResult, error) {
e.logger.Debug("eth_feeHistory")
return nil, fmt.Errorf("eth_feeHistory not implemented")
}
// Accounts returns the list of accounts available to this node.
@ -355,6 +403,29 @@ func (e *PublicAPI) SendTransaction(args evmtypes.TransactionArgs) (common.Hash,
return e.backend.SendTransaction(args)
}
// FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields)
// on a given unsigned transaction, and returns it to the caller for further
// processing (signing + broadcast).
func (e *PublicAPI) FillTransaction(args evmtypes.TransactionArgs) (*rpctypes.SignTransactionResult, error) {
// Set some sanity defaults and terminate on failure
args, err := e.backend.SetTxDefaults(args)
if err != nil {
return nil, err
}
// Assemble the transaction and obtain rlp
tx := args.ToTransaction().AsTransaction()
data, err := tx.MarshalBinary()
if err != nil {
return nil, err
}
return &rpctypes.SignTransactionResult{
Raw: data,
Tx: tx,
}, nil
}
// SendRawTransaction send a raw Ethereum transaction.
func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
e.logger.Debug("eth_sendRawTransaction", "length", len(data))
@ -407,7 +478,12 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
return common.Hash{}, err
}
fees := sdk.Coins{sdk.NewCoin(res.Params.EvmDenom, sdk.NewIntFromBigInt(txData.Fee()))}
fees := sdk.Coins{
{
Denom: res.Params.EvmDenom,
Amount: sdk.NewIntFromBigInt(txData.Fee()),
},
}
builder.SetFeeAmount(fees)
builder.SetGasLimit(ethereumTx.GetGas())
@ -433,6 +509,57 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
return txHash, nil
}
// Resend accepts an existing transaction and a new gas price and limit. It will remove
// the given transaction from the pool and reinsert it with the new gas price and limit.
func (e *PublicAPI) Resend(ctx context.Context, args evmtypes.TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) {
e.logger.Debug("eth_resend", "args", args.String())
if args.Nonce == nil {
return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec")
}
args, err := e.backend.SetTxDefaults(args)
if err != nil {
return common.Hash{}, err
}
matchTx := args.ToTransaction().AsTransaction()
pending, err := e.backend.PendingTransactions()
if err != nil {
return common.Hash{}, err
}
for _, tx := range pending {
p, err := evmtypes.UnwrapEthereumMsg(tx)
if err != nil {
// not valid ethereum tx
continue
}
pTx := p.AsTransaction()
wantSigHash := e.signer.Hash(matchTx)
pFrom, err := ethtypes.Sender(e.signer, pTx)
if err != nil {
continue
}
if pFrom == *args.From && e.signer.Hash(pTx) == wantSigHash {
// Match. Re-sign and send the transaction.
if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 {
args.GasPrice = gasPrice
}
if gasLimit != nil && *gasLimit != 0 {
args.Gas = gasLimit
}
return e.backend.SendTransaction(args) // TODO: this calls SetTxDefaults again, refactor to avoid calling it twice
}
}
return common.Hash{}, fmt.Errorf("transaction %#x not found", matchTx.Hash())
}
// Call performs a raw contract call.
func (e *PublicAPI) Call(args evmtypes.TransactionArgs, blockNrOrHash rpctypes.BlockNumberOrHash, _ *rpctypes.StateOverride) (hexutil.Bytes, error) {
e.logger.Debug("eth_call", "args", args.String(), "block number or hash", blockNrOrHash)
@ -458,7 +585,23 @@ func (e *PublicAPI) doCall(
if err != nil {
return nil, err
}
req := evmtypes.EthCallRequest{Args: bz, GasCap: e.backend.RPCGasCap()}
baseFee, err := e.backend.BaseFee()
if err != nil {
return nil, err
}
var bf *sdk.Int
if baseFee != nil {
aux := sdk.NewIntFromBigInt(baseFee)
bf = &aux
}
req := evmtypes.EthCallRequest{
Args: bz,
GasCap: e.backend.RPCGasCap(),
BaseFee: bf,
}
// From ContextWithHeight: if the provided height is 0,
// it will return an empty context and the gRPC query will use
@ -536,12 +679,17 @@ func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexu
return nil, err
}
baseFee, err := e.backend.BaseFee()
if err != nil {
return nil, err
}
return rpctypes.NewTransactionFromMsg(
msg,
hash,
uint64(resBlock.Block.Height),
uint64(idx),
e.chainIDEpoch,
baseFee,
)
}

View File

@ -3,6 +3,7 @@ package filters
import (
"context"
"fmt"
"math/big"
"sync"
"time"
@ -17,6 +18,7 @@ import (
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
@ -223,6 +225,9 @@ func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
return rpc.ID(fmt.Sprintf("error creating block filter: %s", err.Error()))
}
// TODO: use events to get the base fee amount
baseFee := big.NewInt(params.InitialBaseFee)
api.filtersMu.Lock()
api.filters[headerSub.ID()] = &filter{typ: filters.BlocksSubscription, deadline: time.NewTimer(deadline), hashes: []common.Hash{}, s: headerSub}
api.filtersMu.Unlock()
@ -246,7 +251,7 @@ func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
continue
}
header := types.EthHeaderFromTendermint(data.Header)
header := types.EthHeaderFromTendermint(data.Header, baseFee)
api.filtersMu.Lock()
if f, found := api.filters[headerSub.ID()]; found {
f.hashes = append(f.hashes, header.Hash())
@ -279,6 +284,9 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
return &rpc.Subscription{}, err
}
// TODO: use events to get the base fee amount
baseFee := big.NewInt(params.InitialBaseFee)
go func(headersCh <-chan coretypes.ResultEvent) {
defer cancelSubs()
@ -296,7 +304,7 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
continue
}
header := types.EthHeaderFromTendermint(data.Header)
header := types.EthHeaderFromTendermint(data.Header, baseFee)
err = notifier.Notify(rpcSub.ID, header)
if err != nil {
headersSub.err <- err

View File

@ -150,7 +150,7 @@ func (api *PrivateAccountAPI) UnlockAccount(_ context.Context, addr common.Addre
// SendTransaction will create a transaction from the given arguments and
// tries to sign it with the key associated with args.To. If the given password isn't
// able to decrypt the key it fails.
func (api *PrivateAccountAPI) SendTransaction(_ context.Context, args evmtypes.TransactionArgs, pwrd string) (common.Hash, error) {
func (api *PrivateAccountAPI) SendTransaction(_ context.Context, args evmtypes.TransactionArgs, _ string) (common.Hash, error) {
api.logger.Debug("personal_sendTransaction", "address", args.To.String())
if args.From == nil {
@ -177,7 +177,7 @@ func (api *PrivateAccountAPI) SendTransaction(_ context.Context, args evmtypes.T
// The key used to calculate the signature is decrypted with the given password.
//
// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign
func (api *PrivateAccountAPI) Sign(_ context.Context, data hexutil.Bytes, addr common.Address, pwrd string) (hexutil.Bytes, error) {
func (api *PrivateAccountAPI) Sign(_ context.Context, data hexutil.Bytes, addr common.Address, _ string) (hexutil.Bytes, error) {
api.logger.Debug("personal_sign", "data", data, "address", addr.String())
cosmosAddr := sdk.AccAddress(addr.Bytes())

View File

@ -66,3 +66,16 @@ type OverrideAccount struct {
State *map[common.Hash]common.Hash `json:"state"`
StateDiff *map[common.Hash]common.Hash `json:"stateDiff"`
}
type FeeHistoryResult struct {
OldestBlock *hexutil.Big `json:"oldestBlock"`
Reward [][]*hexutil.Big `json:"reward,omitempty"`
BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"`
GasUsedRatio []float64 `json:"gasUsedRatio"`
}
// SignTransactionResult represents a RLP encoded signed transaction.
type SignTransactionResult struct {
Raw hexutil.Bytes `json:"raw"`
Tx *ethtypes.Transaction `json:"tx"`
}

View File

@ -16,6 +16,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
@ -33,56 +34,14 @@ func RawTxToEthTx(clientCtx client.Context, txBz tmtypes.Tx) (*evmtypes.MsgEther
return ethTx, nil
}
// NewTransaction returns a transaction that will serialize to the RPC
// representation, with the given location metadata set (if available).
func NewTransaction(tx *ethtypes.Transaction, blockHash common.Hash, blockNumber, index uint64) *RPCTransaction {
// Determine the signer. For replay-protected transactions, use the most permissive
// signer, because we assume that signers are backwards-compatible with old
// transactions. For non-protected transactions, the homestead signer signer is used
// because the return value of ChainId is zero for those transactions.
var signer ethtypes.Signer
if tx.Protected() {
signer = ethtypes.LatestSignerForChainID(tx.ChainId())
} else {
signer = ethtypes.HomesteadSigner{}
}
from, _ := ethtypes.Sender(signer, tx)
v, r, s := tx.RawSignatureValues()
result := &RPCTransaction{
Type: hexutil.Uint64(tx.Type()),
From: from,
Gas: hexutil.Uint64(tx.Gas()),
GasPrice: (*hexutil.Big)(tx.GasPrice()),
Hash: tx.Hash(), // NOTE: transaction hash here uses the ethereum format for compatibility
Input: hexutil.Bytes(tx.Data()),
Nonce: hexutil.Uint64(tx.Nonce()),
To: tx.To(),
Value: (*hexutil.Big)(tx.Value()),
V: (*hexutil.Big)(v),
R: (*hexutil.Big)(r),
S: (*hexutil.Big)(s),
}
if blockHash != (common.Hash{}) {
result.BlockHash = &blockHash
result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
result.TransactionIndex = (*hexutil.Uint64)(&index)
}
if tx.Type() == ethtypes.AccessListTxType {
al := tx.AccessList()
result.Accesses = &al
result.ChainID = (*hexutil.Big)(tx.ChainId())
}
return result
}
// EthHeaderFromTendermint is an util function that returns an Ethereum Header
// from a tendermint Header.
func EthHeaderFromTendermint(header tmtypes.Header) *ethtypes.Header {
func EthHeaderFromTendermint(header tmtypes.Header, baseFee *big.Int) *ethtypes.Header {
txHash := ethtypes.EmptyRootHash
if len(header.DataHash) == 0 {
txHash = common.BytesToHash(header.DataHash)
}
return &ethtypes.Header{
ParentHash: common.BytesToHash(header.LastBlockID.Hash.Bytes()),
UncleHash: ethtypes.EmptyUncleHash,
@ -99,6 +58,7 @@ func EthHeaderFromTendermint(header tmtypes.Header) *ethtypes.Header {
Extra: nil,
MixDigest: common.Hash{},
Nonce: ethtypes.BlockNonce{},
BaseFee: baseFee,
}
}
@ -220,65 +180,67 @@ func NewTransactionFromMsg(
msg *evmtypes.MsgEthereumTx,
blockHash common.Hash,
blockNumber, index uint64,
chainID *big.Int,
baseFee *big.Int,
) (*RPCTransaction, error) {
from, err := msg.GetSender(chainID)
if err != nil {
return nil, err
}
data, err := evmtypes.UnpackTxData(msg.Data)
if err != nil {
return nil, fmt.Errorf("failed to unpack tx data: %w", err)
}
return NewTransactionFromData(data, from, msg.AsTransaction().Hash(), blockHash, blockNumber, index)
tx := msg.AsTransaction()
return NewRPCTransaction(tx, blockHash, blockNumber, index, baseFee)
}
// NewTransactionFromData returns a transaction that will serialize to the RPC
// representation, with the given location metadata set (if available).
func NewTransactionFromData(
txData evmtypes.TxData,
from common.Address,
txHash, blockHash common.Hash,
blockNumber, index uint64,
func NewRPCTransaction(
tx *ethtypes.Transaction, blockHash common.Hash, blockNumber, index uint64, baseFee *big.Int,
) (*RPCTransaction, error) {
if txHash == (common.Hash{}) {
txHash = ethtypes.EmptyRootHash
// Determine the signer. For replay-protected transactions, use the most permissive
// signer, because we assume that signers are backwards-compatible with old
// transactions. For non-protected transactions, the homestead signer signer is used
// because the return value of ChainId is zero for those transactions.
var signer ethtypes.Signer
if tx.Protected() {
signer = ethtypes.LatestSignerForChainID(tx.ChainId())
} else {
signer = ethtypes.HomesteadSigner{}
}
v, r, s := txData.GetRawSignatureValues()
rpcTx := &RPCTransaction{
Type: hexutil.Uint64(txData.TxType()),
from, _ := ethtypes.Sender(signer, tx)
v, r, s := tx.RawSignatureValues()
result := &RPCTransaction{
Type: hexutil.Uint64(tx.Type()),
From: from,
Gas: hexutil.Uint64(txData.GetGas()),
GasPrice: (*hexutil.Big)(txData.GetGasPrice()),
Hash: txHash,
Input: hexutil.Bytes(txData.GetData()),
Nonce: hexutil.Uint64(txData.GetNonce()),
To: txData.GetTo(),
Value: (*hexutil.Big)(txData.GetValue()),
Gas: hexutil.Uint64(tx.Gas()),
GasPrice: (*hexutil.Big)(tx.GasPrice()),
Hash: tx.Hash(),
Input: hexutil.Bytes(tx.Data()),
Nonce: hexutil.Uint64(tx.Nonce()),
To: tx.To(),
Value: (*hexutil.Big)(tx.Value()),
V: (*hexutil.Big)(v),
R: (*hexutil.Big)(r),
S: (*hexutil.Big)(s),
}
if rpcTx.To == nil {
addr := common.Address{}
rpcTx.To = &addr
}
if blockHash != (common.Hash{}) {
rpcTx.BlockHash = &blockHash
rpcTx.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
rpcTx.TransactionIndex = (*hexutil.Uint64)(&index)
result.BlockHash = &blockHash
result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
result.TransactionIndex = (*hexutil.Uint64)(&index)
}
if txData.TxType() == ethtypes.AccessListTxType {
accesses := txData.GetAccessList()
rpcTx.Accesses = &accesses
rpcTx.ChainID = (*hexutil.Big)(txData.GetChainID())
switch tx.Type() {
case ethtypes.AccessListTxType:
al := tx.AccessList()
result.Accesses = &al
result.ChainID = (*hexutil.Big)(tx.ChainId())
case ethtypes.DynamicFeeTxType:
al := tx.AccessList()
result.Accesses = &al
result.ChainID = (*hexutil.Big)(tx.ChainId())
result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap())
result.GasTipCap = (*hexutil.Big)(tx.GasTipCap())
// if the transaction has been mined, compute the effective gas price
if baseFee != nil && blockHash != (common.Hash{}) {
// price = min(tip, gasFeeCap - baseFee) + baseFee
price := math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap())
result.GasPrice = (*hexutil.Big)(price)
} else {
result.GasPrice = (*hexutil.Big)(tx.GasFeeCap())
}
}
return rpcTx, nil
return result, nil
}

View File

@ -17,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
"github.com/tendermint/tendermint/libs/log"
@ -352,6 +353,9 @@ func (api *pubSubAPI) subscribeNewHeads(wsConn *wsConn) (rpc.ID, error) {
return "", errors.Wrap(err, "error creating block filter")
}
// TODO: use events
baseFee := big.NewInt(params.InitialBaseFee)
unsubscribed := make(chan struct{})
api.filtersMu.Lock()
api.filters[subID] = &wsSubscription{
@ -377,7 +381,7 @@ func (api *pubSubAPI) subscribeNewHeads(wsConn *wsConn) (rpc.ID, error) {
continue
}
header := types.EthHeaderFromTendermint(data.Header)
header := types.EthHeaderFromTendermint(data.Header, baseFee)
api.filtersMu.RLock()
for subID, wsSub := range api.filters {

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/hex"
"encoding/json"
"math/big"
"net/http"
"strings"
@ -15,6 +16,7 @@ import (
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
"github.com/ethereum/go-ethereum/common"
)
@ -79,6 +81,17 @@ func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte,
return nil, err
}
client := feemarkettypes.NewQueryClient(clientCtx)
res, err := client.BaseFee(context.Background(), &feemarkettypes.QueryBaseFeeRequest{})
if err != nil {
return nil, err
}
var baseFee *big.Int
if res.BaseFee != nil {
baseFee = res.BaseFee.BigInt()
}
blockHash := common.BytesToHash(block.Block.Header.Hash())
ethTx, err := rpctypes.RawTxToEthTx(clientCtx, tx.Tx)
@ -87,7 +100,11 @@ func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte,
}
height := uint64(tx.Height)
rpcTx := rpctypes.NewTransaction(ethTx.AsTransaction(), blockHash, height, uint64(tx.Index))
rpcTx, err := rpctypes.NewRPCTransaction(ethTx.AsTransaction(), blockHash, height, uint64(tx.Index), baseFee)
if err != nil {
return nil, err
}
return json.Marshal(rpcTx)
}

View File

@ -113,7 +113,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx {
GasFeeCap: &maxFeePerGas,
GasTipCap: &maxPriorityFeePerGas,
Amount: &value,
Data: args.data(),
Data: args.GetData(),
Accesses: al,
}
case args.AccessList != nil:
@ -124,7 +124,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx {
GasLimit: gas,
GasPrice: &gasPrice,
Amount: &value,
Data: args.data(),
Data: args.GetData(),
Accesses: NewAccessList(args.AccessList),
}
default:
@ -134,7 +134,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx {
GasLimit: gas,
GasPrice: &gasPrice,
Amount: &value,
Data: args.data(),
Data: args.GetData(),
}
}
@ -162,7 +162,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (e
}
// Set sender address or use zero address if none specified.
addr := args.from()
addr := args.GetFrom()
// Set default gas & gas price if none were set
gas := globalGasCap
@ -214,7 +214,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (e
if args.Value != nil {
value = args.Value.ToInt()
}
data := args.data()
data := args.GetData()
var accessList ethtypes.AccessList
if args.AccessList != nil {
accessList = *args.AccessList
@ -223,16 +223,16 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (e
return msg, nil
}
// from retrieves the transaction sender address.
func (args *TransactionArgs) from() common.Address {
// GetFrom retrieves the transaction sender address.
func (args *TransactionArgs) GetFrom() common.Address {
if args.From == nil {
return common.Address{}
}
return *args.From
}
// data retrieves the transaction calldata. Input field is preferred.
func (args *TransactionArgs) data() []byte {
// GetData retrieves the transaction calldata. Input field is preferred.
func (args *TransactionArgs) GetData() []byte {
if args.Input != nil {
return *args.Input
}

View File

@ -2,7 +2,6 @@ package keeper
import (
"context"
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -25,15 +24,15 @@ func (k Keeper) Params(c context.Context, _ *types.QueryParamsRequest) (*types.Q
func (k Keeper) BaseFee(c context.Context, _ *types.QueryBaseFeeRequest) (*types.QueryBaseFeeResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
res := &types.QueryBaseFeeResponse{}
baseFee := k.GetBaseFee(ctx)
if baseFee == nil {
// TODO: should this be 0? 1? error?
baseFee = big.NewInt(0)
if baseFee != nil {
aux := sdk.NewIntFromBigInt(baseFee)
res.BaseFee = &aux
}
return &types.QueryBaseFeeResponse{
BaseFee: sdk.NewIntFromBigInt(baseFee),
}, nil
return res, nil
}
// BlockGas implements the Query/BlockGas gRPC method

View File

@ -153,7 +153,7 @@ var xxx_messageInfo_QueryBaseFeeRequest proto.InternalMessageInfo
// BaseFeeResponse returns the EIP1559 base fee.
type QueryBaseFeeResponse struct {
BaseFee github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=base_fee,json=baseFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"base_fee"`
BaseFee *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=base_fee,json=baseFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"base_fee,omitempty"`
}
func (m *QueryBaseFeeResponse) Reset() { *m = QueryBaseFeeResponse{} }
@ -287,34 +287,34 @@ func init() {
var fileDescriptor_71a07c1ffd85fde2 = []byte{
// 450 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xbf, 0x8f, 0xd3, 0x30,
0x14, 0x8e, 0x29, 0xf4, 0x0e, 0xb3, 0x20, 0xd3, 0x3b, 0x9d, 0xc2, 0x91, 0x3b, 0x05, 0xe9, 0xc4,
0xaf, 0xb3, 0x75, 0xc7, 0xca, 0x94, 0x01, 0xb8, 0x0d, 0xc2, 0xc6, 0x52, 0x39, 0xe5, 0x35, 0x8d,
0xda, 0xc4, 0x69, 0xec, 0x56, 0x74, 0x85, 0x85, 0x81, 0x01, 0x89, 0x3f, 0x82, 0x7f, 0xa5, 0x63,
0x25, 0x16, 0xc4, 0x50, 0xa1, 0x96, 0x3f, 0x04, 0xc5, 0x71, 0xda, 0x86, 0xb6, 0xd0, 0x29, 0xd6,
0xcb, 0xe7, 0xef, 0xfb, 0xde, 0xf7, 0xfc, 0xb0, 0x0b, 0xaa, 0x03, 0x59, 0x1c, 0x25, 0x8a, 0xb5,
0x01, 0x62, 0x9e, 0x75, 0x41, 0xb1, 0xe1, 0x05, 0xeb, 0x0f, 0x20, 0x1b, 0xd1, 0x34, 0x13, 0x4a,
0x90, 0xc3, 0x05, 0x86, 0x2e, 0x30, 0x74, 0x78, 0x61, 0x37, 0x42, 0x11, 0x0a, 0x0d, 0x61, 0xf9,
0xa9, 0x40, 0xdb, 0xc7, 0xa1, 0x10, 0x61, 0x0f, 0x18, 0x4f, 0x23, 0xc6, 0x93, 0x44, 0x28, 0xae,
0x22, 0x91, 0x48, 0xf3, 0xf7, 0x6c, 0x8b, 0xde, 0x92, 0x58, 0xe3, 0xdc, 0x06, 0x26, 0xaf, 0x73,
0x0b, 0xaf, 0x78, 0xc6, 0x63, 0xe9, 0x43, 0x7f, 0x00, 0x52, 0xb9, 0x6f, 0xf0, 0x9d, 0x4a, 0x55,
0xa6, 0x22, 0x91, 0x40, 0x9e, 0xe1, 0x7a, 0xaa, 0x2b, 0x47, 0xe8, 0x14, 0x3d, 0xb8, 0x75, 0xe9,
0xd0, 0xcd, 0x8e, 0x69, 0x71, 0xcf, 0xbb, 0x3e, 0x9e, 0x9e, 0x58, 0xbe, 0xb9, 0xe3, 0x1e, 0x18,
0x52, 0x8f, 0x4b, 0x78, 0x0e, 0x50, 0x6a, 0x71, 0xdc, 0xa8, 0x96, 0x8d, 0xd8, 0x15, 0xde, 0x0f,
0xb8, 0x84, 0x66, 0x1b, 0x40, 0xcb, 0xdd, 0xf4, 0x68, 0x4e, 0xf7, 0x73, 0x7a, 0x72, 0x16, 0x46,
0xaa, 0x33, 0x08, 0x68, 0x4b, 0xc4, 0xac, 0x25, 0x64, 0x2c, 0xa4, 0xf9, 0x9c, 0xcb, 0x77, 0x5d,
0xa6, 0x46, 0x29, 0x48, 0x7a, 0x95, 0x28, 0x7f, 0x2f, 0x28, 0x28, 0xdd, 0xc3, 0x52, 0xa2, 0x27,
0x5a, 0xdd, 0x17, 0x7c, 0xd1, 0xe6, 0x43, 0x7c, 0xf0, 0x57, 0xdd, 0x68, 0xdf, 0xc6, 0xb5, 0x90,
0x17, 0x5d, 0xd6, 0xfc, 0xfc, 0x78, 0xf9, 0xad, 0x86, 0x6f, 0x68, 0x2c, 0xf9, 0x88, 0x70, 0xbd,
0xe8, 0x8f, 0x3c, 0xda, 0xd6, 0xff, 0x7a, 0xa4, 0xf6, 0xe3, 0x9d, 0xb0, 0x85, 0xbe, 0x7b, 0xfa,
0xe1, 0xfb, 0xef, 0xaf, 0xd7, 0x6c, 0x72, 0xb4, 0x32, 0x3c, 0x18, 0xc6, 0xf9, 0x00, 0x8b, 0x30,
0xc9, 0x27, 0x84, 0xf7, 0x4c, 0x62, 0xe4, 0xdf, 0xd4, 0xd5, 0xb8, 0xed, 0x27, 0xbb, 0x81, 0x8d,
0x11, 0x57, 0x1b, 0x39, 0x26, 0xf6, 0xba, 0x91, 0x72, 0x38, 0xe4, 0x33, 0xc2, 0xfb, 0x65, 0x82,
0xe4, 0x3f, 0xf4, 0xd5, 0x01, 0xd8, 0xe7, 0x3b, 0xa2, 0x8d, 0x9b, 0xfb, 0xda, 0xcd, 0x3d, 0x72,
0x77, 0x83, 0x9b, 0x1c, 0xdb, 0x0c, 0xb9, 0xf4, 0x5e, 0x8e, 0x67, 0x0e, 0x9a, 0xcc, 0x1c, 0xf4,
0x6b, 0xe6, 0xa0, 0x2f, 0x73, 0xc7, 0x9a, 0xcc, 0x1d, 0xeb, 0xc7, 0xdc, 0xb1, 0xde, 0xd2, 0x95,
0x77, 0xa3, 0x3a, 0x3c, 0x93, 0x91, 0x64, 0xcb, 0x35, 0x79, 0xbf, 0x42, 0xaa, 0xdf, 0x50, 0x50,
0xd7, 0x2b, 0xf2, 0xf4, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xeb, 0xc7, 0xba, 0xe5, 0xbc, 0x03,
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xcf, 0x6f, 0xd3, 0x30,
0x14, 0x8e, 0x29, 0x74, 0xc3, 0x5c, 0x90, 0xe9, 0xa6, 0x29, 0x8c, 0x6c, 0x0a, 0xd2, 0x04, 0x83,
0xd9, 0xda, 0xb8, 0x72, 0x8a, 0xc4, 0xaf, 0x1b, 0x84, 0x1b, 0x12, 0x9a, 0x9c, 0xf2, 0x9a, 0x46,
0x6d, 0xe2, 0x34, 0x76, 0x2b, 0x7a, 0x85, 0x0b, 0x07, 0x0e, 0x48, 0xfc, 0x11, 0xfc, 0x2b, 0x3d,
0x56, 0xe2, 0x82, 0x38, 0x54, 0xa8, 0xe5, 0x0f, 0x41, 0x71, 0x9c, 0xb6, 0xa1, 0x2d, 0xf4, 0x14,
0xeb, 0xe5, 0xf3, 0xf7, 0x7d, 0xef, 0x7b, 0x7e, 0xd8, 0x05, 0xd5, 0x86, 0x2c, 0x8e, 0x12, 0xc5,
0x5a, 0x00, 0x31, 0xcf, 0x3a, 0xa0, 0xd8, 0xe0, 0x9c, 0xf5, 0xfa, 0x90, 0x0d, 0x69, 0x9a, 0x09,
0x25, 0xc8, 0xfe, 0x1c, 0x43, 0xe7, 0x18, 0x3a, 0x38, 0xb7, 0x1b, 0xa1, 0x08, 0x85, 0x86, 0xb0,
0xfc, 0x54, 0xa0, 0xed, 0xc3, 0x50, 0x88, 0xb0, 0x0b, 0x8c, 0xa7, 0x11, 0xe3, 0x49, 0x22, 0x14,
0x57, 0x91, 0x48, 0xa4, 0xf9, 0x7b, 0xb2, 0x41, 0x6f, 0x41, 0xac, 0x71, 0x6e, 0x03, 0x93, 0x57,
0xb9, 0x85, 0x97, 0x3c, 0xe3, 0xb1, 0xf4, 0xa1, 0xd7, 0x07, 0xa9, 0xdc, 0xd7, 0xf8, 0x56, 0xa5,
0x2a, 0x53, 0x91, 0x48, 0x20, 0x8f, 0x71, 0x3d, 0xd5, 0x95, 0x03, 0x74, 0x8c, 0xee, 0xdd, 0xb8,
0x70, 0xe8, 0x7a, 0xc7, 0xb4, 0xb8, 0xe7, 0x5d, 0x1d, 0x4d, 0x8e, 0x2c, 0xdf, 0xdc, 0x71, 0xf7,
0x0c, 0xa9, 0xc7, 0x25, 0x3c, 0x05, 0x28, 0xb5, 0xde, 0xe2, 0x46, 0xb5, 0x6c, 0xc4, 0x9e, 0xe0,
0xdd, 0x80, 0x4b, 0xb8, 0x6c, 0x01, 0x68, 0xb9, 0xeb, 0xde, 0xe9, 0xcf, 0xc9, 0xd1, 0x49, 0x18,
0xa9, 0x76, 0x3f, 0xa0, 0x4d, 0x11, 0xb3, 0xa6, 0x90, 0xb1, 0x90, 0xe6, 0x73, 0x26, 0xdf, 0x75,
0x98, 0x1a, 0xa6, 0x20, 0xe9, 0x8b, 0x44, 0xf9, 0x3b, 0x41, 0x41, 0xe7, 0xee, 0x97, 0xf4, 0x5d,
0xd1, 0xec, 0x3c, 0xe3, 0xf3, 0x16, 0xef, 0xe3, 0xbd, 0xbf, 0xea, 0x46, 0xf7, 0x26, 0xae, 0x85,
0xbc, 0xe8, 0xb0, 0xe6, 0xe7, 0xc7, 0x8b, 0x6f, 0x35, 0x7c, 0x4d, 0x63, 0xc9, 0x47, 0x84, 0xeb,
0x45, 0x6f, 0xe4, 0x74, 0x53, 0xef, 0xab, 0x71, 0xda, 0x0f, 0xb6, 0xc2, 0x16, 0xfa, 0xee, 0xf1,
0x87, 0xef, 0xbf, 0xbf, 0x5e, 0xb1, 0xc9, 0xc1, 0xd2, 0xe0, 0x60, 0x10, 0xe7, 0xc3, 0x2b, 0x82,
0x24, 0x9f, 0x10, 0xde, 0x31, 0x69, 0x91, 0x7f, 0x53, 0x57, 0xa3, 0xb6, 0x1f, 0x6e, 0x07, 0x36,
0x46, 0x5c, 0x6d, 0xe4, 0x90, 0xd8, 0xab, 0x46, 0xca, 0xc1, 0x90, 0xcf, 0x08, 0xef, 0x96, 0x09,
0x92, 0xff, 0xd0, 0x57, 0x07, 0x60, 0x9f, 0x6d, 0x89, 0x36, 0x6e, 0xee, 0x6a, 0x37, 0x77, 0xc8,
0xed, 0x35, 0x6e, 0x72, 0xec, 0x65, 0xc8, 0xa5, 0xf7, 0x7c, 0x34, 0x75, 0xd0, 0x78, 0xea, 0xa0,
0x5f, 0x53, 0x07, 0x7d, 0x99, 0x39, 0xd6, 0x78, 0xe6, 0x58, 0x3f, 0x66, 0x8e, 0xf5, 0x86, 0x2e,
0xbd, 0x1b, 0xd5, 0xe6, 0x99, 0x8c, 0x24, 0x5b, 0xac, 0xc8, 0xfb, 0x25, 0x52, 0xfd, 0x86, 0x82,
0xba, 0x5e, 0x8f, 0x47, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x85, 0x23, 0x79, 0x71, 0xb8, 0x03,
0x00, 0x00,
}
@ -575,16 +575,18 @@ func (m *QueryBaseFeeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
{
size := m.BaseFee.Size()
i -= size
if _, err := m.BaseFee.MarshalTo(dAtA[i:]); err != nil {
return 0, err
if m.BaseFee != nil {
{
size := m.BaseFee.Size()
i -= size
if _, err := m.BaseFee.MarshalTo(dAtA[i:]); err != nil {
return 0, err
}
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i = encodeVarintQuery(dAtA, i, uint64(size))
i--
dAtA[i] = 0xa
}
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
@ -685,8 +687,10 @@ func (m *QueryBaseFeeResponse) Size() (n int) {
}
var l int
_ = l
l = m.BaseFee.Size()
n += 1 + l + sovQuery(uint64(l))
if m.BaseFee != nil {
l = m.BaseFee.Size()
n += 1 + l + sovQuery(uint64(l))
}
return n
}
@ -959,6 +963,8 @@ func (m *QueryBaseFeeResponse) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
var v github_com_cosmos_cosmos_sdk_types.Int
m.BaseFee = &v
if err := m.BaseFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}