34 return util::Error{
_(
"Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
46 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
52typedef std::vector<unsigned char>
valtype;
62enum class IsMineSigVersion
74enum class IsMineResult
82bool PermitsUncompressed(IsMineSigVersion sigversion)
84 return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
87bool HaveKeys(
const std::vector<valtype>& pubkeys,
const LegacyDataSPKM& keystore)
89 for (
const valtype& pubkey : pubkeys) {
91 if (!keystore.
HaveKey(keyID))
return false;
105IsMineResult IsMineInner(
const LegacyDataSPKM& keystore,
const CScript& scriptPubKey, IsMineSigVersion sigversion,
bool recurse_scripthash=
true)
107 IsMineResult
ret = IsMineResult::NO;
109 std::vector<valtype> vSolutions;
122 if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
123 return IsMineResult::INVALID;
126 ret = std::max(
ret, IsMineResult::SPENDABLE);
131 if (sigversion == IsMineSigVersion::WITNESS_V0) {
133 return IsMineResult::INVALID;
146 if (!PermitsUncompressed(sigversion)) {
149 return IsMineResult::INVALID;
153 ret = std::max(
ret, IsMineResult::SPENDABLE);
158 if (sigversion != IsMineSigVersion::TOP) {
160 return IsMineResult::INVALID;
164 if (keystore.
GetCScript(scriptID, subscript)) {
165 ret = std::max(
ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::P2SH) : IsMineResult::SPENDABLE);
171 if (sigversion == IsMineSigVersion::WITNESS_V0) {
173 return IsMineResult::INVALID;
180 if (keystore.
GetCScript(scriptID, subscript)) {
181 ret = std::max(
ret, recurse_scripthash ? IsMineInner(keystore, subscript, IsMineSigVersion::WITNESS_V0) : IsMineResult::SPENDABLE);
189 if (sigversion == IsMineSigVersion::TOP) {
198 std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
199 if (!PermitsUncompressed(sigversion)) {
200 for (
size_t i = 0; i < keys.size(); i++) {
201 if (keys[i].size() != 33) {
202 return IsMineResult::INVALID;
206 if (HaveKeys(keys, keystore)) {
207 ret = std::max(
ret, IsMineResult::SPENDABLE);
214 ret = std::max(
ret, IsMineResult::WATCH_ONLY);
223 switch (IsMineInner(*
this,
script, IsMineSigVersion::TOP)) {
224 case IsMineResult::INVALID:
225 case IsMineResult::NO:
227 case IsMineResult::WATCH_ONLY:
229 case IsMineResult::SPENDABLE:
241 bool keyPass = mapCryptedKeys.empty();
242 bool keyFail =
false;
243 CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
245 for (; mi != mapCryptedKeys.end(); ++mi)
247 const CPubKey &vchPubKey = (*mi).second.first;
248 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
250 if (!
DecryptKey(master_key, vchCryptedSecret, vchPubKey, key))
263 if (keyPass && keyFail)
265 LogPrintf(
"The wallet is probably corrupted: Some keys decrypt but not all.\n");
266 throw std::runtime_error(
"Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
268 if (keyFail || !keyPass)
278 encrypted_batch = batch;
279 if (!mapCryptedKeys.empty()) {
280 encrypted_batch =
nullptr;
285 keys_to_encrypt.swap(mapKeys);
286 for (
const KeyMap::value_type& mKey : keys_to_encrypt)
288 const CKey &key = mKey.second;
291 std::vector<unsigned char> vchCryptedSecret;
293 encrypted_batch =
nullptr;
297 encrypted_batch =
nullptr;
301 encrypted_batch =
nullptr;
308 return util::Error{
_(
"Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
314 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
321 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
352 std::vector<WalletDestination> result;
357 WalletLogPrintf(
"%s: Detected a used keypool key, mark all keypool keys up to this key as used\n", __func__);
362 result.push_back({dest, keypool.fInternal});
367 WalletLogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
373 auto it = mapKeyMetadata.find(keyid);
374 if (it != mapKeyMetadata.end()){
377 std::vector<uint32_t> path;
381 WalletLogPrintf(
"%s: Adding inactive seed keys failed, invalid hdKeypath: %s\n",
385 if (path.size() != 3) {
386 WalletLogPrintf(
"%s: Adding inactive seed keys failed, invalid path size: %d, has_key_origin: %s\n",
391 bool internal = (path[1] & ~BIP32_HARDENED_KEY_LIMIT) != 0;
392 int64_t index = path[2] & ~BIP32_HARDENED_KEY_LIMIT;
413 for (
auto& meta_pair : mapKeyMetadata) {
424 throw std::runtime_error(
"Invalid stored hdKeypath");
433 if (
GetPubKey(meta_pair.first, pubkey)) {
434 batch->WriteKeyMetadata(meta, pubkey,
true);
462 bool keypool_has_keys;
464 keypool_has_keys = setInternalKeyPool.size() > 0;
469 if (!keypool_has_keys) {
472 return keypool_has_keys;
484 bool hd_upgrade =
false;
485 bool split_upgrade =
false;
504 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
515 error =
_(
"Unable to generate keys");
525 return !mapKeys.empty() || !mapCryptedKeys.empty();
531 return !mapCryptedKeys.empty();
537 setInternalKeyPool.clear();
538 setExternalKeyPool.clear();
546 if (setKeyPool.empty()) {
551 int64_t nIndex = *(setKeyPool.begin());
552 if (!batch.
ReadPool(nIndex, keypool)) {
553 throw std::runtime_error(std::string(__func__) +
": read oldest key in keypool failed");
556 return keypool.
nTime;
569 if (!set_pre_split_keypool.empty()) {
580 return setExternalKeyPool.size() + set_pre_split_keypool.size();
586 return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
592 return nTimeFirstKey;
597 return std::make_unique<LegacySigningProvider>(*
this);
602 IsMineResult ismine = IsMineInner(*
this,
script, IsMineSigVersion::TOP,
false);
603 if (ismine == IsMineResult::SPENDABLE || ismine == IsMineResult::WATCH_ONLY) {
613 bool has_privkeys =
false;
614 for (
const auto& key_sig_pair : sigdata.
signatures) {
615 has_privkeys |=
HaveKey(key_sig_pair.first);
646 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
647 const CTxIn& txin = psbtx.
tx->vin[i];
656 return PSBTError::SIGHASH_MISMATCH;
662 return PSBTError::MISSING_INPUTS;
671 if (n_signed && (signed_one || !
sign)) {
680 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
693 auto it = mapKeyMetadata.find(key_id);
694 if (it != mapKeyMetadata.end()) {
695 return std::make_unique<CKeyMetadata>(it->second);
700 auto it = m_script_metadata.find(
CScriptID(scriptPubKey));
701 if (it != m_script_metadata.end()) {
702 return std::make_unique<CKeyMetadata>(it->second);
720 if (nCreateTime <= 1) {
724 }
else if (nTimeFirstKey ==
UNKNOWN_TIME || nCreateTime < nTimeFirstKey) {
725 nTimeFirstKey = nCreateTime;
753 bool needsDB = !encrypted_batch;
755 encrypted_batch = &batch;
758 if (needsDB) encrypted_batch =
nullptr;
761 if (needsDB) encrypted_batch =
nullptr;
778 mapKeyMetadata[pubkey.
GetID()]);
791 WalletLogPrintf(
"%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n", __func__, redeemScript.
size(),
MAX_SCRIPT_ELEMENT_SIZE, strAddr);
801 mapKeyMetadata[keyID] = meta;
814 m_script_metadata[script_id] = meta;
841 std::vector<unsigned char> vchCryptedSecret;
844 return EncryptSecret(encryption_key, vchSecret, pubkey.GetHash(), vchCryptedSecret);
858 if (!checksum_valid) {
870 mapCryptedKeys[vchPubKey.
GetID()] = make_pair(vchPubKey, vchCryptedSecret);
876 const std::vector<unsigned char> &vchCryptedSecret)
883 return encrypted_batch->WriteCryptedKey(vchPubKey,
885 mapKeyMetadata[vchPubKey.
GetID()]);
889 mapKeyMetadata[vchPubKey.
GetID()]);
896 return setWatchOnly.count(dest) > 0;
902 return (!setWatchOnly.empty());
907 std::vector<std::vector<unsigned char>> solutions;
909 (pubKeyOut =
CPubKey(solutions[0])).IsFullyValid();
916 setWatchOnly.erase(dest);
919 mapWatchKeys.erase(pubKey.
GetID());
941 setWatchOnly.insert(dest);
944 mapWatchKeys[pubKey.
GetID()] = pubKey;
966 m_script_metadata[
CScriptID(dest)].nCreateTime = create_time;
978 m_script_metadata[
CScriptID(dest)].nCreateTime = nCreateTime;
993 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
1016 return mapCryptedKeys.count(address) > 0;
1026 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1027 if (mi != mapCryptedKeys.end())
1029 const CPubKey &vchPubKey = (*mi).second.first;
1030 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
1032 return DecryptKey(encryption_key, vchCryptedSecret, vchPubKey, keyOut);
1043 auto it = mapKeyMetadata.find(keyID);
1044 if (it == mapKeyMetadata.end()) {
1061 WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
1062 if (it != mapWatchKeys.end()) {
1063 pubkey_out = it->second;
1079 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1080 if (mi != mapCryptedKeys.end())
1082 vchPubKeyOut = (*mi).second.first;
1099 int64_t nCreationTime =
GetTime();
1117 mapKeyMetadata[pubkey.
GetID()] = metadata;
1121 throw std::runtime_error(std::string(__func__) +
": AddKey failed");
1128 if (!key_in.
Derive(key_out, index)) {
1129 throw std::runtime_error(
"Could not derive extended key");
1144 throw std::runtime_error(std::string(__func__) +
": seed not found");
1178 secret = childKey.
key;
1185 throw std::runtime_error(std::string(__func__) +
": writing HD chain model failed");
1192 set_pre_split_keypool.insert(nIndex);
1194 setInternalKeyPool.insert(nIndex);
1196 setExternalKeyPool.insert(nIndex);
1198 m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
1205 if (mapKeyMetadata.count(keyid) == 0)
1225 int64_t nCreationTime =
GetTime();
1241 mapKeyMetadata[seed.
GetID()] = metadata;
1245 throw std::runtime_error(std::string(__func__) +
": AddKeyPubKey failed");
1279 for (
const int64_t nIndex : setInternalKeyPool) {
1282 setInternalKeyPool.clear();
1284 for (
const int64_t nIndex : setExternalKeyPool) {
1287 setExternalKeyPool.clear();
1289 for (
const int64_t nIndex : set_pre_split_keypool) {
1292 set_pre_split_keypool.clear();
1299 WalletLogPrintf(
"LegacyScriptPubKeyMan::NewKeyPool rewrote keypool\n");
1311 if (!batch.
TxnBegin())
return false;
1335 unsigned int nTargetSize;
1337 nTargetSize = kpSize;
1339 nTargetSize = m_keypool_size;
1341 int64_t target = std::max((int64_t) nTargetSize, int64_t{1});
1345 int64_t missingExternal;
1346 int64_t missingInternal;
1348 missingExternal = std::max(target - (int64_t)setExternalKeyPool.size(), int64_t{0});
1349 missingInternal = std::max(target - (int64_t)setInternalKeyPool.size(), int64_t{0});
1357 missingInternal = 0;
1359 bool internal =
false;
1360 for (int64_t i = missingInternal + missingExternal; i--;) {
1361 if (i < missingInternal) {
1370 if (missingInternal + missingExternal > 0) {
1372 WalletLogPrintf(
"keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size(), setInternalKeyPool.size());
1374 WalletLogPrintf(
"inactive seed with id %s added %d external keys, %d internal keys\n",
HexStr(chain.
seed_id), missingExternal, missingInternal);
1383 assert(m_max_keypool_index < std::numeric_limits<int64_t>::max());
1384 int64_t index = ++m_max_keypool_index;
1386 throw std::runtime_error(std::string(__func__) +
": writing imported pubkey failed");
1389 setInternalKeyPool.insert(index);
1391 setExternalKeyPool.insert(index);
1416 setInternalKeyPool.insert(nIndex);
1417 }
else if (!set_pre_split_keypool.empty()) {
1418 set_pre_split_keypool.insert(nIndex);
1420 setExternalKeyPool.insert(nIndex);
1460 bool fReturningInternal = fRequestedInternal;
1462 bool use_split_keypool = set_pre_split_keypool.empty();
1463 std::set<int64_t>& setKeyPool = use_split_keypool ? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) : set_pre_split_keypool;
1466 if (setKeyPool.empty()) {
1472 auto it = setKeyPool.begin();
1474 setKeyPool.erase(it);
1475 if (!batch.
ReadPool(nIndex, keypool)) {
1476 throw std::runtime_error(std::string(__func__) +
": read failed");
1480 throw std::runtime_error(std::string(__func__) +
": unknown key in key pool");
1483 if (use_split_keypool && keypool.
fInternal != fReturningInternal) {
1484 throw std::runtime_error(std::string(__func__) +
": keypool entry misclassified");
1487 throw std::runtime_error(std::string(__func__) +
": keypool entry invalid");
1507 assert(desc && desc->IsSolvable());
1521 bool internal = setInternalKeyPool.count(keypool_id);
1522 if (!internal)
assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id));
1523 std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
1524 auto it = setKeyPool->begin();
1526 std::vector<CKeyPool> result;
1528 while (it != std::end(*setKeyPool)) {
1529 const int64_t& index = *(it);
1530 if (index > keypool_id)
break;
1533 if (batch.
ReadPool(index, keypool)) {
1539 it = setKeyPool->erase(it);
1540 result.push_back(std::move(keypool));
1548 std::vector<CScript> dummy;
1551 std::vector<CKeyID>
ret;
1552 ret.reserve(
out.pubkeys.size());
1553 for (
const auto& entry :
out.pubkeys) {
1554 ret.push_back(entry.first);
1562 for (
auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) {
1563 int64_t index = *it;
1565 if (!batch.
ReadPool(index, keypool)) {
1566 throw std::runtime_error(std::string(__func__) +
": read keypool entry failed");
1570 throw std::runtime_error(std::string(__func__) +
": writing modified keypool entry failed");
1572 set_pre_split_keypool.insert(index);
1573 it = setExternalKeyPool.erase(it);
1598 mapKeyMetadata[pubkey.
GetID()].key_origin.path = info.
path;
1599 mapKeyMetadata[pubkey.
GetID()].has_key_origin =
true;
1607 for (
const auto& entry : scripts) {
1617 if (timestamp > 0) {
1618 m_script_metadata[
CScriptID(entry)].nCreateTime = timestamp;
1621 if (timestamp > 0) {
1631 for (
const auto& entry : privkey_map) {
1632 const CKey& key = entry.second;
1634 const CKeyID&
id = entry.first;
1641 mapKeyMetadata[id].nCreateTime = timestamp;
1651bool LegacyScriptPubKeyMan::ImportPubKeys(
const std::vector<std::pair<CKeyID, bool>>& ordered_pubkeys,
const std::map<CKeyID, CPubKey>& pubkey_map,
const std::map<
CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins,
const bool add_keypool,
const int64_t timestamp)
1654 for (
const auto& entry : key_origins) {
1657 for (
const auto& [
id, internal] : ordered_pubkeys) {
1658 auto entry = pubkey_map.find(
id);
1659 if (entry == pubkey_map.end()) {
1662 const CPubKey& pubkey = entry->second;
1672 mapKeyMetadata[id].nCreateTime = timestamp;
1702 std::set<CKeyID> set_address;
1703 for (
const auto& mi : mapCryptedKeys) {
1704 set_address.insert(mi.first);
1712 std::unordered_set<CScript, SaltedSipHasher> candidate_spks;
1715 const auto& add_pubkey = [&candidate_spks](
const CPubKey& pub) ->
void {
1720 candidate_spks.insert(wpkh);
1723 for (
const auto& [
_, key] : mapKeys) {
1724 add_pubkey(key.GetPubKey());
1726 for (
const auto& [
_, ckeypair] : mapCryptedKeys) {
1727 add_pubkey(ckeypair.first);
1734 const auto& add_script = [&candidate_spks](
const CScript&
script) ->
void {
1735 candidate_spks.insert(
script);
1739 candidate_spks.insert(wsh);
1742 for (
const auto& [
_,
script] : mapScripts) {
1748 for (
const auto&
script : setWatchOnly) {
1752 return candidate_spks;
1760 std::unordered_set<CScript, SaltedSipHasher> spks;
1773 std::unordered_set<CScript, SaltedSipHasher> spks;
1784 return std::nullopt;
1792 std::set<CKeyID> keyids;
1793 for (
const auto& key_pair : mapKeys) {
1794 keyids.insert(key_pair.first);
1796 for (
const auto& key_pair : mapCryptedKeys) {
1797 keyids.insert(key_pair.first);
1802 for (
auto keyid_it = keyids.begin(); keyid_it != keyids.end();) {
1803 const CKeyID& keyid = *keyid_it;
1804 const auto& it = mapKeyMetadata.find(keyid);
1805 if (it != mapKeyMetadata.end()) {
1812 keyid_it = keyids.erase(keyid_it);
1821 LogPrintf(
"Error generating descriptors for migration, cannot initialize db transaction\n");
1822 return std::nullopt;
1826 for (
const CKeyID& keyid : keyids) {
1828 if (!
GetKey(keyid, key)) {
1833 uint64_t creation_time = 0;
1834 const auto& it = mapKeyMetadata.find(keyid);
1835 if (it != mapKeyMetadata.end()) {
1836 creation_time = it->second.nCreateTime;
1846 std::string desc_str =
"combo(" + origin_str +
HexStr(key.
GetPubKey()) +
")";
1849 std::vector<std::unique_ptr<Descriptor>> descs =
Parse(desc_str, keys, error,
false);
1854 auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(
m_storage, w_desc, 0);
1855 WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, key, key.
GetPubKey()));
1856 desc_spk_man->TopUpWithDB(batch);
1857 auto desc_spks = desc_spk_man->GetScriptPubKeys();
1860 for (
const CScript& spk : desc_spks) {
1861 size_t erased = spks.erase(spk);
1866 out.desc_spkms.push_back(std::move(desc_spk_man));
1870 std::vector<CHDChain> chains;
1873 chains.push_back(chain_pair.second);
1875 for (
const CHDChain& chain : chains) {
1876 for (
int i = 0; i < 2; ++i) {
1883 if (!
GetKey(chain.seed_id, seed_key)) {
1891 std::string desc_str =
"combo(" + xpub +
"/0h/" +
ToString(i) +
"h/*h)";
1894 std::vector<std::unique_ptr<Descriptor>> descs =
Parse(desc_str, keys, error,
false);
1896 uint32_t chain_counter = std::max((i == 1 ? chain.nInternalChainCounter : chain.nExternalChainCounter), (uint32_t)0);
1900 auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(
m_storage, w_desc, 0);
1901 WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, master_key.
key, master_key.
key.
GetPubKey()));
1902 desc_spk_man->TopUpWithDB(batch);
1903 auto desc_spks = desc_spk_man->GetScriptPubKeys();
1906 for (
const CScript& spk : desc_spks) {
1907 size_t erased = spks.erase(spk);
1912 out.desc_spkms.push_back(std::move(desc_spk_man));
1921 out.master_key.SetSeed(seed_key);
1925 for (
auto it = spks.begin(); it != spks.end();) {
1929 uint64_t creation_time = 0;
1930 const auto& mit = m_script_metadata.find(
CScriptID(spk));
1931 if (mit != m_script_metadata.end()) {
1932 creation_time = mit->second.nCreateTime;
1941 std::string desc_str = desc->ToString();
1943 std::string parse_error;
1944 std::vector<std::unique_ptr<Descriptor>> parsed_descs =
Parse(desc_str, parsed_keys, parse_error);
1945 if (parsed_descs.empty()) {
1947 it = spks.erase(it);
1953 std::vector<CScript> scripts;
1958 std::set<CKeyID> privkeyids;
1959 for (
const auto& key_orig_pair : keys.
origins) {
1960 privkeyids.insert(key_orig_pair.first);
1963 std::vector<CScript> desc_spks;
1966 std::string desc_str;
1967 bool watchonly = !desc->ToPrivateString(*
this, desc_str);
1969 out.watch_descs.emplace_back(desc->ToString(), creation_time);
1973 desc->Expand(0, provider, desc_spks, provider);
1977 auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(
m_storage, w_desc, 0);
1978 for (
const auto& keyid : privkeyids) {
1980 if (!
GetKey(keyid, key)) {
1983 WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, key, key.
GetPubKey()));
1985 desc_spk_man->TopUpWithDB(batch);
1986 auto desc_spks_set = desc_spk_man->GetScriptPubKeys();
1987 desc_spks.insert(desc_spks.end(), desc_spks_set.begin(), desc_spks_set.end());
1989 out.desc_spkms.push_back(std::move(desc_spk_man));
1993 for (
const CScript& desc_spk : desc_spks) {
1994 auto del_it = spks.find(desc_spk);
1995 assert(del_it != spks.end());
1997 it = spks.erase(del_it);
2002 if (!
Assume(spks.empty())) {
2004 return std::nullopt;
2014 if (!
script.IsPayToScriptHash() && !
script.IsPayToWitnessScriptHash()) {
2026 uint64_t creation_time = 0;
2028 if (it != m_script_metadata.end()) {
2029 creation_time = it->second.nCreateTime;
2034 if (!desc->IsSolvable()) {
2043 std::string desc_str = desc->ToString();
2045 std::string parse_error;
2046 std::vector<std::unique_ptr<Descriptor>> parsed_descs =
Parse(desc_str, parsed_keys, parse_error,
false);
2047 if (parsed_descs.empty()) {
2052 out.solvable_descs.emplace_back(desc->ToString(), creation_time);
2057 LogPrintf(
"Error generating descriptors for migration, cannot commit db transaction\n");
2058 return std::nullopt;
2067 return DeleteRecordsWithDB(batch);
2085 assert(m_wallet_descriptor.descriptor->IsSingleType());
2086 std::optional<OutputType> desc_addr_type = m_wallet_descriptor.descriptor->GetOutputType();
2088 if (type != *desc_addr_type) {
2089 throw std::runtime_error(std::string(__func__) +
": Types are inconsistent. Stored type does not match type of newly generated address");
2096 std::vector<CScript> scripts_temp;
2099 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2101 if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2103 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2108 return util::Error{
_(
"Error: Cannot extract destination from the generated scriptpubkey")};
2110 m_wallet_descriptor.next_index++;
2119 if (m_map_script_pub_keys.count(
script) > 0) {
2128 if (!m_map_keys.empty()) {
2132 bool keyPass = m_map_crypted_keys.empty();
2133 bool keyFail =
false;
2134 for (
const auto& mi : m_map_crypted_keys) {
2135 const CPubKey &pubkey = mi.second.first;
2136 const std::vector<unsigned char> &crypted_secret = mi.second.second;
2138 if (!
DecryptKey(master_key, crypted_secret, pubkey, key)) {
2146 if (keyPass && keyFail) {
2147 LogPrintf(
"The wallet is probably corrupted: Some keys decrypt but not all.\n");
2148 throw std::runtime_error(
"Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
2150 if (keyFail || !keyPass) {
2160 if (!m_map_crypted_keys.empty()) {
2164 for (
const KeyMap::value_type& key_in : m_map_keys)
2166 const CKey &key = key_in.second;
2169 std::vector<unsigned char> crypted_secret;
2173 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2184 index = m_wallet_descriptor.next_index - 1;
2192 if (m_wallet_descriptor.next_index - 1 == index) {
2193 m_wallet_descriptor.next_index--;
2204 for (
const auto& key_pair : m_map_crypted_keys) {
2205 const CPubKey& pubkey = key_pair.second.first;
2206 const std::vector<unsigned char>& crypted_secret = key_pair.second.second;
2209 return DecryptKey(encryption_key, crypted_secret, pubkey, key);
2211 keys[pubkey.
GetID()] = key;
2221 return m_map_keys.contains(keyid) || m_map_crypted_keys.contains(keyid);
2228 const auto& it = m_map_crypted_keys.find(keyid);
2229 if (it == m_map_crypted_keys.end()) {
2230 return std::nullopt;
2232 const std::vector<unsigned char>& crypted_secret = it->second.second;
2235 return DecryptKey(encryption_key, crypted_secret, it->second.first, key);
2237 return std::nullopt;
2241 const auto& it = m_map_keys.find(keyid);
2242 if (it == m_map_keys.end()) {
2243 return std::nullopt;
2251 if (!batch.
TxnBegin())
return false;
2260 std::set<CScript> new_spks;
2261 unsigned int target_size;
2265 target_size = m_keypool_size;
2269 int32_t new_range_end = std::max(m_wallet_descriptor.next_index + (int32_t)target_size, m_wallet_descriptor.range_end);
2272 if (!m_wallet_descriptor.descriptor->IsRange()) {
2274 m_wallet_descriptor.range_end = 1;
2275 m_wallet_descriptor.range_start = 0;
2284 std::vector<CScript> scripts_temp;
2287 if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2288 if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache))
return false;
2291 new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2293 m_map_script_pub_keys[
script] = i;
2295 for (
const auto& pk_pair : out_keys.
pubkeys) {
2296 const CPubKey& pubkey = pk_pair.second;
2297 if (m_map_pubkeys.count(pubkey) != 0) {
2302 m_map_pubkeys[pubkey] = i;
2307 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2311 m_wallet_descriptor.range_end = new_range_end;
2325 std::vector<WalletDestination> result;
2327 int32_t index = m_map_script_pub_keys[
script];
2328 if (index >= m_wallet_descriptor.next_index) {
2329 WalletLogPrintf(
"%s: Detected a used keypool item at index %d, mark all keypool items up to this item as used\n", __func__, index);
2330 auto out_keys = std::make_unique<FlatSigningProvider>();
2331 std::vector<CScript> scripts_temp;
2332 while (index >= m_wallet_descriptor.next_index) {
2333 if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) {
2334 throw std::runtime_error(std::string(__func__) +
": Unable to expand descriptor from cache");
2338 result.push_back({dest, std::nullopt});
2339 m_wallet_descriptor.next_index++;
2343 WalletLogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
2355 throw std::runtime_error(std::string(__func__) +
": writing descriptor private key failed");
2365 if (m_map_keys.find(pubkey.
GetID()) != m_map_keys.end() ||
2366 m_map_crypted_keys.find(pubkey.
GetID()) != m_map_crypted_keys.end()) {
2375 std::vector<unsigned char> crypted_secret;
2378 return EncryptSecret(encryption_key, secret, pubkey.GetHash(), crypted_secret);
2383 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2386 m_map_keys[pubkey.
GetID()] = key;
2397 if (m_wallet_descriptor.descriptor) {
2405 throw std::runtime_error(std::string(__func__) +
": writing descriptor master private key failed");
2408 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2421 return m_wallet_descriptor.descriptor->IsRange();
2429 return m_wallet_descriptor.descriptor->IsSingleType() &&
2430 m_wallet_descriptor.descriptor->IsRange() &&
2431 (
HavePrivateKeys() || m_wallet_descriptor.next_index < m_wallet_descriptor.range_end);
2437 return m_map_keys.size() > 0 || m_map_crypted_keys.size() > 0;
2443 return !m_map_crypted_keys.empty();
2449 return std::nullopt;
2456 return m_wallet_descriptor.range_end - m_wallet_descriptor.next_index;
2462 return m_wallet_descriptor.creation_time;
2470 auto it = m_map_script_pub_keys.find(
script);
2471 if (it == m_map_script_pub_keys.end()) {
2474 int32_t index = it->second;
2484 auto it = m_map_pubkeys.find(pubkey);
2485 if (it == m_map_pubkeys.end()) {
2488 int32_t index = it->second;
2492 if (!
out->HaveKey(pubkey.
GetID())) {
2502 std::unique_ptr<FlatSigningProvider> out_keys = std::make_unique<FlatSigningProvider>();
2510 std::vector<CScript> scripts_temp;
2511 if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys))
return nullptr;
2520 m_wallet_descriptor.descriptor->ExpandPrivate(index, master_provider, *out_keys);
2538 std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2539 for (
const auto& coin_pair : coins) {
2540 std::unique_ptr<FlatSigningProvider> coin_keys =
GetSigningProvider(coin_pair.second.out.scriptPubKey,
true);
2544 keys->Merge(std::move(*coin_keys));
2558 if (!keys->GetKey(
ToKeyID(pkhash), key)) {
2573 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
2574 const CTxIn& txin = psbtx.
tx->vin[i];
2583 return PSBTError::SIGHASH_MISMATCH;
2592 return PSBTError::MISSING_INPUTS;
2600 std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2603 keys->Merge(std::move(*script_keys));
2606 std::vector<CPubKey> pubkeys;
2611 pubkeys.push_back(
pk);
2615 std::vector<std::vector<unsigned char>> sols;
2617 sols[0].insert(sols[0].begin(), 0x02);
2618 pubkeys.emplace_back(sols[0]);
2620 pubkeys.emplace_back(sols[0]);
2626 for (
unsigned char prefix : {0x02, 0x03}) {
2627 unsigned char b[33] = {
prefix};
2628 std::copy(pubkey.
begin(), pubkey.
end(), b + 1);
2630 fullpubkey.
Set(b, b + 33);
2631 pubkeys.push_back(fullpubkey);
2635 for (
const auto& pubkey : pubkeys) {
2638 keys->Merge(std::move(*pk_keys));
2646 if (n_signed && (signed_one || !
sign)) {
2655 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
2672 if (provider->GetKeyOrigin(key_id, orig)) {
2674 std::unique_ptr<CKeyMetadata> meta = std::make_unique<CKeyMetadata>();
2675 meta->key_origin = orig;
2676 meta->has_key_origin =
true;
2677 meta->nCreateTime = m_wallet_descriptor.creation_time;
2687 return m_wallet_descriptor.id;
2693 std::set<CScript> new_spks;
2694 m_wallet_descriptor.cache = cache;
2695 for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
2697 std::vector<CScript> scripts_temp;
2698 if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2699 throw std::runtime_error(
"Error: Unable to expand wallet descriptor from cache");
2702 new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2704 if (m_map_script_pub_keys.count(
script) != 0) {
2705 throw std::runtime_error(
strprintf(
"Error: Already loaded script at index %d as being at index %d", i, m_map_script_pub_keys[
script]));
2707 m_map_script_pub_keys[
script] = i;
2709 for (
const auto& pk_pair : out_keys.
pubkeys) {
2710 const CPubKey& pubkey = pk_pair.second;
2711 if (m_map_pubkeys.count(pubkey) != 0) {
2716 m_map_pubkeys[pubkey] = i;
2727 m_map_keys[key_id] = key;
2734 if (!m_map_keys.empty()) {
2738 m_map_crypted_keys[key_id] = make_pair(pubkey, crypted_key);
2745 return !m_wallet_descriptor.id.IsNull() && !desc.
id.
IsNull() && m_wallet_descriptor.id == desc.
id;
2753 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2759 return m_wallet_descriptor;
2770 std::unordered_set<CScript, SaltedSipHasher> script_pub_keys;
2771 script_pub_keys.reserve(m_map_script_pub_keys.size());
2773 for (
auto const& [script_pub_key, index] : m_map_script_pub_keys) {
2774 if (index >= minimum_index) script_pub_keys.insert(script_pub_key);
2776 return script_pub_keys;
2795 return m_wallet_descriptor.descriptor->ToPrivateString(provider,
out);
2798 return m_wallet_descriptor.descriptor->ToNormalizedString(provider,
out, &m_wallet_descriptor.cache);
2809 if (m_wallet_descriptor.cache.GetCachedLastHardenedExtPubKeys().size() > 0) {
2817 std::vector<CScript> scripts_temp;
2819 if (!m_wallet_descriptor.descriptor->Expand(0, provider, scripts_temp, out_keys, &temp_cache)){
2820 throw std::runtime_error(
"Unable to expand descriptor");
2826 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2835 throw std::runtime_error(std::string(__func__) +
": " + error);
2838 m_map_pubkeys.clear();
2839 m_map_script_pub_keys.clear();
2841 m_wallet_descriptor = descriptor;
2850 error =
"can only update matching descriptor";
2854 if (descriptor.
range_start > m_wallet_descriptor.range_start ||
2855 descriptor.
range_end < m_wallet_descriptor.range_end) {
2857 error =
strprintf(
"new range must include current range = [%d,%d]",
2858 m_wallet_descriptor.range_start,
2859 m_wallet_descriptor.range_end - 1);
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
CKeyID ToKeyID(const PKHash &key_hash)
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0'/2000".
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath, bool apostrophe)
Write HD keypaths as strings.
#define CHECK_NONFATAL(condition)
Identity function.
#define STR_INTERNAL_BUG(msg)
#define Assume(val)
Assume is the identity function.
An encapsulated private key.
const std::byte * begin() const
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
CPubKey GetPubKey() const
Compute the public key from a private key.
const std::byte * end() const
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
A reference to a CKey: the Hash160 of its serialized public key.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
uint256 GetHash() const
Get the 256-bit hash of this public key.
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
An input of a transaction.
Cache for single descriptor's derived extended pubkeys.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const override
virtual bool AddCScript(const CScript &redeemScript)
void ImplicitlyLearnRelatedKeyScripts(const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
virtual std::set< CKeyID > GetKeys() const
std::map< CKeyID, CKey > KeyMap
virtual bool HaveCScript(const CScriptID &hash) const override
RecursiveMutex cs_KeyStore
virtual bool HaveKey(const CKeyID &address) const override
An interface to be implemented by keystores that support signing.
const unsigned char * end() const
const unsigned char * begin() const
constexpr bool IsNull() const
constexpr unsigned char * begin()
uint32_t nInternalChainCounter
static const int VERSION_HD_BASE
uint32_t nExternalChainCounter
int64_t m_next_external_index
static const int VERSION_HD_CHAIN_SPLIT
CKeyID seed_id
seed hash160
int64_t m_next_internal_index
A key from a CWallet's keypool.
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
CPubKey vchPubKey
The public key.
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
bool m_pre_split
Whether this key was generated for a keypool before the wallet was upgraded to HD-split.
KeyMap GetKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
std::optional< common::PSBTError > FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const override
Adds script and derivation path information to a PSBT, and optionally signs it.
void SetCache(const DescriptorCache &cache)
std::map< int32_t, FlatSigningProvider > m_map_signing_providers
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that,...
void UpgradeDescriptorCache()
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
std::optional< CKey > GetKey(const CKeyID &keyid) const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
Retrieve the particular key if it is available. Returns nullopt if the key is not in the wallet,...
bool AddCryptedKey(const CKeyID &key_id, const CPubKey &pubkey, const std::vector< unsigned char > &crypted_key)
bool SetupDescriptorGeneration(WalletBatch &batch, const CExtKey &master_key, OutputType addr_type, bool internal)
Setup descriptors based on the given CExtkey.
bool TopUp(unsigned int size=0) override
Fills internal address pool.
bool m_decryption_thoroughly_checked
keeps track of whether Unlock has run a thorough check before
std::map< CKeyID, CKey > KeyMap
unsigned int GetKeyPoolSize() const override
int64_t GetTimeFirstKey() const override
std::unique_ptr< FlatSigningProvider > GetSigningProvider(const CScript &script, bool include_private=false) const
bool HaveCryptedKeys() const override
int32_t GetEndRange() const
bool CheckDecryptionKey(const CKeyingMaterial &master_key) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
bool CanGetAddresses(bool internal=false) const override
bool CanUpdateToWalletDescriptor(const WalletDescriptor &descriptor, std::string &error)
bool GetDescriptorString(std::string &out, const bool priv) const
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
void AddDescriptorKey(const CKey &key, const CPubKey &pubkey)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
bool HavePrivateKeys() const override
bool AddKey(const CKeyID &key_id, const CKey &key)
bool TopUpWithDB(WalletBatch &batch, unsigned int size=0)
Same as 'TopUp' but designed for use within a batch transaction context.
void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr) override
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
bool AddDescriptorKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool HasWalletDescriptor(const WalletDescriptor &desc) const
void UpdateWalletDescriptor(WalletDescriptor &descriptor)
int32_t m_max_cached_index
RecursiveMutex cs_desc_man
std::optional< int64_t > GetOldestKeyPoolTime() const override
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
bool IsHDEnabled() const override
isminetype IsMine(const CScript &script) const override
bool HasPrivKey(const CKeyID &keyid) const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
uint256 GetID() const override
bool DeleteRecordsWithDB(WalletBatch &batch)
isminetype IsMine(const CScript &script) const override
std::optional< MigrationData > MigrateToDescriptor()
Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this Legac...
virtual bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey)
bool DeleteRecords()
Delete all the records of this LegacyScriptPubKeyMan from disk.
std::unordered_set< CScript, SaltedSipHasher > GetCandidateScriptPubKeys() const
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
virtual void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, bool checksum_valid)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
void AddInactiveHDChain(const CHDChain &chain)
bool HaveWatchOnly(const CScript &dest) const
Returns whether the watch-only script is in the wallet.
bool HaveWatchOnly() const
Returns whether there are any watch-only things in the wallet.
bool fDecryptionThoroughlyChecked
keeps track of whether Unlock has run a thorough check before
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
std::map< CKeyID, int64_t > m_pool_key_to_index
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
std::unordered_set< CScript, SaltedSipHasher > GetNotMineScriptPubKeys() const
Retrieves scripts that were imported by bugs into the legacy spkm and are simply invalid,...
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
bool AddWatchOnlyInMem(const CScript &dest)
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
bool CheckDecryptionKey(const CKeyingMaterial &master_key) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
bool GetKey(const CKeyID &address, CKey &keyOut) const override
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
virtual void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that,...
std::unordered_map< CKeyID, CHDChain, SaltedSipHasher > m_inactive_hd_chains
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
bool HaveKey(const CKeyID &address) const override
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
std::vector< CKeyPool > MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Marks all keys in the keypool up to and including the provided key as used.
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata) override
bool CanGenerateKeys() const
bool CanGetAddresses(bool internal=false) const override
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
bool GetKeyFromPool(CPubKey &key, const OutputType type)
Fetches a key from the keypool.
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
size_t KeypoolCountExternalKeys() const
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
void AddHDChain(const CHDChain &chain)
bool AddCScriptWithDB(WalletBatch &batch, const CScript &script)
Adds a script to the store and saves it to disk.
bool AddKeyOriginWithDB(WalletBatch &batch, const CPubKey &pubkey, const KeyOriginInfo &info)
Add a KeyOriginInfo to the wallet.
void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
uint256 GetID() const override
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, and saves it to disk.
bool ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal)
Reserves a key from the keypool and sets nIndex to its index.
void AddKeypoolPubkeyWithDB(const CPubKey &pubkey, const bool internal, WalletBatch &batch)
std::map< int64_t, CKeyID > m_index_to_reserved_key
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
void UpgradeKeyMetadata()
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
bool AddWatchOnly(const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Private version of AddWatchOnly method which does not accept a timestamp, and which will reset the wa...
bool HavePrivateKeys() const override
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata) override
Load metadata (used by LoadWallet)
void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Update wallet first key creation time.
bool TopUp(unsigned int size=0) override
Fills internal address pool.
unsigned int GetKeyPoolSize() const override
bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey) override
bool ImportPubKeys(const std::vector< std::pair< CKeyID, bool > > &ordered_pubkeys, const std::map< CKeyID, CPubKey > &pubkey_map, const std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > &key_origins, const bool add_keypool, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal)
Like TopUp() but adds keys for inactive HD chains.
std::set< CKeyID > GetKeys() const override
bool HaveCryptedKeys() const override
bool IsHDEnabled() const override
bool TopUpChain(WalletBatch &batch, CHDChain &chain, unsigned int size)
bool AddKeyPubKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Adds a key to the store, and saves it to disk.
bool AddCScript(const CScript &redeemScript) override
int64_t GetTimeFirstKey() const override
std::optional< common::PSBTError > FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const override
Adds script and derivation path information to a PSBT, and optionally signs it.
bool NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
CPubKey GenerateNewSeed()
bool SetupGeneration(bool force=false) override
Sets up the key generation stuff, i.e.
void LearnRelatedScripts(const CPubKey &key, OutputType)
Explicitly make the wallet learn the related scripts for outputs to the given key.
void LearnAllRelatedScripts(const CPubKey &key)
Same as LearnRelatedScripts, but when the OutputType is not known (and could be anything).
CPubKey DeriveNewSeed(const CKey &key)
void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, CKey &secret, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
void ReturnDestination(int64_t index, bool internal, const CTxDestination &) override
CPubKey GenerateNewKey(WalletBatch &batch, CHDChain &hd_chain, bool internal=false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Generate a new key.
void SetHDSeed(const CPubKey &key)
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
bool Upgrade(int prev_version, int new_version, bilingual_str &error) override
Upgrades the wallet to the specified version.
void KeepDestination(int64_t index, const OutputType &type) override
void RewriteDB() override
The action to do when the DB needs rewrite.
std::optional< int64_t > GetOldestKeyPoolTime() const override
bool RemoveWatchOnly(const CScript &dest)
Remove a watch only script from the keystore.
bool ImportScriptPubKeys(const std::set< CScript > &script_pub_keys, const bool have_solving_data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
boost::signals2::signal< void(const ScriptPubKeyMan *spkm, int64_t new_birth_time)> NotifyFirstKeyTimeChanged
Birth time changed.
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
void WalletLogPrintf(util::ConstevalFormatString< sizeof...(Params)> wallet_fmt, const Params &... params) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
WalletStorage & m_storage
Access to the wallet database.
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
bool TxnBegin()
Begin a new transaction.
bool TxnCommit()
Commit current transaction.
bool EraseRecords(const std::unordered_set< std::string > &types)
Delete records of the given types.
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, const bool overwrite)
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
bool ReadPool(int64_t nPool, CKeyPool &keypool)
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
bool WriteCryptedDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const std::vector< unsigned char > &secret)
bool WritePool(int64_t nPool, const CKeyPool &keypool)
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
bool ErasePool(int64_t nPool)
bool EraseWatchOnly(const CScript &script)
Descriptor with some wallet metadata.
virtual bool IsWalletFlagSet(uint64_t) const =0
virtual void TopUpCallback(const std::set< CScript > &, ScriptPubKeyMan *)=0
Callback function for after TopUp completes containing any scripts that were added by a SPKMan.
virtual void SetMinVersion(enum WalletFeature, WalletBatch *=nullptr)=0
virtual bool CanSupportFeature(enum WalletFeature) const =0
virtual std::string GetDisplayName() const =0
virtual WalletDatabase & GetDatabase() const =0
virtual void UnsetBlankWalletFlag(WalletBatch &)=0
virtual bool IsLocked() const =0
virtual bool HasEncryptionKeys() const =0
virtual bool WithEncryptionKey(std::function< bool(const CKeyingMaterial &)> cb) const =0
Pass the encryption key to cb().
static UniValue Parse(std::string_view raw)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
@ WITNESS_V0
Witness v0 (P2WPKH and P2WSH); see BIP 141.
CKey GenerateRandomKey(bool compressed) noexcept
std::string EncodeDestination(const CTxDestination &dest)
std::string EncodeExtPubKey(const CExtPubKey &key)
static int sign(const secp256k1_context *ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
const std::unordered_set< std::string > LEGACY_TYPES
static int64_t GetOldestKeyTimeInPool(const std::set< int64_t > &setKeyPool, WalletBatch &batch)
std::vector< unsigned char > valtype
static bool RunWithinTxn(WalletBatch &batch, std::string_view process_desc, const std::function< bool(WalletBatch &)> &func)
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
static const std::unordered_set< OutputType > LEGACY_OUTPUT_TYPES
OutputTypes supported by the LegacyScriptPubKeyMan.
const uint32_t BIP32_HARDENED_KEY_LIMIT
Value for the first BIP 32 hardened derivation. Can be used as a bit mask and as a value....
static constexpr int64_t UNKNOWN_TIME
Constant representing an unknown spkm creation time.
static void DeriveExtKey(CExtKey &key_in, unsigned int index, CExtKey &key_out)
Try to derive an extended key, throw if it fails.
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
bool DecryptKey(const CKeyingMaterial &master_key, const std::span< const unsigned char > crypted_secret, const CPubKey &pub_key, CKey &key)
static bool ExtractPubKey(const CScript &dest, CPubKey &pubKeyOut)
@ FEATURE_PRE_SPLIT_KEYPOOL
bool EncryptSecret(const CKeyingMaterial &vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256 &nIV, std::vector< unsigned char > &vchCiphertext)
bool IsFeatureSupported(int wallet_version, int feature_version)
@ WALLET_FLAG_LAST_HARDENED_XPUB_CACHED
@ WALLET_FLAG_KEY_ORIGIN_METADATA
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
@ WALLET_FLAG_BLANK_WALLET
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses,...
WalletDescriptor GenerateWalletDescriptor(const CExtPubKey &master_key, const OutputType &addr_type, bool internal)
is a home for public enum and struct type definitions that are used internally by node code,...
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
bool SignPSBTInput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index, const PrecomputedTransactionData *txdata, int sighash, SignatureData *out_sigdata, bool finalize)
Signs a PSBTInput, verifying that all provided data matches what is being signed.
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed by checking for non-null finalized fields.
void SignTransaction(CMutableTransaction &mtx, const SigningProvider *keystore, const std::map< COutPoint, Coin > &coins, const UniValue &hashType, UniValue &result)
Sign a transaction with the given keystore and previous transactions.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
const SigningProvider & DUMMY_SIGNING_PROVIDER
CKeyID GetKeyForDestination(const SigningProvider &store, const CTxDestination &dest)
Return the CKeyID of the key involved in a script (if there is a unique one).
@ PRIVATE_KEY_NOT_AVAILABLE
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
@ WITNESS_UNKNOWN
Only for Witness versions not already defined above.
@ ANCHOR
anyone can spend script
@ NULL_DATA
unspendable OP_RETURN script that carries data
unsigned char * UCharCast(char *c)
CExtPubKey Neuter() const
bool Derive(CExtKey &out, unsigned int nChild) const
void SetSeed(Span< const std::byte > seed)
A mutable version of CTransaction.
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
std::map< CKeyID, CPubKey > pubkeys
std::map< CKeyID, CKey > keys
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
std::vector< uint32_t > path
A version of CTransaction with the PSBT format.
std::vector< PSBTInput > inputs
std::optional< CMutableTransaction > tx
std::map< CKeyID, SigPair > signatures
BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a ...
struct containing information needed for migrating legacy wallets to descriptor wallets
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
consteval auto _(util::TranslatedLiteral str)