29 return util::Error{
_(
"Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
41 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
47 typedef std::vector<unsigned char>
valtype;
77 bool PermitsUncompressed(IsMineSigVersion sigversion)
82 bool HaveKeys(
const std::vector<valtype>& pubkeys,
const LegacyScriptPubKeyMan& keystore)
84 for (
const valtype& pubkey : pubkeys) {
86 if (!keystore.HaveKey(keyID))
return false;
99 IsMineResult IsMineInner(
const LegacyScriptPubKeyMan& keystore,
const CScript& scriptPubKey, IsMineSigVersion sigversion,
bool recurse_scripthash=
true)
103 std::vector<valtype> vSolutions;
115 if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
116 return IsMineResult::INVALID;
118 if (keystore.HaveKey(keyID)) {
119 ret = std::max(
ret, IsMineResult::SPENDABLE);
126 return IsMineResult::INVALID;
139 if (!PermitsUncompressed(sigversion)) {
141 if (keystore.GetPubKey(keyID, pubkey) && !pubkey.
IsCompressed()) {
142 return IsMineResult::INVALID;
145 if (keystore.HaveKey(keyID)) {
146 ret = std::max(
ret, IsMineResult::SPENDABLE);
153 return IsMineResult::INVALID;
157 if (keystore.GetCScript(scriptID, subscript)) {
166 return IsMineResult::INVALID;
173 if (keystore.GetCScript(scriptID, subscript)) {
191 std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
192 if (!PermitsUncompressed(sigversion)) {
193 for (
size_t i = 0; i < keys.size(); i++) {
194 if (keys[i].size() != 33) {
195 return IsMineResult::INVALID;
199 if (HaveKeys(keys, keystore)) {
200 ret = std::max(
ret, IsMineResult::SPENDABLE);
206 if (
ret == IsMineResult::NO && keystore.HaveWatchOnly(scriptPubKey)) {
207 ret = std::max(
ret, IsMineResult::WATCH_ONLY);
217 case IsMineResult::INVALID:
218 case IsMineResult::NO:
220 case IsMineResult::WATCH_ONLY:
222 case IsMineResult::SPENDABLE:
234 bool keyPass = mapCryptedKeys.empty();
235 bool keyFail =
false;
236 CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
238 for (; mi != mapCryptedKeys.end(); ++mi)
240 const CPubKey &vchPubKey = (*mi).second.first;
241 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
243 if (!
DecryptKey(master_key, vchCryptedSecret, vchPubKey, key))
253 batch.WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.
GetID()]);
256 if (keyPass && keyFail)
258 LogPrintf(
"The wallet is probably corrupted: Some keys decrypt but not all.\n");
259 throw std::runtime_error(
"Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
261 if (keyFail || !keyPass)
271 encrypted_batch = batch;
272 if (!mapCryptedKeys.empty()) {
273 encrypted_batch =
nullptr;
278 keys_to_encrypt.swap(mapKeys);
279 for (
const KeyMap::value_type& mKey : keys_to_encrypt)
281 const CKey &key = mKey.second;
284 std::vector<unsigned char> vchCryptedSecret;
286 encrypted_batch =
nullptr;
290 encrypted_batch =
nullptr;
294 encrypted_batch =
nullptr;
301 return util::Error{
_(
"Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
307 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
314 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
345 std::vector<WalletDestination> result;
350 WalletLogPrintf(
"%s: Detected a used keypool key, mark all keypool keys up to this key as used\n", __func__);
355 result.push_back({dest, keypool.fInternal});
360 WalletLogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
366 auto it = mapKeyMetadata.find(keyid);
367 if (it != mapKeyMetadata.end()){
370 std::vector<uint32_t> path;
374 WalletLogPrintf(
"%s: Adding inactive seed keys failed, invalid hdKeypath: %s\n",
378 if (path.size() != 3) {
379 WalletLogPrintf(
"%s: Adding inactive seed keys failed, invalid path size: %d, has_key_origin: %s\n",
406 for (
auto& meta_pair : mapKeyMetadata) {
417 throw std::runtime_error(
"Invalid stored hdKeypath");
426 if (
GetPubKey(meta_pair.first, pubkey)) {
427 batch->WriteKeyMetadata(meta, pubkey,
true);
455 bool keypool_has_keys;
457 keypool_has_keys = setInternalKeyPool.size() > 0;
462 if (!keypool_has_keys) {
465 return keypool_has_keys;
477 bool hd_upgrade =
false;
478 bool split_upgrade =
false;
497 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
508 error =
_(
"Unable to generate keys");
518 return !mapKeys.empty() || !mapCryptedKeys.empty();
524 setInternalKeyPool.clear();
525 setExternalKeyPool.clear();
533 if (setKeyPool.empty()) {
538 int64_t nIndex = *(setKeyPool.begin());
539 if (!batch.
ReadPool(nIndex, keypool)) {
540 throw std::runtime_error(std::string(__func__) +
": read oldest key in keypool failed");
543 return keypool.
nTime;
556 if (!set_pre_split_keypool.empty()) {
567 return setExternalKeyPool.size() + set_pre_split_keypool.size();
573 return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
579 return nTimeFirstKey;
584 return std::make_unique<LegacySigningProvider>(*this);
590 if (ismine == IsMineResult::SPENDABLE || ismine == IsMineResult::WATCH_ONLY) {
600 bool has_privkeys =
false;
601 for (
const auto& key_sig_pair : sigdata.
signatures) {
602 has_privkeys |=
HaveKey(key_sig_pair.first);
633 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
634 const CTxIn& txin = psbtx.
tx->vin[i];
658 if (n_signed && (signed_one || !sign)) {
667 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
680 auto it = mapKeyMetadata.find(key_id);
681 if (it != mapKeyMetadata.end()) {
682 return std::make_unique<CKeyMetadata>(it->second);
687 auto it = m_script_metadata.find(
CScriptID(scriptPubKey));
688 if (it != m_script_metadata.end()) {
689 return std::make_unique<CKeyMetadata>(it->second);
707 if (nCreateTime <= 1) {
711 }
else if (nTimeFirstKey ==
UNKNOWN_TIME || nCreateTime < nTimeFirstKey) {
712 nTimeFirstKey = nCreateTime;
740 bool needsDB = !encrypted_batch;
742 encrypted_batch = &batch;
745 if (needsDB) encrypted_batch =
nullptr;
748 if (needsDB) encrypted_batch =
nullptr;
765 mapKeyMetadata[pubkey.
GetID()]);
778 WalletLogPrintf(
"%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n", __func__, redeemScript.
size(),
MAX_SCRIPT_ELEMENT_SIZE, strAddr);
789 mapKeyMetadata[keyID] = meta;
796 m_script_metadata[script_id] = meta;
810 std::vector<unsigned char> vchCryptedSecret;
813 return EncryptSecret(encryption_key, vchSecret, pubkey.GetHash(), vchCryptedSecret);
827 if (!checksum_valid) {
839 mapCryptedKeys[vchPubKey.
GetID()] = make_pair(vchPubKey, vchCryptedSecret);
845 const std::vector<unsigned char> &vchCryptedSecret)
852 return encrypted_batch->WriteCryptedKey(vchPubKey,
854 mapKeyMetadata[vchPubKey.
GetID()]);
858 mapKeyMetadata[vchPubKey.
GetID()]);
865 return setWatchOnly.count(dest) > 0;
871 return (!setWatchOnly.empty());
876 std::vector<std::vector<unsigned char>> solutions;
878 (pubKeyOut =
CPubKey(solutions[0])).IsFullyValid();
885 setWatchOnly.erase(dest);
888 mapWatchKeys.erase(pubKey.
GetID());
910 setWatchOnly.insert(dest);
913 mapWatchKeys[pubKey.
GetID()] = pubKey;
935 m_script_metadata[
CScriptID(dest)].nCreateTime = create_time;
947 m_script_metadata[
CScriptID(dest)].nCreateTime = nCreateTime;
962 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
985 return mapCryptedKeys.count(address) > 0;
995 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
996 if (mi != mapCryptedKeys.end())
998 const CPubKey &vchPubKey = (*mi).second.first;
999 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
1001 return DecryptKey(encryption_key, vchCryptedSecret, vchPubKey, keyOut);
1012 auto it = mapKeyMetadata.find(keyID);
1013 if (it == mapKeyMetadata.end()) {
1030 WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
1031 if (it != mapWatchKeys.end()) {
1032 pubkey_out = it->second;
1048 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1049 if (mi != mapCryptedKeys.end())
1051 vchPubKeyOut = (*mi).second.first;
1068 int64_t nCreationTime =
GetTime();
1086 mapKeyMetadata[pubkey.
GetID()] = metadata;
1090 throw std::runtime_error(std::string(__func__) +
": AddKey failed");
1097 if (!key_in.
Derive(key_out, index)) {
1098 throw std::runtime_error(
"Could not derive extended key");
1113 throw std::runtime_error(std::string(__func__) +
": seed not found");
1147 secret = childKey.
key;
1154 throw std::runtime_error(std::string(__func__) +
": writing HD chain model failed");
1161 set_pre_split_keypool.insert(nIndex);
1163 setInternalKeyPool.insert(nIndex);
1165 setExternalKeyPool.insert(nIndex);
1167 m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
1174 if (mapKeyMetadata.count(keyid) == 0)
1194 int64_t nCreationTime =
GetTime();
1210 mapKeyMetadata[seed.
GetID()] = metadata;
1214 throw std::runtime_error(std::string(__func__) +
": AddKeyPubKey failed");
1248 for (
const int64_t nIndex : setInternalKeyPool) {
1251 setInternalKeyPool.clear();
1253 for (
const int64_t nIndex : setExternalKeyPool) {
1254 batch.ErasePool(nIndex);
1256 setExternalKeyPool.clear();
1258 for (
const int64_t nIndex : set_pre_split_keypool) {
1259 batch.ErasePool(nIndex);
1261 set_pre_split_keypool.clear();
1268 WalletLogPrintf(
"LegacyScriptPubKeyMan::NewKeyPool rewrote keypool\n");
1280 if (!batch.TxnBegin())
return false;
1289 if (!batch.TxnCommit())
throw std::runtime_error(
strprintf(
"Error during keypool top up. Cannot commit changes for wallet %s",
m_storage.
GetDisplayName()));
1304 unsigned int nTargetSize;
1306 nTargetSize = kpSize;
1308 nTargetSize = m_keypool_size;
1310 int64_t target = std::max((int64_t) nTargetSize, int64_t{1});
1314 int64_t missingExternal;
1315 int64_t missingInternal;
1317 missingExternal = std::max(target - (int64_t)setExternalKeyPool.size(), int64_t{0});
1318 missingInternal = std::max(target - (int64_t)setInternalKeyPool.size(), int64_t{0});
1326 missingInternal = 0;
1328 bool internal =
false;
1329 for (int64_t i = missingInternal + missingExternal; i--;) {
1330 if (i < missingInternal) {
1339 if (missingInternal + missingExternal > 0) {
1341 WalletLogPrintf(
"keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size(), setInternalKeyPool.size());
1343 WalletLogPrintf(
"inactive seed with id %s added %d external keys, %d internal keys\n",
HexStr(chain.
seed_id), missingExternal, missingInternal);
1352 assert(m_max_keypool_index < std::numeric_limits<int64_t>::max());
1353 int64_t index = ++m_max_keypool_index;
1355 throw std::runtime_error(std::string(__func__) +
": writing imported pubkey failed");
1358 setInternalKeyPool.insert(index);
1360 setExternalKeyPool.insert(index);
1385 setInternalKeyPool.insert(nIndex);
1386 }
else if (!set_pre_split_keypool.empty()) {
1387 set_pre_split_keypool.insert(nIndex);
1389 setExternalKeyPool.insert(nIndex);
1429 bool fReturningInternal = fRequestedInternal;
1431 bool use_split_keypool = set_pre_split_keypool.empty();
1432 std::set<int64_t>& setKeyPool = use_split_keypool ? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) : set_pre_split_keypool;
1435 if (setKeyPool.empty()) {
1441 auto it = setKeyPool.begin();
1443 setKeyPool.erase(it);
1444 if (!batch.ReadPool(nIndex, keypool)) {
1445 throw std::runtime_error(std::string(__func__) +
": read failed");
1449 throw std::runtime_error(std::string(__func__) +
": unknown key in key pool");
1452 if (use_split_keypool && keypool.
fInternal != fReturningInternal) {
1453 throw std::runtime_error(std::string(__func__) +
": keypool entry misclassified");
1456 throw std::runtime_error(std::string(__func__) +
": keypool entry invalid");
1476 assert(desc && desc->IsSolvable());
1490 bool internal = setInternalKeyPool.count(keypool_id);
1491 if (!
internal)
assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id));
1492 std::set<int64_t> *setKeyPool =
internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
1493 auto it = setKeyPool->begin();
1495 std::vector<CKeyPool> result;
1497 while (it != std::end(*setKeyPool)) {
1498 const int64_t& index = *(it);
1499 if (index > keypool_id)
break;
1502 if (batch.ReadPool(index, keypool)) {
1506 batch.ErasePool(index);
1508 it = setKeyPool->erase(it);
1509 result.push_back(std::move(keypool));
1517 std::vector<CScript> dummy;
1520 std::vector<CKeyID>
ret;
1521 ret.reserve(
out.pubkeys.size());
1522 for (
const auto& entry :
out.pubkeys) {
1523 ret.push_back(entry.first);
1531 for (
auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) {
1532 int64_t index = *it;
1534 if (!batch.ReadPool(index, keypool)) {
1535 throw std::runtime_error(std::string(__func__) +
": read keypool entry failed");
1538 if (!batch.WritePool(index, keypool)) {
1539 throw std::runtime_error(std::string(__func__) +
": writing modified keypool entry failed");
1541 set_pre_split_keypool.insert(index);
1542 it = setExternalKeyPool.erase(it);
1567 mapKeyMetadata[pubkey.
GetID()].key_origin.path = info.
path;
1568 mapKeyMetadata[pubkey.
GetID()].has_key_origin =
true;
1576 for (
const auto& entry : scripts) {
1586 if (timestamp > 0) {
1587 m_script_metadata[
CScriptID(entry)].nCreateTime = timestamp;
1590 if (timestamp > 0) {
1600 for (
const auto& entry : privkey_map) {
1601 const CKey& key = entry.second;
1603 const CKeyID&
id = entry.first;
1610 mapKeyMetadata[id].nCreateTime = timestamp;
1620 bool LegacyScriptPubKeyMan::ImportPubKeys(
const std::vector<CKeyID>& ordered_pubkeys,
const std::map<CKeyID, CPubKey>& pubkey_map,
const std::map<
CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins,
const bool add_keypool,
const bool internal,
const int64_t timestamp)
1623 for (
const auto& entry : key_origins) {
1626 for (
const CKeyID&
id : ordered_pubkeys) {
1627 auto entry = pubkey_map.find(
id);
1628 if (entry == pubkey_map.end()) {
1631 const CPubKey& pubkey = entry->second;
1641 mapKeyMetadata[id].nCreateTime = timestamp;
1655 for (
const CScript& script : script_pub_keys) {
1656 if (!have_solving_data || !
IsMine(script)) {
1671 std::set<CKeyID> set_address;
1672 for (
const auto& mi : mapCryptedKeys) {
1673 set_address.insert(mi.first);
1681 std::unordered_set<CScript, SaltedSipHasher> spks;
1684 for (
const auto& key_pair : mapKeys) {
1685 const CPubKey& pub = key_pair.second.GetPubKey();
1689 for (
const auto& key_pair : mapCryptedKeys) {
1690 const CPubKey& pub = key_pair.second.first;
1698 for (
const auto& script_pair : mapScripts) {
1699 const CScript& script = script_pair.second;
1707 std::vector<unsigned char> witprog;
1709 spks.insert(script);
1714 std::vector<std::vector<unsigned char>> sols;
1719 spks.insert(ms_spk);
1726 for (
const CScript& script : setWatchOnly) {
1739 std::unordered_set<CScript, SaltedSipHasher> spks;
1740 for (
const CScript& script : setWatchOnly) {
1750 return std::nullopt;
1758 std::set<CKeyID> keyids;
1759 for (
const auto& key_pair : mapKeys) {
1760 keyids.insert(key_pair.first);
1762 for (
const auto& key_pair : mapCryptedKeys) {
1763 keyids.insert(key_pair.first);
1768 for (
auto keyid_it = keyids.begin(); keyid_it != keyids.end();) {
1769 const CKeyID& keyid = *keyid_it;
1770 const auto& it = mapKeyMetadata.find(keyid);
1771 if (it != mapKeyMetadata.end()) {
1778 keyid_it = keyids.erase(keyid_it);
1786 for (
const CKeyID& keyid : keyids) {
1788 if (!
GetKey(keyid, key)) {
1793 uint64_t creation_time = 0;
1794 const auto& it = mapKeyMetadata.find(keyid);
1795 if (it != mapKeyMetadata.end()) {
1796 creation_time = it->second.nCreateTime;
1806 std::string desc_str =
"combo(" + origin_str +
HexStr(key.
GetPubKey()) +
")";
1809 std::unique_ptr<Descriptor> desc =
Parse(desc_str, keys,
error,
false);
1814 desc_spk_man->AddDescriptorKey(key, key.
GetPubKey());
1815 desc_spk_man->TopUp();
1816 auto desc_spks = desc_spk_man->GetScriptPubKeys();
1819 for (
const CScript& spk : desc_spks) {
1820 size_t erased = spks.erase(spk);
1825 out.desc_spkms.push_back(std::move(desc_spk_man));
1829 std::vector<CHDChain> chains;
1832 chains.push_back(chain_pair.second);
1834 for (
const CHDChain& chain : chains) {
1835 for (
int i = 0; i < 2; ++i) {
1842 if (!
GetKey(chain.seed_id, seed_key)) {
1850 std::string desc_str =
"combo(" + xpub +
"/0h/" +
ToString(i) +
"h/*h)";
1853 std::unique_ptr<Descriptor> desc =
Parse(desc_str, keys,
error,
false);
1854 uint32_t chain_counter = std::max((i == 1 ? chain.nInternalChainCounter : chain.nExternalChainCounter), (uint32_t)0);
1859 desc_spk_man->AddDescriptorKey(master_key.
key, master_key.
key.
GetPubKey());
1860 desc_spk_man->TopUp();
1861 auto desc_spks = desc_spk_man->GetScriptPubKeys();
1864 for (
const CScript& spk : desc_spks) {
1865 size_t erased = spks.erase(spk);
1870 out.desc_spkms.push_back(std::move(desc_spk_man));
1879 out.master_key.SetSeed(seed_key);
1883 for (
auto it = spks.begin(); it != spks.end();) {
1887 uint64_t creation_time = 0;
1888 const auto& mit = m_script_metadata.find(
CScriptID(spk));
1889 if (mit != m_script_metadata.end()) {
1890 creation_time = mit->second.nCreateTime;
1896 std::vector<CScript> scripts;
1901 std::set<CKeyID> privkeyids;
1902 for (
const auto& key_orig_pair : keys.
origins) {
1903 privkeyids.insert(key_orig_pair.first);
1906 std::vector<CScript> desc_spks;
1909 std::string desc_str;
1910 bool watchonly = !desc->ToPrivateString(*
this, desc_str);
1912 out.watch_descs.emplace_back(desc->ToString(), creation_time);
1916 desc->Expand(0, provider, desc_spks, provider);
1921 for (
const auto& keyid : privkeyids) {
1923 if (!
GetKey(keyid, key)) {
1926 desc_spk_man->AddDescriptorKey(key, key.
GetPubKey());
1928 desc_spk_man->TopUp();
1929 auto desc_spks_set = desc_spk_man->GetScriptPubKeys();
1930 desc_spks.insert(desc_spks.end(), desc_spks_set.begin(), desc_spks_set.end());
1932 out.desc_spkms.push_back(std::move(desc_spk_man));
1936 for (
const CScript& desc_spk : desc_spks) {
1937 auto del_it = spks.find(desc_spk);
1938 assert(del_it != spks.end());
1940 it = spks.erase(del_it);
1946 for (
const auto& script_pair : mapScripts) {
1947 const CScript script = script_pair.second;
1950 uint64_t creation_time = 0;
1951 const auto& it = m_script_metadata.find(
CScriptID(script));
1952 if (it != m_script_metadata.end()) {
1953 creation_time = it->second.nCreateTime;
1956 std::vector<std::vector<unsigned char>> sols;
1972 std::vector<std::vector<unsigned char>> keys(sols.begin() + 1, sols.begin() + sols.size() - 1);
1981 out.solvable_descs.emplace_back(sh_desc->ToString(), creation_time);
1984 if (desc->IsSolvable()) {
1986 out.solvable_descs.emplace_back(wsh_desc->ToString(), creation_time);
1988 out.solvable_descs.emplace_back(sh_wsh_desc->ToString(), creation_time);
1994 assert(spks.size() == 0);
2013 assert(m_wallet_descriptor.descriptor->IsSingleType());
2014 std::optional<OutputType> desc_addr_type = m_wallet_descriptor.descriptor->GetOutputType();
2016 if (type != *desc_addr_type) {
2017 throw std::runtime_error(std::string(__func__) +
": Types are inconsistent. Stored type does not match type of newly generated address");
2024 std::vector<CScript> scripts_temp;
2027 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2029 if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2031 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2036 return util::Error{
_(
"Error: Cannot extract destination from the generated scriptpubkey")};
2038 m_wallet_descriptor.next_index++;
2047 if (m_map_script_pub_keys.count(script) > 0) {
2056 if (!m_map_keys.empty()) {
2060 bool keyPass = m_map_crypted_keys.empty();
2061 bool keyFail =
false;
2062 for (
const auto& mi : m_map_crypted_keys) {
2063 const CPubKey &pubkey = mi.second.first;
2064 const std::vector<unsigned char> &crypted_secret = mi.second.second;
2066 if (!
DecryptKey(master_key, crypted_secret, pubkey, key)) {
2074 if (keyPass && keyFail) {
2075 LogPrintf(
"The wallet is probably corrupted: Some keys decrypt but not all.\n");
2076 throw std::runtime_error(
"Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
2078 if (keyFail || !keyPass) {
2088 if (!m_map_crypted_keys.empty()) {
2092 for (
const KeyMap::value_type& key_in : m_map_keys)
2094 const CKey &key = key_in.second;
2097 std::vector<unsigned char> crypted_secret;
2101 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2112 index = m_wallet_descriptor.next_index - 1;
2120 if (m_wallet_descriptor.next_index - 1 == index) {
2121 m_wallet_descriptor.next_index--;
2132 for (
const auto& key_pair : m_map_crypted_keys) {
2133 const CPubKey& pubkey = key_pair.second.first;
2134 const std::vector<unsigned char>& crypted_secret = key_pair.second.second;
2137 return DecryptKey(encryption_key, crypted_secret, pubkey, key);
2139 keys[pubkey.
GetID()] = key;
2149 if (!batch.TxnBegin())
return false;
2151 if (!batch.TxnCommit())
throw std::runtime_error(
strprintf(
"Error during descriptors keypool top up. Cannot commit changes for wallet %s",
m_storage.
GetDisplayName()));
2158 std::set<CScript> new_spks;
2159 unsigned int target_size;
2163 target_size = m_keypool_size;
2167 int32_t new_range_end = std::max(m_wallet_descriptor.next_index + (int32_t)target_size, m_wallet_descriptor.range_end);
2170 if (!m_wallet_descriptor.descriptor->IsRange()) {
2172 m_wallet_descriptor.range_end = 1;
2173 m_wallet_descriptor.range_start = 0;
2182 std::vector<CScript> scripts_temp;
2185 if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2186 if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache))
return false;
2189 new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2190 for (
const CScript& script : scripts_temp) {
2191 m_map_script_pub_keys[script] = i;
2193 for (
const auto& pk_pair : out_keys.
pubkeys) {
2194 const CPubKey& pubkey = pk_pair.second;
2195 if (m_map_pubkeys.count(pubkey) != 0) {
2200 m_map_pubkeys[pubkey] = i;
2205 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2209 m_wallet_descriptor.range_end = new_range_end;
2223 std::vector<WalletDestination> result;
2225 int32_t index = m_map_script_pub_keys[script];
2226 if (index >= m_wallet_descriptor.next_index) {
2227 WalletLogPrintf(
"%s: Detected a used keypool item at index %d, mark all keypool items up to this item as used\n", __func__, index);
2228 auto out_keys = std::make_unique<FlatSigningProvider>();
2229 std::vector<CScript> scripts_temp;
2230 while (index >= m_wallet_descriptor.next_index) {
2231 if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) {
2232 throw std::runtime_error(std::string(__func__) +
": Unable to expand descriptor from cache");
2236 result.push_back({dest, std::nullopt});
2237 m_wallet_descriptor.next_index++;
2241 WalletLogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
2253 throw std::runtime_error(std::string(__func__) +
": writing descriptor private key failed");
2263 if (m_map_keys.find(pubkey.
GetID()) != m_map_keys.end() ||
2264 m_map_crypted_keys.find(pubkey.
GetID()) != m_map_crypted_keys.end()) {
2273 std::vector<unsigned char> crypted_secret;
2276 return EncryptSecret(encryption_key, secret, pubkey.GetHash(), crypted_secret);
2281 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2284 m_map_keys[pubkey.
GetID()] = key;
2295 if (m_wallet_descriptor.descriptor) {
2299 int64_t creation_time =
GetTime();
2304 std::string desc_prefix;
2305 std::string desc_suffix =
"/*)";
2306 switch (addr_type) {
2308 desc_prefix =
"pkh(" + xpub +
"/44h";
2312 desc_prefix =
"sh(wpkh(" + xpub +
"/49h";
2317 desc_prefix =
"wpkh(" + xpub +
"/84h";
2321 desc_prefix =
"tr(" + xpub +
"/86h";
2330 assert(!desc_prefix.empty());
2334 desc_prefix +=
"/1h";
2336 desc_prefix +=
"/0h";
2339 std::string internal_path =
internal ?
"/1" :
"/0";
2340 std::string desc_str = desc_prefix +
"/0h" + internal_path + desc_suffix;
2345 std::unique_ptr<Descriptor> desc =
Parse(desc_str, keys,
error,
false);
2347 m_wallet_descriptor = w_desc;
2351 throw std::runtime_error(std::string(__func__) +
": writing descriptor master private key failed");
2354 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2367 return m_wallet_descriptor.descriptor->IsRange();
2375 return m_wallet_descriptor.descriptor->IsSingleType() &&
2376 m_wallet_descriptor.descriptor->IsRange() &&
2377 (
HavePrivateKeys() || m_wallet_descriptor.next_index < m_wallet_descriptor.range_end);
2383 return m_map_keys.size() > 0 || m_map_crypted_keys.size() > 0;
2389 return std::nullopt;
2396 return m_wallet_descriptor.range_end - m_wallet_descriptor.next_index;
2402 return m_wallet_descriptor.creation_time;
2410 auto it = m_map_script_pub_keys.find(script);
2411 if (it == m_map_script_pub_keys.end()) {
2414 int32_t index = it->second;
2424 auto it = m_map_pubkeys.find(pubkey);
2425 if (it == m_map_pubkeys.end()) {
2428 int32_t index = it->second;
2438 std::unique_ptr<FlatSigningProvider> out_keys = std::make_unique<FlatSigningProvider>();
2446 std::vector<CScript> scripts_temp;
2447 if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys))
return nullptr;
2456 m_wallet_descriptor.descriptor->ExpandPrivate(index, master_provider, *out_keys);
2474 std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2475 for (
const auto& coin_pair : coins) {
2476 std::unique_ptr<FlatSigningProvider> coin_keys =
GetSigningProvider(coin_pair.second.out.scriptPubKey,
true);
2480 keys->Merge(std::move(*coin_keys));
2494 if (!keys->GetKey(
ToKeyID(pkhash), key)) {
2509 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
2510 const CTxIn& txin = psbtx.
tx->vin[i];
2536 std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2539 keys->Merge(std::move(*script_keys));
2542 std::vector<CPubKey> pubkeys;
2547 pubkeys.push_back(
pk);
2551 std::vector<std::vector<unsigned char>> sols;
2553 sols[0].insert(sols[0].begin(), 0x02);
2554 pubkeys.emplace_back(sols[0]);
2556 pubkeys.emplace_back(sols[0]);
2562 for (
unsigned char prefix : {0x02, 0x03}) {
2563 unsigned char b[33] = {
prefix};
2564 std::copy(pubkey.
begin(), pubkey.
end(), b + 1);
2566 fullpubkey.
Set(b, b + 33);
2567 pubkeys.push_back(fullpubkey);
2571 for (
const auto& pubkey : pubkeys) {
2574 keys->Merge(std::move(*pk_keys));
2582 if (n_signed && (signed_one || !sign)) {
2591 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
2608 if (provider->GetKeyOrigin(key_id, orig)) {
2610 std::unique_ptr<CKeyMetadata> meta = std::make_unique<CKeyMetadata>();
2611 meta->key_origin = orig;
2612 meta->has_key_origin =
true;
2613 meta->nCreateTime = m_wallet_descriptor.creation_time;
2623 return m_wallet_descriptor.id;
2629 std::set<CScript> new_spks;
2630 m_wallet_descriptor.cache = cache;
2631 for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
2633 std::vector<CScript> scripts_temp;
2634 if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2635 throw std::runtime_error(
"Error: Unable to expand wallet descriptor from cache");
2638 new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2639 for (
const CScript& script : scripts_temp) {
2640 if (m_map_script_pub_keys.count(script) != 0) {
2641 throw std::runtime_error(
strprintf(
"Error: Already loaded script at index %d as being at index %d", i, m_map_script_pub_keys[script]));
2643 m_map_script_pub_keys[script] = i;
2645 for (
const auto& pk_pair : out_keys.
pubkeys) {
2646 const CPubKey& pubkey = pk_pair.second;
2647 if (m_map_pubkeys.count(pubkey) != 0) {
2652 m_map_pubkeys[pubkey] = i;
2663 m_map_keys[key_id] = key;
2670 if (!m_map_keys.empty()) {
2674 m_map_crypted_keys[key_id] = make_pair(pubkey, crypted_key);
2681 return !m_wallet_descriptor.id.IsNull() && !desc.
id.
IsNull() && m_wallet_descriptor.id == desc.
id;
2688 if (!batch.WriteDescriptor(
GetID(), m_wallet_descriptor)) {
2689 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2695 return m_wallet_descriptor;
2706 std::unordered_set<CScript, SaltedSipHasher> script_pub_keys;
2707 script_pub_keys.reserve(m_map_script_pub_keys.size());
2709 for (
auto const& [script_pub_key, index] : m_map_script_pub_keys) {
2710 if (index >= minimum_index) script_pub_keys.insert(script_pub_key);
2712 return script_pub_keys;
2731 return m_wallet_descriptor.descriptor->ToPrivateString(provider,
out);
2734 return m_wallet_descriptor.descriptor->ToNormalizedString(provider,
out, &m_wallet_descriptor.cache);
2745 if (m_wallet_descriptor.cache.GetCachedLastHardenedExtPubKeys().size() > 0) {
2753 std::vector<CScript> scripts_temp;
2755 if (!m_wallet_descriptor.descriptor->Expand(0, provider, scripts_temp, out_keys, &temp_cache)){
2756 throw std::runtime_error(
"Unable to expand descriptor");
2762 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2771 throw std::runtime_error(std::string(__func__) +
": " +
error);
2774 m_map_pubkeys.clear();
2775 m_map_script_pub_keys.clear();
2777 m_wallet_descriptor = descriptor;
2786 error =
"can only update matching descriptor";
2790 if (descriptor.
range_start > m_wallet_descriptor.range_start ||
2791 descriptor.
range_end < m_wallet_descriptor.range_end) {
2793 error =
strprintf(
"new range must include current range = [%d,%d]",
2794 m_wallet_descriptor.range_start,
2795 m_wallet_descriptor.range_end - 1);
int64_t GetTimeFirstKey() const override
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. ...
virtual std::string GetDisplayName() const =0
IsMineSigVersion
This is an enum that tracks the execution context of a script, similar to SigVersion in script/interp...
bool AddWatchOnlyInMem(const CScript &dest)
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
static const std::string sighash
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...
void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Update wallet first key creation time.
static UniValue Parse(std::string_view raw)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
bool RemoveWatchOnly(const CScript &dest)
Remove a watch only script from the keystore.
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
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 AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, and saves it to disk.
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.
bool SetupDescriptorGeneration(WalletBatch &batch, const CExtKey &master_key, OutputType addr_type, bool internal)
Setup descriptors based on the given CExtkey.
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...
void UpgradeKeyMetadata()
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
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 Upgrade(int prev_version, int new_version, bilingual_str &error) override
Upgrades the wallet to the specified version.
virtual bool IsWalletFlagSet(uint64_t) const =0
virtual WalletDatabase & GetDatabase() const =0
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
isminetype IsMine(const CScript &script) const override
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath, bool apostrophe)
Write HD keypaths as strings.
void AddKeypoolPubkeyWithDB(const CPubKey &pubkey, const bool internal, WalletBatch &batch)
iterator insert(iterator pos, const T &value)
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) ...
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
bool Derive(CExtKey &out, unsigned int nChild) const
std::map< int64_t, CKeyID > m_index_to_reserved_key
bool NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
bool CanGenerateKeys() const
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
unsigned int GetKeyPoolSize() const override
static bool ExtractPubKey(const CScript &dest, CPubKey &pubKeyOut)
bool IsPayToScriptHash() const
RecursiveMutex cs_KeyStore
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
CPubKey GetPubKey() const
Compute the public key from a private key.
bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal)
Like TopUp() but adds keys for inactive HD chains.
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
IsMineResult
This is an internal representation of isminetype + invalidity.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
std::map< CKeyID, CKey > keys
bool AddCScript(const CScript &redeemScript) override
std::optional< MigrationData > MigrateToDescriptor()
Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this Legac...
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
virtual bool AddCScript(const CScript &redeemScript)
bool WriteCryptedDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const std::vector< unsigned char > &secret)
uint32_t nExternalChainCounter
bool CanGetAddresses(bool internal=false) const override
struct containing information needed for migrating legacy wallets to descriptor wallets ...
int64_t m_next_internal_index
std::map< CKeyID, CKey > KeyMap
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
bool CanUpdateToWalletDescriptor(const WalletDescriptor &descriptor, std::string &error)
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
uint256 GetHash() const
Get the 256-bit hash of this public key.
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
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 LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
virtual std::set< CKeyID > GetKeys() const
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
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 m_pre_split
Whether this key was generated for a keypool before the wallet was upgraded to HD-split.
void UpdateWalletDescriptor(WalletDescriptor &descriptor)
bool ImportScriptPubKeys(const std::set< CScript > &script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
CKeyID GetKeyForDestination(const SigningProvider &store, const CTxDestination &dest)
Return the CKeyID of the key involved in a script (if there is a unique one).
void SetHDSeed(const CPubKey &key)
const std::byte * end() const
bool DeleteRecords()
Delete all the records ofthis LegacyScriptPubKeyMan from disk.
A version of CTransaction with the PSBT format.
bool IsWitnessProgram(int &version, std::vector< unsigned char > &program) const
virtual void UnsetBlankWalletFlag(WalletBatch &)=0
Access to the wallet database.
bool WritePool(int64_t nPool, const CKeyPool &keypool)
A key from a CWallet's keypool.
bool GetKey(const CKeyID &address, CKey &keyOut) const override
boost::signals2::signal< void(const ScriptPubKeyMan *spkm, int64_t new_birth_time)> NotifyFirstKeyTimeChanged
Birth time changed.
bool AddKey(const CKeyID &key_id, const CKey &key)
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
virtual bool IsLocked() const =0
unsigned int GetKeyPoolSize() const override
bool IsHDEnabled() const override
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
const std::unordered_set< std::string > LEGACY_TYPES
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses, and other watch only things, and is therefore "blank.".
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, const bool overwrite)
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible...
bool CanGetAddresses(bool internal=false) const override
int64_t m_next_external_index
constexpr unsigned char * begin()
void SetCache(const DescriptorCache &cache)
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that...
CKey GenerateRandomKey(bool compressed) noexcept
bool AddCryptedKey(const CKeyID &key_id, const CPubKey &pubkey, const std::vector< unsigned char > &crypted_key)
WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool HaveKey(const CKeyID &address) const override
std::string ToString(const T &t)
Locale-independent version of std::to_string.
static constexpr int64_t UNKNOWN_TIME
Constant representing an unknown spkm creation time.
size_t KeypoolCountExternalKeys() const
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that...
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
std::set< CKeyID > GetKeys() const override
static void DeriveExtKey(CExtKey &key_in, unsigned int index, CExtKey &key_out)
Try to derive an extended key, throw if it fails.
bool HavePrivateKeys() const override
const unsigned char * begin() const
virtual bool CanSupportFeature(enum WalletFeature) const =0
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
CPubKey vchPubKey
The public key.
bool ReadPool(int64_t nPool, CKeyPool &keypool)
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr) override
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
An input of a transaction.
virtual void SetMinVersion(enum WalletFeature, WalletBatch *=nullptr)=0
void RewriteDB() override
The action to do when the DB needs rewrite.
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
virtual bool HasEncryptionKeys() const =0
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
std::optional< int64_t > GetOldestKeyPoolTime() const override
int32_t GetEndRange() const
bilingual_str _(const char *psz)
Translation function.
void AddHDChain(const CHDChain &chain)
const SigningProvider & DUMMY_SIGNING_PROVIDER
uint256 GetID() const override
An encapsulated public key.
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
std::map< CKeyID, CPubKey > pubkeys
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
bool IsFeatureSupported(int wallet_version, int feature_version)
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
bool EraseRecords(const std::unordered_set< std::string > &types)
Delete records of the given types.
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
Indicate that this wallet supports DescriptorScriptPubKeyMan.
void ImplicitlyLearnRelatedKeyScripts(const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
isminetype IsMine(const CScript &script) const override
void ReturnDestination(int64_t index, bool internal, const CTxDestination &) override
uint32_t nInternalChainCounter
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
static const std::unordered_set< OutputType > LEGACY_OUTPUT_TYPES
OutputTypes supported by the LegacyScriptPubKeyMan.
std::optional< int64_t > GetOldestKeyPoolTime() const override
constexpr bool IsNull() const
std::unordered_set< CScript, SaltedSipHasher > GetNotMineScriptPubKeys() const
Retrieves scripts that were imported by bugs into the legacy spkm and are simply invalid, such as a sh(sh(pkh())) script, or not watched.
std::vector< PSBTInput > inputs
virtual void TopUpCallback(const std::set< CScript > &, ScriptPubKeyMan *)=0
Callback function for after TopUp completes containing any scripts that were added by a SPKMan...
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 ErasePool(int64_t nPool)
uint256 GetID() const override
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 UpgradeDescriptorCache()
Descriptor with some wallet metadata.
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)
bool AddCScriptWithDB(WalletBatch &batch, const CScript &script)
Adds a script to the store and saves it to disk.
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const override
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
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...
std::vector< unsigned char > valtype
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
CPubKey DeriveNewSeed(const CKey &key)
bool TopUpChain(WalletBatch &batch, CHDChain &chain, unsigned int size)
void LearnRelatedScripts(const CPubKey &key, OutputType)
Explicitly make the wallet learn the related scripts for outputs to the given key.
bool DecryptKey(const CKeyingMaterial &vMasterKey, const std::vector< unsigned char > &vchCryptedSecret, const CPubKey &vchPubKey, CKey &key)
std::string EncodeExtPubKey(const CExtPubKey &key)
void WalletLogPrintf(const char *fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
bool IsTestChain() const
If this chain is exclusively used for testing.
virtual bool WithEncryptionKey(std::function< bool(const CKeyingMaterial &)> cb) const =0
Pass the encryption key to cb().
void SetSeed(Span< const std::byte > seed)
bool EncryptSecret(const CKeyingMaterial &vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256 &nIV, std::vector< unsigned char > &vchCiphertext)
An interface to be implemented by keystores that support signing.
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
CExtPubKey Neuter() const
std::unordered_map< CKeyID, CHDChain, SaltedSipHasher > m_inactive_hd_chains
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0'/2000".
bool error(const char *fmt, const Args &... args)
const CChainParams & Params()
Return the currently selected parameters.
Cache for single descriptor's derived extended pubkeys.
std::map< CKeyID, CKey > KeyMap
bool GetDescriptorString(std::string &out, const bool priv) const
Serialized script, used inside transaction inputs and outputs.
CPubKey GenerateNewSeed()
const std::byte * begin() const
RecursiveMutex cs_desc_man
bool SetupGeneration(bool force=false) override
Sets up the key generation stuff, i.e.
void LearnAllRelatedScripts(const CPubKey &key)
Same as LearnRelatedScripts, but when the OutputType is not known (and could be anything).
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
A reference to a CKey: the Hash160 of its serialized public key.
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
std::map< int32_t, FlatSigningProvider > m_map_signing_providers
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
bool m_decryption_thoroughly_checked
keeps track of whether Unlock has run a thorough check before
bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey)
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
virtual bool HaveCScript(const CScriptID &hash) const override
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
bool HaveWatchOnly() const
Returns whether there are any watch-only things in the wallet.
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
static const int VERSION_HD_BASE
void AddDescriptorKey(const CKey &key, const CPubKey &pubkey)
void AddInactiveHDChain(const CHDChain &chain)
A reference to a CScript: the Hash160 of its serialization.
std::string EncodeDestination(const CTxDestination &dest)
A mutable version of CTransaction.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
bool IsHDEnabled() const override
unsigned char * UCharCast(char *c)
CPubKey GenerateNewKey(WalletBatch &batch, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Generate a new key.
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
bool GetKeyFromPool(CPubKey &key, const OutputType type)
Fetches a key from the keypool.
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed by checking for non-null finalized fields.
static int64_t GetOldestKeyTimeInPool(const std::set< int64_t > &setKeyPool, WalletBatch &batch)
bool fDecryptionThoroughlyChecked
keeps track of whether Unlock has run a thorough check before
bool AddDescriptorKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
KeyMap GetKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
void KeepDestination(int64_t index, const OutputType &type) override
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
bool TopUp(unsigned int size=0) override
Fills internal address pool.
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.
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.
An encapsulated private key.
std::map< CKeyID, int64_t > m_pool_key_to_index
bool HavePrivateKeys() const override
bool ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal)
Reserves a key from the keypool and sets nIndex to its index.
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::optional< CMutableTransaction > tx
std::vector< unsigned char > valtype
void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, CKey &secret, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
int32_t m_max_cached_index
int64_t GetTime()
DEPRECATED, see GetTime.
std::vector< uint32_t > path
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
Only for Witness versions not already defined above.
const unsigned char * end() const
CKeyID seed_id
seed hash160
bool TopUpWithDB(WalletBatch &batch, unsigned int size=0)
Same as 'TopUp' but designed for use within a batch transaction context.
bool HasWalletDescriptor(const WalletDescriptor &desc) const
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
CKeyID ToKeyID(const PKHash &key_hash)
int64_t GetTimeFirstKey() const override
bool TopUp(unsigned int size=0) override
Fills internal address pool.
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
util::Result< CTxDestination > GetNewDestination(const OutputType type) 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.
std::map< CKeyID, SigPair > signatures
BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a ...
std::unique_ptr< FlatSigningProvider > GetSigningProvider(const CScript &script, bool include_private=false) const
WalletStorage & m_storage
unspendable OP_RETURN script that carries data
bool AddKeyOriginWithDB(WalletBatch &batch, const CPubKey &pubkey, const KeyOriginInfo &info)
Add a KeyOriginInfo to the wallet.
bool IsCompressed() const
Check whether this is a compressed public key.
virtual bool HaveKey(const CKeyID &address) const override
static const int VERSION_HD_CHAIN_SPLIT