* fix(rpc): align fee history (#1611) * update nix * add next fee in fee history * fix test * add change doc * height + 1 for next fee * cross check baseFeePerGas len * Update tests/integration_tests/test_fee_history.py Co-authored-by: MalteHerrmann <42640438+MalteHerrmann@users.noreply.github.com> * fix oldestBlock & align earliest input as eth * update doc * update nix * isort test_fee_history.py * fix test * align rpc res as eth * add cross check * add baseFeePerGas len check * add oldestBlock check Co-authored-by: MalteHerrmann <42640438+MalteHerrmann@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> (cherry picked from commit 47fdfd3d8318358c2578b610bc35bc8c1ebb131e) # Conflicts: # CHANGELOG.md * address merge conflicts Co-authored-by: mmsqe <mavis@crypto.com> Co-authored-by: MalteHerrmann <malte@evmos.org> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
c1c25b1818
commit
949674e511
@ -36,7 +36,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [v0.21.0-rc2] - 2022-1-20
|
## [v0.21.0-rc2] - 2022-01-20
|
||||||
|
|
||||||
### State Machine Breaking
|
### State Machine Breaking
|
||||||
|
|
||||||
@ -54,6 +54,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
* (rpc) [#1600](https://github.com/evmos/ethermint/pull/1600) Revert changes from `TypedEvents`
|
* (rpc) [#1600](https://github.com/evmos/ethermint/pull/1600) Revert changes from `TypedEvents`
|
||||||
* (rpc) [#1613](https://github.com/evmos/ethermint/pull/1613) Change the default json-rpc listen address to localhost.
|
* (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.
|
||||||
* (proto) [#1586](https://github.com/evmos/ethermint/pull/1586) Avoid duplicate register proto type in `evm` & `feemarket`
|
* (proto) [#1586](https://github.com/evmos/ethermint/pull/1586) Avoid duplicate register proto type in `evm` & `feemarket`
|
||||||
|
|
||||||
## [v0.20.0] - 2022-12-28
|
## [v0.20.0] - 2022-12-28
|
||||||
|
@ -361,8 +361,8 @@ schema = 3
|
|||||||
version = "v2.7.0"
|
version = "v2.7.0"
|
||||||
hash = "sha256-BKqQKCsPA73FaQwYpAY+QsWFHIncrG5jgRhC2IiNmCk="
|
hash = "sha256-BKqQKCsPA73FaQwYpAY+QsWFHIncrG5jgRhC2IiNmCk="
|
||||||
[mod."github.com/onsi/gomega"]
|
[mod."github.com/onsi/gomega"]
|
||||||
version = "v1.24.2"
|
version = "v1.25.0"
|
||||||
hash = "sha256-iascSzzBT1Uv/XybezSblIwwrq78BU4a9BVB5MvK6MM="
|
hash = "sha256-knaJppfBzKSMD4Gsqzx22SGrti7G5UyDBYrothAqsrs="
|
||||||
[mod."github.com/pelletier/go-toml"]
|
[mod."github.com/pelletier/go-toml"]
|
||||||
version = "v1.9.5"
|
version = "v1.9.5"
|
||||||
hash = "sha256-RJ9K1BTId0Mled7S66iGgxHkZ5JKEIsrrNaEfM8aImc="
|
hash = "sha256-RJ9K1BTId0Mled7S66iGgxHkZ5JKEIsrrNaEfM8aImc="
|
||||||
|
@ -161,7 +161,7 @@ func (b *Backend) FeeHistory(
|
|||||||
) (*rpctypes.FeeHistoryResult, error) {
|
) (*rpctypes.FeeHistoryResult, error) {
|
||||||
blockEnd := int64(lastBlock)
|
blockEnd := int64(lastBlock)
|
||||||
|
|
||||||
if blockEnd <= 0 {
|
if blockEnd < 0 {
|
||||||
blockNumber, err := b.BlockNumber()
|
blockNumber, err := b.BlockNumber()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -169,36 +169,34 @@ func (b *Backend) FeeHistory(
|
|||||||
blockEnd = int64(blockNumber)
|
blockEnd = int64(blockNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
userBlockCountInt := int64(userBlockCount)
|
blocks := int64(userBlockCount)
|
||||||
maxBlockCount := int64(b.cfg.JSONRPC.FeeHistoryCap)
|
maxBlockCount := int64(b.cfg.JSONRPC.FeeHistoryCap)
|
||||||
if userBlockCountInt > maxBlockCount {
|
if blocks > maxBlockCount {
|
||||||
return nil, fmt.Errorf("FeeHistory user block count %d higher than %d", userBlockCountInt, maxBlockCount)
|
return nil, fmt.Errorf("FeeHistory user block count %d higher than %d", blocks, maxBlockCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
blockStart := blockEnd - userBlockCountInt
|
if blockEnd+1 < blocks {
|
||||||
if blockStart < 0 {
|
blocks = blockEnd + 1
|
||||||
blockStart = 0
|
|
||||||
}
|
}
|
||||||
|
// Ensure not trying to retrieve before genesis.
|
||||||
blockCount := blockEnd - blockStart
|
blockStart := blockEnd + 1 - blocks
|
||||||
|
|
||||||
oldestBlock := (*hexutil.Big)(big.NewInt(blockStart))
|
oldestBlock := (*hexutil.Big)(big.NewInt(blockStart))
|
||||||
|
|
||||||
// prepare space
|
// prepare space
|
||||||
reward := make([][]*hexutil.Big, blockCount)
|
reward := make([][]*hexutil.Big, blocks)
|
||||||
rewardCount := len(rewardPercentiles)
|
rewardCount := len(rewardPercentiles)
|
||||||
for i := 0; i < int(blockCount); i++ {
|
for i := 0; i < int(blocks); i++ {
|
||||||
reward[i] = make([]*hexutil.Big, rewardCount)
|
reward[i] = make([]*hexutil.Big, rewardCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
thisBaseFee := make([]*hexutil.Big, blockCount)
|
thisBaseFee := make([]*hexutil.Big, blocks+1)
|
||||||
thisGasUsedRatio := make([]float64, blockCount)
|
thisGasUsedRatio := make([]float64, blocks)
|
||||||
|
|
||||||
// rewards should only be calculated if reward percentiles were included
|
// rewards should only be calculated if reward percentiles were included
|
||||||
calculateRewards := rewardCount != 0
|
calculateRewards := rewardCount != 0
|
||||||
|
|
||||||
// fetch block
|
// fetch block
|
||||||
for blockID := blockStart; blockID < blockEnd; blockID++ {
|
for blockID := blockStart; blockID <= blockEnd; blockID++ {
|
||||||
index := int32(blockID - blockStart)
|
index := int32(blockID - blockStart)
|
||||||
// tendermint block
|
// tendermint block
|
||||||
tendermintblock, err := b.TendermintBlockByNumber(rpctypes.BlockNumber(blockID))
|
tendermintblock, err := b.TendermintBlockByNumber(rpctypes.BlockNumber(blockID))
|
||||||
@ -227,6 +225,7 @@ func (b *Backend) FeeHistory(
|
|||||||
|
|
||||||
// copy
|
// copy
|
||||||
thisBaseFee[index] = (*hexutil.Big)(oneFeeHistory.BaseFee)
|
thisBaseFee[index] = (*hexutil.Big)(oneFeeHistory.BaseFee)
|
||||||
|
thisBaseFee[index+1] = (*hexutil.Big)(oneFeeHistory.NextBaseFee)
|
||||||
thisGasUsedRatio[index] = oneFeeHistory.GasUsedRatio
|
thisGasUsedRatio[index] = oneFeeHistory.GasUsedRatio
|
||||||
if calculateRewards {
|
if calculateRewards {
|
||||||
for j := 0; j < rewardCount; j++ {
|
for j := 0; j < rewardCount; j++ {
|
||||||
|
@ -337,7 +337,7 @@ func (suite *BackendTestSuite) TestFeeHistory() {
|
|||||||
RegisterParamsError(queryClient, &header, ethrpc.BlockNumber(1).Int64())
|
RegisterParamsError(queryClient, &header, ethrpc.BlockNumber(1).Int64())
|
||||||
},
|
},
|
||||||
1,
|
1,
|
||||||
0,
|
-1,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
false,
|
false,
|
||||||
@ -351,7 +351,7 @@ func (suite *BackendTestSuite) TestFeeHistory() {
|
|||||||
RegisterParams(queryClient, &header, ethrpc.BlockNumber(1).Int64())
|
RegisterParams(queryClient, &header, ethrpc.BlockNumber(1).Int64())
|
||||||
},
|
},
|
||||||
1,
|
1,
|
||||||
0,
|
-1,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
false,
|
false,
|
||||||
@ -405,6 +405,7 @@ func (suite *BackendTestSuite) TestFeeHistory() {
|
|||||||
{
|
{
|
||||||
"pass - Valid FeeHistoryResults object",
|
"pass - Valid FeeHistoryResults object",
|
||||||
func(validator sdk.AccAddress) {
|
func(validator sdk.AccAddress) {
|
||||||
|
var header metadata.MD
|
||||||
baseFee := sdk.NewInt(1)
|
baseFee := sdk.NewInt(1)
|
||||||
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
|
||||||
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
client := suite.backend.clientCtx.Client.(*mocks.Client)
|
||||||
@ -414,12 +415,14 @@ func (suite *BackendTestSuite) TestFeeHistory() {
|
|||||||
RegisterBaseFee(queryClient, baseFee)
|
RegisterBaseFee(queryClient, baseFee)
|
||||||
RegisterValidatorAccount(queryClient, validator)
|
RegisterValidatorAccount(queryClient, validator)
|
||||||
RegisterConsensusParams(client, 1)
|
RegisterConsensusParams(client, 1)
|
||||||
|
RegisterParams(queryClient, &header, 1)
|
||||||
|
RegisterParamsWithoutHeader(queryClient, 1)
|
||||||
},
|
},
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
&rpc.FeeHistoryResult{
|
&rpc.FeeHistoryResult{
|
||||||
OldestBlock: (*hexutil.Big)(big.NewInt(0)),
|
OldestBlock: (*hexutil.Big)(big.NewInt(1)),
|
||||||
BaseFee: []*hexutil.Big{(*hexutil.Big)(big.NewInt(1))},
|
BaseFee: []*hexutil.Big{(*hexutil.Big)(big.NewInt(1)), (*hexutil.Big)(big.NewInt(1))},
|
||||||
GasUsedRatio: []float64{0},
|
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))}},
|
Reward: [][]*hexutil.Big{{(*hexutil.Big)(big.NewInt(0)), (*hexutil.Big)(big.NewInt(0)), (*hexutil.Big)(big.NewInt(0)), (*hexutil.Big)(big.NewInt(0))}},
|
||||||
},
|
},
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
|
|
||||||
"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"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
@ -132,7 +133,12 @@ func (b *Backend) processBlock(
|
|||||||
|
|
||||||
// set basefee
|
// set basefee
|
||||||
targetOneFeeHistory.BaseFee = blockBaseFee
|
targetOneFeeHistory.BaseFee = blockBaseFee
|
||||||
|
cfg := b.ChainConfig()
|
||||||
|
if cfg.IsLondon(big.NewInt(blockHeight + 1)) {
|
||||||
|
targetOneFeeHistory.NextBaseFee = misc.CalcBaseFee(cfg, b.CurrentHeader())
|
||||||
|
} else {
|
||||||
|
targetOneFeeHistory.NextBaseFee = new(big.Int)
|
||||||
|
}
|
||||||
// set gas used ratio
|
// set gas used ratio
|
||||||
gasLimitUint64, ok := (*ethBlock)["gasLimit"].(hexutil.Uint64)
|
gasLimitUint64, ok := (*ethBlock)["gasLimit"].(hexutil.Uint64)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -98,7 +98,7 @@ type SignTransactionResult struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type OneFeeHistory struct {
|
type OneFeeHistory struct {
|
||||||
BaseFee *big.Int // base fee 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
|
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
|
GasUsedRatio float64 // the ratio of gas used to the gas limit for each block
|
||||||
}
|
}
|
||||||
|
73
tests/integration_tests/test_fee_history.py
Normal file
73
tests/integration_tests/test_fee_history.py
Normal file
@ -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)
|
@ -595,8 +595,8 @@ func TestEth_FeeHistory(t *testing.T) {
|
|||||||
baseFeePerGas := info["baseFeePerGas"].([]interface{})
|
baseFeePerGas := info["baseFeePerGas"].([]interface{})
|
||||||
gasUsedRatio := info["gasUsedRatio"].([]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(gasUsedRatio))
|
||||||
require.Equal(t, 4, len(baseFeePerGas))
|
require.Equal(t, 5, len(baseFeePerGas))
|
||||||
require.Equal(t, 4, len(reward))
|
require.Equal(t, 4, len(reward))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user