Bitcoin Core  0.19.99
P2P Digital Currency
scriptpubkeyman.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <key_io.h>
6 #include <outputtype.h>
7 #include <script/descriptor.h>
8 #include <util/bip32.h>
9 #include <util/strencodings.h>
10 #include <util/translation.h>
11 #include <wallet/scriptpubkeyman.h>
12 
14 {
16  error.clear();
17 
18  // Generate a new key that is added to wallet
19  CPubKey new_key;
20  if (!GetKeyFromPool(new_key, type)) {
21  error = "Error: Keypool ran out, please call keypoolrefill first";
22  return false;
23  }
24  LearnRelatedScripts(new_key, type);
25  dest = GetDestinationForKey(new_key, type);
26  return true;
27 }
28 
29 typedef std::vector<unsigned char> valtype;
30 
31 namespace {
32 
39 enum class IsMineSigVersion
40 {
41  TOP = 0,
42  P2SH = 1,
43  WITNESS_V0 = 2,
44 };
45 
51 enum class IsMineResult
52 {
53  NO = 0,
54  WATCH_ONLY = 1,
55  SPENDABLE = 2,
56  INVALID = 3,
57 };
58 
59 bool PermitsUncompressed(IsMineSigVersion sigversion)
60 {
61  return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
62 }
63 
64 bool HaveKeys(const std::vector<valtype>& pubkeys, const LegacyScriptPubKeyMan& keystore)
65 {
66  for (const valtype& pubkey : pubkeys) {
67  CKeyID keyID = CPubKey(pubkey).GetID();
68  if (!keystore.HaveKey(keyID)) return false;
69  }
70  return true;
71 }
72 
81 IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& scriptPubKey, IsMineSigVersion sigversion, bool recurse_scripthash=true)
82 {
83  IsMineResult ret = IsMineResult::NO;
84 
85  std::vector<valtype> vSolutions;
86  txnouttype whichType = Solver(scriptPubKey, vSolutions);
87 
88  CKeyID keyID;
89  switch (whichType)
90  {
91  case TX_NONSTANDARD:
92  case TX_NULL_DATA:
93  case TX_WITNESS_UNKNOWN:
94  break;
95  case TX_PUBKEY:
96  keyID = CPubKey(vSolutions[0]).GetID();
97  if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
98  return IsMineResult::INVALID;
99  }
100  if (keystore.HaveKey(keyID)) {
101  ret = std::max(ret, IsMineResult::SPENDABLE);
102  }
103  break;
105  {
106  if (sigversion == IsMineSigVersion::WITNESS_V0) {
107  // P2WPKH inside P2WSH is invalid.
108  return IsMineResult::INVALID;
109  }
110  if (sigversion == IsMineSigVersion::TOP && !keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
111  // We do not support bare witness outputs unless the P2SH version of it would be
112  // acceptable as well. This protects against matching before segwit activates.
113  // This also applies to the P2WSH case.
114  break;
115  }
116  ret = std::max(ret, IsMineInner(keystore, GetScriptForDestination(PKHash(uint160(vSolutions[0]))), IsMineSigVersion::WITNESS_V0));
117  break;
118  }
119  case TX_PUBKEYHASH:
120  keyID = CKeyID(uint160(vSolutions[0]));
121  if (!PermitsUncompressed(sigversion)) {
122  CPubKey pubkey;
123  if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) {
124  return IsMineResult::INVALID;
125  }
126  }
127  if (keystore.HaveKey(keyID)) {
128  ret = std::max(ret, IsMineResult::SPENDABLE);
129  }
130  break;
131  case TX_SCRIPTHASH:
132  {
133  if (sigversion != IsMineSigVersion::TOP) {
134  // P2SH inside P2WSH or P2SH is invalid.
135  return IsMineResult::INVALID;
136  }
137  CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
138  CScript subscript;
139  if (keystore.GetCScript(scriptID, subscript)) {
140  ret = std::max(ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::P2SH) : IsMineResult::SPENDABLE);
141  }
142  break;
143  }
145  {
146  if (sigversion == IsMineSigVersion::WITNESS_V0) {
147  // P2WSH inside P2WSH is invalid.
148  return IsMineResult::INVALID;
149  }
150  if (sigversion == IsMineSigVersion::TOP && !keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
151  break;
152  }
153  uint160 hash;
154  CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(hash.begin());
155  CScriptID scriptID = CScriptID(hash);
156  CScript subscript;
157  if (keystore.GetCScript(scriptID, subscript)) {
158  ret = std::max(ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::WITNESS_V0) : IsMineResult::SPENDABLE);
159  }
160  break;
161  }
162 
163  case TX_MULTISIG:
164  {
165  // Never treat bare multisig outputs as ours (they can still be made watchonly-though)
166  if (sigversion == IsMineSigVersion::TOP) {
167  break;
168  }
169 
170  // Only consider transactions "mine" if we own ALL the
171  // keys involved. Multi-signature transactions that are
172  // partially owned (somebody else has a key that can spend
173  // them) enable spend-out-from-under-you attacks, especially
174  // in shared-wallet situations.
175  std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
176  if (!PermitsUncompressed(sigversion)) {
177  for (size_t i = 0; i < keys.size(); i++) {
178  if (keys[i].size() != 33) {
179  return IsMineResult::INVALID;
180  }
181  }
182  }
183  if (HaveKeys(keys, keystore)) {
184  ret = std::max(ret, IsMineResult::SPENDABLE);
185  }
186  break;
187  }
188  }
189 
190  if (ret == IsMineResult::NO && keystore.HaveWatchOnly(scriptPubKey)) {
191  ret = std::max(ret, IsMineResult::WATCH_ONLY);
192  }
193  return ret;
194 }
195 
196 } // namespace
197 
199 {
200  switch (IsMineInner(*this, script, IsMineSigVersion::TOP)) {
201  case IsMineResult::INVALID:
202  case IsMineResult::NO:
203  return ISMINE_NO;
204  case IsMineResult::WATCH_ONLY:
205  return ISMINE_WATCH_ONLY;
206  case IsMineResult::SPENDABLE:
207  return ISMINE_SPENDABLE;
208  }
209  assert(false);
210 }
211 
212 bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys)
213 {
214  {
215  LOCK(cs_KeyStore);
216  assert(mapKeys.empty());
217 
218  bool keyPass = mapCryptedKeys.empty(); // Always pass when there are no encrypted keys
219  bool keyFail = false;
220  CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
221  for (; mi != mapCryptedKeys.end(); ++mi)
222  {
223  const CPubKey &vchPubKey = (*mi).second.first;
224  const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
225  CKey key;
226  if (!DecryptKey(master_key, vchCryptedSecret, vchPubKey, key))
227  {
228  keyFail = true;
229  break;
230  }
231  keyPass = true;
233  break;
234  }
235  if (keyPass && keyFail)
236  {
237  LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n");
238  throw std::runtime_error("Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
239  }
240  if (keyFail || (!keyPass && !accept_no_keys))
241  return false;
243  }
244  return true;
245 }
246 
248 {
249  LOCK(cs_KeyStore);
250  encrypted_batch = batch;
251  if (!mapCryptedKeys.empty()) {
252  encrypted_batch = nullptr;
253  return false;
254  }
255 
256  KeyMap keys_to_encrypt;
257  keys_to_encrypt.swap(mapKeys); // Clear mapKeys so AddCryptedKeyInner will succeed.
258  for (const KeyMap::value_type& mKey : keys_to_encrypt)
259  {
260  const CKey &key = mKey.second;
261  CPubKey vchPubKey = key.GetPubKey();
262  CKeyingMaterial vchSecret(key.begin(), key.end());
263  std::vector<unsigned char> vchCryptedSecret;
264  if (!EncryptSecret(master_key, vchSecret, vchPubKey.GetHash(), vchCryptedSecret)) {
265  encrypted_batch = nullptr;
266  return false;
267  }
268  if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) {
269  encrypted_batch = nullptr;
270  return false;
271  }
272  }
273  encrypted_batch = nullptr;
274  return true;
275 }
276 
277 bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool)
278 {
279  LOCK(cs_KeyStore);
280  if (!CanGetAddresses(internal)) {
281  return false;
282  }
283 
284  if (!ReserveKeyFromKeyPool(index, keypool, internal)) {
285  return false;
286  }
287  address = GetDestinationForKey(keypool.vchPubKey, type);
288  return true;
289 }
290 
292 {
293  LOCK(cs_KeyStore);
294  // extract addresses and check if they match with an unused keypool key
295  for (const auto& keyid : GetAffectedKeys(script, *this)) {
296  std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
297  if (mi != m_pool_key_to_index.end()) {
298  WalletLogPrintf("%s: Detected a used keypool key, mark all keypool key up to this key as used\n", __func__);
299  MarkReserveKeysAsUsed(mi->second);
300 
301  if (!TopUp()) {
302  WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
303  }
304  }
305  }
306 }
307 
309 {
310  LOCK(cs_KeyStore);
312  return;
313  }
314 
315  std::unique_ptr<WalletBatch> batch = MakeUnique<WalletBatch>(m_storage.GetDatabase());
316  for (auto& meta_pair : mapKeyMetadata) {
317  CKeyMetadata& meta = meta_pair.second;
318  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
319  CKey key;
320  GetKey(meta.hd_seed_id, key);
321  CExtKey masterKey;
322  masterKey.SetSeed(key.begin(), key.size());
323  // Add to map
324  CKeyID master_id = masterKey.key.GetPubKey().GetID();
325  std::copy(master_id.begin(), master_id.begin() + 4, meta.key_origin.fingerprint);
326  if (!ParseHDKeypath(meta.hdKeypath, meta.key_origin.path)) {
327  throw std::runtime_error("Invalid stored hdKeypath");
328  }
329  meta.has_key_origin = true;
332  }
333 
334  // Write meta to wallet
335  CPubKey pubkey;
336  if (GetPubKey(meta_pair.first, pubkey)) {
337  batch->WriteKeyMetadata(meta, pubkey, true);
338  }
339  }
340  }
341 }
342 
344 {
345  if ((CanGenerateKeys() && !force) || m_storage.IsLocked()) {
346  return false;
347  }
348 
350  if (!NewKeyPool()) {
351  return false;
352  }
353  return true;
354 }
355 
357 {
358  return !hdChain.seed_id.IsNull();
359 }
360 
362 {
363  LOCK(cs_KeyStore);
364  // Check if the keypool has keys
365  bool keypool_has_keys;
366  if (internal && m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) {
367  keypool_has_keys = setInternalKeyPool.size() > 0;
368  } else {
369  keypool_has_keys = KeypoolCountExternalKeys() > 0;
370  }
371  // If the keypool doesn't have keys, check if we can generate them
372  if (!keypool_has_keys) {
373  return CanGenerateKeys();
374  }
375  return keypool_has_keys;
376 }
377 
378 bool LegacyScriptPubKeyMan::Upgrade(int prev_version, std::string& error)
379 {
380  LOCK(cs_KeyStore);
381  error = "";
382  bool hd_upgrade = false;
383  bool split_upgrade = false;
385  WalletLogPrintf("Upgrading wallet to HD\n");
387 
388  // generate a new master key
389  CPubKey masterPubKey = GenerateNewSeed();
390  SetHDSeed(masterPubKey);
391  hd_upgrade = true;
392  }
393  // Upgrade to HD chain split if necessary
395  WalletLogPrintf("Upgrading wallet to use HD chain split\n");
397  split_upgrade = FEATURE_HD_SPLIT > prev_version;
398  }
399  // Mark all keys currently in the keypool as pre-split
400  if (split_upgrade) {
402  }
403  // Regenerate the keypool if upgraded to HD
404  if (hd_upgrade) {
405  if (!TopUp()) {
406  error = _("Unable to generate keys").translated;
407  return false;
408  }
409  }
410  return true;
411 }
412 
414 {
415  LOCK(cs_KeyStore);
416  return !mapKeys.empty() || !mapCryptedKeys.empty();
417 }
418 
420 {
421  LOCK(cs_KeyStore);
422  setInternalKeyPool.clear();
423  setExternalKeyPool.clear();
424  m_pool_key_to_index.clear();
425  // Note: can't top-up keypool here, because wallet is locked.
426  // User will be prompted to unlock wallet the next operation
427  // that requires a new key.
428 }
429 
430 static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, WalletBatch& batch) {
431  if (setKeyPool.empty()) {
432  return GetTime();
433  }
434 
435  CKeyPool keypool;
436  int64_t nIndex = *(setKeyPool.begin());
437  if (!batch.ReadPool(nIndex, keypool)) {
438  throw std::runtime_error(std::string(__func__) + ": read oldest key in keypool failed");
439  }
440  assert(keypool.vchPubKey.IsValid());
441  return keypool.nTime;
442 }
443 
445 {
446  LOCK(cs_KeyStore);
447 
449 
450  // load oldest key from keypool, get time and return
451  int64_t oldestKey = GetOldestKeyTimeInPool(setExternalKeyPool, batch);
453  oldestKey = std::max(GetOldestKeyTimeInPool(setInternalKeyPool, batch), oldestKey);
454  if (!set_pre_split_keypool.empty()) {
455  oldestKey = std::max(GetOldestKeyTimeInPool(set_pre_split_keypool, batch), oldestKey);
456  }
457  }
458 
459  return oldestKey;
460 }
461 
463 {
464  LOCK(cs_KeyStore);
465  return setExternalKeyPool.size() + set_pre_split_keypool.size();
466 }
467 
469 {
470  LOCK(cs_KeyStore);
471  return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
472 }
473 
475 {
476  LOCK(cs_KeyStore);
477  return nTimeFirstKey;
478 }
479 
480 std::unique_ptr<SigningProvider> LegacyScriptPubKeyMan::GetSigningProvider(const CScript& script) const
481 {
482  return MakeUnique<LegacySigningProvider>(*this);
483 }
484 
486 {
487  IsMineResult ismine = IsMineInner(*this, script, IsMineSigVersion::TOP, /* recurse_scripthash= */ false);
488  if (ismine == IsMineResult::SPENDABLE || ismine == IsMineResult::WATCH_ONLY) {
489  // If ismine, it means we recognize keys or script ids in the script, or
490  // are watching the script itself, and we can at least provide metadata
491  // or solving information, even if not able to sign fully.
492  return true;
493  } else {
494  // If, given the stuff in sigdata, we could make a valid sigature, then we can provide for this script
495  ProduceSignature(*this, DUMMY_SIGNATURE_CREATOR, script, sigdata);
496  if (!sigdata.signatures.empty()) {
497  // If we could make signatures, make sure we have a private key to actually make a signature
498  bool has_privkeys = false;
499  for (const auto& key_sig_pair : sigdata.signatures) {
500  has_privkeys |= HaveKey(key_sig_pair.first);
501  }
502  return has_privkeys;
503  }
504  return false;
505  }
506 }
507 
509 {
510  LOCK(cs_KeyStore);
511 
512  CKeyID key_id = GetKeyForDestination(*this, dest);
513  if (!key_id.IsNull()) {
514  auto it = mapKeyMetadata.find(key_id);
515  if (it != mapKeyMetadata.end()) {
516  return &it->second;
517  }
518  }
519 
520  CScript scriptPubKey = GetScriptForDestination(dest);
521  auto it = m_script_metadata.find(CScriptID(scriptPubKey));
522  if (it != m_script_metadata.end()) {
523  return &it->second;
524  }
525 
526  return nullptr;
527 }
528 
530 {
531  return UINT256_ONE();
532 }
533 
539 {
541  if (nCreateTime <= 1) {
542  // Cannot determine birthday information, so set the wallet birthday to
543  // the beginning of time.
544  nTimeFirstKey = 1;
545  } else if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) {
546  nTimeFirstKey = nCreateTime;
547  }
548 }
549 
550 bool LegacyScriptPubKeyMan::LoadKey(const CKey& key, const CPubKey &pubkey)
551 {
552  return AddKeyPubKeyInner(key, pubkey);
553 }
554 
555 bool LegacyScriptPubKeyMan::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
556 {
557  LOCK(cs_KeyStore);
559  return LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(batch, secret, pubkey);
560 }
561 
562 bool LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& secret, const CPubKey& pubkey)
563 {
565 
566  // Make sure we aren't adding private keys to private key disabled wallets
568 
569  // FillableSigningProvider has no concept of wallet databases, but calls AddCryptedKey
570  // which is overridden below. To avoid flushes, the database handle is
571  // tunneled through to it.
572  bool needsDB = !encrypted_batch;
573  if (needsDB) {
574  encrypted_batch = &batch;
575  }
576  if (!AddKeyPubKeyInner(secret, pubkey)) {
577  if (needsDB) encrypted_batch = nullptr;
578  return false;
579  }
580  if (needsDB) encrypted_batch = nullptr;
581 
582  // check if we need to remove from watch-only
583  CScript script;
584  script = GetScriptForDestination(PKHash(pubkey));
585  if (HaveWatchOnly(script)) {
586  RemoveWatchOnly(script);
587  }
588  script = GetScriptForRawPubKey(pubkey);
589  if (HaveWatchOnly(script)) {
590  RemoveWatchOnly(script);
591  }
592 
593  if (!m_storage.HasEncryptionKeys()) {
594  return batch.WriteKey(pubkey,
595  secret.GetPrivKey(),
596  mapKeyMetadata[pubkey.GetID()]);
597  }
599  return true;
600 }
601 
603 {
604  /* A sanity check was added in pull #3843 to avoid adding redeemScripts
605  * that never can be redeemed. However, old wallets may still contain
606  * these. Do not add them to the wallet and warn. */
607  if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
608  {
609  std::string strAddr = EncodeDestination(ScriptHash(redeemScript));
610  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);
611  return true;
612  }
613 
614  return FillableSigningProvider::AddCScript(redeemScript);
615 }
616 
618 {
619  LOCK(cs_KeyStore);
621  mapKeyMetadata[keyID] = meta;
622 }
623 
625 {
626  LOCK(cs_KeyStore);
628  m_script_metadata[script_id] = meta;
629 }
630 
632 {
633  LOCK(cs_KeyStore);
634  if (!m_storage.HasEncryptionKeys()) {
635  return FillableSigningProvider::AddKeyPubKey(key, pubkey);
636  }
637 
638  if (m_storage.IsLocked()) {
639  return false;
640  }
641 
642  std::vector<unsigned char> vchCryptedSecret;
643  CKeyingMaterial vchSecret(key.begin(), key.end());
644  if (!EncryptSecret(m_storage.GetEncryptionKey(), vchSecret, pubkey.GetHash(), vchCryptedSecret)) {
645  return false;
646  }
647 
648  if (!AddCryptedKey(pubkey, vchCryptedSecret)) {
649  return false;
650  }
651  return true;
652 }
653 
654 bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
655 {
656  return AddCryptedKeyInner(vchPubKey, vchCryptedSecret);
657 }
658 
659 bool LegacyScriptPubKeyMan::AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
660 {
661  LOCK(cs_KeyStore);
662  assert(mapKeys.empty());
663 
664  mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
666  return true;
667 }
668 
670  const std::vector<unsigned char> &vchCryptedSecret)
671 {
672  if (!AddCryptedKeyInner(vchPubKey, vchCryptedSecret))
673  return false;
674  {
675  LOCK(cs_KeyStore);
676  if (encrypted_batch)
677  return encrypted_batch->WriteCryptedKey(vchPubKey,
678  vchCryptedSecret,
679  mapKeyMetadata[vchPubKey.GetID()]);
680  else
681  return WalletBatch(m_storage.GetDatabase()).WriteCryptedKey(vchPubKey,
682  vchCryptedSecret,
683  mapKeyMetadata[vchPubKey.GetID()]);
684  }
685 }
686 
688 {
689  LOCK(cs_KeyStore);
690  return setWatchOnly.count(dest) > 0;
691 }
692 
694 {
695  LOCK(cs_KeyStore);
696  return (!setWatchOnly.empty());
697 }
698 
699 static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
700 {
701  std::vector<std::vector<unsigned char>> solutions;
702  return Solver(dest, solutions) == TX_PUBKEY &&
703  (pubKeyOut = CPubKey(solutions[0])).IsFullyValid();
704 }
705 
707 {
708  {
709  LOCK(cs_KeyStore);
710  setWatchOnly.erase(dest);
711  CPubKey pubKey;
712  if (ExtractPubKey(dest, pubKey)) {
713  mapWatchKeys.erase(pubKey.GetID());
714  }
715  // Related CScripts are not removed; having superfluous scripts around is
716  // harmless (see comment in ImplicitlyLearnRelatedKeyScripts).
717  }
718 
719  if (!HaveWatchOnly())
720  NotifyWatchonlyChanged(false);
721  if (!WalletBatch(m_storage.GetDatabase()).EraseWatchOnly(dest))
722  return false;
723 
724  return true;
725 }
726 
728 {
729  return AddWatchOnlyInMem(dest);
730 }
731 
733 {
734  LOCK(cs_KeyStore);
735  setWatchOnly.insert(dest);
736  CPubKey pubKey;
737  if (ExtractPubKey(dest, pubKey)) {
738  mapWatchKeys[pubKey.GetID()] = pubKey;
740  }
741  return true;
742 }
743 
745 {
746  if (!AddWatchOnlyInMem(dest))
747  return false;
748  const CKeyMetadata& meta = m_script_metadata[CScriptID(dest)];
751  if (batch.WriteWatchOnly(dest, meta)) {
753  return true;
754  }
755  return false;
756 }
757 
758 bool LegacyScriptPubKeyMan::AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time)
759 {
760  m_script_metadata[CScriptID(dest)].nCreateTime = create_time;
761  return AddWatchOnlyWithDB(batch, dest);
762 }
763 
765 {
767  return AddWatchOnlyWithDB(batch, dest);
768 }
769 
770 bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
771 {
772  m_script_metadata[CScriptID(dest)].nCreateTime = nCreateTime;
773  return AddWatchOnly(dest);
774 }
775 
776 void LegacyScriptPubKeyMan::SetHDChain(const CHDChain& chain, bool memonly)
777 {
778  LOCK(cs_KeyStore);
779  if (!memonly && !WalletBatch(m_storage.GetDatabase()).WriteHDChain(chain))
780  throw std::runtime_error(std::string(__func__) + ": writing chain failed");
781 
782  hdChain = chain;
783 }
784 
785 bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const
786 {
787  LOCK(cs_KeyStore);
788  if (!m_storage.HasEncryptionKeys()) {
789  return FillableSigningProvider::HaveKey(address);
790  }
791  return mapCryptedKeys.count(address) > 0;
792 }
793 
794 bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const
795 {
796  LOCK(cs_KeyStore);
797  if (!m_storage.HasEncryptionKeys()) {
798  return FillableSigningProvider::GetKey(address, keyOut);
799  }
800 
801  CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
802  if (mi != mapCryptedKeys.end())
803  {
804  const CPubKey &vchPubKey = (*mi).second.first;
805  const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
806  return DecryptKey(m_storage.GetEncryptionKey(), vchCryptedSecret, vchPubKey, keyOut);
807  }
808  return false;
809 }
810 
812 {
813  CKeyMetadata meta;
814  {
815  LOCK(cs_KeyStore);
816  auto it = mapKeyMetadata.find(keyID);
817  if (it != mapKeyMetadata.end()) {
818  meta = it->second;
819  }
820  }
821  if (meta.has_key_origin) {
822  std::copy(meta.key_origin.fingerprint, meta.key_origin.fingerprint + 4, info.fingerprint);
823  info.path = meta.key_origin.path;
824  } else { // Single pubkeys get the master fingerprint of themselves
825  std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint);
826  }
827  return true;
828 }
829 
830 bool LegacyScriptPubKeyMan::GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
831 {
832  LOCK(cs_KeyStore);
833  WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
834  if (it != mapWatchKeys.end()) {
835  pubkey_out = it->second;
836  return true;
837  }
838  return false;
839 }
840 
841 bool LegacyScriptPubKeyMan::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
842 {
843  LOCK(cs_KeyStore);
844  if (!m_storage.HasEncryptionKeys()) {
845  if (!FillableSigningProvider::GetPubKey(address, vchPubKeyOut)) {
846  return GetWatchPubKey(address, vchPubKeyOut);
847  }
848  return true;
849  }
850 
851  CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
852  if (mi != mapCryptedKeys.end())
853  {
854  vchPubKeyOut = (*mi).second.first;
855  return true;
856  }
857  // Check for watch-only pubkeys
858  return GetWatchPubKey(address, vchPubKeyOut);
859 }
860 
862 {
866  bool fCompressed = m_storage.CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
867 
868  CKey secret;
869 
870  // Create new metadata
871  int64_t nCreationTime = GetTime();
872  CKeyMetadata metadata(nCreationTime);
873 
874  // use HD key derivation if HD was enabled during wallet creation and a seed is present
875  if (IsHDEnabled()) {
876  DeriveNewChildKey(batch, metadata, secret, (m_storage.CanSupportFeature(FEATURE_HD_SPLIT) ? internal : false));
877  } else {
878  secret.MakeNewKey(fCompressed);
879  }
880 
881  // Compressed public keys were introduced in version 0.6.0
882  if (fCompressed) {
884  }
885 
886  CPubKey pubkey = secret.GetPubKey();
887  assert(secret.VerifyPubKey(pubkey));
888 
889  mapKeyMetadata[pubkey.GetID()] = metadata;
890  UpdateTimeFirstKey(nCreationTime);
891 
892  if (!AddKeyPubKeyWithDB(batch, secret, pubkey)) {
893  throw std::runtime_error(std::string(__func__) + ": AddKey failed");
894  }
895  return pubkey;
896 }
897 
898 const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
899 
900 void LegacyScriptPubKeyMan::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey& secret, bool internal)
901 {
902  // for now we use a fixed keypath scheme of m/0'/0'/k
903  CKey seed; //seed (256bit)
904  CExtKey masterKey; //hd master key
905  CExtKey accountKey; //key at m/0'
906  CExtKey chainChildKey; //key at m/0'/0' (external) or m/0'/1' (internal)
907  CExtKey childKey; //key at m/0'/0'/<n>'
908 
909  // try to get the seed
910  if (!GetKey(hdChain.seed_id, seed))
911  throw std::runtime_error(std::string(__func__) + ": seed not found");
912 
913  masterKey.SetSeed(seed.begin(), seed.size());
914 
915  // derive m/0'
916  // use hardened derivation (child keys >= 0x80000000 are hardened after bip32)
917  masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT);
918 
919  // derive m/0'/0' (external chain) OR m/0'/1' (internal chain)
920  assert(internal ? m_storage.CanSupportFeature(FEATURE_HD_SPLIT) : true);
921  accountKey.Derive(chainChildKey, BIP32_HARDENED_KEY_LIMIT+(internal ? 1 : 0));
922 
923  // derive child key at next index, skip keys already known to the wallet
924  do {
925  // always derive hardened keys
926  // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
927  // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
928  if (internal) {
930  metadata.hdKeypath = "m/0'/1'/" + std::to_string(hdChain.nInternalChainCounter) + "'";
931  metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
932  metadata.key_origin.path.push_back(1 | BIP32_HARDENED_KEY_LIMIT);
935  }
936  else {
938  metadata.hdKeypath = "m/0'/0'/" + std::to_string(hdChain.nExternalChainCounter) + "'";
939  metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
940  metadata.key_origin.path.push_back(0 | BIP32_HARDENED_KEY_LIMIT);
943  }
944  } while (HaveKey(childKey.key.GetPubKey().GetID()));
945  secret = childKey.key;
946  metadata.hd_seed_id = hdChain.seed_id;
947  CKeyID master_id = masterKey.key.GetPubKey().GetID();
948  std::copy(master_id.begin(), master_id.begin() + 4, metadata.key_origin.fingerprint);
949  metadata.has_key_origin = true;
950  // update the chain model in the database
951  if (!batch.WriteHDChain(hdChain))
952  throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
953 }
954 
955 void LegacyScriptPubKeyMan::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
956 {
957  LOCK(cs_KeyStore);
958  if (keypool.m_pre_split) {
959  set_pre_split_keypool.insert(nIndex);
960  } else if (keypool.fInternal) {
961  setInternalKeyPool.insert(nIndex);
962  } else {
963  setExternalKeyPool.insert(nIndex);
964  }
965  m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
966  m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex;
967 
968  // If no metadata exists yet, create a default with the pool key's
969  // creation time. Note that this may be overwritten by actually
970  // stored metadata for that key later, which is fine.
971  CKeyID keyid = keypool.vchPubKey.GetID();
972  if (mapKeyMetadata.count(keyid) == 0)
973  mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
974 }
975 
977 {
978  // A wallet can generate keys if it has an HD seed (IsHDEnabled) or it is a non-HD wallet (pre FEATURE_HD)
979  LOCK(cs_KeyStore);
981 }
982 
984 {
986  CKey key;
987  key.MakeNewKey(true);
988  return DeriveNewSeed(key);
989 }
990 
992 {
993  int64_t nCreationTime = GetTime();
994  CKeyMetadata metadata(nCreationTime);
995 
996  // calculate the seed
997  CPubKey seed = key.GetPubKey();
998  assert(key.VerifyPubKey(seed));
999 
1000  // set the hd keypath to "s" -> Seed, refers the seed to itself
1001  metadata.hdKeypath = "s";
1002  metadata.has_key_origin = false;
1003  metadata.hd_seed_id = seed.GetID();
1004 
1005  {
1006  LOCK(cs_KeyStore);
1007 
1008  // mem store the metadata
1009  mapKeyMetadata[seed.GetID()] = metadata;
1010 
1011  // write the key&metadata to the database
1012  if (!AddKeyPubKey(key, seed))
1013  throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed");
1014  }
1015 
1016  return seed;
1017 }
1018 
1020 {
1021  LOCK(cs_KeyStore);
1022  // store the keyid (hash160) together with
1023  // the child index counter in the database
1024  // as a hdchain object
1025  CHDChain newHdChain;
1027  newHdChain.seed_id = seed.GetID();
1028  SetHDChain(newHdChain, false);
1032 }
1033 
1039 {
1041  return false;
1042  }
1043  {
1044  LOCK(cs_KeyStore);
1046 
1047  for (const int64_t nIndex : setInternalKeyPool) {
1048  batch.ErasePool(nIndex);
1049  }
1050  setInternalKeyPool.clear();
1051 
1052  for (const int64_t nIndex : setExternalKeyPool) {
1053  batch.ErasePool(nIndex);
1054  }
1055  setExternalKeyPool.clear();
1056 
1057  for (const int64_t nIndex : set_pre_split_keypool) {
1058  batch.ErasePool(nIndex);
1059  }
1060  set_pre_split_keypool.clear();
1061 
1062  m_pool_key_to_index.clear();
1063 
1064  if (!TopUp()) {
1065  return false;
1066  }
1067  WalletLogPrintf("LegacyScriptPubKeyMan::NewKeyPool rewrote keypool\n");
1068  }
1069  return true;
1070 }
1071 
1072 bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
1073 {
1074  if (!CanGenerateKeys()) {
1075  return false;
1076  }
1077  {
1078  LOCK(cs_KeyStore);
1079 
1080  if (m_storage.IsLocked()) return false;
1081 
1082  // Top up key pool
1083  unsigned int nTargetSize;
1084  if (kpSize > 0)
1085  nTargetSize = kpSize;
1086  else
1087  nTargetSize = std::max(gArgs.GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0);
1088 
1089  // count amount of available keys (internal, external)
1090  // make sure the keypool of external and internal keys fits the user selected target (-keypool)
1091  int64_t missingExternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setExternalKeyPool.size(), (int64_t) 0);
1092  int64_t missingInternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setInternalKeyPool.size(), (int64_t) 0);
1093 
1095  {
1096  // don't create extra internal keys
1097  missingInternal = 0;
1098  }
1099  bool internal = false;
1101  for (int64_t i = missingInternal + missingExternal; i--;)
1102  {
1103  if (i < missingInternal) {
1104  internal = true;
1105  }
1106 
1107  CPubKey pubkey(GenerateNewKey(batch, internal));
1108  AddKeypoolPubkeyWithDB(pubkey, internal, batch);
1109  }
1110  if (missingInternal + missingExternal > 0) {
1111  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());
1112  }
1113  }
1115  return true;
1116 }
1117 
1118 void LegacyScriptPubKeyMan::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch)
1119 {
1120  LOCK(cs_KeyStore);
1121  assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
1122  int64_t index = ++m_max_keypool_index;
1123  if (!batch.WritePool(index, CKeyPool(pubkey, internal))) {
1124  throw std::runtime_error(std::string(__func__) + ": writing imported pubkey failed");
1125  }
1126  if (internal) {
1127  setInternalKeyPool.insert(index);
1128  } else {
1129  setExternalKeyPool.insert(index);
1130  }
1131  m_pool_key_to_index[pubkey.GetID()] = index;
1132 }
1133 
1134 void LegacyScriptPubKeyMan::KeepDestination(int64_t nIndex, const OutputType& type)
1135 {
1136  // Remove from key pool
1138  batch.ErasePool(nIndex);
1139  CPubKey pubkey;
1140  bool have_pk = GetPubKey(m_index_to_reserved_key.at(nIndex), pubkey);
1141  assert(have_pk);
1142  LearnRelatedScripts(pubkey, type);
1143  m_index_to_reserved_key.erase(nIndex);
1144  WalletLogPrintf("keypool keep %d\n", nIndex);
1145 }
1146 
1147 void LegacyScriptPubKeyMan::ReturnDestination(int64_t nIndex, bool fInternal, const CTxDestination&)
1148 {
1149  // Return to key pool
1150  {
1151  LOCK(cs_KeyStore);
1152  if (fInternal) {
1153  setInternalKeyPool.insert(nIndex);
1154  } else if (!set_pre_split_keypool.empty()) {
1155  set_pre_split_keypool.insert(nIndex);
1156  } else {
1157  setExternalKeyPool.insert(nIndex);
1158  }
1159  CKeyID& pubkey_id = m_index_to_reserved_key.at(nIndex);
1160  m_pool_key_to_index[pubkey_id] = nIndex;
1161  m_index_to_reserved_key.erase(nIndex);
1163  }
1164  WalletLogPrintf("keypool return %d\n", nIndex);
1165 }
1166 
1167 bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType type, bool internal)
1168 {
1169  if (!CanGetAddresses(internal)) {
1170  return false;
1171  }
1172 
1173  CKeyPool keypool;
1174  {
1175  LOCK(cs_KeyStore);
1176  int64_t nIndex;
1178  if (m_storage.IsLocked()) return false;
1180  result = GenerateNewKey(batch, internal);
1181  return true;
1182  }
1183  KeepDestination(nIndex, type);
1184  result = keypool.vchPubKey;
1185  }
1186  return true;
1187 }
1188 
1189 bool LegacyScriptPubKeyMan::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal)
1190 {
1191  nIndex = -1;
1192  keypool.vchPubKey = CPubKey();
1193  {
1194  LOCK(cs_KeyStore);
1195 
1196  bool fReturningInternal = fRequestedInternal;
1198  bool use_split_keypool = set_pre_split_keypool.empty();
1199  std::set<int64_t>& setKeyPool = use_split_keypool ? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) : set_pre_split_keypool;
1200 
1201  // Get the oldest key
1202  if (setKeyPool.empty()) {
1203  return false;
1204  }
1205 
1207 
1208  auto it = setKeyPool.begin();
1209  nIndex = *it;
1210  setKeyPool.erase(it);
1211  if (!batch.ReadPool(nIndex, keypool)) {
1212  throw std::runtime_error(std::string(__func__) + ": read failed");
1213  }
1214  CPubKey pk;
1215  if (!GetPubKey(keypool.vchPubKey.GetID(), pk)) {
1216  throw std::runtime_error(std::string(__func__) + ": unknown key in key pool");
1217  }
1218  // If the key was pre-split keypool, we don't care about what type it is
1219  if (use_split_keypool && keypool.fInternal != fReturningInternal) {
1220  throw std::runtime_error(std::string(__func__) + ": keypool entry misclassified");
1221  }
1222  if (!keypool.vchPubKey.IsValid()) {
1223  throw std::runtime_error(std::string(__func__) + ": keypool entry invalid");
1224  }
1225 
1226  assert(m_index_to_reserved_key.count(nIndex) == 0);
1227  m_index_to_reserved_key[nIndex] = keypool.vchPubKey.GetID();
1228  m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
1229  WalletLogPrintf("keypool reserve %d\n", nIndex);
1230  }
1232  return true;
1233 }
1234 
1236 {
1237  if (key.IsCompressed() && (type == OutputType::P2SH_SEGWIT || type == OutputType::BECH32)) {
1238  CTxDestination witdest = WitnessV0KeyHash(key.GetID());
1239  CScript witprog = GetScriptForDestination(witdest);
1240  // Make sure the resulting program is solvable.
1241  assert(IsSolvable(*this, witprog));
1242  AddCScript(witprog);
1243  }
1244 }
1245 
1247 {
1248  // OutputType::P2SH_SEGWIT always adds all necessary scripts for all types.
1250 }
1251 
1253 {
1255  bool internal = setInternalKeyPool.count(keypool_id);
1256  if (!internal) assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id));
1257  std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
1258  auto it = setKeyPool->begin();
1259 
1261  while (it != std::end(*setKeyPool)) {
1262  const int64_t& index = *(it);
1263  if (index > keypool_id) break; // set*KeyPool is ordered
1264 
1265  CKeyPool keypool;
1266  if (batch.ReadPool(index, keypool)) { //TODO: This should be unnecessary
1267  m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
1268  }
1270  batch.ErasePool(index);
1271  WalletLogPrintf("keypool index %d removed\n", index);
1272  it = setKeyPool->erase(it);
1273  }
1274 }
1275 
1276 std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& provider)
1277 {
1278  std::vector<CScript> dummy;
1279  FlatSigningProvider out;
1280  InferDescriptor(spk, provider)->Expand(0, DUMMY_SIGNING_PROVIDER, dummy, out);
1281  std::vector<CKeyID> ret;
1282  for (const auto& entry : out.pubkeys) {
1283  ret.push_back(entry.first);
1284  }
1285  return ret;
1286 }
1287 
1289 {
1291  for (auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) {
1292  int64_t index = *it;
1293  CKeyPool keypool;
1294  if (!batch.ReadPool(index, keypool)) {
1295  throw std::runtime_error(std::string(__func__) + ": read keypool entry failed");
1296  }
1297  keypool.m_pre_split = true;
1298  if (!batch.WritePool(index, keypool)) {
1299  throw std::runtime_error(std::string(__func__) + ": writing modified keypool entry failed");
1300  }
1301  set_pre_split_keypool.insert(index);
1302  it = setExternalKeyPool.erase(it);
1303  }
1304 }
1305 
1307 {
1309  return AddCScriptWithDB(batch, redeemScript);
1310 }
1311 
1313 {
1314  if (!FillableSigningProvider::AddCScript(redeemScript))
1315  return false;
1316  if (batch.WriteCScript(Hash160(redeemScript), redeemScript)) {
1318  return true;
1319  }
1320  return false;
1321 }
1322 
1324 {
1325  LOCK(cs_KeyStore);
1326  std::copy(info.fingerprint, info.fingerprint + 4, mapKeyMetadata[pubkey.GetID()].key_origin.fingerprint);
1327  mapKeyMetadata[pubkey.GetID()].key_origin.path = info.path;
1328  mapKeyMetadata[pubkey.GetID()].has_key_origin = true;
1329  mapKeyMetadata[pubkey.GetID()].hdKeypath = WriteHDKeypath(info.path);
1330  return batch.WriteKeyMetadata(mapKeyMetadata[pubkey.GetID()], pubkey, true);
1331 }
1332 
1333 bool LegacyScriptPubKeyMan::ImportScripts(const std::set<CScript> scripts, int64_t timestamp)
1334 {
1336  for (const auto& entry : scripts) {
1337  CScriptID id(entry);
1338  if (HaveCScript(id)) {
1339  WalletLogPrintf("Already have script %s, skipping\n", HexStr(entry));
1340  continue;
1341  }
1342  if (!AddCScriptWithDB(batch, entry)) {
1343  return false;
1344  }
1345 
1346  if (timestamp > 0) {
1347  m_script_metadata[CScriptID(entry)].nCreateTime = timestamp;
1348  }
1349  }
1350  if (timestamp > 0) {
1351  UpdateTimeFirstKey(timestamp);
1352  }
1353 
1354  return true;
1355 }
1356 
1357 bool LegacyScriptPubKeyMan::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp)
1358 {
1360  for (const auto& entry : privkey_map) {
1361  const CKey& key = entry.second;
1362  CPubKey pubkey = key.GetPubKey();
1363  const CKeyID& id = entry.first;
1364  assert(key.VerifyPubKey(pubkey));
1365  // Skip if we already have the key
1366  if (HaveKey(id)) {
1367  WalletLogPrintf("Already have key with pubkey %s, skipping\n", HexStr(pubkey));
1368  continue;
1369  }
1370  mapKeyMetadata[id].nCreateTime = timestamp;
1371  // If the private key is not present in the wallet, insert it.
1372  if (!AddKeyPubKeyWithDB(batch, key, pubkey)) {
1373  return false;
1374  }
1375  UpdateTimeFirstKey(timestamp);
1376  }
1377  return true;
1378 }
1379 
1380 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)
1381 {
1383  for (const auto& entry : key_origins) {
1384  AddKeyOriginWithDB(batch, entry.second.first, entry.second.second);
1385  }
1386  for (const CKeyID& id : ordered_pubkeys) {
1387  auto entry = pubkey_map.find(id);
1388  if (entry == pubkey_map.end()) {
1389  continue;
1390  }
1391  const CPubKey& pubkey = entry->second;
1392  CPubKey temp;
1393  if (GetPubKey(id, temp)) {
1394  // Already have pubkey, skipping
1395  WalletLogPrintf("Already have pubkey %s, skipping\n", HexStr(temp));
1396  continue;
1397  }
1398  if (!AddWatchOnlyWithDB(batch, GetScriptForRawPubKey(pubkey), timestamp)) {
1399  return false;
1400  }
1401  mapKeyMetadata[id].nCreateTime = timestamp;
1402 
1403  // Add to keypool only works with pubkeys
1404  if (add_keypool) {
1405  AddKeypoolPubkeyWithDB(pubkey, internal, batch);
1407  }
1408  }
1409  return true;
1410 }
1411 
1412 bool LegacyScriptPubKeyMan::ImportScriptPubKeys(const std::set<CScript>& script_pub_keys, const bool have_solving_data, const int64_t timestamp)
1413 {
1415  for (const CScript& script : script_pub_keys) {
1416  if (!have_solving_data || !IsMine(script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1417  if (!AddWatchOnlyWithDB(batch, script, timestamp)) {
1418  return false;
1419  }
1420  }
1421  }
1422  return true;
1423 }
1424 
1425 std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const
1426 {
1427  LOCK(cs_KeyStore);
1428  if (!m_storage.HasEncryptionKeys()) {
1430  }
1431  std::set<CKeyID> set_address;
1432  for (const auto& mi : mapCryptedKeys) {
1433  set_address.insert(mi.first);
1434  }
1435  return set_address;
1436 }
void ReturnDestination(int64_t index, bool internal, const CTxDestination &) override
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
Top-level scriptPubKey.
bool NewKeyPool()
Mark old keypool keys as used, and generate all new 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
bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey)
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
Definition: key.cpp:171
std::string hdKeypath
Definition: walletdb.h:124
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.
void KeepDestination(int64_t index, const OutputType &type) override
void RewriteDB() override
The action to do when the DB needs rewrite.
bool GetNewDestination(const OutputType type, CTxDestination &dest, std::string &error) override
virtual const CKeyingMaterial & GetEncryptionKey() const =0
virtual void UnsetBlankWalletFlag(WalletBatch &)=0
unspendable OP_RETURN script that carries data
Definition: standard.h:63
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
void LearnAllRelatedScripts(const CPubKey &key)
Same as LearnRelatedScripts, but when the OutputType is not known (and could be anything).
void MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Marks all keys in the keypool up to and including reserve_key as used.
bool ImportScriptPubKeys(const std::set< CScript > &script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
bool AddKeyOriginWithDB(WalletBatch &batch, const CPubKey &pubkey, const KeyOriginInfo &info)
Add a KeyOriginInfo to the wallet.
bool DecryptKey(const CKeyingMaterial &vMasterKey, const std::vector< unsigned char > &vchCryptedSecret, const CPubKey &vchPubKey, CKey &key)
Definition: crypter.cpp:127
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
CKey key
Definition: key.h:149
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:293
isminetype IsMine(const CScript &script) const override
RecursiveMutex cs_KeyStore
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
Definition: key.cpp:232
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:184
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) ...
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
Definition: walletdb.cpp:752
void AddKeypoolPubkeyWithDB(const CPubKey &pubkey, const bool internal, WalletBatch &batch)
virtual bool AddCScript(const CScript &redeemScript)
Definition: key.h:144
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
Definition: walletdb.cpp:129
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
Definition: sign.cpp:431
bool CanGetAddresses(bool internal=false) override
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: standard.cpp:297
uint256 GetHash() const
Get the 256-bit hash of this public key.
Definition: pubkey.h:161
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSigningProvider) that...
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
Definition: crypter.h:67
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:163
virtual std::set< CKeyID > GetKeys() const
uint256 GetID() const override
static std::string WriteHDKeypath(std::vector< uint32_t > &keypath)
CKeyID GetKeyForDestination(const SigningProvider &store, const CTxDestination &dest)
Return the CKeyID of the key involved in a script (if there is a unique one).
uint32_t nExternalChainCounter
Definition: walletdb.h:85
void LearnRelatedScripts(const CPubKey &key, OutputType)
Explicitly make the wallet learn the related scripts for outputs to the given key.
txnouttype Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: standard.cpp:91
std::string translated
Definition: translation.h:18
virtual WalletDatabase & GetDatabase()=0
size_t KeypoolCountExternalKeys() override
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
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)
uint160 Hash160(const T1 pbegin, const T1 pend)
Compute the 160-bit hash an object.
Definition: hash.h:94
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
Definition: script.h:23
bool Upgrade(int prev_version, std::string &error) override
Upgrades the wallet to the specified version.
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
const unsigned char * begin() const
Definition: key.h:89
uint256 & UINT256_ONE()
Definition: uint256.cpp:79
virtual bool IsWalletFlagSet(uint64_t) const =0
unsigned char * begin()
Definition: uint256.h:54
bool RemoveWatchOnly(const CScript &dest)
Remove a watch only script from the keystore.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:155
bool IsNull() const
Definition: uint256.h:30
OutputType
Definition: outputtype.h:17
bool IsHDEnabled() const override
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
Access to the wallet database.
Definition: walletdb.h:175
static bool ExtractPubKey(const CScript &dest, CPubKey &pubKeyOut)
void WalletLogPrintf(std::string fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
unsigned int GetKeyPoolSize() const override
void SetHDChain(const CHDChain &chain, bool memonly)
IsMineSigVersion
This is an enum that tracks the execution context of a script, similar to SigVersion in script/interp...
CPubKey GenerateNewKey(WalletBatch &batch, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Generate a new key.
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
Only for Witness versions not already defined above.
Definition: standard.h:66
void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Update wallet first key creation time.
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
Definition: walletdb.cpp:124
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, and saves it to disk.
bool AddWatchOnlyInMem(const CScript &dest)
#define LOCK(cs)
Definition: sync.h:179
void MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used.
static const unsigned int DEFAULT_KEYPOOL_SIZE
Default for -keypool.
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:36
const SigningProvider & DUMMY_SIGNING_PROVIDER
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
bool TopUp(unsigned int size=0) override
Fills internal address pool.
bool IsValid() const
Definition: pubkey.h:171
An encapsulated public key.
Definition: pubkey.h:30
std::map< CKeyID, CPubKey > pubkeys
void SetHDSeed(const CPubKey &key)
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:157
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses, and other watch only things, and is therefore "blank.".
Definition: walletutil.h:57
void ImplicitlyLearnRelatedKeyScripts(const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool m_pre_split
Whether this key was generated for a keypool before the wallet was upgraded to HD-split.
bool GetKey(const CKeyID &address, CKey &keyOut) const override
isminetype
IsMine() return codes.
Definition: ismine.h:18
unsigned int size() const
Simple read-only vector-like interface.
Definition: key.h:88
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:289
KeyOriginInfo key_origin
Definition: walletdb.h:126
int64_t nCreateTime
Definition: walletdb.h:123
const CKeyMetadata * GetMetadata(const CTxDestination &dest) const override
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) ...
bool has_key_origin
Whether the key_origin is useful.
Definition: walletdb.h:127
bool ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal)
Reserves a key from the keypool and sets nIndex to its index.
void SetSeed(const unsigned char *seed, unsigned int nSeedLen)
Definition: key.cpp:301
bool GetKeyFromPool(CPubKey &key, const OutputType type, bool internal=false)
Fetches a key from the keypool.
virtual bool IsLocked() const =0
bool HavePrivateKeys() const override
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, const bool overwrite)
Definition: walletdb.cpp:84
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const override
std::map< int64_t, CKeyID > m_index_to_reserved_key
bool IsSolvable(const SigningProvider &provider, const CScript &script)
Definition: sign.cpp:434
CRIPEMD160 & Write(const unsigned char *data, size_t len)
Definition: ripemd160.cpp:247
bool AddCScript(const CScript &redeemScript) override
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
int nVersion
Definition: walletdb.h:122
P2SH redeemScript.
static int64_t GetOldestKeyTimeInPool(const std::set< int64_t > &setKeyPool, WalletBatch &batch)
bool ErasePool(int64_t nPool)
Definition: walletdb.cpp:172
bool WritePool(int64_t nPool, const CKeyPool &keypool)
Definition: walletdb.cpp:167
txnouttype
Definition: standard.h:55
256-bit opaque blob.
Definition: uint256.h:120
bool GetReservedDestination(const OutputType type, bool internal, CTxDestination &address, int64_t &index, CKeyPool &keypool) override
CPubKey vchPubKey
The public key.
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
virtual bool CanSupportFeature(enum WalletFeature) const =0
bool HaveWatchOnly() const
Returns whether there are any watch-only things in the wallet.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible...
An interface to be implemented by keystores that support signing.
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0&#39;/2000".
Definition: bip32.cpp:12
bool HaveKey(const CKeyID &address) const override
std::map< CKeyID, CKey > KeyMap
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:390
const unsigned char * end() const
Definition: key.h:90
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:372
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, CKey &secret, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
bool CheckDecryptionKey(const CKeyingMaterial &master_key, bool accept_no_keys=false) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
std::string HexStr(const T itbegin, const T itend)
Definition: strencodings.h:125
ArgsManager gArgs
Definition: system.cpp:76
160-bit opaque blob.
Definition: uint256.h:109
virtual bool HaveCScript(const CScriptID &hash) const override
std::vector< unsigned char > valtype
Definition: interpreter.cpp:15
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...
IsMineResult
This is an internal representation of isminetype + invalidity.
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:196
void UpgradeKeyMetadata()
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
static const int VERSION_WITH_KEY_ORIGIN
Definition: walletdb.h:120
CPubKey DeriveNewSeed(const CKey &key)
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
Definition: outputtype.cpp:49
bool EncryptSecret(const CKeyingMaterial &vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256 &nIV, std::vector< unsigned char > &vchCiphertext)
Definition: crypter.cpp:107
bool ReadPool(int64_t nPool, CKeyPool &keypool)
Definition: walletdb.cpp:162
int64_t GetTimeFirstKey() const override
static const int VERSION_HD_CHAIN_SPLIT
Definition: walletdb.h:90
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:21
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:210
virtual bool HasEncryptionKeys() const =0
size_type size() const
Definition: prevector.h:282
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
std::vector< unsigned char > valtype
bool SetupGeneration(bool force=false) override
Sets up the key generation stuff, i.e.
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:89
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
int64_t GetOldestKeyPoolTime() override
An encapsulated private key.
Definition: key.h:27
CKeyID hd_seed_id
Definition: walletdb.h:125
WalletStorage & m_storage
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: ripemd160.cpp:273
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:143
AssertLockHeld(g_cs_orphans)
CKeyID seed_id
seed hash160
Definition: walletdb.h:87
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
int64_t GetTime()
Return system time (or mocked time, if set)
Definition: time.cpp:20
auto it
Definition: validation.cpp:362
std::vector< uint32_t > path
Definition: keyorigin.h:14
Definition: script.h:57
virtual void SetMinVersion(enum WalletFeature, WalletBatch *=nullptr, bool=false)=0
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
bool AddCScriptWithDB(WalletBatch &batch, const CScript &script)
Adds a script to the store and saves it to disk.
int nVersion
Definition: walletdb.h:92
bool fDecryptionThoroughlyChecked
keeps track of whether Unlock has run a thorough check before
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
std::unique_ptr< SigningProvider > GetSigningProvider(const CScript &script) const override
std::set< CKeyID > GetKeys() const override
static const int VERSION_HD_BASE
Definition: walletdb.h:89
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
std::map< CKeyID, SigPair > signatures
BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a ...
Definition: sign.h:65
A hasher class for RIPEMD-160.
Definition: ripemd160.h:12
uint32_t nInternalChainCounter
Definition: walletdb.h:86
std::map< CKeyID, int64_t > m_pool_key_to_index
A key from a CWallet&#39;s keypool.
bool HaveWatchOnly(const CScript &dest) const
Returns whether the watch-only script is in the wallet.
const uint32_t BIP32_HARDENED_KEY_LIMIT
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:180
virtual bool HaveKey(const CKeyID &address) const override