34 return util::Error{
_(
"Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
46 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
52typedef std::vector<unsigned char>
valtype;
62enum class IsMineSigVersion
74enum class IsMineResult
82bool PermitsUncompressed(IsMineSigVersion sigversion)
84 return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
87bool HaveKeys(
const std::vector<valtype>& pubkeys,
const LegacyDataSPKM& keystore)
89 for (
const valtype& pubkey : pubkeys) {
91 if (!keystore.
HaveKey(keyID))
return false;
105IsMineResult IsMineInner(
const LegacyDataSPKM& keystore,
const CScript& scriptPubKey, IsMineSigVersion sigversion,
bool recurse_scripthash=
true)
107 IsMineResult
ret = IsMineResult::NO;
109 std::vector<valtype> vSolutions;
122 if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
123 return IsMineResult::INVALID;
126 ret = std::max(
ret, IsMineResult::SPENDABLE);
131 if (sigversion == IsMineSigVersion::WITNESS_V0) {
133 return IsMineResult::INVALID;
146 if (!PermitsUncompressed(sigversion)) {
149 return IsMineResult::INVALID;
153 ret = std::max(
ret, IsMineResult::SPENDABLE);
158 if (sigversion != IsMineSigVersion::TOP) {
160 return IsMineResult::INVALID;
164 if (keystore.
GetCScript(scriptID, subscript)) {
165 ret = std::max(
ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::P2SH) : IsMineResult::SPENDABLE);
171 if (sigversion == IsMineSigVersion::WITNESS_V0) {
173 return IsMineResult::INVALID;
180 if (keystore.
GetCScript(scriptID, subscript)) {
181 ret = std::max(
ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::WITNESS_V0) : IsMineResult::SPENDABLE);
189 if (sigversion == IsMineSigVersion::TOP) {
198 std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
199 if (!PermitsUncompressed(sigversion)) {
200 for (
size_t i = 0; i < keys.size(); i++) {
201 if (keys[i].size() != 33) {
202 return IsMineResult::INVALID;
206 if (HaveKeys(keys, keystore)) {
207 ret = std::max(
ret, IsMineResult::SPENDABLE);
214 ret = std::max(
ret, IsMineResult::WATCH_ONLY);
223 switch (IsMineInner(*
this,
script, IsMineSigVersion::TOP)) {
224 case IsMineResult::INVALID:
225 case IsMineResult::NO:
227 case IsMineResult::WATCH_ONLY:
229 case IsMineResult::SPENDABLE:
241 bool keyPass = mapCryptedKeys.empty();
242 bool keyFail =
false;
243 CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
245 for (; mi != mapCryptedKeys.end(); ++mi)
247 const CPubKey &vchPubKey = (*mi).second.first;
248 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
250 if (!
DecryptKey(master_key, vchCryptedSecret, vchPubKey, key))
263 if (keyPass && keyFail)
265 LogPrintf(
"The wallet is probably corrupted: Some keys decrypt but not all.\n");
266 throw std::runtime_error(
"Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
268 if (keyFail || !keyPass)
278 encrypted_batch = batch;
279 if (!mapCryptedKeys.empty()) {
280 encrypted_batch =
nullptr;
285 keys_to_encrypt.swap(mapKeys);
286 for (
const KeyMap::value_type& mKey : keys_to_encrypt)
288 const CKey &key = mKey.second;
291 std::vector<unsigned char> vchCryptedSecret;
293 encrypted_batch =
nullptr;
297 encrypted_batch =
nullptr;
301 encrypted_batch =
nullptr;
308 return util::Error{
_(
"Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
314 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
321 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
352 std::vector<WalletDestination> result;
357 WalletLogPrintf(
"%s: Detected a used keypool key, mark all keypool keys up to this key as used\n", __func__);
362 result.push_back({dest, keypool.fInternal});
367 WalletLogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
373 auto it = mapKeyMetadata.find(keyid);
374 if (it != mapKeyMetadata.end()){
377 std::vector<uint32_t> path;
381 WalletLogPrintf(
"%s: Adding inactive seed keys failed, invalid hdKeypath: %s\n",
385 if (path.size() != 3) {
386 WalletLogPrintf(
"%s: Adding inactive seed keys failed, invalid path size: %d, has_key_origin: %s\n",
391 bool internal = (path[1] & ~BIP32_HARDENED_KEY_LIMIT) != 0;
392 int64_t index = path[2] & ~BIP32_HARDENED_KEY_LIMIT;
413 for (
auto& meta_pair : mapKeyMetadata) {
424 throw std::runtime_error(
"Invalid stored hdKeypath");
433 if (
GetPubKey(meta_pair.first, pubkey)) {
434 batch->WriteKeyMetadata(meta, pubkey,
true);
462 bool keypool_has_keys;
464 keypool_has_keys = setInternalKeyPool.size() > 0;
469 if (!keypool_has_keys) {
472 return keypool_has_keys;
484 bool hd_upgrade =
false;
485 bool split_upgrade =
false;
504 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
515 error =
_(
"Unable to generate keys");
525 return !mapKeys.empty() || !mapCryptedKeys.empty();
531 return !mapCryptedKeys.empty();
537 setInternalKeyPool.clear();
538 setExternalKeyPool.clear();
546 if (setKeyPool.empty()) {
551 int64_t nIndex = *(setKeyPool.begin());
552 if (!batch.
ReadPool(nIndex, keypool)) {
553 throw std::runtime_error(std::string(__func__) +
": read oldest key in keypool failed");
556 return keypool.
nTime;
569 if (!set_pre_split_keypool.empty()) {
580 return setExternalKeyPool.size() + set_pre_split_keypool.size();
586 return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
592 return nTimeFirstKey;
597 return std::make_unique<LegacySigningProvider>(*
this);
602 IsMineResult ismine = IsMineInner(*
this,
script, IsMineSigVersion::TOP,
false);
603 if (ismine == IsMineResult::SPENDABLE || ismine == IsMineResult::WATCH_ONLY) {
613 bool has_privkeys =
false;
614 for (
const auto& key_sig_pair : sigdata.
signatures) {
615 has_privkeys |=
HaveKey(key_sig_pair.first);
646 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
647 const CTxIn& txin = psbtx.
tx->vin[i];
656 return PSBTError::SIGHASH_MISMATCH;
662 return PSBTError::MISSING_INPUTS;
671 if (n_signed && (signed_one || !
sign)) {
680 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
693 auto it = mapKeyMetadata.find(key_id);
694 if (it != mapKeyMetadata.end()) {
695 return std::make_unique<CKeyMetadata>(it->second);
700 auto it = m_script_metadata.find(
CScriptID(scriptPubKey));
701 if (it != m_script_metadata.end()) {
702 return std::make_unique<CKeyMetadata>(it->second);
720 if (nCreateTime <= 1) {
724 }
else if (nTimeFirstKey ==
UNKNOWN_TIME || nCreateTime < nTimeFirstKey) {
725 nTimeFirstKey = nCreateTime;
753 bool needsDB = !encrypted_batch;
755 encrypted_batch = &batch;
758 if (needsDB) encrypted_batch =
nullptr;
761 if (needsDB) encrypted_batch =
nullptr;
778 mapKeyMetadata[pubkey.
GetID()]);
791 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);
801 mapKeyMetadata[keyID] = meta;
814 m_script_metadata[script_id] = meta;
841 std::vector<unsigned char> vchCryptedSecret;
844 return EncryptSecret(encryption_key, vchSecret, pubkey.GetHash(), vchCryptedSecret);
858 if (!checksum_valid) {
870 mapCryptedKeys[vchPubKey.
GetID()] = make_pair(vchPubKey, vchCryptedSecret);
876 const std::vector<unsigned char> &vchCryptedSecret)
883 return encrypted_batch->WriteCryptedKey(vchPubKey,
885 mapKeyMetadata[vchPubKey.
GetID()]);
889 mapKeyMetadata[vchPubKey.
GetID()]);
896 return setWatchOnly.count(dest) > 0;
902 return (!setWatchOnly.empty());
907 std::vector<std::vector<unsigned char>> solutions;
909 (pubKeyOut =
CPubKey(solutions[0])).IsFullyValid();
916 setWatchOnly.erase(dest);
919 mapWatchKeys.erase(pubKey.
GetID());
941 setWatchOnly.insert(dest);
944 mapWatchKeys[pubKey.
GetID()] = pubKey;
966 m_script_metadata[
CScriptID(dest)].nCreateTime = create_time;
978 m_script_metadata[
CScriptID(dest)].nCreateTime = nCreateTime;
993 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
1016 return mapCryptedKeys.count(address) > 0;
1026 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1027 if (mi != mapCryptedKeys.end())
1029 const CPubKey &vchPubKey = (*mi).second.first;
1030 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
1032 return DecryptKey(encryption_key, vchCryptedSecret, vchPubKey, keyOut);
1043 auto it = mapKeyMetadata.find(keyID);
1044 if (it == mapKeyMetadata.end()) {
1061 WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
1062 if (it != mapWatchKeys.end()) {
1063 pubkey_out = it->second;
1079 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1080 if (mi != mapCryptedKeys.end())
1082 vchPubKeyOut = (*mi).second.first;
1099 int64_t nCreationTime =
GetTime();
1117 mapKeyMetadata[pubkey.
GetID()] = metadata;
1121 throw std::runtime_error(std::string(__func__) +
": AddKey failed");
1128 if (!key_in.
Derive(key_out, index)) {
1129 throw std::runtime_error(
"Could not derive extended key");
1144 throw std::runtime_error(std::string(__func__) +
": seed not found");
1178 secret = childKey.
key;
1185 throw std::runtime_error(std::string(__func__) +
": writing HD chain model failed");
1192 set_pre_split_keypool.insert(nIndex);
1194 setInternalKeyPool.insert(nIndex);
1196 setExternalKeyPool.insert(nIndex);
1198 m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
1205 if (mapKeyMetadata.count(keyid) == 0)
1225 int64_t nCreationTime =
GetTime();
1241 mapKeyMetadata[seed.
GetID()] = metadata;
1245 throw std::runtime_error(std::string(__func__) +
": AddKeyPubKey failed");
1279 for (
const int64_t nIndex : setInternalKeyPool) {
1282 setInternalKeyPool.clear();
1284 for (
const int64_t nIndex : setExternalKeyPool) {
1287 setExternalKeyPool.clear();
1289 for (
const int64_t nIndex : set_pre_split_keypool) {
1292 set_pre_split_keypool.clear();
1299 WalletLogPrintf(
"LegacyScriptPubKeyMan::NewKeyPool rewrote keypool\n");
1311 if (!batch.
TxnBegin())
return false;
1335 unsigned int nTargetSize;
1337 nTargetSize = kpSize;
1339 nTargetSize = m_keypool_size;
1341 int64_t target = std::max((int64_t) nTargetSize, int64_t{1});
1345 int64_t missingExternal;
1346 int64_t missingInternal;
1348 missingExternal = std::max(target - (int64_t)setExternalKeyPool.size(), int64_t{0});
1349 missingInternal = std::max(target - (int64_t)setInternalKeyPool.size(), int64_t{0});
1357 missingInternal = 0;
1359 bool internal =
false;
1360 for (int64_t i = missingInternal + missingExternal; i--;) {
1361 if (i < missingInternal) {
1370 if (missingInternal + missingExternal > 0) {
1372 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());
1374 WalletLogPrintf(
"inactive seed with id %s added %d external keys, %d internal keys\n",
HexStr(chain.
seed_id), missingExternal, missingInternal);
1383 assert(m_max_keypool_index < std::numeric_limits<int64_t>::max());
1384 int64_t index = ++m_max_keypool_index;
1386 throw std::runtime_error(std::string(__func__) +
": writing imported pubkey failed");
1389 setInternalKeyPool.insert(index);
1391 setExternalKeyPool.insert(index);
1416 setInternalKeyPool.insert(nIndex);
1417 }
else if (!set_pre_split_keypool.empty()) {
1418 set_pre_split_keypool.insert(nIndex);
1420 setExternalKeyPool.insert(nIndex);
1460 bool fReturningInternal = fRequestedInternal;
1462 bool use_split_keypool = set_pre_split_keypool.empty();
1463 std::set<int64_t>& setKeyPool = use_split_keypool ? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) : set_pre_split_keypool;
1466 if (setKeyPool.empty()) {
1472 auto it = setKeyPool.begin();
1474 setKeyPool.erase(it);
1475 if (!batch.
ReadPool(nIndex, keypool)) {
1476 throw std::runtime_error(std::string(__func__) +
": read failed");
1480 throw std::runtime_error(std::string(__func__) +
": unknown key in key pool");
1483 if (use_split_keypool && keypool.
fInternal != fReturningInternal) {
1484 throw std::runtime_error(std::string(__func__) +
": keypool entry misclassified");
1487 throw std::runtime_error(std::string(__func__) +
": keypool entry invalid");
1507 assert(desc && desc->IsSolvable());
1521 bool internal = setInternalKeyPool.count(keypool_id);
1522 if (!internal)
assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id));
1523 std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
1524 auto it = setKeyPool->begin();
1526 std::vector<CKeyPool> result;
1528 while (it != std::end(*setKeyPool)) {
1529 const int64_t& index = *(it);
1530 if (index > keypool_id)
break;
1533 if (batch.
ReadPool(index, keypool)) {
1539 it = setKeyPool->erase(it);
1540 result.push_back(std::move(keypool));
1548 std::vector<CScript> dummy;
1551 std::vector<CKeyID>
ret;
1552 ret.reserve(
out.pubkeys.size());
1553 for (
const auto& entry :
out.pubkeys) {
1554 ret.push_back(entry.first);
1562 for (
auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) {
1563 int64_t index = *it;
1565 if (!batch.
ReadPool(index, keypool)) {
1566 throw std::runtime_error(std::string(__func__) +
": read keypool entry failed");
1570 throw std::runtime_error(std::string(__func__) +
": writing modified keypool entry failed");
1572 set_pre_split_keypool.insert(index);
1573 it = setExternalKeyPool.erase(it);
1598 mapKeyMetadata[pubkey.
GetID()].key_origin.path = info.
path;
1599 mapKeyMetadata[pubkey.
GetID()].has_key_origin =
true;
1607 for (
const auto& entry : scripts) {
1617 if (timestamp > 0) {
1618 m_script_metadata[
CScriptID(entry)].nCreateTime = timestamp;
1621 if (timestamp > 0) {
1631 for (
const auto& entry : privkey_map) {
1632 const CKey& key = entry.second;
1634 const CKeyID&
id = entry.first;
1641 mapKeyMetadata[id].nCreateTime = timestamp;
1651bool LegacyScriptPubKeyMan::ImportPubKeys(
const std::vector<std::pair<CKeyID, bool>>& ordered_pubkeys,
const std::map<CKeyID, CPubKey>& pubkey_map,
const std::map<
CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins,
const bool add_keypool,
const int64_t timestamp)
1654 for (
const auto& entry : key_origins) {
1657 for (
const auto& [
id, internal] : ordered_pubkeys) {
1658 auto entry = pubkey_map.find(
id);
1659 if (entry == pubkey_map.end()) {
1662 const CPubKey& pubkey = entry->second;
1672 mapKeyMetadata[id].nCreateTime = timestamp;
1702 std::set<CKeyID> set_address;
1703 for (
const auto& mi : mapCryptedKeys) {
1704 set_address.insert(mi.first);
1712 std::unordered_set<CScript, SaltedSipHasher> spks;
1715 for (
const auto& key_pair : mapKeys) {
1716 const CPubKey& pub = key_pair.second.GetPubKey();
1720 for (
const auto& key_pair : mapCryptedKeys) {
1721 const CPubKey& pub = key_pair.second.first;
1729 for (
const auto& script_pair : mapScripts) {
1733 if (!
script.IsPayToScriptHash()) {
1738 std::vector<unsigned char> witprog;
1739 if (
script.IsWitnessProgram(wit_ver, witprog) && wit_ver == 0) {
1745 std::vector<std::vector<unsigned char>> sols;
1750 spks.insert(ms_spk);
1770 std::unordered_set<CScript, SaltedSipHasher> spks;
1781 return std::nullopt;
1789 std::set<CKeyID> keyids;
1790 for (
const auto& key_pair : mapKeys) {
1791 keyids.insert(key_pair.first);
1793 for (
const auto& key_pair : mapCryptedKeys) {
1794 keyids.insert(key_pair.first);
1799 for (
auto keyid_it = keyids.begin(); keyid_it != keyids.end();) {
1800 const CKeyID& keyid = *keyid_it;
1801 const auto& it = mapKeyMetadata.find(keyid);
1802 if (it != mapKeyMetadata.end()) {
1809 keyid_it = keyids.erase(keyid_it);
1818 LogPrintf(
"Error generating descriptors for migration, cannot initialize db transaction\n");
1819 return std::nullopt;
1823 for (
const CKeyID& keyid : keyids) {
1825 if (!
GetKey(keyid, key)) {
1830 uint64_t creation_time = 0;
1831 const auto& it = mapKeyMetadata.find(keyid);
1832 if (it != mapKeyMetadata.end()) {
1833 creation_time = it->second.nCreateTime;
1843 std::string desc_str =
"combo(" + origin_str +
HexStr(key.
GetPubKey()) +
")";
1846 std::vector<std::unique_ptr<Descriptor>> descs =
Parse(desc_str, keys, error,
false);
1851 auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(
m_storage, w_desc, 0);
1852 WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, key, key.
GetPubKey()));
1853 desc_spk_man->TopUpWithDB(batch);
1854 auto desc_spks = desc_spk_man->GetScriptPubKeys();
1857 for (
const CScript& spk : desc_spks) {
1858 size_t erased = spks.erase(spk);
1863 out.desc_spkms.push_back(std::move(desc_spk_man));
1867 std::vector<CHDChain> chains;
1870 chains.push_back(chain_pair.second);
1872 for (
const CHDChain& chain : chains) {
1873 for (
int i = 0; i < 2; ++i) {
1880 if (!
GetKey(chain.seed_id, seed_key)) {
1888 std::string desc_str =
"combo(" + xpub +
"/0h/" +
ToString(i) +
"h/*h)";
1891 std::vector<std::unique_ptr<Descriptor>> descs =
Parse(desc_str, keys, error,
false);
1893 uint32_t chain_counter = std::max((i == 1 ? chain.nInternalChainCounter : chain.nExternalChainCounter), (uint32_t)0);
1897 auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(
m_storage, w_desc, 0);
1898 WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, master_key.
key, master_key.
key.
GetPubKey()));
1899 desc_spk_man->TopUpWithDB(batch);
1900 auto desc_spks = desc_spk_man->GetScriptPubKeys();
1903 for (
const CScript& spk : desc_spks) {
1904 size_t erased = spks.erase(spk);
1909 out.desc_spkms.push_back(std::move(desc_spk_man));
1918 out.master_key.SetSeed(seed_key);
1922 for (
auto it = spks.begin(); it != spks.end();) {
1926 uint64_t creation_time = 0;
1927 const auto& mit = m_script_metadata.find(
CScriptID(spk));
1928 if (mit != m_script_metadata.end()) {
1929 creation_time = mit->second.nCreateTime;
1935 std::vector<CScript> scripts;
1940 std::set<CKeyID> privkeyids;
1941 for (
const auto& key_orig_pair : keys.
origins) {
1942 privkeyids.insert(key_orig_pair.first);
1945 std::vector<CScript> desc_spks;
1948 std::string desc_str;
1949 bool watchonly = !desc->ToPrivateString(*
this, desc_str);
1951 out.watch_descs.emplace_back(desc->ToString(), creation_time);
1955 desc->Expand(0, provider, desc_spks, provider);
1959 auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(
m_storage, w_desc, 0);
1960 for (
const auto& keyid : privkeyids) {
1962 if (!
GetKey(keyid, key)) {
1965 WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, key, key.
GetPubKey()));
1967 desc_spk_man->TopUpWithDB(batch);
1968 auto desc_spks_set = desc_spk_man->GetScriptPubKeys();
1969 desc_spks.insert(desc_spks.end(), desc_spks_set.begin(), desc_spks_set.end());
1971 out.desc_spkms.push_back(std::move(desc_spk_man));
1975 for (
const CScript& desc_spk : desc_spks) {
1976 auto del_it = spks.find(desc_spk);
1977 assert(del_it != spks.end());
1979 it = spks.erase(del_it);
1985 for (
const auto& script_pair : mapScripts) {
1989 uint64_t creation_time = 0;
1991 if (it != m_script_metadata.end()) {
1992 creation_time = it->second.nCreateTime;
1995 std::vector<std::vector<unsigned char>> sols;
2011 std::vector<std::vector<unsigned char>> keys(sols.begin() + 1, sols.begin() + sols.size() - 1);
2020 out.solvable_descs.emplace_back(sh_desc->ToString(), creation_time);
2023 if (desc->IsSolvable()) {
2025 out.solvable_descs.emplace_back(wsh_desc->ToString(), creation_time);
2027 out.solvable_descs.emplace_back(sh_wsh_desc->ToString(), creation_time);
2033 assert(spks.size() == 0);
2037 LogPrintf(
"Error generating descriptors for migration, cannot commit db transaction\n");
2038 return std::nullopt;
2047 return DeleteRecordsWithDB(batch);
2065 assert(m_wallet_descriptor.descriptor->IsSingleType());
2066 std::optional<OutputType> desc_addr_type = m_wallet_descriptor.descriptor->GetOutputType();
2068 if (type != *desc_addr_type) {
2069 throw std::runtime_error(std::string(__func__) +
": Types are inconsistent. Stored type does not match type of newly generated address");
2076 std::vector<CScript> scripts_temp;
2079 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2081 if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2083 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2088 return util::Error{
_(
"Error: Cannot extract destination from the generated scriptpubkey")};
2090 m_wallet_descriptor.next_index++;
2099 if (m_map_script_pub_keys.count(
script) > 0) {
2108 if (!m_map_keys.empty()) {
2112 bool keyPass = m_map_crypted_keys.empty();
2113 bool keyFail =
false;
2114 for (
const auto& mi : m_map_crypted_keys) {
2115 const CPubKey &pubkey = mi.second.first;
2116 const std::vector<unsigned char> &crypted_secret = mi.second.second;
2118 if (!
DecryptKey(master_key, crypted_secret, pubkey, key)) {
2126 if (keyPass && keyFail) {
2127 LogPrintf(
"The wallet is probably corrupted: Some keys decrypt but not all.\n");
2128 throw std::runtime_error(
"Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
2130 if (keyFail || !keyPass) {
2140 if (!m_map_crypted_keys.empty()) {
2144 for (
const KeyMap::value_type& key_in : m_map_keys)
2146 const CKey &key = key_in.second;
2149 std::vector<unsigned char> crypted_secret;
2153 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2164 index = m_wallet_descriptor.next_index - 1;
2172 if (m_wallet_descriptor.next_index - 1 == index) {
2173 m_wallet_descriptor.next_index--;
2184 for (
const auto& key_pair : m_map_crypted_keys) {
2185 const CPubKey& pubkey = key_pair.second.first;
2186 const std::vector<unsigned char>& crypted_secret = key_pair.second.second;
2189 return DecryptKey(encryption_key, crypted_secret, pubkey, key);
2191 keys[pubkey.
GetID()] = key;
2201 return m_map_keys.contains(keyid) || m_map_crypted_keys.contains(keyid);
2208 const auto& it = m_map_crypted_keys.find(keyid);
2209 if (it == m_map_crypted_keys.end()) {
2210 return std::nullopt;
2212 const std::vector<unsigned char>& crypted_secret = it->second.second;
2215 return DecryptKey(encryption_key, crypted_secret, it->second.first, key);
2217 return std::nullopt;
2221 const auto& it = m_map_keys.find(keyid);
2222 if (it == m_map_keys.end()) {
2223 return std::nullopt;
2231 if (!batch.
TxnBegin())
return false;
2240 std::set<CScript> new_spks;
2241 unsigned int target_size;
2245 target_size = m_keypool_size;
2249 int32_t new_range_end = std::max(m_wallet_descriptor.next_index + (int32_t)target_size, m_wallet_descriptor.range_end);
2252 if (!m_wallet_descriptor.descriptor->IsRange()) {
2254 m_wallet_descriptor.range_end = 1;
2255 m_wallet_descriptor.range_start = 0;
2264 std::vector<CScript> scripts_temp;
2267 if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2268 if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache))
return false;
2271 new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2273 m_map_script_pub_keys[
script] = i;
2275 for (
const auto& pk_pair : out_keys.
pubkeys) {
2276 const CPubKey& pubkey = pk_pair.second;
2277 if (m_map_pubkeys.count(pubkey) != 0) {
2282 m_map_pubkeys[pubkey] = i;
2287 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2291 m_wallet_descriptor.range_end = new_range_end;
2305 std::vector<WalletDestination> result;
2307 int32_t index = m_map_script_pub_keys[
script];
2308 if (index >= m_wallet_descriptor.next_index) {
2309 WalletLogPrintf(
"%s: Detected a used keypool item at index %d, mark all keypool items up to this item as used\n", __func__, index);
2310 auto out_keys = std::make_unique<FlatSigningProvider>();
2311 std::vector<CScript> scripts_temp;
2312 while (index >= m_wallet_descriptor.next_index) {
2313 if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) {
2314 throw std::runtime_error(std::string(__func__) +
": Unable to expand descriptor from cache");
2318 result.push_back({dest, std::nullopt});
2319 m_wallet_descriptor.next_index++;
2323 WalletLogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
2335 throw std::runtime_error(std::string(__func__) +
": writing descriptor private key failed");
2345 if (m_map_keys.find(pubkey.
GetID()) != m_map_keys.end() ||
2346 m_map_crypted_keys.find(pubkey.
GetID()) != m_map_crypted_keys.end()) {
2355 std::vector<unsigned char> crypted_secret;
2358 return EncryptSecret(encryption_key, secret, pubkey.GetHash(), crypted_secret);
2363 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2366 m_map_keys[pubkey.
GetID()] = key;
2377 if (m_wallet_descriptor.descriptor) {
2385 throw std::runtime_error(std::string(__func__) +
": writing descriptor master private key failed");
2388 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2401 return m_wallet_descriptor.descriptor->IsRange();
2409 return m_wallet_descriptor.descriptor->IsSingleType() &&
2410 m_wallet_descriptor.descriptor->IsRange() &&
2411 (
HavePrivateKeys() || m_wallet_descriptor.next_index < m_wallet_descriptor.range_end);
2417 return m_map_keys.size() > 0 || m_map_crypted_keys.size() > 0;
2423 return !m_map_crypted_keys.empty();
2429 return std::nullopt;
2436 return m_wallet_descriptor.range_end - m_wallet_descriptor.next_index;
2442 return m_wallet_descriptor.creation_time;
2450 auto it = m_map_script_pub_keys.find(
script);
2451 if (it == m_map_script_pub_keys.end()) {
2454 int32_t index = it->second;
2464 auto it = m_map_pubkeys.find(pubkey);
2465 if (it == m_map_pubkeys.end()) {
2468 int32_t index = it->second;
2472 if (!
out->HaveKey(pubkey.
GetID())) {
2482 std::unique_ptr<FlatSigningProvider> out_keys = std::make_unique<FlatSigningProvider>();
2490 std::vector<CScript> scripts_temp;
2491 if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys))
return nullptr;
2500 m_wallet_descriptor.descriptor->ExpandPrivate(index, master_provider, *out_keys);
2518 std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2519 for (
const auto& coin_pair : coins) {
2520 std::unique_ptr<FlatSigningProvider> coin_keys =
GetSigningProvider(coin_pair.second.out.scriptPubKey,
true);
2524 keys->Merge(std::move(*coin_keys));
2538 if (!keys->GetKey(
ToKeyID(pkhash), key)) {
2553 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
2554 const CTxIn& txin = psbtx.
tx->vin[i];
2563 return PSBTError::SIGHASH_MISMATCH;
2572 return PSBTError::MISSING_INPUTS;
2580 std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2583 keys->Merge(std::move(*script_keys));
2586 std::vector<CPubKey> pubkeys;
2591 pubkeys.push_back(
pk);
2595 std::vector<std::vector<unsigned char>> sols;
2597 sols[0].insert(sols[0].begin(), 0x02);
2598 pubkeys.emplace_back(sols[0]);
2600 pubkeys.emplace_back(sols[0]);
2606 for (
unsigned char prefix : {0x02, 0x03}) {
2607 unsigned char b[33] = {
prefix};
2608 std::copy(pubkey.
begin(), pubkey.
end(), b + 1);
2610 fullpubkey.
Set(b, b + 33);
2611 pubkeys.push_back(fullpubkey);
2615 for (
const auto& pubkey : pubkeys) {
2618 keys->Merge(std::move(*pk_keys));
2626 if (n_signed && (signed_one || !
sign)) {
2635 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
2652 if (provider->GetKeyOrigin(key_id, orig)) {
2654 std::unique_ptr<CKeyMetadata> meta = std::make_unique<CKeyMetadata>();
2655 meta->key_origin = orig;
2656 meta->has_key_origin =
true;
2657 meta->nCreateTime = m_wallet_descriptor.creation_time;
2667 return m_wallet_descriptor.id;
2673 std::set<CScript> new_spks;
2674 m_wallet_descriptor.cache = cache;
2675 for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
2677 std::vector<CScript> scripts_temp;
2678 if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2679 throw std::runtime_error(
"Error: Unable to expand wallet descriptor from cache");
2682 new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2684 if (m_map_script_pub_keys.count(
script) != 0) {
2685 throw std::runtime_error(
strprintf(
"Error: Already loaded script at index %d as being at index %d", i, m_map_script_pub_keys[
script]));
2687 m_map_script_pub_keys[
script] = i;
2689 for (
const auto& pk_pair : out_keys.
pubkeys) {
2690 const CPubKey& pubkey = pk_pair.second;
2691 if (m_map_pubkeys.count(pubkey) != 0) {
2696 m_map_pubkeys[pubkey] = i;
2707 m_map_keys[key_id] = key;
2714 if (!m_map_keys.empty()) {
2718 m_map_crypted_keys[key_id] = make_pair(pubkey, crypted_key);
2725 return !m_wallet_descriptor.id.IsNull() && !desc.
id.
IsNull() && m_wallet_descriptor.id == desc.
id;
2733 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2739 return m_wallet_descriptor;
2750 std::unordered_set<CScript, SaltedSipHasher> script_pub_keys;
2751 script_pub_keys.reserve(m_map_script_pub_keys.size());
2753 for (
auto const& [script_pub_key, index] : m_map_script_pub_keys) {
2754 if (index >= minimum_index) script_pub_keys.insert(script_pub_key);
2756 return script_pub_keys;
2775 return m_wallet_descriptor.descriptor->ToPrivateString(provider,
out);
2778 return m_wallet_descriptor.descriptor->ToNormalizedString(provider,
out, &m_wallet_descriptor.cache);
2789 if (m_wallet_descriptor.cache.GetCachedLastHardenedExtPubKeys().size() > 0) {
2797 std::vector<CScript> scripts_temp;
2799 if (!m_wallet_descriptor.descriptor->Expand(0, provider, scripts_temp, out_keys, &temp_cache)){
2800 throw std::runtime_error(
"Unable to expand descriptor");
2806 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2815 throw std::runtime_error(std::string(__func__) +
": " + error);
2818 m_map_pubkeys.clear();
2819 m_map_script_pub_keys.clear();
2821 m_wallet_descriptor = descriptor;
2830 error =
"can only update matching descriptor";
2834 if (descriptor.
range_start > m_wallet_descriptor.range_start ||
2835 descriptor.
range_end < m_wallet_descriptor.range_end) {
2837 error =
strprintf(
"new range must include current range = [%d,%d]",
2838 m_wallet_descriptor.range_start,
2839 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, PayToAnchor, 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 CHECK_NONFATAL(condition)
Identity function.
#define Assume(val)
Assume is the identity function.
An encapsulated private key.
const std::byte * begin() 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.
const std::byte * end() const
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
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.
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 * end() const
const unsigned char * begin() const
constexpr bool IsNull() const
constexpr unsigned char * begin()
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)
std::optional< common::PSBTError > 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.
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
bool HaveCryptedKeys() const override
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
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 DeleteRecordsWithDB(WalletBatch &batch)
isminetype IsMine(const CScript &script) const override
std::optional< MigrationData > MigrateToDescriptor()
Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this Legac...
virtual bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey)
bool DeleteRecords()
Delete all the records of this LegacyScriptPubKeyMan from disk.
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
virtual void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
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)
void AddInactiveHDChain(const CHDChain &chain)
bool HaveWatchOnly(const CScript &dest) const
Returns whether the watch-only script is in the wallet.
bool HaveWatchOnly() const
Returns whether there are any watch-only things in the wallet.
bool fDecryptionThoroughlyChecked
keeps track of whether Unlock has run a thorough check before
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
std::map< CKeyID, int64_t > m_pool_key_to_index
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
std::unordered_set< CScript, SaltedSipHasher > GetNotMineScriptPubKeys() const
Retrieves scripts that were imported by bugs into the legacy spkm and are simply invalid,...
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
bool AddWatchOnlyInMem(const CScript &dest)
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
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 GetKey(const CKeyID &address, CKey &keyOut) const override
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
virtual void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
std::unordered_map< CKeyID, CHDChain, SaltedSipHasher > m_inactive_hd_chains
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
bool HaveKey(const CKeyID &address) const override
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
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.
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata) override
bool CanGenerateKeys() const
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
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
void AddHDChain(const CHDChain &chain)
bool AddCScriptWithDB(WalletBatch &batch, const CScript &script)
Adds a script to the store and saves it to disk.
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 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 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
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...
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata) override
Load metadata (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 AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey) override
bool ImportPubKeys(const std::vector< std::pair< CKeyID, bool > > &ordered_pubkeys, const std::map< CKeyID, CPubKey > &pubkey_map, const std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > &key_origins, const bool add_keypool, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
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,...
std::set< CKeyID > GetKeys() const override
bool HaveCryptedKeys() const override
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 AddCScript(const CScript &redeemScript) override
int64_t GetTimeFirstKey() const override
std::optional< common::PSBTError > 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 NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
CPubKey GenerateNewSeed()
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)
void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, CKey &secret, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
void ReturnDestination(int64_t index, bool internal, const CTxDestination &) override
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 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.
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
void WalletLogPrintf(util::ConstevalFormatString< sizeof...(Params)> wallet_fmt, const Params &... params) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
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.
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
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.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
@ 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)
static int sign(const secp256k1_context *ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
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
static bool RunWithinTxn(WalletBatch &batch, std::string_view process_desc, const std::function< bool(WalletBatch &)> &func)
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
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.
bool DecryptKey(const CKeyingMaterial &master_key, const std::span< const unsigned char > crypted_secret, const CPubKey &pub_key, CKey &key)
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)
is a home for public enum and struct type definitions that are used internally by node code,...
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).
@ PRIVATE_KEY_NOT_AVAILABLE
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.
@ ANCHOR
anyone can spend script
@ NULL_DATA
unspendable OP_RETURN script that carries data
unsigned char * UCharCast(char *c)
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
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
consteval auto _(util::TranslatedLiteral str)