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.
1// Copyright (c) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#ifndef BITCOIN_WALLET_DB_H7#define BITCOIN_WALLET_DB_H9#include <clientversion.h>10#include <streams.h>11#include <support/allocators/secure.h>12#include <util/fs.h>14#include <memory>15#include <optional>16#include <string>18class ArgsManager;19struct bilingual_str;21namespace wallet {22// BytePrefix compares equality with other byte spans that begin with the same prefix.23struct BytePrefix {24std::span<const std::byte> prefix;25};26bool operator<(BytePrefix a, std::span<const std::byte> b);27bool operator<(std::span<const std::byte> a, BytePrefix b);29class DatabaseCursor30{31public:32explicit DatabaseCursor() = default;33virtual ~DatabaseCursor() = default;35DatabaseCursor(const DatabaseCursor&) = delete;36DatabaseCursor& operator=(const DatabaseCursor&) = delete;38enum class Status39{40FAIL,41MORE,42DONE,43};45virtual Status Next(DataStream& key, DataStream& value) { return Status::FAIL; }46};48/** RAII class that provides access to a WalletDatabase */49class DatabaseBatch50{51private:52virtual bool ReadKey(DataStream&& key, DataStream& value) = 0;53virtual bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) = 0;54virtual bool EraseKey(DataStream&& key) = 0;55virtual bool HasKey(DataStream&& key) = 0;57public:58explicit DatabaseBatch() = default;59virtual ~DatabaseBatch() = default;61DatabaseBatch(const DatabaseBatch&) = delete;62DatabaseBatch& operator=(const DatabaseBatch&) = delete;64virtual void Close() = 0;66template <typename K, typename T>67bool Read(const K& key, T& value)68{69DataStream ssKey{};70ssKey.reserve(1000);71ssKey << key;73DataStream ssValue{};74if (!ReadKey(std::move(ssKey), ssValue)) return false;75try {76ssValue >> value;77return true;78} catch (const std::exception&) {79return false;80}81}83template <typename K, typename T>84bool Write(const K& key, const T& value, bool fOverwrite = true)85{86DataStream ssKey{};87ssKey.reserve(1000);88ssKey << key;90DataStream ssValue{};91ssValue.reserve(10000);92ssValue << value;94return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);95}97template <typename K>98bool Erase(const K& key)99{100DataStream ssKey{};101ssKey.reserve(1000);102ssKey << key;104return EraseKey(std::move(ssKey));105}107template <typename K>108bool Exists(const K& key)109{110DataStream ssKey{};111ssKey.reserve(1000);112ssKey << key;114return HasKey(std::move(ssKey));115}116virtual bool ErasePrefix(std::span<const std::byte> prefix) = 0;118virtual std::unique_ptr<DatabaseCursor> GetNewCursor() = 0;119virtual std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(std::span<const std::byte> prefix) = 0;120virtual bool TxnBegin() = 0;121virtual bool TxnCommit() = 0;122virtual bool TxnAbort() = 0;123virtual bool HasActiveTxn() = 0;124};126/** An instance of this class represents one database.127**/128class WalletDatabase129{130public:131/** Create dummy DB handle */132WalletDatabase() = default;133virtual ~WalletDatabase() = default;135/** Open the database if it is not already opened. */136virtual void Open() = 0;138/** Rewrite the entire database on disk139*/140virtual bool Rewrite() = 0;142/** Back up the entire database to a file.143*/144virtual bool Backup(const std::string& strDest) const = 0;146/** Flush to the database file and close the database.147* Also close the environment if no other databases are open in it.148*/149virtual void Close() = 0;151/** Return path to main database file for logs and error messages. */152virtual std::string Filename() = 0;154/** Return paths to all database created files */155virtual std::vector<fs::path> Files() = 0;157virtual std::string Format() = 0;159/** Make a DatabaseBatch connected to this database */160virtual std::unique_ptr<DatabaseBatch> MakeBatch() = 0;161};163enum class DatabaseFormat {164SQLITE,165BERKELEY_RO,166};168struct DatabaseOptions {169bool require_existing = false;170bool require_create = false;171std::optional<DatabaseFormat> require_format;172uint64_t create_flags = 0;173SecureString create_passphrase;175// Specialized options. Not every option is supported by every backend.176bool verify = true; //!< Check data integrity on load.177bool use_unsafe_sync = false; //!< Disable file sync for faster performance.178};180enum class DatabaseStatus {181SUCCESS,182FAILED_BAD_PATH,183FAILED_BAD_FORMAT,184FAILED_LEGACY_DISABLED,185FAILED_ALREADY_LOADED,186FAILED_ALREADY_EXISTS,187FAILED_NOT_FOUND,188FAILED_CREATE,189FAILED_LOAD,190FAILED_VERIFY,191FAILED_ENCRYPT,192FAILED_INVALID_BACKUP_FILE,193FAILED_NEW_UNNAMED,194};196/** Recursively list database paths in directory. */197std::vector<std::pair<fs::path, std::string>> ListDatabases(const fs::path& path);199void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options);200std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);202fs::path BDBDataFile(const fs::path& path);203fs::path SQLiteDataFile(const fs::path& path);204bool IsBDBFile(const fs::path& path);205bool IsSQLiteFile(const fs::path& path);206} // namespace wallet208#endif // BITCOIN_WALLET_DB_H