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;
57 enum class IsMineSigVersion
69 enum class IsMineResult
77 bool PermitsUncompressed(IsMineSigVersion sigversion)
79 return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
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)
101 IsMineResult
ret = IsMineResult::NO;
103 std::vector<valtype> vSolutions;
115 if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
116 return IsMineResult::INVALID;
119 ret = std::max(
ret, IsMineResult::SPENDABLE);
124 if (sigversion == IsMineSigVersion::WITNESS_V0) {
126 return IsMineResult::INVALID;
139 if (!PermitsUncompressed(sigversion)) {
142 return IsMineResult::INVALID;
146 ret = std::max(
ret, IsMineResult::SPENDABLE);
151 if (sigversion != IsMineSigVersion::TOP) {
153 return IsMineResult::INVALID;
157 if (keystore.
GetCScript(scriptID, subscript)) {
158 ret = std::max(
ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::P2SH) : IsMineResult::SPENDABLE);
164 if (sigversion == IsMineSigVersion::WITNESS_V0) {
166 return IsMineResult::INVALID;
173 if (keystore.
GetCScript(scriptID, subscript)) {
174 ret = std::max(
ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::WITNESS_V0) : IsMineResult::SPENDABLE);
182 if (sigversion == IsMineSigVersion::TOP) {
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);
207 ret = std::max(
ret, IsMineResult::WATCH_ONLY);
216 switch (IsMineInner(*
this, script, IsMineSigVersion::TOP)) {
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))
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);
589 IsMineResult ismine = IsMineInner(*
this, script, IsMineSigVersion::TOP,
false);
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) {
1256 setExternalKeyPool.clear();
1258 for (
const int64_t nIndex : set_pre_split_keypool) {
1261 set_pre_split_keypool.clear();
1268 WalletLogPrintf(
"LegacyScriptPubKeyMan::NewKeyPool rewrote keypool\n");
1280 if (!batch.
TxnBegin())
return false;
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)) {
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");
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;
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());
2333 if (
Params().IsTestChain()) {
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;
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);
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
CKeyID ToKeyID(const PKHash &key_hash)
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0'/2000".
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath, bool apostrophe)
Write HD keypaths as strings.
const CChainParams & Params()
Return the currently selected parameters.
An encapsulated private key.
const std::byte * end() const
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
CPubKey GetPubKey() const
Compute the public key from a private key.
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
const std::byte * begin() const
A reference to a CKey: the Hash160 of its serialized public key.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
uint256 GetHash() const
Get the 256-bit hash of this public key.
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Serialized script, used inside transaction inputs and outputs.
bool IsPayToScriptHash() const
bool IsWitnessProgram(int &version, std::vector< unsigned char > &program) const
A reference to a CScript: the Hash160 of its serialization.
An input of a transaction.
Cache for single descriptor's derived extended pubkeys.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const override
virtual bool AddCScript(const CScript &redeemScript)
void ImplicitlyLearnRelatedKeyScripts(const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
virtual std::set< CKeyID > GetKeys() const
std::map< CKeyID, CKey > KeyMap
virtual bool HaveCScript(const CScriptID &hash) const override
RecursiveMutex cs_KeyStore
virtual bool HaveKey(const CKeyID &address) const override
An interface to be implemented by keystores that support signing.
const unsigned char * begin() const
const unsigned char * end() const
constexpr bool IsNull() const
constexpr unsigned char * begin()
iterator insert(iterator pos, const T &value)
uint32_t nInternalChainCounter
static const int VERSION_HD_BASE
uint32_t nExternalChainCounter
int64_t m_next_external_index
static const int VERSION_HD_CHAIN_SPLIT
CKeyID seed_id
seed hash160
int64_t m_next_internal_index
A key from a CWallet's keypool.
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
CPubKey vchPubKey
The public key.
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
bool m_pre_split
Whether this key was generated for a keypool before the wallet was upgraded to HD-split.
KeyMap GetKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
void SetCache(const DescriptorCache &cache)
std::map< int32_t, FlatSigningProvider > m_map_signing_providers
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that,...
void UpgradeDescriptorCache()
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool AddCryptedKey(const CKeyID &key_id, const CPubKey &pubkey, const std::vector< unsigned char > &crypted_key)
bool SetupDescriptorGeneration(WalletBatch &batch, const CExtKey &master_key, OutputType addr_type, bool internal)
Setup descriptors based on the given CExtkey.
bool TopUp(unsigned int size=0) override
Fills internal address pool.
bool m_decryption_thoroughly_checked
keeps track of whether Unlock has run a thorough check before
std::map< CKeyID, CKey > KeyMap
unsigned int GetKeyPoolSize() const override
int64_t GetTimeFirstKey() const override
std::unique_ptr< FlatSigningProvider > GetSigningProvider(const CScript &script, bool include_private=false) const
int32_t GetEndRange() const
bool CheckDecryptionKey(const CKeyingMaterial &master_key) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
bool CanGetAddresses(bool internal=false) const override
bool CanUpdateToWalletDescriptor(const WalletDescriptor &descriptor, std::string &error)
bool GetDescriptorString(std::string &out, const bool priv) const
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
void AddDescriptorKey(const CKey &key, const CPubKey &pubkey)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
bool HavePrivateKeys() const override
bool AddKey(const CKeyID &key_id, const CKey &key)
bool TopUpWithDB(WalletBatch &batch, unsigned int size=0)
Same as 'TopUp' but designed for use within a batch transaction context.
void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr) override
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
bool AddDescriptorKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool HasWalletDescriptor(const WalletDescriptor &desc) const
void UpdateWalletDescriptor(WalletDescriptor &descriptor)
int32_t m_max_cached_index
RecursiveMutex cs_desc_man
std::optional< int64_t > GetOldestKeyPoolTime() const override
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
TransactionError FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const override
Adds script and derivation path information to a PSBT, and optionally signs it.
bool IsHDEnabled() const override
isminetype IsMine(const CScript &script) const override
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
uint256 GetID() const override
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
std::vector< CKeyPool > MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Marks all keys in the keypool up to and including the provided key as used.
bool DeleteRecords()
Delete all the records ofthis LegacyScriptPubKeyMan from disk.
bool CanGenerateKeys() const
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
bool CanGetAddresses(bool internal=false) const override
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
bool GetKeyFromPool(CPubKey &key, const OutputType type)
Fetches a key from the keypool.
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
size_t KeypoolCountExternalKeys() const
void AddInactiveHDChain(const CHDChain &chain)
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
void AddHDChain(const CHDChain &chain)
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, bool checksum_valid)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
bool AddCScriptWithDB(WalletBatch &batch, const CScript &script)
Adds a script to the store and saves it to disk.
std::unordered_map< CKeyID, CHDChain, SaltedSipHasher > m_inactive_hd_chains
bool GetKey(const CKeyID &address, CKey &keyOut) const override
bool AddKeyOriginWithDB(WalletBatch &batch, const CPubKey &pubkey, const KeyOriginInfo &info)
Add a KeyOriginInfo to the wallet.
void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
uint256 GetID() const override
bool AddWatchOnlyInMem(const CScript &dest)
bool HaveWatchOnly() const
Returns whether there are any watch-only things in the wallet.
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
bool CheckDecryptionKey(const CKeyingMaterial &master_key) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, and saves it to disk.
bool ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal)
Reserves a key from the keypool and sets nIndex to its index.
void AddKeypoolPubkeyWithDB(const CPubKey &pubkey, const bool internal, WalletBatch &batch)
std::map< int64_t, CKeyID > m_index_to_reserved_key
bool fDecryptionThoroughlyChecked
keeps track of whether Unlock has run a thorough check before
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
void UpgradeKeyMetadata()
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
bool AddWatchOnly(const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Private version of AddWatchOnly method which does not accept a timestamp, and which will reset the wa...
bool HavePrivateKeys() const override
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
std::unordered_set< CScript, SaltedSipHasher > GetNotMineScriptPubKeys() const
Retrieves scripts that were imported by bugs into the legacy spkm and are simply invalid,...
TransactionError FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const override
Adds script and derivation path information to a PSBT, and optionally signs it.
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
bool HaveWatchOnly(const CScript &dest) const
Returns whether the watch-only script is in the wallet.
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Update wallet first key creation time.
bool TopUp(unsigned int size=0) override
Fills internal address pool.
unsigned int GetKeyPoolSize() const override
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal)
Like TopUp() but adds keys for inactive HD chains.
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that,...
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
std::set< CKeyID > GetKeys() const override
bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey)
bool ImportPubKeys(const std::vector< CKeyID > &ordered_pubkeys, const std::map< CKeyID, CPubKey > &pubkey_map, const std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo >> &key_origins, const bool add_keypool, const bool internal, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
bool IsHDEnabled() const override
bool TopUpChain(WalletBatch &batch, CHDChain &chain, unsigned int size)
bool AddKeyPubKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Adds a key to the store, and saves it to disk.
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
isminetype IsMine(const CScript &script) const override
bool AddCScript(const CScript &redeemScript) override
int64_t GetTimeFirstKey() const override
bool NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
CPubKey GenerateNewSeed()
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
bool SetupGeneration(bool force=false) override
Sets up the key generation stuff, i.e.
void LearnRelatedScripts(const CPubKey &key, OutputType)
Explicitly make the wallet learn the related scripts for outputs to the given key.
void LearnAllRelatedScripts(const CPubKey &key)
Same as LearnRelatedScripts, but when the OutputType is not known (and could be anything).
CPubKey DeriveNewSeed(const CKey &key)
std::optional< MigrationData > MigrateToDescriptor()
Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this Legac...
void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, CKey &secret, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
void ReturnDestination(int64_t index, bool internal, const CTxDestination &) override
std::map< CKeyID, int64_t > m_pool_key_to_index
CPubKey GenerateNewKey(WalletBatch &batch, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Generate a new key.
void SetHDSeed(const CPubKey &key)
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
bool Upgrade(int prev_version, int new_version, bilingual_str &error) override
Upgrades the wallet to the specified version.
void KeepDestination(int64_t index, const OutputType &type) override
void RewriteDB() override
The action to do when the DB needs rewrite.
std::optional< int64_t > GetOldestKeyPoolTime() const override
bool RemoveWatchOnly(const CScript &dest)
Remove a watch only script from the keystore.
bool HaveKey(const CKeyID &address) const override
bool ImportScriptPubKeys(const std::set< CScript > &script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
boost::signals2::signal< void(const ScriptPubKeyMan *spkm, int64_t new_birth_time)> NotifyFirstKeyTimeChanged
Birth time changed.
void WalletLogPrintf(const char *fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
WalletStorage & m_storage
Access to the wallet database.
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
bool TxnBegin()
Begin a new transaction.
bool TxnCommit()
Commit current transaction.
bool EraseRecords(const std::unordered_set< std::string > &types)
Delete records of the given types.
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, const bool overwrite)
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
bool ReadPool(int64_t nPool, CKeyPool &keypool)
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
bool WriteCryptedDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const std::vector< unsigned char > &secret)
bool WritePool(int64_t nPool, const CKeyPool &keypool)
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
bool ErasePool(int64_t nPool)
bool EraseWatchOnly(const CScript &script)
Descriptor with some wallet metadata.
virtual bool IsWalletFlagSet(uint64_t) const =0
virtual void TopUpCallback(const std::set< CScript > &, ScriptPubKeyMan *)=0
Callback function for after TopUp completes containing any scripts that were added by a SPKMan.
virtual void SetMinVersion(enum WalletFeature, WalletBatch *=nullptr)=0
virtual bool CanSupportFeature(enum WalletFeature) const =0
virtual std::string GetDisplayName() const =0
virtual WalletDatabase & GetDatabase() const =0
virtual void UnsetBlankWalletFlag(WalletBatch &)=0
virtual bool IsLocked() const =0
virtual bool HasEncryptionKeys() const =0
virtual bool WithEncryptionKey(std::function< bool(const CKeyingMaterial &)> cb) const =0
Pass the encryption key to cb().
static UniValue Parse(std::string_view raw)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
@ WITNESS_V0
Witness v0 (P2WPKH and P2WSH); see BIP 141.
CKey GenerateRandomKey(bool compressed) noexcept
std::string EncodeDestination(const CTxDestination &dest)
std::string EncodeExtPubKey(const CExtPubKey &key)
@ PRIVATE_KEY_NOT_AVAILABLE
const std::unordered_set< std::string > LEGACY_TYPES
static int64_t GetOldestKeyTimeInPool(const std::set< int64_t > &setKeyPool, WalletBatch &batch)
std::vector< unsigned char > valtype
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
bool DecryptKey(const CKeyingMaterial &vMasterKey, const std::vector< unsigned char > &vchCryptedSecret, const CPubKey &vchPubKey, CKey &key)
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
static const std::unordered_set< OutputType > LEGACY_OUTPUT_TYPES
OutputTypes supported by the LegacyScriptPubKeyMan.
const uint32_t BIP32_HARDENED_KEY_LIMIT
Value for the first BIP 32 hardened derivation. Can be used as a bit mask and as a value....
static constexpr int64_t UNKNOWN_TIME
Constant representing an unknown spkm creation time.
static void DeriveExtKey(CExtKey &key_in, unsigned int index, CExtKey &key_out)
Try to derive an extended key, throw if it fails.
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
static bool ExtractPubKey(const CScript &dest, CPubKey &pubKeyOut)
@ FEATURE_PRE_SPLIT_KEYPOOL
bool EncryptSecret(const CKeyingMaterial &vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256 &nIV, std::vector< unsigned char > &vchCiphertext)
bool IsFeatureSupported(int wallet_version, int feature_version)
@ WALLET_FLAG_LAST_HARDENED_XPUB_CACHED
@ WALLET_FLAG_KEY_ORIGIN_METADATA
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
@ WALLET_FLAG_BLANK_WALLET
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses,...
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, const PrecomputedTransactionData *txdata, int sighash, SignatureData *out_sigdata, bool finalize)
Signs a PSBTInput, verifying that all provided data matches what is being signed.
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed by checking for non-null finalized fields.
void SignTransaction(CMutableTransaction &mtx, const SigningProvider *keystore, const std::map< COutPoint, Coin > &coins, const UniValue &hashType, UniValue &result)
Sign a transaction with the given keystore and previous transactions.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
const SigningProvider & DUMMY_SIGNING_PROVIDER
CKeyID GetKeyForDestination(const SigningProvider &store, const CTxDestination &dest)
Return the CKeyID of the key involved in a script (if there is a unique one).
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
@ WITNESS_UNKNOWN
Only for Witness versions not already defined above.
@ NULL_DATA
unspendable OP_RETURN script that carries data
unsigned char * UCharCast(char *c)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
CExtPubKey Neuter() const
bool Derive(CExtKey &out, unsigned int nChild) const
void SetSeed(Span< const std::byte > seed)
A mutable version of CTransaction.
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
std::map< CKeyID, CPubKey > pubkeys
std::map< CKeyID, CKey > keys
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
std::vector< uint32_t > path
A version of CTransaction with the PSBT format.
std::vector< PSBTInput > inputs
std::optional< CMutableTransaction > tx
std::map< CKeyID, SigPair > signatures
BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a ...
struct containing information needed for migrating legacy wallets to descriptor wallets
bilingual_str _(const char *psz)
Translation function.
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.