6#include <bitcoin-build-config.h>
41const std::string
FLAGS{
"flags"};
44const std::string
KEY{
"key"};
50const std::string
NAME{
"name"};
53const std::string
POOL{
"pool"};
56const std::string
TX{
"tx"};
105 for (
const auto& [wtxid, tx] : wtx.
GetTxs()) {
140 const auto keypair_hash =
Hash(vchPubKey, vchPrivKey);
142 return WriteIC(std::make_pair(
DBKeys::KEY, vchPubKey), std::make_pair(vchPrivKey, keypair_hash),
false);
146 const std::vector<unsigned char>& vchCryptedSecret,
157 if (!
WriteIC(key, std::make_pair(vchCryptedSecret, checksum),
false)) {
159 std::vector<unsigned char> val;
160 if (!
m_batch->Read(key, val)) {
163 if (!
WriteIC(key, std::make_pair(val, checksum),
true)) {
220 return WriteIC(make_pair(key, type),
id);
226 return EraseIC(make_pair(key, type));
232 const auto keypair_hash =
Hash(pubkey, privkey);
239 const auto descriptor_key{std::make_pair(desc_id, pubkey)};
245 if (own_txn && !
TxnBegin())
return false;
260 std::vector<unsigned char> ser_xpub;
267 std::vector<unsigned char> ser_xpub;
274 std::vector<unsigned char> ser_xpub;
287 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
319 strErr =
"Error reading wallet database: CPubKey corrupt";
337 catch (
const std::ios_base::failure&) {}
339 bool fSkipCheck =
false;
344 const auto keypair_hash =
Hash(vchPubKey, pkey);
346 if (keypair_hash != hash)
348 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
355 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
357 strErr =
"Error reading wallet database: CPrivKey corrupt";
362 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadKey failed";
365 }
catch (
const std::exception& e) {
366 if (strErr.empty()) {
382 strErr =
"Error reading wallet database: CPubKey corrupt";
385 std::vector<unsigned char> vchPrivKey;
386 ssValue >> vchPrivKey;
389 bool checksum_valid =
false;
390 if (!ssValue.
empty()) {
393 if (!(checksum_valid =
Hash(vchPrivKey) == checksum)) {
394 strErr =
"Error reading wallet database: Encrypted key corrupt";
401 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCryptedKey failed";
404 }
catch (
const std::exception& e) {
405 if (strErr.empty()) {
421 ssValue >> kMasterKey;
424 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
431 }
catch (
const std::exception& e) {
432 if (strErr.empty()) {
447 }
catch (
const std::exception& e) {
448 if (strErr.empty()) {
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 throw std::runtime_error(
strprintf(
"Error getting database cursor for '%s' records", type));
561 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());
574 result = std::max(result, hd_chain_res.
m_result);
581 result = std::max(result, key_res.
m_result);
588 result = std::max(result, ckey_res.
m_result);
599 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCScript failed";
600 return DBErrors::NONCRITICAL_ERROR;
604 result = std::max(result, script_res.
m_result);
607 std::map<uint160, CHDChain> hd_chains;
621 bool internal = false;
623 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
624 std::vector<uint32_t> path;
625 if (keyMeta.has_key_origin) {
627 path = keyMeta.key_origin.path;
630 if (!ParseHDKeypath(keyMeta.hdKeypath, path)) {
631 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
632 return DBErrors::NONCRITICAL_ERROR;
640 if (path.size() != 3) {
641 strErr =
"Error reading wallet database: keymeta found with unexpected path";
642 return DBErrors::NONCRITICAL_ERROR;
644 if (path[0] != BIP32_HARDENED_FLAG) {
645 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
646 return DBErrors::NONCRITICAL_ERROR;
648 if (path[1] != BIP32_HARDENED_FLAG && path[1] != (1 | BIP32_HARDENED_FLAG)) {
649 strErr = strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
650 return DBErrors::NONCRITICAL_ERROR;
652 if ((path[2] & BIP32_HARDENED_FLAG) == 0) {
653 strErr = strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
654 return DBErrors::NONCRITICAL_ERROR;
656 internal = path[1] == (1 | BIP32_HARDENED_FLAG);
657 index = path[2] & ~BIP32_HARDENED_FLAG;
677 result = std::max(result, keymeta_res.m_result);
680 if (!hd_chains.empty()) {
681 LegacyDataSPKM* legacy_spkm = pwallet->GetLegacyDataSPKM();
683 for (
const auto& [hd_seed_id, chain] : hd_chains) {
684 if (hd_seed_id != legacy_spkm->GetHDChain().seed_id) {
685 legacy_spkm->AddInactiveHDChain(chain);
689 pwallet->WalletLogPrintf(
"Inactive HD chains found but no LegacyDataSPKM\n");
702 pwallet->GetOrCreateLegacyDataSPKM()->LoadWatchOnly(
script);
706 result = std::max(result, watch_script_res.m_result);
713 CKeyMetadata keyMeta;
715 pwallet->GetOrCreateLegacyDataSPKM()->LoadScriptMetadata(
CScriptID(
script), keyMeta);
718 result = std::max(result, watch_meta_res.m_result);
730 value >> default_pubkey;
731 }
catch (
const std::exception& e) {
735 if (!default_pubkey.
IsValid()) {
736 err =
"Error reading wallet database: Default Key corrupt";
737 return DBErrors::CORRUPT;
741 result = std::max(result, default_key_res.m_result);
746 err =
"Found unsupported 'wkey' record, try loading with version 0.18";
749 result = std::max(result, wkey_res.m_result);
753 pwallet->WalletLogPrintf(
"Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
754 key_res.m_records, ckey_res.m_records, keymeta_res.m_records, key_res.m_records + ckey_res.m_records);
760template<
typename... Args>
777 DBErrors result = DBErrors::LOAD_OK;
781 std::optional<WalletDescriptor> desc;
783 desc.emplace(WalletDescriptor::FromStream(
deserialize, value));
784 }
catch (
const std::ios_base::failure& e) {
785 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
786 strErr += (last_client >
VERSION_LATEST) ?
"The wallet might have been created on a newer version. " :
787 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
788 strErr +=
"Please try running the latest software version";
790 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
791 return DBErrors::UNKNOWN_DESCRIPTOR;
802 uint32_t key_exp_index;
806 key >> key_exp_index;
818 err =
"Error reading wallet database: descriptor cache xpub has invalid size";
819 return DBErrors::CORRUPT;
828 return DBErrors::LOAD_OK;
830 result = std::max(result, key_cache_res.
m_result);
837 uint32_t key_exp_index;
840 key >> key_exp_index;
844 err =
"Error reading wallet database: descriptor last hardened cache xpub has invalid size";
845 return DBErrors::CORRUPT;
850 return DBErrors::LOAD_OK;
852 result = std::max(result, lh_cache_res.
m_result);
869 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
870 return DBErrors::CORRUPT;
880 const auto keypair_hash =
Hash(pubkey, pkey);
882 if (keypair_hash != hash)
884 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
885 return DBErrors::CORRUPT;
888 if (!privkey.
Load(pkey, pubkey,
true))
890 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
891 return DBErrors::CORRUPT;
894 return DBErrors::LOAD_OK;
896 result = std::max(result, key_res.
m_result);
911 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
912 return DBErrors::CORRUPT;
914 std::vector<unsigned char> privkey;
917 ckeys[pubkey.
GetID()] = std::make_pair(pubkey, privkey);
918 return DBErrors::LOAD_OK;
920 result = std::max(result, ckey_res.
m_result);
925 }
catch (std::runtime_error& e) {
927 return DBErrors::CORRUPT;
933 if (desc_res.
m_result <= DBErrors::NONCRITICAL_ERROR) {
935 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
936 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
945 DBErrors result = DBErrors::LOAD_OK;
950 std::string strAddress;
954 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
955 return DBErrors::LOAD_OK;
957 result = std::max(result, name_res.
m_result);
962 std::string strAddress;
964 std::string purpose_str;
965 value >> purpose_str;
966 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
968 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
971 return DBErrors::LOAD_OK;
973 result = std::max(result, purpose_res.m_result);
978 std::string strAddress, strKey, strValue;
982 const CTxDestination& dest{DecodeDestination(strAddress)};
983 if (strKey.compare(
"used") == 0) {
990 pwallet->LoadAddressPreviouslySpent(dest);
991 }
else if (strKey.starts_with(
"rr")) {
994 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
996 return DBErrors::LOAD_OK;
998 result = std::max(result, dest_res.m_result);
1005 std::map<Wtxid, CTransactionRef> variants;
1018 if (status == DatabaseCursor::Status::DONE)
break;
1019 if (status == DatabaseCursor::Status::FAIL) {
1024 if (tx->GetHash() != txid) {
1025 throw std::runtime_error(
strprintf(
"Corrupted witness variant, tx hash differs"));
1027 if (!variants.emplace(tx->GetWitnessHash(), std::move(tx)).second) {
1028 throw std::runtime_error(
strprintf(
"Duplicate witness variant"));
1037 DBErrors result = DBErrors::LOAD_OK;
1040 any_unordered =
false;
1043 DBErrors result = DBErrors::LOAD_OK;
1047 CWalletTx wtx{deserialize, value, ReadWtxVariants(batch, hash)};
1048 if (wtx.GetHash() != hash) {
1049 result = std::max(result, DBErrors::NEED_RESCAN);
1052 if (wtx.nOrderPos == -1) {
1053 any_unordered = true;
1056 if (!pwallet->LoadToWallet(std::move(wtx))) {
1057 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1058 return DBErrors::CORRUPT;
1060 }
catch (
const std::exception& e) {
1061 err =
strprintf(
"Error: Corrupt tx record found: %s" ,e.what());
1062 return DBErrors::CORRUPT;
1066 result = std::max(result, tx_res.m_result);
1075 pwallet->LoadLockedCoin(COutPoint(hash, n), true);
1076 return DBErrors::LOAD_OK;
1078 result = std::max(result, locked_utxo_res.m_result);
1085 value >> pwallet->nOrderPosNext;
1086 }
catch (
const std::exception& e) {
1088 return DBErrors::NONCRITICAL_ERROR;
1090 return DBErrors::LOAD_OK;
1092 result = std::max(result, order_pos_res.m_result);
1096 for (
auto& [
id, wtx] : pwallet->mapWallet) {
1097 if (wtx.IsCoinBase() && wtx.isInactive()) {
1098 pwallet->AbandonTransaction(wtx);
1108 DBErrors result = DBErrors::LOAD_OK;
1111 std::set<std::pair<OutputType, bool>> seen_spks;
1115 uint8_t output_type;
1121 auto [it,
insert] = seen_spks.emplace(
static_cast<OutputType>(output_type), internal);
1123 strErr =
"Multiple ScriptpubKeyMans specified for a single type";
1124 return DBErrors::CORRUPT;
1127 return DBErrors::LOAD_OK;
1129 result = std::max(result, spkm_res.
m_result);
1142 return DBErrors::CORRUPT;
1144 return DBErrors::LOAD_OK;
1151 DBErrors result = DBErrors::LOAD_OK;
1152 bool any_unordered =
false;
1159 if (has_last_client) pwallet->
WalletLogPrintf(
"Last client version = %d\n", last_client);
1161 std::optional<uint64_t> last_client_features;
1165 last_client_features = features;
1177 if ((result =
LoadWalletFlags(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1179#ifndef ENABLE_EXTERNAL_SIGNER
1181 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
1182 return DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED;
1194 if (result == DBErrors::UNKNOWN_DESCRIPTOR)
return result;
1206 result = std::max(
LoadTxRecords(pwallet, *m_batch, any_unordered), result);
1207 }
catch (std::runtime_error& e) {
1213 result = DBErrors::CORRUPT;
1216 result = DBErrors::CORRUPT;
1221 if (result != DBErrors::LOAD_OK)
1232 result = DBErrors::CORRUPT;
1240 pwallet->
WalletLogPrintf(
"Detected extraneous encryption keys in this wallet without private keys. Removing extraneous encryption keys.\n");
1242 if (!EraseMasterKey(
id)) {
1243 pwallet->
WalletLogPrintf(
"Error: Unable to remove extraneous encryption key '%u'. Wallet corrupt.\n",
id);
1244 return DBErrors::CORRUPT;
1254 pwallet->
WalletLogPrintf(
"Error: Unable to erase last decrypted client features.\n");
1255 return DBErrors::LOAD_FAIL;
1263 if (!WriteLastOpenedVersion()) {
1264 pwallet->
WalletLogPrintf(
"Error: Unable to write the last opened version. Wallet corrupt.\n");
1265 return DBErrors::CORRUPT;
1270 if (!WriteLastOpenedFeatures()) {
1271 pwallet->
WalletLogPrintf(
"Error: Unable to write the last opened features. Wallet corrupt.\n");
1272 return DBErrors::CORRUPT;
1308bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1311 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1314bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1319bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1328 return m_batch->ErasePrefix(
prefix);
1331bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1336bool WalletBatch::WriteLastOpenedVersion()
1341bool WalletBatch::WriteLastOpenedFeatures()
1346bool WalletBatch::WriteLastDecryptedFeatures()
1351bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1353 return std::all_of(types.begin(), types.end(), [&](
const std::string& type) {
1354 return m_batch->ErasePrefix(DataStream() << type);
1358bool WalletBatch::TxnBegin()
1360 return m_batch->TxnBegin();
1363bool WalletBatch::TxnCommit()
1365 bool res = m_batch->TxnCommit();
1367 for (
const auto&
listener : m_txn_listeners) {
1371 m_txn_listeners.clear();
1376bool WalletBatch::TxnAbort()
1378 bool res = m_batch->TxnAbort();
1380 for (
const auto&
listener : m_txn_listeners) {
1384 m_txn_listeners.clear();
1391 assert(m_batch->HasActiveTxn());
1392 m_txn_listeners.emplace_back(std::move(l));
1399 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1400 }
catch (
const fs::filesystem_error& e) {
1402 status = DatabaseStatus::FAILED_BAD_PATH;
1406 std::optional<DatabaseFormat>
format;
1409 format = DatabaseFormat::BERKELEY_RO;
1414 status = DatabaseStatus::FAILED_BAD_FORMAT;
1417 format = DatabaseFormat::SQLITE;
1421 status = DatabaseStatus::FAILED_NOT_FOUND;
1427 status = DatabaseStatus::FAILED_BAD_FORMAT;
1433 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1439 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 or the GUI option).",
fs::PathToString(path)));
1440 status = DatabaseStatus::FAILED_LEGACY_DISABLED;
1447 status = DatabaseStatus::FAILED_BAD_FORMAT;
1455 format = DatabaseFormat::SQLITE;
1458 if (
format == DatabaseFormat::SQLITE) {
1462 if (
format == DatabaseFormat::BERKELEY_RO) {
1467 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)
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
Double ended buffer combining vector and stream-like interfaces.
Cache for single descriptor's derived extended pubkeys.
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
constexpr bool IsNull() const
const uint256 & ToUint256() const LIFETIMEBOUND
static constexpr int VERSION_HD_CHAIN_SPLIT
uint32_t nInternalChainCounter
uint32_t nExternalChainCounter
CKeyID seed_id
seed hash160
static constexpr int VERSION_HD_BASE
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
bool HaveCryptedKeys() const
LegacyDataSPKM * GetOrCreateLegacyDataSPKM()
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
void LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor &desc, const KeyMap &keys, const CryptedKeyMap &ckeys)
Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it.
void WalletLogPrintf(util::ConstevalFormatString< sizeof...(Params)> wallet_fmt, const Params &... params) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
bool HasEncryptionKeys() const override
MasterKeyMap mapMasterKeys
RecursiveMutex cs_wallet
Main wallet lock.
void SetLastDecryptedFeatures(uint64_t features) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Set the features of the last client to decrypt this wallet.
A transaction with a bunch of additional info that only the owner cares about.
const Txid & GetHash() const LIFETIMEBOUND
const std::map< Wtxid, CTransactionRef > & GetTxs() const
RAII class that provides access to a WalletDatabase.
virtual std::unique_ptr< DatabaseCursor > GetNewPrefixCursor(std::span< const std::byte > prefix)=0
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, bool checksum_valid)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
Access to the wallet database.
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
bool TxnAbort()
Abort current transaction.
bool WriteDescriptorParentCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index)
bool EraseName(const std::string &strAddress)
bool WriteBestBlock(const CBlockLocator &locator)
bool ReadBestBlock(CBlockLocator &locator)
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
bool 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 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 WriteFullTx(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 WriteTxMetadata(const CWalletTx &wtx)
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 WriteWtxVariant(const Txid &txid, const CTransactionRef &tx)
bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal)
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, bool overwrite)
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
An instance of this class represents one database.
Descriptor with some wallet metadata.
static std::string PathToString(const path &path)
Convert path object to a byte string.
bool IsWalletFlagSet(uint64_t flag) const override
check if a certain wallet flag is set
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 WTX_VARIANT
const std::string ACENTRY
const std::string ACTIVEEXTERNALSPK
const std::string LAST_DECRYPTED_FEATURES
const std::string CRYPTED_KEY
const std::string LAST_OPENED_FEATURES
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::map< CKeyID, std::pair< CPubKey, std::vector< unsigned char > > > CryptedKeyMap
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)
static DBErrors LoadTxRecords(CWallet *pwallet, DatabaseBatch &batch, bool &any_unordered) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
static std::map< Wtxid, CTransactionRef > ReadWtxVariants(DatabaseBatch &batch, const Txid &txid)
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.
std::string SQLiteDatabaseVersion()
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
@ VERSION_LAST_CLIENT_FEATURES
static DBErrors LoadAddressBookRecords(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
std::map< CKeyID, CKey > KeyMap
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)
constexpr TransactionSerParams TX_WITH_WITNESS
std::shared_ptr< const CTransaction > CTransactionRef
constexpr unsigned int BIP32_EXTKEY_SIZE
void SerializeMany(Stream &s, const Args &... args)
Support for (un)serializing many things at once.
constexpr deserialize_type deserialize
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
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
std::optional< DatabaseFormat > require_format
std::vector< uint16_t > keys
#define EXCLUSIVE_LOCKS_REQUIRED(...)
consteval auto _(util::TranslatedLiteral str)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.