6#include <bitcoin-build-config.h>
45const std::string
FLAGS{
"flags"};
48const std::string
KEY{
"key"};
52const std::string
NAME{
"name"};
55const std::string
POOL{
"pool"};
58const std::string
TX{
"tx"};
118 std::vector<unsigned char> vchKey;
119 vchKey.reserve(vchPubKey.
size() + vchPrivKey.size());
120 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
121 vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
127 const std::vector<unsigned char>& vchCryptedSecret,
138 if (!
WriteIC(key, std::make_pair(vchCryptedSecret, checksum),
false)) {
140 std::vector<unsigned char> val;
141 if (!
m_batch->Read(key, val)) {
144 if (!
WriteIC(key, std::make_pair(val, checksum),
true)) {
234 return WriteIC(make_pair(key, type),
id);
240 return EraseIC(make_pair(key, type));
246 std::vector<unsigned char> key;
247 key.reserve(pubkey.
size() + privkey.size());
248 key.insert(key.end(), pubkey.
begin(), pubkey.
end());
249 key.insert(key.end(), privkey.begin(), privkey.end());
271 xpub.
Encode(ser_xpub.data());
278 xpub.
Encode(ser_xpub.data());
285 xpub.
Encode(ser_xpub.data());
297 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
329 strErr =
"Error reading wallet database: CPubKey corrupt";
347 catch (
const std::ios_base::failure&) {}
349 bool fSkipCheck =
false;
354 std::vector<unsigned char> vchKey;
355 vchKey.reserve(vchPubKey.
size() + pkey.size());
356 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
357 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
359 if (
Hash(vchKey) != hash)
361 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
368 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
370 strErr =
"Error reading wallet database: CPrivKey corrupt";
375 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadKey failed";
378 }
catch (
const std::exception& e) {
379 if (strErr.empty()) {
395 strErr =
"Error reading wallet database: CPubKey corrupt";
398 std::vector<unsigned char> vchPrivKey;
399 ssValue >> vchPrivKey;
402 bool checksum_valid =
false;
403 if (!ssValue.
eof()) {
406 if (!(checksum_valid =
Hash(vchPrivKey) == checksum)) {
407 strErr =
"Error reading wallet database: Encrypted key corrupt";
414 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCryptedKey failed";
417 }
catch (
const std::exception& e) {
418 if (strErr.empty()) {
434 ssValue >> kMasterKey;
437 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
444 }
catch (
const std::exception& e) {
445 if (strErr.empty()) {
460 }
catch (
const std::exception& e) {
461 if (strErr.empty()) {
476 pwallet->LoadMinVersion(nMinVersion);
486 if (!pwallet->LoadWalletFlags(
flags)) {
487 pwallet->WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
510 pwallet->
WalletLogPrintf(
"Error getting database cursor for '%s' records\n", key);
520 pwallet->
WalletLogPrintf(
"Error reading next '%s' record for wallet database\n", key);
528 DBErrors record_res = load_func(pwallet, ssKey, ssValue, error);
558 std::unique_ptr<DatabaseCursor> cursor = batch.GetNewPrefixCursor(
prefix);
560 pwallet->WalletLogPrintf(
"Error getting database cursor for '%s' records\n", type);
566 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());
580 result = std::max(result, hd_chain_res.
m_result);
587 result = std::max(result, key_res.
m_result);
594 result = std::max(result, ckey_res.
m_result);
605 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCScript failed";
606 return DBErrors::NONCRITICAL_ERROR;
610 result = std::max(result, script_res.
m_result);
619 std::map<uint160, CHDChain> hd_chains;
633 bool internal = false;
635 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
636 std::vector<uint32_t> path;
637 if (keyMeta.has_key_origin) {
639 path = keyMeta.key_origin.path;
642 if (!ParseHDKeypath(keyMeta.hdKeypath, path)) {
643 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
644 return DBErrors::NONCRITICAL_ERROR;
652 if (path.size() != 3) {
653 strErr =
"Error reading wallet database: keymeta found with unexpected path";
654 return DBErrors::NONCRITICAL_ERROR;
656 if (path[0] != 0x80000000) {
657 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
658 return DBErrors::NONCRITICAL_ERROR;
660 if (path[1] != 0x80000000 && path[1] != (1 | 0x80000000)) {
661 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
662 return DBErrors::NONCRITICAL_ERROR;
664 if ((path[2] & 0x80000000) == 0) {
665 strErr = strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
666 return DBErrors::NONCRITICAL_ERROR;
668 internal = path[1] == (1 | 0x80000000);
669 index = path[2] & ~0x80000000;
689 result = std::max(result, keymeta_res.m_result);
692 if (!hd_chains.empty()) {
693 LegacyDataSPKM* legacy_spkm = pwallet->GetLegacyDataSPKM();
695 for (
const auto& [hd_seed_id, chain] : hd_chains) {
696 if (hd_seed_id != legacy_spkm->GetHDChain().seed_id) {
697 legacy_spkm->AddInactiveHDChain(chain);
701 pwallet->WalletLogPrintf(
"Inactive HD Chains found but no Legacy ScriptPubKeyMan\n");
714 pwallet->GetOrCreateLegacyDataSPKM()->LoadWatchOnly(
script);
718 result = std::max(result, watch_script_res.m_result);
725 CKeyMetadata keyMeta;
727 pwallet->GetOrCreateLegacyDataSPKM()->LoadScriptMetadata(
CScriptID(
script), keyMeta);
730 result = std::max(result, watch_meta_res.m_result);
739 pwallet->GetOrCreateLegacyDataSPKM()->LoadKeyPool(nIndex, keypool);
742 result = std::max(result, pool_res.m_result);
754 value >> default_pubkey;
755 }
catch (
const std::exception& e) {
759 if (!default_pubkey.
IsValid()) {
760 err =
"Error reading wallet database: Default Key corrupt";
761 return DBErrors::CORRUPT;
765 result = std::max(result, default_key_res.m_result);
770 err =
"Found unsupported 'wkey' record, try loading with version 0.18";
773 result = std::max(result, wkey_res.m_result);
777 pwallet->WalletLogPrintf(
"Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
778 key_res.m_records, ckey_res.m_records, keymeta_res.m_records, key_res.m_records + ckey_res.m_records);
781 if (pwallet->IsLegacy() && (key_res.m_records + ckey_res.m_records + watch_script_res.m_records) != (keymeta_res.m_records + watch_meta_res.m_records)) {
782 auto spk_man = pwallet->GetLegacyScriptPubKeyMan();
784 LOCK(spk_man->cs_KeyStore);
785 spk_man->UpdateTimeFirstKey(1);
793template<
typename... Args>
810 DBErrors result = DBErrors::LOAD_OK;
817 }
catch (
const std::ios_base::failure& e) {
818 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
819 strErr += (last_client >
CLIENT_VERSION) ?
"The wallet might had been created on a newer version. " :
820 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
821 strErr +=
"Please try running the latest software version";
823 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
824 return DBErrors::UNKNOWN_DESCRIPTOR;
829 if (
id != spkm.
GetID()) {
830 strErr =
"The descriptor ID calculated by the wallet differs from the one in DB";
831 return DBErrors::CORRUPT;
842 uint32_t key_exp_index;
846 key >> key_exp_index;
859 xpub.
Decode(ser_xpub.data());
865 return DBErrors::LOAD_OK;
867 result = std::max(result, key_cache_res.
m_result);
874 uint32_t key_exp_index;
877 key >> key_exp_index;
882 xpub.
Decode(ser_xpub.data());
884 return DBErrors::LOAD_OK;
886 result = std::max(result, lh_cache_res.
m_result);
891 spk_man->SetCache(cache);
904 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
905 return DBErrors::CORRUPT;
915 std::vector<unsigned char> to_hash;
916 to_hash.reserve(pubkey.
size() + pkey.size());
917 to_hash.insert(to_hash.end(), pubkey.
begin(), pubkey.
end());
918 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
920 if (
Hash(to_hash) != hash)
922 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
923 return DBErrors::CORRUPT;
926 if (!privkey.
Load(pkey, pubkey,
true))
928 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
929 return DBErrors::CORRUPT;
931 spk_man->AddKey(pubkey.
GetID(), privkey);
932 return DBErrors::LOAD_OK;
934 result = std::max(result, key_res.
m_result);
948 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
949 return DBErrors::CORRUPT;
951 std::vector<unsigned char> privkey;
954 spk_man->AddCryptedKey(pubkey.
GetID(), pubkey, privkey);
955 return DBErrors::LOAD_OK;
957 result = std::max(result, ckey_res.
m_result);
963 if (desc_res.
m_result <= DBErrors::NONCRITICAL_ERROR) {
965 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
966 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
975 DBErrors result = DBErrors::LOAD_OK;
980 std::string strAddress;
984 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
985 return DBErrors::LOAD_OK;
987 result = std::max(result, name_res.
m_result);
992 std::string strAddress;
994 std::string purpose_str;
995 value >> purpose_str;
996 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
998 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
1001 return DBErrors::LOAD_OK;
1003 result = std::max(result, purpose_res.m_result);
1008 std::string strAddress, strKey, strValue;
1012 const CTxDestination& dest{DecodeDestination(strAddress)};
1013 if (strKey.compare(
"used") == 0) {
1020 pwallet->LoadAddressPreviouslySpent(dest);
1021 }
else if (strKey.starts_with(
"rr")) {
1024 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
1026 return DBErrors::LOAD_OK;
1028 result = std::max(result, dest_res.m_result);
1036 DBErrors result = DBErrors::LOAD_OK;
1039 any_unordered =
false;
1042 DBErrors result = DBErrors::LOAD_OK;
1047 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
1050 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1051 result = DBErrors::CORRUPT;
1055 if (wtx.GetHash() != hash)
1059 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
1065 std::string unused_string;
1066 value >> fTmp >> fUnused >> unused_string;
1067 pwallet->WalletLogPrintf(
"LoadWallet() upgrading tx ver=%d %d %s\n",
1068 wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
1069 wtx.fTimeReceivedIsTxTime = fTmp;
1073 pwallet->WalletLogPrintf(
"LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString());
1074 wtx.fTimeReceivedIsTxTime = 0;
1076 upgraded_txs.push_back(hash);
1079 if (wtx.nOrderPos == -1)
1080 any_unordered = true;
1086 result = std::max(result, DBErrors::NEED_RESCAN);
1090 result = std::max(result, tx_res.m_result);
1099 pwallet->LockCoin(COutPoint(hash, n));
1100 return DBErrors::LOAD_OK;
1102 result = std::max(result, locked_utxo_res.m_result);
1109 value >> pwallet->nOrderPosNext;
1110 }
catch (
const std::exception& e) {
1112 return DBErrors::NONCRITICAL_ERROR;
1114 return DBErrors::LOAD_OK;
1116 result = std::max(result, order_pos_res.m_result);
1124 DBErrors result = DBErrors::LOAD_OK;
1127 std::set<std::pair<OutputType, bool>> seen_spks;
1131 uint8_t output_type;
1137 auto [it,
insert] = seen_spks.emplace(
static_cast<OutputType>(output_type), internal);
1139 strErr =
"Multiple ScriptpubKeyMans specified for a single type";
1140 return DBErrors::CORRUPT;
1143 return DBErrors::LOAD_OK;
1145 result = std::max(result, spkm_res.
m_result);
1158 return DBErrors::CORRUPT;
1160 return DBErrors::LOAD_OK;
1167 DBErrors result = DBErrors::LOAD_OK;
1168 bool any_unordered =
false;
1169 std::vector<uint256> upgraded_txs;
1179 if ((result =
LoadMinVersion(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1183 if ((result =
LoadWalletFlags(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1185#ifndef ENABLE_EXTERNAL_SIGNER
1187 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
1188 return DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED;
1200 if (result == DBErrors::UNKNOWN_DESCRIPTOR)
return result;
1206 result = std::max(
LoadTxRecords(pwallet, *m_batch, upgraded_txs, any_unordered), result);
1216 result = DBErrors::CORRUPT;
1221 if (result != DBErrors::LOAD_OK)
1224 for (
const uint256& hash : upgraded_txs)
1225 WriteTx(pwallet->mapWallet.at(hash));
1238 result = DBErrors::CORRUPT;
1246 result = DBErrors::CORRUPT;
1254 pwallet->
WalletLogPrintf(
"Detected extraneous encryption keys in this wallet without private keys. Removing extraneous encryption keys.\n");
1256 if (!EraseMasterKey(
id)) {
1257 pwallet->
WalletLogPrintf(
"Error: Unable to remove extraneous encryption key '%u'. Wallet corrupt.\n",
id);
1258 return DBErrors::CORRUPT;
1298 static std::atomic<bool> fOneThread(
false);
1299 if (fOneThread.exchange(
true)) {
1303 for (
const std::shared_ptr<CWallet>& pwallet :
GetWallets(context)) {
1323bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1326 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1329bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1334bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1343 return m_batch->ErasePrefix(
prefix);
1351bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1356bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1358 return std::all_of(types.begin(), types.end(), [&](
const std::string& type) {
1359 return m_batch->ErasePrefix(DataStream() << type);
1363bool WalletBatch::TxnBegin()
1365 return m_batch->TxnBegin();
1368bool WalletBatch::TxnCommit()
1370 bool res = m_batch->TxnCommit();
1372 for (
const auto& listener : m_txn_listeners) {
1373 listener.on_commit();
1376 m_txn_listeners.clear();
1381bool WalletBatch::TxnAbort()
1383 bool res = m_batch->TxnAbort();
1385 for (
const auto& listener : m_txn_listeners) {
1386 listener.on_abort();
1389 m_txn_listeners.clear();
1396 assert(m_batch->HasActiveTxn());
1397 m_txn_listeners.emplace_back(l);
1404 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1405 }
catch (
const fs::filesystem_error& e) {
1407 status = DatabaseStatus::FAILED_BAD_PATH;
1411 std::optional<DatabaseFormat>
format;
1414 format = DatabaseFormat::BERKELEY;
1419 status = DatabaseStatus::FAILED_BAD_FORMAT;
1422 format = DatabaseFormat::SQLITE;
1426 status = DatabaseStatus::FAILED_NOT_FOUND;
1432 status = DatabaseStatus::FAILED_BAD_FORMAT;
1438 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1444 format = DatabaseFormat::BERKELEY_RO;
1450 status = DatabaseStatus::FAILED_BAD_FORMAT;
1460 format = DatabaseFormat::SQLITE;
1463 format = DatabaseFormat::BERKELEY;
1467 if (
format == DatabaseFormat::SQLITE) {
1469 if constexpr (
true) {
1475 status = DatabaseStatus::FAILED_BAD_FORMAT;
1480 if (
format == DatabaseFormat::BERKELEY_RO) {
1485 if constexpr (
true) {
1491 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 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
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
uint32_t nInternalChainCounter
static const int VERSION_HD_BASE
uint32_t nExternalChainCounter
static const int VERSION_HD_CHAIN_SPLIT
CKeyID seed_id
seed hash160
A key from a CWallet's keypool.
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(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 ReadPool(int64_t nPool, CKeyPool &keypool)
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 WritePool(int64_t nPool, const CKeyPool &keypool)
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
bool ErasePool(int64_t nPool)
bool EraseWatchOnly(const CScript &script)
An instance of this class represents one database.
virtual bool PeriodicFlush()=0
int64_t nLastWalletUpdate
std::atomic< unsigned int > nUpdateCounter
unsigned int nLastFlushed
Descriptor with some wallet metadata.
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
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
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
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,...)
static bool exists(const path &p)
static std::string PathToString(const path &path)
Convert path object to a byte string.
std::string get_filesystem_error_message(const fs::filesystem_error &e)
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
std::unique_ptr< BerkeleyDatabase > MakeBerkeleyDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Return object giving access to Berkeley database at specified path.
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)
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
void MaybeCompactWalletDB(WalletContext &context)
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
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
Error statuses for the wallet database.
@ 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 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
WalletContext struct containing references to state shared between CWallet instances,...
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
consteval auto _(util::TranslatedLiteral str)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.