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