LCOV - code coverage report
Current view: top level - src/wallet - walletdb.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 0 66 0.0 %
Date: 2023-09-26 12:08:55 Functions: 0 56 0.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2022 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 <wallet/db.h>
      11             : #include <wallet/walletutil.h>
      12             : #include <key.h>
      13             : 
      14             : #include <stdint.h>
      15             : #include <string>
      16             : #include <vector>
      17             : 
      18             : class CScript;
      19             : class uint160;
      20             : class uint256;
      21             : struct CBlockLocator;
      22             : 
      23             : namespace wallet {
      24             : class CKeyPool;
      25             : class CMasterKey;
      26             : class CWallet;
      27             : class CWalletTx;
      28             : struct WalletContext;
      29             : 
      30             : /**
      31             :  * Overview of wallet database classes:
      32             :  *
      33             :  * - WalletBatch is an abstract modifier object for the wallet database, and encapsulates a database
      34             :  *   batch update as well as methods to act on the database. It should be agnostic to the database implementation.
      35             :  *
      36             :  * The following classes are implementation specific:
      37             :  * - BerkeleyEnvironment is an environment in which the database exists.
      38             :  * - BerkeleyDatabase represents a wallet database.
      39             :  * - BerkeleyBatch is a low-level database batch update.
      40             :  */
      41             : 
      42             : static const bool DEFAULT_FLUSHWALLET = true;
      43             : 
      44             : /** Error statuses for the wallet database.
      45             :  * Values are in order of severity. When multiple errors occur, the most severe (highest value) will be returned.
      46             :  */
      47             : enum class DBErrors : int
      48             : {
      49             :     LOAD_OK = 0,
      50             :     NEED_RESCAN = 1,
      51             :     NEED_REWRITE = 2,
      52             :     EXTERNAL_SIGNER_SUPPORT_REQUIRED = 3,
      53             :     NONCRITICAL_ERROR = 4,
      54             :     TOO_NEW = 5,
      55             :     UNKNOWN_DESCRIPTOR = 6,
      56             :     LOAD_FAIL = 7,
      57             :     UNEXPECTED_LEGACY_ENTRY = 8,
      58             :     CORRUPT = 9,
      59             : };
      60             : 
      61             : namespace DBKeys {
      62             : extern const std::string ACENTRY;
      63             : extern const std::string ACTIVEEXTERNALSPK;
      64             : extern const std::string ACTIVEINTERNALSPK;
      65             : extern const std::string BESTBLOCK;
      66             : extern const std::string BESTBLOCK_NOMERKLE;
      67             : extern const std::string CRYPTED_KEY;
      68             : extern const std::string CSCRIPT;
      69             : extern const std::string DEFAULTKEY;
      70             : extern const std::string DESTDATA;
      71             : extern const std::string FLAGS;
      72             : extern const std::string HDCHAIN;
      73             : extern const std::string KEY;
      74             : extern const std::string KEYMETA;
      75             : extern const std::string LOCKED_UTXO;
      76             : extern const std::string MASTER_KEY;
      77             : extern const std::string MINVERSION;
      78             : extern const std::string NAME;
      79             : extern const std::string OLD_KEY;
      80             : extern const std::string ORDERPOSNEXT;
      81             : extern const std::string POOL;
      82             : extern const std::string PURPOSE;
      83             : extern const std::string SETTINGS;
      84             : extern const std::string TX;
      85             : extern const std::string VERSION;
      86             : extern const std::string WALLETDESCRIPTOR;
      87             : extern const std::string WALLETDESCRIPTORCKEY;
      88             : extern const std::string WALLETDESCRIPTORKEY;
      89             : extern const std::string WATCHMETA;
      90             : extern const std::string WATCHS;
      91             : 
      92             : // Keys in this set pertain only to the legacy wallet (LegacyScriptPubKeyMan) and are removed during migration from legacy to descriptors.
      93             : extern const std::unordered_set<std::string> LEGACY_TYPES;
      94             : } // namespace DBKeys
      95             : 
      96             : /* simple HD chain data model */
      97             : class CHDChain
      98             : {
      99             : public:
     100             :     uint32_t nExternalChainCounter;
     101             :     uint32_t nInternalChainCounter;
     102             :     CKeyID seed_id; //!< seed hash160
     103           0 :     int64_t m_next_external_index{0}; // Next index in the keypool to be used. Memory only.
     104           0 :     int64_t m_next_internal_index{0}; // Next index in the keypool to be used. Memory only.
     105             : 
     106             :     static const int VERSION_HD_BASE        = 1;
     107             :     static const int VERSION_HD_CHAIN_SPLIT = 2;
     108             :     static const int CURRENT_VERSION        = VERSION_HD_CHAIN_SPLIT;
     109             :     int nVersion;
     110             : 
     111           0 :     CHDChain() { SetNull(); }
     112             : 
     113           0 :     SERIALIZE_METHODS(CHDChain, obj)
     114             :     {
     115           0 :         READWRITE(obj.nVersion, obj.nExternalChainCounter, obj.seed_id);
     116           0 :         if (obj.nVersion >= VERSION_HD_CHAIN_SPLIT) {
     117           0 :             READWRITE(obj.nInternalChainCounter);
     118           0 :         }
     119           0 :     }
     120             : 
     121           0 :     void SetNull()
     122             :     {
     123           0 :         nVersion = CHDChain::CURRENT_VERSION;
     124           0 :         nExternalChainCounter = 0;
     125           0 :         nInternalChainCounter = 0;
     126           0 :         seed_id.SetNull();
     127           0 :     }
     128             : 
     129           0 :     bool operator==(const CHDChain& chain) const
     130             :     {
     131           0 :         return seed_id == chain.seed_id;
     132             :     }
     133             : };
     134             : 
     135           0 : class CKeyMetadata
     136             : {
     137             : public:
     138             :     static const int VERSION_BASIC=1;
     139             :     static const int VERSION_WITH_HDDATA=10;
     140             :     static const int VERSION_WITH_KEY_ORIGIN = 12;
     141             :     static const int CURRENT_VERSION=VERSION_WITH_KEY_ORIGIN;
     142             :     int nVersion;
     143             :     int64_t nCreateTime; // 0 means unknown
     144             :     std::string hdKeypath; //optional HD/bip32 keypath. Still used to determine whether a key is a seed. Also kept for backwards compatibility
     145             :     CKeyID hd_seed_id; //id of the HD seed used to derive this key
     146             :     KeyOriginInfo key_origin; // Key origin info with path and fingerprint
     147           0 :     bool has_key_origin = false; //!< Whether the key_origin is useful
     148             : 
     149           0 :     CKeyMetadata()
     150             :     {
     151           0 :         SetNull();
     152           0 :     }
     153           0 :     explicit CKeyMetadata(int64_t nCreateTime_)
     154             :     {
     155           0 :         SetNull();
     156           0 :         nCreateTime = nCreateTime_;
     157           0 :     }
     158             : 
     159           0 :     SERIALIZE_METHODS(CKeyMetadata, obj)
     160             :     {
     161           0 :         READWRITE(obj.nVersion, obj.nCreateTime);
     162           0 :         if (obj.nVersion >= VERSION_WITH_HDDATA) {
     163           0 :             READWRITE(obj.hdKeypath, obj.hd_seed_id);
     164           0 :         }
     165           0 :         if (obj.nVersion >= VERSION_WITH_KEY_ORIGIN)
     166             :         {
     167           0 :             READWRITE(obj.key_origin);
     168           0 :             READWRITE(obj.has_key_origin);
     169           0 :         }
     170           0 :     }
     171             : 
     172           0 :     void SetNull()
     173             :     {
     174           0 :         nVersion = CKeyMetadata::CURRENT_VERSION;
     175           0 :         nCreateTime = 0;
     176           0 :         hdKeypath.clear();
     177           0 :         hd_seed_id.SetNull();
     178           0 :         key_origin.clear();
     179           0 :         has_key_origin = false;
     180           0 :     }
     181             : };
     182             : 
     183             : /** Access to the wallet database.
     184             :  * Opens the database and provides read and write access to it. Each read and write is its own transaction.
     185             :  * Multiple operation transactions can be started using TxnBegin() and committed using TxnCommit()
     186             :  * Otherwise the transaction will be committed when the object goes out of scope.
     187             :  * Optionally (on by default) it will flush to disk on close.
     188             :  * Every 1000 writes will automatically trigger a flush to disk.
     189             :  */
     190             : class WalletBatch
     191             : {
     192             : private:
     193             :     template <typename K, typename T>
     194           0 :     bool WriteIC(const K& key, const T& value, bool fOverwrite = true)
     195             :     {
     196           0 :         if (!m_batch->Write(key, value, fOverwrite)) {
     197           0 :             return false;
     198             :         }
     199           0 :         m_database.IncrementUpdateCounter();
     200           0 :         if (m_database.nUpdateCounter % 1000 == 0) {
     201           0 :             m_batch->Flush();
     202           0 :         }
     203           0 :         return true;
     204           0 :     }
     205             : 
     206             :     template <typename K>
     207           0 :     bool EraseIC(const K& key)
     208             :     {
     209           0 :         if (!m_batch->Erase(key)) {
     210           0 :             return false;
     211             :         }
     212           0 :         m_database.IncrementUpdateCounter();
     213           0 :         if (m_database.nUpdateCounter % 1000 == 0) {
     214           0 :             m_batch->Flush();
     215           0 :         }
     216           0 :         return true;
     217           0 :     }
     218             : 
     219             : public:
     220           0 :     explicit WalletBatch(WalletDatabase &database, bool _fFlushOnClose = true) :
     221           0 :         m_batch(database.MakeBatch(_fFlushOnClose)),
     222           0 :         m_database(database)
     223             :     {
     224           0 :     }
     225             :     WalletBatch(const WalletBatch&) = delete;
     226             :     WalletBatch& operator=(const WalletBatch&) = delete;
     227             : 
     228             :     bool WriteName(const std::string& strAddress, const std::string& strName);
     229             :     bool EraseName(const std::string& strAddress);
     230             : 
     231             :     bool WritePurpose(const std::string& strAddress, const std::string& purpose);
     232             :     bool ErasePurpose(const std::string& strAddress);
     233             : 
     234             :     bool WriteTx(const CWalletTx& wtx);
     235             :     bool EraseTx(uint256 hash);
     236             : 
     237             :     bool WriteKeyMetadata(const CKeyMetadata& meta, const CPubKey& pubkey, const bool overwrite);
     238             :     bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta);
     239             :     bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta);
     240             :     bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey);
     241             : 
     242             :     bool WriteCScript(const uint160& hash, const CScript& redeemScript);
     243             : 
     244             :     bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta);
     245             :     bool EraseWatchOnly(const CScript &script);
     246             : 
     247             :     bool WriteBestBlock(const CBlockLocator& locator);
     248             :     bool ReadBestBlock(CBlockLocator& locator);
     249             : 
     250             :     bool WriteOrderPosNext(int64_t nOrderPosNext);
     251             : 
     252             :     bool ReadPool(int64_t nPool, CKeyPool& keypool);
     253             :     bool WritePool(int64_t nPool, const CKeyPool& keypool);
     254             :     bool ErasePool(int64_t nPool);
     255             : 
     256             :     bool WriteMinVersion(int nVersion);
     257             : 
     258             :     bool WriteDescriptorKey(const uint256& desc_id, const CPubKey& pubkey, const CPrivKey& privkey);
     259             :     bool WriteCryptedDescriptorKey(const uint256& desc_id, const CPubKey& pubkey, const std::vector<unsigned char>& secret);
     260             :     bool WriteDescriptor(const uint256& desc_id, const WalletDescriptor& descriptor);
     261             :     bool WriteDescriptorDerivedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index, uint32_t der_index);
     262             :     bool WriteDescriptorParentCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index);
     263             :     bool WriteDescriptorLastHardenedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index);
     264             :     bool WriteDescriptorCacheItems(const uint256& desc_id, const DescriptorCache& cache);
     265             : 
     266             :     bool WriteLockedUTXO(const COutPoint& output);
     267             :     bool EraseLockedUTXO(const COutPoint& output);
     268             : 
     269             :     bool WriteAddressPreviouslySpent(const CTxDestination& dest, bool previously_spent);
     270             :     bool WriteAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& receive_request);
     271             :     bool EraseAddressReceiveRequest(const CTxDestination& dest, const std::string& id);
     272             :     bool EraseAddressData(const CTxDestination& dest);
     273             : 
     274             :     bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256& id, bool internal);
     275             :     bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal);
     276             : 
     277             :     DBErrors LoadWallet(CWallet* pwallet);
     278             :     DBErrors FindWalletTxHashes(std::vector<uint256>& tx_hashes);
     279             :     DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut);
     280             : 
     281             :     //! write the hdchain model (external chain child index counter)
     282             :     bool WriteHDChain(const CHDChain& chain);
     283             : 
     284             :     //! Delete records of the given types
     285             :     bool EraseRecords(const std::unordered_set<std::string>& types);
     286             : 
     287             :     bool WriteWalletFlags(const uint64_t flags);
     288             :     //! Begin a new transaction
     289             :     bool TxnBegin();
     290             :     //! Commit current transaction
     291             :     bool TxnCommit();
     292             :     //! Abort current transaction
     293             :     bool TxnAbort();
     294             : private:
     295             :     std::unique_ptr<DatabaseBatch> m_batch;
     296             :     WalletDatabase& m_database;
     297             : };
     298             : 
     299             : //! Compacts BDB state so that wallet.dat is self-contained (if there are changes)
     300             : void MaybeCompactWalletDB(WalletContext& context);
     301             : 
     302             : bool LoadKey(CWallet* pwallet, DataStream& ssKey, DataStream& ssValue, std::string& strErr);
     303             : bool LoadCryptedKey(CWallet* pwallet, DataStream& ssKey, DataStream& ssValue, std::string& strErr);
     304             : bool LoadEncryptionKey(CWallet* pwallet, DataStream& ssKey, DataStream& ssValue, std::string& strErr);
     305             : bool LoadHDChain(CWallet* pwallet, DataStream& ssValue, std::string& strErr);
     306             : } // namespace wallet
     307             : 
     308             : #endif // BITCOIN_WALLET_WALLETDB_H

Generated by: LCOV version 1.14