Skip to content

Commit 57237ce

Browse files
committed
db: cache chain config in local kv::api
1 parent af456b3 commit 57237ce

6 files changed

+51
-10
lines changed

silkworm/db/chain/local_chain_storage.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,18 @@
2323

2424
namespace silkworm::db::chain {
2525

26+
LocalChainStorage::LocalChainStorage(
27+
db::DataModel data_model,
28+
std::shared_ptr<Cache> cache)
29+
: data_model_{data_model},
30+
cache_{cache} {
31+
std::call_once(cache_->chain_config_once_flag, [this] {
32+
cache_->chain_config = data_model_.read_chain_config();
33+
});
34+
}
35+
2636
Task<ChainConfig> LocalChainStorage::read_chain_config() const {
27-
const auto chain_config{data_model_.read_chain_config()};
37+
const auto chain_config = cache_->chain_config;
2838
if (!chain_config) {
2939
throw std::runtime_error{"empty chain config data in storage"};
3040
}

silkworm/db/chain/local_chain_storage.hpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#pragma once
1818

19+
#include <mutex>
20+
1921
#include <silkworm/db/access_layer.hpp>
2022

2123
#include "chain_storage.hpp"
@@ -26,8 +28,14 @@ namespace silkworm::db::chain {
2628
//! in local database (accessed via MDBX API) or local snapshot files (accessed via custom snapshot API)
2729
class LocalChainStorage : public ChainStorage {
2830
public:
29-
explicit LocalChainStorage(db::DataModel data_model)
30-
: data_model_{data_model} {}
31+
struct Cache {
32+
std::optional<ChainConfig> chain_config;
33+
std::once_flag chain_config_once_flag;
34+
};
35+
36+
LocalChainStorage(
37+
db::DataModel data_model,
38+
std::shared_ptr<Cache> cache);
3139
~LocalChainStorage() override = default;
3240

3341
Task<ChainConfig> read_chain_config() const override;
@@ -74,6 +82,7 @@ class LocalChainStorage : public ChainStorage {
7482

7583
private:
7684
db::DataModel data_model_;
85+
std::shared_ptr<Cache> cache_;
7786
};
7887

7988
} // namespace silkworm::db::chain

silkworm/db/kv/api/direct_service.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace silkworm::db::kv::api {
2626
DirectService::DirectService(ServiceRouter router, DataStoreRef data_store, StateCache* state_cache)
2727
: router_{router},
2828
data_store_{std::move(data_store)},
29-
state_cache_{state_cache} {}
29+
shared_transaction_cache_{std::make_shared<LocalTransaction::Cache>(state_cache)} {}
3030

3131
// rpc Version(google.protobuf.Empty) returns (types.VersionReply);
3232
Task<Version> DirectService::version() {
@@ -35,7 +35,7 @@ Task<Version> DirectService::version() {
3535

3636
// rpc Tx(stream Cursor) returns (stream Pair);
3737
Task<std::unique_ptr<Transaction>> DirectService::begin_transaction() {
38-
co_return std::make_unique<LocalTransaction>(data_store_, state_cache_);
38+
co_return std::make_unique<LocalTransaction>(data_store_, shared_transaction_cache_);
3939
}
4040

4141
// rpc StateChanges(StateChangeRequest) returns (stream StateChangeBatch);

silkworm/db/kv/api/direct_service.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <silkworm/db/data_store.hpp>
2020

21+
#include "local_transaction.hpp"
2122
#include "service.hpp"
2223
#include "service_router.hpp"
2324

@@ -52,8 +53,7 @@ class DirectService : public Service {
5253
//! The data store
5354
DataStoreRef data_store_;
5455

55-
//! The local state cache built upon incoming state changes
56-
StateCache* state_cache_;
56+
std::shared_ptr<LocalTransaction::Cache> shared_transaction_cache_;
5757
};
5858

5959
} // namespace silkworm::db::kv::api

silkworm/db/kv/api/local_transaction.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ Task<std::shared_ptr<CursorDupSort>> LocalTransaction::get_cursor(const std::str
138138

139139
std::shared_ptr<chain::ChainStorage> LocalTransaction::create_storage() {
140140
// The calling thread *must* be the *same* which created this LocalTransaction instance
141-
return std::make_shared<chain::LocalChainStorage>(DataModel{tx_, data_store_.blocks_repository});
141+
return std::make_shared<chain::LocalChainStorage>(
142+
DataModel{tx_, data_store_.blocks_repository},
143+
cache_->chain_storage_cache());
142144
}
143145

144146
Task<TxnId> LocalTransaction::first_txn_num_in_block(BlockNum block_num) {

silkworm/db/kv/api/local_transaction.hpp

+22-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include <silkworm/infra/concurrency/task.hpp>
2626

27+
#include <silkworm/db/chain/local_chain_storage.hpp>
2728
#include <silkworm/db/data_store.hpp>
2829

2930
#include "base_transaction.hpp"
@@ -34,9 +35,27 @@ namespace silkworm::db::kv::api {
3435

3536
class LocalTransaction : public BaseTransaction {
3637
public:
37-
LocalTransaction(DataStoreRef data_store, StateCache* state_cache)
38-
: BaseTransaction(state_cache),
38+
class Cache {
39+
public:
40+
using ChainStorageCache = db::chain::LocalChainStorage::Cache;
41+
explicit Cache(StateCache* state_cache)
42+
: state_cache_{state_cache},
43+
chain_storage_cache_{std::make_shared<ChainStorageCache>()} {}
44+
StateCache* state_cache() const { return state_cache_; }
45+
std::shared_ptr<ChainStorageCache> chain_storage_cache() const { return chain_storage_cache_; }
46+
47+
private:
48+
//! The local state cache built upon incoming state changes
49+
StateCache* state_cache_;
50+
std::shared_ptr<ChainStorageCache> chain_storage_cache_;
51+
};
52+
53+
LocalTransaction(
54+
DataStoreRef data_store,
55+
std::shared_ptr<Cache> cache)
56+
: BaseTransaction{cache->state_cache()},
3957
data_store_{std::move(data_store)},
58+
cache_{std::move(cache)},
4059
tx_{data_store_.chaindata.access_ro().start_ro_tx()} {}
4160

4261
~LocalTransaction() override = default;
@@ -105,6 +124,7 @@ class LocalTransaction : public BaseTransaction {
105124
std::map<std::string, std::shared_ptr<CursorDupSort>> dup_cursors_;
106125

107126
DataStoreRef data_store_;
127+
std::shared_ptr<Cache> cache_;
108128
uint32_t last_cursor_id_{0};
109129
datastore::kvdb::ROTxnManaged tx_;
110130
uint64_t tx_id_{++next_tx_id_};

0 commit comments

Comments
 (0)