Skip to content

Commit

Permalink
rpcdaemon: implement eth_baseFee + eth_blobBaseFee (#2465)
Browse files Browse the repository at this point in the history
  • Loading branch information
lupin012 authored Nov 1, 2024
1 parent 13fcf8d commit b3e4f2e
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 6 deletions.
11 changes: 5 additions & 6 deletions .github/workflows/run_integration_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ set +e # Disable exit on error
cd "$1" || exit 1
rm -rf ./mainnet/results/

# eth_baseFee & eth_blobBaseFee: new APIs
# eth_estimateGas new fields
# eth_getBlockReceipts/test_07.json new blobFields
# debug_accountRange: new algo using TKV
Expand All @@ -29,7 +28,7 @@ rm -rf ./mainnet/results/
# trace_rawTransaction: different implementation
# trace_replayTransaction/trace_replyBlockTransaction: silkworm has different response with erigon3 but could be erigon3 problem (to be analyzed)

python3 ./run_tests.py --continue --blockchain mainnet --jwt "$2" --display-only-fail --port 51515 -x \
python3 ./run_tests.py --continue --blockchain mainnet --jwt "$2" --display-only-fail --json-diff --port 51515 -x \
debug_accountRange,\
debug_getModifiedAccounts,\
debug_storageRangeAt,\
Expand All @@ -48,16 +47,16 @@ debug_traceTransaction/test_96.json,\
engine_,\
erigon_getBalanceChangesInBlock,\
erigon_getLatestLogs,\
eth_estimateGas,\
eth_getBlockReceipts/test_07.json,\
eth_getLogs,\
ots_getTransactionBySenderAndNonce,\
ots_getContractCreator,\
ots_hasCode,\
ots_hasCode/test_09.json,\
ots_searchTransactionsAfter,\
ots_searchTransactionsBefore,\
parity_listStorageKeys/test_12.json,\
trace_rawTransaction,\
trace_filter/test_16.json,\
txpool_content --transport_type http,websocket
trace_rawTransaction --transport_type http,websocket

failed_test=$?

Expand Down
2 changes: 2 additions & 0 deletions docs/JSON-RPC-API.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ The following table shows the current [JSON RPC API](https://eth.wiki/json-rpc/A
| eth_gasPrice | Yes | | Yes | |
| eth_maxPriorityFeePerGas | Yes | | Yes | |
| eth_feeHistory | Yes | | Yes | |
| eth_baseFee | Yes | | Yes | |
| eth_blobBaseFee | Yes | | Yes | |
| | | | | |
| eth_getBlockByHash | Yes | | Yes | Yes |
| eth_getBlockByNumber | Yes | | Yes | Yes |
Expand Down
85 changes: 85 additions & 0 deletions silkworm/rpc/commands/eth_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <silkworm/core/common/bytes_to_string.hpp>
#include <silkworm/core/common/util.hpp>
#include <silkworm/core/types/address.hpp>
#include <silkworm/core/types/block.hpp>
#include <silkworm/core/types/evmc_bytes32.hpp>
#include <silkworm/core/types/transaction.hpp>
#include <silkworm/db/state/state_reader.hpp>
Expand Down Expand Up @@ -2060,4 +2061,88 @@ Task<void> EthereumRpcApi::handle_fee_history(const nlohmann::json& request, nlo
co_await tx->close(); // RAII not (yet) available with coroutines
}

Task<void> EthereumRpcApi::handle_base_fee(const nlohmann::json& request, nlohmann::json& reply) {
const auto& params = request["params"];
if (params.size() != 0) {
const auto error_msg = "invalid eth_baseFee params: " + params.dump();
SILK_ERROR << error_msg;
reply = make_json_error(request, 100, error_msg);
co_return;
}

auto tx = co_await database_->begin();

try {
intx::uint256 base_fee{0};
const auto chain_storage{tx->create_storage()};
const auto chain_config = co_await chain_storage->read_chain_config();
const auto latest_block_number = co_await core::get_block_number(core::kLatestBlockId, *tx);
const auto latest_block_with_hash = co_await core::read_block_by_number(*block_cache_, *chain_storage, latest_block_number);
if (!latest_block_with_hash) {
reply = make_json_content(request, to_quantity(base_fee));
co_await tx->close(); // RAII not (yet) available with coroutines
co_return;
}
auto& header = latest_block_with_hash->block.header;

if (chain_config.is_london(header.number + 1)) {
base_fee = protocol::expected_base_fee_per_gas(header);
} else {
base_fee = 0;
}

reply = make_json_content(request, to_quantity(base_fee));

} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, kInternalError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, kServerError, "unexpected exception");
}

co_await tx->close(); // RAII not (yet) available with coroutines
}

Task<void> EthereumRpcApi::handle_blob_base_fee(const nlohmann::json& request, nlohmann::json& reply) {
const auto& params = request["params"];
if (params.size() != 0) {
const auto error_msg = "invalid eth_blobBaseFee params: " + params.dump();
SILK_ERROR << error_msg;
reply = make_json_error(request, 100, error_msg);
co_return;
}

auto tx = co_await database_->begin();

try {
intx::uint256 blob_base_fee{0};
const auto chain_storage{tx->create_storage()};
const auto latest_block_number = co_await core::get_block_number(core::kLatestBlockId, *tx);
const auto latest_block_with_hash = co_await core::read_block_by_number(*block_cache_, *chain_storage, latest_block_number);
if (!latest_block_with_hash) {
reply = make_json_content(request, to_quantity(blob_base_fee));
co_await tx->close(); // RAII not (yet) available with coroutines
co_return;
}
auto& header = latest_block_with_hash->block.header;

if (header.excess_blob_gas) {
blob_base_fee = calc_blob_gas_price(protocol::calc_excess_blob_gas(header));
} else {
blob_base_fee = 0;
}
reply = make_json_content(request, to_quantity(blob_base_fee));

} catch (const std::exception& e) {
SILK_ERROR << "exception: " << e.what() << " processing request: " << request.dump();
reply = make_json_error(request, kInternalError, e.what());
} catch (...) {
SILK_ERROR << "unexpected exception processing request: " << request.dump();
reply = make_json_error(request, kServerError, "unexpected exception");
}

co_await tx->close(); // RAII not (yet) available with coroutines
}

} // namespace silkworm::rpc::commands
2 changes: 2 additions & 0 deletions silkworm/rpc/commands/eth_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class EthereumRpcApi {
Task<void> handle_eth_max_priority_fee_per_gas(const nlohmann::json& request, nlohmann::json& reply);
Task<void> handle_fee_history(const nlohmann::json& request, nlohmann::json& reply);
Task<void> handle_eth_call_many(const nlohmann::json& request, nlohmann::json& reply);
Task<void> handle_blob_base_fee(const nlohmann::json& request, nlohmann::json& reply);
Task<void> handle_base_fee(const nlohmann::json& request, nlohmann::json& reply);

// GLAZE format routine
Task<void> handle_eth_get_logs(const nlohmann::json& request, std::string& reply);
Expand Down
2 changes: 2 additions & 0 deletions silkworm/rpc/commands/rpc_api_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ void RpcApiTable::add_eth_handlers() {
method_handlers_[json_rpc::method::k_eth_maxPriorityFeePerGas] = &commands::RpcApi::handle_eth_max_priority_fee_per_gas;
method_handlers_[json_rpc::method::k_eth_feeHistory] = &commands::RpcApi::handle_fee_history;
method_handlers_[json_rpc::method::k_eth_callMany] = &commands::RpcApi::handle_eth_call_many;
method_handlers_[json_rpc::method::k_eth_baseFee] = &commands::RpcApi::handle_base_fee;
method_handlers_[json_rpc::method::k_eth_blobBaseFee] = &commands::RpcApi::handle_blob_base_fee;

// GLAZE methods
method_handlers_glaze_[json_rpc::method::k_eth_getLogs] = &commands::RpcApi::handle_eth_get_logs;
Expand Down
2 changes: 2 additions & 0 deletions silkworm/rpc/json_rpc/methods.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ inline constexpr const char* k_eth_getBlockReceipts{"eth_getBlockReceipts"};
inline constexpr const char* k_eth_getTransactionReceiptsByBlock{"eth_getTransactionReceiptsByBlock"};
inline constexpr const char* k_eth_maxPriorityFeePerGas{"eth_maxPriorityFeePerGas"};
inline constexpr const char* k_eth_feeHistory{"eth_feeHistory"};
inline constexpr const char* k_eth_blobBaseFee{"eth_blobBaseFee"};
inline constexpr const char* k_eth_baseFee{"eth_baseFee"};

inline constexpr const char* k_debug_accountRange{"debug_accountRange"};
inline constexpr const char* k_debug_getModifiedAccountsByNumber{"debug_getModifiedAccountsByNumber"};
Expand Down

0 comments on commit b3e4f2e

Please sign in to comment.