Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251DataStream ssKey{};252ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);253// Key serialization is the only operation that may throw.254// Callers are expected to provide well-formed keys.255ssKey << key;257std::optional<std::string> strValue;258try {259strValue = ReadImpl(ssKey);260if (!strValue) {261return false; // not found262}263} catch (const std::exception& e) {264return util::Unexpected(ReadFailure{ReadFailure::Code::DatabaseError, e.what()});265}267try {268std::span ssValue{MakeWritableByteSpan(*strValue)};269m_obfuscation(ssValue);270SpanReader{ssValue} >> value;271} catch (const std::exception& e) {272return util::Unexpected(ReadFailure{ReadFailure::Code::DeserializationError, e.what()});273}275return true;276}278/**279* Wrapper around TryRead() that preserves the original Read() semantics:280* returns true on success, false if the key is absent or deserialization281* fails, and throws dbwrapper_error on an internal DB error.282*283* Prefer TryRead() when the caller needs to distinguish between a missing284* key and a corrupt value.285*/286template <typename K, typename V>287bool Read(const K& key, V& value) const288{289const ReadStatus res = TryRead(key,value);290if (res.has_value()) return res.value();291switch (const auto& [err_code, err_msg] = res.error(); err_code) {292case ReadFailure::Code::DeserializationError: return false;293case ReadFailure::Code::DatabaseError: throw dbwrapper_error(err_msg);294} // no default case, so the compiler can warn about missing cases295std::abort(); // unreachable296}298template <typename K, typename V>299void Write(const K& key, const V& value, bool fSync = false)300{301CDBBatch batch(*this);302batch.Write(key, value);303WriteBatch(batch, fSync);304}306template <typename K>307bool Exists(const K& key) const308{309DataStream ssKey{};310ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);311ssKey << key;312return ExistsImpl(ssKey);313}315template <typename K>316void Erase(const K& key, bool fSync = false)317{318CDBBatch batch(*this);319batch.Erase(key);320WriteBatch(batch, fSync);321}323void WriteBatch(CDBBatch& batch, bool fSync = false);325//! Perform a blocking full compaction of the underlying LevelDB.326void CompactFull();328//! Return a LevelDB property value, if available.329std::optional<std::string> GetProperty(const std::string& property) const;331// Get an estimate of LevelDB memory usage (in bytes).332size_t DynamicMemoryUsage() const;334CDBIterator* NewIterator();336/**337* Return true if the database managed by this class contains no entries.338*/339bool IsEmpty();341//! Probe an unopened database for a key prefix. Return true if a database at342//! path exists and contains at least 1 entry beginning with prefix; missing343//! or empty databases return false, and database errors throw dbwrapper_error.344static bool HasKeyStartingWith(const fs::path& path, uint8_t prefix);346template<typename K>347size_t EstimateSize(const K& key_begin, const K& key_end) const348{349DataStream ssKey1{}, ssKey2{};350ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);351ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);352ssKey1 << key_begin;353ssKey2 << key_end;354return EstimateSizeImpl(ssKey1, ssKey2);355}356};358#endif // BITCOIN_DBWRAPPER_H