45 const std::string
FLAGS{
"flags"};
48 const std::string
KEY{
"key"};
52 const std::string
NAME{
"name"};
55 const std::string
POOL{
"pool"};
58 const 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)) {
218 return WriteIC(make_pair(key, type),
id);
224 return EraseIC(make_pair(key, type));
230 std::vector<unsigned char> key;
231 key.reserve(pubkey.
size() + privkey.size());
232 key.insert(key.end(), pubkey.
begin(), pubkey.
end());
233 key.insert(key.end(), privkey.begin(), privkey.end());
255 xpub.
Encode(ser_xpub.data());
262 xpub.
Encode(ser_xpub.data());
269 xpub.
Encode(ser_xpub.data());
281 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
313 strErr =
"Error reading wallet database: CPubKey corrupt";
331 catch (
const std::ios_base::failure&) {}
333 bool fSkipCheck =
false;
338 std::vector<unsigned char> vchKey;
339 vchKey.reserve(vchPubKey.
size() + pkey.size());
340 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
341 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
343 if (
Hash(vchKey) != hash)
345 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
352 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
354 strErr =
"Error reading wallet database: CPrivKey corrupt";
359 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadKey failed";
362 }
catch (
const std::exception& e) {
363 if (strErr.empty()) {
379 strErr =
"Error reading wallet database: CPubKey corrupt";
382 std::vector<unsigned char> vchPrivKey;
383 ssValue >> vchPrivKey;
386 bool checksum_valid =
false;
387 if (!ssValue.
eof()) {
390 if (!(checksum_valid =
Hash(vchPrivKey) == checksum)) {
391 strErr =
"Error reading wallet database: Encrypted key corrupt";
398 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCryptedKey failed";
401 }
catch (
const std::exception& e) {
402 if (strErr.empty()) {
418 ssValue >> kMasterKey;
421 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
428 }
catch (
const std::exception& e) {
429 if (strErr.empty()) {
444 }
catch (
const std::exception& e) {
445 if (strErr.empty()) {
460 pwallet->LoadMinVersion(nMinVersion);
470 if (!pwallet->LoadWalletFlags(
flags)) {
471 pwallet->WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
494 pwallet->
WalletLogPrintf(
"Error getting database cursor for '%s' records\n", key);
504 pwallet->
WalletLogPrintf(
"Error reading next '%s' record for wallet database\n", key);
512 DBErrors record_res = load_func(pwallet, ssKey, ssValue, error);
542 std::unique_ptr<DatabaseCursor> cursor = batch.GetNewPrefixCursor(
prefix);
544 pwallet->WalletLogPrintf(
"Error getting database cursor for '%s' records\n", type);
550 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);
723 pwallet->GetOrCreateLegacyDataSPKM()->LoadKeyPool(nIndex, keypool);
726 result = std::max(result, pool_res.m_result);
738 value >> default_pubkey;
739 }
catch (
const std::exception& e) {
743 if (!default_pubkey.
IsValid()) {
744 err =
"Error reading wallet database: Default Key corrupt";
745 return DBErrors::CORRUPT;
749 result = std::max(result, default_key_res.m_result);
754 err =
"Found unsupported 'wkey' record, try loading with version 0.18";
757 result = std::max(result, wkey_res.m_result);
761 pwallet->WalletLogPrintf(
"Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
762 key_res.m_records, ckey_res.m_records, keymeta_res.m_records, key_res.m_records + ckey_res.m_records);
765 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)) {
766 auto spk_man = pwallet->GetLegacyScriptPubKeyMan();
768 LOCK(spk_man->cs_KeyStore);
769 spk_man->UpdateTimeFirstKey(1);
777 template<
typename... Args>
794 DBErrors result = DBErrors::LOAD_OK;
801 }
catch (
const std::ios_base::failure& e) {
802 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
803 strErr += (last_client >
CLIENT_VERSION) ?
"The wallet might had been created on a newer version. " :
804 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
805 strErr +=
"Please try running the latest software version";
807 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
808 return DBErrors::UNKNOWN_DESCRIPTOR;
813 if (
id != spkm.
GetID()) {
814 strErr =
"The descriptor ID calculated by the wallet differs from the one in DB";
815 return DBErrors::CORRUPT;
826 uint32_t key_exp_index;
830 key >> key_exp_index;
843 xpub.
Decode(ser_xpub.data());
849 return DBErrors::LOAD_OK;
851 result = std::max(result, key_cache_res.
m_result);
858 uint32_t key_exp_index;
861 key >> key_exp_index;
866 xpub.
Decode(ser_xpub.data());
868 return DBErrors::LOAD_OK;
870 result = std::max(result, lh_cache_res.
m_result);
875 spk_man->SetCache(cache);
888 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
889 return DBErrors::CORRUPT;
899 std::vector<unsigned char> to_hash;
900 to_hash.reserve(pubkey.
size() + pkey.size());
901 to_hash.insert(to_hash.end(), pubkey.
begin(), pubkey.
end());
902 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
904 if (
Hash(to_hash) != hash)
906 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
907 return DBErrors::CORRUPT;
910 if (!privkey.
Load(pkey, pubkey,
true))
912 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
913 return DBErrors::CORRUPT;
915 spk_man->AddKey(pubkey.
GetID(), privkey);
916 return DBErrors::LOAD_OK;
918 result = std::max(result, key_res.
m_result);
932 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
933 return DBErrors::CORRUPT;
935 std::vector<unsigned char> privkey;
938 spk_man->AddCryptedKey(pubkey.
GetID(), pubkey, privkey);
939 return DBErrors::LOAD_OK;
941 result = std::max(result, ckey_res.
m_result);
947 if (desc_res.
m_result <= DBErrors::NONCRITICAL_ERROR) {
949 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
950 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
959 DBErrors result = DBErrors::LOAD_OK;
964 std::string strAddress;
968 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
969 return DBErrors::LOAD_OK;
971 result = std::max(result, name_res.
m_result);
976 std::string strAddress;
978 std::string purpose_str;
979 value >> purpose_str;
980 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
982 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
985 return DBErrors::LOAD_OK;
987 result = std::max(result, purpose_res.m_result);
992 std::string strAddress, strKey, strValue;
996 const CTxDestination& dest{DecodeDestination(strAddress)};
997 if (strKey.compare(
"used") == 0) {
1004 pwallet->LoadAddressPreviouslySpent(dest);
1005 }
else if (strKey.compare(0, 2,
"rr") == 0) {
1008 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
1010 return DBErrors::LOAD_OK;
1012 result = std::max(result, dest_res.m_result);
1020 DBErrors result = DBErrors::LOAD_OK;
1023 any_unordered =
false;
1026 DBErrors result = DBErrors::LOAD_OK;
1031 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
1034 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1035 result = DBErrors::CORRUPT;
1039 if (wtx.GetHash() != hash)
1043 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
1049 std::string unused_string;
1050 value >> fTmp >> fUnused >> unused_string;
1051 pwallet->WalletLogPrintf(
"LoadWallet() upgrading tx ver=%d %d %s\n",
1052 wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
1053 wtx.fTimeReceivedIsTxTime = fTmp;
1057 pwallet->WalletLogPrintf(
"LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString());
1058 wtx.fTimeReceivedIsTxTime = 0;
1060 upgraded_txs.push_back(hash);
1063 if (wtx.nOrderPos == -1)
1064 any_unordered = true;
1070 result = std::max(result, DBErrors::NEED_RESCAN);
1074 result = std::max(result, tx_res.m_result);
1083 pwallet->LockCoin(COutPoint(hash, n));
1084 return DBErrors::LOAD_OK;
1086 result = std::max(result, locked_utxo_res.m_result);
1093 value >> pwallet->nOrderPosNext;
1094 }
catch (
const std::exception& e) {
1096 return DBErrors::NONCRITICAL_ERROR;
1098 return DBErrors::LOAD_OK;
1100 result = std::max(result, order_pos_res.m_result);
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<uint256> upgraded_txs;
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 uint256& hash : upgraded_txs)
1209 WriteTx(pwallet->mapWallet.at(hash));
1222 result = DBErrors::CORRUPT;
1230 result = DBErrors::CORRUPT;
1267 static std::atomic<bool> fOneThread(
false);
1268 if (fOneThread.exchange(
true)) {
1272 for (
const std::shared_ptr<CWallet>& pwallet :
GetWallets(context)) {
1292 bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1295 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1298 bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1303 bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1312 return m_batch->ErasePrefix(
prefix);
1320 bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1325 bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1328 return std::all_of(types.begin(), types.end(), [&
self](
const std::string& type) {
1329 return self.m_batch->ErasePrefix(DataStream() << type);
1334 bool WalletBatch::TxnBegin()
1336 return m_batch->TxnBegin();
1339 bool WalletBatch::TxnCommit()
1341 return m_batch->TxnCommit();
1344 bool WalletBatch::TxnAbort()
1346 return m_batch->TxnAbort();
1353 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1354 }
catch (
const fs::filesystem_error& e) {
1356 status = DatabaseStatus::FAILED_BAD_PATH;
1360 std::optional<DatabaseFormat>
format;
1363 format = DatabaseFormat::BERKELEY;
1368 status = DatabaseStatus::FAILED_BAD_FORMAT;
1371 format = DatabaseFormat::SQLITE;
1375 status = DatabaseStatus::FAILED_NOT_FOUND;
1381 status = DatabaseStatus::FAILED_BAD_FORMAT;
1387 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1393 format = DatabaseFormat::BERKELEY_RO;
1399 status = DatabaseStatus::FAILED_BAD_FORMAT;
1409 format = DatabaseFormat::SQLITE;
1412 format = DatabaseFormat::BERKELEY;
1416 if (
format == DatabaseFormat::SQLITE) {
1418 if constexpr (
true) {
1424 status = DatabaseStatus::FAILED_BAD_FORMAT;
1429 if (
format == DatabaseFormat::BERKELEY_RO) {
1434 if constexpr (
true) {
1440 status = DatabaseStatus::FAILED_BAD_FORMAT;
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, 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.
const unsigned char * end() const
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
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...
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
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.
LegacyDataSPKM * GetOrCreateLegacyDataSPKM()
int GetVersion() const
get the current wallet format (the oldest client version guaranteed to understand this wallet)
MasterKeyMap mapMasterKeys
void WalletLogPrintf(const char *fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
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 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 LogPrint(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.
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(...)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.