6#include <bitcoin-build-config.h>
40const std::string
FLAGS{
"flags"};
43const std::string
KEY{
"key"};
47const std::string
NAME{
"name"};
50const std::string
POOL{
"pool"};
53const std::string
TX{
"tx"};
113 std::vector<unsigned char> vchKey;
114 vchKey.reserve(vchPubKey.
size() + vchPrivKey.size());
115 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
116 vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
122 const std::vector<unsigned char>& vchCryptedSecret,
133 if (!
WriteIC(key, std::make_pair(vchCryptedSecret, checksum),
false)) {
135 std::vector<unsigned char> val;
136 if (!
m_batch->Read(key, val)) {
139 if (!
WriteIC(key, std::make_pair(val, checksum),
true)) {
209 return WriteIC(make_pair(key, type),
id);
215 return EraseIC(make_pair(key, type));
221 std::vector<unsigned char> key;
222 key.reserve(pubkey.
size() + privkey.size());
223 key.insert(key.end(), pubkey.
begin(), pubkey.
end());
224 key.insert(key.end(), privkey.begin(), privkey.end());
246 xpub.
Encode(ser_xpub.data());
253 xpub.
Encode(ser_xpub.data());
260 xpub.
Encode(ser_xpub.data());
272 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
304 strErr =
"Error reading wallet database: CPubKey corrupt";
322 catch (
const std::ios_base::failure&) {}
324 bool fSkipCheck =
false;
329 std::vector<unsigned char> vchKey;
330 vchKey.reserve(vchPubKey.
size() + pkey.size());
331 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
332 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
334 if (
Hash(vchKey) != hash)
336 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
343 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
345 strErr =
"Error reading wallet database: CPrivKey corrupt";
350 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadKey failed";
353 }
catch (
const std::exception& e) {
354 if (strErr.empty()) {
370 strErr =
"Error reading wallet database: CPubKey corrupt";
373 std::vector<unsigned char> vchPrivKey;
374 ssValue >> vchPrivKey;
377 bool checksum_valid =
false;
378 if (!ssValue.
eof()) {
381 if (!(checksum_valid =
Hash(vchPrivKey) == checksum)) {
382 strErr =
"Error reading wallet database: Encrypted key corrupt";
389 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCryptedKey failed";
392 }
catch (
const std::exception& e) {
393 if (strErr.empty()) {
409 ssValue >> kMasterKey;
412 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
419 }
catch (
const std::exception& e) {
420 if (strErr.empty()) {
435 }
catch (
const std::exception& e) {
436 if (strErr.empty()) {
451 pwallet->LoadMinVersion(nMinVersion);
461 if (!pwallet->LoadWalletFlags(
flags)) {
462 pwallet->WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
490 pwallet->
WalletLogPrintf(
"Error getting database cursor for '%s' records\n", key);
500 pwallet->
WalletLogPrintf(
"Error reading next '%s' record for wallet database\n", key);
508 DBErrors record_res = load_func(pwallet, ssKey, ssValue, error);
527 const auto& batch =
wallet.GetDatabase().MakeBatch();
542 wallet.WalletLogPrintf(
"Error getting database cursor for '%s' records", type);
543 throw std::runtime_error(
strprintf(
"Error getting database cursor for '%s' records", type));
562 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());
575 result = std::max(result, hd_chain_res.
m_result);
582 result = std::max(result, key_res.
m_result);
589 result = std::max(result, ckey_res.
m_result);
600 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCScript failed";
601 return DBErrors::NONCRITICAL_ERROR;
605 result = std::max(result, script_res.
m_result);
614 std::map<uint160, CHDChain> hd_chains;
628 bool internal = false;
630 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
631 std::vector<uint32_t> path;
632 if (keyMeta.has_key_origin) {
634 path = keyMeta.key_origin.path;
637 if (!ParseHDKeypath(keyMeta.hdKeypath, path)) {
638 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
639 return DBErrors::NONCRITICAL_ERROR;
647 if (path.size() != 3) {
648 strErr =
"Error reading wallet database: keymeta found with unexpected path";
649 return DBErrors::NONCRITICAL_ERROR;
651 if (path[0] != 0x80000000) {
652 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
653 return DBErrors::NONCRITICAL_ERROR;
655 if (path[1] != 0x80000000 && path[1] != (1 | 0x80000000)) {
656 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
657 return DBErrors::NONCRITICAL_ERROR;
659 if ((path[2] & 0x80000000) == 0) {
660 strErr = strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
661 return DBErrors::NONCRITICAL_ERROR;
663 internal = path[1] == (1 | 0x80000000);
664 index = path[2] & ~0x80000000;
684 result = std::max(result, keymeta_res.m_result);
687 if (!hd_chains.empty()) {
688 LegacyDataSPKM* legacy_spkm = pwallet->GetLegacyDataSPKM();
690 for (
const auto& [hd_seed_id, chain] : hd_chains) {
691 if (hd_seed_id != legacy_spkm->GetHDChain().seed_id) {
692 legacy_spkm->AddInactiveHDChain(chain);
696 pwallet->WalletLogPrintf(
"Inactive HD Chains found but no Legacy ScriptPubKeyMan\n");
709 pwallet->GetOrCreateLegacyDataSPKM()->LoadWatchOnly(
script);
713 result = std::max(result, watch_script_res.m_result);
720 CKeyMetadata keyMeta;
722 pwallet->GetOrCreateLegacyDataSPKM()->LoadScriptMetadata(
CScriptID(
script), keyMeta);
725 result = std::max(result, watch_meta_res.m_result);
737 value >> default_pubkey;
738 }
catch (
const std::exception& e) {
742 if (!default_pubkey.
IsValid()) {
743 err =
"Error reading wallet database: Default Key corrupt";
744 return DBErrors::CORRUPT;
748 result = std::max(result, default_key_res.m_result);
753 err =
"Found unsupported 'wkey' record, try loading with version 0.18";
756 result = std::max(result, wkey_res.m_result);
760 pwallet->WalletLogPrintf(
"Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
761 key_res.m_records, ckey_res.m_records, keymeta_res.m_records, key_res.m_records + ckey_res.m_records);
767template<
typename... Args>
784 DBErrors result = DBErrors::LOAD_OK;
791 }
catch (
const std::ios_base::failure& e) {
792 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
793 strErr += (last_client >
CLIENT_VERSION) ?
"The wallet might had been created on a newer version. " :
794 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
795 strErr +=
"Please try running the latest software version";
797 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
798 return DBErrors::UNKNOWN_DESCRIPTOR;
803 if (
id != spkm.
GetID()) {
804 strErr =
"The descriptor ID calculated by the wallet differs from the one in DB";
805 return DBErrors::CORRUPT;
816 uint32_t key_exp_index;
820 key >> key_exp_index;
833 xpub.
Decode(ser_xpub.data());
839 return DBErrors::LOAD_OK;
841 result = std::max(result, key_cache_res.
m_result);
848 uint32_t key_exp_index;
851 key >> key_exp_index;
856 xpub.
Decode(ser_xpub.data());
858 return DBErrors::LOAD_OK;
860 result = std::max(result, lh_cache_res.
m_result);
865 spk_man->SetCache(cache);
878 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
879 return DBErrors::CORRUPT;
889 std::vector<unsigned char> to_hash;
890 to_hash.reserve(pubkey.
size() + pkey.size());
891 to_hash.insert(to_hash.end(), pubkey.
begin(), pubkey.
end());
892 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
894 if (
Hash(to_hash) != hash)
896 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
897 return DBErrors::CORRUPT;
900 if (!privkey.
Load(pkey, pubkey,
true))
902 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
903 return DBErrors::CORRUPT;
905 spk_man->AddKey(pubkey.
GetID(), privkey);
906 return DBErrors::LOAD_OK;
908 result = std::max(result, key_res.
m_result);
922 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
923 return DBErrors::CORRUPT;
925 std::vector<unsigned char> privkey;
928 spk_man->AddCryptedKey(pubkey.
GetID(), pubkey, privkey);
929 return DBErrors::LOAD_OK;
931 result = std::max(result, ckey_res.
m_result);
937 if (desc_res.
m_result <= DBErrors::NONCRITICAL_ERROR) {
939 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
940 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
949 DBErrors result = DBErrors::LOAD_OK;
954 std::string strAddress;
958 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
959 return DBErrors::LOAD_OK;
961 result = std::max(result, name_res.
m_result);
966 std::string strAddress;
968 std::string purpose_str;
969 value >> purpose_str;
970 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
972 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
975 return DBErrors::LOAD_OK;
977 result = std::max(result, purpose_res.m_result);
982 std::string strAddress, strKey, strValue;
986 const CTxDestination& dest{DecodeDestination(strAddress)};
987 if (strKey.compare(
"used") == 0) {
994 pwallet->LoadAddressPreviouslySpent(dest);
995 }
else if (strKey.starts_with(
"rr")) {
998 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
1000 return DBErrors::LOAD_OK;
1002 result = std::max(result, dest_res.m_result);
1010 DBErrors result = DBErrors::LOAD_OK;
1013 any_unordered =
false;
1016 DBErrors result = DBErrors::LOAD_OK;
1021 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
1024 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1025 result = DBErrors::CORRUPT;
1029 if (wtx.GetHash() != hash)
1033 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
1039 std::string unused_string;
1040 value >> fTmp >> fUnused >> unused_string;
1041 pwallet->WalletLogPrintf(
"LoadWallet() upgrading tx ver=%d %d %s\n",
1042 wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
1043 wtx.fTimeReceivedIsTxTime = fTmp;
1047 pwallet->WalletLogPrintf(
"LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString());
1048 wtx.fTimeReceivedIsTxTime = 0;
1050 upgraded_txs.push_back(hash);
1053 if (wtx.nOrderPos == -1)
1054 any_unordered = true;
1060 result = std::max(result, DBErrors::NEED_RESCAN);
1064 result = std::max(result, tx_res.m_result);
1073 pwallet->LockCoin(COutPoint(hash, n));
1074 return DBErrors::LOAD_OK;
1076 result = std::max(result, locked_utxo_res.m_result);
1083 value >> pwallet->nOrderPosNext;
1084 }
catch (
const std::exception& e) {
1086 return DBErrors::NONCRITICAL_ERROR;
1088 return DBErrors::LOAD_OK;
1090 result = std::max(result, order_pos_res.m_result);
1094 for (
auto& [
id, wtx] : pwallet->mapWallet) {
1095 if (wtx.IsCoinBase() && wtx.isInactive()) {
1096 pwallet->AbandonTransaction(wtx);
1106 DBErrors result = DBErrors::LOAD_OK;
1109 std::set<std::pair<OutputType, bool>> seen_spks;
1113 uint8_t output_type;
1119 auto [it,
insert] = seen_spks.emplace(
static_cast<OutputType>(output_type), internal);
1121 strErr =
"Multiple ScriptpubKeyMans specified for a single type";
1122 return DBErrors::CORRUPT;
1125 return DBErrors::LOAD_OK;
1127 result = std::max(result, spkm_res.
m_result);
1140 return DBErrors::CORRUPT;
1142 return DBErrors::LOAD_OK;
1149 DBErrors result = DBErrors::LOAD_OK;
1150 bool any_unordered =
false;
1151 std::vector<uint256> upgraded_txs;
1161 if ((result =
LoadMinVersion(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1165 if ((result =
LoadWalletFlags(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1167#ifndef ENABLE_EXTERNAL_SIGNER
1169 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
1170 return DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED;
1182 if (result == DBErrors::UNKNOWN_DESCRIPTOR)
return result;
1188 result = std::max(
LoadTxRecords(pwallet, *m_batch, upgraded_txs, any_unordered), result);
1198 result = DBErrors::CORRUPT;
1203 if (result != DBErrors::LOAD_OK)
1206 for (
const uint256& hash : upgraded_txs)
1207 WriteTx(pwallet->mapWallet.at(hash));
1220 result = DBErrors::CORRUPT;
1228 pwallet->
WalletLogPrintf(
"Detected extraneous encryption keys in this wallet without private keys. Removing extraneous encryption keys.\n");
1230 if (!EraseMasterKey(
id)) {
1231 pwallet->
WalletLogPrintf(
"Error: Unable to remove extraneous encryption key '%u'. Wallet corrupt.\n",
id);
1232 return DBErrors::CORRUPT;
1270bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1273 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1276bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1281bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1290 return m_batch->ErasePrefix(
prefix);
1293bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1298bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1300 return std::all_of(types.begin(), types.end(), [&](
const std::string& type) {
1301 return m_batch->ErasePrefix(DataStream() << type);
1305bool WalletBatch::TxnBegin()
1307 return m_batch->TxnBegin();
1310bool WalletBatch::TxnCommit()
1312 bool res = m_batch->TxnCommit();
1314 for (
const auto& listener : m_txn_listeners) {
1315 listener.on_commit();
1318 m_txn_listeners.clear();
1323bool WalletBatch::TxnAbort()
1325 bool res = m_batch->TxnAbort();
1327 for (
const auto& listener : m_txn_listeners) {
1328 listener.on_abort();
1331 m_txn_listeners.clear();
1338 assert(m_batch->HasActiveTxn());
1339 m_txn_listeners.emplace_back(l);
1346 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1347 }
catch (
const fs::filesystem_error& e) {
1349 status = DatabaseStatus::FAILED_BAD_PATH;
1353 std::optional<DatabaseFormat>
format;
1356 format = DatabaseFormat::BERKELEY_RO;
1361 status = DatabaseStatus::FAILED_BAD_FORMAT;
1364 format = DatabaseFormat::SQLITE;
1368 status = DatabaseStatus::FAILED_NOT_FOUND;
1374 status = DatabaseStatus::FAILED_BAD_FORMAT;
1380 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1386 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)));
1387 status = DatabaseStatus::FAILED_BAD_FORMAT;
1394 status = DatabaseStatus::FAILED_BAD_FORMAT;
1402 format = DatabaseFormat::SQLITE;
1405 if (
format == DatabaseFormat::SQLITE) {
1409 if (
format == DatabaseFormat::BERKELEY_RO) {
1414 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
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 EraseTx(uint256 hash)
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 LoadToWallet(const uint256 &hash, const UpdateWalletTxFn &fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool IsWalletFlagSet(uint64_t flag) const override
check if a certain wallet flag is set
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)
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 LoadTxRecords(CWallet *pwallet, DatabaseBatch &batch, std::vector< uint256 > &upgraded_txs, bool &any_unordered) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
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.