Bitcoin Core  27.99.0
P2P Digital Currency
scriptpubkeyman.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2022 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 <hash.h>
6 #include <key_io.h>
7 #include <logging.h>
8 #include <outputtype.h>
9 #include <script/descriptor.h>
10 #include <script/script.h>
11 #include <script/sign.h>
12 #include <script/solver.h>
13 #include <util/bip32.h>
14 #include <util/strencodings.h>
15 #include <util/string.h>
16 #include <util/time.h>
17 #include <util/translation.h>
18 #include <wallet/scriptpubkeyman.h>
19 
20 #include <optional>
21 
22 namespace wallet {
24 const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
25 
27 {
28  if (LEGACY_OUTPUT_TYPES.count(type) == 0) {
29  return util::Error{_("Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
30  }
31  assert(type != OutputType::BECH32M);
32 
33  // Fill-up keypool if needed
34  TopUp();
35 
37 
38  // Generate a new key that is added to wallet
39  CPubKey new_key;
40  if (!GetKeyFromPool(new_key, type)) {
41  return util::Error{_("Error: Keypool ran out, please call keypoolrefill first")};
42  }
43  LearnRelatedScripts(new_key, type);
44  return GetDestinationForKey(new_key, type);
45 }
46 
47 typedef std::vector<unsigned char> valtype;
48 
49 namespace {
50 
57 enum class IsMineSigVersion
58 {
59  TOP = 0,
60  P2SH = 1,
61  WITNESS_V0 = 2,
62 };
63 
69 enum class IsMineResult
70 {
71  NO = 0,
72  WATCH_ONLY = 1,
73  SPENDABLE = 2,
74  INVALID = 3,
75 };
76 
77 bool PermitsUncompressed(IsMineSigVersion sigversion)
78 {
79  return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
80 }
81 
82 bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyScriptPubKeyMan& keystore)
83 {
84  for (const valtype& pubkey : pubkeys) {
85  CKeyID keyID = CPubKey(pubkey).GetID();
86  if (!keystore.HaveKey(keyID)) return false;
87  }
88  return true;
89 }
90 
99 IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion, bool recurse_scripthash=true)
100 {
101  IsMineResult ret = IsMineResult::NO;
102 
103  std::vector<valtype> vSolutions;
104  TxoutType whichType = Solver(scriptPubKey, vSolutions);
105 
106  CKeyID keyID;
107  switch (whichType) {
112  break;
113  case TxoutType::PUBKEY:
114  keyID = CPubKey(vSolutions[0]).GetID();
115  if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
116  return IsMineResult::INVALID;
117  }
118  if (keystore.HaveKey(keyID)) {
119  ret = std::max(ret, IsMineResult::SPENDABLE);
120  }
121  break;
123  {
124  if (sigversion == IsMineSigVersion::WITNESS_V0) {
125  // P2WPKH inside P2WSH is invalid.
126  return IsMineResult::INVALID;
127  }
128  if (sigversion == IsMineSigVersion::TOP && !keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
129  // We do not support bare witness outputs unless the P2SH version of it would be
130  // acceptable as well. This protects against matching before segwit activates.
131  // This also applies to the P2WSH case.
132  break;
133  }
134  ret = std::max(ret, IsMineInner(keystore, GetScriptForDestination(PKHash(uint160(vSolutions[0]))), IsMineSigVersion::WITNESS_V0));
135  break;
136  }
138  keyID = CKeyID(uint160(vSolutions[0]));
139  if (!PermitsUncompressed(sigversion)) {
140  CPubKey pubkey;
141  if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) {
142  return IsMineResult::INVALID;
143  }
144  }
145  if (keystore.HaveKey(keyID)) {
146  ret = std::max(ret, IsMineResult::SPENDABLE);
147  }
148  break;
150  {
151  if (sigversion != IsMineSigVersion::TOP) {
152  // P2SH inside P2WSH or P2SH is invalid.
153  return IsMineResult::INVALID;
154  }
155  CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
156  CScript subscript;
157  if (keystore.GetCScript(scriptID, subscript)) {
158  ret = std::max(ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::P2SH) : IsMineResult::SPENDABLE);
159  }
160  break;
161  }
163  {
164  if (sigversion == IsMineSigVersion::WITNESS_V0) {
165  // P2WSH inside P2WSH is invalid.
166  return IsMineResult::INVALID;
167  }
168  if (sigversion == IsMineSigVersion::TOP && !keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
169  break;
170  }
171  CScriptID scriptID{RIPEMD160(vSolutions[0])};
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 
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 
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();
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;
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)
262  return false;
264  }
265  return true;
266 }
267 
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{UCharCast(key.begin()), UCharCast(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 
299 {
300  if (LEGACY_OUTPUT_TYPES.count(type) == 0) {
301  return util::Error{_("Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
302  }
303  assert(type != OutputType::BECH32M);
304 
305  LOCK(cs_KeyStore);
306  if (!CanGetAddresses(internal)) {
307  return util::Error{_("Error: Keypool ran out, please call keypoolrefill first")};
308  }
309 
310  // Fill-up keypool if needed
311  TopUp();
312 
313  if (!ReserveKeyFromKeyPool(index, keypool, internal)) {
314  return util::Error{_("Error: Keypool ran out, please call keypoolrefill first")};
315  }
316  return GetDestinationForKey(keypool.vchPubKey, type);
317 }
318 
319 bool LegacyScriptPubKeyMan::TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal)
320 {
321  LOCK(cs_KeyStore);
322 
323  auto it = m_inactive_hd_chains.find(seed_id);
324  if (it == m_inactive_hd_chains.end()) {
325  return false;
326  }
327 
328  CHDChain& chain = it->second;
329 
330  if (internal) {
331  chain.m_next_internal_index = std::max(chain.m_next_internal_index, index + 1);
332  } else {
333  chain.m_next_external_index = std::max(chain.m_next_external_index, index + 1);
334  }
335 
337  TopUpChain(batch, chain, 0);
338 
339  return true;
340 }
341 
342 std::vector<WalletDestination> LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
343 {
344  LOCK(cs_KeyStore);
345  std::vector<WalletDestination> result;
346  // extract addresses and check if they match with an unused keypool key
347  for (const auto& keyid : GetAffectedKeys(script, *this)) {
348  std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
349  if (mi != m_pool_key_to_index.end()) {
350  WalletLogPrintf("%s: Detected a used keypool key, mark all keypool keys up to this key as used\n", __func__);
351  for (const auto& keypool : MarkReserveKeysAsUsed(mi->second)) {
352  // derive all possible destinations as any of them could have been used
353  for (const auto& type : LEGACY_OUTPUT_TYPES) {
354  const auto& dest = GetDestinationForKey(keypool.vchPubKey, type);
355  result.push_back({dest, keypool.fInternal});
356  }
357  }
358 
359  if (!TopUp()) {
360  WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
361  }
362  }
363 
364  // 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.
365  // If so, TopUp the inactive hd chain
366  auto it = mapKeyMetadata.find(keyid);
367  if (it != mapKeyMetadata.end()){
368  CKeyMetadata meta = it->second;
369  if (!meta.hd_seed_id.IsNull() && meta.hd_seed_id != m_hd_chain.seed_id) {
370  std::vector<uint32_t> path;
371  if (meta.has_key_origin) {
372  path = meta.key_origin.path;
373  } else if (!ParseHDKeypath(meta.hdKeypath, path)) {
374  WalletLogPrintf("%s: Adding inactive seed keys failed, invalid hdKeypath: %s\n",
375  __func__,
376  meta.hdKeypath);
377  }
378  if (path.size() != 3) {
379  WalletLogPrintf("%s: Adding inactive seed keys failed, invalid path size: %d, has_key_origin: %s\n",
380  __func__,
381  path.size(),
382  meta.has_key_origin);
383  } else {
384  bool internal = (path[1] & ~BIP32_HARDENED_KEY_LIMIT) != 0;
385  int64_t index = path[2] & ~BIP32_HARDENED_KEY_LIMIT;
386 
387  if (!TopUpInactiveHDChain(meta.hd_seed_id, index, internal)) {
388  WalletLogPrintf("%s: Adding inactive seed keys failed\n", __func__);
389  }
390  }
391  }
392  }
393  }
394 
395  return result;
396 }
397 
399 {
400  LOCK(cs_KeyStore);
402  return;
403  }
404 
405  std::unique_ptr<WalletBatch> batch = std::make_unique<WalletBatch>(m_storage.GetDatabase());
406  for (auto& meta_pair : mapKeyMetadata) {
407  CKeyMetadata& meta = meta_pair.second;
408  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
409  CKey key;
410  GetKey(meta.hd_seed_id, key);
411  CExtKey masterKey;
412  masterKey.SetSeed(key);
413  // Add to map
414  CKeyID master_id = masterKey.key.GetPubKey().GetID();
415  std::copy(master_id.begin(), master_id.begin() + 4, meta.key_origin.fingerprint);
416  if (!ParseHDKeypath(meta.hdKeypath, meta.key_origin.path)) {
417  throw std::runtime_error("Invalid stored hdKeypath");
418  }
419  meta.has_key_origin = true;
422  }
423 
424  // Write meta to wallet
425  CPubKey pubkey;
426  if (GetPubKey(meta_pair.first, pubkey)) {
427  batch->WriteKeyMetadata(meta, pubkey, true);
428  }
429  }
430  }
431 }
432 
434 {
435  if ((CanGenerateKeys() && !force) || m_storage.IsLocked()) {
436  return false;
437  }
438 
440  if (!NewKeyPool()) {
441  return false;
442  }
443  return true;
444 }
445 
447 {
448  return !m_hd_chain.seed_id.IsNull();
449 }
450 
451 bool LegacyScriptPubKeyMan::CanGetAddresses(bool internal) const
452 {
453  LOCK(cs_KeyStore);
454  // Check if the keypool has keys
455  bool keypool_has_keys;
456  if (internal && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) {
457  keypool_has_keys = setInternalKeyPool.size() > 0;
458  } else {
459  keypool_has_keys = KeypoolCountExternalKeys() > 0;
460  }
461  // If the keypool doesn't have keys, check if we can generate them
462  if (!keypool_has_keys) {
463  return CanGenerateKeys();
464  }
465  return keypool_has_keys;
466 }
467 
468 bool LegacyScriptPubKeyMan::Upgrade(int prev_version, int new_version, bilingual_str& error)
469 {
470  LOCK(cs_KeyStore);
471 
473  // Nothing to do here if private keys are not enabled
474  return true;
475  }
476 
477  bool hd_upgrade = false;
478  bool split_upgrade = false;
479  if (IsFeatureSupported(new_version, FEATURE_HD) && !IsHDEnabled()) {
480  WalletLogPrintf("Upgrading wallet to HD\n");
482 
483  // generate a new master key
484  CPubKey masterPubKey = GenerateNewSeed();
485  SetHDSeed(masterPubKey);
486  hd_upgrade = true;
487  }
488  // Upgrade to HD chain split if necessary
489  if (!IsFeatureSupported(prev_version, FEATURE_HD_SPLIT) && IsFeatureSupported(new_version, FEATURE_HD_SPLIT)) {
490  WalletLogPrintf("Upgrading wallet to use HD chain split\n");
492  split_upgrade = FEATURE_HD_SPLIT > prev_version;
493  // Upgrade the HDChain
497  throw std::runtime_error(std::string(__func__) + ": writing chain failed");
498  }
499  }
500  }
501  // Mark all keys currently in the keypool as pre-split
502  if (split_upgrade) {
504  }
505  // Regenerate the keypool if upgraded to HD
506  if (hd_upgrade) {
507  if (!NewKeyPool()) {
508  error = _("Unable to generate keys");
509  return false;
510  }
511  }
512  return true;
513 }
514 
516 {
517  LOCK(cs_KeyStore);
518  return !mapKeys.empty() || !mapCryptedKeys.empty();
519 }
520 
522 {
523  LOCK(cs_KeyStore);
524  setInternalKeyPool.clear();
525  setExternalKeyPool.clear();
526  m_pool_key_to_index.clear();
527  // Note: can't top-up keypool here, because wallet is locked.
528  // User will be prompted to unlock wallet the next operation
529  // that requires a new key.
530 }
531 
532 static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, WalletBatch& batch) {
533  if (setKeyPool.empty()) {
534  return GetTime();
535  }
536 
537  CKeyPool keypool;
538  int64_t nIndex = *(setKeyPool.begin());
539  if (!batch.ReadPool(nIndex, keypool)) {
540  throw std::runtime_error(std::string(__func__) + ": read oldest key in keypool failed");
541  }
542  assert(keypool.vchPubKey.IsValid());
543  return keypool.nTime;
544 }
545 
546 std::optional<int64_t> LegacyScriptPubKeyMan::GetOldestKeyPoolTime() const
547 {
548  LOCK(cs_KeyStore);
549 
551 
552  // load oldest key from keypool, get time and return
553  int64_t oldestKey = GetOldestKeyTimeInPool(setExternalKeyPool, batch);
555  oldestKey = std::max(GetOldestKeyTimeInPool(setInternalKeyPool, batch), oldestKey);
556  if (!set_pre_split_keypool.empty()) {
557  oldestKey = std::max(GetOldestKeyTimeInPool(set_pre_split_keypool, batch), oldestKey);
558  }
559  }
560 
561  return oldestKey;
562 }
563 
565 {
566  LOCK(cs_KeyStore);
567  return setExternalKeyPool.size() + set_pre_split_keypool.size();
568 }
569 
571 {
572  LOCK(cs_KeyStore);
573  return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
574 }
575 
577 {
578  LOCK(cs_KeyStore);
579  return nTimeFirstKey;
580 }
581 
582 std::unique_ptr<SigningProvider> LegacyScriptPubKeyMan::GetSolvingProvider(const CScript& script) const
583 {
584  return std::make_unique<LegacySigningProvider>(*this);
585 }
586 
588 {
589  IsMineResult ismine = IsMineInner(*this, script, IsMineSigVersion::TOP, /* recurse_scripthash= */ false);
590  if (ismine == IsMineResult::SPENDABLE || ismine == IsMineResult::WATCH_ONLY) {
591  // If ismine, it means we recognize keys or script ids in the script, or
592  // are watching the script itself, and we can at least provide metadata
593  // or solving information, even if not able to sign fully.
594  return true;
595  } else {
596  // If, given the stuff in sigdata, we could make a valid signature, then we can provide for this script
597  ProduceSignature(*this, DUMMY_SIGNATURE_CREATOR, script, sigdata);
598  if (!sigdata.signatures.empty()) {
599  // If we could make signatures, make sure we have a private key to actually make a signature
600  bool has_privkeys = false;
601  for (const auto& key_sig_pair : sigdata.signatures) {
602  has_privkeys |= HaveKey(key_sig_pair.first);
603  }
604  return has_privkeys;
605  }
606  return false;
607  }
608 }
609 
610 bool LegacyScriptPubKeyMan::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const
611 {
612  return ::SignTransaction(tx, this, coins, sighash, input_errors);
613 }
614 
615 SigningResult LegacyScriptPubKeyMan::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const
616 {
617  CKey key;
618  if (!GetKey(ToKeyID(pkhash), key)) {
620  }
621 
622  if (MessageSign(key, message, str_sig)) {
623  return SigningResult::OK;
624  }
626 }
627 
628 TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed, bool finalize) const
629 {
630  if (n_signed) {
631  *n_signed = 0;
632  }
633  for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
634  const CTxIn& txin = psbtx.tx->vin[i];
635  PSBTInput& input = psbtx.inputs.at(i);
636 
637  if (PSBTInputSigned(input)) {
638  continue;
639  }
640 
641  // Get the Sighash type
642  if (sign && input.sighash_type != std::nullopt && *input.sighash_type != sighash_type) {
644  }
645 
646  // Check non_witness_utxo has specified prevout
647  if (input.non_witness_utxo) {
648  if (txin.prevout.n >= input.non_witness_utxo->vout.size()) {
650  }
651  } else if (input.witness_utxo.IsNull()) {
652  // There's no UTXO so we can just skip this now
653  continue;
654  }
655  SignPSBTInput(HidingSigningProvider(this, !sign, !bip32derivs), psbtx, i, &txdata, sighash_type, nullptr, finalize);
656 
657  bool signed_one = PSBTInputSigned(input);
658  if (n_signed && (signed_one || !sign)) {
659  // If sign is false, we assume that we _could_ sign if we get here. This
660  // will never have false negatives; it is hard to tell under what i
661  // circumstances it could have false positives.
662  (*n_signed)++;
663  }
664  }
665 
666  // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
667  for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
668  UpdatePSBTOutput(HidingSigningProvider(this, true, !bip32derivs), psbtx, i);
669  }
670 
671  return TransactionError::OK;
672 }
673 
674 std::unique_ptr<CKeyMetadata> LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const
675 {
676  LOCK(cs_KeyStore);
677 
678  CKeyID key_id = GetKeyForDestination(*this, dest);
679  if (!key_id.IsNull()) {
680  auto it = mapKeyMetadata.find(key_id);
681  if (it != mapKeyMetadata.end()) {
682  return std::make_unique<CKeyMetadata>(it->second);
683  }
684  }
685 
686  CScript scriptPubKey = GetScriptForDestination(dest);
687  auto it = m_script_metadata.find(CScriptID(scriptPubKey));
688  if (it != m_script_metadata.end()) {
689  return std::make_unique<CKeyMetadata>(it->second);
690  }
691 
692  return nullptr;
693 }
694 
696 {
697  return uint256::ONE;
698 }
699 
705 {
707  if (nCreateTime <= 1) {
708  // Cannot determine birthday information, so set the wallet birthday to
709  // the beginning of time.
710  nTimeFirstKey = 1;
711  } else if (nTimeFirstKey == UNKNOWN_TIME || nCreateTime < nTimeFirstKey) {
712  nTimeFirstKey = nCreateTime;
713  }
714 
715  NotifyFirstKeyTimeChanged(this, nTimeFirstKey);
716 }
717 
718 bool LegacyScriptPubKeyMan::LoadKey(const CKey& key, const CPubKey &pubkey)
719 {
720  return AddKeyPubKeyInner(key, pubkey);
721 }
722 
723 bool LegacyScriptPubKeyMan::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
724 {
725  LOCK(cs_KeyStore);
727  return LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(batch, secret, pubkey);
728 }
729 
730 bool LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& secret, const CPubKey& pubkey)
731 {
733 
734  // Make sure we aren't adding private keys to private key disabled wallets
736 
737  // FillableSigningProvider has no concept of wallet databases, but calls AddCryptedKey
738  // which is overridden below. To avoid flushes, the database handle is
739  // tunneled through to it.
740  bool needsDB = !encrypted_batch;
741  if (needsDB) {
742  encrypted_batch = &batch;
743  }
744  if (!AddKeyPubKeyInner(secret, pubkey)) {
745  if (needsDB) encrypted_batch = nullptr;
746  return false;
747  }
748  if (needsDB) encrypted_batch = nullptr;
749 
750  // check if we need to remove from watch-only
751  CScript script;
752  script = GetScriptForDestination(PKHash(pubkey));
753  if (HaveWatchOnly(script)) {
754  RemoveWatchOnly(script);
755  }
756  script = GetScriptForRawPubKey(pubkey);
757  if (HaveWatchOnly(script)) {
758  RemoveWatchOnly(script);
759  }
760 
762  if (!m_storage.HasEncryptionKeys()) {
763  return batch.WriteKey(pubkey,
764  secret.GetPrivKey(),
765  mapKeyMetadata[pubkey.GetID()]);
766  }
767  return true;
768 }
769 
771 {
772  /* A sanity check was added in pull #3843 to avoid adding redeemScripts
773  * that never can be redeemed. However, old wallets may still contain
774  * these. Do not add them to the wallet and warn. */
775  if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
776  {
777  std::string strAddr = EncodeDestination(ScriptHash(redeemScript));
778  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);
779  return true;
780  }
781 
782  return FillableSigningProvider::AddCScript(redeemScript);
783 }
784 
786 {
787  LOCK(cs_KeyStore);
789  mapKeyMetadata[keyID] = meta;
790 }
791 
793 {
794  LOCK(cs_KeyStore);
796  m_script_metadata[script_id] = meta;
797 }
798 
800 {
801  LOCK(cs_KeyStore);
802  if (!m_storage.HasEncryptionKeys()) {
803  return FillableSigningProvider::AddKeyPubKey(key, pubkey);
804  }
805 
806  if (m_storage.IsLocked()) {
807  return false;
808  }
809 
810  std::vector<unsigned char> vchCryptedSecret;
811  CKeyingMaterial vchSecret{UCharCast(key.begin()), UCharCast(key.end())};
812  if (!m_storage.WithEncryptionKey([&](const CKeyingMaterial& encryption_key) {
813  return EncryptSecret(encryption_key, vchSecret, pubkey.GetHash(), vchCryptedSecret);
814  })) {
815  return false;
816  }
817 
818  if (!AddCryptedKey(pubkey, vchCryptedSecret)) {
819  return false;
820  }
821  return true;
822 }
823 
824 bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid)
825 {
826  // Set fDecryptionThoroughlyChecked to false when the checksum is invalid
827  if (!checksum_valid) {
829  }
830 
831  return AddCryptedKeyInner(vchPubKey, vchCryptedSecret);
832 }
833 
834 bool LegacyScriptPubKeyMan::AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
835 {
836  LOCK(cs_KeyStore);
837  assert(mapKeys.empty());
838 
839  mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
841  return true;
842 }
843 
845  const std::vector<unsigned char> &vchCryptedSecret)
846 {
847  if (!AddCryptedKeyInner(vchPubKey, vchCryptedSecret))
848  return false;
849  {
850  LOCK(cs_KeyStore);
851  if (encrypted_batch)
852  return encrypted_batch->WriteCryptedKey(vchPubKey,
853  vchCryptedSecret,
854  mapKeyMetadata[vchPubKey.GetID()]);
855  else
856  return WalletBatch(m_storage.GetDatabase()).WriteCryptedKey(vchPubKey,
857  vchCryptedSecret,
858  mapKeyMetadata[vchPubKey.GetID()]);
859  }
860 }
861 
863 {
864  LOCK(cs_KeyStore);
865  return setWatchOnly.count(dest) > 0;
866 }
867 
869 {
870  LOCK(cs_KeyStore);
871  return (!setWatchOnly.empty());
872 }
873 
874 static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
875 {
876  std::vector<std::vector<unsigned char>> solutions;
877  return Solver(dest, solutions) == TxoutType::PUBKEY &&
878  (pubKeyOut = CPubKey(solutions[0])).IsFullyValid();
879 }
880 
882 {
883  {
884  LOCK(cs_KeyStore);
885  setWatchOnly.erase(dest);
886  CPubKey pubKey;
887  if (ExtractPubKey(dest, pubKey)) {
888  mapWatchKeys.erase(pubKey.GetID());
889  }
890  // Related CScripts are not removed; having superfluous scripts around is
891  // harmless (see comment in ImplicitlyLearnRelatedKeyScripts).
892  }
893 
894  if (!HaveWatchOnly())
895  NotifyWatchonlyChanged(false);
897  return false;
898 
899  return true;
900 }
901 
903 {
904  return AddWatchOnlyInMem(dest);
905 }
906 
908 {
909  LOCK(cs_KeyStore);
910  setWatchOnly.insert(dest);
911  CPubKey pubKey;
912  if (ExtractPubKey(dest, pubKey)) {
913  mapWatchKeys[pubKey.GetID()] = pubKey;
915  }
916  return true;
917 }
918 
920 {
921  if (!AddWatchOnlyInMem(dest))
922  return false;
923  const CKeyMetadata& meta = m_script_metadata[CScriptID(dest)];
926  if (batch.WriteWatchOnly(dest, meta)) {
928  return true;
929  }
930  return false;
931 }
932 
933 bool LegacyScriptPubKeyMan::AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time)
934 {
935  m_script_metadata[CScriptID(dest)].nCreateTime = create_time;
936  return AddWatchOnlyWithDB(batch, dest);
937 }
938 
940 {
942  return AddWatchOnlyWithDB(batch, dest);
943 }
944 
945 bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
946 {
947  m_script_metadata[CScriptID(dest)].nCreateTime = nCreateTime;
948  return AddWatchOnly(dest);
949 }
950 
952 {
953  LOCK(cs_KeyStore);
954  m_hd_chain = chain;
955 }
956 
958 {
959  LOCK(cs_KeyStore);
960  // Store the new chain
962  throw std::runtime_error(std::string(__func__) + ": writing chain failed");
963  }
964  // When there's an old chain, add it as an inactive chain as we are now rotating hd chains
965  if (!m_hd_chain.seed_id.IsNull()) {
967  }
968 
969  m_hd_chain = chain;
970 }
971 
973 {
974  LOCK(cs_KeyStore);
975  assert(!chain.seed_id.IsNull());
976  m_inactive_hd_chains[chain.seed_id] = chain;
977 }
978 
979 bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const
980 {
981  LOCK(cs_KeyStore);
982  if (!m_storage.HasEncryptionKeys()) {
983  return FillableSigningProvider::HaveKey(address);
984  }
985  return mapCryptedKeys.count(address) > 0;
986 }
987 
988 bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const
989 {
990  LOCK(cs_KeyStore);
991  if (!m_storage.HasEncryptionKeys()) {
992  return FillableSigningProvider::GetKey(address, keyOut);
993  }
994 
995  CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
996  if (mi != mapCryptedKeys.end())
997  {
998  const CPubKey &vchPubKey = (*mi).second.first;
999  const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
1000  return m_storage.WithEncryptionKey([&](const CKeyingMaterial& encryption_key) {
1001  return DecryptKey(encryption_key, vchCryptedSecret, vchPubKey, keyOut);
1002  });
1003  }
1004  return false;
1005 }
1006 
1008 {
1009  CKeyMetadata meta;
1010  {
1011  LOCK(cs_KeyStore);
1012  auto it = mapKeyMetadata.find(keyID);
1013  if (it == mapKeyMetadata.end()) {
1014  return false;
1015  }
1016  meta = it->second;
1017  }
1018  if (meta.has_key_origin) {
1019  std::copy(meta.key_origin.fingerprint, meta.key_origin.fingerprint + 4, info.fingerprint);
1020  info.path = meta.key_origin.path;
1021  } else { // Single pubkeys get the master fingerprint of themselves
1022  std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint);
1023  }
1024  return true;
1025 }
1026 
1027 bool LegacyScriptPubKeyMan::GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
1028 {
1029  LOCK(cs_KeyStore);
1030  WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
1031  if (it != mapWatchKeys.end()) {
1032  pubkey_out = it->second;
1033  return true;
1034  }
1035  return false;
1036 }
1037 
1038 bool LegacyScriptPubKeyMan::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
1039 {
1040  LOCK(cs_KeyStore);
1041  if (!m_storage.HasEncryptionKeys()) {
1042  if (!FillableSigningProvider::GetPubKey(address, vchPubKeyOut)) {
1043  return GetWatchPubKey(address, vchPubKeyOut);
1044  }
1045  return true;
1046  }
1047 
1048  CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1049  if (mi != mapCryptedKeys.end())
1050  {
1051  vchPubKeyOut = (*mi).second.first;
1052  return true;
1053  }
1054  // Check for watch-only pubkeys
1055  return GetWatchPubKey(address, vchPubKeyOut);
1056 }
1057 
1059 {
1063  bool fCompressed = m_storage.CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
1064 
1065  CKey secret;
1066 
1067  // Create new metadata
1068  int64_t nCreationTime = GetTime();
1069  CKeyMetadata metadata(nCreationTime);
1070 
1071  // use HD key derivation if HD was enabled during wallet creation and a seed is present
1072  if (IsHDEnabled()) {
1073  DeriveNewChildKey(batch, metadata, secret, hd_chain, (m_storage.CanSupportFeature(FEATURE_HD_SPLIT) ? internal : false));
1074  } else {
1075  secret.MakeNewKey(fCompressed);
1076  }
1077 
1078  // Compressed public keys were introduced in version 0.6.0
1079  if (fCompressed) {
1081  }
1082 
1083  CPubKey pubkey = secret.GetPubKey();
1084  assert(secret.VerifyPubKey(pubkey));
1085 
1086  mapKeyMetadata[pubkey.GetID()] = metadata;
1087  UpdateTimeFirstKey(nCreationTime);
1088 
1089  if (!AddKeyPubKeyWithDB(batch, secret, pubkey)) {
1090  throw std::runtime_error(std::string(__func__) + ": AddKey failed");
1091  }
1092  return pubkey;
1093 }
1094 
1096 static void DeriveExtKey(CExtKey& key_in, unsigned int index, CExtKey& key_out) {
1097  if (!key_in.Derive(key_out, index)) {
1098  throw std::runtime_error("Could not derive extended key");
1099  }
1100 }
1101 
1102 void LegacyScriptPubKeyMan::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey& secret, CHDChain& hd_chain, bool internal)
1103 {
1104  // for now we use a fixed keypath scheme of m/0'/0'/k
1105  CKey seed; //seed (256bit)
1106  CExtKey masterKey; //hd master key
1107  CExtKey accountKey; //key at m/0'
1108  CExtKey chainChildKey; //key at m/0'/0' (external) or m/0'/1' (internal)
1109  CExtKey childKey; //key at m/0'/0'/<n>'
1110 
1111  // try to get the seed
1112  if (!GetKey(hd_chain.seed_id, seed))
1113  throw std::runtime_error(std::string(__func__) + ": seed not found");
1114 
1115  masterKey.SetSeed(seed);
1116 
1117  // derive m/0'
1118  // use hardened derivation (child keys >= 0x80000000 are hardened after bip32)
1119  DeriveExtKey(masterKey, BIP32_HARDENED_KEY_LIMIT, accountKey);
1120 
1121  // derive m/0'/0' (external chain) OR m/0'/1' (internal chain)
1122  assert(internal ? m_storage.CanSupportFeature(FEATURE_HD_SPLIT) : true);
1123  DeriveExtKey(accountKey, BIP32_HARDENED_KEY_LIMIT+(internal ? 1 : 0), chainChildKey);
1124 
1125  // derive child key at next index, skip keys already known to the wallet
1126  do {
1127  // always derive hardened keys
1128  // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
1129  // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
1130  if (internal) {
1131  DeriveExtKey(chainChildKey, hd_chain.nInternalChainCounter | BIP32_HARDENED_KEY_LIMIT, childKey);
1132  metadata.hdKeypath = "m/0'/1'/" + ToString(hd_chain.nInternalChainCounter) + "'";
1133  metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
1134  metadata.key_origin.path.push_back(1 | BIP32_HARDENED_KEY_LIMIT);
1135  metadata.key_origin.path.push_back(hd_chain.nInternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1136  hd_chain.nInternalChainCounter++;
1137  }
1138  else {
1139  DeriveExtKey(chainChildKey, hd_chain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT, childKey);
1140  metadata.hdKeypath = "m/0'/0'/" + ToString(hd_chain.nExternalChainCounter) + "'";
1141  metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
1142  metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
1143  metadata.key_origin.path.push_back(hd_chain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
1144  hd_chain.nExternalChainCounter++;
1145  }
1146  } while (HaveKey(childKey.key.GetPubKey().GetID()));
1147  secret = childKey.key;
1148  metadata.hd_seed_id = hd_chain.seed_id;
1149  CKeyID master_id = masterKey.key.GetPubKey().GetID();
1150  std::copy(master_id.begin(), master_id.begin() + 4, metadata.key_origin.fingerprint);
1151  metadata.has_key_origin = true;
1152  // update the chain model in the database
1153  if (hd_chain.seed_id == m_hd_chain.seed_id && !batch.WriteHDChain(hd_chain))
1154  throw std::runtime_error(std::string(__func__) + ": writing HD chain model failed");
1155 }
1156 
1157 void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
1158 {
1159  LOCK(cs_KeyStore);
1160  if (keypool.m_pre_split) {
1161  set_pre_split_keypool.insert(nIndex);
1162  } else if (keypool.fInternal) {
1163  setInternalKeyPool.insert(nIndex);
1164  } else {
1165  setExternalKeyPool.insert(nIndex);
1166  }
1167  m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
1168  m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex;
1169 
1170  // If no metadata exists yet, create a default with the pool key's
1171  // creation time. Note that this may be overwritten by actually
1172  // stored metadata for that key later, which is fine.
1173  CKeyID keyid = keypool.vchPubKey.GetID();
1174  if (mapKeyMetadata.count(keyid) == 0)
1175  mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
1176 }
1177 
1179 {
1180  // A wallet can generate keys if it has an HD seed (IsHDEnabled) or it is a non-HD wallet (pre FEATURE_HD)
1181  LOCK(cs_KeyStore);
1183 }
1184 
1186 {
1188  CKey key = GenerateRandomKey();
1189  return DeriveNewSeed(key);
1190 }
1191 
1193 {
1194  int64_t nCreationTime = GetTime();
1195  CKeyMetadata metadata(nCreationTime);
1196 
1197  // calculate the seed
1198  CPubKey seed = key.GetPubKey();
1199  assert(key.VerifyPubKey(seed));
1200 
1201  // set the hd keypath to "s" -> Seed, refers the seed to itself
1202  metadata.hdKeypath = "s";
1203  metadata.has_key_origin = false;
1204  metadata.hd_seed_id = seed.GetID();
1205 
1206  {
1207  LOCK(cs_KeyStore);
1208 
1209  // mem store the metadata
1210  mapKeyMetadata[seed.GetID()] = metadata;
1211 
1212  // write the key&metadata to the database
1213  if (!AddKeyPubKey(key, seed))
1214  throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed");
1215  }
1216 
1217  return seed;
1218 }
1219 
1221 {
1222  LOCK(cs_KeyStore);
1223  // store the keyid (hash160) together with
1224  // the child index counter in the database
1225  // as a hdchain object
1226  CHDChain newHdChain;
1228  newHdChain.seed_id = seed.GetID();
1229  AddHDChain(newHdChain);
1233 }
1234 
1240 {
1242  return false;
1243  }
1244  {
1245  LOCK(cs_KeyStore);
1247 
1248  for (const int64_t nIndex : setInternalKeyPool) {
1249  batch.ErasePool(nIndex);
1250  }
1251  setInternalKeyPool.clear();
1252 
1253  for (const int64_t nIndex : setExternalKeyPool) {
1254  batch.ErasePool(nIndex);
1255  }
1256  setExternalKeyPool.clear();
1257 
1258  for (const int64_t nIndex : set_pre_split_keypool) {
1259  batch.ErasePool(nIndex);
1260  }
1261  set_pre_split_keypool.clear();
1262 
1263  m_pool_key_to_index.clear();
1264 
1265  if (!TopUp()) {
1266  return false;
1267  }
1268  WalletLogPrintf("LegacyScriptPubKeyMan::NewKeyPool rewrote keypool\n");
1269  }
1270  return true;
1271 }
1272 
1273 bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
1274 {
1275  if (!CanGenerateKeys()) {
1276  return false;
1277  }
1278 
1280  if (!batch.TxnBegin()) return false;
1281  if (!TopUpChain(batch, m_hd_chain, kpSize)) {
1282  return false;
1283  }
1284  for (auto& [chain_id, chain] : m_inactive_hd_chains) {
1285  if (!TopUpChain(batch, chain, kpSize)) {
1286  return false;
1287  }
1288  }
1289  if (!batch.TxnCommit()) throw std::runtime_error(strprintf("Error during keypool top up. Cannot commit changes for wallet %s", m_storage.GetDisplayName()));
1291  // Note: Unlike with DescriptorSPKM, LegacySPKM does not need to call
1292  // m_storage.TopUpCallback() as we do not know what new scripts the LegacySPKM is
1293  // watching for. CWallet's scriptPubKey cache is not used for LegacySPKMs.
1294  return true;
1295 }
1296 
1297 bool LegacyScriptPubKeyMan::TopUpChain(WalletBatch& batch, CHDChain& chain, unsigned int kpSize)
1298 {
1299  LOCK(cs_KeyStore);
1300 
1301  if (m_storage.IsLocked()) return false;
1302 
1303  // Top up key pool
1304  unsigned int nTargetSize;
1305  if (kpSize > 0) {
1306  nTargetSize = kpSize;
1307  } else {
1308  nTargetSize = m_keypool_size;
1309  }
1310  int64_t target = std::max((int64_t) nTargetSize, int64_t{1});
1311 
1312  // count amount of available keys (internal, external)
1313  // make sure the keypool of external and internal keys fits the user selected target (-keypool)
1314  int64_t missingExternal;
1315  int64_t missingInternal;
1316  if (chain == m_hd_chain) {
1317  missingExternal = std::max(target - (int64_t)setExternalKeyPool.size(), int64_t{0});
1318  missingInternal = std::max(target - (int64_t)setInternalKeyPool.size(), int64_t{0});
1319  } else {
1320  missingExternal = std::max(target - (chain.nExternalChainCounter - chain.m_next_external_index), int64_t{0});
1321  missingInternal = std::max(target - (chain.nInternalChainCounter - chain.m_next_internal_index), int64_t{0});
1322  }
1323 
1325  // don't create extra internal keys
1326  missingInternal = 0;
1327  }
1328  bool internal = false;
1329  for (int64_t i = missingInternal + missingExternal; i--;) {
1330  if (i < missingInternal) {
1331  internal = true;
1332  }
1333 
1334  CPubKey pubkey(GenerateNewKey(batch, chain, internal));
1335  if (chain == m_hd_chain) {
1336  AddKeypoolPubkeyWithDB(pubkey, internal, batch);
1337  }
1338  }
1339  if (missingInternal + missingExternal > 0) {
1340  if (chain == m_hd_chain) {
1341  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());
1342  } else {
1343  WalletLogPrintf("inactive seed with id %s added %d external keys, %d internal keys\n", HexStr(chain.seed_id), missingExternal, missingInternal);
1344  }
1345  }
1346  return true;
1347 }
1348 
1349 void LegacyScriptPubKeyMan::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch)
1350 {
1351  LOCK(cs_KeyStore);
1352  assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
1353  int64_t index = ++m_max_keypool_index;
1354  if (!batch.WritePool(index, CKeyPool(pubkey, internal))) {
1355  throw std::runtime_error(std::string(__func__) + ": writing imported pubkey failed");
1356  }
1357  if (internal) {
1358  setInternalKeyPool.insert(index);
1359  } else {
1360  setExternalKeyPool.insert(index);
1361  }
1362  m_pool_key_to_index[pubkey.GetID()] = index;
1363 }
1364 
1365 void LegacyScriptPubKeyMan::KeepDestination(int64_t nIndex, const OutputType& type)
1366 {
1367  assert(type != OutputType::BECH32M);
1368  // Remove from key pool
1370  batch.ErasePool(nIndex);
1371  CPubKey pubkey;
1372  bool have_pk = GetPubKey(m_index_to_reserved_key.at(nIndex), pubkey);
1373  assert(have_pk);
1374  LearnRelatedScripts(pubkey, type);
1375  m_index_to_reserved_key.erase(nIndex);
1376  WalletLogPrintf("keypool keep %d\n", nIndex);
1377 }
1378 
1379 void LegacyScriptPubKeyMan::ReturnDestination(int64_t nIndex, bool fInternal, const CTxDestination&)
1380 {
1381  // Return to key pool
1382  {
1383  LOCK(cs_KeyStore);
1384  if (fInternal) {
1385  setInternalKeyPool.insert(nIndex);
1386  } else if (!set_pre_split_keypool.empty()) {
1387  set_pre_split_keypool.insert(nIndex);
1388  } else {
1389  setExternalKeyPool.insert(nIndex);
1390  }
1391  CKeyID& pubkey_id = m_index_to_reserved_key.at(nIndex);
1392  m_pool_key_to_index[pubkey_id] = nIndex;
1393  m_index_to_reserved_key.erase(nIndex);
1395  }
1396  WalletLogPrintf("keypool return %d\n", nIndex);
1397 }
1398 
1400 {
1401  assert(type != OutputType::BECH32M);
1402  if (!CanGetAddresses(/*internal=*/ false)) {
1403  return false;
1404  }
1405 
1406  CKeyPool keypool;
1407  {
1408  LOCK(cs_KeyStore);
1409  int64_t nIndex;
1410  if (!ReserveKeyFromKeyPool(nIndex, keypool, /*fRequestedInternal=*/ false) && !m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
1411  if (m_storage.IsLocked()) return false;
1413  result = GenerateNewKey(batch, m_hd_chain, /*internal=*/ false);
1414  return true;
1415  }
1416  KeepDestination(nIndex, type);
1417  result = keypool.vchPubKey;
1418  }
1419  return true;
1420 }
1421 
1422 bool LegacyScriptPubKeyMan::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal)
1423 {
1424  nIndex = -1;
1425  keypool.vchPubKey = CPubKey();
1426  {
1427  LOCK(cs_KeyStore);
1428 
1429  bool fReturningInternal = fRequestedInternal;
1431  bool use_split_keypool = set_pre_split_keypool.empty();
1432  std::set<int64_t>& setKeyPool = use_split_keypool ? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) : set_pre_split_keypool;
1433 
1434  // Get the oldest key
1435  if (setKeyPool.empty()) {
1436  return false;
1437  }
1438 
1440 
1441  auto it = setKeyPool.begin();
1442  nIndex = *it;
1443  setKeyPool.erase(it);
1444  if (!batch.ReadPool(nIndex, keypool)) {
1445  throw std::runtime_error(std::string(__func__) + ": read failed");
1446  }
1447  CPubKey pk;
1448  if (!GetPubKey(keypool.vchPubKey.GetID(), pk)) {
1449  throw std::runtime_error(std::string(__func__) + ": unknown key in key pool");
1450  }
1451  // If the key was pre-split keypool, we don't care about what type it is
1452  if (use_split_keypool && keypool.fInternal != fReturningInternal) {
1453  throw std::runtime_error(std::string(__func__) + ": keypool entry misclassified");
1454  }
1455  if (!keypool.vchPubKey.IsValid()) {
1456  throw std::runtime_error(std::string(__func__) + ": keypool entry invalid");
1457  }
1458 
1459  assert(m_index_to_reserved_key.count(nIndex) == 0);
1460  m_index_to_reserved_key[nIndex] = keypool.vchPubKey.GetID();
1461  m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
1462  WalletLogPrintf("keypool reserve %d\n", nIndex);
1463  }
1465  return true;
1466 }
1467 
1469 {
1470  assert(type != OutputType::BECH32M);
1471  if (key.IsCompressed() && (type == OutputType::P2SH_SEGWIT || type == OutputType::BECH32)) {
1472  CTxDestination witdest = WitnessV0KeyHash(key.GetID());
1473  CScript witprog = GetScriptForDestination(witdest);
1474  // Make sure the resulting program is solvable.
1475  const auto desc = InferDescriptor(witprog, *this);
1476  assert(desc && desc->IsSolvable());
1477  AddCScript(witprog);
1478  }
1479 }
1480 
1482 {
1483  // OutputType::P2SH_SEGWIT always adds all necessary scripts for all types.
1485 }
1486 
1487 std::vector<CKeyPool> LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id)
1488 {
1490  bool internal = setInternalKeyPool.count(keypool_id);
1491  if (!internal) assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id));
1492  std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
1493  auto it = setKeyPool->begin();
1494 
1495  std::vector<CKeyPool> result;
1497  while (it != std::end(*setKeyPool)) {
1498  const int64_t& index = *(it);
1499  if (index > keypool_id) break; // set*KeyPool is ordered
1500 
1501  CKeyPool keypool;
1502  if (batch.ReadPool(index, keypool)) { //TODO: This should be unnecessary
1503  m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
1504  }
1506  batch.ErasePool(index);
1507  WalletLogPrintf("keypool index %d removed\n", index);
1508  it = setKeyPool->erase(it);
1509  result.push_back(std::move(keypool));
1510  }
1511 
1512  return result;
1513 }
1514 
1515 std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& provider)
1516 {
1517  std::vector<CScript> dummy;
1519  InferDescriptor(spk, provider)->Expand(0, DUMMY_SIGNING_PROVIDER, dummy, out);
1520  std::vector<CKeyID> ret;
1521  ret.reserve(out.pubkeys.size());
1522  for (const auto& entry : out.pubkeys) {
1523  ret.push_back(entry.first);
1524  }
1525  return ret;
1526 }
1527 
1529 {
1531  for (auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) {
1532  int64_t index = *it;
1533  CKeyPool keypool;
1534  if (!batch.ReadPool(index, keypool)) {
1535  throw std::runtime_error(std::string(__func__) + ": read keypool entry failed");
1536  }
1537  keypool.m_pre_split = true;
1538  if (!batch.WritePool(index, keypool)) {
1539  throw std::runtime_error(std::string(__func__) + ": writing modified keypool entry failed");
1540  }
1541  set_pre_split_keypool.insert(index);
1542  it = setExternalKeyPool.erase(it);
1543  }
1544 }
1545 
1547 {
1549  return AddCScriptWithDB(batch, redeemScript);
1550 }
1551 
1553 {
1554  if (!FillableSigningProvider::AddCScript(redeemScript))
1555  return false;
1556  if (batch.WriteCScript(Hash160(redeemScript), redeemScript)) {
1558  return true;
1559  }
1560  return false;
1561 }
1562 
1564 {
1565  LOCK(cs_KeyStore);
1566  std::copy(info.fingerprint, info.fingerprint + 4, mapKeyMetadata[pubkey.GetID()].key_origin.fingerprint);
1567  mapKeyMetadata[pubkey.GetID()].key_origin.path = info.path;
1568  mapKeyMetadata[pubkey.GetID()].has_key_origin = true;
1569  mapKeyMetadata[pubkey.GetID()].hdKeypath = WriteHDKeypath(info.path, /*apostrophe=*/true);
1570  return batch.WriteKeyMetadata(mapKeyMetadata[pubkey.GetID()], pubkey, true);
1571 }
1572 
1573 bool LegacyScriptPubKeyMan::ImportScripts(const std::set<CScript> scripts, int64_t timestamp)
1574 {
1576  for (const auto& entry : scripts) {
1577  CScriptID id(entry);
1578  if (HaveCScript(id)) {
1579  WalletLogPrintf("Already have script %s, skipping\n", HexStr(entry));
1580  continue;
1581  }
1582  if (!AddCScriptWithDB(batch, entry)) {
1583  return false;
1584  }
1585 
1586  if (timestamp > 0) {
1587  m_script_metadata[CScriptID(entry)].nCreateTime = timestamp;
1588  }
1589  }
1590  if (timestamp > 0) {
1591  UpdateTimeFirstKey(timestamp);
1592  }
1593 
1594  return true;
1595 }
1596 
1597 bool LegacyScriptPubKeyMan::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp)
1598 {
1600  for (const auto& entry : privkey_map) {
1601  const CKey& key = entry.second;
1602  CPubKey pubkey = key.GetPubKey();
1603  const CKeyID& id = entry.first;
1604  assert(key.VerifyPubKey(pubkey));
1605  // Skip if we already have the key
1606  if (HaveKey(id)) {
1607  WalletLogPrintf("Already have key with pubkey %s, skipping\n", HexStr(pubkey));
1608  continue;
1609  }
1610  mapKeyMetadata[id].nCreateTime = timestamp;
1611  // If the private key is not present in the wallet, insert it.
1612  if (!AddKeyPubKeyWithDB(batch, key, pubkey)) {
1613  return false;
1614  }
1615  UpdateTimeFirstKey(timestamp);
1616  }
1617  return true;
1618 }
1619 
1620 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)
1621 {
1623  for (const auto& entry : key_origins) {
1624  AddKeyOriginWithDB(batch, entry.second.first, entry.second.second);
1625  }
1626  for (const CKeyID& id : ordered_pubkeys) {
1627  auto entry = pubkey_map.find(id);
1628  if (entry == pubkey_map.end()) {
1629  continue;
1630  }
1631  const CPubKey& pubkey = entry->second;
1632  CPubKey temp;
1633  if (GetPubKey(id, temp)) {
1634  // Already have pubkey, skipping
1635  WalletLogPrintf("Already have pubkey %s, skipping\n", HexStr(temp));
1636  continue;
1637  }
1638  if (!AddWatchOnlyWithDB(batch, GetScriptForRawPubKey(pubkey), timestamp)) {
1639  return false;
1640  }
1641  mapKeyMetadata[id].nCreateTime = timestamp;
1642 
1643  // Add to keypool only works with pubkeys
1644  if (add_keypool) {
1645  AddKeypoolPubkeyWithDB(pubkey, internal, batch);
1647  }
1648  }
1649  return true;
1650 }
1651 
1652 bool LegacyScriptPubKeyMan::ImportScriptPubKeys(const std::set<CScript>& script_pub_keys, const bool have_solving_data, const int64_t timestamp)
1653 {
1655  for (const CScript& script : script_pub_keys) {
1656  if (!have_solving_data || !IsMine(script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1657  if (!AddWatchOnlyWithDB(batch, script, timestamp)) {
1658  return false;
1659  }
1660  }
1661  }
1662  return true;
1663 }
1664 
1665 std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const
1666 {
1667  LOCK(cs_KeyStore);
1668  if (!m_storage.HasEncryptionKeys()) {
1670  }
1671  std::set<CKeyID> set_address;
1672  for (const auto& mi : mapCryptedKeys) {
1673  set_address.insert(mi.first);
1674  }
1675  return set_address;
1676 }
1677 
1678 std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetScriptPubKeys() const
1679 {
1680  LOCK(cs_KeyStore);
1681  std::unordered_set<CScript, SaltedSipHasher> spks;
1682 
1683  // All keys have at least P2PK and P2PKH
1684  for (const auto& key_pair : mapKeys) {
1685  const CPubKey& pub = key_pair.second.GetPubKey();
1686  spks.insert(GetScriptForRawPubKey(pub));
1687  spks.insert(GetScriptForDestination(PKHash(pub)));
1688  }
1689  for (const auto& key_pair : mapCryptedKeys) {
1690  const CPubKey& pub = key_pair.second.first;
1691  spks.insert(GetScriptForRawPubKey(pub));
1692  spks.insert(GetScriptForDestination(PKHash(pub)));
1693  }
1694 
1695  // For every script in mapScript, only the ISMINE_SPENDABLE ones are being tracked.
1696  // The watchonly ones will be in setWatchOnly which we deal with later
1697  // For all keys, if they have segwit scripts, those scripts will end up in mapScripts
1698  for (const auto& script_pair : mapScripts) {
1699  const CScript& script = script_pair.second;
1700  if (IsMine(script) == ISMINE_SPENDABLE) {
1701  // Add ScriptHash for scripts that are not already P2SH
1702  if (!script.IsPayToScriptHash()) {
1703  spks.insert(GetScriptForDestination(ScriptHash(script)));
1704  }
1705  // For segwit scripts, we only consider them spendable if we have the segwit spk
1706  int wit_ver = -1;
1707  std::vector<unsigned char> witprog;
1708  if (script.IsWitnessProgram(wit_ver, witprog) && wit_ver == 0) {
1709  spks.insert(script);
1710  }
1711  } else {
1712  // Multisigs are special. They don't show up as ISMINE_SPENDABLE unless they are in a P2SH
1713  // So check the P2SH of a multisig to see if we should insert it
1714  std::vector<std::vector<unsigned char>> sols;
1715  TxoutType type = Solver(script, sols);
1716  if (type == TxoutType::MULTISIG) {
1717  CScript ms_spk = GetScriptForDestination(ScriptHash(script));
1718  if (IsMine(ms_spk) != ISMINE_NO) {
1719  spks.insert(ms_spk);
1720  }
1721  }
1722  }
1723  }
1724 
1725  // All watchonly scripts are raw
1726  for (const CScript& script : setWatchOnly) {
1727  // As the legacy wallet allowed to import any script, we need to verify the validity here.
1728  // LegacyScriptPubKeyMan::IsMine() return 'ISMINE_NO' for invalid or not watched scripts (IsMineResult::INVALID or IsMineResult::NO).
1729  // e.g. a "sh(sh(pkh()))" which legacy wallets allowed to import!.
1730  if (IsMine(script) != ISMINE_NO) spks.insert(script);
1731  }
1732 
1733  return spks;
1734 }
1735 
1736 std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetNotMineScriptPubKeys() const
1737 {
1738  LOCK(cs_KeyStore);
1739  std::unordered_set<CScript, SaltedSipHasher> spks;
1740  for (const CScript& script : setWatchOnly) {
1741  if (IsMine(script) == ISMINE_NO) spks.insert(script);
1742  }
1743  return spks;
1744 }
1745 
1746 std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor()
1747 {
1748  LOCK(cs_KeyStore);
1749  if (m_storage.IsLocked()) {
1750  return std::nullopt;
1751  }
1752 
1754 
1755  std::unordered_set<CScript, SaltedSipHasher> spks{GetScriptPubKeys()};
1756 
1757  // Get all key ids
1758  std::set<CKeyID> keyids;
1759  for (const auto& key_pair : mapKeys) {
1760  keyids.insert(key_pair.first);
1761  }
1762  for (const auto& key_pair : mapCryptedKeys) {
1763  keyids.insert(key_pair.first);
1764  }
1765 
1766  // Get key metadata and figure out which keys don't have a seed
1767  // Note that we do not ignore the seeds themselves because they are considered IsMine!
1768  for (auto keyid_it = keyids.begin(); keyid_it != keyids.end();) {
1769  const CKeyID& keyid = *keyid_it;
1770  const auto& it = mapKeyMetadata.find(keyid);
1771  if (it != mapKeyMetadata.end()) {
1772  const CKeyMetadata& meta = it->second;
1773  if (meta.hdKeypath == "s" || meta.hdKeypath == "m") {
1774  keyid_it++;
1775  continue;
1776  }
1777  if (m_hd_chain.seed_id == meta.hd_seed_id || m_inactive_hd_chains.count(meta.hd_seed_id) > 0) {
1778  keyid_it = keyids.erase(keyid_it);
1779  continue;
1780  }
1781  }
1782  keyid_it++;
1783  }
1784 
1785  // keyids is now all non-HD keys. Each key will have its own combo descriptor
1786  for (const CKeyID& keyid : keyids) {
1787  CKey key;
1788  if (!GetKey(keyid, key)) {
1789  assert(false);
1790  }
1791 
1792  // Get birthdate from key meta
1793  uint64_t creation_time = 0;
1794  const auto& it = mapKeyMetadata.find(keyid);
1795  if (it != mapKeyMetadata.end()) {
1796  creation_time = it->second.nCreateTime;
1797  }
1798 
1799  // Get the key origin
1800  // Maybe this doesn't matter because floating keys here shouldn't have origins
1801  KeyOriginInfo info;
1802  bool has_info = GetKeyOrigin(keyid, info);
1803  std::string origin_str = has_info ? "[" + HexStr(info.fingerprint) + FormatHDKeypath(info.path) + "]" : "";
1804 
1805  // Construct the combo descriptor
1806  std::string desc_str = "combo(" + origin_str + HexStr(key.GetPubKey()) + ")";
1807  FlatSigningProvider keys;
1808  std::string error;
1809  std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, error, false);
1810  WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
1811 
1812  // Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
1813  auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc, m_keypool_size));
1814  desc_spk_man->AddDescriptorKey(key, key.GetPubKey());
1815  desc_spk_man->TopUp();
1816  auto desc_spks = desc_spk_man->GetScriptPubKeys();
1817 
1818  // Remove the scriptPubKeys from our current set
1819  for (const CScript& spk : desc_spks) {
1820  size_t erased = spks.erase(spk);
1821  assert(erased == 1);
1822  assert(IsMine(spk) == ISMINE_SPENDABLE);
1823  }
1824 
1825  out.desc_spkms.push_back(std::move(desc_spk_man));
1826  }
1827 
1828  // Handle HD keys by using the CHDChains
1829  std::vector<CHDChain> chains;
1830  chains.push_back(m_hd_chain);
1831  for (const auto& chain_pair : m_inactive_hd_chains) {
1832  chains.push_back(chain_pair.second);
1833  }
1834  for (const CHDChain& chain : chains) {
1835  for (int i = 0; i < 2; ++i) {
1836  // Skip if doing internal chain and split chain is not supported
1837  if (chain.seed_id.IsNull() || (i == 1 && !m_storage.CanSupportFeature(FEATURE_HD_SPLIT))) {
1838  continue;
1839  }
1840  // Get the master xprv
1841  CKey seed_key;
1842  if (!GetKey(chain.seed_id, seed_key)) {
1843  assert(false);
1844  }
1845  CExtKey master_key;
1846  master_key.SetSeed(seed_key);
1847 
1848  // Make the combo descriptor
1849  std::string xpub = EncodeExtPubKey(master_key.Neuter());
1850  std::string desc_str = "combo(" + xpub + "/0h/" + ToString(i) + "h/*h)";
1851  FlatSigningProvider keys;
1852  std::string error;
1853  std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, error, false);
1854  uint32_t chain_counter = std::max((i == 1 ? chain.nInternalChainCounter : chain.nExternalChainCounter), (uint32_t)0);
1855  WalletDescriptor w_desc(std::move(desc), 0, 0, chain_counter, 0);
1856 
1857  // Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
1858  auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc, m_keypool_size));
1859  desc_spk_man->AddDescriptorKey(master_key.key, master_key.key.GetPubKey());
1860  desc_spk_man->TopUp();
1861  auto desc_spks = desc_spk_man->GetScriptPubKeys();
1862 
1863  // Remove the scriptPubKeys from our current set
1864  for (const CScript& spk : desc_spks) {
1865  size_t erased = spks.erase(spk);
1866  assert(erased == 1);
1867  assert(IsMine(spk) == ISMINE_SPENDABLE);
1868  }
1869 
1870  out.desc_spkms.push_back(std::move(desc_spk_man));
1871  }
1872  }
1873  // Add the current master seed to the migration data
1874  if (!m_hd_chain.seed_id.IsNull()) {
1875  CKey seed_key;
1876  if (!GetKey(m_hd_chain.seed_id, seed_key)) {
1877  assert(false);
1878  }
1879  out.master_key.SetSeed(seed_key);
1880  }
1881 
1882  // Handle the rest of the scriptPubKeys which must be imports and may not have all info
1883  for (auto it = spks.begin(); it != spks.end();) {
1884  const CScript& spk = *it;
1885 
1886  // Get birthdate from script meta
1887  uint64_t creation_time = 0;
1888  const auto& mit = m_script_metadata.find(CScriptID(spk));
1889  if (mit != m_script_metadata.end()) {
1890  creation_time = mit->second.nCreateTime;
1891  }
1892 
1893  // InferDescriptor as that will get us all the solving info if it is there
1894  std::unique_ptr<Descriptor> desc = InferDescriptor(spk, *GetSolvingProvider(spk));
1895  // Get the private keys for this descriptor
1896  std::vector<CScript> scripts;
1897  FlatSigningProvider keys;
1898  if (!desc->Expand(0, DUMMY_SIGNING_PROVIDER, scripts, keys)) {
1899  assert(false);
1900  }
1901  std::set<CKeyID> privkeyids;
1902  for (const auto& key_orig_pair : keys.origins) {
1903  privkeyids.insert(key_orig_pair.first);
1904  }
1905 
1906  std::vector<CScript> desc_spks;
1907 
1908  // Make the descriptor string with private keys
1909  std::string desc_str;
1910  bool watchonly = !desc->ToPrivateString(*this, desc_str);
1912  out.watch_descs.emplace_back(desc->ToString(), creation_time);
1913 
1914  // Get the scriptPubKeys without writing this to the wallet
1915  FlatSigningProvider provider;
1916  desc->Expand(0, provider, desc_spks, provider);
1917  } else {
1918  // Make the DescriptorScriptPubKeyMan and get the scriptPubKeys
1919  WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
1920  auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc, m_keypool_size));
1921  for (const auto& keyid : privkeyids) {
1922  CKey key;
1923  if (!GetKey(keyid, key)) {
1924  continue;
1925  }
1926  desc_spk_man->AddDescriptorKey(key, key.GetPubKey());
1927  }
1928  desc_spk_man->TopUp();
1929  auto desc_spks_set = desc_spk_man->GetScriptPubKeys();
1930  desc_spks.insert(desc_spks.end(), desc_spks_set.begin(), desc_spks_set.end());
1931 
1932  out.desc_spkms.push_back(std::move(desc_spk_man));
1933  }
1934 
1935  // Remove the scriptPubKeys from our current set
1936  for (const CScript& desc_spk : desc_spks) {
1937  auto del_it = spks.find(desc_spk);
1938  assert(del_it != spks.end());
1939  assert(IsMine(desc_spk) != ISMINE_NO);
1940  it = spks.erase(del_it);
1941  }
1942  }
1943 
1944  // Multisigs are special. They don't show up as ISMINE_SPENDABLE unless they are in a P2SH
1945  // So we have to check if any of our scripts are a multisig and if so, add the P2SH
1946  for (const auto& script_pair : mapScripts) {
1947  const CScript script = script_pair.second;
1948 
1949  // Get birthdate from script meta
1950  uint64_t creation_time = 0;
1951  const auto& it = m_script_metadata.find(CScriptID(script));
1952  if (it != m_script_metadata.end()) {
1953  creation_time = it->second.nCreateTime;
1954  }
1955 
1956  std::vector<std::vector<unsigned char>> sols;
1957  TxoutType type = Solver(script, sols);
1958  if (type == TxoutType::MULTISIG) {
1959  CScript sh_spk = GetScriptForDestination(ScriptHash(script));
1960  CTxDestination witdest = WitnessV0ScriptHash(script);
1961  CScript witprog = GetScriptForDestination(witdest);
1962  CScript sh_wsh_spk = GetScriptForDestination(ScriptHash(witprog));
1963 
1964  // We only want the multisigs that we have not already seen, i.e. they are not watchonly and not spendable
1965  // For P2SH, a multisig is not ISMINE_NO when:
1966  // * All keys are in the wallet
1967  // * The multisig itself is watch only
1968  // * The P2SH is watch only
1969  // For P2SH-P2WSH, if the script is in the wallet, then it will have the same conditions as P2SH.
1970  // For P2WSH, a multisig is not ISMINE_NO when, other than the P2SH conditions:
1971  // * The P2WSH script is in the wallet and it is being watched
1972  std::vector<std::vector<unsigned char>> keys(sols.begin() + 1, sols.begin() + sols.size() - 1);
1973  if (HaveWatchOnly(sh_spk) || HaveWatchOnly(script) || HaveKeys(keys, *this) || (HaveCScript(CScriptID(witprog)) && HaveWatchOnly(witprog))) {
1974  // The above emulates IsMine for these 3 scriptPubKeys, so double check that by running IsMine
1975  assert(IsMine(sh_spk) != ISMINE_NO || IsMine(witprog) != ISMINE_NO || IsMine(sh_wsh_spk) != ISMINE_NO);
1976  continue;
1977  }
1978  assert(IsMine(sh_spk) == ISMINE_NO && IsMine(witprog) == ISMINE_NO && IsMine(sh_wsh_spk) == ISMINE_NO);
1979 
1980  std::unique_ptr<Descriptor> sh_desc = InferDescriptor(sh_spk, *GetSolvingProvider(sh_spk));
1981  out.solvable_descs.emplace_back(sh_desc->ToString(), creation_time);
1982 
1983  const auto desc = InferDescriptor(witprog, *this);
1984  if (desc->IsSolvable()) {
1985  std::unique_ptr<Descriptor> wsh_desc = InferDescriptor(witprog, *GetSolvingProvider(witprog));
1986  out.solvable_descs.emplace_back(wsh_desc->ToString(), creation_time);
1987  std::unique_ptr<Descriptor> sh_wsh_desc = InferDescriptor(sh_wsh_spk, *GetSolvingProvider(sh_wsh_spk));
1988  out.solvable_descs.emplace_back(sh_wsh_desc->ToString(), creation_time);
1989  }
1990  }
1991  }
1992 
1993  // Make sure that we have accounted for all scriptPubKeys
1994  assert(spks.size() == 0);
1995  return out;
1996 }
1997 
1999 {
2000  LOCK(cs_KeyStore);
2002  return batch.EraseRecords(DBKeys::LEGACY_TYPES);
2003 }
2004 
2006 {
2007  // Returns true if this descriptor supports getting new addresses. Conditions where we may be unable to fetch them (e.g. locked) are caught later
2008  if (!CanGetAddresses()) {
2009  return util::Error{_("No addresses available")};
2010  }
2011  {
2012  LOCK(cs_desc_man);
2013  assert(m_wallet_descriptor.descriptor->IsSingleType()); // This is a combo descriptor which should not be an active descriptor
2014  std::optional<OutputType> desc_addr_type = m_wallet_descriptor.descriptor->GetOutputType();
2015  assert(desc_addr_type);
2016  if (type != *desc_addr_type) {
2017  throw std::runtime_error(std::string(__func__) + ": Types are inconsistent. Stored type does not match type of newly generated address");
2018  }
2019 
2020  TopUp();
2021 
2022  // Get the scriptPubKey from the descriptor
2023  FlatSigningProvider out_keys;
2024  std::vector<CScript> scripts_temp;
2025  if (m_wallet_descriptor.range_end <= m_max_cached_index && !TopUp(1)) {
2026  // We can't generate anymore keys
2027  return util::Error{_("Error: Keypool ran out, please call keypoolrefill first")};
2028  }
2029  if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2030  // We can't generate anymore keys
2031  return util::Error{_("Error: Keypool ran out, please call keypoolrefill first")};
2032  }
2033 
2034  CTxDestination dest;
2035  if (!ExtractDestination(scripts_temp[0], dest)) {
2036  return util::Error{_("Error: Cannot extract destination from the generated scriptpubkey")}; // shouldn't happen
2037  }
2038  m_wallet_descriptor.next_index++;
2039  WalletBatch(m_storage.GetDatabase()).WriteDescriptor(GetID(), m_wallet_descriptor);
2040  return dest;
2041  }
2042 }
2043 
2045 {
2046  LOCK(cs_desc_man);
2047  if (m_map_script_pub_keys.count(script) > 0) {
2048  return ISMINE_SPENDABLE;
2049  }
2050  return ISMINE_NO;
2051 }
2052 
2054 {
2055  LOCK(cs_desc_man);
2056  if (!m_map_keys.empty()) {
2057  return false;
2058  }
2059 
2060  bool keyPass = m_map_crypted_keys.empty(); // Always pass when there are no encrypted keys
2061  bool keyFail = false;
2062  for (const auto& mi : m_map_crypted_keys) {
2063  const CPubKey &pubkey = mi.second.first;
2064  const std::vector<unsigned char> &crypted_secret = mi.second.second;
2065  CKey key;
2066  if (!DecryptKey(master_key, crypted_secret, pubkey, key)) {
2067  keyFail = true;
2068  break;
2069  }
2070  keyPass = true;
2072  break;
2073  }
2074  if (keyPass && keyFail) {
2075  LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n");
2076  throw std::runtime_error("Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
2077  }
2078  if (keyFail || !keyPass) {
2079  return false;
2080  }
2082  return true;
2083 }
2084 
2086 {
2087  LOCK(cs_desc_man);
2088  if (!m_map_crypted_keys.empty()) {
2089  return false;
2090  }
2091 
2092  for (const KeyMap::value_type& key_in : m_map_keys)
2093  {
2094  const CKey &key = key_in.second;
2095  CPubKey pubkey = key.GetPubKey();
2096  CKeyingMaterial secret{UCharCast(key.begin()), UCharCast(key.end())};
2097  std::vector<unsigned char> crypted_secret;
2098  if (!EncryptSecret(master_key, secret, pubkey.GetHash(), crypted_secret)) {
2099  return false;
2100  }
2101  m_map_crypted_keys[pubkey.GetID()] = make_pair(pubkey, crypted_secret);
2102  batch->WriteCryptedDescriptorKey(GetID(), pubkey, crypted_secret);
2103  }
2104  m_map_keys.clear();
2105  return true;
2106 }
2107 
2109 {
2110  LOCK(cs_desc_man);
2111  auto op_dest = GetNewDestination(type);
2112  index = m_wallet_descriptor.next_index - 1;
2113  return op_dest;
2114 }
2115 
2116 void DescriptorScriptPubKeyMan::ReturnDestination(int64_t index, bool internal, const CTxDestination& addr)
2117 {
2118  LOCK(cs_desc_man);
2119  // Only return when the index was the most recent
2120  if (m_wallet_descriptor.next_index - 1 == index) {
2121  m_wallet_descriptor.next_index--;
2122  }
2123  WalletBatch(m_storage.GetDatabase()).WriteDescriptor(GetID(), m_wallet_descriptor);
2125 }
2126 
2127 std::map<CKeyID, CKey> DescriptorScriptPubKeyMan::GetKeys() const
2128 {
2131  KeyMap keys;
2132  for (const auto& key_pair : m_map_crypted_keys) {
2133  const CPubKey& pubkey = key_pair.second.first;
2134  const std::vector<unsigned char>& crypted_secret = key_pair.second.second;
2135  CKey key;
2136  m_storage.WithEncryptionKey([&](const CKeyingMaterial& encryption_key) {
2137  return DecryptKey(encryption_key, crypted_secret, pubkey, key);
2138  });
2139  keys[pubkey.GetID()] = key;
2140  }
2141  return keys;
2142  }
2143  return m_map_keys;
2144 }
2145 
2146 bool DescriptorScriptPubKeyMan::TopUp(unsigned int size)
2147 {
2149  if (!batch.TxnBegin()) return false;
2150  bool res = TopUpWithDB(batch, size);
2151  if (!batch.TxnCommit()) throw std::runtime_error(strprintf("Error during descriptors keypool top up. Cannot commit changes for wallet %s", m_storage.GetDisplayName()));
2152  return res;
2153 }
2154 
2156 {
2157  LOCK(cs_desc_man);
2158  std::set<CScript> new_spks;
2159  unsigned int target_size;
2160  if (size > 0) {
2161  target_size = size;
2162  } else {
2163  target_size = m_keypool_size;
2164  }
2165 
2166  // Calculate the new range_end
2167  int32_t new_range_end = std::max(m_wallet_descriptor.next_index + (int32_t)target_size, m_wallet_descriptor.range_end);
2168 
2169  // If the descriptor is not ranged, we actually just want to fill the first cache item
2170  if (!m_wallet_descriptor.descriptor->IsRange()) {
2171  new_range_end = 1;
2172  m_wallet_descriptor.range_end = 1;
2173  m_wallet_descriptor.range_start = 0;
2174  }
2175 
2176  FlatSigningProvider provider;
2177  provider.keys = GetKeys();
2178 
2179  uint256 id = GetID();
2180  for (int32_t i = m_max_cached_index + 1; i < new_range_end; ++i) {
2181  FlatSigningProvider out_keys;
2182  std::vector<CScript> scripts_temp;
2183  DescriptorCache temp_cache;
2184  // Maybe we have a cached xpub and we can expand from the cache first
2185  if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2186  if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache)) return false;
2187  }
2188  // Add all of the scriptPubKeys to the scriptPubKey set
2189  new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2190  for (const CScript& script : scripts_temp) {
2191  m_map_script_pub_keys[script] = i;
2192  }
2193  for (const auto& pk_pair : out_keys.pubkeys) {
2194  const CPubKey& pubkey = pk_pair.second;
2195  if (m_map_pubkeys.count(pubkey) != 0) {
2196  // We don't need to give an error here.
2197  // 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
2198  continue;
2199  }
2200  m_map_pubkeys[pubkey] = i;
2201  }
2202  // Merge and write the cache
2203  DescriptorCache new_items = m_wallet_descriptor.cache.MergeAndDiff(temp_cache);
2204  if (!batch.WriteDescriptorCacheItems(id, new_items)) {
2205  throw std::runtime_error(std::string(__func__) + ": writing cache items failed");
2206  }
2208  }
2209  m_wallet_descriptor.range_end = new_range_end;
2210  batch.WriteDescriptor(GetID(), m_wallet_descriptor);
2211 
2212  // By this point, the cache size should be the size of the entire range
2213  assert(m_wallet_descriptor.range_end - 1 == m_max_cached_index);
2214 
2215  m_storage.TopUpCallback(new_spks, this);
2217  return true;
2218 }
2219 
2220 std::vector<WalletDestination> DescriptorScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
2221 {
2222  LOCK(cs_desc_man);
2223  std::vector<WalletDestination> result;
2224  if (IsMine(script)) {
2225  int32_t index = m_map_script_pub_keys[script];
2226  if (index >= m_wallet_descriptor.next_index) {
2227  WalletLogPrintf("%s: Detected a used keypool item at index %d, mark all keypool items up to this item as used\n", __func__, index);
2228  auto out_keys = std::make_unique<FlatSigningProvider>();
2229  std::vector<CScript> scripts_temp;
2230  while (index >= m_wallet_descriptor.next_index) {
2231  if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) {
2232  throw std::runtime_error(std::string(__func__) + ": Unable to expand descriptor from cache");
2233  }
2234  CTxDestination dest;
2235  ExtractDestination(scripts_temp[0], dest);
2236  result.push_back({dest, std::nullopt});
2237  m_wallet_descriptor.next_index++;
2238  }
2239  }
2240  if (!TopUp()) {
2241  WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
2242  }
2243  }
2244 
2245  return result;
2246 }
2247 
2249 {
2250  LOCK(cs_desc_man);
2252  if (!AddDescriptorKeyWithDB(batch, key, pubkey)) {
2253  throw std::runtime_error(std::string(__func__) + ": writing descriptor private key failed");
2254  }
2255 }
2256 
2258 {
2261 
2262  // Check if provided key already exists
2263  if (m_map_keys.find(pubkey.GetID()) != m_map_keys.end() ||
2264  m_map_crypted_keys.find(pubkey.GetID()) != m_map_crypted_keys.end()) {
2265  return true;
2266  }
2267 
2268  if (m_storage.HasEncryptionKeys()) {
2269  if (m_storage.IsLocked()) {
2270  return false;
2271  }
2272 
2273  std::vector<unsigned char> crypted_secret;
2274  CKeyingMaterial secret{UCharCast(key.begin()), UCharCast(key.end())};
2275  if (!m_storage.WithEncryptionKey([&](const CKeyingMaterial& encryption_key) {
2276  return EncryptSecret(encryption_key, secret, pubkey.GetHash(), crypted_secret);
2277  })) {
2278  return false;
2279  }
2280 
2281  m_map_crypted_keys[pubkey.GetID()] = make_pair(pubkey, crypted_secret);
2282  return batch.WriteCryptedDescriptorKey(GetID(), pubkey, crypted_secret);
2283  } else {
2284  m_map_keys[pubkey.GetID()] = key;
2285  return batch.WriteDescriptorKey(GetID(), pubkey, key.GetPrivKey());
2286  }
2287 }
2288 
2289 bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(WalletBatch& batch, const CExtKey& master_key, OutputType addr_type, bool internal)
2290 {
2291  LOCK(cs_desc_man);
2293 
2294  // Ignore when there is already a descriptor
2295  if (m_wallet_descriptor.descriptor) {
2296  return false;
2297  }
2298 
2299  int64_t creation_time = GetTime();
2300 
2301  std::string xpub = EncodeExtPubKey(master_key.Neuter());
2302 
2303  // Build descriptor string
2304  std::string desc_prefix;
2305  std::string desc_suffix = "/*)";
2306  switch (addr_type) {
2307  case OutputType::LEGACY: {
2308  desc_prefix = "pkh(" + xpub + "/44h";
2309  break;
2310  }
2311  case OutputType::P2SH_SEGWIT: {
2312  desc_prefix = "sh(wpkh(" + xpub + "/49h";
2313  desc_suffix += ")";
2314  break;
2315  }
2316  case OutputType::BECH32: {
2317  desc_prefix = "wpkh(" + xpub + "/84h";
2318  break;
2319  }
2320  case OutputType::BECH32M: {
2321  desc_prefix = "tr(" + xpub + "/86h";
2322  break;
2323  }
2324  case OutputType::UNKNOWN: {
2325  // We should never have a DescriptorScriptPubKeyMan for an UNKNOWN OutputType,
2326  // so if we get to this point something is wrong
2327  assert(false);
2328  }
2329  } // no default case, so the compiler can warn about missing cases
2330  assert(!desc_prefix.empty());
2331 
2332  // Mainnet derives at 0', testnet and regtest derive at 1'
2333  if (Params().IsTestChain()) {
2334  desc_prefix += "/1h";
2335  } else {
2336  desc_prefix += "/0h";
2337  }
2338 
2339  std::string internal_path = internal ? "/1" : "/0";
2340  std::string desc_str = desc_prefix + "/0h" + internal_path + desc_suffix;
2341 
2342  // Make the descriptor
2343  FlatSigningProvider keys;
2344  std::string error;
2345  std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, error, false);
2346  WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
2347  m_wallet_descriptor = w_desc;
2348 
2349  // Store the master private key, and descriptor
2350  if (!AddDescriptorKeyWithDB(batch, master_key.key, master_key.key.GetPubKey())) {
2351  throw std::runtime_error(std::string(__func__) + ": writing descriptor master private key failed");
2352  }
2353  if (!batch.WriteDescriptor(GetID(), m_wallet_descriptor)) {
2354  throw std::runtime_error(std::string(__func__) + ": writing descriptor failed");
2355  }
2356 
2357  // TopUp
2358  TopUpWithDB(batch);
2359 
2361  return true;
2362 }
2363 
2365 {
2366  LOCK(cs_desc_man);
2367  return m_wallet_descriptor.descriptor->IsRange();
2368 }
2369 
2371 {
2372  // We can only give out addresses from descriptors that are single type (not combo), ranged,
2373  // and either have cached keys or can generate more keys (ignoring encryption)
2374  LOCK(cs_desc_man);
2375  return m_wallet_descriptor.descriptor->IsSingleType() &&
2376  m_wallet_descriptor.descriptor->IsRange() &&
2377  (HavePrivateKeys() || m_wallet_descriptor.next_index < m_wallet_descriptor.range_end);
2378 }
2379 
2381 {
2382  LOCK(cs_desc_man);
2383  return m_map_keys.size() > 0 || m_map_crypted_keys.size() > 0;
2384 }
2385 
2387 {
2388  // This is only used for getwalletinfo output and isn't relevant to descriptor wallets.
2389  return std::nullopt;
2390 }
2391 
2392 
2394 {
2395  LOCK(cs_desc_man);
2396  return m_wallet_descriptor.range_end - m_wallet_descriptor.next_index;
2397 }
2398 
2400 {
2401  LOCK(cs_desc_man);
2402  return m_wallet_descriptor.creation_time;
2403 }
2404 
2405 std::unique_ptr<FlatSigningProvider> DescriptorScriptPubKeyMan::GetSigningProvider(const CScript& script, bool include_private) const
2406 {
2407  LOCK(cs_desc_man);
2408 
2409  // Find the index of the script
2410  auto it = m_map_script_pub_keys.find(script);
2411  if (it == m_map_script_pub_keys.end()) {
2412  return nullptr;
2413  }
2414  int32_t index = it->second;
2415 
2416  return GetSigningProvider(index, include_private);
2417 }
2418 
2419 std::unique_ptr<FlatSigningProvider> DescriptorScriptPubKeyMan::GetSigningProvider(const CPubKey& pubkey) const
2420 {
2421  LOCK(cs_desc_man);
2422 
2423  // Find index of the pubkey
2424  auto it = m_map_pubkeys.find(pubkey);
2425  if (it == m_map_pubkeys.end()) {
2426  return nullptr;
2427  }
2428  int32_t index = it->second;
2429 
2430  // Always try to get the signing provider with private keys. This function should only be called during signing anyways
2431  return GetSigningProvider(index, true);
2432 }
2433 
2434 std::unique_ptr<FlatSigningProvider> DescriptorScriptPubKeyMan::GetSigningProvider(int32_t index, bool include_private) const
2435 {
2437 
2438  std::unique_ptr<FlatSigningProvider> out_keys = std::make_unique<FlatSigningProvider>();
2439 
2440  // Fetch SigningProvider from cache to avoid re-deriving
2441  auto it = m_map_signing_providers.find(index);
2442  if (it != m_map_signing_providers.end()) {
2443  out_keys->Merge(FlatSigningProvider{it->second});
2444  } else {
2445  // Get the scripts, keys, and key origins for this script
2446  std::vector<CScript> scripts_temp;
2447  if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) return nullptr;
2448 
2449  // Cache SigningProvider so we don't need to re-derive if we need this SigningProvider again
2450  m_map_signing_providers[index] = *out_keys;
2451  }
2452 
2453  if (HavePrivateKeys() && include_private) {
2454  FlatSigningProvider master_provider;
2455  master_provider.keys = GetKeys();
2456  m_wallet_descriptor.descriptor->ExpandPrivate(index, master_provider, *out_keys);
2457  }
2458 
2459  return out_keys;
2460 }
2461 
2462 std::unique_ptr<SigningProvider> DescriptorScriptPubKeyMan::GetSolvingProvider(const CScript& script) const
2463 {
2464  return GetSigningProvider(script, false);
2465 }
2466 
2468 {
2469  return IsMine(script);
2470 }
2471 
2472 bool DescriptorScriptPubKeyMan::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const
2473 {
2474  std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2475  for (const auto& coin_pair : coins) {
2476  std::unique_ptr<FlatSigningProvider> coin_keys = GetSigningProvider(coin_pair.second.out.scriptPubKey, true);
2477  if (!coin_keys) {
2478  continue;
2479  }
2480  keys->Merge(std::move(*coin_keys));
2481  }
2482 
2483  return ::SignTransaction(tx, keys.get(), coins, sighash, input_errors);
2484 }
2485 
2486 SigningResult DescriptorScriptPubKeyMan::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const
2487 {
2488  std::unique_ptr<FlatSigningProvider> keys = GetSigningProvider(GetScriptForDestination(pkhash), true);
2489  if (!keys) {
2491  }
2492 
2493  CKey key;
2494  if (!keys->GetKey(ToKeyID(pkhash), key)) {
2496  }
2497 
2498  if (!MessageSign(key, message, str_sig)) {
2500  }
2501  return SigningResult::OK;
2502 }
2503 
2504 TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, const PrecomputedTransactionData& txdata, int sighash_type, bool sign, bool bip32derivs, int* n_signed, bool finalize) const
2505 {
2506  if (n_signed) {
2507  *n_signed = 0;
2508  }
2509  for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
2510  const CTxIn& txin = psbtx.tx->vin[i];
2511  PSBTInput& input = psbtx.inputs.at(i);
2512 
2513  if (PSBTInputSigned(input)) {
2514  continue;
2515  }
2516 
2517  // Get the Sighash type
2518  if (sign && input.sighash_type != std::nullopt && *input.sighash_type != sighash_type) {
2520  }
2521 
2522  // Get the scriptPubKey to know which SigningProvider to use
2523  CScript script;
2524  if (!input.witness_utxo.IsNull()) {
2525  script = input.witness_utxo.scriptPubKey;
2526  } else if (input.non_witness_utxo) {
2527  if (txin.prevout.n >= input.non_witness_utxo->vout.size()) {
2529  }
2530  script = input.non_witness_utxo->vout[txin.prevout.n].scriptPubKey;
2531  } else {
2532  // There's no UTXO so we can just skip this now
2533  continue;
2534  }
2535 
2536  std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2537  std::unique_ptr<FlatSigningProvider> script_keys = GetSigningProvider(script, /*include_private=*/sign);
2538  if (script_keys) {
2539  keys->Merge(std::move(*script_keys));
2540  } else {
2541  // Maybe there are pubkeys listed that we can sign for
2542  std::vector<CPubKey> pubkeys;
2543  pubkeys.reserve(input.hd_keypaths.size() + 2);
2544 
2545  // ECDSA Pubkeys
2546  for (const auto& [pk, _] : input.hd_keypaths) {
2547  pubkeys.push_back(pk);
2548  }
2549 
2550  // Taproot output pubkey
2551  std::vector<std::vector<unsigned char>> sols;
2552  if (Solver(script, sols) == TxoutType::WITNESS_V1_TAPROOT) {
2553  sols[0].insert(sols[0].begin(), 0x02);
2554  pubkeys.emplace_back(sols[0]);
2555  sols[0][0] = 0x03;
2556  pubkeys.emplace_back(sols[0]);
2557  }
2558 
2559  // Taproot pubkeys
2560  for (const auto& pk_pair : input.m_tap_bip32_paths) {
2561  const XOnlyPubKey& pubkey = pk_pair.first;
2562  for (unsigned char prefix : {0x02, 0x03}) {
2563  unsigned char b[33] = {prefix};
2564  std::copy(pubkey.begin(), pubkey.end(), b + 1);
2565  CPubKey fullpubkey;
2566  fullpubkey.Set(b, b + 33);
2567  pubkeys.push_back(fullpubkey);
2568  }
2569  }
2570 
2571  for (const auto& pubkey : pubkeys) {
2572  std::unique_ptr<FlatSigningProvider> pk_keys = GetSigningProvider(pubkey);
2573  if (pk_keys) {
2574  keys->Merge(std::move(*pk_keys));
2575  }
2576  }
2577  }
2578 
2579  SignPSBTInput(HidingSigningProvider(keys.get(), /*hide_secret=*/!sign, /*hide_origin=*/!bip32derivs), psbtx, i, &txdata, sighash_type, nullptr, finalize);
2580 
2581  bool signed_one = PSBTInputSigned(input);
2582  if (n_signed && (signed_one || !sign)) {
2583  // If sign is false, we assume that we _could_ sign if we get here. This
2584  // will never have false negatives; it is hard to tell under what i
2585  // circumstances it could have false positives.
2586  (*n_signed)++;
2587  }
2588  }
2589 
2590  // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
2591  for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
2592  std::unique_ptr<SigningProvider> keys = GetSolvingProvider(psbtx.tx->vout.at(i).scriptPubKey);
2593  if (!keys) {
2594  continue;
2595  }
2596  UpdatePSBTOutput(HidingSigningProvider(keys.get(), /*hide_secret=*/true, /*hide_origin=*/!bip32derivs), psbtx, i);
2597  }
2598 
2599  return TransactionError::OK;
2600 }
2601 
2602 std::unique_ptr<CKeyMetadata> DescriptorScriptPubKeyMan::GetMetadata(const CTxDestination& dest) const
2603 {
2604  std::unique_ptr<SigningProvider> provider = GetSigningProvider(GetScriptForDestination(dest));
2605  if (provider) {
2606  KeyOriginInfo orig;
2607  CKeyID key_id = GetKeyForDestination(*provider, dest);
2608  if (provider->GetKeyOrigin(key_id, orig)) {
2609  LOCK(cs_desc_man);
2610  std::unique_ptr<CKeyMetadata> meta = std::make_unique<CKeyMetadata>();
2611  meta->key_origin = orig;
2612  meta->has_key_origin = true;
2613  meta->nCreateTime = m_wallet_descriptor.creation_time;
2614  return meta;
2615  }
2616  }
2617  return nullptr;
2618 }
2619 
2621 {
2622  LOCK(cs_desc_man);
2623  return m_wallet_descriptor.id;
2624 }
2625 
2627 {
2628  LOCK(cs_desc_man);
2629  std::set<CScript> new_spks;
2630  m_wallet_descriptor.cache = cache;
2631  for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
2632  FlatSigningProvider out_keys;
2633  std::vector<CScript> scripts_temp;
2634  if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2635  throw std::runtime_error("Error: Unable to expand wallet descriptor from cache");
2636  }
2637  // Add all of the scriptPubKeys to the scriptPubKey set
2638  new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2639  for (const CScript& script : scripts_temp) {
2640  if (m_map_script_pub_keys.count(script) != 0) {
2641  throw std::runtime_error(strprintf("Error: Already loaded script at index %d as being at index %d", i, m_map_script_pub_keys[script]));
2642  }
2643  m_map_script_pub_keys[script] = i;
2644  }
2645  for (const auto& pk_pair : out_keys.pubkeys) {
2646  const CPubKey& pubkey = pk_pair.second;
2647  if (m_map_pubkeys.count(pubkey) != 0) {
2648  // We don't need to give an error here.
2649  // 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
2650  continue;
2651  }
2652  m_map_pubkeys[pubkey] = i;
2653  }
2655  }
2656  // Make sure the wallet knows about our new spks
2657  m_storage.TopUpCallback(new_spks, this);
2658 }
2659 
2660 bool DescriptorScriptPubKeyMan::AddKey(const CKeyID& key_id, const CKey& key)
2661 {
2662  LOCK(cs_desc_man);
2663  m_map_keys[key_id] = key;
2664  return true;
2665 }
2666 
2667 bool DescriptorScriptPubKeyMan::AddCryptedKey(const CKeyID& key_id, const CPubKey& pubkey, const std::vector<unsigned char>& crypted_key)
2668 {
2669  LOCK(cs_desc_man);
2670  if (!m_map_keys.empty()) {
2671  return false;
2672  }
2673 
2674  m_map_crypted_keys[key_id] = make_pair(pubkey, crypted_key);
2675  return true;
2676 }
2677 
2679 {
2680  LOCK(cs_desc_man);
2681  return !m_wallet_descriptor.id.IsNull() && !desc.id.IsNull() && m_wallet_descriptor.id == desc.id;
2682 }
2683 
2685 {
2686  LOCK(cs_desc_man);
2688  if (!batch.WriteDescriptor(GetID(), m_wallet_descriptor)) {
2689  throw std::runtime_error(std::string(__func__) + ": writing descriptor failed");
2690  }
2691 }
2692 
2694 {
2695  return m_wallet_descriptor;
2696 }
2697 
2698 std::unordered_set<CScript, SaltedSipHasher> DescriptorScriptPubKeyMan::GetScriptPubKeys() const
2699 {
2700  return GetScriptPubKeys(0);
2701 }
2702 
2703 std::unordered_set<CScript, SaltedSipHasher> DescriptorScriptPubKeyMan::GetScriptPubKeys(int32_t minimum_index) const
2704 {
2705  LOCK(cs_desc_man);
2706  std::unordered_set<CScript, SaltedSipHasher> script_pub_keys;
2707  script_pub_keys.reserve(m_map_script_pub_keys.size());
2708 
2709  for (auto const& [script_pub_key, index] : m_map_script_pub_keys) {
2710  if (index >= minimum_index) script_pub_keys.insert(script_pub_key);
2711  }
2712  return script_pub_keys;
2713 }
2714 
2716 {
2717  return m_max_cached_index + 1;
2718 }
2719 
2720 bool DescriptorScriptPubKeyMan::GetDescriptorString(std::string& out, const bool priv) const
2721 {
2722  LOCK(cs_desc_man);
2723 
2724  FlatSigningProvider provider;
2725  provider.keys = GetKeys();
2726 
2727  if (priv) {
2728  // For the private version, always return the master key to avoid
2729  // exposing child private keys. The risk implications of exposing child
2730  // private keys together with the parent xpub may be non-obvious for users.
2731  return m_wallet_descriptor.descriptor->ToPrivateString(provider, out);
2732  }
2733 
2734  return m_wallet_descriptor.descriptor->ToNormalizedString(provider, out, &m_wallet_descriptor.cache);
2735 }
2736 
2738 {
2739  LOCK(cs_desc_man);
2741  return;
2742  }
2743 
2744  // Skip if we have the last hardened xpub cache
2745  if (m_wallet_descriptor.cache.GetCachedLastHardenedExtPubKeys().size() > 0) {
2746  return;
2747  }
2748 
2749  // Expand the descriptor
2750  FlatSigningProvider provider;
2751  provider.keys = GetKeys();
2752  FlatSigningProvider out_keys;
2753  std::vector<CScript> scripts_temp;
2754  DescriptorCache temp_cache;
2755  if (!m_wallet_descriptor.descriptor->Expand(0, provider, scripts_temp, out_keys, &temp_cache)){
2756  throw std::runtime_error("Unable to expand descriptor");
2757  }
2758 
2759  // Cache the last hardened xpubs
2760  DescriptorCache diff = m_wallet_descriptor.cache.MergeAndDiff(temp_cache);
2762  throw std::runtime_error(std::string(__func__) + ": writing cache items failed");
2763  }
2764 }
2765 
2767 {
2768  LOCK(cs_desc_man);
2769  std::string error;
2770  if (!CanUpdateToWalletDescriptor(descriptor, error)) {
2771  throw std::runtime_error(std::string(__func__) + ": " + error);
2772  }
2773 
2774  m_map_pubkeys.clear();
2775  m_map_script_pub_keys.clear();
2776  m_max_cached_index = -1;
2777  m_wallet_descriptor = descriptor;
2778 
2779  NotifyFirstKeyTimeChanged(this, m_wallet_descriptor.creation_time);
2780 }
2781 
2783 {
2784  LOCK(cs_desc_man);
2785  if (!HasWalletDescriptor(descriptor)) {
2786  error = "can only update matching descriptor";
2787  return false;
2788  }
2789 
2790  if (descriptor.range_start > m_wallet_descriptor.range_start ||
2791  descriptor.range_end < m_wallet_descriptor.range_end) {
2792  // Use inclusive range for error
2793  error = strprintf("new range must include current range = [%d,%d]",
2794  m_wallet_descriptor.range_start,
2795  m_wallet_descriptor.range_end - 1);
2796  return false;
2797  }
2798 
2799  return true;
2800 }
2801 } // namespace wallet
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
Definition: addresstype.cpp:49
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
CKeyID ToKeyID(const PKHash &key_hash)
Definition: addresstype.cpp:29
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:131
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0'/2000".
Definition: bip32.cpp:13
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
Definition: bip32.cpp:54
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath, bool apostrophe)
Write HD keypaths as strings.
Definition: bip32.cpp:64
int ret
const CChainParams & Params()
Return the currently selected parameters.
An encapsulated private key.
Definition: key.h:33
const std::byte * end() const
Definition: key.h:116
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
Definition: key.cpp:175
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:161
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:188
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
Definition: key.cpp:242
const std::byte * begin() const
Definition: key.h:115
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:24
uint32_t n
Definition: transaction.h:32
An encapsulated public key.
Definition: pubkey.h:34
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:204
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:164
bool IsValid() const
Definition: pubkey.h:189
uint256 GetHash() const
Get the 256-bit hash of this public key.
Definition: pubkey.h:170
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:89
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:414
bool IsPayToScriptHash() const
Definition: script.cpp:207
bool IsWitnessProgram(int &version, std::vector< unsigned char > &program) const
Definition: script.cpp:226
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:583
An input of a transaction.
Definition: transaction.h:67
COutPoint prevout
Definition: transaction.h:69
CScript scriptPubKey
Definition: transaction.h:153
bool IsNull() const
Definition: transaction.h:170
Cache for single descriptor's derived extended pubkeys.
Definition: descriptor.h:19
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const override
virtual bool AddCScript(const CScript &redeemScript)
void ImplicitlyLearnRelatedKeyScripts(const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
virtual std::set< CKeyID > GetKeys() const
std::map< CKeyID, CKey > KeyMap
virtual bool HaveCScript(const CScriptID &hash) const override
RecursiveMutex cs_KeyStore
virtual bool HaveKey(const CKeyID &address) const override
An interface to be implemented by keystores that support signing.
const unsigned char * begin() const
Definition: pubkey.h:290
const unsigned char * end() const
Definition: pubkey.h:291
constexpr bool IsNull() const
Definition: uint256.h:42
constexpr unsigned char * begin()
Definition: uint256.h:68
size_type size() const
Definition: prevector.h:296
iterator insert(iterator pos, const T &value)
Definition: prevector.h:361
160-bit opaque blob.
Definition: uint256.h:95
256-bit opaque blob.
Definition: uint256.h:106
static const uint256 ONE
Definition: uint256.h:112
uint32_t nInternalChainCounter
Definition: walletdb.h:101
static const int VERSION_HD_BASE
Definition: walletdb.h:106
uint32_t nExternalChainCounter
Definition: walletdb.h:100
int64_t m_next_external_index
Definition: walletdb.h:103
static const int VERSION_HD_CHAIN_SPLIT
Definition: walletdb.h:107
CKeyID seed_id
seed hash160
Definition: walletdb.h:102
int64_t m_next_internal_index
Definition: walletdb.h:104
static const int VERSION_WITH_KEY_ORIGIN
Definition: walletdb.h:140
std::string hdKeypath
Definition: walletdb.h:144
bool has_key_origin
Whether the key_origin is useful.
Definition: walletdb.h:147
KeyOriginInfo key_origin
Definition: walletdb.h:146
A key from a CWallet's keypool.
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
CPubKey vchPubKey
The public key.
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
bool m_pre_split
Whether this key was generated for a keypool before the wallet was upgraded to HD-split.
KeyMap GetKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
void SetCache(const DescriptorCache &cache)
std::map< int32_t, FlatSigningProvider > m_map_signing_providers
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that,...
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool AddCryptedKey(const CKeyID &key_id, const CPubKey &pubkey, const std::vector< unsigned char > &crypted_key)
bool SetupDescriptorGeneration(WalletBatch &batch, const CExtKey &master_key, OutputType addr_type, bool internal)
Setup descriptors based on the given CExtkey.
bool TopUp(unsigned int size=0) override
Fills internal address pool.
bool m_decryption_thoroughly_checked
keeps track of whether Unlock has run a thorough check before
std::map< CKeyID, CKey > KeyMap
unsigned int GetKeyPoolSize() const override
int64_t GetTimeFirstKey() const override
std::unique_ptr< FlatSigningProvider > GetSigningProvider(const CScript &script, bool include_private=false) const
bool CheckDecryptionKey(const CKeyingMaterial &master_key) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
bool CanGetAddresses(bool internal=false) const override
bool CanUpdateToWalletDescriptor(const WalletDescriptor &descriptor, std::string &error)
bool GetDescriptorString(std::string &out, const bool priv) const
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
void AddDescriptorKey(const CKey &key, const CPubKey &pubkey)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
bool AddKey(const CKeyID &key_id, const CKey &key)
bool TopUpWithDB(WalletBatch &batch, unsigned int size=0)
Same as 'TopUp' but designed for use within a batch transaction context.
void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr) override
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
bool AddDescriptorKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool HasWalletDescriptor(const WalletDescriptor &desc) const
void UpdateWalletDescriptor(WalletDescriptor &descriptor)
std::optional< int64_t > GetOldestKeyPoolTime() const override
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
TransactionError FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const override
Adds script and derivation path information to a PSBT, and optionally signs it.
isminetype IsMine(const CScript &script) const override
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
std::vector< CKeyPool > MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Marks all keys in the keypool up to and including the provided key as used.
bool DeleteRecords()
Delete all the records ofthis LegacyScriptPubKeyMan from disk.
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
bool CanGetAddresses(bool internal=false) const override
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
bool GetKeyFromPool(CPubKey &key, const OutputType type)
Fetches a key from the keypool.
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
void AddInactiveHDChain(const CHDChain &chain)
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
void AddHDChain(const CHDChain &chain)
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, bool checksum_valid)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
bool AddCScriptWithDB(WalletBatch &batch, const CScript &script)
Adds a script to the store and saves it to disk.
std::unordered_map< CKeyID, CHDChain, SaltedSipHasher > m_inactive_hd_chains
bool GetKey(const CKeyID &address, CKey &keyOut) const override
bool AddKeyOriginWithDB(WalletBatch &batch, const CPubKey &pubkey, const KeyOriginInfo &info)
Add a KeyOriginInfo to the wallet.
void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
uint256 GetID() const override
bool AddWatchOnlyInMem(const CScript &dest)
bool HaveWatchOnly() const
Returns whether there are any watch-only things in the wallet.
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
bool CheckDecryptionKey(const CKeyingMaterial &master_key) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, and saves it to disk.
bool ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal)
Reserves a key from the keypool and sets nIndex to its index.
void AddKeypoolPubkeyWithDB(const CPubKey &pubkey, const bool internal, WalletBatch &batch)
std::map< int64_t, CKeyID > m_index_to_reserved_key
bool fDecryptionThoroughlyChecked
keeps track of whether Unlock has run a thorough check before
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
void UpgradeKeyMetadata()
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
bool AddWatchOnly(const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Private version of AddWatchOnly method which does not accept a timestamp, and which will reset the wa...
bool HavePrivateKeys() const override
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
std::unordered_set< CScript, SaltedSipHasher > GetNotMineScriptPubKeys() const
Retrieves scripts that were imported by bugs into the legacy spkm and are simply invalid,...
TransactionError FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const override
Adds script and derivation path information to a PSBT, and optionally signs it.
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
bool HaveWatchOnly(const CScript &dest) const
Returns whether the watch-only script is in the wallet.
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Update wallet first key creation time.
bool TopUp(unsigned int size=0) override
Fills internal address pool.
unsigned int GetKeyPoolSize() const override
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal)
Like TopUp() but adds keys for inactive HD chains.
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that,...
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
std::set< CKeyID > GetKeys() const override
bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey)
bool 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) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
bool IsHDEnabled() const override
bool TopUpChain(WalletBatch &batch, CHDChain &chain, unsigned int size)
bool AddKeyPubKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Adds a key to the store, and saves it to disk.
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
isminetype IsMine(const CScript &script) const override
bool AddCScript(const CScript &redeemScript) override
int64_t GetTimeFirstKey() const override
bool NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
bool SetupGeneration(bool force=false) override
Sets up the key generation stuff, i.e.
void LearnRelatedScripts(const CPubKey &key, OutputType)
Explicitly make the wallet learn the related scripts for outputs to the given key.
void LearnAllRelatedScripts(const CPubKey &key)
Same as LearnRelatedScripts, but when the OutputType is not known (and could be anything).
CPubKey DeriveNewSeed(const CKey &key)
std::optional< MigrationData > MigrateToDescriptor()
Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this Legac...
void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, CKey &secret, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
void ReturnDestination(int64_t index, bool internal, const CTxDestination &) override
std::map< CKeyID, int64_t > m_pool_key_to_index
CPubKey GenerateNewKey(WalletBatch &batch, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Generate a new key.
void SetHDSeed(const CPubKey &key)
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
bool Upgrade(int prev_version, int new_version, bilingual_str &error) override
Upgrades the wallet to the specified version.
void KeepDestination(int64_t index, const OutputType &type) override
void RewriteDB() override
The action to do when the DB needs rewrite.
std::optional< int64_t > GetOldestKeyPoolTime() const override
bool RemoveWatchOnly(const CScript &dest)
Remove a watch only script from the keystore.
bool HaveKey(const CKeyID &address) const override
bool ImportScriptPubKeys(const std::set< CScript > &script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
boost::signals2::signal< void(const ScriptPubKeyMan *spkm, int64_t new_birth_time)> NotifyFirstKeyTimeChanged
Birth time changed.
void WalletLogPrintf(const char *fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
WalletStorage & m_storage
Access to the wallet database.
Definition: walletdb.h:191
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
Definition: walletdb.cpp:248
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
Definition: walletdb.cpp:274
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
Definition: walletdb.cpp:1316
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
Definition: walletdb.cpp:163
bool TxnBegin()
Begin a new transaction.
Definition: walletdb.cpp:1335
bool TxnCommit()
Commit current transaction.
Definition: walletdb.cpp:1340
bool EraseRecords(const std::unordered_set< std::string > &types)
Delete records of the given types.
Definition: walletdb.cpp:1326
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, const bool overwrite)
Definition: walletdb.cpp:107
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:112
bool ReadPool(int64_t nPool, CKeyPool &keypool)
Definition: walletdb.cpp:196
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:127
bool WriteCryptedDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const std::vector< unsigned char > &secret)
Definition: walletdb.cpp:239
bool WritePool(int64_t nPool, const CKeyPool &keypool)
Definition: walletdb.cpp:201
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
Definition: walletdb.cpp:228
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
Definition: walletdb.cpp:158
bool ErasePool(int64_t nPool)
Definition: walletdb.cpp:206
bool EraseWatchOnly(const CScript &script)
Definition: walletdb.cpp:171
Descriptor with some wallet metadata.
Definition: walletutil.h:85
virtual bool IsWalletFlagSet(uint64_t) const =0
virtual void TopUpCallback(const std::set< CScript > &, ScriptPubKeyMan *)=0
Callback function for after TopUp completes containing any scripts that were added by a SPKMan.
virtual void SetMinVersion(enum WalletFeature, WalletBatch *=nullptr)=0
virtual bool CanSupportFeature(enum WalletFeature) const =0
virtual std::string GetDisplayName() const =0
virtual WalletDatabase & GetDatabase() const =0
virtual void UnsetBlankWalletFlag(WalletBatch &)=0
virtual bool IsLocked() const =0
virtual bool HasEncryptionKeys() const =0
virtual bool WithEncryptionKey(std::function< bool(const CKeyingMaterial &)> cb) const =0
Pass the encryption key to cb().
static UniValue Parse(std::string_view raw)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
Definition: client.cpp:313
TransactionError
Definition: error.h:22
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
Definition: hash.h:222
@ WITNESS_V0
Witness v0 (P2WPKH and P2WSH); see BIP 141.
CKey GenerateRandomKey(bool compressed) noexcept
Definition: key.cpp:372
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:287
std::string EncodeExtPubKey(const CExtPubKey &key)
Definition: key_io.cpp:253
#define LogPrintf(...)
Definition: logging.h:245
SigningResult
Definition: message.h:43
@ PRIVATE_KEY_NOT_AVAILABLE
@ OK
No error.
const std::unordered_set< std::string > LEGACY_TYPES
Definition: walletdb.cpp:68
static int64_t GetOldestKeyTimeInPool(const std::set< int64_t > &setKeyPool, WalletBatch &batch)
std::vector< unsigned char > valtype
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
Definition: crypter.h:62
bool DecryptKey(const CKeyingMaterial &vMasterKey, const std::vector< unsigned char > &vchCryptedSecret, const CPubKey &vchPubKey, CKey &key)
Definition: crypter.cpp:128
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
static const std::unordered_set< OutputType > LEGACY_OUTPUT_TYPES
OutputTypes supported by the LegacyScriptPubKeyMan.
const uint32_t BIP32_HARDENED_KEY_LIMIT
Value for the first BIP 32 hardened derivation. Can be used as a bit mask and as a value....
static constexpr int64_t UNKNOWN_TIME
Constant representing an unknown spkm creation time.
static void DeriveExtKey(CExtKey &key_in, unsigned int index, CExtKey &key_out)
Try to derive an extended key, throw if it fails.
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
Definition: types.h:40
@ ISMINE_NO
Definition: types.h:41
@ ISMINE_SPENDABLE
Definition: types.h:43
@ ISMINE_WATCH_ONLY
Definition: types.h:42
static bool ExtractPubKey(const CScript &dest, CPubKey &pubKeyOut)
@ FEATURE_COMPRPUBKEY
Definition: walletutil.h:20
@ FEATURE_HD_SPLIT
Definition: walletutil.h:24
@ FEATURE_HD
Definition: walletutil.h:22
@ FEATURE_PRE_SPLIT_KEYPOOL
Definition: walletutil.h:28
bool EncryptSecret(const CKeyingMaterial &vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256 &nIV, std::vector< unsigned char > &vchCiphertext)
Definition: crypter.cpp:108
bool IsFeatureSupported(int wallet_version, int feature_version)
Definition: walletutil.cpp:33
@ WALLET_FLAG_LAST_HARDENED_XPUB_CACHED
Definition: walletutil.h:48
@ WALLET_FLAG_KEY_ORIGIN_METADATA
Definition: walletutil.h:45
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
Definition: walletutil.h:74
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
Definition: walletutil.h:51
@ WALLET_FLAG_BLANK_WALLET
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses,...
Definition: walletutil.h:71
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
Definition: outputtype.cpp:50
OutputType
Definition: outputtype.h:17
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
Definition: psbt.cpp:338
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, const PrecomputedTransactionData *txdata, int sighash, SignatureData *out_sigdata, bool finalize)
Signs a PSBTInput, verifying that all provided data matches what is being signed.
Definition: psbt.cpp:375
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed by checking for non-null finalized fields.
Definition: psbt.cpp:293
void SignTransaction(CMutableTransaction &mtx, const SigningProvider *keystore, const std::map< COutPoint, Coin > &coins, const UniValue &hashType, UniValue &result)
Sign a transaction with the given keystore and previous transactions.
const char * prefix
Definition: rest.cpp:1007
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
Definition: script.h:27
@ OP_0
Definition: script.h:75
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:499
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
Definition: sign.cpp:762
const SigningProvider & DUMMY_SIGNING_PROVIDER
CKeyID GetKeyForDestination(const SigningProvider &store, const CTxDestination &dest)
Return the CKeyID of the key involved in a script (if there is a unique one).
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: solver.cpp:140
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: solver.cpp:209
TxoutType
Definition: solver.h:22
@ WITNESS_V1_TAPROOT
@ WITNESS_UNKNOWN
Only for Witness versions not already defined above.
@ WITNESS_V0_SCRIPTHASH
@ NULL_DATA
unspendable OP_RETURN script that carries data
@ WITNESS_V0_KEYHASH
unsigned char * UCharCast(char *c)
Definition: span.h:288
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:109
Definition: key.h:210
CExtPubKey Neuter() const
Definition: key.cpp:400
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:379
CKey key
Definition: key.h:215
void SetSeed(Span< const std::byte > seed)
Definition: key.cpp:388
A mutable version of CTransaction.
Definition: transaction.h:378
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
std::map< CKeyID, CPubKey > pubkeys
std::map< CKeyID, CKey > keys
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
Definition: keyorigin.h:13
std::vector< uint32_t > path
Definition: keyorigin.h:14
A structure for PSBTs which contain per-input information.
Definition: psbt.h:194
std::map< CPubKey, KeyOriginInfo > hd_keypaths
Definition: psbt.h:201
CTransactionRef non_witness_utxo
Definition: psbt.h:195
std::optional< int > sighash_type
Definition: psbt.h:218
std::map< XOnlyPubKey, std::pair< std::set< uint256 >, KeyOriginInfo > > m_tap_bip32_paths
Definition: psbt.h:212
CTxOut witness_utxo
Definition: psbt.h:196
A version of CTransaction with the PSBT format.
Definition: psbt.h:947
std::vector< PSBTInput > inputs
Definition: psbt.h:952
std::optional< CMutableTransaction > tx
Definition: psbt.h:948
std::map< CKeyID, SigPair > signatures
BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a ...
Definition: sign.h:77
Bilingual messages:
Definition: translation.h:18
struct containing information needed for migrating legacy wallets to descriptor wallets
#define LOCK(cs)
Definition: sync.h:257
int64_t GetTime()
Definition: time.cpp:97
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1162
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:74
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
Definition: message.cpp:57
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
AssertLockHeld(pool.cs)
assert(!tx.IsCoinBase())