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:
Jongwhan Lee 2021-11-17 20:58:52 +09:00 committed by GitHub
parent b7e8dd8216
commit 392d1dd8cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 287 additions and 34 deletions

View File

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

View File

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

View 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, &ethBlock, 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
}

View File

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

View File

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

View File

@ -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"`
} }
@ -153,14 +157,15 @@ func GetDefaultAPINamespaces() []string {
// DefaultJSONRPCConfig returns an EVM config with the JSON-RPC API enabled by default // DefaultJSONRPCConfig returns an EVM config with the JSON-RPC API enabled by default
func DefaultJSONRPCConfig() *JSONRPCConfig { func DefaultJSONRPCConfig() *JSONRPCConfig {
return &JSONRPCConfig{ return &JSONRPCConfig{
Enable: true, Enable: true,
API: GetDefaultAPINamespaces(), API: GetDefaultAPINamespaces(),
Address: DefaultJSONRPCAddress, Address: DefaultJSONRPCAddress,
WsAddress: DefaultJSONRPCWsAddress, WsAddress: DefaultJSONRPCWsAddress,
GasCap: DefaultGasCap, GasCap: DefaultGasCap,
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")
} }
@ -230,14 +239,15 @@ func GetConfig(v *viper.Viper) Config {
Tracer: v.GetString("evm.tracer"), Tracer: v.GetString("evm.tracer"),
}, },
JSONRPC: JSONRPCConfig{ JSONRPC: JSONRPCConfig{
Enable: v.GetBool("json-rpc.enable"), Enable: v.GetBool("json-rpc.enable"),
API: v.GetStringSlice("json-rpc.api"), API: v.GetStringSlice("json-rpc.api"),
Address: v.GetString("json-rpc.address"), Address: v.GetString("json-rpc.address"),
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"),
TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"), FeeHistoryCap: v.GetInt32("json-rpc.feehistory-cap"),
EVMTimeout: v.GetDuration("json-rpc.evm-timeout"), TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"),
EVMTimeout: v.GetDuration("json-rpc.evm-timeout"),
}, },
TLS: TLSConfig{ TLS: TLSConfig{
CertificatePath: v.GetString("tls.certificate-path"), CertificatePath: v.GetString("tls.certificate-path"),

View File

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

View File

@ -26,14 +26,15 @@ const (
// JSON-RPC flags // JSON-RPC flags
const ( const (
JSONRPCEnable = "json-rpc.enable" JSONRPCEnable = "json-rpc.enable"
JSONRPCAPI = "json-rpc.api" JSONRPCAPI = "json-rpc.api"
JSONRPCAddress = "json-rpc.address" JSONRPCAddress = "json-rpc.address"
JSONWsAddress = "json-rpc.ws-address" JSONWsAddress = "json-rpc.ws-address"
JSONRPCGasCap = "json-rpc.gas-cap" JSONRPCGasCap = "json-rpc.gas-cap"
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

View File

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

View File

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

View File

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

View File

@ -436,7 +436,6 @@ func (suite *KeeperTestSuite) TestRefundGas() {
} else { } else {
suite.Require().Error(err) suite.Require().Error(err)
} }
}) })
} }
suite.mintFeeCollector = false suite.mintFeeCollector = false

View File

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