Skip to content

Commit be9a92a

Browse files
authored
rpcdaemon: fix eth_feeHistory (#2115)
1 parent 5dfc835 commit be9a92a

File tree

5 files changed

+42
-25
lines changed

5 files changed

+42
-25
lines changed

silkworm/core/chain/config.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,12 @@ std::optional<ChainConfig> ChainConfig::from_json(const nlohmann::json& json) no
181181
return config;
182182
}
183183

184-
[[nodiscard]] bool ChainConfig::withdrawals_activated(uint64_t block_time) const noexcept {
184+
[[nodiscard]] bool ChainConfig::withdrawals_activated(BlockTime block_time) const noexcept {
185185
return shanghai_time && block_time >= shanghai_time;
186186
}
187+
[[nodiscard]] bool ChainConfig::is_london(BlockNum block_number) const noexcept {
188+
return (london_block && block_number >= london_block);
189+
}
187190

188191
evmc_revision ChainConfig::revision(uint64_t block_number, uint64_t block_time) const noexcept {
189192
if (cancun_time && block_time >= cancun_time) return EVMC_CANCUN;

silkworm/core/chain/config.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ struct ChainConfig {
9595
protocol::PreMergeRuleSetConfig rule_set_config{protocol::NoPreMergeConfig{}};
9696

9797
// The Shanghai hard fork has withdrawals, but Agra does not
98-
[[nodiscard]] bool withdrawals_activated(uint64_t block_time) const noexcept;
98+
[[nodiscard]] bool withdrawals_activated(BlockTime block_time) const noexcept;
99+
[[nodiscard]] bool is_london(BlockNum block_number) const noexcept;
99100

100101
//! \brief Returns the revision level at given block number
101102
//! \details In other words, on behalf of Json chain config data

silkworm/rpc/commands/eth_api.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2086,6 +2086,9 @@ Task<void> EthereumRpcApi::handle_fee_history(const nlohmann::json& request, nlo
20862086
try {
20872087
const auto chain_storage{tx->create_storage()};
20882088

2089+
rpc::fee_history::BlockHeaderProvider block_header_provider = [&chain_storage](BlockNum block_number) {
2090+
return chain_storage->read_canonical_header(block_number);
2091+
};
20892092
rpc::fee_history::BlockProvider block_provider = [this, &chain_storage](BlockNum block_number) {
20902093
return core::read_block_by_number(*block_cache_, *chain_storage, block_number);
20912094
};
@@ -2100,7 +2103,7 @@ Task<void> EthereumRpcApi::handle_fee_history(const nlohmann::json& request, nlo
21002103
auto chain_config = co_await chain_storage->read_chain_config();
21012104
ensure(chain_config.has_value(), "cannot read chain config");
21022105

2103-
rpc::fee_history::FeeHistoryOracle oracle{*chain_config, block_provider, receipts_provider, latest_block_provider};
2106+
rpc::fee_history::FeeHistoryOracle oracle{*chain_config, block_header_provider, block_provider, receipts_provider, latest_block_provider};
21042107

21052108
const auto block_number = co_await core::get_block_number(newest_block, *tx);
21062109
const auto fee_history = co_await oracle.fee_history(block_number, block_count, reward_percentiles);

silkworm/rpc/core/fee_history_oracle.cpp

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -109,24 +109,34 @@ Task<FeeHistory> FeeHistoryOracle::fee_history(BlockNum newest_block,
109109
}
110110

111111
BlockFees block_fees{block_number};
112-
if (block_number >= block_range.last_block->block.header.number) {
113-
block_fees.block = block_range.last_block;
114-
block_fees.receipts = co_await receipts_provider_(*block_fees.block);
112+
113+
if (!reward_percentiles.empty()) {
114+
if (block_number >= block_range.last_block->block.header.number) {
115+
block_fees.block = block_range.last_block;
116+
block_fees.receipts = co_await receipts_provider_(*block_fees.block);
117+
} else {
118+
const auto block_with_hash = co_await block_provider_(block_number);
119+
if (!block_with_hash) {
120+
continue;
121+
}
122+
block_fees.block = block_with_hash;
123+
if (!reward_percentiles.empty()) {
124+
block_fees.receipts = co_await receipts_provider_(*block_fees.block);
125+
}
126+
}
127+
block_fees.block_header = block_fees.block->block.header;
115128
} else {
116-
const auto block_with_hash = co_await block_provider_(block_number);
117-
if (!block_with_hash) {
129+
const auto block_header = co_await block_header_provider_(block_number);
130+
if (!block_header) {
118131
continue;
119132
}
120-
block_fees.block = block_with_hash;
121-
if (!reward_percentiles.empty()) {
122-
block_fees.receipts = co_await receipts_provider_(*block_fees.block);
123-
}
133+
block_fees.block_header = block_header;
124134
}
125135
co_await process_block(block_fees, reward_percentiles);
126136

127137
ensure(block_fees.block_number >= oldest_block_number, "fee_history: block_number lower than oldest");
128138
const auto index = block_fees.block_number - oldest_block_number;
129-
if (block_fees.block) {
139+
if (block_fees.block_header) {
130140
fee_history.rewards[index] = block_fees.rewards;
131141
fee_history.base_fees_per_gas[index] = block_fees.base_fee;
132142
fee_history.base_fees_per_gas[index + 1] = block_fees.next_base_fee;
@@ -188,23 +198,20 @@ bool sort_by_reward(std::pair<intx::uint256, uint64_t>& p1, const std::pair<intx
188198
}
189199

190200
Task<void> FeeHistoryOracle::process_block(BlockFees& block_fees, const std::vector<int8_t>& reward_percentiles) {
191-
auto& header = block_fees.block->block.header;
201+
auto& header = *(block_fees.block_header);
202+
auto next_block_number = header.number + 1;
192203
block_fees.base_fee = header.base_fee_per_gas.value_or(0);
193204

194205
block_fees.gas_used_ratio = static_cast<double>(header.gas_used) / static_cast<double>(header.gas_limit);
195206

196-
const auto parent_block = co_await block_provider_(header.number + 1);
197-
if (!parent_block) {
198-
co_return;
199-
}
200-
const auto evmc_revision = config_.revision(parent_block->block.header.number, parent_block->block.header.timestamp);
201-
block_fees.next_base_fee = 0;
202-
if (evmc_revision >= EVMC_LONDON) {
207+
if (config_.is_london(next_block_number)) {
203208
block_fees.next_base_fee = protocol::expected_base_fee_per_gas(header);
209+
} else {
210+
block_fees.next_base_fee = 0;
204211
}
205212

206213
if (reward_percentiles.empty()) {
207-
co_return;
214+
co_return; // rewards were not requested, return
208215
}
209216
if (block_fees.receipts.size() != block_fees.block->block.transactions.size()) {
210217
co_return;

silkworm/rpc/core/fee_history_oracle.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
namespace silkworm::rpc::fee_history {
3333

34+
using BlockHeaderProvider = std::function<Task<std::optional<silkworm::BlockHeader>>(BlockNum)>;
3435
using BlockProvider = std::function<Task<std::shared_ptr<silkworm::BlockWithHash>>(BlockNum)>;
3536
using ReceiptsProvider = std::function<Task<rpc::Receipts>(const BlockWithHash&)>;
3637
using LatestBlockProvider = std::function<Task<uint64_t>()>;
@@ -56,7 +57,8 @@ struct BlockRange {
5657

5758
struct BlockFees {
5859
BlockNum block_number{0};
59-
std::shared_ptr<BlockWithHash> block;
60+
std::optional<BlockHeader> block_header;
61+
std::shared_ptr<BlockWithHash> block; // only set if reward percentiles are requested
6062
rpc::Receipts receipts;
6163
Rewards rewards;
6264
intx::uint256 base_fee;
@@ -66,9 +68,9 @@ struct BlockFees {
6668

6769
class FeeHistoryOracle {
6870
public:
69-
explicit FeeHistoryOracle(const silkworm::ChainConfig& config, const BlockProvider& block_provider, ReceiptsProvider& receipts_provider,
71+
explicit FeeHistoryOracle(const silkworm::ChainConfig& config, const BlockHeaderProvider& header_provider, const BlockProvider& block_provider, ReceiptsProvider& receipts_provider,
7072
LatestBlockProvider& latest_block_provider)
71-
: config_{config}, block_provider_(block_provider), receipts_provider_(receipts_provider), latest_block_provider_{latest_block_provider} {}
73+
: config_{config}, block_header_provider_(header_provider), block_provider_(block_provider), receipts_provider_(receipts_provider), latest_block_provider_{latest_block_provider} {}
7274
virtual ~FeeHistoryOracle() = default;
7375

7476
FeeHistoryOracle(const FeeHistoryOracle&) = delete;
@@ -85,6 +87,7 @@ class FeeHistoryOracle {
8587
Task<void> process_block(BlockFees& block_fees, const std::vector<int8_t>& reward_percentiles);
8688

8789
const silkworm::ChainConfig& config_;
90+
const BlockHeaderProvider& block_header_provider_;
8891
const BlockProvider& block_provider_;
8992
const ReceiptsProvider& receipts_provider_;
9093
const LatestBlockProvider& latest_block_provider_;

0 commit comments

Comments
 (0)