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

fix(rpc): align fee history #1611

Merged
merged 19 commits into from
Jan 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Bug Fixes

fedekunze marked this conversation as resolved.
Show resolved Hide resolved
* (rpc) [#1613](https://github.com/evmos/ethermint/pull/1613) Change the default json-rpc listen address to localhost.
* (rpc) [#1611](https://github.com/evmos/ethermint/pull/1611) Add missing next fee in fee history, fix wrong oldestBlock and align earliest input as ethereum.

## [v0.21.0-rc1] - 2022-1-13

Expand Down
4 changes: 2 additions & 2 deletions gomod2nix.toml
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@ schema = 3
version = "v2.7.0"
hash = "sha256-BKqQKCsPA73FaQwYpAY+QsWFHIncrG5jgRhC2IiNmCk="
[mod."github.com/onsi/gomega"]
version = "v1.24.2"
hash = "sha256-iascSzzBT1Uv/XybezSblIwwrq78BU4a9BVB5MvK6MM="
version = "v1.25.0"
hash = "sha256-knaJppfBzKSMD4Gsqzx22SGrti7G5UyDBYrothAqsrs="
[mod."github.com/pelletier/go-toml"]
version = "v1.9.5"
hash = "sha256-RJ9K1BTId0Mled7S66iGgxHkZ5JKEIsrrNaEfM8aImc="
Expand Down
29 changes: 14 additions & 15 deletions rpc/backend/chain_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,44 +161,42 @@ func (b *Backend) FeeHistory(
) (*rpctypes.FeeHistoryResult, error) {
blockEnd := int64(lastBlock)

if blockEnd <= 0 {
if blockEnd < 0 {
blockNumber, err := b.BlockNumber()
if err != nil {
return nil, err
}
blockEnd = int64(blockNumber)
}

userBlockCountInt := int64(userBlockCount)
blocks := int64(userBlockCount)

Check failure

Code scanning / gosec

Potential integer overflow by integer type conversion

Potential integer overflow by integer type conversion
maxBlockCount := int64(b.cfg.JSONRPC.FeeHistoryCap)
if userBlockCountInt > maxBlockCount {
return nil, fmt.Errorf("FeeHistory user block count %d higher than %d", userBlockCountInt, maxBlockCount)
if blocks > maxBlockCount {
return nil, fmt.Errorf("FeeHistory user block count %d higher than %d", blocks, maxBlockCount)
}

blockStart := blockEnd - userBlockCountInt
if blockStart < 0 {
blockStart = 0
if blockEnd+1 < blocks {
blocks = blockEnd + 1
}

blockCount := blockEnd - blockStart

// Ensure not trying to retrieve before genesis.
blockStart := blockEnd + 1 - blocks
oldestBlock := (*hexutil.Big)(big.NewInt(blockStart))

// prepare space
reward := make([][]*hexutil.Big, blockCount)
reward := make([][]*hexutil.Big, blocks)
rewardCount := len(rewardPercentiles)
for i := 0; i < int(blockCount); i++ {
for i := 0; i < int(blocks); i++ {
reward[i] = make([]*hexutil.Big, rewardCount)
}

thisBaseFee := make([]*hexutil.Big, blockCount)
thisGasUsedRatio := make([]float64, blockCount)
thisBaseFee := make([]*hexutil.Big, blocks+1)
thisGasUsedRatio := make([]float64, blocks)

// rewards should only be calculated if reward percentiles were included
calculateRewards := rewardCount != 0

// fetch block
for blockID := blockStart; blockID < blockEnd; blockID++ {
for blockID := blockStart; blockID <= blockEnd; blockID++ {
index := int32(blockID - blockStart)
// tendermint block
tendermintblock, err := b.TendermintBlockByNumber(rpctypes.BlockNumber(blockID))
Expand Down Expand Up @@ -227,6 +225,7 @@ func (b *Backend) FeeHistory(

// copy
thisBaseFee[index] = (*hexutil.Big)(oneFeeHistory.BaseFee)
thisBaseFee[index+1] = (*hexutil.Big)(oneFeeHistory.NextBaseFee)
thisGasUsedRatio[index] = oneFeeHistory.GasUsedRatio
if calculateRewards {
for j := 0; j < rewardCount; j++ {
Expand Down
11 changes: 7 additions & 4 deletions rpc/backend/chain_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func (suite *BackendTestSuite) TestFeeHistory() {
RegisterParamsError(queryClient, &header, ethrpc.BlockNumber(1).Int64())
},
1,
0,
-1,
nil,
nil,
false,
Expand All @@ -351,7 +351,7 @@ func (suite *BackendTestSuite) TestFeeHistory() {
RegisterParams(queryClient, &header, ethrpc.BlockNumber(1).Int64())
},
1,
0,
-1,
nil,
nil,
false,
Expand Down Expand Up @@ -405,6 +405,7 @@ func (suite *BackendTestSuite) TestFeeHistory() {
{
"pass - Valid FeeHistoryResults object",
func(validator sdk.AccAddress) {
var header metadata.MD
baseFee := sdk.NewInt(1)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
client := suite.backend.clientCtx.Client.(*mocks.Client)
Expand All @@ -414,12 +415,14 @@ func (suite *BackendTestSuite) TestFeeHistory() {
RegisterBaseFee(queryClient, baseFee)
RegisterValidatorAccount(queryClient, validator)
RegisterConsensusParams(client, 1)
RegisterParams(queryClient, &header, 1)
RegisterParamsWithoutHeader(queryClient, 1)
},
1,
1,
&rpc.FeeHistoryResult{
OldestBlock: (*hexutil.Big)(big.NewInt(0)),
BaseFee: []*hexutil.Big{(*hexutil.Big)(big.NewInt(1))},
OldestBlock: (*hexutil.Big)(big.NewInt(1)),
BaseFee: []*hexutil.Big{(*hexutil.Big)(big.NewInt(1)), (*hexutil.Big)(big.NewInt(1))},
GasUsedRatio: []float64{0},
Reward: [][]*hexutil.Big{{(*hexutil.Big)(big.NewInt(0)), (*hexutil.Big)(big.NewInt(0)), (*hexutil.Big)(big.NewInt(0)), (*hexutil.Big)(big.NewInt(0))}},
},
Expand Down
8 changes: 7 additions & 1 deletion rpc/backend/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus/misc"
ethtypes "github.com/ethereum/go-ethereum/core/types"

abci "github.com/tendermint/tendermint/abci/types"
Expand Down Expand Up @@ -132,7 +133,12 @@ func (b *Backend) processBlock(

// set basefee
targetOneFeeHistory.BaseFee = blockBaseFee

cfg := b.ChainConfig()
if cfg.IsLondon(big.NewInt(blockHeight + 1)) {
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
targetOneFeeHistory.NextBaseFee = misc.CalcBaseFee(cfg, b.CurrentHeader())
} else {
targetOneFeeHistory.NextBaseFee = new(big.Int)
}
// set gas used ratio
gasLimitUint64, ok := (*ethBlock)["gasLimit"].(hexutil.Uint64)
if !ok {
Expand Down
6 changes: 3 additions & 3 deletions rpc/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ type SignTransactionResult struct {
}

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
BaseFee, NextBaseFee *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
}
73 changes: 73 additions & 0 deletions tests/integration_tests/test_fee_history.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from concurrent.futures import ThreadPoolExecutor, as_completed

import pytest
from web3 import Web3

from .network import setup_ethermint
from .utils import ADDRS, send_transaction


@pytest.fixture(scope="module")
def custom_ethermint(tmp_path_factory):
path = tmp_path_factory.mktemp("fee-history")
yield from setup_ethermint(path, 26500, long_timeout_commit=True)


@pytest.fixture(scope="module", params=["ethermint", "geth"])
def cluster(request, custom_ethermint, geth):
"""
run on both ethermint and geth
"""
provider = request.param
if provider == "ethermint":
yield custom_ethermint
elif provider == "geth":
yield geth
else:
raise NotImplementedError


def test_basic(cluster):
w3: Web3 = cluster.w3
call = w3.provider.make_request
tx = {"to": ADDRS["community"], "value": 10, "gasPrice": w3.eth.gas_price}
send_transaction(w3, tx)
size = 4
# size of base fee + next fee
max = size + 1
# only 1 base fee + next fee
min = 2
method = "eth_feeHistory"
field = "baseFeePerGas"
percentiles = [100]
height = w3.eth.block_number
latest = dict(
blocks=["latest", hex(height)],
expect=max,
)
earliest = dict(
blocks=["earliest", "0x0"],
expect=min,
)
for tc in [latest, earliest]:
res = []
with ThreadPoolExecutor(len(tc["blocks"])) as exec:
tasks = [
exec.submit(call, method, [size, b, percentiles]) for b in tc["blocks"]
]
res = [future.result()["result"][field] for future in as_completed(tasks)]
assert len(res) == len(tc["blocks"])
assert res[0] == res[1]
assert len(res[0]) == tc["expect"]

for x in range(max):
i = x + 1
fee_history = call(method, [size, hex(i), percentiles])
# start to reduce diff on i <= size - min
diff = size - min - i
reduce = size - diff
target = reduce if diff >= 0 else max
res = fee_history["result"]
assert len(res[field]) == target
oldest = i + min - max
assert res["oldestBlock"] == hex(oldest if oldest > 0 else 0)
4 changes: 2 additions & 2 deletions tests/rpc/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,8 @@ func TestEth_FeeHistory(t *testing.T) {
baseFeePerGas := info["baseFeePerGas"].([]interface{})
gasUsedRatio := info["gasUsedRatio"].([]interface{})

require.Equal(t, info["oldestBlock"].(string), "0x6")
require.Equal(t, info["oldestBlock"].(string), "0x7")
require.Equal(t, 4, len(gasUsedRatio))
require.Equal(t, 4, len(baseFeePerGas))
require.Equal(t, 5, len(baseFeePerGas))
require.Equal(t, 4, len(reward))
}