6#include <bitcoin-build-config.h>
41const std::string
FLAGS{
"flags"};
44const std::string
KEY{
"key"};
48const std::string
NAME{
"name"};
51const std::string
POOL{
"pool"};
54const std::string
TX{
"tx"};
114 std::vector<unsigned char> vchKey;
115 vchKey.reserve(vchPubKey.
size() + vchPrivKey.size());
116 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
117 vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
123 const std::vector<unsigned char>& vchCryptedSecret,
134 if (!
WriteIC(key, std::make_pair(vchCryptedSecret, checksum),
false)) {
136 std::vector<unsigned char> val;
137 if (!
m_batch->Read(key, val)) {
140 if (!
WriteIC(key, std::make_pair(val, checksum),
true)) {
210 return WriteIC(make_pair(key, type),
id);
216 return EraseIC(make_pair(key, type));
222 std::vector<unsigned char> key;
223 key.reserve(pubkey.
size() + privkey.size());
224 key.insert(key.end(), pubkey.
begin(), pubkey.
end());
225 key.insert(key.end(), privkey.begin(), privkey.end());
247 xpub.
Encode(ser_xpub.data());
254 xpub.
Encode(ser_xpub.data());
261 xpub.
Encode(ser_xpub.data());
273 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
305 strErr =
"Error reading wallet database: CPubKey corrupt";
323 catch (
const std::ios_base::failure&) {}
325 bool fSkipCheck =
false;
330 std::vector<unsigned char> vchKey;
331 vchKey.reserve(vchPubKey.
size() + pkey.size());
332 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
333 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
335 if (
Hash(vchKey) != hash)
337 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
344 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
346 strErr =
"Error reading wallet database: CPrivKey corrupt";
351 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadKey failed";
354 }
catch (
const std::exception& e) {
355 if (strErr.empty()) {
371 strErr =
"Error reading wallet database: CPubKey corrupt";
374 std::vector<unsigned char> vchPrivKey;
375 ssValue >> vchPrivKey;
378 bool checksum_valid =
false;
379 if (!ssValue.
eof()) {
382 if (!(checksum_valid =
Hash(vchPrivKey) == checksum)) {
383 strErr =
"Error reading wallet database: Encrypted key corrupt";
390 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCryptedKey failed";
393 }
catch (
const std::exception& e) {
394 if (strErr.empty()) {
410 ssValue >> kMasterKey;
413 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
420 }
catch (
const std::exception& e) {
421 if (strErr.empty()) {
436 }
catch (
const std::exception& e) {
437 if (strErr.empty()) {
452 pwallet->LoadMinVersion(nMinVersion);
462 if (!pwallet->LoadWalletFlags(
flags)) {
463 pwallet->WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
491 pwallet->
WalletLogPrintf(
"Error getting database cursor for '%s' records\n", key);
501 pwallet->
WalletLogPrintf(
"Error reading next '%s' record for wallet database\n", key);
509 DBErrors record_res = load_func(pwallet, ssKey, ssValue, error);
528 const auto& batch =
wallet.GetDatabase().MakeBatch();
543 wallet.WalletLogPrintf(
"Error getting database cursor for '%s' records", type);
544 throw std::runtime_error(
strprintf(
"Error getting database cursor for '%s' records", type));
563 pwallet->WalletLogPrintf(
"Error: Unexpected legacy entry found in descriptor wallet %s. The wallet might have been tampered with or created with malicious intent.\n", pwallet->GetName());
576 result = std::max(result, hd_chain_res.
m_result);
583 result = std::max(result, key_res.
m_result);
590 result = std::max(result, ckey_res.
m_result);
601 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCScript failed";
602 return DBErrors::NONCRITICAL_ERROR;
606 result = std::max(result, script_res.
m_result);
615 std::map<uint160, CHDChain> hd_chains;
629 bool internal = false;
631 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
632 std::vector<uint32_t> path;
633 if (keyMeta.has_key_origin) {
635 path = keyMeta.key_origin.path;
638 if (!ParseHDKeypath(keyMeta.hdKeypath, path)) {
639 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
640 return DBErrors::NONCRITICAL_ERROR;
648 if (path.size() != 3) {
649 strErr =
"Error reading wallet database: keymeta found with unexpected path";
650 return DBErrors::NONCRITICAL_ERROR;
652 if (path[0] != 0x80000000) {
653 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
654 return DBErrors::NONCRITICAL_ERROR;
656 if (path[1] != 0x80000000 && path[1] != (1 | 0x80000000)) {
657 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
658 return DBErrors::NONCRITICAL_ERROR;
660 if ((path[2] & 0x80000000) == 0) {
661 strErr = strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
662 return DBErrors::NONCRITICAL_ERROR;
664 internal = path[1] == (1 | 0x80000000);
665 index = path[2] & ~0x80000000;
685 result = std::max(result, keymeta_res.m_result);
688 if (!hd_chains.empty()) {
689 LegacyDataSPKM* legacy_spkm = pwallet->GetLegacyDataSPKM();
691 for (
const auto& [hd_seed_id, chain] : hd_chains) {
692 if (hd_seed_id != legacy_spkm->GetHDChain().seed_id) {
693 legacy_spkm->AddInactiveHDChain(chain);
697 pwallet->WalletLogPrintf(
"Inactive HD Chains found but no Legacy ScriptPubKeyMan\n");
710 pwallet->GetOrCreateLegacyDataSPKM()->LoadWatchOnly(
script);
714 result = std::max(result, watch_script_res.m_result);
721 CKeyMetadata keyMeta;
723 pwallet->GetOrCreateLegacyDataSPKM()->LoadScriptMetadata(
CScriptID(
script), keyMeta);
726 result = std::max(result, watch_meta_res.m_result);
738 value >> default_pubkey;
739 }
catch (
const std::exception& e) {
743 if (!default_pubkey.
IsValid()) {
744 err =
"Error reading wallet database: Default Key corrupt";
745 return DBErrors::CORRUPT;
749 result = std::max(result, default_key_res.m_result);
754 err =
"Found unsupported 'wkey' record, try loading with version 0.18";
757 result = std::max(result, wkey_res.m_result);
761 pwallet->WalletLogPrintf(
"Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
762 key_res.m_records, ckey_res.m_records, keymeta_res.m_records, key_res.m_records + ckey_res.m_records);
768template<
typename... Args>
785 DBErrors result = DBErrors::LOAD_OK;
792 }
catch (
const std::ios_base::failure& e) {
793 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
794 strErr += (last_client >
CLIENT_VERSION) ?
"The wallet might had been created on a newer version. " :
795 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
796 strErr +=
"Please try running the latest software version";
798 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
799 return DBErrors::UNKNOWN_DESCRIPTOR;
804 if (
id != spkm.
GetID()) {
805 strErr =
"The descriptor ID calculated by the wallet differs from the one in DB";
806 return DBErrors::CORRUPT;
817 uint32_t key_exp_index;
821 key >> key_exp_index;
834 xpub.
Decode(ser_xpub.data());
840 return DBErrors::LOAD_OK;
842 result = std::max(result, key_cache_res.
m_result);
849 uint32_t key_exp_index;
852 key >> key_exp_index;
857 xpub.
Decode(ser_xpub.data());
859 return DBErrors::LOAD_OK;
861 result = std::max(result, lh_cache_res.
m_result);
866 spk_man->SetCache(cache);
879 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
880 return DBErrors::CORRUPT;
890 std::vector<unsigned char> to_hash;
891 to_hash.reserve(pubkey.
size() + pkey.size());
892 to_hash.insert(to_hash.end(), pubkey.
begin(), pubkey.
end());
893 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
895 if (
Hash(to_hash) != hash)
897 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
898 return DBErrors::CORRUPT;
901 if (!privkey.
Load(pkey, pubkey,
true))
903 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
904 return DBErrors::CORRUPT;
906 spk_man->AddKey(pubkey.
GetID(), privkey);
907 return DBErrors::LOAD_OK;
909 result = std::max(result, key_res.
m_result);
923 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
924 return DBErrors::CORRUPT;
926 std::vector<unsigned char> privkey;
929 spk_man->AddCryptedKey(pubkey.
GetID(), pubkey, privkey);
930 return DBErrors::LOAD_OK;
932 result = std::max(result, ckey_res.
m_result);
938 if (desc_res.
m_result <= DBErrors::NONCRITICAL_ERROR) {
940 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
941 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
950 DBErrors result = DBErrors::LOAD_OK;
955 std::string strAddress;
959 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
960 return DBErrors::LOAD_OK;
962 result = std::max(result, name_res.
m_result);
967 std::string strAddress;
969 std::string purpose_str;
970 value >> purpose_str;
971 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
973 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
976 return DBErrors::LOAD_OK;
978 result = std::max(result, purpose_res.m_result);
983 std::string strAddress, strKey, strValue;
987 const CTxDestination& dest{DecodeDestination(strAddress)};
988 if (strKey.compare(
"used") == 0) {
995 pwallet->LoadAddressPreviouslySpent(dest);
996 }
else if (strKey.starts_with(
"rr")) {
999 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
1001 return DBErrors::LOAD_OK;
1003 result = std::max(result, dest_res.m_result);
1011 DBErrors result = DBErrors::LOAD_OK;
1014 any_unordered =
false;
1017 DBErrors result = DBErrors::LOAD_OK;
1022 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
1025 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1026 result = DBErrors::CORRUPT;
1030 if (wtx.GetHash() != hash)
1034 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
1040 std::string unused_string;
1041 value >> fTmp >> fUnused >> unused_string;
1042 pwallet->WalletLogPrintf(
"LoadWallet() upgrading tx ver=%d %d %s\n",
1043 wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
1044 wtx.fTimeReceivedIsTxTime = fTmp;
1048 pwallet->WalletLogPrintf(
"LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString());
1049 wtx.fTimeReceivedIsTxTime = 0;
1051 upgraded_txs.push_back(hash);
1054 if (wtx.nOrderPos == -1)
1055 any_unordered = true;
1061 result = std::max(result, DBErrors::NEED_RESCAN);
1065 result = std::max(result, tx_res.m_result);
1074 pwallet->LockCoin(COutPoint(hash, n));
1075 return DBErrors::LOAD_OK;
1077 result = std::max(result, locked_utxo_res.m_result);
1084 value >> pwallet->nOrderPosNext;
1085 }
catch (
const std::exception& e) {
1087 return DBErrors::NONCRITICAL_ERROR;
1089 return DBErrors::LOAD_OK;
1091 result = std::max(result, order_pos_res.m_result);
1095 for (
auto& [
id, wtx] : pwallet->mapWallet) {
1096 if (wtx.IsCoinBase() && wtx.isInactive()) {
1097 pwallet->AbandonTransaction(wtx);
1107 DBErrors result = DBErrors::LOAD_OK;
1110 std::set<std::pair<OutputType, bool>> seen_spks;
1114 uint8_t output_type;
1120 auto [it,
insert] = seen_spks.emplace(
static_cast<OutputType>(output_type), internal);
1122 strErr =
"Multiple ScriptpubKeyMans specified for a single type";
1123 return DBErrors::CORRUPT;
1126 return DBErrors::LOAD_OK;
1128 result = std::max(result, spkm_res.
m_result);
1141 return DBErrors::CORRUPT;
1143 return DBErrors::LOAD_OK;
1150 DBErrors result = DBErrors::LOAD_OK;
1151 bool any_unordered =
false;
1152 std::vector<Txid> upgraded_txs;
1162 if ((result =
LoadMinVersion(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1166 if ((result =
LoadWalletFlags(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1168#ifndef ENABLE_EXTERNAL_SIGNER
1170 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
1171 return DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED;
1183 if (result == DBErrors::UNKNOWN_DESCRIPTOR)
return result;
1189 result = std::max(
LoadTxRecords(pwallet, *m_batch, upgraded_txs, any_unordered), result);
1199 result = DBErrors::CORRUPT;
1204 if (result != DBErrors::LOAD_OK)
1207 for (
const Txid& hash : upgraded_txs)
1208 WriteTx(pwallet->mapWallet.at(hash));
1221 result = DBErrors::CORRUPT;
1229 pwallet->
WalletLogPrintf(
"Detected extraneous encryption keys in this wallet without private keys. Removing extraneous encryption keys.\n");
1231 if (!EraseMasterKey(
id)) {
1232 pwallet->
WalletLogPrintf(
"Error: Unable to remove extraneous encryption key '%u'. Wallet corrupt.\n",
id);
1233 return DBErrors::CORRUPT;
1271bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1274 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1277bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1282bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1291 return m_batch->ErasePrefix(
prefix);
1294bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1299bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1301 return std::all_of(types.begin(), types.end(), [&](
const std::string& type) {
1302 return m_batch->ErasePrefix(DataStream() << type);
1306bool WalletBatch::TxnBegin()
1308 return m_batch->TxnBegin();
1311bool WalletBatch::TxnCommit()
1313 bool res = m_batch->TxnCommit();
1315 for (
const auto& listener : m_txn_listeners) {
1316 listener.on_commit();
1319 m_txn_listeners.clear();
1324bool WalletBatch::TxnAbort()
1326 bool res = m_batch->TxnAbort();
1328 for (
const auto& listener : m_txn_listeners) {
1329 listener.on_abort();
1332 m_txn_listeners.clear();
1339 assert(m_batch->HasActiveTxn());
1340 m_txn_listeners.emplace_back(l);
1347 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1348 }
catch (
const fs::filesystem_error& e) {
1350 status = DatabaseStatus::FAILED_BAD_PATH;
1354 std::optional<DatabaseFormat>
format;
1357 format = DatabaseFormat::BERKELEY_RO;
1362 status = DatabaseStatus::FAILED_BAD_FORMAT;
1365 format = DatabaseFormat::SQLITE;
1369 status = DatabaseStatus::FAILED_NOT_FOUND;
1375 status = DatabaseStatus::FAILED_BAD_FORMAT;
1381 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1387 error =
Untranslated(
strprintf(
"Failed to open database path '%s'. The wallet appears to be a Legacy wallet, please use the wallet migration tool (migratewallet RPC).",
fs::PathToString(path)));
1388 status = DatabaseStatus::FAILED_BAD_FORMAT;
1395 status = DatabaseStatus::FAILED_BAD_FORMAT;
1403 format = DatabaseFormat::SQLITE;
1406 if (
format == DatabaseFormat::SQLITE) {
1410 if (
format == DatabaseFormat::BERKELEY_RO) {
1415 status = DatabaseStatus::FAILED_BAD_FORMAT;
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
catch(const std::exception &e)
#define STR_INTERNAL_BUG(msg)
#define Assume(val)
Assume is the identity function.
An encapsulated private key.
bool Load(const CPrivKey &privkey, const CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
An outpoint - a combination of a transaction hash and an index n into its vout.
An encapsulated public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
const unsigned char * end() const
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
const unsigned char * begin() const
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
Double ended buffer combining vector and stream-like interfaces.
Cache for single descriptor's derived extended pubkeys.
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
constexpr bool IsNull() const
const uint256 & ToUint256() const LIFETIMEBOUND
uint32_t nInternalChainCounter
static const int VERSION_HD_BASE
uint32_t nExternalChainCounter
static const int VERSION_HD_CHAIN_SPLIT
CKeyID seed_id
seed hash160
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Loads an active ScriptPubKeyMan for the specified type and internal.
unsigned int nMasterKeyMaxID
DescriptorScriptPubKeyMan & LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor &desc)
Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it.
bool HaveCryptedKeys() const
LegacyDataSPKM * GetOrCreateLegacyDataSPKM()
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
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.
bool HasEncryptionKeys() const override
int GetVersion() const
get the current wallet format (the oldest client version guaranteed to understand this wallet)
MasterKeyMap mapMasterKeys
ScriptPubKeyMan * GetScriptPubKeyMan(const OutputType &type, bool internal) const
Get the ScriptPubKeyMan for the given OutputType and internal/external chain.
RecursiveMutex cs_wallet
Main wallet lock.
A transaction with a bunch of additional info that only the owner cares about.
const Txid & GetHash() const LIFETIMEBOUND
RAII class that provides access to a WalletDatabase.
virtual std::unique_ptr< DatabaseCursor > GetNewPrefixCursor(std::span< const std::byte > prefix)=0
uint256 GetID() const override
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, bool checksum_valid)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
Access to the wallet database.
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
bool TxnAbort()
Abort current transaction.
bool WriteDescriptorParentCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index)
bool EraseName(const std::string &strAddress)
bool WriteBestBlock(const CBlockLocator &locator)
bool ReadBestBlock(CBlockLocator &locator)
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
bool WriteMinVersion(int nVersion)
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
bool TxnBegin()
Begin a new transaction.
bool TxnCommit()
Commit current transaction.
bool WriteName(const std::string &strAddress, const std::string &strName)
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
std::unique_ptr< DatabaseBatch > m_batch
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, const bool overwrite)
bool WriteDescriptorLastHardenedCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index)
bool WriteIC(const K &key, const T &value, bool fOverwrite=true)
bool WriteOrderPosNext(int64_t nOrderPosNext)
bool WriteTx(const CWalletTx &wtx)
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
bool EraseIC(const K &key)
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
bool ErasePurpose(const std::string &strAddress)
bool EraseLockedUTXO(const COutPoint &output)
bool WriteDescriptorDerivedCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index, uint32_t der_index)
bool WriteCryptedDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const std::vector< unsigned char > &secret)
bool WriteLockedUTXO(const COutPoint &output)
bool EraseMasterKey(unsigned int id)
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256 &id, bool internal)
bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal)
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
bool EraseWatchOnly(const CScript &script)
An instance of this class represents one database.
Descriptor with some wallet metadata.
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
static std::string PathToString(const path &path)
Convert path object to a byte string.
bool IsWalletFlagSet(uint64_t flag) const override
check if a certain wallet flag is set
bool LoadToWallet(const Txid &hash, const UpdateWalletTxFn &fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
DBErrors ReorderTransactions()
void UpgradeDescriptorCache() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade DescriptorCaches.
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
CPrivKey is a serialized private key, with all parameters included (SIZE bytes)
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
std::string EncodeDestination(const CTxDestination &dest)
#define LogDebug(category,...)
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
const std::string BESTBLOCK
const std::string WALLETDESCRIPTORCKEY
const std::string WALLETDESCRIPTORLHCACHE
const std::string MINVERSION
const std::string WATCHMETA
const std::string DEFAULTKEY
const std::string OLD_KEY
const std::string WALLETDESCRIPTORKEY
const std::string ACENTRY
const std::string ACTIVEEXTERNALSPK
const std::string CRYPTED_KEY
const std::string DESTDATA
const std::string CSCRIPT
const std::unordered_set< std::string > LEGACY_TYPES
const std::string SETTINGS
const std::string BESTBLOCK_NOMERKLE
const std::string LOCKED_UTXO
const std::string ACTIVEINTERNALSPK
const std::string HDCHAIN
const std::string ORDERPOSNEXT
const std::string VERSION
const std::string WALLETDESCRIPTORCACHE
const std::string MASTER_KEY
const std::string KEYMETA
const std::string PURPOSE
const std::string WALLETDESCRIPTOR
static LoadResult LoadRecords(CWallet *pwallet, DatabaseBatch &batch, const std::string &key, LoadFunc load_func)
std::shared_ptr< CWallet > LoadWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
bool RunWithinTxn(WalletDatabase &database, std::string_view process_desc, const std::function< bool(WalletBatch &)> &func)
Executes the provided function 'func' within a database transaction context.
bool LoadKey(CWallet *pwallet, DataStream &ssKey, DataStream &ssValue, std::string &strErr)
static DataStream PrefixStream(const Args &... args)
static DBErrors LoadLegacyWalletRecords(CWallet *pwallet, DatabaseBatch &batch, int last_client) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
bool LoadCryptedKey(CWallet *pwallet, DataStream &ssKey, DataStream &ssValue, std::string &strErr)
static DBErrors LoadTxRecords(CWallet *pwallet, DatabaseBatch &batch, std::vector< Txid > &upgraded_txs, bool &any_unordered) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
std::function< DBErrors(CWallet *pwallet, DataStream &key, DataStream &value, std::string &err)> LoadFunc
std::unique_ptr< SQLiteDatabase > MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
fs::path SQLiteDataFile(const fs::path &path)
DBErrors
Overview of wallet database classes:
@ UNEXPECTED_LEGACY_ENTRY
static DBErrors LoadWalletFlags(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
static DBErrors LoadActiveSPKMs(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
static DBErrors LoadDecryptionKeys(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
bool LoadEncryptionKey(CWallet *pwallet, DataStream &ssKey, DataStream &ssValue, std::string &strErr)
bool HasLegacyRecords(CWallet &wallet)
Returns true if there are any DBKeys::LEGACY_TYPES record in the wallet db.
bool IsBDBFile(const fs::path &path)
fs::path BDBDataFile(const fs::path &wallet_path)
bool LoadHDChain(CWallet *pwallet, DataStream &ssValue, std::string &strErr)
std::unique_ptr< BerkeleyRODatabase > MakeBerkeleyRODatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Return object giving access to Berkeley Read Only database at specified path.
bool IsSQLiteFile(const fs::path &path)
@ WALLET_FLAG_EXTERNAL_SIGNER
Indicates that the wallet needs an external signer.
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
static DBErrors LoadAddressBookRecords(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
static LoadResult LoadRecords(CWallet *pwallet, DatabaseBatch &batch, const std::string &key, DataStream &prefix, LoadFunc load_func)
static DBErrors LoadDescriptorWalletRecords(CWallet *pwallet, DatabaseBatch &batch, int last_client) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
static DBErrors LoadMinVersion(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
const unsigned int BIP32_EXTKEY_SIZE
void SerializeMany(Stream &s, const Args &... args)
Support for (un)serializing many things at once.
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::vector< uint256 > vHave
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
std::optional< DatabaseFormat > require_format
#define EXCLUSIVE_LOCKS_REQUIRED(...)
consteval auto _(util::TranslatedLiteral str)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.