Skip to content

Commit

Permalink
rpcdaemon: trace_block/trace_block_transactions rework actions by wor…
Browse files Browse the repository at this point in the history
…ker thread (#1271)
  • Loading branch information
lupin012 authored Jun 22, 2023
1 parent 8361208 commit 685d782
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 85 deletions.
6 changes: 3 additions & 3 deletions silkworm/silkrpc/commands/ots_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ boost::asio::awaitable<void> OtsRpcApi::handle_ots_get_contract_creator(const nl
ethdb::TransactionDatabase tx_database{*tx};
auto block_with_hash = co_await core::read_block_by_number(*block_cache_, tx_database, block_found);

trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};
const auto result = co_await executor.trace_deploy_transaction(block_with_hash->block, contract_address);

reply = make_json_content(request["id"], result);
Expand Down Expand Up @@ -515,7 +515,7 @@ boost::asio::awaitable<void> OtsRpcApi::handle_ots_trace_transaction(const nlohm

try {
ethdb::TransactionDatabase tx_database{*tx};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};

const auto transaction_with_block = co_await core::read_transaction_by_hash(*block_cache_, tx_database, transaction_hash);

Expand Down Expand Up @@ -561,7 +561,7 @@ boost::asio::awaitable<void> OtsRpcApi::handle_ots_get_transaction_error(const n

try {
ethdb::TransactionDatabase tx_database{*tx};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};

const auto transaction_with_block = co_await core::read_transaction_by_hash(*block_cache_, tx_database, transaction_hash);

Expand Down
18 changes: 9 additions & 9 deletions silkworm/silkrpc/commands/trace_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ boost::asio::awaitable<void> TraceRpcApi::handle_trace_call(const nlohmann::json
const bool is_latest_block = co_await core::is_latest_block_number(block_with_hash->block.header.number, tx_database);
const core::rawdb::DatabaseReader& db_reader =
is_latest_block ? static_cast<core::rawdb::DatabaseReader&>(cached_database) : static_cast<core::rawdb::DatabaseReader&>(tx_database);
trace::TraceCallExecutor executor{*block_cache_, db_reader, workers_};
trace::TraceCallExecutor executor{*block_cache_, db_reader, workers_, *tx};
const auto result = co_await executor.trace_call(block_with_hash->block, call, config);

if (result.pre_check_error) {
Expand Down Expand Up @@ -103,7 +103,7 @@ boost::asio::awaitable<void> TraceRpcApi::handle_trace_call_many(const nlohmann:

const core::rawdb::DatabaseReader& db_reader =
is_latest_block ? static_cast<core::rawdb::DatabaseReader&>(cached_database) : static_cast<core::rawdb::DatabaseReader&>(tx_database);
trace::TraceCallExecutor executor{*block_cache_, db_reader, workers_};
trace::TraceCallExecutor executor{*block_cache_, db_reader, workers_, *tx};
const auto result = co_await executor.trace_calls(block_with_hash->block, trace_calls);

if (result.pre_check_error) {
Expand Down Expand Up @@ -187,7 +187,7 @@ boost::asio::awaitable<void> TraceRpcApi::handle_trace_raw_transaction(const nlo
const auto block_number = co_await core::get_latest_block_number(tx_database);
const auto block_with_hash = co_await core::read_block_by_number(*block_cache_, tx_database, block_number);

trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};
const auto result = co_await executor.trace_transaction(block_with_hash->block, transaction, config);

if (result.pre_check_error) {
Expand Down Expand Up @@ -228,7 +228,7 @@ boost::asio::awaitable<void> TraceRpcApi::handle_trace_replay_block_transactions

const auto block_with_hash = co_await core::read_block_by_number_or_hash(*block_cache_, tx_database, block_number_or_hash);

trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};
const auto result = co_await executor.trace_block_transactions(block_with_hash->block, config);
reply = make_json_content(request["id"], result);
} catch (const std::exception& e) {
Expand Down Expand Up @@ -267,7 +267,7 @@ boost::asio::awaitable<void> TraceRpcApi::handle_trace_replay_transaction(const
oss << "transaction 0x" << transaction_hash << " not found";
reply = make_json_error(request["id"], -32000, oss.str());
} else {
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};
const auto result = co_await executor.trace_transaction(tx_with_block->block_with_hash.block, tx_with_block->transaction, config);

if (result.pre_check_error) {
Expand Down Expand Up @@ -308,7 +308,7 @@ boost::asio::awaitable<void> TraceRpcApi::handle_trace_block(const nlohmann::jso

const auto block_with_hash = co_await core::read_block_by_number_or_hash(*block_cache_, tx_database, block_number_or_hash);

trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};
trace::Filter filter;
const auto result = co_await executor.trace_block(*block_with_hash, filter);
reply = make_json_content(request["id"], result);
Expand Down Expand Up @@ -348,7 +348,7 @@ boost::asio::awaitable<void> TraceRpcApi::handle_trace_filter(const nlohmann::js
try {
ethdb::TransactionDatabase tx_database{*tx};

trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};

co_await executor.trace_filter(trace_filter, &stream);
} catch (const std::exception& e) {
Expand Down Expand Up @@ -402,7 +402,7 @@ boost::asio::awaitable<void> TraceRpcApi::handle_trace_get(const nlohmann::json&
if (!tx_with_block) {
reply = make_json_content(request["id"]);
} else {
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};
const auto result = co_await executor.trace_transaction(tx_with_block->block_with_hash, tx_with_block->transaction);

uint16_t index = indices[0] + 1; // Erigon RpcDaemon compatibility
Expand Down Expand Up @@ -444,7 +444,7 @@ boost::asio::awaitable<void> TraceRpcApi::handle_trace_transaction(const nlohman
if (!tx_with_block) {
reply = make_json_content(request["id"]);
} else {
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_};
trace::TraceCallExecutor executor{*block_cache_, tx_database, workers_, *tx};
auto result = co_await executor.trace_transaction(tx_with_block->block_with_hash, tx_with_block->transaction);
reply = make_json_content(request["id"], result);
}
Expand Down
100 changes: 57 additions & 43 deletions silkworm/silkrpc/core/evm_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include <stack>
#include <string>

#include <boost/asio/compose.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <evmc/hex.hpp>
#include <evmc/instructions.h>
#include <evmone/execution_state.hpp>
Expand Down Expand Up @@ -1215,55 +1218,66 @@ awaitable<std::vector<TraceCallResult>> TraceCallExecutor::trace_block_transacti
auto chain_config_ptr = lookup_chain_config(chain_id);

auto current_executor = co_await boost::asio::this_coro::executor;
state::RemoteState remote_state{current_executor, database_reader_, block_number - 1};
IntraBlockState initial_ibs{remote_state};

StateAddresses state_addresses(initial_ibs);
std::shared_ptr<EvmTracer> ibsTracer = std::make_shared<trace::IntraBlockStateTracer>(state_addresses);
const auto call_result = co_await boost::asio::async_compose<decltype(boost::asio::use_awaitable), void(std::vector<TraceCallResult>)>(
[&](auto&& self) {
boost::asio::post(workers_, [&, self = std::move(self)]() mutable {
auto state = tx_.create_state(current_executor, database_reader_, block_number - 1);
IntraBlockState initial_ibs{*state};

state::RemoteState curr_remote_state{current_executor, database_reader_, block_number - 1};
EVMExecutor executor{*chain_config_ptr, workers_, curr_remote_state};
StateAddresses state_addresses(initial_ibs);
std::shared_ptr<EvmTracer> ibs_tracer = std::make_shared<trace::IntraBlockStateTracer>(state_addresses);

std::vector<TraceCallResult> trace_call_result(transactions.size());
for (std::uint64_t index = 0; index < transactions.size(); index++) {
silkworm::Transaction transaction{block.transactions[index]};
if (!transaction.from) {
transaction.recover_sender();
}
auto curr_state = tx_.create_state(current_executor, database_reader_, block_number - 1);
EVMExecutor executor{*chain_config_ptr, workers_, curr_state};

auto& result = trace_call_result.at(index);
TraceCallTraces& traces = result.traces;
auto hash{hash_of_transaction(transaction)};
traces.transaction_hash = silkworm::to_bytes32({hash.bytes, silkworm::kHashLength});
std::vector<TraceCallResult> trace_call_result(transactions.size());
for (std::uint64_t index = 0; index < transactions.size(); index++) {
silkworm::Transaction transaction{block.transactions[index]};
if (!transaction.from) {
transaction.recover_sender();
}

Tracers tracers;
if (config.vm_trace) {
traces.vm_trace.emplace();
std::shared_ptr<silkworm::EvmTracer> tracer = std::make_shared<trace::VmTraceTracer>(traces.vm_trace.value(), index);
tracers.push_back(tracer);
}
if (config.trace) {
std::shared_ptr<silkworm::EvmTracer> tracer = std::make_shared<trace::TraceTracer>(traces.trace, initial_ibs);
tracers.push_back(tracer);
}
if (config.state_diff) {
traces.state_diff.emplace();
auto& result = trace_call_result.at(index);
TraceCallTraces& traces = result.traces;
auto hash{hash_of_transaction(transaction)};
traces.transaction_hash = silkworm::to_bytes32({hash.bytes, silkworm::kHashLength});

std::shared_ptr<silkworm::EvmTracer> tracer = std::make_shared<trace::StateDiffTracer>(traces.state_diff.value(), state_addresses);
tracers.push_back(tracer);
}
Tracers tracers;
if (config.vm_trace) {
traces.vm_trace.emplace();
std::shared_ptr<silkworm::EvmTracer> tracer = std::make_shared<trace::VmTraceTracer>(traces.vm_trace.value(), index);
tracers.push_back(tracer);
}
if (config.trace) {
std::shared_ptr<silkworm::EvmTracer> tracer = std::make_shared<trace::TraceTracer>(traces.trace, initial_ibs);
tracers.push_back(tracer);
}
if (config.state_diff) {
traces.state_diff.emplace();

tracers.push_back(ibsTracer);
std::shared_ptr<silkworm::EvmTracer> tracer = std::make_shared<trace::StateDiffTracer>(traces.state_diff.value(), state_addresses);
tracers.push_back(tracer);
}

auto execution_result = co_await executor.call(block, transaction, tracers, /*refund=*/true, /*gas_bailout=*/true);
if (execution_result.pre_check_error) {
result.pre_check_error = execution_result.pre_check_error.value();
} else {
traces.output = "0x" + silkworm::to_hex(execution_result.data);
}
executor.reset();
}
co_return trace_call_result;
tracers.push_back(ibs_tracer);

auto execution_result = executor.call_sync(block, transaction, tracers, /*refund=*/true, /*gas_bailout=*/true);
if (execution_result.pre_check_error) {
result.pre_check_error = execution_result.pre_check_error.value();
} else {
traces.output = "0x" + silkworm::to_hex(execution_result.data);
}
executor.reset();
}
boost::asio::post(current_executor, [trace_call_result, self = std::move(self)]() mutable {
self.complete(trace_call_result);
});
});
},
boost::asio::use_awaitable);

co_return call_result;
}

awaitable<TraceCallResult> TraceCallExecutor::trace_call(const silkworm::Block& block, const Call& call, const TraceConfig& config) {
Expand All @@ -1289,7 +1303,7 @@ awaitable<TraceManyCallResult> TraceCallExecutor::trace_calls(const silkworm::Bl
state::RemoteState curr_remote_state{current_executor, database_reader_, block_number};
EVMExecutor executor{*chain_config_ptr, workers_, remote_state};

std::shared_ptr<silkworm::EvmTracer> ibsTracer = std::make_shared<trace::IntraBlockStateTracer>(state_addresses);
std::shared_ptr<silkworm::EvmTracer> ibs_tracer = std::make_shared<trace::IntraBlockStateTracer>(state_addresses);

TraceManyCallResult result;
for (std::size_t index{0}; index < calls.size(); index++) {
Expand All @@ -1314,7 +1328,7 @@ awaitable<TraceManyCallResult> TraceCallExecutor::trace_calls(const silkworm::Bl
std::shared_ptr<silkworm::EvmTracer> tracer = std::make_shared<trace::StateDiffTracer>(traces.state_diff.value(), state_addresses);
tracers.push_back(tracer);
}
tracers.push_back(ibsTracer);
tracers.push_back(ibs_tracer);

auto execution_result = co_await executor.call(block, transaction, tracers, /*refund=*/true, /*gas_bailout=*/true);

Expand Down
7 changes: 5 additions & 2 deletions silkworm/silkrpc/core/evm_trace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <silkworm/silkrpc/common/block_cache.hpp>
#include <silkworm/silkrpc/core/evm_executor.hpp>
#include <silkworm/silkrpc/core/rawdb/accessors.hpp>
#include <silkworm/silkrpc/ethdb/transaction.hpp>
#include <silkworm/silkrpc/json/stream.hpp>
#include <silkworm/silkrpc/types/block.hpp>
#include <silkworm/silkrpc/types/call.hpp>
Expand Down Expand Up @@ -422,8 +423,9 @@ class TraceCallExecutor {
public:
explicit TraceCallExecutor(silkworm::BlockCache& block_cache,
const core::rawdb::DatabaseReader& database_reader,
boost::asio::thread_pool& workers)
: block_cache_(block_cache), database_reader_(database_reader), workers_{workers} {}
boost::asio::thread_pool& workers,
ethdb::Transaction& tx)
: block_cache_(block_cache), database_reader_(database_reader), workers_{workers}, tx_{tx} {}
virtual ~TraceCallExecutor() = default;

TraceCallExecutor(const TraceCallExecutor&) = delete;
Expand All @@ -449,6 +451,7 @@ class TraceCallExecutor {
silkworm::BlockCache& block_cache_;
const core::rawdb::DatabaseReader& database_reader_;
boost::asio::thread_pool& workers_;
ethdb::Transaction& tx_;
};

} // namespace silkworm::rpc::trace
Loading

0 comments on commit 685d782

Please sign in to comment.