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 setInternalKeyPool.clear();
532 setExternalKeyPool.clear();
540 if (setKeyPool.empty()) {
545 int64_t nIndex = *(setKeyPool.begin());
546 if (!batch.
ReadPool(nIndex, keypool)) {
547 throw std::runtime_error(std::string(__func__) +
": read oldest key in keypool failed");
550 return keypool.
nTime;
563 if (!set_pre_split_keypool.empty()) {
574 return setExternalKeyPool.size() + set_pre_split_keypool.size();
580 return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size();
586 return nTimeFirstKey;
591 return std::make_unique<LegacySigningProvider>(*
this);
596 IsMineResult ismine = IsMineInner(*
this,
script, IsMineSigVersion::TOP,
false);
597 if (ismine == IsMineResult::SPENDABLE || ismine == IsMineResult::WATCH_ONLY) {
607 bool has_privkeys =
false;
608 for (
const auto& key_sig_pair : sigdata.
signatures) {
609 has_privkeys |=
HaveKey(key_sig_pair.first);
640 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
641 const CTxIn& txin = psbtx.
tx->vin[i];
650 return PSBTError::SIGHASH_MISMATCH;
656 return PSBTError::MISSING_INPUTS;
665 if (n_signed && (signed_one || !
sign)) {
674 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
687 auto it = mapKeyMetadata.find(key_id);
688 if (it != mapKeyMetadata.end()) {
689 return std::make_unique<CKeyMetadata>(it->second);
694 auto it = m_script_metadata.find(
CScriptID(scriptPubKey));
695 if (it != m_script_metadata.end()) {
696 return std::make_unique<CKeyMetadata>(it->second);
714 if (nCreateTime <= 1) {
718 }
else if (nTimeFirstKey ==
UNKNOWN_TIME || nCreateTime < nTimeFirstKey) {
719 nTimeFirstKey = nCreateTime;
747 bool needsDB = !encrypted_batch;
749 encrypted_batch = &batch;
752 if (needsDB) encrypted_batch =
nullptr;
755 if (needsDB) encrypted_batch =
nullptr;
772 mapKeyMetadata[pubkey.
GetID()]);
785 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);
795 mapKeyMetadata[keyID] = meta;
808 m_script_metadata[script_id] = meta;
835 std::vector<unsigned char> vchCryptedSecret;
838 return EncryptSecret(encryption_key, vchSecret, pubkey.GetHash(), vchCryptedSecret);
852 if (!checksum_valid) {
864 mapCryptedKeys[vchPubKey.
GetID()] = make_pair(vchPubKey, vchCryptedSecret);
870 const std::vector<unsigned char> &vchCryptedSecret)
877 return encrypted_batch->WriteCryptedKey(vchPubKey,
879 mapKeyMetadata[vchPubKey.
GetID()]);
883 mapKeyMetadata[vchPubKey.
GetID()]);
890 return setWatchOnly.count(dest) > 0;
896 return (!setWatchOnly.empty());
901 std::vector<std::vector<unsigned char>> solutions;
903 (pubKeyOut =
CPubKey(solutions[0])).IsFullyValid();
910 setWatchOnly.erase(dest);
913 mapWatchKeys.erase(pubKey.
GetID());
935 setWatchOnly.insert(dest);
938 mapWatchKeys[pubKey.
GetID()] = pubKey;
960 m_script_metadata[
CScriptID(dest)].nCreateTime = create_time;
972 m_script_metadata[
CScriptID(dest)].nCreateTime = nCreateTime;
987 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
1010 return mapCryptedKeys.count(address) > 0;
1020 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1021 if (mi != mapCryptedKeys.end())
1023 const CPubKey &vchPubKey = (*mi).second.first;
1024 const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
1026 return DecryptKey(encryption_key, vchCryptedSecret, vchPubKey, keyOut);
1037 auto it = mapKeyMetadata.find(keyID);
1038 if (it == mapKeyMetadata.end()) {
1055 WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
1056 if (it != mapWatchKeys.end()) {
1057 pubkey_out = it->second;
1073 CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
1074 if (mi != mapCryptedKeys.end())
1076 vchPubKeyOut = (*mi).second.first;
1093 int64_t nCreationTime =
GetTime();
1111 mapKeyMetadata[pubkey.
GetID()] = metadata;
1115 throw std::runtime_error(std::string(__func__) +
": AddKey failed");
1122 if (!key_in.
Derive(key_out, index)) {
1123 throw std::runtime_error(
"Could not derive extended key");
1138 throw std::runtime_error(std::string(__func__) +
": seed not found");
1172 secret = childKey.
key;
1179 throw std::runtime_error(std::string(__func__) +
": writing HD chain model failed");
1186 set_pre_split_keypool.insert(nIndex);
1188 setInternalKeyPool.insert(nIndex);
1190 setExternalKeyPool.insert(nIndex);
1192 m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
1199 if (mapKeyMetadata.count(keyid) == 0)
1219 int64_t nCreationTime =
GetTime();
1235 mapKeyMetadata[seed.
GetID()] = metadata;
1239 throw std::runtime_error(std::string(__func__) +
": AddKeyPubKey failed");
1273 for (
const int64_t nIndex : setInternalKeyPool) {
1276 setInternalKeyPool.clear();
1278 for (
const int64_t nIndex : setExternalKeyPool) {
1281 setExternalKeyPool.clear();
1283 for (
const int64_t nIndex : set_pre_split_keypool) {
1286 set_pre_split_keypool.clear();
1293 WalletLogPrintf(
"LegacyScriptPubKeyMan::NewKeyPool rewrote keypool\n");
1305 if (!batch.
TxnBegin())
return false;
1329 unsigned int nTargetSize;
1331 nTargetSize = kpSize;
1333 nTargetSize = m_keypool_size;
1335 int64_t target = std::max((int64_t) nTargetSize, int64_t{1});
1339 int64_t missingExternal;
1340 int64_t missingInternal;
1342 missingExternal = std::max(target - (int64_t)setExternalKeyPool.size(), int64_t{0});
1343 missingInternal = std::max(target - (int64_t)setInternalKeyPool.size(), int64_t{0});
1351 missingInternal = 0;
1353 bool internal =
false;
1354 for (int64_t i = missingInternal + missingExternal; i--;) {
1355 if (i < missingInternal) {
1364 if (missingInternal + missingExternal > 0) {
1366 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());
1368 WalletLogPrintf(
"inactive seed with id %s added %d external keys, %d internal keys\n",
HexStr(chain.
seed_id), missingExternal, missingInternal);
1377 assert(m_max_keypool_index < std::numeric_limits<int64_t>::max());
1378 int64_t index = ++m_max_keypool_index;
1380 throw std::runtime_error(std::string(__func__) +
": writing imported pubkey failed");
1383 setInternalKeyPool.insert(index);
1385 setExternalKeyPool.insert(index);
1410 setInternalKeyPool.insert(nIndex);
1411 }
else if (!set_pre_split_keypool.empty()) {
1412 set_pre_split_keypool.insert(nIndex);
1414 setExternalKeyPool.insert(nIndex);
1454 bool fReturningInternal = fRequestedInternal;
1456 bool use_split_keypool = set_pre_split_keypool.empty();
1457 std::set<int64_t>& setKeyPool = use_split_keypool ? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) : set_pre_split_keypool;
1460 if (setKeyPool.empty()) {
1466 auto it = setKeyPool.begin();
1468 setKeyPool.erase(it);
1469 if (!batch.
ReadPool(nIndex, keypool)) {
1470 throw std::runtime_error(std::string(__func__) +
": read failed");
1474 throw std::runtime_error(std::string(__func__) +
": unknown key in key pool");
1477 if (use_split_keypool && keypool.
fInternal != fReturningInternal) {
1478 throw std::runtime_error(std::string(__func__) +
": keypool entry misclassified");
1481 throw std::runtime_error(std::string(__func__) +
": keypool entry invalid");
1501 assert(desc && desc->IsSolvable());
1515 bool internal = setInternalKeyPool.count(keypool_id);
1516 if (!internal)
assert(setExternalKeyPool.count(keypool_id) || set_pre_split_keypool.count(keypool_id));
1517 std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
1518 auto it = setKeyPool->begin();
1520 std::vector<CKeyPool> result;
1522 while (it != std::end(*setKeyPool)) {
1523 const int64_t& index = *(it);
1524 if (index > keypool_id)
break;
1527 if (batch.
ReadPool(index, keypool)) {
1533 it = setKeyPool->erase(it);
1534 result.push_back(std::move(keypool));
1542 std::vector<CScript> dummy;
1545 std::vector<CKeyID>
ret;
1546 ret.reserve(
out.pubkeys.size());
1547 for (
const auto& entry :
out.pubkeys) {
1548 ret.push_back(entry.first);
1556 for (
auto it = setExternalKeyPool.begin(); it != setExternalKeyPool.end();) {
1557 int64_t index = *it;
1559 if (!batch.
ReadPool(index, keypool)) {
1560 throw std::runtime_error(std::string(__func__) +
": read keypool entry failed");
1564 throw std::runtime_error(std::string(__func__) +
": writing modified keypool entry failed");
1566 set_pre_split_keypool.insert(index);
1567 it = setExternalKeyPool.erase(it);
1592 mapKeyMetadata[pubkey.
GetID()].key_origin.path = info.
path;
1593 mapKeyMetadata[pubkey.
GetID()].has_key_origin =
true;
1601 for (
const auto& entry : scripts) {
1611 if (timestamp > 0) {
1612 m_script_metadata[
CScriptID(entry)].nCreateTime = timestamp;
1615 if (timestamp > 0) {
1625 for (
const auto& entry : privkey_map) {
1626 const CKey& key = entry.second;
1628 const CKeyID&
id = entry.first;
1635 mapKeyMetadata[id].nCreateTime = timestamp;
1645bool 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)
1648 for (
const auto& entry : key_origins) {
1651 for (
const auto& [
id, internal] : ordered_pubkeys) {
1652 auto entry = pubkey_map.find(
id);
1653 if (entry == pubkey_map.end()) {
1656 const CPubKey& pubkey = entry->second;
1666 mapKeyMetadata[id].nCreateTime = timestamp;
1696 std::set<CKeyID> set_address;
1697 for (
const auto& mi : mapCryptedKeys) {
1698 set_address.insert(mi.first);
1706 std::unordered_set<CScript, SaltedSipHasher> spks;
1709 for (
const auto& key_pair : mapKeys) {
1710 const CPubKey& pub = key_pair.second.GetPubKey();
1714 for (
const auto& key_pair : mapCryptedKeys) {
1715 const CPubKey& pub = key_pair.second.first;
1723 for (
const auto& script_pair : mapScripts) {
1727 if (!
script.IsPayToScriptHash()) {
1732 std::vector<unsigned char> witprog;
1733 if (
script.IsWitnessProgram(wit_ver, witprog) && wit_ver == 0) {
1739 std::vector<std::vector<unsigned char>> sols;
1744 spks.insert(ms_spk);
1764 std::unordered_set<CScript, SaltedSipHasher> spks;
1775 return std::nullopt;
1783 std::set<CKeyID> keyids;
1784 for (
const auto& key_pair : mapKeys) {
1785 keyids.insert(key_pair.first);
1787 for (
const auto& key_pair : mapCryptedKeys) {
1788 keyids.insert(key_pair.first);
1793 for (
auto keyid_it = keyids.begin(); keyid_it != keyids.end();) {
1794 const CKeyID& keyid = *keyid_it;
1795 const auto& it = mapKeyMetadata.find(keyid);
1796 if (it != mapKeyMetadata.end()) {
1803 keyid_it = keyids.erase(keyid_it);
1812 LogPrintf(
"Error generating descriptors for migration, cannot initialize db transaction\n");
1813 return std::nullopt;
1817 for (
const CKeyID& keyid : keyids) {
1819 if (!
GetKey(keyid, key)) {
1824 uint64_t creation_time = 0;
1825 const auto& it = mapKeyMetadata.find(keyid);
1826 if (it != mapKeyMetadata.end()) {
1827 creation_time = it->second.nCreateTime;
1837 std::string desc_str =
"combo(" + origin_str +
HexStr(key.
GetPubKey()) +
")";
1840 std::vector<std::unique_ptr<Descriptor>> descs =
Parse(desc_str, keys, error,
false);
1845 auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(
m_storage, w_desc, 0);
1846 WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, key, key.
GetPubKey()));
1847 desc_spk_man->TopUpWithDB(batch);
1848 auto desc_spks = desc_spk_man->GetScriptPubKeys();
1851 for (
const CScript& spk : desc_spks) {
1852 size_t erased = spks.erase(spk);
1857 out.desc_spkms.push_back(std::move(desc_spk_man));
1861 std::vector<CHDChain> chains;
1864 chains.push_back(chain_pair.second);
1866 for (
const CHDChain& chain : chains) {
1867 for (
int i = 0; i < 2; ++i) {
1874 if (!
GetKey(chain.seed_id, seed_key)) {
1882 std::string desc_str =
"combo(" + xpub +
"/0h/" +
ToString(i) +
"h/*h)";
1885 std::vector<std::unique_ptr<Descriptor>> descs =
Parse(desc_str, keys, error,
false);
1887 uint32_t chain_counter = std::max((i == 1 ? chain.nInternalChainCounter : chain.nExternalChainCounter), (uint32_t)0);
1891 auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(
m_storage, w_desc, 0);
1892 WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, master_key.
key, master_key.
key.
GetPubKey()));
1893 desc_spk_man->TopUpWithDB(batch);
1894 auto desc_spks = desc_spk_man->GetScriptPubKeys();
1897 for (
const CScript& spk : desc_spks) {
1898 size_t erased = spks.erase(spk);
1903 out.desc_spkms.push_back(std::move(desc_spk_man));
1912 out.master_key.SetSeed(seed_key);
1916 for (
auto it = spks.begin(); it != spks.end();) {
1920 uint64_t creation_time = 0;
1921 const auto& mit = m_script_metadata.find(
CScriptID(spk));
1922 if (mit != m_script_metadata.end()) {
1923 creation_time = mit->second.nCreateTime;
1929 std::vector<CScript> scripts;
1934 std::set<CKeyID> privkeyids;
1935 for (
const auto& key_orig_pair : keys.
origins) {
1936 privkeyids.insert(key_orig_pair.first);
1939 std::vector<CScript> desc_spks;
1942 std::string desc_str;
1943 bool watchonly = !desc->ToPrivateString(*
this, desc_str);
1945 out.watch_descs.emplace_back(desc->ToString(), creation_time);
1949 desc->Expand(0, provider, desc_spks, provider);
1953 auto desc_spk_man = std::make_unique<DescriptorScriptPubKeyMan>(
m_storage, w_desc, 0);
1954 for (
const auto& keyid : privkeyids) {
1956 if (!
GetKey(keyid, key)) {
1959 WITH_LOCK(desc_spk_man->cs_desc_man, desc_spk_man->AddDescriptorKeyWithDB(batch, key, key.
GetPubKey()));
1961 desc_spk_man->TopUpWithDB(batch);
1962 auto desc_spks_set = desc_spk_man->GetScriptPubKeys();
1963 desc_spks.insert(desc_spks.end(), desc_spks_set.begin(), desc_spks_set.end());
1965 out.desc_spkms.push_back(std::move(desc_spk_man));
1969 for (
const CScript& desc_spk : desc_spks) {
1970 auto del_it = spks.find(desc_spk);
1971 assert(del_it != spks.end());
1973 it = spks.erase(del_it);
1979 for (
const auto& script_pair : mapScripts) {
1983 uint64_t creation_time = 0;
1985 if (it != m_script_metadata.end()) {
1986 creation_time = it->second.nCreateTime;
1989 std::vector<std::vector<unsigned char>> sols;
2005 std::vector<std::vector<unsigned char>> keys(sols.begin() + 1, sols.begin() + sols.size() - 1);
2014 out.solvable_descs.emplace_back(sh_desc->ToString(), creation_time);
2017 if (desc->IsSolvable()) {
2019 out.solvable_descs.emplace_back(wsh_desc->ToString(), creation_time);
2021 out.solvable_descs.emplace_back(sh_wsh_desc->ToString(), creation_time);
2027 assert(spks.size() == 0);
2031 LogPrintf(
"Error generating descriptors for migration, cannot commit db transaction\n");
2032 return std::nullopt;
2041 return DeleteRecordsWithDB(batch);
2059 assert(m_wallet_descriptor.descriptor->IsSingleType());
2060 std::optional<OutputType> desc_addr_type = m_wallet_descriptor.descriptor->GetOutputType();
2062 if (type != *desc_addr_type) {
2063 throw std::runtime_error(std::string(__func__) +
": Types are inconsistent. Stored type does not match type of newly generated address");
2070 std::vector<CScript> scripts_temp;
2073 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2075 if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2077 return util::Error{
_(
"Error: Keypool ran out, please call keypoolrefill first")};
2082 return util::Error{
_(
"Error: Cannot extract destination from the generated scriptpubkey")};
2084 m_wallet_descriptor.next_index++;
2093 if (m_map_script_pub_keys.count(
script) > 0) {
2102 if (!m_map_keys.empty()) {
2106 bool keyPass = m_map_crypted_keys.empty();
2107 bool keyFail =
false;
2108 for (
const auto& mi : m_map_crypted_keys) {
2109 const CPubKey &pubkey = mi.second.first;
2110 const std::vector<unsigned char> &crypted_secret = mi.second.second;
2112 if (!
DecryptKey(master_key, crypted_secret, pubkey, key)) {
2120 if (keyPass && keyFail) {
2121 LogPrintf(
"The wallet is probably corrupted: Some keys decrypt but not all.\n");
2122 throw std::runtime_error(
"Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
2124 if (keyFail || !keyPass) {
2134 if (!m_map_crypted_keys.empty()) {
2138 for (
const KeyMap::value_type& key_in : m_map_keys)
2140 const CKey &key = key_in.second;
2143 std::vector<unsigned char> crypted_secret;
2147 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2158 index = m_wallet_descriptor.next_index - 1;
2166 if (m_wallet_descriptor.next_index - 1 == index) {
2167 m_wallet_descriptor.next_index--;
2178 for (
const auto& key_pair : m_map_crypted_keys) {
2179 const CPubKey& pubkey = key_pair.second.first;
2180 const std::vector<unsigned char>& crypted_secret = key_pair.second.second;
2183 return DecryptKey(encryption_key, crypted_secret, pubkey, key);
2185 keys[pubkey.
GetID()] = key;
2195 return m_map_keys.contains(keyid) || m_map_crypted_keys.contains(keyid);
2202 const auto& it = m_map_crypted_keys.find(keyid);
2203 if (it == m_map_crypted_keys.end()) {
2204 return std::nullopt;
2206 const std::vector<unsigned char>& crypted_secret = it->second.second;
2209 return DecryptKey(encryption_key, crypted_secret, it->second.first, key);
2211 return std::nullopt;
2215 const auto& it = m_map_keys.find(keyid);
2216 if (it == m_map_keys.end()) {
2217 return std::nullopt;
2225 if (!batch.
TxnBegin())
return false;
2234 std::set<CScript> new_spks;
2235 unsigned int target_size;
2239 target_size = m_keypool_size;
2243 int32_t new_range_end = std::max(m_wallet_descriptor.next_index + (int32_t)target_size, m_wallet_descriptor.range_end);
2246 if (!m_wallet_descriptor.descriptor->IsRange()) {
2248 m_wallet_descriptor.range_end = 1;
2249 m_wallet_descriptor.range_start = 0;
2258 std::vector<CScript> scripts_temp;
2261 if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2262 if (!m_wallet_descriptor.descriptor->Expand(i, provider, scripts_temp, out_keys, &temp_cache))
return false;
2265 new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2267 m_map_script_pub_keys[
script] = i;
2269 for (
const auto& pk_pair : out_keys.
pubkeys) {
2270 const CPubKey& pubkey = pk_pair.second;
2271 if (m_map_pubkeys.count(pubkey) != 0) {
2276 m_map_pubkeys[pubkey] = i;
2281 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2285 m_wallet_descriptor.range_end = new_range_end;
2299 std::vector<WalletDestination> result;
2301 int32_t index = m_map_script_pub_keys[
script];
2302 if (index >= m_wallet_descriptor.next_index) {
2303 WalletLogPrintf(
"%s: Detected a used keypool item at index %d, mark all keypool items up to this item as used\n", __func__, index);
2304 auto out_keys = std::make_unique<FlatSigningProvider>();
2305 std::vector<CScript> scripts_temp;
2306 while (index >= m_wallet_descriptor.next_index) {
2307 if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) {
2308 throw std::runtime_error(std::string(__func__) +
": Unable to expand descriptor from cache");
2312 result.push_back({dest, std::nullopt});
2313 m_wallet_descriptor.next_index++;
2317 WalletLogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
2329 throw std::runtime_error(std::string(__func__) +
": writing descriptor private key failed");
2339 if (m_map_keys.find(pubkey.
GetID()) != m_map_keys.end() ||
2340 m_map_crypted_keys.find(pubkey.
GetID()) != m_map_crypted_keys.end()) {
2349 std::vector<unsigned char> crypted_secret;
2352 return EncryptSecret(encryption_key, secret, pubkey.GetHash(), crypted_secret);
2357 m_map_crypted_keys[pubkey.
GetID()] = make_pair(pubkey, crypted_secret);
2360 m_map_keys[pubkey.
GetID()] = key;
2371 if (m_wallet_descriptor.descriptor) {
2379 throw std::runtime_error(std::string(__func__) +
": writing descriptor master private key failed");
2382 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2395 return m_wallet_descriptor.descriptor->IsRange();
2403 return m_wallet_descriptor.descriptor->IsSingleType() &&
2404 m_wallet_descriptor.descriptor->IsRange() &&
2405 (
HavePrivateKeys() || m_wallet_descriptor.next_index < m_wallet_descriptor.range_end);
2411 return m_map_keys.size() > 0 || m_map_crypted_keys.size() > 0;
2417 return std::nullopt;
2424 return m_wallet_descriptor.range_end - m_wallet_descriptor.next_index;
2430 return m_wallet_descriptor.creation_time;
2438 auto it = m_map_script_pub_keys.find(
script);
2439 if (it == m_map_script_pub_keys.end()) {
2442 int32_t index = it->second;
2452 auto it = m_map_pubkeys.find(pubkey);
2453 if (it == m_map_pubkeys.end()) {
2456 int32_t index = it->second;
2466 std::unique_ptr<FlatSigningProvider> out_keys = std::make_unique<FlatSigningProvider>();
2474 std::vector<CScript> scripts_temp;
2475 if (!m_wallet_descriptor.descriptor->ExpandFromCache(index, m_wallet_descriptor.cache, scripts_temp, *out_keys))
return nullptr;
2484 m_wallet_descriptor.descriptor->ExpandPrivate(index, master_provider, *out_keys);
2502 std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2503 for (
const auto& coin_pair : coins) {
2504 std::unique_ptr<FlatSigningProvider> coin_keys =
GetSigningProvider(coin_pair.second.out.scriptPubKey,
true);
2508 keys->Merge(std::move(*coin_keys));
2522 if (!keys->GetKey(
ToKeyID(pkhash), key)) {
2537 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
2538 const CTxIn& txin = psbtx.
tx->vin[i];
2547 return PSBTError::SIGHASH_MISMATCH;
2556 return PSBTError::MISSING_INPUTS;
2564 std::unique_ptr<FlatSigningProvider> keys = std::make_unique<FlatSigningProvider>();
2567 keys->Merge(std::move(*script_keys));
2570 std::vector<CPubKey> pubkeys;
2575 pubkeys.push_back(
pk);
2579 std::vector<std::vector<unsigned char>> sols;
2581 sols[0].insert(sols[0].begin(), 0x02);
2582 pubkeys.emplace_back(sols[0]);
2584 pubkeys.emplace_back(sols[0]);
2590 for (
unsigned char prefix : {0x02, 0x03}) {
2591 unsigned char b[33] = {
prefix};
2592 std::copy(pubkey.
begin(), pubkey.
end(), b + 1);
2594 fullpubkey.
Set(b, b + 33);
2595 pubkeys.push_back(fullpubkey);
2599 for (
const auto& pubkey : pubkeys) {
2602 keys->Merge(std::move(*pk_keys));
2610 if (n_signed && (signed_one || !
sign)) {
2619 for (
unsigned int i = 0; i < psbtx.
tx->vout.size(); ++i) {
2636 if (provider->GetKeyOrigin(key_id, orig)) {
2638 std::unique_ptr<CKeyMetadata> meta = std::make_unique<CKeyMetadata>();
2639 meta->key_origin = orig;
2640 meta->has_key_origin =
true;
2641 meta->nCreateTime = m_wallet_descriptor.creation_time;
2651 return m_wallet_descriptor.id;
2657 std::set<CScript> new_spks;
2658 m_wallet_descriptor.cache = cache;
2659 for (int32_t i = m_wallet_descriptor.range_start; i < m_wallet_descriptor.range_end; ++i) {
2661 std::vector<CScript> scripts_temp;
2662 if (!m_wallet_descriptor.descriptor->ExpandFromCache(i, m_wallet_descriptor.cache, scripts_temp, out_keys)) {
2663 throw std::runtime_error(
"Error: Unable to expand wallet descriptor from cache");
2666 new_spks.insert(scripts_temp.begin(), scripts_temp.end());
2668 if (m_map_script_pub_keys.count(
script) != 0) {
2669 throw std::runtime_error(
strprintf(
"Error: Already loaded script at index %d as being at index %d", i, m_map_script_pub_keys[
script]));
2671 m_map_script_pub_keys[
script] = i;
2673 for (
const auto& pk_pair : out_keys.
pubkeys) {
2674 const CPubKey& pubkey = pk_pair.second;
2675 if (m_map_pubkeys.count(pubkey) != 0) {
2680 m_map_pubkeys[pubkey] = i;
2691 m_map_keys[key_id] = key;
2698 if (!m_map_keys.empty()) {
2702 m_map_crypted_keys[key_id] = make_pair(pubkey, crypted_key);
2709 return !m_wallet_descriptor.id.IsNull() && !desc.
id.
IsNull() && m_wallet_descriptor.id == desc.
id;
2717 throw std::runtime_error(std::string(__func__) +
": writing descriptor failed");
2723 return m_wallet_descriptor;
2734 std::unordered_set<CScript, SaltedSipHasher> script_pub_keys;
2735 script_pub_keys.reserve(m_map_script_pub_keys.size());
2737 for (
auto const& [script_pub_key, index] : m_map_script_pub_keys) {
2738 if (index >= minimum_index) script_pub_keys.insert(script_pub_key);
2740 return script_pub_keys;
2759 return m_wallet_descriptor.descriptor->ToPrivateString(provider,
out);
2762 return m_wallet_descriptor.descriptor->ToNormalizedString(provider,
out, &m_wallet_descriptor.cache);
2773 if (m_wallet_descriptor.cache.GetCachedLastHardenedExtPubKeys().size() > 0) {
2781 std::vector<CScript> scripts_temp;
2783 if (!m_wallet_descriptor.descriptor->Expand(0, provider, scripts_temp, out_keys, &temp_cache)){
2784 throw std::runtime_error(
"Unable to expand descriptor");
2790 throw std::runtime_error(std::string(__func__) +
": writing cache items failed");
2799 throw std::runtime_error(std::string(__func__) +
": " + error);
2802 m_map_pubkeys.clear();
2803 m_map_script_pub_keys.clear();
2805 m_wallet_descriptor = descriptor;
2814 error =
"can only update matching descriptor";
2818 if (descriptor.
range_start > m_wallet_descriptor.range_start ||
2819 descriptor.
range_end < m_wallet_descriptor.range_end) {
2821 error =
strprintf(
"new range must include current range = [%d,%d]",
2822 m_wallet_descriptor.range_start,
2823 m_wallet_descriptor.range_end - 1);
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
CKeyID ToKeyID(const PKHash &key_hash)
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0'/2000".
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath, bool apostrophe)
Write HD keypaths as strings.
#define CHECK_NONFATAL(condition)
Identity function.
#define Assume(val)
Assume is the identity function.
An encapsulated private key.
const std::byte * begin() const
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
CPubKey GetPubKey() const
Compute the public key from a private key.
const std::byte * end() const
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
A reference to a CKey: the Hash160 of its serialized public key.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
uint256 GetHash() const
Get the 256-bit hash of this public key.
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
An input of a transaction.
Cache for single descriptor's derived extended pubkeys.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const override
virtual bool AddCScript(const CScript &redeemScript)
void ImplicitlyLearnRelatedKeyScripts(const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
virtual std::set< CKeyID > GetKeys() const
std::map< CKeyID, CKey > KeyMap
virtual bool HaveCScript(const CScriptID &hash) const override
RecursiveMutex cs_KeyStore
virtual bool HaveKey(const CKeyID &address) const override
An interface to be implemented by keystores that support signing.
const unsigned char * end() const
const unsigned char * begin() const
constexpr bool IsNull() const
constexpr unsigned char * begin()
uint32_t nInternalChainCounter
static const int VERSION_HD_BASE
uint32_t nExternalChainCounter
int64_t m_next_external_index
static const int VERSION_HD_CHAIN_SPLIT
CKeyID seed_id
seed hash160
int64_t m_next_internal_index
A key from a CWallet's keypool.
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
CPubKey vchPubKey
The public key.
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
bool m_pre_split
Whether this key was generated for a keypool before the wallet was upgraded to HD-split.
KeyMap GetKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
std::optional< common::PSBTError > FillPSBT(PartiallySignedTransaction &psbt, const PrecomputedTransactionData &txdata, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=false, int *n_signed=nullptr, bool finalize=true) const override
Adds script and derivation path information to a PSBT, and optionally signs it.
void SetCache(const DescriptorCache &cache)
std::map< int32_t, FlatSigningProvider > m_map_signing_providers
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that,...
void UpgradeDescriptorCache()
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
std::optional< CKey > GetKey(const CKeyID &keyid) const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
Retrieve the particular key if it is available. Returns nullopt if the key is not in the wallet,...
bool AddCryptedKey(const CKeyID &key_id, const CPubKey &pubkey, const std::vector< unsigned char > &crypted_key)
bool SetupDescriptorGeneration(WalletBatch &batch, const CExtKey &master_key, OutputType addr_type, bool internal)
Setup descriptors based on the given CExtkey.
bool TopUp(unsigned int size=0) override
Fills internal address pool.
bool m_decryption_thoroughly_checked
keeps track of whether Unlock has run a thorough check before
std::map< CKeyID, CKey > KeyMap
unsigned int GetKeyPoolSize() const override
int64_t GetTimeFirstKey() const override
std::unique_ptr< FlatSigningProvider > GetSigningProvider(const CScript &script, bool include_private=false) const
int32_t GetEndRange() const
bool CheckDecryptionKey(const CKeyingMaterial &master_key) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
bool CanGetAddresses(bool internal=false) const override
bool CanUpdateToWalletDescriptor(const WalletDescriptor &descriptor, std::string &error)
bool GetDescriptorString(std::string &out, const bool priv) const
std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const override
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
void AddDescriptorKey(const CKey &key, const CPubKey &pubkey)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
bool HavePrivateKeys() const override
bool AddKey(const CKeyID &key_id, const CKey &key)
bool TopUpWithDB(WalletBatch &batch, unsigned int size=0)
Same as 'TopUp' but designed for use within a batch transaction context.
void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr) override
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
bool AddDescriptorKeyWithDB(WalletBatch &batch, const CKey &key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool HasWalletDescriptor(const WalletDescriptor &desc) const
void UpdateWalletDescriptor(WalletDescriptor &descriptor)
int32_t m_max_cached_index
RecursiveMutex cs_desc_man
std::optional< int64_t > GetOldestKeyPoolTime() const override
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
bool IsHDEnabled() const override
isminetype IsMine(const CScript &script) const override
bool HasPrivKey(const CKeyID &keyid) const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
uint256 GetID() const override
bool DeleteRecordsWithDB(WalletBatch &batch)
isminetype IsMine(const CScript &script) const override
std::optional< MigrationData > MigrateToDescriptor()
Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this Legac...
virtual bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey)
bool DeleteRecords()
Delete all the records of this LegacyScriptPubKeyMan from disk.
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
virtual void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, bool checksum_valid)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
void AddInactiveHDChain(const CHDChain &chain)
bool HaveWatchOnly(const CScript &dest) const
Returns whether the watch-only script is in the wallet.
bool HaveWatchOnly() const
Returns whether there are any watch-only things in the wallet.
bool fDecryptionThoroughlyChecked
keeps track of whether Unlock has run a thorough check before
bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override
std::map< CKeyID, int64_t > m_pool_key_to_index
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override
std::unordered_set< CScript, SaltedSipHasher > GetScriptPubKeys() const override
Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches.
std::unordered_set< CScript, SaltedSipHasher > GetNotMineScriptPubKeys() const
Retrieves scripts that were imported by bugs into the legacy spkm and are simply invalid,...
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
bool AddWatchOnlyInMem(const CScript &dest)
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
bool CheckDecryptionKey(const CKeyingMaterial &master_key) override
Check that the given decryption key is valid for this ScriptPubKeyMan, i.e. it decrypts all of the ke...
bool GetKey(const CKeyID &address, CKey &keyOut) const override
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
virtual void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const override
std::unordered_map< CKeyID, CHDChain, SaltedSipHasher > m_inactive_hd_chains
bool AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
bool HaveKey(const CKeyID &address) const override
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
std::vector< CKeyPool > MarkReserveKeysAsUsed(int64_t keypool_id) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Marks all keys in the keypool up to and including the provided key as used.
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata) override
bool CanGenerateKeys() const
bool CanGetAddresses(bool internal=false) const override
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
util::Result< CTxDestination > GetNewDestination(const OutputType type) override
bool GetKeyFromPool(CPubKey &key, const OutputType type)
Fetches a key from the keypool.
util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool) override
size_t KeypoolCountExternalKeys() const
bool Encrypt(const CKeyingMaterial &master_key, WalletBatch *batch) override
void AddHDChain(const CHDChain &chain)
bool AddCScriptWithDB(WalletBatch &batch, const CScript &script)
Adds a script to the store and saves it to disk.
bool AddKeyOriginWithDB(WalletBatch &batch, const CPubKey &pubkey, const KeyOriginInfo &info)
Add a KeyOriginInfo to the wallet.
void MarkPreSplitKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const override
Sign a message with the given script.
uint256 GetID() const override
bool SignTransaction(CMutableTransaction &tx, const std::map< COutPoint, Coin > &coins, int sighash, std::map< int, bilingual_str > &input_errors) const override
Creates new signatures and adds them to the transaction.
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, and saves it to disk.
bool ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal)
Reserves a key from the keypool and sets nIndex to its index.
void AddKeypoolPubkeyWithDB(const CPubKey &pubkey, const bool internal, WalletBatch &batch)
std::map< int64_t, CKeyID > m_index_to_reserved_key
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
void UpgradeKeyMetadata()
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
bool AddWatchOnly(const CScript &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Private version of AddWatchOnly method which does not accept a timestamp, and which will reset the wa...
bool HavePrivateKeys() const override
std::vector< WalletDestination > MarkUnusedAddresses(const CScript &script) override
Mark unused addresses as being used Affects all keys up to and including the one determined by provid...
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata) override
Load metadata (used by LoadWallet)
void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
Update wallet first key creation time.
bool TopUp(unsigned int size=0) override
Fills internal address pool.
unsigned int GetKeyPoolSize() const override
bool AddKeyPubKeyInner(const CKey &key, const CPubKey &pubkey) override
bool ImportPubKeys(const std::vector< std::pair< CKeyID, bool > > &ordered_pubkeys, const std::map< CKeyID, CPubKey > &pubkey_map, const std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > &key_origins, const bool add_keypool, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore)
bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal)
Like TopUp() but adds keys for inactive HD chains.
bool CanProvide(const CScript &script, SignatureData &sigdata) override
Whether this ScriptPubKeyMan can provide a SigningProvider (via GetSolvingProvider) that,...
std::set< CKeyID > GetKeys() const override
bool 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 by 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.
bilingual_str _(ConstevalStringLiteral str)
Translation function.