Line data Source code
1 : // Copyright (c) 2019 The Bitcoin Core developers 2 : // Copyright (c) 2020-2021 The PIVX 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 PIVX_WALLET_SCRIPTPUBKEYMAN_H 7 : #define PIVX_WALLET_SCRIPTPUBKEYMAN_H 8 : 9 : #include "wallet/hdchain.h" 10 : #include "wallet/wallet.h" 11 : #include "wallet/walletdb.h" 12 : 13 : //! Default for -keypool 14 : static const unsigned int DEFAULT_KEYPOOL_SIZE = 100; 15 : static const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; 16 : 17 : /* 18 : * A class implementing ScriptPubKeyMan manages some (or all) scriptPubKeys used in a wallet. 19 : * It contains the scripts and keys related to the scriptPubKeys it manages. 20 : * A ScriptPubKeyMan will be able to give out scriptPubKeys to be used, as well as marking 21 : * when a scriptPubKey has been used. It also handles when and how to store a scriptPubKey 22 : * and its related scripts and keys, including encryption. 23 : */ 24 : class ScriptPubKeyMan { 25 : 26 : public: 27 1010 : explicit ScriptPubKeyMan(CWallet* parent) : wallet(parent) {} 28 504 : ~ScriptPubKeyMan() {}; 29 : 30 : /* Set the HD chain model (chain child index counters) */ 31 : void SetHDChain(CHDChain& chain, bool memonly); 32 311 : const CHDChain& GetHDChain() const { return hdChain; } 33 : 34 : /** Sets up the key generation stuff, i.e. generates new HD seeds and sets them as active. 35 : * Returns false if already setup or setup fails, true if setup is successful 36 : * Set force=true to make it re-setup if already setup, used for upgrades 37 : */ 38 : bool SetupGeneration(bool newKeypool = true, bool force = false, bool memOnly = false); 39 : 40 : /** Upgrades the wallet to the specified version */ 41 : bool Upgrade(const int prev_version, std::string& error); 42 : 43 : /* Returns true if the wallet can generate new keys */ 44 : bool CanGenerateKeys(); 45 : 46 : /* True is HD wallet is enabled */ 47 : bool IsHDEnabled() const; 48 : 49 : /* Return the oldest key time */ 50 : int64_t GetOldestKeyPoolTime(); 51 : 52 : /* Count external keypool available keys */ 53 : size_t KeypoolCountExternalKeys(); 54 : 55 : /* Key pool size */ 56 : unsigned int GetKeyPoolSize() const; 57 : 58 : /* Staking key pool size */ 59 : unsigned int GetStakingKeyPoolSize() const; 60 : 61 : /* Whether the wallet has or not keys in the pool */ 62 : bool CanGetAddresses(const uint8_t& type = HDChain::ChangeType::EXTERNAL); 63 : 64 : /* Generates a new HD seed (will not be activated) */ 65 : CPubKey GenerateNewSeed(); 66 : 67 : /* Derives a new HD seed (will not be activated) */ 68 : CPubKey DeriveNewSeed(const CKey& key); 69 : 70 : /* Set the current HD seed (will reset the chain child index counters) 71 : Sets the seed's version based on the current wallet version (so the 72 : caller must ensure the current wallet version is correct before calling 73 : this function). */ 74 : void SetHDSeed(const CPubKey& key, bool force = false, bool memOnly = false); 75 : 76 : //! Load a keypool entry 77 : void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool); 78 : //! Key pool 79 : bool NewKeyPool(); 80 : //! Update pre HD keys in db with the pre-split flag enabled. 81 : void MarkPreSplitKeys(); 82 : 83 : /** Fills internal address pool. Use within ScriptPubKeyMan implementations should be used sparingly and only 84 : * when something from the address pool is removed, excluding GetNewDestination and GetReservedDestination. 85 : * External wallet code is primarily responsible for topping up prior to fetching new addresses 86 : */ 87 : bool TopUp(unsigned int size = 0); 88 : 89 : //! Mark unused addresses as being used 90 : void MarkUnusedAddresses(const CScript& script); 91 : 92 : //! First wallet key time 93 : void UpdateTimeFirstKey(int64_t nCreateTime); 94 : //! Generate a new key 95 : CPubKey GenerateNewKey(WalletBatch& batch, const uint8_t& type = HDChain::ChangeType::EXTERNAL); 96 : 97 : 98 : //! Fetches a key from the keypool 99 : bool GetKeyFromPool(CPubKey &key, const uint8_t& changeType = HDChain::ChangeType::EXTERNAL); 100 : //! Reserve + fetch a key from the keypool 101 : bool GetReservedKey(const uint8_t& changeType, int64_t& index, CKeyPool& keypool); 102 : 103 8 : const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; } 104 : /** 105 : * Reserves a key from the keypool and sets nIndex to its index 106 : * 107 : * @param[out] nIndex the index of the key in keypool 108 : * @param[out] keypool the keypool the key was drawn from, which could be the 109 : * the pre-split pool if present, or the internal or external pool 110 : * @param fRequestedInternal true if the caller would like the key drawn 111 : * from the internal keypool, false if external is preferred 112 : * 113 : * @return true if succeeded, false if failed due to empty keypool 114 : * @throws std::runtime_error if keypool read failed, key was invalid, 115 : * was not found in the wallet, or was misclassified in the internal 116 : * or external keypool 117 : */ 118 : bool ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, const uint8_t& type = HDChain::ChangeType::EXTERNAL); 119 : 120 : void KeepDestination(int64_t index); 121 : void ReturnDestination(int64_t index, const uint8_t& type, const CTxDestination&); 122 : 123 : // TODO: This is public for now but shouldn't be here. 124 : std::set<int64_t> set_pre_split_keypool; 125 : 126 : private: 127 : /* Parent wallet */ 128 : CWallet* wallet{nullptr}; 129 : /* the HD chain data model (external/internal chain counters) */ 130 : CHDChain hdChain; 131 : 132 : /* TODO: This has not been implemented yet.. */ 133 : WalletBatch *encrypted_batch = nullptr; 134 : 135 : // Key pool maps 136 : std::set<int64_t> setInternalKeyPool; 137 : std::set<int64_t> setExternalKeyPool; 138 : std::set<int64_t> setStakingKeyPool; 139 : int64_t m_max_keypool_index = 0; 140 : std::map<CKeyID, int64_t> m_pool_key_to_index; 141 : // Tracks keypool indexes to CKeyIDs of keys that have been taken out of the keypool but may be returned to it 142 : std::map<int64_t, CKeyID> m_index_to_reserved_key; 143 : 144 : /* */ 145 : bool AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey); 146 : 147 : //! Adds a key to the store, and saves it to disk. 148 : bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey); 149 : /* Complete me */ 150 : void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const uint8_t& type, WalletBatch& batch); 151 : void GeneratePool(WalletBatch& batch, int64_t targetSize, const uint8_t& type); 152 : 153 : /* HD derive new child key (on internal or external chain) */ 154 : void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey& secret, const uint8_t& type = HDChain::ChangeType::EXTERNAL); 155 : 156 : /** 157 : * Marks all keys in the keypool up to and including reserve_key as used. 158 : */ 159 : void MarkReserveKeysAsUsed(int64_t keypool_id); 160 : }; 161 : 162 : 163 : #endif // PIVX_WALLET_SCRIPTPUBKEYMAN_H