LCOV - code coverage report
Current view: top level - src/wallet - walletdb.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 44 45 97.8 %
Date: 2026-06-25 07:23:43 Functions: 55 55 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2021 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #ifndef BITCOIN_WALLET_WALLETDB_H
       7             : #define BITCOIN_WALLET_WALLETDB_H
       8             : 
       9             : #include <script/sign.h>
      10             : #include <script/standard.h>
      11             : #include <wallet/db.h>
      12             : #include <wallet/walletutil.h>
      13             : #include <key.h>
      14             : 
      15             : #include <stdint.h>
      16             : #include <string>
      17             : #include <vector>
      18             : 
      19             : struct CBlockLocator;
      20             : class CScript;
      21             : class uint160;
      22             : class uint256;
      23             : namespace Governance {
      24             : class Object;
      25             : } // namespace Governance
      26             : 
      27             : namespace wallet {
      28             : class CHDChain;
      29             : class CHDPubKey;
      30             : class CKeyPool;
      31             : class CMasterKey;
      32             : class CWallet;
      33             : class CWalletTx;
      34             : struct WalletContext;
      35             : 
      36             : /**
      37             :  * Overview of wallet database classes:
      38             :  *
      39             :  * - WalletBatch is an abstract modifier object for the wallet database, and encapsulates a database
      40             :  *   batch update as well as methods to act on the database. It should be agnostic to the database implementation.
      41             :  *
      42             :  * The following classes are implementation specific:
      43             :  * - BerkeleyEnvironment is an environment in which the database exists.
      44             :  * - BerkeleyDatabase represents a wallet database.
      45             :  * - BerkeleyBatch is a low-level database batch update.
      46             :  */
      47             : 
      48             : static const bool DEFAULT_FLUSHWALLET = true;
      49             : 
      50             : /** Error statuses for the wallet database */
      51             : enum class DBErrors
      52             : {
      53             :     LOAD_OK,
      54             :     CORRUPT,
      55             :     NONCRITICAL_ERROR,
      56             :     TOO_NEW,
      57             :     EXTERNAL_SIGNER_SUPPORT_REQUIRED,
      58             :     LOAD_FAIL,
      59             :     NEED_REWRITE
      60             : };
      61             : 
      62             : namespace DBKeys {
      63             : extern const std::string ACENTRY;
      64             : extern const std::string ACTIVEEXTERNALSPK;
      65             : extern const std::string ACTIVEINTERNALSPK;
      66             : extern const std::string BESTBLOCK;
      67             : extern const std::string BESTBLOCK_NOMERKLE;
      68             : extern const std::string CRYPTED_HDCHAIN;
      69             : extern const std::string CRYPTED_KEY;
      70             : extern const std::string COINJOIN_SALT;
      71             : extern const std::string CSCRIPT;
      72             : extern const std::string DEFAULTKEY;
      73             : extern const std::string DESTDATA;
      74             : extern const std::string FLAGS;
      75             : extern const std::string G_OBJECT;
      76             : extern const std::string HDCHAIN;
      77             : extern const std::string HDPUBKEY;
      78             : extern const std::string KEY;
      79             : extern const std::string KEYMETA;
      80             : extern const std::string LOCKED_UTXO;
      81             : extern const std::string MASTER_KEY;
      82             : extern const std::string MINVERSION;
      83             : extern const std::string NAME;
      84             : extern const std::string OLD_KEY;
      85             : extern const std::string ORDERPOSNEXT;
      86             : extern const std::string POOL;
      87             : extern const std::string PURPOSE;
      88             : extern const std::string PRIVATESEND_SALT;
      89             : extern const std::string SETTINGS;
      90             : extern const std::string TX;
      91             : extern const std::string VERSION;
      92             : extern const std::string WALLETDESCRIPTOR;
      93             : extern const std::string WALLETDESCRIPTORCKEY;
      94             : extern const std::string WALLETDESCRIPTORKEY;
      95             : extern const std::string WATCHMETA;
      96             : extern const std::string WATCHS;
      97             : 
      98             : // Keys in this set pertain only to the legacy wallet (LegacyScriptPubKeyMan) and are removed during migration from legacy to descriptors.
      99             : extern const std::unordered_set<std::string> LEGACY_TYPES;
     100             : } // namespace DBKeys
     101             : 
     102             : class CKeyMetadata
     103             : {
     104             : public:
     105             :     static const int VERSION_BASIC=1;
     106             :     static const int VERSION_WITH_KEY_ORIGIN = 12;
     107             :     static const int CURRENT_VERSION=VERSION_WITH_KEY_ORIGIN;
     108             :     int nVersion;
     109             :     int64_t nCreateTime; // 0 means unknown
     110             :     KeyOriginInfo key_origin; // Key origin info with path and fingerprint
     111      760593 :     bool has_key_origin = false; //!< Whether the key_origin is useful
     112             : 
     113     1401970 :     CKeyMetadata()
     114      700985 :     {
     115      700985 :         SetNull();
     116     1401970 :     }
     117      119216 :     explicit CKeyMetadata(int64_t nCreateTime_)
     118       59608 :     {
     119       59608 :         SetNull();
     120       59608 :         nCreateTime = nCreateTime_;
     121      119216 :     }
     122             : 
     123      227913 :     SERIALIZE_METHODS(CKeyMetadata, obj)
     124             :     {
     125       75971 :         READWRITE(obj.nVersion, obj.nCreateTime);
     126       75971 :         if (obj.nVersion >= VERSION_WITH_KEY_ORIGIN) {
     127       75971 :             READWRITE(obj.key_origin, obj.has_key_origin);
     128       75971 :         }
     129       75971 :     }
     130             : 
     131      760593 :     void SetNull()
     132             :     {
     133      760593 :         nVersion = CKeyMetadata::CURRENT_VERSION;
     134      760593 :         nCreateTime = 0;
     135      760593 :         key_origin.clear();
     136      760593 :         has_key_origin = false;
     137      760593 :     }
     138             : };
     139             : 
     140             : /** Access to the wallet database.
     141             :  * Opens the database and provides read and write access to it. Each read and write is its own transaction.
     142             :  * Multiple operation transactions can be started using TxnBegin() and committed using TxnCommit()
     143             :  * Otherwise the transaction will be committed when the object goes out of scope.
     144             :  * Optionally (on by default) it will flush to disk on close.
     145             :  * Every 1000 writes will automatically trigger a flush to disk.
     146             :  */
     147             : class WalletBatch
     148             : {
     149             : private:
     150             :     template <typename K, typename T>
     151      567918 :     bool WriteIC(const K& key, const T& value, bool fOverwrite = true)
     152             :     {
     153      567918 :         if (!m_batch->Write(key, value, fOverwrite)) {
     154           3 :             return false;
     155             :         }
     156      567915 :         m_database.IncrementUpdateCounter();
     157      567915 :         if (m_database.nUpdateCounter % 1000 == 0) {
     158         307 :             m_batch->Flush();
     159         307 :         }
     160      567915 :         return true;
     161      567918 :     }
     162             : 
     163             :     template <typename K>
     164       23031 :     bool EraseIC(const K& key)
     165             :     {
     166       23031 :         if (!m_batch->Erase(key)) {
     167           0 :             return false;
     168             :         }
     169       23031 :         m_database.IncrementUpdateCounter();
     170       23031 :         if (m_database.nUpdateCounter % 1000 == 0) {
     171           9 :             m_batch->Flush();
     172           9 :         }
     173       23031 :         return true;
     174       23031 :     }
     175             : 
     176             : public:
     177      900936 :     explicit WalletBatch(WalletDatabase &database, bool _fFlushOnClose = true) :
     178      450468 :         m_batch(database.MakeBatch(_fFlushOnClose)),
     179      450468 :         m_database(database)
     180      450468 :     {
     181      900936 :     }
     182             :     WalletBatch(const WalletBatch&) = delete;
     183             :     WalletBatch& operator=(const WalletBatch&) = delete;
     184             : 
     185             :     bool WriteName(const std::string& strAddress, const std::string& strName);
     186             :     bool EraseName(const std::string& strAddress);
     187             : 
     188             :     bool WritePurpose(const std::string& strAddress, const std::string& purpose);
     189             :     bool ErasePurpose(const std::string& strAddress);
     190             : 
     191             :     bool WriteTx(const CWalletTx& wtx);
     192             :     bool EraseTx(uint256 hash);
     193             : 
     194             :     bool WriteKeyMetadata(const CKeyMetadata& meta, const CPubKey& pubkey, const bool overwrite);
     195             :     bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta);
     196             :     bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta);
     197             :     bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey);
     198             : 
     199             :     bool WriteCScript(const uint160& hash, const CScript& redeemScript);
     200             : 
     201             :     bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta);
     202             :     bool EraseWatchOnly(const CScript &script);
     203             : 
     204             :     bool WriteBestBlock(const CBlockLocator& locator);
     205             :     bool ReadBestBlock(CBlockLocator& locator);
     206             : 
     207             :     bool WriteOrderPosNext(int64_t nOrderPosNext);
     208             : 
     209             :     bool ReadPool(int64_t nPool, CKeyPool& keypool);
     210             :     bool WritePool(int64_t nPool, const CKeyPool& keypool);
     211             :     bool ErasePool(int64_t nPool);
     212             : 
     213             :     bool WriteMinVersion(int nVersion);
     214             : 
     215             :     bool ReadCoinJoinSalt(uint256& salt, bool fLegacy = false);
     216             :     bool WriteCoinJoinSalt(const uint256& salt);
     217             : 
     218             :     /** Write a CGovernanceObject to the database */
     219             :     bool WriteGovernanceObject(const Governance::Object& obj);
     220             : 
     221             :     bool WriteDescriptorKey(const uint256& desc_id, const CPubKey& pubkey, const CPrivKey& privkey, const SecureString& mnemonic, const SecureString& mnemonic_passphrase);
     222             :     bool WriteCryptedDescriptorKey(const uint256& desc_id, const CPubKey& pubkey, const std::vector<unsigned char>& secret, const std::vector<unsigned char>& crypted_mnemonic, const std::vector<unsigned char>& crypted_mnemonic_passphrase);
     223             :     bool WriteDescriptor(const uint256& desc_id, const WalletDescriptor& descriptor);
     224             :     bool WriteDescriptorDerivedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index, uint32_t der_index);
     225             :     bool WriteDescriptorParentCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index);
     226             :     bool WriteDescriptorLastHardenedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index);
     227             :     bool WriteDescriptorCacheItems(const uint256& desc_id, const DescriptorCache& cache);
     228             : 
     229             :     bool WriteLockedUTXO(const COutPoint& output);
     230             :     bool EraseLockedUTXO(const COutPoint& output);
     231             : 
     232             :     bool WriteAddressPreviouslySpent(const CTxDestination& dest, bool previously_spent);
     233             :     bool WriteAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& receive_request);
     234             :     bool EraseAddressReceiveRequest(const CTxDestination& dest, const std::string& id);
     235             :     bool EraseAddressData(const CTxDestination& dest);
     236             : 
     237             :     bool WriteActiveScriptPubKeyMan(const uint256& id, bool internal);
     238             :     bool EraseActiveScriptPubKeyMan(bool internal);
     239             : 
     240             :     DBErrors LoadWallet(CWallet* pwallet);
     241             :     DBErrors FindWalletTxHashes(std::vector<uint256>& tx_hashes);
     242             :     DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut);
     243             :     /* Function to determine if a certain KV/key-type is a key (cryptographical key) type */
     244             :     static bool IsKeyType(const std::string& strType);
     245             : 
     246             :     //! write the hdchain model (external chain child index counter)
     247             :     bool WriteHDChain(const CHDChain& chain);
     248             :     bool WriteHDPubKey(const CHDPubKey& hdPubKey, const CKeyMetadata& keyMeta);
     249             : 
     250             :     //! Delete records of the given types
     251             :     bool EraseRecords(const std::unordered_set<std::string>& types);
     252             : 
     253             :     bool WriteWalletFlags(const uint64_t flags);
     254             :     //! Begin a new transaction
     255             :     bool TxnBegin();
     256             :     //! Commit current transaction
     257             :     bool TxnCommit();
     258             :     //! Abort current transaction
     259             :     bool TxnAbort();
     260             : private:
     261             :     std::unique_ptr<DatabaseBatch> m_batch;
     262             :     WalletDatabase& m_database;
     263             : };
     264             : 
     265             : //! Compacts BDB state so that wallet.dat is self-contained (if there are changes)
     266             : void MaybeCompactWalletDB(WalletContext& context);
     267             : 
     268             : //! Callback for filtering key types to deserialize in ReadKeyValue
     269             : using KeyFilterFn = std::function<bool(const std::string&)>;
     270             : 
     271             : //! Unserialize a given Key-Value pair and load it into the wallet
     272             : bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, std::string& strType, std::string& strErr, const KeyFilterFn& filter_fn = nullptr);
     273             : 
     274             : /** Return object for accessing dummy database with no read/write capabilities. */
     275             : std::unique_ptr<WalletDatabase> CreateDummyWalletDatabase();
     276             : 
     277             : /** Return object for accessing temporary in-memory database. */
     278             : std::unique_ptr<WalletDatabase> CreateMockWalletDatabase(DatabaseOptions& options);
     279             : std::unique_ptr<WalletDatabase> CreateMockWalletDatabase();
     280             : } // namespace wallet
     281             : 
     282             : #endif // BITCOIN_WALLET_WALLETDB_H

Generated by: LCOV version 1.16