diff --git a/doc/release-notes-35634.md b/doc/release-notes-35634.md index ccbd7fd7c22..2398305bdf0 100644 --- a/doc/release-notes-35634.md +++ b/doc/release-notes-35634.md @@ -1,9 +1,8 @@ Indexes ------- -- The transaction output spender index (`-txospenderindex`) now stores one byte - less per spender entry for newly indexed blocks. Existing indexes remain - compatible and no action is required. To apply the same saving to entries - indexed before upgrading, stop the node, delete the +- The transaction output spender index (`-txospenderindex`) now uses less disk + space. Existing indexes remain compatible and no action is required. To reclaim + the space for data indexed before upgrading, stop the node, delete the `/indexes/txospenderindex/` directory, and restart with - `-txospenderindex` enabled to rebuild it. + `-txospenderindex` enabled to rebuild it. (#35634, #35568) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index ffe6f267a6b..ed914273634 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -136,12 +136,12 @@ static void SetMaxOpenFiles(leveldb::Options *options) { options->max_open_files, default_open_files); } -static leveldb::Options GetOptions(size_t nCacheSize) +static leveldb::Options GetOptions(size_t nCacheSize, bool bloom_filter) { leveldb::Options options; options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously - options.filter_policy = leveldb::NewBloomFilterPolicy(10); + options.filter_policy = bloom_filter ? leveldb::NewBloomFilterPolicy(10) : nullptr; options.compression = leveldb::kNoCompression; options.info_log = new CBitcoinLevelDBLogger(); if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) { @@ -225,7 +225,7 @@ CDBWrapper::CDBWrapper(const DBParams& params) DBContext().iteroptions.verify_checksums = true; DBContext().iteroptions.fill_cache = false; DBContext().syncoptions.sync = true; - DBContext().options = GetOptions(params.cache_bytes); + DBContext().options = GetOptions(params.cache_bytes, params.bloom_filter); DBContext().options.create_if_missing = true; DBContext().options.max_file_size = params.max_file_size; assert(!(params.testing_env && params.memory_only)); diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 2c1f80393c1..1eb68a3bb1f 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -50,6 +50,8 @@ struct DBParams { //! If true, store data obfuscated via simple XOR. If false, XOR with a //! zero'd byte array. bool obfuscate = false; + //! If true, build a LevelDB bloom filter to accelerate point lookups. + bool bloom_filter = true; //! Passed-through options. DBOptions options{}; //! If non-null, use this as the leveldb::Env instead of the default. diff --git a/src/index/base.cpp b/src/index/base.cpp index 68b712bbb12..5820448bb7f 100644 --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -65,13 +65,14 @@ CBlockLocator GetLocator(interfaces::Chain& chain, const uint256& block_hash) return locator; } -BaseIndex::DB::DB(const fs::path& path, size_t n_cache_size, bool f_memory, bool f_wipe, bool f_obfuscate) : +BaseIndex::DB::DB(const fs::path& path, size_t n_cache_size, bool f_memory, bool f_wipe, bool f_obfuscate, bool f_bloom) : CDBWrapper{DBParams{ .path = path, .cache_bytes = n_cache_size, .memory_only = f_memory, .wipe_data = f_wipe, .obfuscate = f_obfuscate, + .bloom_filter = f_bloom, .options = [] { DBOptions options; node::ReadDatabaseArgs(gArgs, options); return options; }()}} {} diff --git a/src/index/base.h b/src/index/base.h index 86ee9029c85..73282a96850 100644 --- a/src/index/base.h +++ b/src/index/base.h @@ -65,7 +65,7 @@ protected: { public: DB(const fs::path& path, size_t n_cache_size, - bool f_memory = false, bool f_wipe = false, bool f_obfuscate = false); + bool f_memory = false, bool f_wipe = false, bool f_obfuscate = false, bool f_bloom = true); /// Read block locator of the chain that the index is in sync with. /// Note, the returned locator will be empty if no record exists. diff --git a/src/index/txospenderindex.cpp b/src/index/txospenderindex.cpp index 50b9bfeb8b5..304104df02e 100644 --- a/src/index/txospenderindex.cpp +++ b/src/index/txospenderindex.cpp @@ -62,7 +62,7 @@ struct DBKey { }; TxoSpenderIndex::TxoSpenderIndex(std::unique_ptr chain, size_t n_cache_size, bool f_memory, bool f_wipe) - : BaseIndex(std::move(chain), "txospenderindex", "txospenderidx"), m_db{std::make_unique(gArgs.GetDataDirNet() / "indexes" / "txospenderindex" / "db", n_cache_size, f_memory, f_wipe)} + : BaseIndex(std::move(chain), "txospenderindex", "txospenderidx"), m_db{std::make_unique(gArgs.GetDataDirNet() / "indexes" / "txospenderindex" / "db", n_cache_size, f_memory, f_wipe, /*f_obfuscate=*/false, /*f_bloom=*/false)} { if (!m_db->Read("siphash_key", m_siphash_key)) { FastRandomContext rng(false); diff --git a/src/test/fuzz/dbwrapper.cpp b/src/test/fuzz/dbwrapper.cpp index 265f0ca3a09..66b7327f64a 100644 --- a/src/test/fuzz/dbwrapper.cpp +++ b/src/test/fuzz/dbwrapper.cpp @@ -188,6 +188,7 @@ DBParams ConsumeDBParams(FuzzedDataProvider& provider, leveldb::Env* testing_env .path = "dbwrapper_fuzz", .cache_bytes = provider.ConsumeIntegralInRange(64 << 10, 1_MiB), .obfuscate = obfuscate, + .bloom_filter = provider.ConsumeBool(), .options = options, .testing_env = testing_env, .max_file_size = provider.ConsumeBool()