Skip to content

Commit 52872de

Browse files
committed
db: cache chain config in local kv::api
1 parent f5918b4 commit 52872de

6 files changed

+47
-7
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

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ namespace silkworm::db::kv::api {
2525

2626
DirectService::DirectService(ServiceRouter router, DataStoreRef data_store)
2727
: router_{router},
28-
data_store_{std::move(data_store)} {}
28+
data_store_{std::move(data_store)},
29+
shared_transaction_cache_{std::make_shared<LocalTransaction::Cache>()} {}
2930

3031
// rpc Version(google.protobuf.Empty) returns (types.VersionReply);
3132
Task<Version> DirectService::version() {
@@ -34,7 +35,7 @@ Task<Version> DirectService::version() {
3435

3536
// rpc Tx(stream Cursor) returns (stream Pair);
3637
Task<std::unique_ptr<Transaction>> DirectService::begin_transaction() {
37-
co_return std::make_unique<LocalTransaction>(data_store_);
38+
co_return std::make_unique<LocalTransaction>(data_store_, shared_transaction_cache_);
3839
}
3940

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

silkworm/db/kv/api/direct_service.hpp

+3
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

@@ -51,6 +52,8 @@ class DirectService : public Service {
5152

5253
//! The data store
5354
DataStoreRef data_store_;
55+
56+
std::shared_ptr<LocalTransaction::Cache> shared_transaction_cache_;
5457
};
5558

5659
} // 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

+16-1
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,8 +35,21 @@ namespace silkworm::db::kv::api {
3435

3536
class LocalTransaction : public BaseTransaction {
3637
public:
37-
explicit LocalTransaction(DataStoreRef data_store)
38+
class Cache {
39+
public:
40+
using ChainStorageCache = db::chain::LocalChainStorage::Cache;
41+
Cache() : chain_storage_cache_{std::make_shared<ChainStorageCache>()} {}
42+
std::shared_ptr<ChainStorageCache> chain_storage_cache() const { return chain_storage_cache_; }
43+
44+
private:
45+
std::shared_ptr<ChainStorageCache> chain_storage_cache_;
46+
};
47+
48+
LocalTransaction(
49+
DataStoreRef data_store,
50+
std::shared_ptr<Cache> cache)
3851
: data_store_{std::move(data_store)},
52+
cache_{std::move(cache)},
3953
tx_{data_store_.chaindata.access_ro().start_ro_tx()} {}
4054

4155
~LocalTransaction() override = default;
@@ -104,6 +118,7 @@ class LocalTransaction : public BaseTransaction {
104118
std::map<std::string, std::shared_ptr<CursorDupSort>> dup_cursors_;
105119

106120
DataStoreRef data_store_;
121+
std::shared_ptr<Cache> cache_;
107122
uint32_t last_cursor_id_{0};
108123
datastore::kvdb::ROTxnManaged tx_;
109124
uint64_t tx_id_{++next_tx_id_};

0 commit comments

Comments
 (0)