1 // Copyright (c) 2019-2020 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <key_io.h>
6 #include <logging.h>
7 #include <outputtype.h>
8 #include <script/descriptor.h>
9 #include <script/sign.h>
10 #include <util/bip32.h>
11 #include <util/strencodings.h>
12 #include <util/string.h>
13 #include <util/system.h>
14 #include <util/time.h>
15 #include <util/translation.h>
16 #include <wallet/scriptpubkeyman.h>
17 
18 #include <optional>
19 
20 //! Value for the first BIP 32 hardened derivation. Can be used as a bit mask and as a value. See BIP 32 for more details.
21 const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
22 
GetNewDestination(const OutputType type,CTxDestination & dest,std::string & error)23 bool LegacyScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error)
24 {
25     if (LEGACY_OUTPUT_TYPES.count(type) == 0) {
26         error = _("Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types").translated;
27         return false;
28     }
29     assert(type != OutputType::BECH32M);
30 
31     LOCK(cs_KeyStore);
32     error.clear();
33 
34     // Generate a new key that is added to wallet
35     CPubKey new_key;
36     if (!GetKeyFromPool(new_key, type)) {
37         error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
38         return false;
39     }
40     LearnRelatedScripts(new_key, type);
41     dest = GetDestinationForKey(new_key, type);
42     return true;
43 }
44 
45 typedef std::vector<unsigned char> valtype;
46 
47 namespace {
48 
49 /**
50  * This is an enum that tracks the execution context of a script, similar to
51  * SigVersion in script/interpreter. It is separate however because we want to
52  * distinguish between top-level scriptPubKey execution and P2SH redeemScript
53  * execution (a distinction that has no impact on consensus rules).
54  */
55 enum class IsMineSigVersion
56 {
57     TOP = 0,        //!< scriptPubKey execution
58     P2SH = 1,       //!< P2SH redeemScript
59     WITNESS_V0 = 2, //!< P2WSH witness script execution
60 };
61 
62 /**
63  * This is an internal representation of isminetype + invalidity.
64  * Its order is significant, as we return the max of all explored
65  * possibilities.
66  */
67 enum class IsMineResult
68 {
69     NO = 0,         //!< Not ours
70     WATCH_ONLY = 1, //!< Included in watch-only balance
71     SPENDABLE = 2,  //!< Included in all balances
72     INVALID = 3,    //!< Not spendable by anyone (uncompressed pubkey in segwit, P2SH inside P2SH or witness, witness inside witness)
73 };
74 
PermitsUncompressed(IsMineSigVersion sigversion)75 bool PermitsUncompressed(IsMineSigVersion sigversion)
76 {
77     return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
78 }
79 
HaveKeys(const std::vector<valtype> & pubkeys,const LegacyScriptPubKeyMan & keystore)80 bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyScriptPubKeyMan& keystore)
81 {
82     for (const valtype& pubkey : pubkeys) {
83         CKeyID keyID = CPubKey(pubkey).GetID();
84         if (!keystore.HaveKey(keyID)) return false;
85     }
86     return true;
87 }
88 
89 //! Recursively solve script and return spendable/watchonly/invalid status.
90 //!
91 //! @param keystore            legacy key and script store
92 //! @param scriptPubKey        script to solve
93 //! @param sigversion          script type (top-level / redeemscript / witnessscript)
94 //! @param recurse_scripthash  whether to recurse into nested p2sh and p2wsh
95 //!                            scripts or simply treat any script that has been
96 //!                            stored in the keystore as spendable
IsMineInner(const LegacyScriptPubKeyMan & keystore,const CScript & scriptPubKey,IsMineSigVersion sigversion,bool recurse_scripthash=true)97 IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion, bool recurse_scripthash=true)
98 {
99     IsMineResult ret = IsMineResult::NO;
100 
101     std::vector<valtype> vSolutions;
102     TxoutType whichType = Solver(scriptPubKey, vSolutions);
103 
104     CKeyID keyID;
105     switch (whichType) {
106     case TxoutType::NONSTANDARD:
107     case TxoutType::NULL_DATA:
108     case TxoutType::WITNESS_UNKNOWN:
109     case TxoutType::WITNESS_V1_TAPROOT:
110         break;
111     case TxoutType::PUBKEY:
112         keyID = CPubKey(vSolutions[0]).GetID();
113         if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
114             return IsMineResult::INVALID;
115         }
116         if (keystore.HaveKey(keyID)) {
117             ret = std::max(ret, IsMineResult::SPENDABLE);
118         }
119         break;
120     case TxoutType::WITNESS_V0_KEYHASH:
121     {
122         if (sigversion == IsMineSigVersion::WITNESS_V0) {
123             // P2WPKH inside P2WSH is invalid.
124             return IsMineResult::INVALID;
125         }
126         if (sigversion == IsMineSigVersion::TOP && !keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
127             // We do not support bare witness outputs unless the P2SH version of it would be
128             // acceptable as well. This protects against matching before segwit activates.
129             // This also applies to the P2WSH case.
130             break;
131         }
132         ret = std::max(ret, IsMineInner(keystore, GetScriptForDestination(PKHash(uint160(vSolutions[0]))), IsMineSigVersion::WITNESS_V0));
133         break;
134     }
135     case TxoutType::PUBKEYHASH:
136         keyID = CKeyID(uint160(vSolutions[0]));
137         if (!PermitsUncompressed(sigversion)) {
138             CPubKey pubkey;
139             if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) {
140                 return IsMineResult::INVALID;
141             }
142         }
143         if (keystore.HaveKey(keyID)) {
144             ret = std::max(ret, IsMineResult::SPENDABLE);
145         }
146         break;
147     case TxoutType::SCRIPTHASH:
148     {
149         if (sigversion != IsMineSigVersion::TOP) {
150             // P2SH inside P2WSH or P2SH is invalid.
151             return IsMineResult::INVALID;
152         }
153         CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
154         CScript subscript;
155         if (keystore.GetCScript(scriptID, subscript)) {
156             ret = std::max(ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::P2SH) : IsMineResult::SPENDABLE);
157         }
158         break;
159     }
160     case TxoutType::WITNESS_V0_SCRIPTHASH:
161     {
162         if (sigversion == IsMineSigVersion::WITNESS_V0) {
163             // P2WSH inside P2WSH is invalid.
164             return IsMineResult::INVALID;
165         }
166         if (sigversion == IsMineSigVersion::TOP && !keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
167             break;
168         }
169         uint160 hash;
170         CRIPEMD160().Write(vSolutions[0].data(), vSolutions[0].size()).Finalize(hash.begin());
171         CScriptID scriptID = CScriptID(hash);
172         CScript subscript;
173         if (keystore.GetCScript(scriptID, subscript)) {
174             ret = std::max(ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::WITNESS_V0) : IsMineResult::SPENDABLE);
175         }
176         break;
177     }
178 
179     case TxoutType::MULTISIG:
180     {
181         // Never treat bare multisig outputs as ours (they can still be made watchonly-though)
182         if (sigversion == IsMineSigVersion::TOP) {
183             break;
184         }
185 
186         // Only consider transactions "mine" if we own ALL the
187         // keys involved. Multi-signature transactions that are
188         // partially owned (somebody else has a key that can spend
189         // them) enable spend-out-from-under-you attacks, especially
190         // in shared-wallet situations.
191         std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
192         if (!PermitsUncompressed(sigversion)) {
193             for (size_t i = 0; i < keys.size(); i++) {
194                 if (keys[i].size() != 33) {
195                     return IsMineResult::INVALID;
196                 }
197             }
198         }
199         if (HaveKeys(keys, keystore)) {
200             ret = std::max(ret, IsMineResult::SPENDABLE);
201         }
202         break;
203     }
204     } // no default case, so the compiler can warn about missing cases
205 
206     if (ret == IsMineResult::NO && keystore.HaveWatchOnly(scriptPubKey)) {
207         ret = std::max(ret, IsMineResult::WATCH_ONLY);
208     }
209     return ret;
210 }
211 
212 } // namespace
213 
IsMine(const CScript & script) const214 isminetype LegacyScriptPubKeyMan::IsMine(const CScript& script) const
215 {
216     switch (IsMineInner(*this, script, IsMineSigVersion::TOP)) {
217     case IsMineResult::INVALID:
218     case IsMineResult::NO:
219         return ISMINE_NO;
220     case IsMineResult::WATCH_ONLY:
221         return ISMINE_WATCH_ONLY;
222     case IsMineResult::SPENDABLE:
223         return ISMINE_SPENDABLE;
224     }
225     assert(false);
226 }
227 
CheckDecryptionKey(const CKeyingMaterial & master_key,bool accept_no_keys)228 bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys)
229 {
230     {
231         LOCK(cs_KeyStore);
232         assert(mapKeys.empty());
233 
234         bool keyPass = mapCryptedKeys.empty(); // Always pass when there are no encrypted keys
235         bool keyFail = false;
236         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
237         WalletBatch batch(m_storage.GetDatabase());
238         for (; mi != mapCryptedKeys.end(); ++mi)
239         {
240             const CPubKey &vchPubKey = (*mi).second.first;
241             const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
242             CKey key;
243             if (!DecryptKey(master_key, vchCryptedSecret, vchPubKey, key))
244             {
245                 keyFail = true;
246                 break;
247             }
248             keyPass = true;
249             if (fDecryptionThoroughlyChecked)
250                 break;
251             else {
252                 // Rewrite these encrypted keys with checksums
253                 batch.WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
254             }
255         }
256         if (keyPass && keyFail)
257         {
258             LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n");
259             throw std::runtime_error("Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
260         }
261         if (keyFail || (!keyPass && !accept_no_keys))
262             return false;
263         fDecryptionThoroughlyChecked = true;
264     }
265     return true;
266 }
267 
Encrypt(const CKeyingMaterial & master_key,WalletBatch * batch)268 bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch)
269 {
270     LOCK(cs_KeyStore);
271     encrypted_batch = batch;
272     if (!mapCryptedKeys.empty()) {
273         encrypted_batch = nullptr;
274         return false;
275     }
276 
277     KeyMap keys_to_encrypt;
278     keys_to_encrypt.swap(mapKeys); // Clear mapKeys so AddCryptedKeyInner will succeed.
279     for (const KeyMap::value_type& mKey : keys_to_encrypt)
280     {
281         const CKey &key = mKey.second;
282         CPubKey vchPubKey = key.GetPubKey();
283         CKeyingMaterial vchSecret(key.begin(), key.end());
284         std::vector<unsigned char> vchCryptedSecret;
285         if (!EncryptSecret(master_key, vchSecret, vchPubKey.GetHash(), vchCryptedSecret)) {
286             encrypted_batch = nullptr;
287             return false;
288         }
289         if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) {
290             encrypted_batch = nullptr;
291             return false;
292         }
293     }
294     encrypted_batch = nullptr;
295     return true;
296 }
297 
GetReservedDestination(const OutputType type,bool internal,CTxDestination & address,int64_t & index,CKeyPool & keypool,std::string & error)298 bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error)
299 {
300     if (LEGACY_OUTPUT_TYPES.count(type) == 0) {
301         error = _("Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types").translated;
302         return false;
303     }
304     assert(type != OutputType::BECH32M);
305 
306     LOCK(cs_KeyStore);
307     if (!CanGetAddresses(internal)) {
308         error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
309         return false;
310     }
311 
312     if (!ReserveKeyFromKeyPool(index, keypool, internal)) {
313         error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
314         return false;
315     }
316     address = GetDestinationForKey(keypool.vchPubKey, type);
317     return true;
318 }
319 
TopUpInactiveHDChain(const CKeyID seed_id,int64_t index,bool internal)320 bool LegacyScriptPubKeyMan::TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal)
321 {
322     LOCK(cs_KeyStore);
323 
324     if (m_storage.IsLocked()) return false;
325 
326     auto it = m_inactive_hd_chains.find(seed_id);
327     if (it == m_inactive_hd_chains.end()) {
328         return false;
329     }
330 
331     CHDChain& chain = it->second;
332 
333     // Top up key pool
334     int64_t target_size = std::max(gArgs.GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 1);
335 
336     // "size" of the keypools. Not really the size, actually the difference between index and the chain counter
337     // Since chain counter is 1 based and index is 0 based, one of them needs to be offset by 1.
338     int64_t kp_size = (internal ? chain.nInternalChainCounter : chain.nExternalChainCounter) - (index + 1);
339 
340     // make sure the keypool fits the user-selected target (-keypool)
341     int64_t missing = std::max(target_size - kp_size, (int64_t) 0);
342 
343     if (missing > 0) {
344         WalletBatch batch(m_storage.GetDatabase());
345         for (int64_t i = missing; i > 0; --i) {
346             GenerateNewKey(batch, chain, internal);
347         }
348         if (internal) {
349             WalletLogPrintf("inactive seed with id %s added %d internal keys\n", HexStr(seed_id), missing);
350         } else {
351             WalletLogPrintf("inactive seed with id %s added %d keys\n", HexStr(seed_id), missing);
352         }
353     }
354     return true;
355 }
356 
MarkUnusedAddresses(const CScript & script)357 void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
358 {
359     LOCK(cs_KeyStore);
360     // extract addresses and check if they match with an unused keypool key
361     for (const auto& keyid : GetAffectedKeys(script, *this)) {
362         std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
363         if (mi != m_pool_key_to_index.end()) {
364             WalletLogPrintf("%s: Detected a used keypool key, mark all keypool keys up to this key as used\n", __func__);
365             MarkReserveKeysAsUsed(mi->second);
366 
367             if (!TopUp()) {
368                 WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
369             }
370         }
371 
372         // Find the key's metadata and check if it's seed id (if it has one) is inactive, i.e. it is not the current m_hd_chain seed id.
373         // If so, TopUp the inactive hd chain
374         auto it = mapKeyMetadata.find(keyid);
375         if (it != mapKeyMetadata.end()){
376             CKeyMetadata meta = it->second;
377             if (!meta.hd_seed_id.IsNull() && meta.hd_seed_id != m_hd_chain.seed_id) {
378                 bool internal = (meta.key_origin.path[1] & ~BIP32_HARDENED_KEY_LIMIT) != 0;
379                 int64_t index = meta.key_origin.path[2] & ~BIP32_HARDENED_KEY_LIMIT;
380 
381                 if (!TopUpInactiveHDChain(meta.hd_seed_id, index, internal)) {
382                     WalletLogPrintf("%s: Adding inactive seed keys failed\n", __func__);
383                 }
384             }
385         }
386     }
387 }
388 
UpgradeKeyMetadata()389 void LegacyScriptPubKeyMan::UpgradeKeyMetadata()
390 {
391     LOCK(cs_KeyStore);
392     if (m_storage.IsLocked() || m_storage.IsWalletFlagSet(WALLET_FLAG_KEY_ORIGIN_METADATA)) {
393         return;
394     }
395 
396     std::unique_ptr<WalletBatch> batch = std::make_unique<WalletBatch>(m_storage.GetDatabase());
397     for (auto& meta_pair : mapKeyMetadata) {
398         CKeyMetadata& meta = meta_pair.second;
399         if (!meta.hd_seed_id.IsNull() && !meta.has_key_origin && meta.hdKeypath != "s") { // If the hdKeypath is "s", that's the seed and it doesn't have a key origin
400             CKey key;
401             GetKey(meta.hd_seed_id, key);
402             CExtKey masterKey;
403             masterKey.SetSeed(key.begin(), key.size());
404             // Add to map
405             CKeyID master_id = masterKey.key.GetPubKey().GetID();
406             std::copy(master_id.begin(), master_id.begin() + 4, meta.key_origin.fingerprint);
407             if (!ParseHDKeypath(meta.hdKeypath, meta.key_origin.path)) {
408                 throw std::runtime_error("Invalid stored hdKeypath");
409             }
410             meta.has_key_origin = true;
411             if (meta.nVersion < CKeyMetadata::VERSION_WITH_KEY_ORIGIN) {
412                 meta.nVersion = CKeyMetadata::VERSION_WITH_KEY_ORIGIN;
413             }
414 
415             // Write meta to wallet
416             CPubKey pubkey;
417             if (GetPubKey(meta_pair.first, pubkey)) {
418                 batch->WriteKeyMetadata(meta, pubkey, true);
419             }
420         }
421     }
422 }
423 
SetupGeneration(bool force)424 bool LegacyScriptPubKeyMan::SetupGeneration(bool force)
425 {
426     if ((CanGenerateKeys() && !force) || m_storage.IsLocked()) {
427         return false;
428     }
429 
430     SetHDSeed(GenerateNewSeed());
431     if (!NewKeyPool()) {
432         return false;
433     }
434     return true;
435 }
436 
IsHDEnabled() const437 bool LegacyScriptPubKeyMan::IsHDEnabled() const
438 {
439     return !m_hd_chain.seed_id.IsNull();
440 }
441 
CanGetAddresses(bool internal) const442 bool LegacyScriptPubKeyMan::CanGetAddresses(bool internal) const
443 {
444     LOCK(cs_KeyStore);
445     // Check if the keypool has keys
446     bool keypool_has_keys;
447     if (internal && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) {
448         keypool_has_keys = setInternalKeyPool.size() > 0;
449     } else {
450         keypool_has_keys = KeypoolCountExternalKeys() > 0;
451     }
452     // If the keypool doesn't have keys, check if we can generate them
453     if (!keypool_has_keys) {
454         return CanGenerateKeys();
455     }
456     return keypool_has_keys;
457 }
458 
Upgrade(int prev_version,int new_version,bilingual_str & error)459 bool LegacyScriptPubKeyMan::Upgrade(int prev_version, int new_version, bilingual_str& error)
460 {
461     LOCK(cs_KeyStore);
462     bool hd_upgrade = false;
463     bool split_upgrade = false;
464     if (IsFeatureSupported(new_version, FEATURE_HD) && !IsHDEnabled()) {
465         WalletLogPrintf("Upgrading wallet to HD\n");
466         m_storage.SetMinVersion(FEATURE_HD);
467 
468         // generate a new master key
469         CPubKey masterPubKey = GenerateNewSeed();
470         SetHDSeed(masterPubKey);
471         hd_upgrade = true;
472     }
473     // Upgrade to HD chain split if necessary
474     if (!IsFeatureSupported(prev_version, FEATURE_HD_SPLIT) && IsFeatureSupported(new_version, FEATURE_HD_SPLIT)) {
475         WalletLogPrintf("Upgrading wallet to use HD chain split\n");
476         m_storage.SetMinVersion(FEATURE_PRE_SPLIT_KEYPOOL);
477         split_upgrade = FEATURE_HD_SPLIT > prev_version;
478         // Upgrade the HDChain
479         if (m_hd_chain.nVersion < CHDChain::VERSION_HD_CHAIN_SPLIT) {
480             m_hd_chain.nVersion = CHDChain::VERSION_HD_CHAIN_SPLIT;
481             if (!WalletBatch(m_storage.GetDatabase()).WriteHDChain(m_hd_chain)) {
482                 throw std::runtime_error(std::string(__func__) + ": writing chain failed");
483             }
484         }
485     }
486     // Mark all keys currently in the keypool as pre-split
487     if (split_upgrade) {
488         MarkPreSplitKeys();
489     }
490     // Regenerate the keypool if upgraded to HD
491     if (hd_upgrade) {
492         if (!TopUp()) {
493             error = _("Unable to generate keys");
494             return false;
495         }
496     }
497     return true;
498 }
499 
HavePrivateKeys() const500 bool LegacyScriptPubKeyMan::HavePrivateKeys() const
501 {
502     LOCK(cs_KeyStore);
503     return !mapKeys.empty() || !mapCryptedKeys.empty();
504 }
505 
RewriteDB()506 void LegacyScriptPubKeyMan::RewriteDB()
507 {
508     LOCK(cs_KeyStore);
509     setInternalKeyPool.clear();
510     setExternalKeyPool.clear();
511     m_pool_key_to_index.clear();
512     // Note: can't top-up keypool here, because wallet is locked.
513     // User will be prompted to unlock wallet the next operation
514     // that requires a new key.
515 }
516 
GetOldestKeyTimeInPool(const std::set<int64_t> & setKeyPool,WalletBatch & batch)517 static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, WalletBatch& batch) {
518     if (setKeyPool.empty()) {
519         return GetTime();
520     }
521 
522     CKeyPool keypool;
523     int64_t nIndex = *(setKeyPool.begin());
524     if (!batch.ReadPool(nIndex, keypool)) {
525         throw std::runtime_error(std::string(__func__) + ": read oldest key in keypool failed");
526     }
527     assert(keypool.vchPubKey.IsValid());
528     return keypool.nTime;
529 }
530 
GetOldestKeyPoolTime() const531 int64_t LegacyScriptPubKeyMan::GetOldestKeyPoolTime() const
532 {
533     LOCK(cs_KeyStore);
534 
535     WalletBatch batch(m_storage.GetDatabase());
536 
537     // load oldest key from keypool, get time and return
538     int64_t oldestKey = GetOldestKeyTimeInPool(setExternalKeyPool, batch);
539     if (IsHDEnabled() && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) {
540         oldestKey = std::max(GetOldestKeyTimeInPool(setInternalKeyPool, batch), oldestKey);
541         if (!set_pre_split_keypool.empty()) {
542             oldestKey = std::max(GetOldestKeyTimeInPool(set_pre_split_keypool, batch), oldestKey);
543         }
544     }
545 
546     return oldestKey;
547 }
548 
KeypoolCountExternalKeys() const549 size_t LegacyScriptPubKeyMan::KeypoolCountExternalKeys() const
550 {
551     LOCK(cs_KeyStore);
552     return setExternalKeyPool.size() + set_pre_split_keypool.size();
553 }
554 
GetKeyPoolSize() const555 unsigned int LegacyScriptPubKeyMan::GetKeyPoolSize() const
556 {
557     LOCK(cs_KeyStore);
558     return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
559 }
560 
GetTimeFirstKey() const561 int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const
562 {
563     LOCK(cs_KeyStore);
564     return nTimeFirstKey;
565 }
566 
GetSolvingProvider(const CScript & script) const567 std::unique_ptr<SigningProvider> LegacyScriptPubKeyMan::GetSolvingProvider(const CScript& script) const
568 {
569     return std::make_unique<LegacySigningProvider>(*this);
570 }
571 
CanProvide(const CScript & script,SignatureData & sigdata)572 bool LegacyScriptPubKeyMan::CanProvide(const CScript& script, SignatureData& sigdata)
573 {
574     IsMineResult ismine = IsMineInner(*this, script, IsMineSigVersion::TOP, /* recurse_scripthash= */ false);
575     if (ismine == IsMineResult::SPENDABLE || ismine == IsMineResult::WATCH_ONLY) {
576         // If ismine, it means we recognize keys or script ids in the script, or
577         // are watching the script itself, and we can at least provide metadata
578         // or solving information, even if not able to sign fully.
579         return true;
580     } else {
581         // If, given the stuff in sigdata, we could make a valid sigature, then we can provide for this script
582         ProduceSignature(*this, DUMMY_SIGNATURE_CREATOR, script, sigdata);
583         if (!sigdata.signatures.empty()) {
584             // If we could make signatures, make sure we have a private key to actually make a signature
585             bool has_privkeys = false;
586             for (const auto& key_sig_pair : sigdata.signatures) {
587                 has_privkeys |= HaveKey(key_sig_pair.first);
588             }
589             return has_privkeys;
590         }
591         return false;
592     }
593 }
594 
SignTransaction(CMutableTransaction & tx,const std::map<COutPoint,Coin> & coins,int sighash,std::map<int,std::string> & input_errors) const595 bool LegacyScriptPubKeyMan::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const
596 {
597     return ::SignTransaction(tx, this, coins, sighash, input_errors);
598 }
599 
SignMessage(const std::string & message,const PKHash & pkhash,std::string & str_sig) const600 SigningResult LegacyScriptPubKeyMan::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const
601 {
602     CKey key;
603     if (!GetKey(ToKeyID(pkhash), key)) {
604         return SigningResult::PRIVATE_KEY_NOT_AVAILABLE;
605     }
606 
607     if (MessageSign(key, message, str_sig)) {
608         return SigningResult::OK;
609     }
610     return SigningResult::SIGNING_FAILED;
611 }
612 
FillPSBT(PartiallySignedTransaction & psbtx,const PrecomputedTransactionData & txdata,int sighash_type,bool sign,bool bip32derivs,int * n_signed) const613 TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed) const
614 {
615     if (n_signed) {
616         *n_signed = 0;
617     }
618     for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
619         const CTxIn& txin = psbtx.tx->vin[i];
620         PSBTInput& input = psbtx.inputs.at(i);
621 
622         if (PSBTInputSigned(input)) {
623             continue;
624         }
625 
626         // Get the Sighash type
627         if (sign && input.sighash_type > 0 && input.sighash_type != sighash_type) {
628             return TransactionError::SIGHASH_MISMATCH;
629         }
630 
631         // Check non_witness_utxo has specified prevout
632         if (input.non_witness_utxo) {
633             if (txin.prevout.n >= input.non_witness_utxo->vout.size()) {
634                 return TransactionError::MISSING_INPUTS;
635             }
636         } else if (input.witness_utxo.IsNull()) {
637             // There's no UTXO so we can just skip this now
638             continue;
639         }
640         SignatureData sigdata;
641         input.FillSignatureData(sigdata);
642         SignPSBTInput(HidingSigningProvider(this, !sign, !bip32derivs), psbtx, i, &txdata, sighash_type);
643 
644         bool signed_one = PSBTInputSigned(input);
645         if (n_signed && (signed_one || !sign)) {
646             // If sign is false, we assume that we _could_ sign if we get here. This
647             // will never have false negatives; it is hard to tell under what i
648             // circumstances it could have false positives.
649             (*n_signed)++;
650         }
651     }
652 
653     // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
654     for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
655         UpdatePSBTOutput(HidingSigningProvider(this, true, !bip32derivs), psbtx, i);
656     }
657 
658     return TransactionError::OK;
659 }
660 
GetMetadata(const CTxDestination & dest) const661 std::unique_ptr<CKeyMetadata> LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const
662 {
663     LOCK(cs_KeyStore);
664 
665     CKeyID key_id = GetKeyForDestination(*this, dest);
666     if (!key_id.IsNull()) {
667         auto it = mapKeyMetadata.find(key_id);
668         if (it != mapKeyMetadata.end()) {
669             return std::make_unique<CKeyMetadata>(it->second);
670         }
671     }
672 
673     CScript scriptPubKey = GetScriptForDestination(dest);
674     auto it = m_script_metadata.find(CScriptID(scriptPubKey));
675     if (it != m_script_metadata.end()) {
676         return std::make_unique<CKeyMetadata>(it->second);
677     }
678 
679     return nullptr;
680 }
681 
GetID() const682 uint256 LegacyScriptPubKeyMan::GetID() const
683 {
684     return uint256::ONE;
685 }
686 
687 /**
688  * Update wallet first key creation time. This should be called whenever keys
689  * are added to the wallet, with the oldest key creation time.
690  */
UpdateTimeFirstKey(int64_t nCreateTime)691 void LegacyScriptPubKeyMan::UpdateTimeFirstKey(int64_t nCreateTime)
692 {
693     AssertLockHeld(cs_KeyStore);
694     if (nCreateTime <= 1) {
695         // Cannot determine birthday information, so set the wallet birthday to
696         // the beginning of time.
697         nTimeFirstKey = 1;
698     } else if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) {
699         nTimeFirstKey = nCreateTime;
700     }
701 }
702 
LoadKey(const CKey & key,const CPubKey & pubkey)703 bool LegacyScriptPubKeyMan::LoadKey(const CKey& key, const CPubKey &pubkey)
704 {
705     return AddKeyPubKeyInner(key, pubkey);
706 }
707 
AddKeyPubKey(const CKey & secret,const CPubKey & pubkey)708 bool LegacyScriptPubKeyMan::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
709 {
710     LOCK(cs_KeyStore);
711     WalletBatch batch(m_storage.GetDatabase());
712     return LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(batch, secret, pubkey);
713 }
714 
AddKeyPubKeyWithDB(WalletBatch & batch,const CKey & secret,const CPubKey & pubkey)715 bool LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& secret, const CPubKey& pubkey)
716 {
717     AssertLockHeld(cs_KeyStore);
718 
719     // Make sure we aren't adding private keys to private key disabled wallets
720     assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
721 
722     // FillableSigningProvider has no concept of wallet databases, but calls AddCryptedKey
723     // which is overridden below.  To avoid flushes, the database handle is
724     // tunneled through to it.
725     bool needsDB = !encrypted_batch;
726     if (needsDB) {
727         encrypted_batch = &batch;
728     }
729     if (!AddKeyPubKeyInner(secret, pubkey)) {
730         if (needsDB) encrypted_batch = nullptr;
731         return false;
732     }
733     if (needsDB) encrypted_batch = nullptr;
734 
735     // check if we need to remove from watch-only
736     CScript script;
737     script = GetScriptForDestination(PKHash(pubkey));
738     if (HaveWatchOnly(script)) {
739         RemoveWatchOnly(script);
740     }
741     script = GetScriptForRawPubKey(pubkey);
742     if (HaveWatchOnly(script)) {
743         RemoveWatchOnly(script);
744     }
745 
746     if (!m_storage.HasEncryptionKeys()) {
747         return batch.WriteKey(pubkey,
748                                                  secret.GetPrivKey(),
749                                                  mapKeyMetadata[pubkey.GetID()]);
750     }
751     m_storage.UnsetBlankWalletFlag(batch);
752     return true;
753 }
754 
LoadCScript(const CScript & redeemScript)755 bool LegacyScriptPubKeyMan::LoadCScript(const CScript& redeemScript)
756 {
757     /* A sanity check was added in pull #3843 to avoid adding redeemScripts
758      * that never can be redeemed. However, old wallets may still contain
759      * these. Do not add them to the wallet and warn. */
760     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
761     {
762         std::string strAddr = EncodeDestination(ScriptHash(redeemScript));
763         WalletLogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n", __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
764         return true;
765     }
766 
767     return FillableSigningProvider::AddCScript(redeemScript);
768 }
769 
LoadKeyMetadata(const CKeyID & keyID,const CKeyMetadata & meta)770 void LegacyScriptPubKeyMan::LoadKeyMetadata(const CKeyID& keyID, const CKeyMetadata& meta)
771 {
772     LOCK(cs_KeyStore);
773     UpdateTimeFirstKey(meta.nCreateTime);
774     mapKeyMetadata[keyID] = meta;
775 }
776 
LoadScriptMetadata(const CScriptID & script_id,const CKeyMetadata & meta)777 void LegacyScriptPubKeyMan::LoadScriptMetadata(const CScriptID& script_id, const CKeyMetadata& meta)
778 {
779     LOCK(cs_KeyStore);
780     UpdateTimeFirstKey(meta.nCreateTime);
781     m_script_metadata[script_id] = meta;
782 }
783 
AddKeyPubKeyInner(const CKey & key,const CPubKey & pubkey)784 bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey)
785 {
786     LOCK(cs_KeyStore);
787     if (!m_storage.HasEncryptionKeys()) {
788         return FillableSigningProvider::AddKeyPubKey(key, pubkey);
789     }
790 
791     if (m_storage.IsLocked()) {
792         return false;
793     }
794 
795     std::vector<unsigned char> vchCryptedSecret;
796     CKeyingMaterial vchSecret(key.begin(), key.end());
797     if (!EncryptSecret(m_storage.GetEncryptionKey(), vchSecret, pubkey.GetHash(), vchCryptedSecret)) {
798         return false;
799     }
800 
801     if (!AddCryptedKey(pubkey, vchCryptedSecret)) {
802         return false;
803     }
804     return true;
805 }
806 
LoadCryptedKey(const CPubKey & vchPubKey,const std::vector<unsigned char> & vchCryptedSecret,bool checksum_valid)807 bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid)
808 {
809     // Set fDecryptionThoroughlyChecked to false when the checksum is invalid
810     if (!checksum_valid) {
811         fDecryptionThoroughlyChecked = false;
812     }
813 
814     return AddCryptedKeyInner(vchPubKey, vchCryptedSecret);
815 }
816 
AddCryptedKeyInner(const CPubKey & vchPubKey,const std::vector<unsigned char> & vchCryptedSecret)817 bool LegacyScriptPubKeyMan::AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
818 {
819     LOCK(cs_KeyStore);
820     assert(mapKeys.empty());
821 
822     mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
823     ImplicitlyLearnRelatedKeyScripts(vchPubKey);
824     return true;
825 }
826 
AddCryptedKey(const CPubKey & vchPubKey,const std::vector<unsigned char> & vchCryptedSecret)827 bool LegacyScriptPubKeyMan::AddCryptedKey(const CPubKey &vchPubKey,
828                             const std::vector<unsigned char> &vchCryptedSecret)
829 {
830     if (!AddCryptedKeyInner(vchPubKey, vchCryptedSecret))
831         return false;
832     {
833         LOCK(cs_KeyStore);
834         if (encrypted_batch)
835             return encrypted_batch->WriteCryptedKey(vchPubKey,
836                                                         vchCryptedSecret,
837                                                         mapKeyMetadata[vchPubKey.GetID()]);
838         else
839             return WalletBatch(m_storage.GetDatabase()).WriteCryptedKey(vchPubKey,
840                                                             vchCryptedSecret,
841                                                             mapKeyMetadata[vchPubKey.GetID()]);
842     }
843 }
844 
HaveWatchOnly(const CScript & dest) const845 bool LegacyScriptPubKeyMan::HaveWatchOnly(const CScript &dest) const
846 {
847     LOCK(cs_KeyStore);
848     return setWatchOnly.count(dest) > 0;
849 }
850 
HaveWatchOnly() const851 bool LegacyScriptPubKeyMan::HaveWatchOnly() const
852 {
853     LOCK(cs_KeyStore);
854     return (!setWatchOnly.empty());
855 }
856 
ExtractPubKey(const CScript & dest,CPubKey & pubKeyOut)857 static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
858 {
859     std::vector<std::vector<unsigned char>> solutions;
860     return Solver(dest, solutions) == TxoutType::PUBKEY &&
861         (pubKeyOut = CPubKey(solutions[0])).IsFullyValid();
862 }
863 
RemoveWatchOnly(const CScript & dest)864 bool LegacyScriptPubKeyMan::RemoveWatchOnly(const CScript &dest)
865 {
866     {
867         LOCK(cs_KeyStore);
868         setWatchOnly.erase(dest);
869         CPubKey pubKey;
870         if (ExtractPubKey(dest, pubKey)) {
871             mapWatchKeys.erase(pubKey.GetID());
872         }
873         // Related CScripts are not removed; having superfluous scripts around is
874         // harmless (see comment in ImplicitlyLearnRelatedKeyScripts).
875     }
876 
877     if (!HaveWatchOnly())
878         NotifyWatchonlyChanged(false);
879     if (!WalletBatch(m_storage.GetDatabase()).EraseWatchOnly(dest))
880         return false;
881 
882     return true;
883 }
884 
LoadWatchOnly(const CScript & dest)885 bool LegacyScriptPubKeyMan::LoadWatchOnly(const CScript &dest)
886 {
887     return AddWatchOnlyInMem(dest);
888 }
889 
AddWatchOnlyInMem(const CScript & dest)890 bool LegacyScriptPubKeyMan::AddWatchOnlyInMem(const CScript &dest)
891 {
892     LOCK(cs_KeyStore);
893     setWatchOnly.insert(dest);
894     CPubKey pubKey;
895     if (ExtractPubKey(dest, pubKey)) {
896         mapWatchKeys[pubKey.GetID()] = pubKey;
897         ImplicitlyLearnRelatedKeyScripts(pubKey);
898     }
899     return true;
900 }
901 
AddWatchOnlyWithDB(WalletBatch & batch,const CScript & dest)902 bool LegacyScriptPubKeyMan::AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest)
903 {
904     if (!AddWatchOnlyInMem(dest))
905         return false;
906     const CKeyMetadata& meta = m_script_metadata[CScriptID(dest)];
907     UpdateTimeFirstKey(meta.nCreateTime);
908     NotifyWatchonlyChanged(true);
909     if (batch.WriteWatchOnly(dest, meta)) {
910         m_storage.UnsetBlankWalletFlag(batch);
911         return true;
912     }
913     return false;
914 }
915 
AddWatchOnlyWithDB(WalletBatch & batch,const CScript & dest,int64_t create_time)916 bool LegacyScriptPubKeyMan::AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time)
917 {
918     m_script_metadata[CScriptID(dest)].nCreateTime = create_time;
919     return AddWatchOnlyWithDB(batch, dest);
920 }
921 
AddWatchOnly(const CScript & dest)922 bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest)
923 {
924     WalletBatch batch(m_storage.GetDatabase());
925     return AddWatchOnlyWithDB(batch, dest);
926 }
927 
AddWatchOnly(const CScript & dest,int64_t nCreateTime)928 bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
929 {
930     m_script_metadata[CScriptID(dest)].nCreateTime = nCreateTime;
931     return AddWatchOnly(dest);
932 }
933 
LoadHDChain(const CHDChain & chain)934 void LegacyScriptPubKeyMan::LoadHDChain(const CHDChain& chain)
935 {
936     LOCK(cs_KeyStore);
937     m_hd_chain = chain;
938 }
939 
AddHDChain(const CHDChain & chain)940 void LegacyScriptPubKeyMan::AddHDChain(const CHDChain& chain)
941 {
942     LOCK(cs_KeyStore);
943     // Store the new chain
944     if (!WalletBatch(m_storage.GetDatabase()).WriteHDChain(chain)) {
945         throw std::runtime_error(std::string(__func__) + ": writing chain failed");
946     }
947     // When there's an old chain, add it as an inactive chain as we are now rotating hd chains
948     if (!m_hd_chain.seed_id.IsNull()) {
949         AddInactiveHDChain(m_hd_chain);
950     }
951 
952     m_hd_chain = chain;
953 }
954 
AddInactiveHDChain(const CHDChain & chain)955 void LegacyScriptPubKeyMan::AddInactiveHDChain(const CHDChain& chain)
956 {
957     LOCK(cs_KeyStore);
958     assert(!chain.seed_id.IsNull());
959     m_inactive_hd_chains[chain.seed_id] = chain;
960 }
961 
HaveKey(const CKeyID & address) const962 bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const
963 {
964     LOCK(cs_KeyStore);
965     if (!m_storage.HasEncryptionKeys()) {
966         return FillableSigningProvider::HaveKey(address);
967     }
968     return mapCryptedKeys.count(address) > 0;
969 }
970 
GetKey(const CKeyID & address,CKey & keyOut) const971 bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const
972 {
973     LOCK(cs_KeyStore);
974     if (!m_storage.HasEncryptionKeys()) {
975         return FillableSigningProvider::GetKey(address, keyOut);
976     }
977 
978     CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
979     if (mi != mapCryptedKeys.end())
980     {
981         const CPubKey &vchPubKey = (*mi).second.first;
982         const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
983         return DecryptKey(m_storage.GetEncryptionKey(), vchCryptedSecret, vchPubKey, keyOut);
984     }
985     return false;
986 }
987 
GetKeyOrigin(const CKeyID & keyID,KeyOriginInfo & info) const988 bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& info) const
989 {
990     CKeyMetadata meta;
991     {
992         LOCK(cs_KeyStore);
993         auto it = mapKeyMetadata.find(keyID);
994         if (it != mapKeyMetadata.end()) {
995             meta = it->second;
996         }
997     }
998     if (meta.has_key_origin) {
999         std::copy(meta.key_origin.fingerprint, meta.key_origin.fingerprint + 4, info.fingerprint);
1000         info.path = meta.key_origin.path;
1001     } else { // Single pubkeys get the master fingerprint of themselves
1002         std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint);
1003     }
1004     return true;
1005 }
1006 
GetWatchPubKey(const CKeyID & address,CPubKey & pubkey_out) const1007 bool LegacyScriptPubKeyMan::GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
1008 {
1009     LOCK(cs_KeyStore);
1010     WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
1011     if (it != mapWatchKeys.end()) {
1012         pubkey_out = it->second;
1013         return true;
1014     }
1015     return false;
1016 }
1017 
GetPubKey(const CKeyID & address,CPubKey & vchPubKeyOut) const1018 bool LegacyScriptPubKeyMan::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
1019 {
1020     LOCK(cs_KeyStore);
1021     if (!m_storage.HasEncryptionKeys()) {
1022         if (!FillableSigningProvider::GetPubKey(address, vchPubKeyOut)) {
1023             return GetWatchPubKey(address, vchPubKeyOut);
1024         }
1025         return true;
1026     }
1027 
1028     CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1029     if (mi != mapCryptedKeys.end())
1030     {
1031         vchPubKeyOut = (*mi).second.first;
1032         return true;
1033     }
1034     // Check for watch-only pubkeys
1035     return GetWatchPubKey(address, vchPubKeyOut);
1036 }
1037 
GenerateNewKey(WalletBatch & batch,CHDChain & hd_chain,bool internal)1038 CPubKey LegacyScriptPubKeyMan::GenerateNewKey(WalletBatch &batch, CHDChain& hd_chain, bool internal)
1039 {
1040     assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
1041     assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET));
1042     AssertLockHeld(cs_KeyStore);
1043     bool fCompressed = m_storage.CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
1044 
1045     CKey secret;
1046 
1047     // Create new metadata
1048     int64_t nCreationTime = GetTime();
1049     CKeyMetadata metadata(nCreationTime);
1050 
1051     // use HD key derivation if HD was enabled during wallet creation and a seed is present
1052     if (IsHDEnabled()) {
1053         DeriveNewChildKey(batch, metadata, secret, hd_chain, (m_storage.CanSupportFeature(FEATURE_HD_SPLIT) ? internal : false));
1054     } else {
1055         secret.MakeNewKey(fCompressed);
1056     }
1057 
1058     // Compressed public keys were introduced in version 0.6.0
1059     if (fCompressed) {
1060         m_storage.SetMinVersion(FEATURE_COMPRPUBKEY);
1061     }
1062 
1063     CPubKey pubkey = secret.GetPubKey();
1064     assert(secret.VerifyPubKey(pubkey));
1065 
1066     mapKeyMetadata[pubkey.GetID()] = metadata;
1067     UpdateTimeFirstKey(nCreationTime);
1068 
1069     if (!AddKeyPubKeyWithDB(batch, secret, pubkey)) {
1070         throw std::runtime_error(std::string(__func__) + ": AddKey failed");
1071     }
1072     return pubkey;
1073 }
1074 
DeriveNewChildKey(WalletBatch & batch,CKeyMetadata & metadata,CKey & secret,CHDChain & hd_chain,bool internal)1075 void LegacyScriptPubKeyMan::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey& secret, CHDChain& hd_chain, bool internal)
1076 {
1077     // for now we use a fixed keypath scheme of m/0'/0'/k
1078     CKey seed;                     //seed (256bit)
1079     CExtKey masterKey;             //hd master key
1080     CExtKey accountKey;            //key at m/0'
1081     CExtKey chainChildKey;         //key at m/0'/0' (external) or m/0'/1' (internal)
1082     CExtKey childKey;              //key at m/0'/0'/<n>'
1083 
1084     // try to get the seed
1085     if (!GetKey(hd_chain.seed_id, seed))
1086         throw std::runtime_error(std::string(__func__) + ": seed not found");
1087 
1088     masterKey.SetSeed(seed.begin(), seed.size());
1089 
1090     // derive m/0'
1091     // use hardened derivation (child keys >= 0x80000000 are hardened after bip32)
1092     masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT);
1093 
1094     // derive m/0'/0' (external chain) OR m/0'/1' (internal chain)
1095     assert(internal ? m_storage.CanSupportFeature(FEATURE_HD_SPLIT) : true);
1096     accountKey.Derive(chainChildKey, BIP32_HARDENED_KEY_LIMIT+(internal ? 1 : 0));
1097 
1098     // derive child key at next index, skip keys already known to the wallet
1099     do {
1100         // always derive hardened keys
1101         // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
1102         // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
1103         if (internal) {
1104             chainChildKey.Derive(childKey, hd_chain.nInternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1105             metadata.hdKeypath = "m/0'/1'/" + ToString(hd_chain.nInternalChainCounter) + "'";
1106             metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
1107             metadata.key_origin.path.push_back(1 | BIP32_HARDENED_KEY_LIMIT);
1108             metadata.key_origin.path.push_back(hd_chain.nInternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1109             hd_chain.nInternalChainCounter++;
1110         }
1111         else {
1112             chainChildKey.Derive(childKey, hd_chain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1113             metadata.hdKeypath = "m/0'/0'/" + ToString(hd_chain.nExternalChainCounter) + "'";
1114             metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
1115             metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
1116             metadata.key_origin.path.push_back(hd_chain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1117             hd_chain.nExternalChainCounter++;
1118         }
1119     } while (HaveKey(childKey.key.GetPubKey().GetID()));
1120     secret = childKey.key;
1121     metadata.hd_seed_id = hd_chain.seed_id;
1122     CKeyID master_id = masterKey.key.GetPubKey().GetID();
1123     std::copy(master_id.begin(), master_id.begin() + 4, metadata.key_origin.fingerprint);
1124     metadata.has_key_origin = true;
1125     // update the chain model in the database
1126     if (hd_chain.seed_id == m_hd_chain.seed_id && !batch.WriteHDChain(hd_chain))
1127         throw std::runtime_error(std::string(__func__) + ": writing HD chain model failed");
1128 }
1129 
LoadKeyPool(int64_t nIndex,const CKeyPool & keypool)1130 void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
1131 {
1132     LOCK(cs_KeyStore);
1133     if (keypool.m_pre_split) {
1134         set_pre_split_keypool.insert(nIndex);
1135     } else if (keypool.fInternal) {
1136         setInternalKeyPool.insert(nIndex);
1137     } else {
1138         setExternalKeyPool.insert(nIndex);
1139     }
1140     m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
1141     m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex;
1142 
1143     // If no metadata exists yet, create a default with the pool key's
1144     // creation time. Note that this may be overwritten by actually
1145     // stored metadata for that key later, which is fine.
1146     CKeyID keyid = keypool.vchPubKey.GetID();
1147     if (mapKeyMetadata.count(keyid) == 0)
1148         mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
1149 }
1150 
CanGenerateKeys() const1151 bool LegacyScriptPubKeyMan::CanGenerateKeys() const
1152 {
1153     // A wallet can generate keys if it has an HD seed (IsHDEnabled) or it is a non-HD wallet (pre FEATURE_HD)
1154     LOCK(cs_KeyStore);
1155     return IsHDEnabled() || !m_storage.CanSupportFeature(FEATURE_HD);
1156 }
1157 
GenerateNewSeed()1158 CPubKey LegacyScriptPubKeyMan::GenerateNewSeed()
1159 {
1160     assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
1161     CKey key;
1162     key.MakeNewKey(true);
1163     return DeriveNewSeed(key);
1164 }
1165 
DeriveNewSeed(const CKey & key)1166 CPubKey LegacyScriptPubKeyMan::DeriveNewSeed(const CKey& key)
1167 {
1168     int64_t nCreationTime = GetTime();
1169     CKeyMetadata metadata(nCreationTime);
1170 
1171     // calculate the seed
1172     CPubKey seed = key.GetPubKey();
1173     assert(key.VerifyPubKey(seed));
1174 
1175     // set the hd keypath to "s" -> Seed, refers the seed to itself
1176     metadata.hdKeypath     = "s";
1177     metadata.has_key_origin = false;
1178     metadata.hd_seed_id = seed.GetID();
1179 
1180     {
1181         LOCK(cs_KeyStore);
1182 
1183         // mem store the metadata
1184         mapKeyMetadata[seed.GetID()] = metadata;
1185 
1186         // write the key&metadata to the database
1187         if (!AddKeyPubKey(key, seed))
1188             throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed");
1189     }
1190 
1191     return seed;
1192 }
1193 
SetHDSeed(const CPubKey & seed)1194 void LegacyScriptPubKeyMan::SetHDSeed(const CPubKey& seed)
1195 {
1196     LOCK(cs_KeyStore);
1197     // store the keyid (hash160) together with
1198     // the child index counter in the database
1199     // as a hdchain object
1200     CHDChain newHdChain;
1201     newHdChain.nVersion = m_storage.CanSupportFeature(FEATURE_HD_SPLIT) ? CHDChain::VERSION_HD_CHAIN_SPLIT : CHDChain::VERSION_HD_BASE;
1202     newHdChain.seed_id = seed.GetID();
1203     AddHDChain(newHdChain);
1204     NotifyCanGetAddressesChanged();
1205     WalletBatch batch(m_storage.GetDatabase());
1206     m_storage.UnsetBlankWalletFlag(batch);
1207 }
1208 
1209 /**
1210  * Mark old keypool keys as used,
1211  * and generate all new keys
1212  */
NewKeyPool()1213 bool LegacyScriptPubKeyMan::NewKeyPool()
1214 {
1215     if (m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
1216         return false;
1217     }
1218     {
1219         LOCK(cs_KeyStore);
1220         WalletBatch batch(m_storage.GetDatabase());
1221 
1222         for (const int64_t nIndex : setInternalKeyPool) {
1223             batch.ErasePool(nIndex);
1224         }
1225         setInternalKeyPool.clear();
1226 
1227         for (const int64_t nIndex : setExternalKeyPool) {
1228             batch.ErasePool(nIndex);
1229         }
1230         setExternalKeyPool.clear();
1231 
1232         for (const int64_t nIndex : set_pre_split_keypool) {
1233             batch.ErasePool(nIndex);
1234         }
1235         set_pre_split_keypool.clear();
1236 
1237         m_pool_key_to_index.clear();
1238 
1239         if (!TopUp()) {
1240             return false;
1241         }
1242         WalletLogPrintf("LegacyScriptPubKeyMan::NewKeyPool rewrote keypool\n");
1243     }
1244     return true;
1245 }
1246 
TopUp(unsigned int kpSize)1247 bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
1248 {
1249     if (!CanGenerateKeys()) {
1250         return false;
1251     }
1252     {
1253         LOCK(cs_KeyStore);
1254 
1255         if (m_storage.IsLocked()) return false;
1256 
1257         // Top up key pool
1258         unsigned int nTargetSize;
1259         if (kpSize > 0)
1260             nTargetSize = kpSize;
1261         else
1262             nTargetSize = std::max(gArgs.GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0);
1263 
1264         // count amount of available keys (internal, external)
1265         // make sure the keypool of external and internal keys fits the user selected target (-keypool)
1266         int64_t missingExternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setExternalKeyPool.size(), (int64_t) 0);
1267         int64_t missingInternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setInternalKeyPool.size(), (int64_t) 0);
1268 
1269         if (!IsHDEnabled() || !m_storage.CanSupportFeature(FEATURE_HD_SPLIT))
1270         {
1271             // don't create extra internal keys
1272             missingInternal = 0;
1273         }
1274         bool internal = false;
1275         WalletBatch batch(m_storage.GetDatabase());
1276         for (int64_t i = missingInternal + missingExternal; i--;)
1277         {
1278             if (i < missingInternal) {
1279                 internal = true;
1280             }
1281 
1282             CPubKey pubkey(GenerateNewKey(batch, m_hd_chain, internal));
1283             AddKeypoolPubkeyWithDB(pubkey, internal, batch);
1284         }
1285         if (missingInternal + missingExternal > 0) {
1286             WalletLogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size(), setInternalKeyPool.size());
1287         }
1288     }
1289     NotifyCanGetAddressesChanged();
1290     return true;
1291 }
1292 
AddKeypoolPubkeyWithDB(const CPubKey & pubkey,const bool internal,WalletBatch & batch)1293 void LegacyScriptPubKeyMan::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch)
1294 {
1295     LOCK(cs_KeyStore);
1296     assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
1297     int64_t index = ++m_max_keypool_index;
1298     if (!batch.WritePool(index, CKeyPool(pubkey, internal))) {
1299         throw std::runtime_error(std::string(__func__) + ": writing imported pubkey failed");
1300     }
1301     if (internal) {
1302         setInternalKeyPool.insert(index);
1303     } else {
1304         setExternalKeyPool.insert(index);
1305     }
1306     m_pool_key_to_index[pubkey.GetID()] = index;
1307 }
1308 
KeepDestination(int64_t nIndex,const OutputType & type)1309 void LegacyScriptPubKeyMan::KeepDestination(int64_t nIndex, const OutputType& type)
1310 {
1311     assert(type != OutputType::BECH32M);
1312     // Remove from key pool
1313     WalletBatch batch(m_storage.GetDatabase());
1314     batch.ErasePool(nIndex);
1315     CPubKey pubkey;
1316     bool have_pk = GetPubKey(m_index_to_reserved_key.at(nIndex), pubkey);
1317     assert(have_pk);
1318     LearnRelatedScripts(pubkey, type);
1319     m_index_to_reserved_key.erase(nIndex);
1320     WalletLogPrintf("keypool keep %d\n", nIndex);
1321 }
1322 
ReturnDestination(int64_t nIndex,bool fInternal,const CTxDestination &)1323 void LegacyScriptPubKeyMan::ReturnDestination(int64_t nIndex, bool fInternal, const CTxDestination&)
1324 {
1325     // Return to key pool
1326     {
1327         LOCK(cs_KeyStore);
1328         if (fInternal) {
1329             setInternalKeyPool.insert(nIndex);
1330         } else if (!set_pre_split_keypool.empty()) {
1331             set_pre_split_keypool.insert(nIndex);
1332         } else {
1333             setExternalKeyPool.insert(nIndex);
1334         }
1335         CKeyID& pubkey_id = m_index_to_reserved_key.at(nIndex);
1336         m_pool_key_to_index[pubkey_id] = nIndex;
1337         m_index_to_reserved_key.erase(nIndex);
1338         NotifyCanGetAddressesChanged();
1339     }
1340     WalletLogPrintf("keypool return %d\n", nIndex);
1341 }
1342 
GetKeyFromPool(CPubKey & result,const OutputType type,bool internal)1343 bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType type, bool internal)
1344 {
1345     assert(type != OutputType::BECH32M);
1346     if (!CanGetAddresses(internal)) {
1347         return false;
1348     }
1349 
1350     CKeyPool keypool;
1351     {
1352         LOCK(cs_KeyStore);
1353         int64_t nIndex;
1354         if (!ReserveKeyFromKeyPool(nIndex, keypool, internal) && !m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
1355             if (m_storage.IsLocked()) return false;
1356             WalletBatch batch(m_storage.GetDatabase());
1357             result = GenerateNewKey(batch, m_hd_chain, internal);
1358             return true;
1359         }
1360         KeepDestination(nIndex, type);
1361         result = keypool.vchPubKey;
1362     }
1363     return true;
1364 }
1365 
ReserveKeyFromKeyPool(int64_t & nIndex,CKeyPool & keypool,bool fRequestedInternal)1366 bool LegacyScriptPubKeyMan::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal)
1367 {
1368     nIndex = -1;
1369     keypool.vchPubKey = CPubKey();
1370     {
1371         LOCK(cs_KeyStore);
1372 
1373         bool fReturningInternal = fRequestedInternal;
1374         fReturningInternal &= (IsHDEnabled() && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) || m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
1375         bool use_split_keypool = set_pre_split_keypool.empty();
1376         std::set<int64_t>& setKeyPool = use_split_keypool ? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) : set_pre_split_keypool;
1377 
1378         // Get the oldest key
1379         if (setKeyPool.empty()) {
1380             return false;
1381         }
1382 
1383         WalletBatch batch(m_storage.GetDatabase());
1384 
1385         auto it = setKeyPool.begin();
1386         nIndex = *it;
1387         setKeyPool.erase(it);
1388         if (!batch.ReadPool(nIndex, keypool)) {
1389             throw std::runtime_error(std::string(__func__) + ": read failed");
1390         }
1391         CPubKey pk;
1392         if (!GetPubKey(keypool.vchPubKey.GetID(), pk)) {
1393             throw std::runtime_error(std::string(__func__) + ": unknown key in key pool");
1394         }
1395         // If the key was pre-split keypool, we don't care about what type it is
1396         if (use_split_keypool && keypool.fInternal != fReturningInternal) {
1397             throw std::runtime_error(std::string(__func__) + ": keypool entry misclassified");
1398         }
1399         if (!keypool.vchPubKey.IsValid()) {
1400             throw std::runtime_error(std::string(__func__) + ": keypool entry invalid");
1401         }
1402 
1403         assert(m_index_to_reserved_key.count(nIndex) == 0);
1404         m_index_to_reserved_key[nIndex] = keypool.vchPubKey.GetID();
1405         m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
1406         WalletLogPrintf("keypool reserve %d\n", nIndex);
1407     }
1408     NotifyCanGetAddressesChanged();
1409     return true;
1410 }
1411 
LearnRelatedScripts(const CPubKey & key,OutputType type)1412 void LegacyScriptPubKeyMan::LearnRelatedScripts(const CPubKey& key, OutputType type)
1413 {
1414     assert(type != OutputType::BECH32M);
1415     if (key.IsCompressed() && (type == OutputType::P2SH_SEGWIT || type == OutputType::BECH32)) {
1416         CTxDestination witdest = WitnessV0KeyHash(key.GetID());
1417         CScript witprog = GetScriptForDestination(witdest);
1418         // Make sure the resulting program is solvable.
1419         assert(IsSolvable(*this, witprog));
1420         AddCScript(witprog);
1421     }
1422 }
1423 
LearnAllRelatedScripts(const CPubKey & key)1424 void LegacyScriptPubKeyMan::LearnAllRelatedScripts(const CPubKey& key)
1425 {
1426     // OutputType::P2SH_SEGWIT always adds all necessary scripts for all types.
1427     LearnRelatedScripts(key, OutputType::P2SH_SEGWIT);
1428 }
1429 
MarkReserveKeysAsUsed(int64_t keypool_id)1430 void LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id)
1431 {
1432     AssertLockHeld(cs_KeyStore);
1433     bool internal = setInternalKeyPool.count(keypool_id);
1434     if (!internal) assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id));
1435     std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
1436     auto it = setKeyPool->begin();
1437 
1438     WalletBatch batch(m_storage.GetDatabase());
1439     while (it != std::end(*setKeyPool)) {
1440         const int64_t& index = *(it);
1441         if (index > keypool_id) break; // set*KeyPool is ordered
1442 
1443         CKeyPool keypool;
1444         if (batch.ReadPool(index, keypool)) { //TODO: This should be unnecessary
1445             m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
1446         }
1447         LearnAllRelatedScripts(keypool.vchPubKey);
1448         batch.ErasePool(index);
1449         WalletLogPrintf("keypool index %d removed\n", index);
1450         it = setKeyPool->erase(it);
1451     }
1452 }
1453 
GetAffectedKeys(const CScript & spk,const SigningProvider & provider)1454 std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& provider)
1455 {
1456     std::vector<CScript> dummy;
1457     FlatSigningProvider out;
1458     InferDescriptor(spk, provider)->Expand(0, DUMMY_SIGNING_PROVIDER, dummy, out);
1459     std::vector<CKeyID> ret;
1460     for (const auto& entry : out.pubkeys) {
1461         ret.push_back(entry.first);
1462     }
1463     return ret;
1464 }
1465 
MarkPreSplitKeys()1466 void LegacyScriptPubKeyMan::MarkPreSplitKeys()
1467 {
1468     WalletBatch batch(m_storage.GetDatabase());
1469     for (auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) {
1470         int64_t index = *it;
1471         CKeyPool keypool;
1472         if (!batch.ReadPool(index, keypool)) {
1473             throw std::runtime_error(std::string(__func__) + ": read keypool entry failed");
1474         }
1475         keypool.m_pre_split = true;
1476         if (!batch.WritePool(index, keypool)) {
1477             throw std::runtime_error(std::string(__func__) + ": writing modified keypool entry failed");
1478         }
1479         set_pre_split_keypool.insert(index);
1480         it = setExternalKeyPool.erase(it);
1481     }
1482 }
1483 
AddCScript(const CScript & redeemScript)1484 bool LegacyScriptPubKeyMan::AddCScript(const CScript& redeemScript)
1485 {
1486     WalletBatch batch(m_storage.GetDatabase());
1487     return AddCScriptWithDB(batch, redeemScript);
1488 }
1489 
AddCScriptWithDB(WalletBatch & batch,const CScript & redeemScript)1490 bool LegacyScriptPubKeyMan::AddCScriptWithDB(WalletBatch& batch, const CScript& redeemScript)
1491 {
1492     if (!FillableSigningProvider::AddCScript(redeemScript))
1493         return false;
1494     if (batch.WriteCScript(Hash160(redeemScript), redeemScript)) {
1495         m_storage.UnsetBlankWalletFlag(batch);
1496         return true;
1497     }
1498     return false;
1499 }
1500 
AddKeyOriginWithDB(WalletBatch & batch,const CPubKey & pubkey,const KeyOriginInfo & info)1501 bool LegacyScriptPubKeyMan::AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info)
1502 {
1503     LOCK(cs_KeyStore);
1504     std::copy(info.fingerprint, info.fingerprint + 4, mapKeyMetadata[pubkey.GetID()].key_origin.fingerprint);
1505     mapKeyMetadata[pubkey.GetID()].key_origin.path = info.path;
1506     mapKeyMetadata[pubkey.GetID()].has_key_origin = true;
1507     mapKeyMetadata[pubkey.GetID()].hdKeypath = WriteHDKeypath(info.path);
1508     return batch.WriteKeyMetadata(mapKeyMetadata[pubkey.GetID()], pubkey, true);
1509 }
1510 
ImportScripts(const std::set<CScript> scripts,int64_t timestamp)1511 bool LegacyScriptPubKeyMan::ImportScripts(const std::set<CScript> scripts, int64_t timestamp)
1512 {
1513     WalletBatch batch(m_storage.GetDatabase());
1514     for (const auto& entry : scripts) {
1515         CScriptID id(entry);
1516         if (HaveCScript(id)) {
1517             WalletLogPrintf("Already have script %s, skipping\n", HexStr(entry));
1518             continue;
1519         }
1520         if (!AddCScriptWithDB(batch, entry)) {
1521             return false;
1522         }
1523 
1524         if (timestamp > 0) {
1525             m_script_metadata[CScriptID(entry)].nCreateTime = timestamp;
1526         }
1527     }
1528     if (timestamp > 0) {
1529         UpdateTimeFirstKey(timestamp);
1530     }
1531 
1532     return true;
1533 }
1534 
ImportPrivKeys(const std::map<CKeyID,CKey> & privkey_map,const int64_t timestamp)1535 bool LegacyScriptPubKeyMan::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp)
1536 {
1537     WalletBatch batch(m_storage.GetDatabase());
1538     for (const auto& entry : privkey_map) {
1539         const CKey& key = entry.second;
1540         CPubKey pubkey = key.GetPubKey();
1541         const CKeyID& id = entry.first;
1542         assert(key.VerifyPubKey(pubkey));
1543         // Skip if we already have the key
1544         if (HaveKey(id)) {
1545             WalletLogPrintf("Already have key with pubkey %s, skipping\n", HexStr(pubkey));
1546             continue;
1547         }
1548         mapKeyMetadata[id].nCreateTime = timestamp;
1549         // If the private key is not present in the wallet, insert it.
1550         if (!AddKeyPubKeyWithDB(batch, key, pubkey)) {
1551             return false;
1552         }
1553         UpdateTimeFirstKey(timestamp);
1554     }
1555     return true;
1556 }
1557 
ImportPubKeys(const std::vector<CKeyID> & ordered_pubkeys,const std::map<CKeyID,CPubKey> & pubkey_map,const std::map<CKeyID,std::pair<CPubKey,KeyOriginInfo>> & key_origins,const bool add_keypool,const bool internal,const int64_t timestamp)1558 bool LegacyScriptPubKeyMan::ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp)
1559 {
1560     WalletBatch batch(m_storage.GetDatabase());
1561     for (const auto& entry : key_origins) {
1562         AddKeyOriginWithDB(batch, entry.second.first, entry.second.second);
1563     }
1564     for (const CKeyID& id : ordered_pubkeys) {
1565         auto entry = pubkey_map.find(id);
1566         if (entry == pubkey_map.end()) {
1567             continue;
1568         }
1569         const CPubKey& pubkey = entry->second;
1570         CPubKey temp;
1571         if (GetPubKey(id, temp)) {
1572             // Already have pubkey, skipping
1573             WalletLogPrintf("Already have pubkey %s, skipping\n", HexStr(temp));
1574             continue;
1575         }
1576         if (!AddWatchOnlyWithDB(batch, GetScriptForRawPubKey(pubkey), timestamp)) {
1577             return false;
1578         }
1579         mapKeyMetadata[id].nCreateTime = timestamp;
1580 
1581         // Add to keypool only works with pubkeys
1582         if (add_keypool) {
1583             AddKeypoolPubkeyWithDB(pubkey, internal, batch);
1584             NotifyCanGetAddressesChanged();
1585         }
1586     }
1587     return true;
1588 }
1589 
ImportScriptPubKeys(const std::set<CScript> & script_pub_keys,const bool have_solving_data,const int64_t timestamp)1590 bool LegacyScriptPubKeyMan::ImportScriptPubKeys(const std::set<CScript>& script_pub_keys, const bool have_solving_data, const int64_t timestamp)
1591 {
1592     WalletBatch batch(m_storage.GetDatabase());
1593     for (const CScript& script : script_pub_keys) {
1594         if (!have_solving_data || !IsMine(script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1595             if (!AddWatchOnlyWithDB(batch, script, timestamp)) {
1596                 return false;
1597             }
1598         }
1599     }
1600     return true;
1601 }
1602 
GetKeys() const1603 std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const
1604 {
1605     LOCK(cs_KeyStore);
1606     if (!m_storage.HasEncryptionKeys()) {
1607         return FillableSigningProvider::GetKeys();
1608     }
1609     std::set<CKeyID> set_address;
1610     for (const auto& mi : mapCryptedKeys) {
1611         set_address.insert(mi.first);
1612     }
1613     return set_address;
1614 }
1615 
GetNewDestination(const OutputType type,CTxDestination & dest,std::string & error)1616 bool DescriptorScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error)
1617 {
1618     // Returns true if this descriptor supports getting new addresses. Conditions where we may be unable to fetch them (e.g. locked) are caught later
1619     if (!CanGetAddresses()) {
1620         error = "No addresses available";
1621         return false;
1622     }
1623     {
1624         LOCK(cs_desc_man);
1625         assert(m_wallet_descriptor.descriptor->IsSingleType()); // This is a combo descriptor which should not be an active descriptor
1626         std::optional<OutputType> desc_addr_type = m_wallet_descriptor.descriptor->GetOutputType();
1627         assert(desc_addr_type);
1628         if (type != *desc_addr_type) {
1629             throw std::runtime_error(std::string(__func__) + ": Types are inconsistent");
1630         }
1631 
1632         TopUp();
1633 
1634         // Get the scriptPubKey from the descriptor
1635         FlatSigningProvider out_keys;
1636         std::vector<CScript> scripts_temp;
1637         if (m_wallet_descriptor.range_end <= m_max_cached_index && !TopUp(1)) {
1638             // We can't generate anymore keys
1639             error = "Error: Keypool ran out, please call keypoolrefill first";
1640             return false;
1641         }
1642         if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
1643             // We can't generate anymore keys
1644             error = "Error: Keypool ran out, please call keypoolrefill first";
1645             return false;
1646         }
1647 
1648         std::optional<OutputType> out_script_type = m_wallet_descriptor.descriptor->GetOutputType();
1649         if (out_script_type && out_script_type == type) {
1650             ExtractDestination(scripts_temp[0], dest);
1651         } else {
1652             throw std::runtime_error(std::string(__func__) + ": Types are inconsistent. Stored type does not match type of newly generated address");
1653         }
1654         m_wallet_descriptor.next_index++;
1655         WalletBatch(m_storage.GetDatabase()).WriteDescriptor(GetID(), m_wallet_descriptor);
1656         return true;
1657     }
1658 }
1659 
IsMine(const CScript & script) const1660 isminetype DescriptorScriptPubKeyMan::IsMine(const CScript& script) const
1661 {
1662     LOCK(cs_desc_man);
1663     if (m_map_script_pub_keys.count(script) > 0) {
1664         return ISMINE_SPENDABLE;
1665     }
1666     return ISMINE_NO;
1667 }
1668 
CheckDecryptionKey(const CKeyingMaterial & master_key,bool accept_no_keys)1669 bool DescriptorScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys)
1670 {
1671     LOCK(cs_desc_man);
1672     if (!m_map_keys.empty()) {
1673         return false;
1674     }
1675 
1676     bool keyPass = m_map_crypted_keys.empty(); // Always pass when there are no encrypted keys
1677     bool keyFail = false;
1678     for (const auto& mi : m_map_crypted_keys) {
1679         const CPubKey &pubkey = mi.second.first;
1680         const std::vector<unsigned char> &crypted_secret = mi.second.second;
1681         CKey key;
1682         if (!DecryptKey(master_key, crypted_secret, pubkey, key)) {
1683             keyFail = true;
1684             break;
1685         }
1686         keyPass = true;
1687         if (m_decryption_thoroughly_checked)
1688             break;
1689     }
1690     if (keyPass && keyFail) {
1691         LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n");
1692         throw std::runtime_error("Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
1693     }
1694     if (keyFail || (!keyPass && !accept_no_keys)) {
1695         return false;
1696     }
1697     m_decryption_thoroughly_checked = true;
1698     return true;
1699 }
1700 
Encrypt(const CKeyingMaterial & master_key,WalletBatch * batch)1701 bool DescriptorScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch)
1702 {
1703     LOCK(cs_desc_man);
1704     if (!m_map_crypted_keys.empty()) {
1705         return false;
1706     }
1707 
1708     for (const KeyMap::value_type& key_in : m_map_keys)
1709     {
1710         const CKey &key = key_in.second;
1711         CPubKey pubkey = key.GetPubKey();
1712         CKeyingMaterial secret(key.begin(), key.end());
1713         std::vector<unsigned char> crypted_secret;
1714         if (!EncryptSecret(master_key, secret, pubkey.GetHash(), crypted_secret)) {
1715             return false;
1716         }
1717         m_map_crypted_keys[pubkey.GetID()] = make_pair(pubkey, crypted_secret);
1718         batch->WriteCryptedDescriptorKey(GetID(), pubkey, crypted_secret);
1719     }
1720     m_map_keys.clear();
1721     return true;
1722 }
1723 
GetReservedDestination(const OutputType type,bool internal,CTxDestination & address,int64_t & index,CKeyPool & keypool,std::string & error)1724 bool DescriptorScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error)
1725 {
1726     LOCK(cs_desc_man);
1727     bool result = GetNewDestination(type, address, error);
1728     index = m_wallet_descriptor.next_index - 1;
1729     return result;
1730 }
1731 
ReturnDestination(int64_t index,bool internal,const CTxDestination & addr)1732 void DescriptorScriptPubKeyMan::ReturnDestination(int64_t index, bool internal, const CTxDestination& addr)
1733 {
1734     LOCK(cs_desc_man);
1735     // Only return when the index was the most recent
1736     if (m_wallet_descriptor.next_index - 1 == index) {
1737         m_wallet_descriptor.next_index--;
1738     }
1739     WalletBatch(m_storage.GetDatabase()).WriteDescriptor(GetID(), m_wallet_descriptor);
1740     NotifyCanGetAddressesChanged();
1741 }
1742 
GetKeys() const1743 std::map<CKeyID, CKey> DescriptorScriptPubKeyMan::GetKeys() const
1744 {
1745     AssertLockHeld(cs_desc_man);
1746     if (m_storage.HasEncryptionKeys() && !m_storage.IsLocked()) {
1747         KeyMap keys;
1748         for (auto key_pair : m_map_crypted_keys) {
1749             const CPubKey& pubkey = key_pair.second.first;
1750             const std::vector<unsigned char>& crypted_secret = key_pair.second.second;
1751             CKey key;
1752             DecryptKey(m_storage.GetEncryptionKey(), crypted_secret, pubkey, key);
1753             keys[pubkey.GetID()] = key;
1754         }
1755         return keys;
1756     }
1757     return m_map_keys;
1758 }
1759 
TopUp(unsigned int size)1760 bool DescriptorScriptPubKeyMan::TopUp(unsigned int size)
1761 {
1762     LOCK(cs_desc_man);
1763     unsigned int target_size;
1764     if (size > 0) {
1765         target_size = size;
1766     } else {
1767         target_size = std::max(gArgs.GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 1);
1768     }
1769 
1770     // Calculate the new range_end
1771     int32_t new_range_end = std::max(m_wallet_descriptor.next_index + (int32_t)target_size, m_wallet_descriptor.range_end);
1772 
1773     // If the descriptor is not ranged, we actually just want to fill the first cache item
1774     if (!m_wallet_descriptor.descriptor->IsRange()) {
1775         new_range_end = 1;
1776         m_wallet_descriptor.range_end = 1;
1777         m_wallet_descriptor.range_start = 0;
1778     }
1779 
1780     FlatSigningProvider provider;
1781     provider.keys = GetKeys();
1782 
1783     WalletBatch batch(m_storage.GetDatabase());
1784     uint256 id = GetID();
1785     for (int32_t i = m_max_cached_index + 1; i < new_range_end; ++i) {
1786         FlatSigningProvider out_keys;
1787         std::vector<CScript> scripts_temp;
1788         DescriptorCache temp_cache;
1789         // Maybe we have a cached xpub and we can expand from the cache first
1790         if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
1791             if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache)) return false;
1792         }
1793         // Add all of the scriptPubKeys to the scriptPubKey set
1794         for (const CScript& script : scripts_temp) {
1795             m_map_script_pub_keys[script] = i;
1796         }
1797         for (const auto& pk_pair : out_keys.pubkeys) {
1798             const CPubKey& pubkey = pk_pair.second;
1799             if (m_map_pubkeys.count(pubkey) != 0) {
1800                 // We don't need to give an error here.
1801                 // It doesn't matter which of many valid indexes the pubkey has, we just need an index where we can derive it and it's private key
1802                 continue;
1803             }
1804             m_map_pubkeys[pubkey] = i;
1805         }
1806         // Merge and write the cache
1807         DescriptorCache new_items = m_wallet_descriptor.cache.MergeAndDiff(temp_cache);
1808         if (!batch.WriteDescriptorCacheItems(id, new_items)) {
1809             throw std::runtime_error(std::string(__func__) + ": writing cache items failed");
1810         }
1811         m_max_cached_index++;
1812     }
1813     m_wallet_descriptor.range_end = new_range_end;
1814     batch.WriteDescriptor(GetID(), m_wallet_descriptor);
1815 
1816     // By this point, the cache size should be the size of the entire range
1817     assert(m_wallet_descriptor.range_end - 1 == m_max_cached_index);
1818 
1819     NotifyCanGetAddressesChanged();
1820     return true;
1821 }
1822 
MarkUnusedAddresses(const CScript & script)1823 void DescriptorScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
1824 {
1825     LOCK(cs_desc_man);
1826     if (IsMine(script)) {
1827         int32_t index = m_map_script_pub_keys[script];
1828         if (index >= m_wallet_descriptor.next_index) {
1829             WalletLogPrintf("%s: Detected a used keypool item at index %d, mark all keypool items up to this item as used\n", __func__, index);
1830             m_wallet_descriptor.next_index = index + 1;
1831         }
1832         if (!TopUp()) {
1833             WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
1834         }
1835     }
1836 }
1837 
AddDescriptorKey(const CKey & key,const CPubKey & pubkey)1838 void DescriptorScriptPubKeyMan::AddDescriptorKey(const CKey& key, const CPubKey &pubkey)
1839 {
1840     LOCK(cs_desc_man);
1841     WalletBatch batch(m_storage.GetDatabase());
1842     if (!AddDescriptorKeyWithDB(batch, key, pubkey)) {
1843         throw std::runtime_error(std::string(__func__) + ": writing descriptor private key failed");
1844     }
1845 }
1846 
AddDescriptorKeyWithDB(WalletBatch & batch,const CKey & key,const CPubKey & pubkey)1847 bool DescriptorScriptPubKeyMan::AddDescriptorKeyWithDB(WalletBatch& batch, const CKey& key, const CPubKey &pubkey)
1848 {
1849     AssertLockHeld(cs_desc_man);
1850     assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
1851 
1852     // Check if provided key already exists
1853     if (m_map_keys.find(pubkey.GetID()) != m_map_keys.end() ||
1854         m_map_crypted_keys.find(pubkey.GetID()) != m_map_crypted_keys.end()) {
1855         return true;
1856     }
1857 
1858     if (m_storage.HasEncryptionKeys()) {
1859         if (m_storage.IsLocked()) {
1860             return false;
1861         }
1862 
1863         std::vector<unsigned char> crypted_secret;
1864         CKeyingMaterial secret(key.begin(), key.end());
1865         if (!EncryptSecret(m_storage.GetEncryptionKey(), secret, pubkey.GetHash(), crypted_secret)) {
1866             return false;
1867         }
1868 
1869         m_map_crypted_keys[pubkey.GetID()] = make_pair(pubkey, crypted_secret);
1870         return batch.WriteCryptedDescriptorKey(GetID(), pubkey, crypted_secret);
1871     } else {
1872         m_map_keys[pubkey.GetID()] = key;
1873         return batch.WriteDescriptorKey(GetID(), pubkey, key.GetPrivKey());
1874     }
1875 }
1876 
SetupDescriptorGeneration(const CExtKey & master_key,OutputType addr_type,bool internal)1877 bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_key, OutputType addr_type, bool internal)
1878 {
1879     if (addr_type == OutputType::BECH32M) {
1880         // Don't allow setting up taproot descriptors yet
1881         // TODO: Allow setting up taproot descriptors
1882         return false;
1883     }
1884 
1885     LOCK(cs_desc_man);
1886     assert(m_storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
1887 
1888     // Ignore when there is already a descriptor
1889     if (m_wallet_descriptor.descriptor) {
1890         return false;
1891     }
1892 
1893     int64_t creation_time = GetTime();
1894 
1895     std::string xpub = EncodeExtPubKey(master_key.Neuter());
1896 
1897     // Build descriptor string
1898     std::string desc_prefix;
1899     std::string desc_suffix = "/*)";
1900     switch (addr_type) {
1901     case OutputType::LEGACY: {
1902         desc_prefix = "pkh(" + xpub + "/44'";
1903         break;
1904     }
1905     case OutputType::P2SH_SEGWIT: {
1906         desc_prefix = "sh(wpkh(" + xpub + "/49'";
1907         desc_suffix += ")";
1908         break;
1909     }
1910     case OutputType::BECH32: {
1911         desc_prefix = "wpkh(" + xpub + "/84'";
1912         break;
1913     }
1914     case OutputType::BECH32M: assert(false); // TODO: Setup taproot descriptor
1915     } // no default case, so the compiler can warn about missing cases
1916     assert(!desc_prefix.empty());
1917 
1918     // Mainnet derives at 0', testnet and regtest derive at 1'
1919     if (Params().IsTestChain()) {
1920         desc_prefix += "/1'";
1921     } else {
1922         desc_prefix += "/0'";
1923     }
1924 
1925     std::string internal_path = internal ? "/1" : "/0";
1926     std::string desc_str = desc_prefix + "/0'" + internal_path + desc_suffix;
1927 
1928     // Make the descriptor
1929     FlatSigningProvider keys;
1930     std::string error;
1931     std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, error, false);
1932     WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
1933     m_wallet_descriptor = w_desc;
1934 
1935     // Store the master private key, and descriptor
1936     WalletBatch batch(m_storage.GetDatabase());
1937     if (!AddDescriptorKeyWithDB(batch, master_key.key, master_key.key.GetPubKey())) {
1938         throw std::runtime_error(std::string(__func__) + ": writing descriptor master private key failed");
1939     }
1940     if (!batch.WriteDescriptor(GetID(), m_wallet_descriptor)) {
1941         throw std::runtime_error(std::string(__func__) + ": writing descriptor failed");
1942     }
1943 
1944     // TopUp
1945     TopUp();
1946 
1947     m_storage.UnsetBlankWalletFlag(batch);
1948     return true;
1949 }
1950 
IsHDEnabled() const1951 bool DescriptorScriptPubKeyMan::IsHDEnabled() const
1952 {
1953     LOCK(cs_desc_man);
1954     return m_wallet_descriptor.descriptor->IsRange();
1955 }
1956 
CanGetAddresses(bool internal) const1957 bool DescriptorScriptPubKeyMan::CanGetAddresses(bool internal) const
1958 {
1959     // We can only give out addresses from descriptors that are single type (not combo), ranged,
1960     // and either have cached keys or can generate more keys (ignoring encryption)
1961     LOCK(cs_desc_man);
1962     return m_wallet_descriptor.descriptor->IsSingleType() &&
1963            m_wallet_descriptor.descriptor->IsRange() &&
1964            (HavePrivateKeys() || m_wallet_descriptor.next_index < m_wallet_descriptor.range_end);
1965 }
1966 
HavePrivateKeys() const1967 bool DescriptorScriptPubKeyMan::HavePrivateKeys() const
1968 {
1969     LOCK(cs_desc_man);
1970     return m_map_keys.size() > 0 || m_map_crypted_keys.size() > 0;
1971 }
1972 
GetOldestKeyPoolTime() const1973 int64_t DescriptorScriptPubKeyMan::GetOldestKeyPoolTime() const
1974 {
1975     // This is only used for getwalletinfo output and isn't relevant to descriptor wallets.
1976     // The magic number 0 indicates that it shouldn't be displayed so that's what we return.
1977     return 0;
1978 }
1979 
1980 
GetKeyPoolSize() const1981 unsigned int DescriptorScriptPubKeyMan::GetKeyPoolSize() const
1982 {
1983     LOCK(cs_desc_man);
1984     return m_wallet_descriptor.range_end - m_wallet_descriptor.next_index;
1985 }
1986 
GetTimeFirstKey() const1987 int64_t DescriptorScriptPubKeyMan::GetTimeFirstKey() const
1988 {
1989     LOCK(cs_desc_man);
1990     return m_wallet_descriptor.creation_time;
1991 }
1992 
GetSigningProvider(const CScript & script,bool include_private) const1993 std::unique_ptr<FlatSigningProvider> DescriptorScriptPubKeyMan::GetSigningProvider(const CScript& script, bool include_private) const
1994 {
1995     LOCK(cs_desc_man);
1996 
1997     // Find the index of the script
1998     auto it = m_map_script_pub_keys.find(script);
1999     if (it == m_map_script_pub_keys.end()) {
2000         return nullptr;
2001     }
2002     int32_t index = it->second;
2003 
2004     return GetSigningProvider(index, include_private);
2005 }
2006 
GetSigningProvider(const CPubKey & pubkey) const2007 std::unique_ptr<FlatSigningProvider> DescriptorScriptPubKeyMan::GetSigningProvider(const CPubKey& pubkey) const
2008 {
2009     LOCK(cs_desc_man);
2010 
2011     // Find index of the pubkey
2012     auto it = m_map_pubkeys.find(pubkey);
2013     if (it == m_map_pubkeys.end()) {
2014         return nullptr;
2015     }
2016     int32_t index = it->second;
2017 
2018     // Always try to get the signing provider with private keys. This function should only be called during signing anyways
2019     return GetSigningProvider(index, true);
2020 }
2021 
GetSigningProvider(int32_t index,bool include_private) const2022 std::unique_ptr<FlatSigningProvider> DescriptorScriptPubKeyMan::GetSigningProvider(int32_t index, bool include_private) const
2023 {
2024     AssertLockHeld(cs_desc_man);
2025     // Get the scripts, keys, and key origins for this script
2026     std::unique_ptr<FlatSigningProvider> out_keys = std::make_unique<FlatSigningProvider>();
2027     std::vector<CScript> scripts_temp;
2028     if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) return nullptr;
2029 
2030     if (HavePrivateKeys() && include_private) {
2031         FlatSigningProvider master_provider;
2032         master_provider.keys = GetKeys();
2033         m_wallet_descriptor.descriptor->ExpandPrivate(index, master_provider, *out_keys);
2034     }
2035 
2036     return out_keys;
2037 }
2038 
GetSolvingProvider(const CScript & script) const2039 std::unique_ptr<SigningProvider> DescriptorScriptPubKeyMan::GetSolvingProvider(const CScript& script) const
2040 {
2041     return GetSigningProvider(script, false);
2042 }
2043 
CanProvide(const CScript & script,SignatureData & sigdata)2044 bool DescriptorScriptPubKeyMan::CanProvide(const CScript& script, SignatureData& sigdata)
2045 {
2046     return IsMine(script);
2047 }
2048 
SignTransaction(CMutableTransaction & tx,const std::map<COutPoint,Coin> & coins,int sighash,std::map<int,std::string> & input_errors) const2049 bool DescriptorScriptPubKeyMan::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const
2050 {
2051     std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2052     for (const auto& coin_pair : coins) {
2053         std::unique_ptr<FlatSigningProvider> coin_keys = GetSigningProvider(coin_pair.second.out.scriptPubKey, true);
2054         if (!coin_keys) {
2055             continue;
2056         }
2057         *keys = Merge(*keys, *coin_keys);
2058     }
2059 
2060     return ::SignTransaction(tx, keys.get(), coins, sighash, input_errors);
2061 }
2062 
SignMessage(const std::string & message,const PKHash & pkhash,std::string & str_sig) const2063 SigningResult DescriptorScriptPubKeyMan::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const
2064 {
2065     std::unique_ptr<FlatSigningProvider> keys = GetSigningProvider(GetScriptForDestination(pkhash), true);
2066     if (!keys) {
2067         return SigningResult::PRIVATE_KEY_NOT_AVAILABLE;
2068     }
2069 
2070     CKey key;
2071     if (!keys->GetKey(ToKeyID(pkhash), key)) {
2072         return SigningResult::PRIVATE_KEY_NOT_AVAILABLE;
2073     }
2074 
2075     if (!MessageSign(key, message, str_sig)) {
2076         return SigningResult::SIGNING_FAILED;
2077     }
2078     return SigningResult::OK;
2079 }
2080 
FillPSBT(PartiallySignedTransaction & psbtx,const PrecomputedTransactionData & txdata,int sighash_type,bool sign,bool bip32derivs,int * n_signed) const2081 TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed) const
2082 {
2083     if (n_signed) {
2084         *n_signed = 0;
2085     }
2086     for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
2087         const CTxIn& txin = psbtx.tx->vin[i];
2088         PSBTInput& input = psbtx.inputs.at(i);
2089 
2090         if (PSBTInputSigned(input)) {
2091             continue;
2092         }
2093 
2094         // Get the Sighash type
2095         if (sign && input.sighash_type > 0 && input.sighash_type != sighash_type) {
2096             return TransactionError::SIGHASH_MISMATCH;
2097         }
2098 
2099         // Get the scriptPubKey to know which SigningProvider to use
2100         CScript script;
2101         if (!input.witness_utxo.IsNull()) {
2102             script = input.witness_utxo.scriptPubKey;
2103         } else if (input.non_witness_utxo) {
2104             if (txin.prevout.n >= input.non_witness_utxo->vout.size()) {
2105                 return TransactionError::MISSING_INPUTS;
2106             }
2107             script = input.non_witness_utxo->vout[txin.prevout.n].scriptPubKey;
2108         } else {
2109             // There's no UTXO so we can just skip this now
2110             continue;
2111         }
2112         SignatureData sigdata;
2113         input.FillSignatureData(sigdata);
2114 
2115         std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2116         std::unique_ptr<FlatSigningProvider> script_keys = GetSigningProvider(script, sign);
2117         if (script_keys) {
2118             *keys = Merge(*keys, *script_keys);
2119         } else {
2120             // Maybe there are pubkeys listed that we can sign for
2121             script_keys = std::make_unique<FlatSigningProvider>();
2122             for (const auto& pk_pair : input.hd_keypaths) {
2123                 const CPubKey& pubkey = pk_pair.first;
2124                 std::unique_ptr<FlatSigningProvider> pk_keys = GetSigningProvider(pubkey);
2125                 if (pk_keys) {
2126                     *keys = Merge(*keys, *pk_keys);
2127                 }
2128             }
2129         }
2130 
2131         SignPSBTInput(HidingSigningProvider(keys.get(), !sign, !bip32derivs), psbtx, i, &txdata, sighash_type);
2132 
2133         bool signed_one = PSBTInputSigned(input);
2134         if (n_signed && (signed_one || !sign)) {
2135             // If sign is false, we assume that we _could_ sign if we get here. This
2136             // will never have false negatives; it is hard to tell under what i
2137             // circumstances it could have false positives.
2138             (*n_signed)++;
2139         }
2140     }
2141 
2142     // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
2143     for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
2144         std::unique_ptr<SigningProvider> keys = GetSolvingProvider(psbtx.tx->vout.at(i).scriptPubKey);
2145         if (!keys) {
2146             continue;
2147         }
2148         UpdatePSBTOutput(HidingSigningProvider(keys.get(), true, !bip32derivs), psbtx, i);
2149     }
2150 
2151     return TransactionError::OK;
2152 }
2153 
GetMetadata(const CTxDestination & dest) const2154 std::unique_ptr<CKeyMetadata> DescriptorScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const
2155 {
2156     std::unique_ptr<SigningProvider> provider = GetSigningProvider(GetScriptForDestination(dest));
2157     if (provider) {
2158         KeyOriginInfo orig;
2159         CKeyID key_id = GetKeyForDestination(*provider, dest);
2160         if (provider->GetKeyOrigin(key_id, orig)) {
2161             LOCK(cs_desc_man);
2162             std::unique_ptr<CKeyMetadata> meta = std::make_unique<CKeyMetadata>();
2163             meta->key_origin = orig;
2164             meta->has_key_origin = true;
2165             meta->nCreateTime = m_wallet_descriptor.creation_time;
2166             return meta;
2167         }
2168     }
2169     return nullptr;
2170 }
2171 
GetID() const2172 uint256 DescriptorScriptPubKeyMan::GetID() const
2173 {
2174     LOCK(cs_desc_man);
2175     std::string desc_str = m_wallet_descriptor.descriptor->ToString();
2176     uint256 id;
2177     CSHA256().Write((unsigned char*)desc_str.data(), desc_str.size()).Finalize(id.begin());
2178     return id;
2179 }
2180 
SetCache(const DescriptorCache & cache)2181 void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
2182 {
2183     LOCK(cs_desc_man);
2184     m_wallet_descriptor.cache = cache;
2185     for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
2186         FlatSigningProvider out_keys;
2187         std::vector<CScript> scripts_temp;
2188         if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2189             throw std::runtime_error("Error: Unable to expand wallet descriptor from cache");
2190         }
2191         // Add all of the scriptPubKeys to the scriptPubKey set
2192         for (const CScript& script : scripts_temp) {
2193             if (m_map_script_pub_keys.count(script) != 0) {
2194                 throw std::runtime_error(strprintf("Error: Already loaded script at index %d as being at index %d", i, m_map_script_pub_keys[script]));
2195             }
2196             m_map_script_pub_keys[script] = i;
2197         }
2198         for (const auto& pk_pair : out_keys.pubkeys) {
2199             const CPubKey& pubkey = pk_pair.second;
2200             if (m_map_pubkeys.count(pubkey) != 0) {
2201                 // We don't need to give an error here.
2202                 // It doesn't matter which of many valid indexes the pubkey has, we just need an index where we can derive it and it's private key
2203                 continue;
2204             }
2205             m_map_pubkeys[pubkey] = i;
2206         }
2207         m_max_cached_index++;
2208     }
2209 }
2210 
AddKey(const CKeyID & key_id,const CKey & key)2211 bool DescriptorScriptPubKeyMan::AddKey(const CKeyID& key_id, const CKey& key)
2212 {
2213     LOCK(cs_desc_man);
2214     m_map_keys[key_id] = key;
2215     return true;
2216 }
2217 
AddCryptedKey(const CKeyID & key_id,const CPubKey & pubkey,const std::vector<unsigned char> & crypted_key)2218 bool DescriptorScriptPubKeyMan::AddCryptedKey(const CKeyID& key_id, const CPubKey& pubkey, const std::vector<unsigned char>& crypted_key)
2219 {
2220     LOCK(cs_desc_man);
2221     if (!m_map_keys.empty()) {
2222         return false;
2223     }
2224 
2225     m_map_crypted_keys[key_id] = make_pair(pubkey, crypted_key);
2226     return true;
2227 }
2228 
HasWalletDescriptor(const WalletDescriptor & desc) const2229 bool DescriptorScriptPubKeyMan::HasWalletDescriptor(const WalletDescriptor& desc) const
2230 {
2231     LOCK(cs_desc_man);
2232     return m_wallet_descriptor.descriptor != nullptr && desc.descriptor != nullptr && m_wallet_descriptor.descriptor->ToString() == desc.descriptor->ToString();
2233 }
2234 
WriteDescriptor()2235 void DescriptorScriptPubKeyMan::WriteDescriptor()
2236 {
2237     LOCK(cs_desc_man);
2238     WalletBatch batch(m_storage.GetDatabase());
2239     if (!batch.WriteDescriptor(GetID(), m_wallet_descriptor)) {
2240         throw std::runtime_error(std::string(__func__) + ": writing descriptor failed");
2241     }
2242 }
2243 
GetWalletDescriptor() const2244 const WalletDescriptor DescriptorScriptPubKeyMan::GetWalletDescriptor() const
2245 {
2246     return m_wallet_descriptor;
2247 }
2248 
GetScriptPubKeys() const2249 const std::vector<CScript> DescriptorScriptPubKeyMan::GetScriptPubKeys() const
2250 {
2251     LOCK(cs_desc_man);
2252     std::vector<CScript> script_pub_keys;
2253     script_pub_keys.reserve(m_map_script_pub_keys.size());
2254 
2255     for (auto const& script_pub_key: m_map_script_pub_keys) {
2256         script_pub_keys.push_back(script_pub_key.first);
2257     }
2258     return script_pub_keys;
2259 }
2260 
GetDescriptorString(std::string & out) const2261 bool DescriptorScriptPubKeyMan::GetDescriptorString(std::string& out) const
2262 {
2263     LOCK(cs_desc_man);
2264 
2265     FlatSigningProvider provider;
2266     provider.keys = GetKeys();
2267 
2268     return m_wallet_descriptor.descriptor->ToNormalizedString(provider, out, &m_wallet_descriptor.cache);
2269 }
2270 
UpgradeDescriptorCache()2271 void DescriptorScriptPubKeyMan::UpgradeDescriptorCache()
2272 {
2273     LOCK(cs_desc_man);
2274     if (m_storage.IsLocked() || m_storage.IsWalletFlagSet(WALLET_FLAG_LAST_HARDENED_XPUB_CACHED)) {
2275         return;
2276     }
2277 
2278     // Skip if we have the last hardened xpub cache
2279     if (m_wallet_descriptor.cache.GetCachedLastHardenedExtPubKeys().size() > 0) {
2280         return;
2281     }
2282 
2283     // Expand the descriptor
2284     FlatSigningProvider provider;
2285     provider.keys = GetKeys();
2286     FlatSigningProvider out_keys;
2287     std::vector<CScript> scripts_temp;
2288     DescriptorCache temp_cache;
2289     if (!m_wallet_descriptor.descriptor->Expand(0, provider, scripts_temp, out_keys, &temp_cache)){
2290         throw std::runtime_error("Unable to expand descriptor");
2291     }
2292 
2293     // Cache the last hardened xpubs
2294     DescriptorCache diff = m_wallet_descriptor.cache.MergeAndDiff(temp_cache);
2295     if (!WalletBatch(m_storage.GetDatabase()).WriteDescriptorCacheItems(GetID(), diff)) {
2296         throw std::runtime_error(std::string(__func__) + ": writing cache items failed");
2297     }
2298 }
2299 
UpdateWalletDescriptor(WalletDescriptor & descriptor)2300 void DescriptorScriptPubKeyMan::UpdateWalletDescriptor(WalletDescriptor& descriptor)
2301 {
2302     LOCK(cs_desc_man);
2303     std::string error;
2304     if (!CanUpdateToWalletDescriptor(descriptor, error)) {
2305         throw std::runtime_error(std::string(__func__) + ": " + error);
2306     }
2307 
2308     m_map_pubkeys.clear();
2309     m_map_script_pub_keys.clear();
2310     m_max_cached_index = -1;
2311     m_wallet_descriptor = descriptor;
2312 }
2313 
CanUpdateToWalletDescriptor(const WalletDescriptor & descriptor,std::string & error)2314 bool DescriptorScriptPubKeyMan::CanUpdateToWalletDescriptor(const WalletDescriptor& descriptor, std::string& error)
2315 {
2316     LOCK(cs_desc_man);
2317     if (!HasWalletDescriptor(descriptor)) {
2318         error = "can only update matching descriptor";
2319         return false;
2320     }
2321 
2322     if (descriptor.range_start > m_wallet_descriptor.range_start ||
2323         descriptor.range_end < m_wallet_descriptor.range_end) {
2324         // Use inclusive range for error
2325         error = strprintf("new range must include current range = [%d,%d]",
2326                           m_wallet_descriptor.range_start,
2327                           m_wallet_descriptor.range_end - 1);
2328         return false;
2329     }
2330 
2331     return true;
2332 }
2333