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>
This commit is contained in:
parent
b7e8dd8216
commit
392d1dd8cf
@ -51,6 +51,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
* (evm) [tharsis#662](https://github.com/tharsis/ethermint/pull/662) Disable basefee for non london blocks
|
* (evm) [tharsis#662](https://github.com/tharsis/ethermint/pull/662) Disable basefee for non london blocks
|
||||||
* (cmd) [tharsis#712](https://github.com/tharsis/ethermint/pull/712) add tx cli to build evm transaction
|
* (cmd) [tharsis#712](https://github.com/tharsis/ethermint/pull/712) add tx cli to build evm transaction
|
||||||
* (rpc) [tharsis#733](https://github.com/tharsis/ethermint/pull/733) add JSON_RPC endpoint `personal_unpair`
|
* (rpc) [tharsis#733](https://github.com/tharsis/ethermint/pull/733) add JSON_RPC endpoint `personal_unpair`
|
||||||
|
* (rpc) [tharsis#734](https://github.com/tharsis/ethermint/pull/734) add JSON_RPC endpoint `eth_feeHistory`
|
||||||
* (rpc) [tharsis#740](https://github.com/tharsis/ethermint/pull/740) add JSON_RPC endpoint `personal_initializeWallet`
|
* (rpc) [tharsis#740](https://github.com/tharsis/ethermint/pull/740) add JSON_RPC endpoint `personal_initializeWallet`
|
||||||
* (rpc) [tharsis#743](https://github.com/tharsis/ethermint/pull/743) add JSON_RPC endpoint `debug_traceBlockByHash`
|
* (rpc) [tharsis#743](https://github.com/tharsis/ethermint/pull/743) add JSON_RPC endpoint `debug_traceBlockByHash`
|
||||||
* (rpc) [tharsis#748](https://github.com/tharsis/ethermint/pull/748) add JSON_RPC endpoint `personal_listWallets`
|
* (rpc) [tharsis#748](https://github.com/tharsis/ethermint/pull/748) add JSON_RPC endpoint `personal_listWallets`
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
|
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
@ -42,6 +43,9 @@ import (
|
|||||||
// Backend implements the functionality shared within namespaces.
|
// Backend implements the functionality shared within namespaces.
|
||||||
// Implemented by EVMBackend.
|
// Implemented by EVMBackend.
|
||||||
type Backend interface {
|
type Backend interface {
|
||||||
|
// Fee API
|
||||||
|
FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*types.FeeHistoryResult, error)
|
||||||
|
|
||||||
// General Ethereum API
|
// General Ethereum API
|
||||||
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
|
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
|
||||||
RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection
|
RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection
|
||||||
@ -76,7 +80,6 @@ type Backend interface {
|
|||||||
GetLogs(hash common.Hash) ([][]*ethtypes.Log, error)
|
GetLogs(hash common.Hash) ([][]*ethtypes.Log, error)
|
||||||
GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error)
|
GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error)
|
||||||
GetFilteredBlocks(from int64, to int64, filter [][]filters.BloomIV, filterAddresses bool) ([]int64, error)
|
GetFilteredBlocks(from int64, to int64, filter [][]filters.BloomIV, filterAddresses bool) ([]int64, error)
|
||||||
|
|
||||||
ChainConfig() *params.ChainConfig
|
ChainConfig() *params.ChainConfig
|
||||||
SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error)
|
SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error)
|
||||||
GetEthereumMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock) []*evmtypes.MsgEthereumTx
|
GetEthereumMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock) []*evmtypes.MsgEthereumTx
|
||||||
@ -889,6 +892,11 @@ func (e *EVMBackend) RPCFilterCap() int32 {
|
|||||||
return e.cfg.JSONRPC.FilterCap
|
return e.cfg.JSONRPC.FilterCap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RPCFeeHistoryCap is the limit for total number of blocks that can be fetched
|
||||||
|
func (e *EVMBackend) RPCFeeHistoryCap() int32 {
|
||||||
|
return e.cfg.JSONRPC.FeeHistoryCap
|
||||||
|
}
|
||||||
|
|
||||||
// RPCMinGasPrice returns the minimum gas price for a transaction obtained from
|
// RPCMinGasPrice returns the minimum gas price for a transaction obtained from
|
||||||
// the node config. If set value is 0, it will default to 20.
|
// the node config. If set value is 0, it will default to 20.
|
||||||
|
|
||||||
|
198
rpc/ethereum/backend/feebackend.go
Normal file
198
rpc/ethereum/backend/feebackend.go
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
package backend
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||||
|
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
||||||
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
txGasAndReward struct {
|
||||||
|
gasUsed uint64
|
||||||
|
reward *big.Int
|
||||||
|
}
|
||||||
|
sortGasAndReward []txGasAndReward
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s sortGasAndReward) Len() int { return len(s) }
|
||||||
|
func (s sortGasAndReward) Swap(i, j int) {
|
||||||
|
s[i], s[j] = s[j], s[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s sortGasAndReward) Less(i, j int) bool {
|
||||||
|
return s[i].reward.Cmp(s[j].reward) < 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// output: targetOneFeeHistory
|
||||||
|
func (e *EVMBackend) processBlock(
|
||||||
|
tendermintBlock *tmrpctypes.ResultBlock,
|
||||||
|
ethBlock *map[string]interface{},
|
||||||
|
rewardPercentiles []float64,
|
||||||
|
tendermintBlockResult *tmrpctypes.ResultBlockResults,
|
||||||
|
targetOneFeeHistory *rpctypes.OneFeeHistory) error {
|
||||||
|
blockHeight := tendermintBlock.Block.Height
|
||||||
|
blockBaseFee, err := e.BaseFee(blockHeight)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// set basefee
|
||||||
|
targetOneFeeHistory.BaseFee = blockBaseFee
|
||||||
|
|
||||||
|
// set gasused ratio
|
||||||
|
gasLimitUint64 := (*ethBlock)["gasLimit"].(hexutil.Uint64)
|
||||||
|
gasUsedBig := (*ethBlock)["gasUsed"].(*hexutil.Big)
|
||||||
|
gasusedfloat, _ := new(big.Float).SetInt(gasUsedBig.ToInt()).Float64()
|
||||||
|
|
||||||
|
if gasLimitUint64 <= 0 {
|
||||||
|
return fmt.Errorf("gasLimit of block height %d should be bigger than 0 , current gaslimit %d", blockHeight, gasLimitUint64)
|
||||||
|
}
|
||||||
|
|
||||||
|
gasUsedRatio := gasusedfloat / float64(gasLimitUint64)
|
||||||
|
blockGasUsed := gasusedfloat
|
||||||
|
targetOneFeeHistory.GasUsedRatio = gasUsedRatio
|
||||||
|
|
||||||
|
rewardCount := len(rewardPercentiles)
|
||||||
|
targetOneFeeHistory.Reward = make([]*big.Int, rewardCount)
|
||||||
|
for i := 0; i < rewardCount; i++ {
|
||||||
|
targetOneFeeHistory.Reward[i] = big.NewInt(2000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check tendermintTxs
|
||||||
|
tendermintTxs := tendermintBlock.Block.Txs
|
||||||
|
tendermintTxResults := tendermintBlockResult.TxsResults
|
||||||
|
tendermintTxCount := len(tendermintTxs)
|
||||||
|
sorter := make(sortGasAndReward, tendermintTxCount)
|
||||||
|
|
||||||
|
for i := 0; i < tendermintTxCount; i++ {
|
||||||
|
eachTendermintTx := tendermintTxs[i]
|
||||||
|
eachTendermintTxResult := tendermintTxResults[i]
|
||||||
|
|
||||||
|
tx, err := e.clientCtx.TxConfig.TxDecoder()(eachTendermintTx)
|
||||||
|
if err != nil {
|
||||||
|
e.logger.Debug("failed to decode transaction in block", "height", blockHeight, "error", err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
txGasUsed := uint64(eachTendermintTxResult.GasUsed)
|
||||||
|
for _, msg := range tx.GetMsgs() {
|
||||||
|
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tx := ethMsg.AsTransaction()
|
||||||
|
reward := tx.EffectiveGasTipValue(blockBaseFee)
|
||||||
|
sorter[i] = txGasAndReward{gasUsed: txGasUsed, reward: reward}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Sort(sorter)
|
||||||
|
|
||||||
|
var txIndex int
|
||||||
|
sumGasUsed := uint64(0)
|
||||||
|
if len(sorter) > 0 {
|
||||||
|
sumGasUsed = sorter[0].gasUsed
|
||||||
|
}
|
||||||
|
for i, p := range rewardPercentiles {
|
||||||
|
thresholdGasUsed := uint64(blockGasUsed * p / 100)
|
||||||
|
for sumGasUsed < thresholdGasUsed && txIndex < tendermintTxCount-1 {
|
||||||
|
txIndex++
|
||||||
|
sumGasUsed += sorter[txIndex].gasUsed
|
||||||
|
}
|
||||||
|
|
||||||
|
chosenReward := big.NewInt(0)
|
||||||
|
if 0 <= txIndex && txIndex < len(sorter) {
|
||||||
|
chosenReward = sorter[txIndex].reward
|
||||||
|
}
|
||||||
|
targetOneFeeHistory.Reward[i] = chosenReward
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EVMBackend) FeeHistory(
|
||||||
|
userBlockCount rpc.DecimalOrHex, // number blocks to fetch, maximum is 100
|
||||||
|
lastBlock rpc.BlockNumber, // the block to start search , to oldest
|
||||||
|
rewardPercentiles []float64, // percentiles to fetch reward
|
||||||
|
) (*rpctypes.FeeHistoryResult, error) {
|
||||||
|
blockEnd := int64(lastBlock)
|
||||||
|
|
||||||
|
if blockEnd <= 0 {
|
||||||
|
blockNumber, err := e.BlockNumber()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
blockEnd = int64(blockNumber)
|
||||||
|
}
|
||||||
|
userBlockCountInt := int64(userBlockCount)
|
||||||
|
maxBlockCount := int64(e.cfg.JSONRPC.FeeHistoryCap)
|
||||||
|
if userBlockCountInt > maxBlockCount {
|
||||||
|
return nil, fmt.Errorf("FeeHistory user block count %d higher than %d", userBlockCountInt, maxBlockCount)
|
||||||
|
}
|
||||||
|
blockStart := blockEnd - userBlockCountInt
|
||||||
|
if blockStart < 0 {
|
||||||
|
blockStart = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
blockCount := blockEnd - blockStart
|
||||||
|
|
||||||
|
oldestBlock := (*hexutil.Big)(big.NewInt(blockStart))
|
||||||
|
|
||||||
|
// prepare space
|
||||||
|
reward := make([][]*hexutil.Big, blockCount)
|
||||||
|
rewardcount := len(rewardPercentiles)
|
||||||
|
for i := 0; i < int(blockCount); i++ {
|
||||||
|
reward[i] = make([]*hexutil.Big, rewardcount)
|
||||||
|
}
|
||||||
|
thisBaseFee := make([]*hexutil.Big, blockCount)
|
||||||
|
thisGasUsedRatio := make([]float64, blockCount)
|
||||||
|
|
||||||
|
// fetch block
|
||||||
|
for blockID := blockStart; blockID < blockEnd; blockID++ {
|
||||||
|
index := int32(blockID - blockStart)
|
||||||
|
// eth block
|
||||||
|
ethBlock, err := e.GetBlockByNumber(rpctypes.BlockNumber(blockID), true)
|
||||||
|
if ethBlock == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// tendermint block
|
||||||
|
tendermintblock, err := e.GetTendermintBlockByNumber(rpctypes.BlockNumber(blockID))
|
||||||
|
if tendermintblock == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// tendermint block result
|
||||||
|
tendermintBlockResult, err := e.clientCtx.Client.BlockResults(e.ctx, &tendermintblock.Block.Height)
|
||||||
|
if tendermintBlockResult == nil {
|
||||||
|
e.logger.Debug("block result not found", "height", tendermintblock.Block.Height, "error", err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
onefeehistory := rpctypes.OneFeeHistory{}
|
||||||
|
err = e.processBlock(tendermintblock, ðBlock, rewardPercentiles, tendermintBlockResult, &onefeehistory)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy
|
||||||
|
thisBaseFee[index] = (*hexutil.Big)(onefeehistory.BaseFee)
|
||||||
|
thisGasUsedRatio[index] = onefeehistory.GasUsedRatio
|
||||||
|
for j := 0; j < rewardcount; j++ {
|
||||||
|
reward[index][j] = (*hexutil.Big)(onefeehistory.Reward[j])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
feeHistory := rpctypes.FeeHistoryResult{
|
||||||
|
OldestBlock: oldestBlock,
|
||||||
|
Reward: reward,
|
||||||
|
BaseFee: thisBaseFee,
|
||||||
|
GasUsedRatio: thisGasUsedRatio,
|
||||||
|
}
|
||||||
|
return &feeHistory, nil
|
||||||
|
}
|
@ -212,8 +212,7 @@ func (e *PublicAPI) MaxPriorityFeePerGas() (*hexutil.Big, error) {
|
|||||||
|
|
||||||
func (e *PublicAPI) FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*rpctypes.FeeHistoryResult, error) {
|
func (e *PublicAPI) FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*rpctypes.FeeHistoryResult, error) {
|
||||||
e.logger.Debug("eth_feeHistory")
|
e.logger.Debug("eth_feeHistory")
|
||||||
|
return e.backend.FeeHistory(blockCount, lastBlock, rewardPercentiles)
|
||||||
return nil, fmt.Errorf("eth_feeHistory not implemented")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accounts returns the list of accounts available to this node.
|
// Accounts returns the list of accounts available to this node.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
@ -79,3 +81,9 @@ type SignTransactionResult struct {
|
|||||||
Raw hexutil.Bytes `json:"raw"`
|
Raw hexutil.Bytes `json:"raw"`
|
||||||
Tx *ethtypes.Transaction `json:"tx"`
|
Tx *ethtypes.Transaction `json:"tx"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OneFeeHistory struct {
|
||||||
|
BaseFee *big.Int // base fee for each block
|
||||||
|
Reward []*big.Int // each element of the array will have the tip provided to miners for the percentile given
|
||||||
|
GasUsedRatio float64 // the ratio of gas used to the gas limit for each block
|
||||||
|
}
|
||||||
|
@ -32,6 +32,8 @@ const (
|
|||||||
|
|
||||||
DefaultFilterCap int32 = 200
|
DefaultFilterCap int32 = 200
|
||||||
|
|
||||||
|
DefaultFeeHistoryCap int32 = 100
|
||||||
|
|
||||||
DefaultEVMTimeout = 5 * time.Second
|
DefaultEVMTimeout = 5 * time.Second
|
||||||
// default 1.0 eth
|
// default 1.0 eth
|
||||||
DefaultTxFeeCap float64 = 1.0
|
DefaultTxFeeCap float64 = 1.0
|
||||||
@ -72,6 +74,8 @@ type JSONRPCConfig struct {
|
|||||||
TxFeeCap float64 `mapstructure:"txfee-cap"`
|
TxFeeCap float64 `mapstructure:"txfee-cap"`
|
||||||
// FilterCap is the global cap for total number of filters that can be created.
|
// FilterCap is the global cap for total number of filters that can be created.
|
||||||
FilterCap int32 `mapstructure:"filter-cap"`
|
FilterCap int32 `mapstructure:"filter-cap"`
|
||||||
|
// FeeHistoryCap is the global cap for total number of blocks that can be fetched
|
||||||
|
FeeHistoryCap int32 `mapstructure:"feehistory-cap"`
|
||||||
// Enable defines if the EVM RPC server should be enabled.
|
// Enable defines if the EVM RPC server should be enabled.
|
||||||
Enable bool `mapstructure:"enable"`
|
Enable bool `mapstructure:"enable"`
|
||||||
}
|
}
|
||||||
@ -161,6 +165,7 @@ func DefaultJSONRPCConfig() *JSONRPCConfig {
|
|||||||
EVMTimeout: DefaultEVMTimeout,
|
EVMTimeout: DefaultEVMTimeout,
|
||||||
TxFeeCap: DefaultTxFeeCap,
|
TxFeeCap: DefaultTxFeeCap,
|
||||||
FilterCap: DefaultFilterCap,
|
FilterCap: DefaultFilterCap,
|
||||||
|
FeeHistoryCap: DefaultFeeHistoryCap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,6 +179,10 @@ func (c JSONRPCConfig) Validate() error {
|
|||||||
return errors.New("JSON-RPC filter-cap cannot be negative")
|
return errors.New("JSON-RPC filter-cap cannot be negative")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.FeeHistoryCap <= 0 {
|
||||||
|
return errors.New("JSON-RPC feehistory-cap cannot be negative or 0")
|
||||||
|
}
|
||||||
|
|
||||||
if c.TxFeeCap < 0 {
|
if c.TxFeeCap < 0 {
|
||||||
return errors.New("JSON-RPC tx fee cap cannot be negative")
|
return errors.New("JSON-RPC tx fee cap cannot be negative")
|
||||||
}
|
}
|
||||||
@ -236,6 +245,7 @@ func GetConfig(v *viper.Viper) Config {
|
|||||||
WsAddress: v.GetString("json-rpc.ws-address"),
|
WsAddress: v.GetString("json-rpc.ws-address"),
|
||||||
GasCap: v.GetUint64("json-rpc.gas-cap"),
|
GasCap: v.GetUint64("json-rpc.gas-cap"),
|
||||||
FilterCap: v.GetInt32("json-rpc.filter-cap"),
|
FilterCap: v.GetInt32("json-rpc.filter-cap"),
|
||||||
|
FeeHistoryCap: v.GetInt32("json-rpc.feehistory-cap"),
|
||||||
TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"),
|
TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"),
|
||||||
EVMTimeout: v.GetDuration("json-rpc.evm-timeout"),
|
EVMTimeout: v.GetDuration("json-rpc.evm-timeout"),
|
||||||
},
|
},
|
||||||
|
@ -44,6 +44,10 @@ txfee-cap = {{ .JSONRPC.TxFeeCap }}
|
|||||||
# FilterCap sets the global cap for total number of filters that can be created
|
# FilterCap sets the global cap for total number of filters that can be created
|
||||||
filter-cap = {{ .JSONRPC.FilterCap }}
|
filter-cap = {{ .JSONRPC.FilterCap }}
|
||||||
|
|
||||||
|
# FeeHistoryCap sets the global cap for total number of blocks that can be fetched
|
||||||
|
feehistory-cap = {{ .JSONRPC.FeeHistoryCap }}
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
### TLS Configuration ###
|
### TLS Configuration ###
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -34,6 +34,7 @@ const (
|
|||||||
JSONRPCEVMTimeout = "json-rpc.evm-timeout"
|
JSONRPCEVMTimeout = "json-rpc.evm-timeout"
|
||||||
JSONRPCTxFeeCap = "json-rpc.txfee-cap"
|
JSONRPCTxFeeCap = "json-rpc.txfee-cap"
|
||||||
JSONRPCFilterCap = "json-rpc.filter-cap"
|
JSONRPCFilterCap = "json-rpc.filter-cap"
|
||||||
|
JSONRPFeeHistoryCap = "json-rpc.feehistory-cap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EVM flags
|
// EVM flags
|
||||||
|
@ -1053,3 +1053,24 @@ func TestEth_EthResend(t *testing.T) {
|
|||||||
_, rpcerror := callWithError("eth_resend", param)
|
_, rpcerror := callWithError("eth_resend", param)
|
||||||
require.Equal(t, "transaction 0x3bf28b46ee1bb3925e50ec6003f899f95913db4b0f579c4e7e887efebf9ecd1b not found", fmt.Sprintf("%s", rpcerror))
|
require.Equal(t, "transaction 0x3bf28b46ee1bb3925e50ec6003f899f95913db4b0f579c4e7e887efebf9ecd1b not found", fmt.Sprintf("%s", rpcerror))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEth_FeeHistory(t *testing.T) {
|
||||||
|
params := make([]interface{}, 0)
|
||||||
|
params = append(params, 4)
|
||||||
|
params = append(params, "0x1c")
|
||||||
|
params = append(params, []int{25, 75})
|
||||||
|
|
||||||
|
rpcRes := call(t, "eth_feeHistory", params)
|
||||||
|
|
||||||
|
info := make(map[string]interface{})
|
||||||
|
err := json.Unmarshal(rpcRes.Result, &info)
|
||||||
|
require.NoError(t, err)
|
||||||
|
reward := info["reward"].([]interface{})
|
||||||
|
baseFeePerGas := info["baseFeePerGas"].([]interface{})
|
||||||
|
gasUsedRatio := info["gasUsedRatio"].([]interface{})
|
||||||
|
|
||||||
|
require.Equal(t, info["oldestBlock"].(string), "0x18")
|
||||||
|
require.Equal(t, 4, len(gasUsedRatio))
|
||||||
|
require.Equal(t, 4, len(baseFeePerGas))
|
||||||
|
require.Equal(t, 4, len(reward))
|
||||||
|
}
|
||||||
|
@ -632,7 +632,8 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
|||||||
expPass: true,
|
expPass: true,
|
||||||
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x33, 0x2c, 0x22, 0x67},
|
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x33, 0x2c, 0x22, 0x67},
|
||||||
dynamicTxFee: false,
|
dynamicTxFee: false,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
msg: "javascript tracer",
|
msg: "javascript tracer",
|
||||||
malleate: func() {
|
malleate: func() {
|
||||||
txIndex = 0
|
txIndex = 0
|
||||||
@ -658,7 +659,8 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
|||||||
expPass: true,
|
expPass: true,
|
||||||
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x33, 0x2c, 0x22, 0x67},
|
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x33, 0x2c, 0x22, 0x67},
|
||||||
dynamicTxFee: true,
|
dynamicTxFee: true,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
msg: "javascript tracer with dynamicTxFee",
|
msg: "javascript tracer with dynamicTxFee",
|
||||||
malleate: func() {
|
malleate: func() {
|
||||||
txIndex = 0
|
txIndex = 0
|
||||||
@ -762,7 +764,8 @@ func (suite *KeeperTestSuite) TestTraceBlock() {
|
|||||||
},
|
},
|
||||||
expPass: true,
|
expPass: true,
|
||||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61},
|
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61},
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
msg: "javascript tracer",
|
msg: "javascript tracer",
|
||||||
malleate: func() {
|
malleate: func() {
|
||||||
traceConfig = &types.TraceConfig{
|
traceConfig = &types.TraceConfig{
|
||||||
@ -784,7 +787,8 @@ func (suite *KeeperTestSuite) TestTraceBlock() {
|
|||||||
expPass: true,
|
expPass: true,
|
||||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61},
|
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x32, 0x39, 0x36, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x33, 0x2c, 0x22, 0x64, 0x65, 0x70, 0x74, 0x68, 0x22, 0x3a, 0x31, 0x7d, 0x2c, 0x7b, 0x22, 0x70, 0x63, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x6f, 0x70, 0x22, 0x3a, 0x22, 0x50, 0x55, 0x53, 0x48, 0x31, 0x22, 0x2c, 0x22, 0x67, 0x61},
|
||||||
dynamicTxFee: true,
|
dynamicTxFee: true,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
msg: "javascript tracer with dynamicTxFee",
|
msg: "javascript tracer with dynamicTxFee",
|
||||||
malleate: func() {
|
malleate: func() {
|
||||||
traceConfig = &types.TraceConfig{
|
traceConfig = &types.TraceConfig{
|
||||||
|
@ -111,7 +111,7 @@ func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) {
|
|||||||
stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ")
|
stateBytes, err := tmjson.MarshalIndent(genesisState, "", " ")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
//Initialize the chain
|
// Initialize the chain
|
||||||
suite.app.InitChain(
|
suite.app.InitChain(
|
||||||
abci.RequestInitChain{
|
abci.RequestInitChain{
|
||||||
ChainId: "ethermint_9000-1",
|
ChainId: "ethermint_9000-1",
|
||||||
|
@ -436,7 +436,6 @@ func (suite *KeeperTestSuite) TestRefundGas() {
|
|||||||
} else {
|
} else {
|
||||||
suite.Require().Error(err)
|
suite.Require().Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
suite.mintFeeCollector = false
|
suite.mintFeeCollector = false
|
||||||
|
@ -363,7 +363,7 @@ func encodeDecodeBinary(tx *ethtypes.Transaction) (*types.MsgEthereumTx, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("rlp encoding failed: %v", err)
|
return nil, fmt.Errorf("rlp encoding failed: %v", err)
|
||||||
}
|
}
|
||||||
var parsedTx = &types.MsgEthereumTx{}
|
parsedTx := &types.MsgEthereumTx{}
|
||||||
if err := parsedTx.UnmarshalBinary(data); err != nil {
|
if err := parsedTx.UnmarshalBinary(data); err != nil {
|
||||||
return nil, fmt.Errorf("rlp decoding failed: %v", err)
|
return nil, fmt.Errorf("rlp decoding failed: %v", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user