30 return util::Error{
_(
"Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
42 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
48 typedef std::vector<unsigned char>
valtype;
58 enum class IsMineSigVersion
70 enum class IsMineResult
78 bool PermitsUncompressed(IsMineSigVersion sigversion)
80 return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
85 for (
const valtype& pubkey : pubkeys) {
87 if (!keystore.
HaveKey(keyID))
return false;
101 IsMineResult IsMineInner(
const LegacyScriptPubKeyMan& keystore,
const CScript& scriptPubKey, IsMineSigVersion sigversion,
bool recurse_scripthash=
true)
103 IsMineResult
ret = IsMineResult::NO;
105 std::vector<valtype> vSolutions;
117 if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
118 return IsMineResult::INVALID;
121 ret = std::max(
ret, IsMineResult::SPENDABLE);
126 if (sigversion == IsMineSigVersion::WITNESS_V0) {
128 return IsMineResult::INVALID;
141 if (!PermitsUncompressed(sigversion)) {
144 return IsMineResult::INVALID;
148 ret = std::max(
ret, IsMineResult::SPENDABLE);
153 if (sigversion != IsMineSigVersion::TOP) {
155 return IsMineResult::INVALID;
159 if (keystore.
GetCScript(scriptID, subscript)) {
160 ret = std::max(
ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::P2SH) : IsMineResult::SPENDABLE);
166 if (sigversion == IsMineSigVersion::WITNESS_V0) {
168 return IsMineResult::INVALID;
175 if (keystore.
GetCScript(scriptID, subscript)) {
176 ret = std::max(
ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::WITNESS_V0) : IsMineResult::SPENDABLE);
184 if (sigversion == IsMineSigVersion::TOP) {
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;
201 if (HaveKeys(keys, keystore)) {
202 ret = std::max(
ret, IsMineResult::SPENDABLE);
209 ret = std::max(
ret, IsMineResult::WATCH_ONLY);
218 switch (IsMineInner(*
this, script, IsMineSigVersion::TOP)) {
219 case IsMineResult::INVALID:
220 case IsMineResult::NO:
222 case IsMineResult::WATCH_ONLY:
224 case IsMineResult::SPENDABLE:
236 bool keyPass = mapCryptedKeys.empty();
237 bool keyFail =
false;
238 CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
240 for (; mi != mapCryptedKeys.end(); ++mi)
242 const CPubKey &vchPubKey = (*mi).second.first;
243 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
245 if (!
DecryptKey(master_key, vchCryptedSecret, vchPubKey, key))
258 if (keyPass && keyFail)
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.");
263 if (keyFail || !keyPass)
273 encrypted_batch = batch;
274 if (!mapCryptedKeys.empty()) {
275 encrypted_batch =
nullptr;
280 keys_to_encrypt.swap(mapKeys);
281 for (
const KeyMap::value_type& mKey : keys_to_encrypt)
283 const CKey &key = mKey.second;
286 std::vector<unsigned char> vchCryptedSecret;
288 encrypted_batch =
nullptr;
292 encrypted_batch =
nullptr;
296 encrypted_batch =
nullptr;
303 return util::Error{
_(
"Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
309 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
316 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
347 std::vector<WalletDestination> result;
352 WalletLogPrintf(
"%s: Detected a used keypool key, mark all keypool keys up to this key as used\n", __func__);
357 result.push_back({dest, keypool.fInternal});
362 WalletLogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
368 auto it = mapKeyMetadata.find(keyid);
369 if (it != mapKeyMetadata.end()){
372 std::vector<uint32_t> path;
376 WalletLogPrintf(
"%s: Adding inactive seed keys failed, invalid hdKeypath: %s\n",
380 if (path.size() != 3) {
381 WalletLogPrintf(
"%s: Adding inactive seed keys failed, invalid path size: %d, has_key_origin: %s\n",
408 for (
auto& meta_pair : mapKeyMetadata) {
419 throw std::runtime_error(
"Invalid stored hdKeypath");
428 if (
GetPubKey(meta_pair.first, pubkey)) {
429 batch->WriteKeyMetadata(meta, pubkey,
true);
457 bool keypool_has_keys;
459 keypool_has_keys = setInternalKeyPool.size() > 0;
464 if (!keypool_has_keys) {
467 return keypool_has_keys;
479 bool hd_upgrade =
false;
480 bool split_upgrade =
false;
499 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
510 error =
_(
"Unable to generate keys");
520 return !mapKeys.empty() || !mapCryptedKeys.empty();
526 setInternalKeyPool.clear();
527 setExternalKeyPool.clear();
535 if (setKeyPool.empty()) {
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");
545 return keypool.
nTime;
558 if (!set_pre_split_keypool.empty()) {
569 return setExternalKeyPool.size() + set_pre_split_keypool.size();
575 return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
581 return nTimeFirstKey;
586 return std::make_unique<LegacySigningProvider>(*
this);
591 IsMineResult ismine = IsMineInner(*
this, script, IsMineSigVersion::TOP,
false);
592 if (ismine == IsMineResult::SPENDABLE || ismine == IsMineResult::WATCH_ONLY) {
602 bool has_privkeys =
false;
603 for (
const auto& key_sig_pair : sigdata.
signatures) {
604 has_privkeys |=
HaveKey(key_sig_pair.first);
635 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
636 const CTxIn& txin = psbtx.
tx->vin[i];
660 if (n_signed && (signed_one || !sign)) {
669 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
682 auto it = mapKeyMetadata.find(key_id);
683 if (it != mapKeyMetadata.end()) {
684 return std::make_unique<CKeyMetadata>(it->second);
689 auto it = m_script_metadata.find(
CScriptID(scriptPubKey));
690 if (it != m_script_metadata.end()) {
691 return std::make_unique<CKeyMetadata>(it->second);
709 if (nCreateTime <= 1) {
713 }
else if (nTimeFirstKey ==
UNKNOWN_TIME || nCreateTime < nTimeFirstKey) {
714 nTimeFirstKey = nCreateTime;
742 bool needsDB = !encrypted_batch;
744 encrypted_batch = &batch;
747 if (needsDB) encrypted_batch =
nullptr;
750 if (needsDB) encrypted_batch =
nullptr;
767 mapKeyMetadata[pubkey.
GetID()]);
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);
791 mapKeyMetadata[keyID] = meta;
798 m_script_metadata[script_id] = meta;
812 std::vector<unsigned char> vchCryptedSecret;
815 return EncryptSecret(encryption_key, vchSecret, pubkey.GetHash(), vchCryptedSecret);
829 if (!checksum_valid) {
841 mapCryptedKeys[vchPubKey.
GetID()] = make_pair(vchPubKey, vchCryptedSecret);
847 const std::vector<unsigned char> &vchCryptedSecret)
854 return encrypted_batch->WriteCryptedKey(vchPubKey,
856 mapKeyMetadata[vchPubKey.
GetID()]);
860 mapKeyMetadata[vchPubKey.
GetID()]);
867 return setWatchOnly.count(dest) > 0;
873 return (!setWatchOnly.empty());
878 std::vector<std::vector<unsigned char>> solutions;
880 (pubKeyOut =
CPubKey(solutions[0])).IsFullyValid();
887 setWatchOnly.erase(dest);
890 mapWatchKeys.erase(pubKey.
GetID());
912 setWatchOnly.insert(dest);
915 mapWatchKeys[pubKey.
GetID()] = pubKey;
937 m_script_metadata[
CScriptID(dest)].nCreateTime = create_time;
949 m_script_metadata[
CScriptID(dest)].nCreateTime = nCreateTime;
964 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
987 return mapCryptedKeys.count(address) > 0;
997 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
998 if (mi != mapCryptedKeys.end())
1000 const CPubKey &vchPubKey = (*mi).second.first;
1001 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
1003 return DecryptKey(encryption_key, vchCryptedSecret, vchPubKey, keyOut);
1014 auto it = mapKeyMetadata.find(keyID);
1015 if (it == mapKeyMetadata.end()) {
1032 WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
1033 if (it != mapWatchKeys.end()) {
1034 pubkey_out = it->second;
1050 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1051 if (mi != mapCryptedKeys.end())
1053 vchPubKeyOut = (*mi).second.first;
1070 int64_t nCreationTime =
GetTime();
1088 mapKeyMetadata[pubkey.
GetID()] = metadata;
1092 throw std::runtime_error(std::string(__func__) +
": AddKey failed");
1099 if (!key_in.
Derive(key_out, index)) {
1100 throw std::runtime_error(
"Could not derive extended key");
1115 throw std::runtime_error(std::string(__func__) +
": seed not found");
1149 secret = childKey.
key;
1156 throw std::runtime_error(std::string(__func__) +
": writing HD chain model failed");
1163 set_pre_split_keypool.insert(nIndex);
1165 setInternalKeyPool.insert(nIndex);
1167 setExternalKeyPool.insert(nIndex);
1169 m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
1176 if (mapKeyMetadata.count(keyid) == 0)
1196 int64_t nCreationTime =
GetTime();
1212 mapKeyMetadata[seed.
GetID()] = metadata;
1216 throw std::runtime_error(std::string(__func__) +
": AddKeyPubKey failed");
1250 for (
const int64_t nIndex : setInternalKeyPool) {
1253 setInternalKeyPool.clear();
1255 for (
const int64_t nIndex : setExternalKeyPool) {
1258 setExternalKeyPool.clear();
1260 for (
const int64_t nIndex : set_pre_split_keypool) {
1263 set_pre_split_keypool.clear();
1270 WalletLogPrintf(
"LegacyScriptPubKeyMan::NewKeyPool rewrote keypool\n");
1282 if (!batch.
TxnBegin())
return false;
1306 unsigned int nTargetSize;
1308 nTargetSize = kpSize;
1310 nTargetSize = m_keypool_size;
1312 int64_t target = std::max((int64_t) nTargetSize, int64_t{1});
1316 int64_t missingExternal;
1317 int64_t missingInternal;
1319 missingExternal = std::max(target - (int64_t)setExternalKeyPool.size(), int64_t{0});
1320 missingInternal = std::max(target - (int64_t)setInternalKeyPool.size(), int64_t{0});
1328 missingInternal = 0;
1330 bool internal =
false;
1331 for (int64_t i = missingInternal + missingExternal; i--;) {
1332 if (i < missingInternal) {
1341 if (missingInternal + missingExternal > 0) {
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());
1345 WalletLogPrintf(
"inactive seed with id %s added %d external keys, %d internal keys\n",
HexStr(chain.
seed_id), missingExternal, missingInternal);
1354 assert(m_max_keypool_index < std::numeric_limits<int64_t>::max());
1355 int64_t index = ++m_max_keypool_index;
1357 throw std::runtime_error(std::string(__func__) +
": writing imported pubkey failed");
1360 setInternalKeyPool.insert(index);
1362 setExternalKeyPool.insert(index);
1387 setInternalKeyPool.insert(nIndex);
1388 }
else if (!set_pre_split_keypool.empty()) {
1389 set_pre_split_keypool.insert(nIndex);
1391 setExternalKeyPool.insert(nIndex);
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;
1437 if (setKeyPool.empty()) {
1443 auto it = setKeyPool.begin();
1445 setKeyPool.erase(it);
1446 if (!batch.
ReadPool(nIndex, keypool)) {
1447 throw std::runtime_error(std::string(__func__) +
": read failed");
1451 throw std::runtime_error(std::string(__func__) +
": unknown key in key pool");
1454 if (use_split_keypool && keypool.
fInternal != fReturningInternal) {
1455 throw std::runtime_error(std::string(__func__) +
": keypool entry misclassified");
1458 throw std::runtime_error(std::string(__func__) +
": keypool entry invalid");
1478 assert(desc && desc->IsSolvable());
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();
1497 std::vector<CKeyPool> result;
1499 while (it != std::end(*setKeyPool)) {
1500 const int64_t& index = *(it);
1501 if (index > keypool_id)
break;
1504 if (batch.
ReadPool(index, keypool)) {
1510 it = setKeyPool->erase(it);
1511 result.push_back(std::move(keypool));
1519 std::vector<CScript> dummy;
1522 std::vector<CKeyID>
ret;
1523 ret.reserve(
out.pubkeys.size());
1524 for (
const auto& entry :
out.pubkeys) {
1525 ret.push_back(entry.first);
1533 for (
auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) {
1534 int64_t index = *it;
1536 if (!batch.
ReadPool(index, keypool)) {
1537 throw std::runtime_error(std::string(__func__) +
": read keypool entry failed");
1541 throw std::runtime_error(std::string(__func__) +
": writing modified keypool entry failed");
1543 set_pre_split_keypool.insert(index);
1544 it = setExternalKeyPool.erase(it);
1569 mapKeyMetadata[pubkey.
GetID()].key_origin.path = info.
path;
1570 mapKeyMetadata[pubkey.
GetID()].has_key_origin =
true;
1578 for (
const auto& entry : scripts) {
1588 if (timestamp > 0) {
1589 m_script_metadata[
CScriptID(entry)].nCreateTime = timestamp;
1592 if (timestamp > 0) {
1602 for (
const auto& entry : privkey_map) {
1603 const CKey& key = entry.second;
1605 const CKeyID&
id = entry.first;
1612 mapKeyMetadata[id].nCreateTime = timestamp;
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)
1625 for (
const auto& entry : key_origins) {
1628 for (
const CKeyID&
id : ordered_pubkeys) {
1629 auto entry = pubkey_map.find(
id);
1630 if (entry == pubkey_map.end()) {
1633 const CPubKey& pubkey = entry->second;
1643 mapKeyMetadata[id].nCreateTime = timestamp;
1657 for (
const CScript& script : script_pub_keys) {
1658 if (!have_solving_data || !
IsMine(script)) {
1673 std::set<CKeyID> set_address;
1674 for (
const auto& mi : mapCryptedKeys) {
1675 set_address.insert(mi.first);
1683 std::unordered_set<CScript, SaltedSipHasher> spks;
1686 for (
const auto& key_pair : mapKeys) {
1687 const CPubKey& pub = key_pair.second.GetPubKey();
1691 for (
const auto& key_pair : mapCryptedKeys) {
1692 const CPubKey& pub = key_pair.second.first;
1700 for (
const auto& script_pair : mapScripts) {
1701 const CScript& script = script_pair.second;
1709 std::vector<unsigned char> witprog;
1711 spks.insert(script);
1716 std::vector<std::vector<unsigned char>> sols;
1721 spks.insert(ms_spk);
1728 for (
const CScript& script : setWatchOnly) {
1741 std::unordered_set<CScript, SaltedSipHasher> spks;
1742 for (
const CScript& script : setWatchOnly) {
1752 return std::nullopt;
1760 std::set<CKeyID> keyids;
1761 for (
const auto& key_pair : mapKeys) {
1762 keyids.insert(key_pair.first);
1764 for (
const auto& key_pair : mapCryptedKeys) {
1765 keyids.insert(key_pair.first);
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()) {
1780 keyid_it = keyids.erase(keyid_it);
1788 for (
const CKeyID& keyid : keyids) {
1790 if (!
GetKey(keyid, key)) {
1795 uint64_t creation_time = 0;
1796 const auto& it = mapKeyMetadata.find(keyid);
1797 if (it != mapKeyMetadata.end()) {
1798 creation_time = it->second.nCreateTime;
1808 std::string desc_str =
"combo(" + origin_str +
HexStr(key.
GetPubKey()) +
")";
1811 std::unique_ptr<Descriptor> desc =
Parse(desc_str, keys, error,
false);
1816 desc_spk_man->AddDescriptorKey(key, key.
GetPubKey());
1817 desc_spk_man->TopUp();
1818 auto desc_spks = desc_spk_man->GetScriptPubKeys();
1821 for (
const CScript& spk : desc_spks) {
1822 size_t erased = spks.erase(spk);
1827 out.desc_spkms.push_back(std::move(desc_spk_man));
1831 std::vector<CHDChain> chains;
1834 chains.push_back(chain_pair.second);
1836 for (
const CHDChain& chain : chains) {
1837 for (
int i = 0; i < 2; ++i) {
1844 if (!
GetKey(chain.seed_id, seed_key)) {
1852 std::string desc_str =
"combo(" + xpub +
"/0h/" +
ToString(i) +
"h/*h)";
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);
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();
1866 for (
const CScript& spk : desc_spks) {
1867 size_t erased = spks.erase(spk);
1872 out.desc_spkms.push_back(std::move(desc_spk_man));
1881 out.master_key.SetSeed(seed_key);
1885 for (
auto it = spks.begin(); it != spks.end();) {
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;
1898 std::vector<CScript> scripts;
1903 std::set<CKeyID> privkeyids;
1904 for (
const auto& key_orig_pair : keys.
origins) {
1905 privkeyids.insert(key_orig_pair.first);
1908 std::vector<CScript> desc_spks;
1911 std::string desc_str;
1912 bool watchonly = !desc->ToPrivateString(*
this, desc_str);
1914 out.watch_descs.emplace_back(desc->ToString(), creation_time);
1918 desc->Expand(0, provider, desc_spks, provider);
1923 for (
const auto& keyid : privkeyids) {
1925 if (!
GetKey(keyid, key)) {
1928 desc_spk_man->AddDescriptorKey(key, key.
GetPubKey());
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());
1934 out.desc_spkms.push_back(std::move(desc_spk_man));
1938 for (
const CScript& desc_spk : desc_spks) {
1939 auto del_it = spks.find(desc_spk);
1940 assert(del_it != spks.end());
1942 it = spks.erase(del_it);
1948 for (
const auto& script_pair : mapScripts) {
1949 const CScript script = script_pair.second;
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;
1958 std::vector<std::vector<unsigned char>> sols;
1974 std::vector<std::vector<unsigned char>> keys(sols.begin() + 1, sols.begin() + sols.size() - 1);
1983 out.solvable_descs.emplace_back(sh_desc->ToString(), creation_time);
1986 if (desc->IsSolvable()) {
1988 out.solvable_descs.emplace_back(wsh_desc->ToString(), creation_time);
1990 out.solvable_descs.emplace_back(sh_wsh_desc->ToString(), creation_time);
1996 assert(spks.size() == 0);
2015 assert(m_wallet_descriptor.descriptor->IsSingleType());
2016 std::optional<OutputType> desc_addr_type = m_wallet_descriptor.descriptor->GetOutputType();
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");
2026 std::vector<CScript> scripts_temp;
2029 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2031 if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2033 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2038 return util::Error{
_(
"Error: Cannot extract destination from the generated scriptpubkey")};
2040 m_wallet_descriptor.next_index++;
2049 if (m_map_script_pub_keys.count(script) > 0) {
2058 if (!m_map_keys.empty()) {
2062 bool keyPass = m_map_crypted_keys.empty();
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;
2068 if (!
DecryptKey(master_key, crypted_secret, pubkey, key)) {
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.");
2080 if (keyFail || !keyPass) {
2090 if (!m_map_crypted_keys.empty()) {
2094 for (
const KeyMap::value_type& key_in : m_map_keys)
2096 const CKey &key = key_in.second;
2099 std::vector<unsigned char> crypted_secret;
2103 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2114 index = m_wallet_descriptor.next_index - 1;
2122 if (m_wallet_descriptor.next_index - 1 == index) {
2123 m_wallet_descriptor.next_index--;
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;
2139 return DecryptKey(encryption_key, crypted_secret, pubkey, key);
2141 keys[pubkey.
GetID()] = key;
2151 return m_map_keys.contains(keyid) || m_map_crypted_keys.contains(keyid);
2158 const auto& it = m_map_crypted_keys.find(keyid);
2159 if (it == m_map_crypted_keys.end()) {
2160 return std::nullopt;
2162 const std::vector<unsigned char>& crypted_secret = it->second.second;
2165 return DecryptKey(encryption_key, crypted_secret, it->second.first, key);
2167 return std::nullopt;
2171 const auto& it = m_map_keys.find(keyid);
2172 if (it == m_map_keys.end()) {
2173 return std::nullopt;
2181 if (!batch.
TxnBegin())
return false;
2190 std::set<CScript> new_spks;
2191 unsigned int target_size;
2195 target_size = m_keypool_size;
2199 int32_t new_range_end = std::max(m_wallet_descriptor.next_index + (int32_t)target_size, m_wallet_descriptor.range_end);
2202 if (!m_wallet_descriptor.descriptor->IsRange()) {
2204 m_wallet_descriptor.range_end = 1;
2205 m_wallet_descriptor.range_start = 0;
2214 std::vector<CScript> scripts_temp;
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;
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;
2225 for (
const auto& pk_pair : out_keys.
pubkeys) {
2226 const CPubKey& pubkey = pk_pair.second;
2227 if (m_map_pubkeys.count(pubkey) != 0) {
2232 m_map_pubkeys[pubkey] = i;
2237 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2241 m_wallet_descriptor.range_end = new_range_end;
2255 std::vector<WalletDestination> result;
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");
2268 result.push_back({dest, std::nullopt});
2269 m_wallet_descriptor.next_index++;
2273 WalletLogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
2285 throw std::runtime_error(std::string(__func__) +
": writing descriptor private key failed");
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()) {
2305 std::vector<unsigned char> crypted_secret;
2308 return EncryptSecret(encryption_key, secret, pubkey.GetHash(), crypted_secret);
2313 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2316 m_map_keys[pubkey.
GetID()] = key;
2327 if (m_wallet_descriptor.descriptor) {
2335 throw std::runtime_error(std::string(__func__) +
": writing descriptor master private key failed");
2338 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2351 return m_wallet_descriptor.descriptor->IsRange();
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);
2367 return m_map_keys.size() > 0 || m_map_crypted_keys.size() > 0;
2373 return std::nullopt;
2380 return m_wallet_descriptor.range_end - m_wallet_descriptor.next_index;
2386 return m_wallet_descriptor.creation_time;
2394 auto it = m_map_script_pub_keys.find(script);
2395 if (it == m_map_script_pub_keys.end()) {
2398 int32_t index = it->second;
2408 auto it = m_map_pubkeys.find(pubkey);
2409 if (it == m_map_pubkeys.end()) {
2412 int32_t index = it->second;
2422 std::unique_ptr<FlatSigningProvider> out_keys = std::make_unique<FlatSigningProvider>();
2430 std::vector<CScript> scripts_temp;
2431 if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys))
return nullptr;
2440 m_wallet_descriptor.descriptor->ExpandPrivate(index, master_provider, *out_keys);
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);
2464 keys->Merge(std::move(*coin_keys));
2478 if (!keys->GetKey(
ToKeyID(pkhash), key)) {
2493 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
2494 const CTxIn& txin = psbtx.
tx->vin[i];
2520 std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2523 keys->Merge(std::move(*script_keys));
2526 std::vector<CPubKey> pubkeys;
2531 pubkeys.push_back(
pk);
2535 std::vector<std::vector<unsigned char>> sols;
2537 sols[0].insert(sols[0].begin(), 0x02);
2538 pubkeys.emplace_back(sols[0]);
2540 pubkeys.emplace_back(sols[0]);
2546 for (
unsigned char prefix : {0x02, 0x03}) {
2547 unsigned char b[33] = {
prefix};
2548 std::copy(pubkey.
begin(), pubkey.
end(), b + 1);
2550 fullpubkey.
Set(b, b + 33);
2551 pubkeys.push_back(fullpubkey);
2555 for (
const auto& pubkey : pubkeys) {
2558 keys->Merge(std::move(*pk_keys));
2566 if (n_signed && (signed_one || !sign)) {
2575 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
2592 if (provider->GetKeyOrigin(key_id, orig)) {
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;
2607 return m_wallet_descriptor.id;
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) {
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");
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]));
2627 m_map_script_pub_keys[script] = i;
2629 for (
const auto& pk_pair : out_keys.
pubkeys) {
2630 const CPubKey& pubkey = pk_pair.second;
2631 if (m_map_pubkeys.count(pubkey) != 0) {
2636 m_map_pubkeys[pubkey] = i;
2647 m_map_keys[key_id] = key;
2654 if (!m_map_keys.empty()) {
2658 m_map_crypted_keys[key_id] = make_pair(pubkey, crypted_key);
2665 return !m_wallet_descriptor.id.IsNull() && !desc.
id.
IsNull() && m_wallet_descriptor.id == desc.
id;
2673 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2679 return m_wallet_descriptor;
2690 std::unordered_set<CScript, SaltedSipHasher> script_pub_keys;
2691 script_pub_keys.reserve(m_map_script_pub_keys.size());
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);
2696 return script_pub_keys;
2715 return m_wallet_descriptor.descriptor->ToPrivateString(provider,
out);
2718 return m_wallet_descriptor.descriptor->ToNormalizedString(provider,
out, &m_wallet_descriptor.cache);
2729 if (m_wallet_descriptor.cache.GetCachedLastHardenedExtPubKeys().size() > 0) {
2737 std::vector<CScript> scripts_temp;
2739 if (!m_wallet_descriptor.descriptor->Expand(0, provider, scripts_temp, out_keys, &temp_cache)){
2740 throw std::runtime_error(
"Unable to expand descriptor");
2746 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2755 throw std::runtime_error(std::string(__func__) +
": " + error);
2758 m_map_pubkeys.clear();
2759 m_map_script_pub_keys.clear();
2761 m_wallet_descriptor = descriptor;
2770 error =
"can only update matching descriptor";
2774 if (descriptor.
range_start > m_wallet_descriptor.range_start ||
2775 descriptor.
range_end < m_wallet_descriptor.range_end) {
2777 error =
strprintf(
"new range must include current range = [%d,%d]",
2778 m_wallet_descriptor.range_start,
2779 m_wallet_descriptor.range_end - 1);
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
CKeyID ToKeyID(const PKHash &key_hash)
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0'/2000".
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath, bool apostrophe)
Write HD keypaths as strings.
#define Assume(val)
Assume is the identity function.
An encapsulated private key.
const std::byte * end() const
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
CPubKey GetPubKey() const
Compute the public key from a private key.
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
const std::byte * begin() const
A reference to a CKey: the Hash160 of its serialized public key.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
uint256 GetHash() const
Get the 256-bit hash of this public key.
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Serialized script, used inside transaction inputs and outputs.
bool IsPayToScriptHash() const
bool IsWitnessProgram(int &version, std::vector< unsigned char > &program) const
A reference to a CScript: the Hash160 of its serialization.
An input of a transaction.
Cache for single descriptor's derived extended pubkeys.
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
const unsigned char * end() const
constexpr bool IsNull() const
constexpr unsigned char * begin()
iterator insert(iterator pos, const T &value)
uint32_t nInternalChainCounter
static const int VERSION_HD_BASE
uint32_t nExternalChainCounter
int64_t m_next_external_index
static const int VERSION_HD_CHAIN_SPLIT
CKeyID seed_id
seed hash160
int64_t m_next_internal_index
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,...
void UpgradeDescriptorCache()
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
int32_t GetEndRange() 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 HavePrivateKeys() 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)
int32_t m_max_cached_index
RecursiveMutex cs_desc_man
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.
bool IsHDEnabled() const override
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
uint256 GetID() const 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 CanGenerateKeys() const
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
size_t KeypoolCountExternalKeys() const
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.
CPubKey GenerateNewSeed()
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.
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
bool TxnBegin()
Begin a new transaction.
bool TxnCommit()
Commit current transaction.
bool EraseRecords(const std::unordered_set< std::string > &types)
Delete records of the given types.
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, const bool overwrite)
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
bool ReadPool(int64_t nPool, CKeyPool &keypool)
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
bool WriteCryptedDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const std::vector< unsigned char > &secret)
bool WritePool(int64_t nPool, const CKeyPool &keypool)
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
bool ErasePool(int64_t nPool)
bool EraseWatchOnly(const CScript &script)
Descriptor with some wallet metadata.
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.
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
@ WITNESS_V0
Witness v0 (P2WPKH and P2WSH); see BIP 141.
CKey GenerateRandomKey(bool compressed) noexcept
std::string EncodeDestination(const CTxDestination &dest)
std::string EncodeExtPubKey(const CExtPubKey &key)
@ PRIVATE_KEY_NOT_AVAILABLE
const std::unordered_set< std::string > LEGACY_TYPES
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
bool DecryptKey(const CKeyingMaterial &vMasterKey, const std::vector< unsigned char > &vchCryptedSecret, const CPubKey &vchPubKey, CKey &key)
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.
static bool ExtractPubKey(const CScript &dest, CPubKey &pubKeyOut)
@ FEATURE_PRE_SPLIT_KEYPOOL
bool EncryptSecret(const CKeyingMaterial &vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256 &nIV, std::vector< unsigned char > &vchCiphertext)
bool IsFeatureSupported(int wallet_version, int feature_version)
@ WALLET_FLAG_LAST_HARDENED_XPUB_CACHED
@ WALLET_FLAG_KEY_ORIGIN_METADATA
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
@ WALLET_FLAG_BLANK_WALLET
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses,...
WalletDescriptor GenerateWalletDescriptor(const CExtPubKey &master_key, const OutputType &addr_type, bool internal)
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
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.
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed by checking for non-null finalized fields.
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.
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
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
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.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
@ WITNESS_UNKNOWN
Only for Witness versions not already defined above.
@ NULL_DATA
unspendable OP_RETURN script that carries data
unsigned char * UCharCast(char *c)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
CExtPubKey Neuter() const
bool Derive(CExtKey &out, unsigned int nChild) const
void SetSeed(Span< const std::byte > seed)
A mutable version of CTransaction.
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.
std::vector< uint32_t > path
A version of CTransaction with the PSBT format.
std::vector< PSBTInput > inputs
std::optional< CMutableTransaction > tx
std::map< CKeyID, SigPair > signatures
BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a ...
struct containing information needed for migrating legacy wallets to descriptor wallets
bilingual_str _(const char *psz)
Translation function.
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.