6 #if defined(HAVE_CONFIG_H)
46 const std::string
FLAGS{
"flags"};
49 const std::string
KEY{
"key"};
53 const std::string
NAME{
"name"};
56 const std::string
POOL{
"pool"};
59 const std::string
TX{
"tx"};
119 std::vector<unsigned char> vchKey;
120 vchKey.reserve(vchPubKey.
size() + vchPrivKey.size());
121 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
122 vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
128 const std::vector<unsigned char>& vchCryptedSecret,
139 if (!
WriteIC(key, std::make_pair(vchCryptedSecret, checksum),
false)) {
141 std::vector<unsigned char> val;
142 if (!
m_batch->Read(key, val)) {
145 if (!
WriteIC(key, std::make_pair(val, checksum),
true)) {
219 return WriteIC(make_pair(key, type),
id);
225 return EraseIC(make_pair(key, type));
231 std::vector<unsigned char> key;
232 key.reserve(pubkey.
size() + privkey.size());
233 key.insert(key.end(), pubkey.
begin(), pubkey.
end());
234 key.insert(key.end(), privkey.begin(), privkey.end());
256 xpub.
Encode(ser_xpub.data());
263 xpub.
Encode(ser_xpub.data());
270 xpub.
Encode(ser_xpub.data());
282 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
314 strErr =
"Error reading wallet database: CPubKey corrupt";
332 catch (
const std::ios_base::failure&) {}
334 bool fSkipCheck =
false;
339 std::vector<unsigned char> vchKey;
340 vchKey.reserve(vchPubKey.
size() + pkey.size());
341 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
342 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
344 if (
Hash(vchKey) != hash)
346 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
353 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
355 strErr =
"Error reading wallet database: CPrivKey corrupt";
360 strErr =
"Error reading wallet database: LegacyScriptPubKeyMan::LoadKey failed";
363 }
catch (
const std::exception& e) {
364 if (strErr.empty()) {
380 strErr =
"Error reading wallet database: CPubKey corrupt";
383 std::vector<unsigned char> vchPrivKey;
384 ssValue >> vchPrivKey;
387 bool checksum_valid =
false;
388 if (!ssValue.
eof()) {
391 if (!(checksum_valid =
Hash(vchPrivKey) == checksum)) {
392 strErr =
"Error reading wallet database: Encrypted key corrupt";
399 strErr =
"Error reading wallet database: LegacyScriptPubKeyMan::LoadCryptedKey failed";
402 }
catch (
const std::exception& e) {
403 if (strErr.empty()) {
419 ssValue >> kMasterKey;
422 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
429 }
catch (
const std::exception& e) {
430 if (strErr.empty()) {
445 }
catch (
const std::exception& e) {
446 if (strErr.empty()) {
461 pwallet->LoadMinVersion(nMinVersion);
471 if (!pwallet->LoadWalletFlags(
flags)) {
472 pwallet->WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
495 pwallet->
WalletLogPrintf(
"Error getting database cursor for '%s' records\n", key);
505 pwallet->
WalletLogPrintf(
"Error reading next '%s' record for wallet database\n", key);
513 DBErrors record_res = load_func(pwallet, ssKey, ssValue, error);
543 std::unique_ptr<DatabaseCursor> cursor = batch.GetNewPrefixCursor(
prefix);
545 pwallet->WalletLogPrintf(
"Error getting database cursor for '%s' records\n", type);
551 pwallet->WalletLogPrintf(
"Error: Unexpected legacy entry found in descriptor wallet %s. The wallet might have been tampered with or created with malicious intent.\n", pwallet->GetName());
565 result = std::max(result, hd_chain_res.
m_result);
572 result = std::max(result, key_res.
m_result);
579 result = std::max(result, ckey_res.
m_result);
590 strErr =
"Error reading wallet database: LegacyScriptPubKeyMan::LoadCScript failed";
591 return DBErrors::NONCRITICAL_ERROR;
595 result = std::max(result, script_res.
m_result);
604 std::map<uint160, CHDChain> hd_chains;
618 bool internal = false;
620 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
621 std::vector<uint32_t> path;
622 if (keyMeta.has_key_origin) {
624 path = keyMeta.key_origin.path;
627 if (!ParseHDKeypath(keyMeta.hdKeypath, path)) {
628 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
629 return DBErrors::NONCRITICAL_ERROR;
637 if (path.size() != 3) {
638 strErr =
"Error reading wallet database: keymeta found with unexpected path";
639 return DBErrors::NONCRITICAL_ERROR;
641 if (path[0] != 0x80000000) {
642 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
643 return DBErrors::NONCRITICAL_ERROR;
645 if (path[1] != 0x80000000 && path[1] != (1 | 0x80000000)) {
646 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
647 return DBErrors::NONCRITICAL_ERROR;
649 if ((path[2] & 0x80000000) == 0) {
650 strErr = strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
651 return DBErrors::NONCRITICAL_ERROR;
653 internal = path[1] == (1 | 0x80000000);
654 index = path[2] & ~0x80000000;
674 result = std::max(result, keymeta_res.m_result);
677 if (!hd_chains.empty()) {
678 LegacyScriptPubKeyMan* legacy_spkm = pwallet->GetLegacyScriptPubKeyMan();
680 for (
const auto& [hd_seed_id, chain] : hd_chains) {
681 if (hd_seed_id != legacy_spkm->GetHDChain().seed_id) {
682 legacy_spkm->AddInactiveHDChain(chain);
686 pwallet->WalletLogPrintf(
"Inactive HD Chains found but no Legacy ScriptPubKeyMan\n");
699 pwallet->GetOrCreateLegacyScriptPubKeyMan()->LoadWatchOnly(script);
703 result = std::max(result, watch_script_res.m_result);
710 CKeyMetadata keyMeta;
712 pwallet->GetOrCreateLegacyScriptPubKeyMan()->LoadScriptMetadata(
CScriptID(script), keyMeta);
715 result = std::max(result, watch_meta_res.m_result);
724 pwallet->GetOrCreateLegacyScriptPubKeyMan()->LoadKeyPool(nIndex, keypool);
727 result = std::max(result, pool_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);
766 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)) {
767 auto spk_man = pwallet->GetOrCreateLegacyScriptPubKeyMan();
769 LOCK(spk_man->cs_KeyStore);
770 spk_man->UpdateTimeFirstKey(1);
778 template<
typename... Args>
795 DBErrors result = DBErrors::LOAD_OK;
802 }
catch (
const std::ios_base::failure& e) {
803 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
804 strErr += (last_client >
CLIENT_VERSION) ?
"The wallet might had been created on a newer version. " :
805 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
806 strErr +=
"Please try running the latest software version";
808 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
809 return DBErrors::UNKNOWN_DESCRIPTOR;
814 if (
id != spkm.
GetID()) {
815 strErr =
"The descriptor ID calculated by the wallet differs from the one in DB";
816 return DBErrors::CORRUPT;
827 uint32_t key_exp_index;
831 key >> key_exp_index;
844 xpub.
Decode(ser_xpub.data());
850 return DBErrors::LOAD_OK;
852 result = std::max(result, key_cache_res.
m_result);
859 uint32_t key_exp_index;
862 key >> key_exp_index;
867 xpub.
Decode(ser_xpub.data());
869 return DBErrors::LOAD_OK;
871 result = std::max(result, lh_cache_res.
m_result);
876 spk_man->SetCache(cache);
889 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
890 return DBErrors::CORRUPT;
900 std::vector<unsigned char> to_hash;
901 to_hash.reserve(pubkey.
size() + pkey.size());
902 to_hash.insert(to_hash.end(), pubkey.
begin(), pubkey.
end());
903 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
905 if (
Hash(to_hash) != hash)
907 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
908 return DBErrors::CORRUPT;
911 if (!privkey.
Load(pkey, pubkey,
true))
913 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
914 return DBErrors::CORRUPT;
916 spk_man->AddKey(pubkey.
GetID(), privkey);
917 return DBErrors::LOAD_OK;
919 result = std::max(result, key_res.
m_result);
933 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
934 return DBErrors::CORRUPT;
936 std::vector<unsigned char> privkey;
939 spk_man->AddCryptedKey(pubkey.
GetID(), pubkey, privkey);
940 return DBErrors::LOAD_OK;
942 result = std::max(result, ckey_res.
m_result);
948 if (desc_res.
m_result <= DBErrors::NONCRITICAL_ERROR) {
950 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
951 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
960 DBErrors result = DBErrors::LOAD_OK;
965 std::string strAddress;
969 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
970 return DBErrors::LOAD_OK;
972 result = std::max(result, name_res.
m_result);
977 std::string strAddress;
979 std::string purpose_str;
980 value >> purpose_str;
981 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
983 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
986 return DBErrors::LOAD_OK;
988 result = std::max(result, purpose_res.m_result);
993 std::string strAddress, strKey, strValue;
997 const CTxDestination& dest{DecodeDestination(strAddress)};
998 if (strKey.compare(
"used") == 0) {
1005 pwallet->LoadAddressPreviouslySpent(dest);
1006 }
else if (strKey.compare(0, 2,
"rr") == 0) {
1009 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
1011 return DBErrors::LOAD_OK;
1013 result = std::max(result, dest_res.m_result);
1021 DBErrors result = DBErrors::LOAD_OK;
1024 any_unordered =
false;
1027 DBErrors result = DBErrors::LOAD_OK;
1032 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
1035 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1036 result = DBErrors::CORRUPT;
1040 if (wtx.GetHash() != hash)
1044 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
1050 std::string unused_string;
1051 value >> fTmp >> fUnused >> unused_string;
1052 pwallet->WalletLogPrintf(
"LoadWallet() upgrading tx ver=%d %d %s\n",
1053 wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
1054 wtx.fTimeReceivedIsTxTime = fTmp;
1058 pwallet->WalletLogPrintf(
"LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString());
1059 wtx.fTimeReceivedIsTxTime = 0;
1061 upgraded_txs.push_back(hash);
1064 if (wtx.nOrderPos == -1)
1065 any_unordered = true;
1071 result = std::max(result, DBErrors::NEED_RESCAN);
1075 result = std::max(result, tx_res.m_result);
1084 pwallet->LockCoin(COutPoint(hash, n));
1085 return DBErrors::LOAD_OK;
1087 result = std::max(result, locked_utxo_res.m_result);
1094 value >> pwallet->nOrderPosNext;
1095 }
catch (
const std::exception& e) {
1097 return DBErrors::NONCRITICAL_ERROR;
1099 return DBErrors::LOAD_OK;
1101 result = std::max(result, order_pos_res.m_result);
1109 DBErrors result = DBErrors::LOAD_OK;
1112 std::set<std::pair<OutputType, bool>> seen_spks;
1116 uint8_t output_type;
1122 auto [it,
insert] = seen_spks.emplace(
static_cast<OutputType>(output_type),
internal);
1124 strErr =
"Multiple ScriptpubKeyMans specified for a single type";
1125 return DBErrors::CORRUPT;
1128 return DBErrors::LOAD_OK;
1130 result = std::max(result, spkm_res.
m_result);
1143 return DBErrors::CORRUPT;
1145 return DBErrors::LOAD_OK;
1152 DBErrors result = DBErrors::LOAD_OK;
1153 bool any_unordered =
false;
1154 std::vector<uint256> upgraded_txs;
1164 if ((result =
LoadMinVersion(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1168 if ((result =
LoadWalletFlags(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1170 #ifndef ENABLE_EXTERNAL_SIGNER
1172 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
1173 return DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED;
1185 if (result == DBErrors::UNKNOWN_DESCRIPTOR)
return result;
1191 result = std::max(
LoadTxRecords(pwallet, *m_batch, upgraded_txs, any_unordered), result);
1201 result = DBErrors::CORRUPT;
1206 if (result != DBErrors::LOAD_OK)
1209 for (
const uint256& hash : upgraded_txs)
1210 WriteTx(pwallet->mapWallet.at(hash));
1223 result = DBErrors::CORRUPT;
1231 result = DBErrors::CORRUPT;
1268 static std::atomic<bool> fOneThread(
false);
1269 if (fOneThread.exchange(
true)) {
1273 for (
const std::shared_ptr<CWallet>& pwallet :
GetWallets(context)) {
1293 bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1296 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1299 bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1304 bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1313 return m_batch->ErasePrefix(
prefix);
1321 bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1326 bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1329 return std::all_of(types.begin(), types.end(), [&
self](
const std::string& type) {
1330 return self.m_batch->ErasePrefix(DataStream() << type);
1335 bool WalletBatch::TxnBegin()
1337 return m_batch->TxnBegin();
1340 bool WalletBatch::TxnCommit()
1342 return m_batch->TxnCommit();
1345 bool WalletBatch::TxnAbort()
1347 return m_batch->TxnAbort();
1354 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1355 }
catch (
const fs::filesystem_error& e) {
1357 status = DatabaseStatus::FAILED_BAD_PATH;
1361 std::optional<DatabaseFormat>
format;
1364 format = DatabaseFormat::BERKELEY;
1369 status = DatabaseStatus::FAILED_BAD_FORMAT;
1372 format = DatabaseFormat::SQLITE;
1376 status = DatabaseStatus::FAILED_NOT_FOUND;
1382 status = DatabaseStatus::FAILED_BAD_FORMAT;
1388 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1395 status = DatabaseStatus::FAILED_BAD_FORMAT;
1405 format = DatabaseFormat::SQLITE;
1408 format = DatabaseFormat::BERKELEY;
1412 if (
format == DatabaseFormat::SQLITE) {
1414 if constexpr (
true) {
1420 status = DatabaseStatus::FAILED_BAD_FORMAT;
1426 if constexpr (
true) {
1432 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.
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.
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
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)
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
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)
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.