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"};
120 std::vector<unsigned char> vchKey;
121 vchKey.reserve(vchPubKey.
size() + vchPrivKey.size());
122 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
123 vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
129 const std::vector<unsigned char>& vchCryptedSecret,
140 if (!
WriteIC(key, std::make_pair(vchCryptedSecret, checksum),
false)) {
142 std::vector<unsigned char> val;
143 if (!
m_batch->Read(key, val)) {
146 if (!
WriteIC(key, std::make_pair(val, checksum),
true)) {
211 return WriteIC(make_pair(key, type),
id);
217 return EraseIC(make_pair(key, type));
223 std::vector<unsigned char> key;
224 key.reserve(pubkey.
size() + privkey.size());
225 key.insert(key.end(), pubkey.
begin(), pubkey.
end());
226 key.insert(key.end(), privkey.begin(), privkey.end());
248 xpub.
Encode(ser_xpub.data());
255 xpub.
Encode(ser_xpub.data());
262 xpub.
Encode(ser_xpub.data());
274 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
306 strErr =
"Error reading wallet database: CPubKey corrupt";
324 catch (
const std::ios_base::failure&) {}
326 bool fSkipCheck =
false;
331 std::vector<unsigned char> vchKey;
332 vchKey.reserve(vchPubKey.
size() + pkey.size());
333 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
334 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
336 if (
Hash(vchKey) != hash)
338 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
345 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
347 strErr =
"Error reading wallet database: CPrivKey corrupt";
352 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadKey failed";
355 }
catch (
const std::exception& e) {
356 if (strErr.empty()) {
372 strErr =
"Error reading wallet database: CPubKey corrupt";
375 std::vector<unsigned char> vchPrivKey;
376 ssValue >> vchPrivKey;
379 bool checksum_valid =
false;
380 if (!ssValue.
eof()) {
383 if (!(checksum_valid =
Hash(vchPrivKey) == checksum)) {
384 strErr =
"Error reading wallet database: Encrypted key corrupt";
391 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCryptedKey failed";
394 }
catch (
const std::exception& e) {
395 if (strErr.empty()) {
411 ssValue >> kMasterKey;
414 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
421 }
catch (
const std::exception& e) {
422 if (strErr.empty()) {
437 }
catch (
const std::exception& e) {
438 if (strErr.empty()) {
451 if (!pwallet->LoadWalletFlags(
flags)) {
452 pwallet->WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
480 pwallet->
WalletLogPrintf(
"Error getting database cursor for '%s' records\n", key);
490 pwallet->
WalletLogPrintf(
"Error reading next '%s' record for wallet database\n", key);
498 DBErrors record_res = load_func(pwallet, ssKey, ssValue, error);
517 const auto& batch =
wallet.GetDatabase().MakeBatch();
532 throw std::runtime_error(
strprintf(
"Error getting database cursor for '%s' records", type));
551 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());
564 result = std::max(result, hd_chain_res.
m_result);
571 result = std::max(result, key_res.
m_result);
578 result = std::max(result, ckey_res.
m_result);
589 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCScript failed";
590 return DBErrors::NONCRITICAL_ERROR;
594 result = std::max(result, script_res.
m_result);
603 std::map<uint160, CHDChain> hd_chains;
617 bool internal = false;
619 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
620 std::vector<uint32_t> path;
621 if (keyMeta.has_key_origin) {
623 path = keyMeta.key_origin.path;
626 if (!ParseHDKeypath(keyMeta.hdKeypath, path)) {
627 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
628 return DBErrors::NONCRITICAL_ERROR;
636 if (path.size() != 3) {
637 strErr =
"Error reading wallet database: keymeta found with unexpected path";
638 return DBErrors::NONCRITICAL_ERROR;
640 if (path[0] != 0x80000000) {
641 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
642 return DBErrors::NONCRITICAL_ERROR;
644 if (path[1] != 0x80000000 && path[1] != (1 | 0x80000000)) {
645 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
646 return DBErrors::NONCRITICAL_ERROR;
648 if ((path[2] & 0x80000000) == 0) {
649 strErr = strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
650 return DBErrors::NONCRITICAL_ERROR;
652 internal = path[1] == (1 | 0x80000000);
653 index = path[2] & ~0x80000000;
673 result = std::max(result, keymeta_res.m_result);
676 if (!hd_chains.empty()) {
677 LegacyDataSPKM* legacy_spkm = pwallet->GetLegacyDataSPKM();
679 for (
const auto& [hd_seed_id, chain] : hd_chains) {
680 if (hd_seed_id != legacy_spkm->GetHDChain().seed_id) {
681 legacy_spkm->AddInactiveHDChain(chain);
685 pwallet->WalletLogPrintf(
"Inactive HD Chains found but no Legacy ScriptPubKeyMan\n");
698 pwallet->GetOrCreateLegacyDataSPKM()->LoadWatchOnly(
script);
702 result = std::max(result, watch_script_res.m_result);
709 CKeyMetadata keyMeta;
711 pwallet->GetOrCreateLegacyDataSPKM()->LoadScriptMetadata(
CScriptID(
script), keyMeta);
714 result = std::max(result, watch_meta_res.m_result);
726 value >> default_pubkey;
727 }
catch (
const std::exception& e) {
731 if (!default_pubkey.
IsValid()) {
732 err =
"Error reading wallet database: Default Key corrupt";
733 return DBErrors::CORRUPT;
737 result = std::max(result, default_key_res.m_result);
742 err =
"Found unsupported 'wkey' record, try loading with version 0.18";
745 result = std::max(result, wkey_res.m_result);
749 pwallet->WalletLogPrintf(
"Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
750 key_res.m_records, ckey_res.m_records, keymeta_res.m_records, key_res.m_records + ckey_res.m_records);
756template<
typename... Args>
773 DBErrors result = DBErrors::LOAD_OK;
780 }
catch (
const std::ios_base::failure& e) {
781 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
782 strErr += (last_client >
CLIENT_VERSION) ?
"The wallet might have been created on a newer version. " :
783 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
784 strErr +=
"Please try running the latest software version";
786 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
787 return DBErrors::UNKNOWN_DESCRIPTOR;
792 if (
id != spkm.
GetID()) {
793 strErr =
"The descriptor ID calculated by the wallet differs from the one in DB";
794 return DBErrors::CORRUPT;
805 uint32_t key_exp_index;
809 key >> key_exp_index;
822 xpub.
Decode(ser_xpub.data());
828 return DBErrors::LOAD_OK;
830 result = std::max(result, key_cache_res.
m_result);
837 uint32_t key_exp_index;
840 key >> key_exp_index;
845 xpub.
Decode(ser_xpub.data());
847 return DBErrors::LOAD_OK;
849 result = std::max(result, lh_cache_res.
m_result);
854 spk_man->SetCache(cache);
867 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
868 return DBErrors::CORRUPT;
878 std::vector<unsigned char> to_hash;
879 to_hash.reserve(pubkey.
size() + pkey.size());
880 to_hash.insert(to_hash.end(), pubkey.
begin(), pubkey.
end());
881 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
883 if (
Hash(to_hash) != hash)
885 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
886 return DBErrors::CORRUPT;
889 if (!privkey.
Load(pkey, pubkey,
true))
891 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
892 return DBErrors::CORRUPT;
894 spk_man->AddKey(pubkey.
GetID(), privkey);
895 return DBErrors::LOAD_OK;
897 result = std::max(result, key_res.
m_result);
911 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
912 return DBErrors::CORRUPT;
914 std::vector<unsigned char> privkey;
917 spk_man->AddCryptedKey(pubkey.
GetID(), pubkey, privkey);
918 return DBErrors::LOAD_OK;
920 result = std::max(result, ckey_res.
m_result);
926 if (desc_res.
m_result <= DBErrors::NONCRITICAL_ERROR) {
928 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
929 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
938 DBErrors result = DBErrors::LOAD_OK;
943 std::string strAddress;
947 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
948 return DBErrors::LOAD_OK;
950 result = std::max(result, name_res.
m_result);
955 std::string strAddress;
957 std::string purpose_str;
958 value >> purpose_str;
959 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
961 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
964 return DBErrors::LOAD_OK;
966 result = std::max(result, purpose_res.m_result);
971 std::string strAddress, strKey, strValue;
975 const CTxDestination& dest{DecodeDestination(strAddress)};
976 if (strKey.compare(
"used") == 0) {
983 pwallet->LoadAddressPreviouslySpent(dest);
984 }
else if (strKey.starts_with(
"rr")) {
987 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
989 return DBErrors::LOAD_OK;
991 result = std::max(result, dest_res.m_result);
999 DBErrors result = DBErrors::LOAD_OK;
1002 any_unordered =
false;
1005 DBErrors result = DBErrors::LOAD_OK;
1010 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
1013 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1014 result = DBErrors::CORRUPT;
1018 if (wtx.GetHash() != hash)
1021 if (wtx.nOrderPos == -1)
1022 any_unordered = true;
1028 result = std::max(result, DBErrors::NEED_RESCAN);
1032 result = std::max(result, tx_res.m_result);
1041 pwallet->LoadLockedCoin(COutPoint(hash, n), true);
1042 return DBErrors::LOAD_OK;
1044 result = std::max(result, locked_utxo_res.m_result);
1051 value >> pwallet->nOrderPosNext;
1052 }
catch (
const std::exception& e) {
1054 return DBErrors::NONCRITICAL_ERROR;
1056 return DBErrors::LOAD_OK;
1058 result = std::max(result, order_pos_res.m_result);
1062 for (
auto& [
id, wtx] : pwallet->mapWallet) {
1063 if (wtx.IsCoinBase() && wtx.isInactive()) {
1064 pwallet->AbandonTransaction(wtx);
1074 DBErrors result = DBErrors::LOAD_OK;
1077 std::set<std::pair<OutputType, bool>> seen_spks;
1081 uint8_t output_type;
1087 auto [it,
insert] = seen_spks.emplace(
static_cast<OutputType>(output_type), internal);
1089 strErr =
"Multiple ScriptpubKeyMans specified for a single type";
1090 return DBErrors::CORRUPT;
1093 return DBErrors::LOAD_OK;
1095 result = std::max(result, spkm_res.
m_result);
1108 return DBErrors::CORRUPT;
1110 return DBErrors::LOAD_OK;
1117 DBErrors result = DBErrors::LOAD_OK;
1118 bool any_unordered =
false;
1125 if (has_last_client) pwallet->
WalletLogPrintf(
"Last client version = %d\n", last_client);
1130 if ((result =
LoadWalletFlags(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1132#ifndef ENABLE_EXTERNAL_SIGNER
1134 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
1135 return DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED;
1147 if (result == DBErrors::UNKNOWN_DESCRIPTOR)
return result;
1159 result = std::max(
LoadTxRecords(pwallet, *m_batch, any_unordered), result);
1160 }
catch (std::runtime_error& e) {
1166 result = DBErrors::CORRUPT;
1169 result = DBErrors::CORRUPT;
1174 if (result != DBErrors::LOAD_OK)
1188 result = DBErrors::CORRUPT;
1196 pwallet->
WalletLogPrintf(
"Detected extraneous encryption keys in this wallet without private keys. Removing extraneous encryption keys.\n");
1198 if (!EraseMasterKey(
id)) {
1199 pwallet->
WalletLogPrintf(
"Error: Unable to remove extraneous encryption key '%u'. Wallet corrupt.\n",
id);
1200 return DBErrors::CORRUPT;
1238bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1241 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1244bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1249bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1258 return m_batch->ErasePrefix(
prefix);
1261bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1266bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1268 return std::all_of(types.begin(), types.end(), [&](
const std::string& type) {
1269 return m_batch->ErasePrefix(DataStream() << type);
1273bool WalletBatch::TxnBegin()
1275 return m_batch->TxnBegin();
1278bool WalletBatch::TxnCommit()
1280 bool res = m_batch->TxnCommit();
1282 for (
const auto& listener : m_txn_listeners) {
1283 listener.on_commit();
1286 m_txn_listeners.clear();
1291bool WalletBatch::TxnAbort()
1293 bool res = m_batch->TxnAbort();
1295 for (
const auto& listener : m_txn_listeners) {
1296 listener.on_abort();
1299 m_txn_listeners.clear();
1306 assert(m_batch->HasActiveTxn());
1307 m_txn_listeners.emplace_back(l);
1314 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1315 }
catch (
const fs::filesystem_error& e) {
1317 status = DatabaseStatus::FAILED_BAD_PATH;
1321 std::optional<DatabaseFormat>
format;
1324 format = DatabaseFormat::BERKELEY_RO;
1329 status = DatabaseStatus::FAILED_BAD_FORMAT;
1332 format = DatabaseFormat::SQLITE;
1336 status = DatabaseStatus::FAILED_NOT_FOUND;
1342 status = DatabaseStatus::FAILED_BAD_FORMAT;
1348 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1354 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 or the GUI option).",
fs::PathToString(path)));
1355 status = DatabaseStatus::FAILED_LEGACY_DISABLED;
1362 status = DatabaseStatus::FAILED_BAD_FORMAT;
1370 format = DatabaseFormat::SQLITE;
1373 if (
format == DatabaseFormat::SQLITE) {
1377 if (
format == DatabaseFormat::BERKELEY_RO) {
1382 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
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 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
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)
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)
static DBErrors LoadTxRecords(CWallet *pwallet, DatabaseBatch &batch, bool &any_unordered) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
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.
std::string SQLiteDatabaseVersion()
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)
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.