Skip to content

Commit

Permalink
move LocalState/RemoteState to execution
Browse files Browse the repository at this point in the history
  • Loading branch information
battlmonstr committed Dec 4, 2024
1 parent 572dde9 commit a66c6e7
Show file tree
Hide file tree
Showing 28 changed files with 146 additions and 155 deletions.
1 change: 1 addition & 0 deletions silkworm/db/kv/api/base_transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class BaseTransaction : public Transaction {
public:
explicit BaseTransaction(StateCache* state_cache) : state_cache_{state_cache} {}

bool is_local() const override { return false; }
void set_state_cache_enabled(bool cache_enabled) override;

Task<KeyValue> get(const std::string& table, ByteView key) override;
Expand Down
6 changes: 0 additions & 6 deletions silkworm/db/kv/api/local_transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "local_transaction.hpp"

#include <silkworm/db/chain/local_chain_storage.hpp>
#include <silkworm/db/state/local_state.hpp>

namespace silkworm::db::kv::api {

Expand Down Expand Up @@ -60,11 +59,6 @@ Task<std::shared_ptr<CursorDupSort>> LocalTransaction::get_cursor(const std::str
co_return cursor;
}

std::shared_ptr<State> LocalTransaction::create_state(boost::asio::any_io_executor&, const chain::ChainStorage&, BlockNum block_num) {
// The calling thread *must* be *different* from the one which created this LocalTransaction instance
return std::make_shared<state::LocalState>(block_num, data_store_);
}

std::shared_ptr<chain::ChainStorage> LocalTransaction::create_storage() {
// The calling thread *must* be the *same* which created this LocalTransaction instance
return std::make_shared<chain::LocalChainStorage>(DataModel{txn_, data_store_.blocks_repository});
Expand Down
3 changes: 2 additions & 1 deletion silkworm/db/kv/api/local_transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class LocalTransaction : public BaseTransaction {

Task<std::shared_ptr<CursorDupSort>> cursor_dup_sort(const std::string& table) override;

std::shared_ptr<State> create_state(boost::asio::any_io_executor& executor, const chain::ChainStorage& storage, BlockNum block_num) override;
bool is_local() const override { return true; }
DataStoreRef data_store() const { return data_store_; }

std::shared_ptr<chain::ChainStorage> create_storage() override;

Expand Down
3 changes: 1 addition & 2 deletions silkworm/db/kv/api/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

#include <silkworm/core/common/base.hpp>
#include <silkworm/core/common/util.hpp>
#include <silkworm/core/state/state.hpp>
#include <silkworm/db/chain/chain_storage.hpp>

#include "cursor.hpp"
Expand Down Expand Up @@ -55,7 +54,7 @@ class Transaction {

virtual Task<std::shared_ptr<CursorDupSort>> cursor_dup_sort(const std::string& table) = 0;

virtual std::shared_ptr<State> create_state(boost::asio::any_io_executor& executor, const chain::ChainStorage& storage, BlockNum block_num) = 0;
virtual bool is_local() const = 0;

virtual std::shared_ptr<chain::ChainStorage> create_storage() = 0;

Expand Down
5 changes: 0 additions & 5 deletions silkworm/db/kv/grpc/client/remote_transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

#include <silkworm/db/chain/remote_chain_storage.hpp>
#include <silkworm/db/kv/txn_num.hpp>
#include <silkworm/db/state/remote_state.hpp>
#include <silkworm/infra/grpc/client/call.hpp>
#include <silkworm/infra/grpc/common/errors.hpp>
#include <silkworm/infra/grpc/common/util.hpp>
Expand Down Expand Up @@ -109,10 +108,6 @@ Task<std::shared_ptr<api::CursorDupSort>> RemoteTransaction::get_cursor(const st
co_return cursor;
}

std::shared_ptr<silkworm::State> RemoteTransaction::create_state(boost::asio::any_io_executor& executor, const chain::ChainStorage& storage, BlockNum block_num) {
return std::make_shared<db::state::RemoteState>(executor, *this, storage, block_num);
}

std::shared_ptr<chain::ChainStorage> RemoteTransaction::create_storage() {
return std::make_shared<chain::RemoteChainStorage>(*this, providers_);
}
Expand Down
2 changes: 0 additions & 2 deletions silkworm/db/kv/grpc/client/remote_transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ class RemoteTransaction : public api::BaseTransaction {

Task<std::shared_ptr<api::CursorDupSort>> cursor_dup_sort(const std::string& table) override;

std::shared_ptr<silkworm::State> create_state(boost::asio::any_io_executor& executor, const chain::ChainStorage& storage, BlockNum block_num) override;

std::shared_ptr<chain::ChainStorage> create_storage() override;

Task<TxnId> first_txn_num_in_block(BlockNum block_num) override;
Expand Down
3 changes: 1 addition & 2 deletions silkworm/db/test_util/mock_transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ class MockTransaction : public kv::api::Transaction {
MOCK_METHOD((Task<void>), open, (), (override));
MOCK_METHOD((Task<std::shared_ptr<kv::api::Cursor>>), cursor, (const std::string&), (override));
MOCK_METHOD((Task<std::shared_ptr<kv::api::CursorDupSort>>), cursor_dup_sort, (const std::string&), (override));
MOCK_METHOD((std::shared_ptr<State>), create_state,
(boost::asio::any_io_executor&, const chain::ChainStorage&, BlockNum), (override));
bool is_local() const override { return false; }
MOCK_METHOD((std::shared_ptr<chain::ChainStorage>), create_storage, (), (override));
MOCK_METHOD((Task<TxnId>), first_txn_num_in_block, (BlockNum), (override));
MOCK_METHOD((Task<void>), close, (), (override));
Expand Down
4 changes: 4 additions & 0 deletions silkworm/execution/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ include("${SILKWORM_MAIN_DIR}/cmake/common/targets.cmake")

find_package(asio-grpc REQUIRED)
find_package(gRPC REQUIRED)
find_package(GTest REQUIRED)

# cmake-format: off
set(LIBS_PRIVATE
Expand All @@ -31,6 +32,7 @@ set(LIBS_PUBLIC
asio-grpc::asio-grpc
silkworm_core
silkworm_infra
silkworm_db
)
# cmake-format: on

Expand All @@ -39,3 +41,5 @@ silkworm_library(
PUBLIC ${LIBS_PUBLIC}
PRIVATE ${LIBS_PRIVATE}
)

target_link_libraries(silkworm_execution_test PRIVATE GTest::gmock silkworm_infra_test_util)
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#include <silkworm/core/common/util.hpp>

namespace silkworm::db::state {
namespace silkworm::execution {

std::optional<Account> LocalState::read_account(const evmc::address& address) const noexcept {
return db::read_account(txn_, address, block_num_ + 1);
Expand Down Expand Up @@ -66,4 +66,4 @@ std::optional<evmc::bytes32> LocalState::canonical_hash(BlockNum block_num) cons
return data_model_.read_canonical_header_hash(block_num);
}

} // namespace silkworm::db::state
} // namespace silkworm::execution
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@
#include <silkworm/core/common/util.hpp>
#include <silkworm/core/state/state.hpp>
#include <silkworm/db/access_layer.hpp>
#include <silkworm/db/data_store.hpp>
#include <silkworm/db/datastore/mdbx/mdbx.hpp>

#include "../data_store.hpp"

namespace silkworm::db::state {
namespace silkworm::execution {

class LocalState : public State {
public:
explicit LocalState(BlockNum block_num, DataStoreRef data_store)
explicit LocalState(BlockNum block_num, db::DataStoreRef data_store)
: block_num_{block_num},
txn_{data_store.chaindata.start_ro_tx()},
data_model_{txn_, data_store.blocks_repository} {}
Expand Down Expand Up @@ -97,4 +96,4 @@ class LocalState : public State {
db::DataModel data_model_;
};

} // namespace silkworm::db::state
} // namespace silkworm::execution
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <silkworm/core/types/evmc_bytes32.hpp>
#include <silkworm/infra/common/log.hpp>

namespace silkworm::db::state {
namespace silkworm::execution {

std::unordered_map<evmc::bytes32, Bytes> AsyncRemoteState::code_;

Expand Down Expand Up @@ -172,4 +172,4 @@ std::optional<evmc::bytes32> RemoteState::canonical_hash(BlockNum /*block_num*/)
throw std::logic_error{"RemoteState::canonical_hash not yet implemented"};
}

} // namespace silkworm::db::state
} // namespace silkworm::execution
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@
#include <silkworm/db/kv/api/transaction.hpp>
#include <silkworm/db/kv/state_reader.hpp>

namespace silkworm::db::state {
namespace silkworm::execution {

class AsyncRemoteState {
public:
explicit AsyncRemoteState(kv::api::Transaction& tx, const chain::ChainStorage& storage, BlockNum block_num)
explicit AsyncRemoteState(
db::kv::api::Transaction& tx,
const db::chain::ChainStorage& storage,
BlockNum block_num)
: storage_(storage), state_reader_(tx, block_num + 1) {}

Task<std::optional<Account>> read_account(const evmc::address& address) const noexcept;
Expand All @@ -62,13 +65,17 @@ class AsyncRemoteState {
private:
static std::unordered_map<evmc::bytes32, Bytes> code_;

const chain::ChainStorage& storage_;
kv::StateReader state_reader_;
const db::chain::ChainStorage& storage_;
db::kv::StateReader state_reader_;
};

class RemoteState : public State {
public:
explicit RemoteState(boost::asio::any_io_executor& executor, kv::api::Transaction& tx, const chain::ChainStorage& storage, BlockNum block_num)
explicit RemoteState(
boost::asio::any_io_executor& executor,
db::kv::api::Transaction& tx,
const db::chain::ChainStorage& storage,
BlockNum block_num)
: executor_(executor), async_state_{tx, storage, block_num} {}

std::optional<Account> read_account(const evmc::address& address) const noexcept override;
Expand Down Expand Up @@ -130,4 +137,4 @@ class RemoteState : public State {

std::ostream& operator<<(std::ostream& out, const RemoteState& s);

} // namespace silkworm::db::state
} // namespace silkworm::execution
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include <silkworm/infra/common/log.hpp>
#include <silkworm/infra/test_util/context_test_base.hpp>

namespace silkworm::db::state {
namespace silkworm::execution {

using testing::_;
using testing::Invoke;
Expand All @@ -50,7 +50,7 @@ TEST_CASE_METHOD(RemoteStateTest, "async remote buffer", "[rpc][core][remote_buf
const evmc::address address{0x0715a7794a1dc8e42615f059dd6e406a6594651a_address};

SECTION("read_code for empty hash") {
EXPECT_CALL(transaction, get_one(table::kCodeName, _))
EXPECT_CALL(transaction, get_one(db::table::kCodeName, _))
.WillRepeatedly(InvokeWithoutArgs([]() -> Task<Bytes> {
co_return Bytes{};
}));
Expand Down Expand Up @@ -374,7 +374,7 @@ TEST_CASE_METHOD(RemoteStateTest, "async remote buffer", "[rpc][core][remote_buf
}

SECTION("AsyncRemoteState::canonical_hash for empty response from chain storage") {
EXPECT_CALL(transaction, get_one(table::kCanonicalHashesName, _))
EXPECT_CALL(transaction, get_one(db::table::kCanonicalHashesName, _))
.WillRepeatedly(InvokeWithoutArgs([=]() -> Task<Bytes> {
co_return Bytes{};
}));
Expand Down Expand Up @@ -406,4 +406,4 @@ TEST_CASE_METHOD(RemoteStateTest, "RemoteState") {
}
#endif // SILKWORM_SANITIZE

} // namespace silkworm::db::state
} // namespace silkworm::execution
39 changes: 39 additions & 0 deletions silkworm/execution/state_factory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
Copyright 2024 The Silkworm Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "state_factory.hpp"

#include <silkworm/db/kv/api/local_transaction.hpp>
#include <silkworm/db/kv/grpc/client/remote_transaction.hpp>

#include "local_state.hpp"
#include "remote_state.hpp"

namespace silkworm::execution {

std::shared_ptr<State> StateFactory::create_state(
boost::asio::any_io_executor& executor,
const db::chain::ChainStorage& storage,
BlockNum block_num) {
if (tx.is_local()) {
auto& local_tx = dynamic_cast<db::kv::api::LocalTransaction&>(tx);
return std::make_shared<LocalState>(block_num, local_tx.data_store());
} else {
return std::make_shared<RemoteState>(executor, tx, storage, block_num);
}
}

} // namespace silkworm::execution
39 changes: 39 additions & 0 deletions silkworm/execution/state_factory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
Copyright 2024 The Silkworm Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#pragma once

#include <memory>

#include <boost/asio/any_io_executor.hpp>

#include <silkworm/core/common/base.hpp>
#include <silkworm/core/state/state.hpp>
#include <silkworm/db/chain/chain_storage.hpp>
#include <silkworm/db/kv/api/transaction.hpp>

namespace silkworm::execution {

struct StateFactory {
db::kv::api::Transaction& tx;

std::shared_ptr<State> create_state(
boost::asio::any_io_executor& executor,
const db::chain::ChainStorage& storage,
BlockNum block_num);
};

} // namespace silkworm::execution
4 changes: 0 additions & 4 deletions silkworm/rpc/commands/debug_api_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,6 @@ class DummyTransaction : public db::kv::api::BaseTransaction {
co_return cursor;
}

std::shared_ptr<silkworm::State> create_state(boost::asio::any_io_executor&, const ChainStorage&, BlockNum) override {
return nullptr;
}

std::shared_ptr<ChainStorage> create_storage() override {
return nullptr;
}
Expand Down
7 changes: 4 additions & 3 deletions silkworm/rpc/commands/eth_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <silkworm/core/types/transaction.hpp>
#include <silkworm/db/kv/state_reader.hpp>
#include <silkworm/db/util.hpp>
#include <silkworm/execution/state_factory.hpp>
#include <silkworm/infra/common/clock_time.hpp>
#include <silkworm/infra/common/log.hpp>
#include <silkworm/rpc/common/util.hpp>
Expand Down Expand Up @@ -1156,7 +1157,7 @@ Task<void> EthereumRpcApi::handle_eth_call(const nlohmann::json& request, std::s

const auto execution_result = co_await EVMExecutor::call(
chain_config, *chain_storage, workers_, block_with_hash->block, txn, [&tx](auto& io_executor, auto block_num1, auto& storage) {
return tx->create_state(io_executor, storage, block_num1);
return execution::StateFactory{*tx}.create_state(io_executor, storage, block_num1);
});

if (execution_result.success()) {
Expand Down Expand Up @@ -1343,7 +1344,7 @@ Task<void> EthereumRpcApi::handle_eth_create_access_list(const nlohmann::json& r
while (true) {
const auto execution_result = co_await EVMExecutor::call(
chain_config, *chain_storage, workers_, block_with_hash->block, txn, [&](auto& io_executor, auto block_num, auto& storage) {
return tx->create_state(io_executor, storage, block_num);
return execution::StateFactory{*tx}.create_state(io_executor, storage, block_num);
},
tracers, /* refund */ true, /* gasBailout */ false);

Expand Down Expand Up @@ -1438,7 +1439,7 @@ Task<void> EthereumRpcApi::handle_eth_call_bundle(const nlohmann::json& request,

const auto execution_result = co_await EVMExecutor::call(
chain_config, *chain_storage, workers_, block_with_hash->block, tx_with_block->transaction, [&](auto& io_executor, auto block_num, auto& storage) {
return tx->create_state(io_executor, storage, block_num);
return execution::StateFactory{*tx}.create_state(io_executor, storage, block_num);
});
if (execution_result.pre_check_error) {
reply = make_json_error(request, kServerError, execution_result.pre_check_error.value());
Expand Down
4 changes: 0 additions & 4 deletions silkworm/rpc/core/account_dumper_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,6 @@ class DummyTransaction : public BaseTransaction {
co_return cursor;
}

std::shared_ptr<silkworm::State> create_state(boost::asio::any_io_executor&, const ChainStorage&, BlockNum) override {
return nullptr;
}

std::shared_ptr<ChainStorage> create_storage() override {
return nullptr;
}
Expand Down
Loading

0 comments on commit a66c6e7

Please sign in to comment.