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()) {
450 pwallet->WalletLogPrintf(
"Wallet file version = %d\n", nMinVersion);
453 pwallet->LoadMinVersion(nMinVersion);
463 if (!pwallet->LoadWalletFlags(
flags)) {
464 pwallet->WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
492 pwallet->
WalletLogPrintf(
"Error getting database cursor for '%s' records\n", key);
502 pwallet->
WalletLogPrintf(
"Error reading next '%s' record for wallet database\n", key);
510 DBErrors record_res = load_func(pwallet, ssKey, ssValue, error);
529 const auto& batch =
wallet.GetDatabase().MakeBatch();
544 wallet.WalletLogPrintf(
"Error getting database cursor for '%s' records", type);
545 throw std::runtime_error(
strprintf(
"Error getting database cursor for '%s' records", type));
564 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());
577 result = std::max(result, hd_chain_res.
m_result);
584 result = std::max(result, key_res.
m_result);
591 result = std::max(result, ckey_res.
m_result);
602 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCScript failed";
603 return DBErrors::NONCRITICAL_ERROR;
607 result = std::max(result, script_res.
m_result);
616 std::map<uint160, CHDChain> hd_chains;
630 bool internal = false;
632 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
633 std::vector<uint32_t> path;
634 if (keyMeta.has_key_origin) {
636 path = keyMeta.key_origin.path;
639 if (!ParseHDKeypath(keyMeta.hdKeypath, path)) {
640 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
641 return DBErrors::NONCRITICAL_ERROR;
649 if (path.size() != 3) {
650 strErr =
"Error reading wallet database: keymeta found with unexpected path";
651 return DBErrors::NONCRITICAL_ERROR;
653 if (path[0] != 0x80000000) {
654 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
655 return DBErrors::NONCRITICAL_ERROR;
657 if (path[1] != 0x80000000 && path[1] != (1 | 0x80000000)) {
658 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
659 return DBErrors::NONCRITICAL_ERROR;
661 if ((path[2] & 0x80000000) == 0) {
662 strErr = strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
663 return DBErrors::NONCRITICAL_ERROR;
665 internal = path[1] == (1 | 0x80000000);
666 index = path[2] & ~0x80000000;
686 result = std::max(result, keymeta_res.m_result);
689 if (!hd_chains.empty()) {
690 LegacyDataSPKM* legacy_spkm = pwallet->GetLegacyDataSPKM();
692 for (
const auto& [hd_seed_id, chain] : hd_chains) {
693 if (hd_seed_id != legacy_spkm->GetHDChain().seed_id) {
694 legacy_spkm->AddInactiveHDChain(chain);
698 pwallet->WalletLogPrintf(
"Inactive HD Chains found but no Legacy ScriptPubKeyMan\n");
711 pwallet->GetOrCreateLegacyDataSPKM()->LoadWatchOnly(
script);
715 result = std::max(result, watch_script_res.m_result);
722 CKeyMetadata keyMeta;
724 pwallet->GetOrCreateLegacyDataSPKM()->LoadScriptMetadata(
CScriptID(
script), keyMeta);
727 result = std::max(result, watch_meta_res.m_result);
739 value >> default_pubkey;
740 }
catch (
const std::exception& e) {
744 if (!default_pubkey.
IsValid()) {
745 err =
"Error reading wallet database: Default Key corrupt";
746 return DBErrors::CORRUPT;
750 result = std::max(result, default_key_res.m_result);
755 err =
"Found unsupported 'wkey' record, try loading with version 0.18";
758 result = std::max(result, wkey_res.m_result);
762 pwallet->WalletLogPrintf(
"Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
763 key_res.m_records, ckey_res.m_records, keymeta_res.m_records, key_res.m_records + ckey_res.m_records);
769template<
typename... Args>
786 DBErrors result = DBErrors::LOAD_OK;
793 }
catch (
const std::ios_base::failure& e) {
794 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
795 strErr += (last_client >
CLIENT_VERSION) ?
"The wallet might had been created on a newer version. " :
796 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
797 strErr +=
"Please try running the latest software version";
799 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
800 return DBErrors::UNKNOWN_DESCRIPTOR;
805 if (
id != spkm.
GetID()) {
806 strErr =
"The descriptor ID calculated by the wallet differs from the one in DB";
807 return DBErrors::CORRUPT;
818 uint32_t key_exp_index;
822 key >> key_exp_index;
835 xpub.
Decode(ser_xpub.data());
841 return DBErrors::LOAD_OK;
843 result = std::max(result, key_cache_res.
m_result);
850 uint32_t key_exp_index;
853 key >> key_exp_index;
858 xpub.
Decode(ser_xpub.data());
860 return DBErrors::LOAD_OK;
862 result = std::max(result, lh_cache_res.
m_result);
867 spk_man->SetCache(cache);
880 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
881 return DBErrors::CORRUPT;
891 std::vector<unsigned char> to_hash;
892 to_hash.reserve(pubkey.
size() + pkey.size());
893 to_hash.insert(to_hash.end(), pubkey.
begin(), pubkey.
end());
894 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
896 if (
Hash(to_hash) != hash)
898 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
899 return DBErrors::CORRUPT;
902 if (!privkey.
Load(pkey, pubkey,
true))
904 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
905 return DBErrors::CORRUPT;
907 spk_man->AddKey(pubkey.
GetID(), privkey);
908 return DBErrors::LOAD_OK;
910 result = std::max(result, key_res.
m_result);
924 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
925 return DBErrors::CORRUPT;
927 std::vector<unsigned char> privkey;
930 spk_man->AddCryptedKey(pubkey.
GetID(), pubkey, privkey);
931 return DBErrors::LOAD_OK;
933 result = std::max(result, ckey_res.
m_result);
939 if (desc_res.
m_result <= DBErrors::NONCRITICAL_ERROR) {
941 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
942 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
951 DBErrors result = DBErrors::LOAD_OK;
956 std::string strAddress;
960 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
961 return DBErrors::LOAD_OK;
963 result = std::max(result, name_res.
m_result);
968 std::string strAddress;
970 std::string purpose_str;
971 value >> purpose_str;
972 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
974 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
977 return DBErrors::LOAD_OK;
979 result = std::max(result, purpose_res.m_result);
984 std::string strAddress, strKey, strValue;
988 const CTxDestination& dest{DecodeDestination(strAddress)};
989 if (strKey.compare(
"used") == 0) {
996 pwallet->LoadAddressPreviouslySpent(dest);
997 }
else if (strKey.starts_with(
"rr")) {
1000 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
1002 return DBErrors::LOAD_OK;
1004 result = std::max(result, dest_res.m_result);
1012 DBErrors result = DBErrors::LOAD_OK;
1015 any_unordered =
false;
1018 DBErrors result = DBErrors::LOAD_OK;
1023 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
1026 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1027 result = DBErrors::CORRUPT;
1031 if (wtx.GetHash() != hash)
1035 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
1041 std::string unused_string;
1042 value >> fTmp >> fUnused >> unused_string;
1043 pwallet->WalletLogPrintf(
"LoadWallet() upgrading tx ver=%d %d %s\n",
1044 wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
1045 wtx.fTimeReceivedIsTxTime = fTmp;
1049 pwallet->WalletLogPrintf(
"LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString());
1050 wtx.fTimeReceivedIsTxTime = 0;
1052 upgraded_txs.push_back(hash);
1055 if (wtx.nOrderPos == -1)
1056 any_unordered = true;
1062 result = std::max(result, DBErrors::NEED_RESCAN);
1066 result = std::max(result, tx_res.m_result);
1075 pwallet->LockCoin(COutPoint(hash, n));
1076 return DBErrors::LOAD_OK;
1078 result = std::max(result, locked_utxo_res.m_result);
1085 value >> pwallet->nOrderPosNext;
1086 }
catch (
const std::exception& e) {
1088 return DBErrors::NONCRITICAL_ERROR;
1090 return DBErrors::LOAD_OK;
1092 result = std::max(result, order_pos_res.m_result);
1096 for (
auto& [
id, wtx] : pwallet->mapWallet) {
1097 if (wtx.IsCoinBase() && wtx.isInactive()) {
1098 pwallet->AbandonTransaction(wtx);
1108 DBErrors result = DBErrors::LOAD_OK;
1111 std::set<std::pair<OutputType, bool>> seen_spks;
1115 uint8_t output_type;
1121 auto [it,
insert] = seen_spks.emplace(
static_cast<OutputType>(output_type), internal);
1123 strErr =
"Multiple ScriptpubKeyMans specified for a single type";
1124 return DBErrors::CORRUPT;
1127 return DBErrors::LOAD_OK;
1129 result = std::max(result, spkm_res.
m_result);
1142 return DBErrors::CORRUPT;
1144 return DBErrors::LOAD_OK;
1151 DBErrors result = DBErrors::LOAD_OK;
1152 bool any_unordered =
false;
1153 std::vector<Txid> upgraded_txs;
1160 if (has_last_client) pwallet->
WalletLogPrintf(
"Last client version = %d\n", last_client);
1163 if ((result =
LoadMinVersion(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1167 if ((result =
LoadWalletFlags(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1169#ifndef ENABLE_EXTERNAL_SIGNER
1171 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
1172 return DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED;
1184 if (result == DBErrors::UNKNOWN_DESCRIPTOR)
return result;
1190 result = std::max(
LoadTxRecords(pwallet, *m_batch, upgraded_txs, any_unordered), result);
1200 result = DBErrors::CORRUPT;
1205 if (result != DBErrors::LOAD_OK)
1208 for (
const Txid& hash : upgraded_txs)
1209 WriteTx(pwallet->mapWallet.at(hash));
1222 result = DBErrors::CORRUPT;
1230 pwallet->
WalletLogPrintf(
"Detected extraneous encryption keys in this wallet without private keys. Removing extraneous encryption keys.\n");
1232 if (!EraseMasterKey(
id)) {
1233 pwallet->
WalletLogPrintf(
"Error: Unable to remove extraneous encryption key '%u'. Wallet corrupt.\n",
id);
1234 return DBErrors::CORRUPT;
1272bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1275 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1278bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1283bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1292 return m_batch->ErasePrefix(
prefix);
1295bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1300bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1302 return std::all_of(types.begin(), types.end(), [&](
const std::string& type) {
1303 return m_batch->ErasePrefix(DataStream() << type);
1307bool WalletBatch::TxnBegin()
1309 return m_batch->TxnBegin();
1312bool WalletBatch::TxnCommit()
1314 bool res = m_batch->TxnCommit();
1316 for (
const auto& listener : m_txn_listeners) {
1317 listener.on_commit();
1320 m_txn_listeners.clear();
1325bool WalletBatch::TxnAbort()
1327 bool res = m_batch->TxnAbort();
1329 for (
const auto& listener : m_txn_listeners) {
1330 listener.on_abort();
1333 m_txn_listeners.clear();
1340 assert(m_batch->HasActiveTxn());
1341 m_txn_listeners.emplace_back(l);
1348 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1349 }
catch (
const fs::filesystem_error& e) {
1351 status = DatabaseStatus::FAILED_BAD_PATH;
1355 std::optional<DatabaseFormat>
format;
1358 format = DatabaseFormat::BERKELEY_RO;
1363 status = DatabaseStatus::FAILED_BAD_FORMAT;
1366 format = DatabaseFormat::SQLITE;
1370 status = DatabaseStatus::FAILED_NOT_FOUND;
1376 status = DatabaseStatus::FAILED_BAD_FORMAT;
1382 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1388 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)));
1389 status = DatabaseStatus::FAILED_BAD_FORMAT;
1396 status = DatabaseStatus::FAILED_BAD_FORMAT;
1404 format = DatabaseFormat::SQLITE;
1407 if (
format == DatabaseFormat::SQLITE) {
1411 if (
format == DatabaseFormat::BERKELEY_RO) {
1416 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 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.