From 34f80e8f1b8c073effc4c39f33ebedcf2e951b18 Mon Sep 17 00:00:00 2001
From: Marat S <dungeon666master@protonmail.com>
Date: Sat, 15 Feb 2025 16:17:13 +0000
Subject: [PATCH 1/3] enable bloom filters for celldb

---
 tddb/td/db/RocksDb.cpp                | 4 ++++
 tddb/td/db/RocksDb.h                  | 1 +
 validator-engine/validator-engine.cpp | 7 +++++++
 validator-engine/validator-engine.hpp | 4 ++++
 validator/db/celldb.cpp               | 1 +
 validator/validator-options.hpp       | 7 +++++++
 validator/validator.h                 | 2 ++
 7 files changed, 26 insertions(+)

diff --git a/tddb/td/db/RocksDb.cpp b/tddb/td/db/RocksDb.cpp
index f1aa64a5d..993da2dba 100644
--- a/tddb/td/db/RocksDb.cpp
+++ b/tddb/td/db/RocksDb.cpp
@@ -24,6 +24,7 @@
 #include "rocksdb/write_batch.h"
 #include "rocksdb/utilities/optimistic_transaction_db.h"
 #include "rocksdb/utilities/transaction.h"
+#include "rocksdb/filter_policy.h"
 
 namespace td {
 namespace {
@@ -75,6 +76,9 @@ Result<RocksDb> RocksDb::open(std::string path, RocksDbOptions options) {
     } else {
       table_options.block_cache = options.block_cache;
     }
+    if (options.enable_bloom_filter) {
+      table_options.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false));
+    }
     db_options.table_factory.reset(rocksdb::NewBlockBasedTableFactory(table_options));
 
     db_options.use_direct_reads = options.use_direct_reads;
diff --git a/tddb/td/db/RocksDb.h b/tddb/td/db/RocksDb.h
index 499a33281..26f733a3b 100644
--- a/tddb/td/db/RocksDb.h
+++ b/tddb/td/db/RocksDb.h
@@ -63,6 +63,7 @@ struct RocksDbOptions {
   std::shared_ptr<RocksDbSnapshotStatistics> snapshot_statistics = nullptr;
   bool use_direct_reads = false;
   bool no_block_cache = false;
+  bool enable_bloom_filter = false;
 };
 
 class RocksDb : public KeyValue {
diff --git a/validator-engine/validator-engine.cpp b/validator-engine/validator-engine.cpp
index cc7c57b35..5585f7f0e 100644
--- a/validator-engine/validator-engine.cpp
+++ b/validator-engine/validator-engine.cpp
@@ -1466,6 +1466,7 @@ td::Status ValidatorEngine::load_global_config() {
   }
   validator_options_.write().set_celldb_compress_depth(celldb_compress_depth_);
   validator_options_.write().set_celldb_in_memory(celldb_in_memory_);
+  validator_options_.write().set_celldb_disable_bloom_filter(celldb_disable_bloom_filter_);
   validator_options_.write().set_max_open_archive_files(max_open_archive_files_);
   validator_options_.write().set_archive_preload_period(archive_preload_period_);
   validator_options_.write().set_disable_rocksdb_stats(disable_rocksdb_stats_);
@@ -4520,6 +4521,12 @@ int main(int argc, char *argv[]) {
       [&]() {
         acts.push_back([&x]() { td::actor::send_closure(x, &ValidatorEngine::set_celldb_in_memory, true); });
       });
+  p.add_option(
+      '\0', "celldb-disable-bloom-filter",
+      "disable using bloom filter in CellDb. Enabled bloom filter reduces read latency, but increases memory usage", 
+      [&]() {
+        acts.push_back([&x]() { td::actor::send_closure(x, &ValidatorEngine::set_celldb_disable_bloom_filter, true); });
+      });
   p.add_checked_option(
       '\0', "catchain-max-block-delay", "delay before creating a new catchain block, in seconds (default: 0.4)",
       [&](td::Slice s) -> td::Status {
diff --git a/validator-engine/validator-engine.hpp b/validator-engine/validator-engine.hpp
index b7abb0b1c..2b81381cf 100644
--- a/validator-engine/validator-engine.hpp
+++ b/validator-engine/validator-engine.hpp
@@ -218,6 +218,7 @@ class ValidatorEngine : public td::actor::Actor {
   bool celldb_direct_io_ = false;
   bool celldb_preload_all_ = false;
   bool celldb_in_memory_ = false;
+  bool celldb_disable_bloom_filter_ = false;
   td::optional<double> catchain_max_block_delay_, catchain_max_block_delay_slow_;
   bool read_config_ = false;
   bool started_keyring_ = false;
@@ -307,6 +308,9 @@ class ValidatorEngine : public td::actor::Actor {
   void set_celldb_in_memory(bool value) {
     celldb_in_memory_ = value;
   }
+  void set_celldb_disable_bloom_filter(bool value) {
+    celldb_disable_bloom_filter_ = value;
+  }
   void set_catchain_max_block_delay(double value) {
     catchain_max_block_delay_ = value;
   }
diff --git a/validator/db/celldb.cpp b/validator/db/celldb.cpp
index 9dcecdb35..8a619a530 100644
--- a/validator/db/celldb.cpp
+++ b/validator/db/celldb.cpp
@@ -101,6 +101,7 @@ void CellDbIn::start_up() {
     LOG(WARNING) << "Set CellDb block cache size to " << td::format::as_size(opts_->get_celldb_cache_size().value());
   }
   db_options.use_direct_reads = opts_->get_celldb_direct_io();
+  db_options.enable_bloom_filter = !opts_->get_celldb_disable_bloom_filter();
 
   if (opts_->get_celldb_in_memory()) {
     td::RocksDbOptions read_db_options;
diff --git a/validator/validator-options.hpp b/validator/validator-options.hpp
index e958d8864..1b657e008 100644
--- a/validator/validator-options.hpp
+++ b/validator/validator-options.hpp
@@ -139,6 +139,9 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
   bool get_celldb_in_memory() const override {
     return celldb_in_memory_;
   }
+  bool get_celldb_disable_bloom_filter() const override {
+    return celldb_disable_bloom_filter_;
+  }
   td::optional<double> get_catchain_max_block_delay() const override {
     return catchain_max_block_delay_;
   }
@@ -234,6 +237,9 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
   void set_celldb_in_memory(bool value) override {
     celldb_in_memory_ = value;
   }
+  void set_celldb_disable_bloom_filter(bool value) override {
+    celldb_disable_bloom_filter_ = value;
+  }
   void set_catchain_max_block_delay(double value) override {
     catchain_max_block_delay_ = value;
   }
@@ -298,6 +304,7 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions {
   bool celldb_direct_io_ = false;
   bool celldb_preload_all_ = false;
   bool celldb_in_memory_ = false;
+  bool celldb_disable_bloom_filter_ = false;
   td::optional<double> catchain_max_block_delay_, catchain_max_block_delay_slow_;
   bool state_serializer_enabled_ = true;
   td::Ref<CollatorOptions> collator_options_{true};
diff --git a/validator/validator.h b/validator/validator.h
index 73065aa98..0d571f3f1 100644
--- a/validator/validator.h
+++ b/validator/validator.h
@@ -110,6 +110,7 @@ struct ValidatorManagerOptions : public td::CntObject {
   virtual td::optional<td::uint64> get_celldb_cache_size() const = 0;
   virtual bool get_celldb_direct_io() const = 0;
   virtual bool get_celldb_preload_all() const = 0;
+  virtual bool get_celldb_disable_bloom_filter() const = 0;
   virtual td::optional<double> get_catchain_max_block_delay() const = 0;
   virtual td::optional<double> get_catchain_max_block_delay_slow() const = 0;
   virtual bool get_state_serializer_enabled() const = 0;
@@ -142,6 +143,7 @@ struct ValidatorManagerOptions : public td::CntObject {
   virtual void set_celldb_direct_io(bool value) = 0;
   virtual void set_celldb_preload_all(bool value) = 0;
   virtual void set_celldb_in_memory(bool value) = 0;
+  virtual void set_celldb_disable_bloom_filter(bool value) = 0;
   virtual void set_catchain_max_block_delay(double value) = 0;
   virtual void set_catchain_max_block_delay_slow(double value) = 0;
   virtual void set_state_serializer_enabled(bool value) = 0;

From 7f1ee5e9e11bf4790f5c57546d71c315e3089e4d Mon Sep 17 00:00:00 2001
From: Marat S <dungeon666master@protonmail.com>
Date: Fri, 28 Feb 2025 23:57:45 +0000
Subject: [PATCH 2/3] 2 level index and filter for state ttl >= 30 days

---
 tddb/td/db/RocksDb.cpp  | 6 ++++++
 tddb/td/db/RocksDb.h    | 1 +
 validator/db/celldb.cpp | 2 ++
 3 files changed, 9 insertions(+)

diff --git a/tddb/td/db/RocksDb.cpp b/tddb/td/db/RocksDb.cpp
index 993da2dba..803e18c47 100644
--- a/tddb/td/db/RocksDb.cpp
+++ b/tddb/td/db/RocksDb.cpp
@@ -78,6 +78,12 @@ Result<RocksDb> RocksDb::open(std::string path, RocksDbOptions options) {
     }
     if (options.enable_bloom_filter) {
       table_options.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false));
+      if (options.two_level_index_and_filter) {
+        table_options.index_type = rocksdb::BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
+        table_options.partition_filters = true;
+        table_options.cache_index_and_filter_blocks = true;
+        table_options.pin_l0_filter_and_index_blocks_in_cache = true;
+      }
     }
     db_options.table_factory.reset(rocksdb::NewBlockBasedTableFactory(table_options));
 
diff --git a/tddb/td/db/RocksDb.h b/tddb/td/db/RocksDb.h
index 26f733a3b..b0ae0659c 100644
--- a/tddb/td/db/RocksDb.h
+++ b/tddb/td/db/RocksDb.h
@@ -64,6 +64,7 @@ struct RocksDbOptions {
   bool use_direct_reads = false;
   bool no_block_cache = false;
   bool enable_bloom_filter = false;
+  bool two_level_index_and_filter = false;
 };
 
 class RocksDb : public KeyValue {
diff --git a/validator/db/celldb.cpp b/validator/db/celldb.cpp
index 8a619a530..a68d8056f 100644
--- a/validator/db/celldb.cpp
+++ b/validator/db/celldb.cpp
@@ -102,6 +102,8 @@ void CellDbIn::start_up() {
   }
   db_options.use_direct_reads = opts_->get_celldb_direct_io();
   db_options.enable_bloom_filter = !opts_->get_celldb_disable_bloom_filter();
+  db_options.two_level_index_and_filter = db_options.enable_bloom_filter 
+                                && opts_->state_ttl() >= 60 * 60 * 24 * 30; // 30 days
 
   if (opts_->get_celldb_in_memory()) {
     td::RocksDbOptions read_db_options;

From aa2e211f977d4cbf90497d6d5d076ae2c730f83b Mon Sep 17 00:00:00 2001
From: Marat S <dungeon666master@protonmail.com>
Date: Sat, 1 Mar 2025 00:28:38 +0000
Subject: [PATCH 3/3] set block cache size to 16gb in case of 2 level index

---
 validator/db/celldb.cpp | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/validator/db/celldb.cpp b/validator/db/celldb.cpp
index a68d8056f..350cc929a 100644
--- a/validator/db/celldb.cpp
+++ b/validator/db/celldb.cpp
@@ -96,14 +96,17 @@ void CellDbIn::start_up() {
     db_options.snapshot_statistics = snapshot_statistics_;
   }
   db_options.statistics = statistics_;
-  if (opts_->get_celldb_cache_size()) {
-    db_options.block_cache = td::RocksDb::create_cache(opts_->get_celldb_cache_size().value());
-    LOG(WARNING) << "Set CellDb block cache size to " << td::format::as_size(opts_->get_celldb_cache_size().value());
-  }
   db_options.use_direct_reads = opts_->get_celldb_direct_io();
   db_options.enable_bloom_filter = !opts_->get_celldb_disable_bloom_filter();
   db_options.two_level_index_and_filter = db_options.enable_bloom_filter 
                                 && opts_->state_ttl() >= 60 * 60 * 24 * 30; // 30 days
+  if (opts_->get_celldb_cache_size()) {
+    db_options.block_cache = td::RocksDb::create_cache(opts_->get_celldb_cache_size().value());
+    LOG(WARNING) << "Set CellDb block cache size to " << td::format::as_size(opts_->get_celldb_cache_size().value());
+  } else if (db_options.two_level_index_and_filter && !opts_->get_celldb_in_memory()) {
+    db_options.block_cache = td::RocksDb::create_cache(16ULL << 30);
+    LOG(WARNING) << "Set CellDb block cache size to 16GB";
+  }
 
   if (opts_->get_celldb_in_memory()) {
     td::RocksDbOptions read_db_options;