42 const std::string
FLAGS{
"flags"};
45 const std::string
KEY{
"key"};
49 const std::string
NAME{
"name"};
52 const std::string
POOL{
"pool"};
55 const std::string
TX{
"tx"};
115 std::vector<unsigned char> vchKey;
116 vchKey.reserve(vchPubKey.
size() + vchPrivKey.size());
117 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
118 vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
124 const std::vector<unsigned char>& vchCryptedSecret,
135 if (!
WriteIC(key, std::make_pair(vchCryptedSecret, checksum),
false)) {
137 std::vector<unsigned char> val;
138 if (!
m_batch->Read(key, val)) {
141 if (!
WriteIC(key, std::make_pair(val, checksum),
true)) {
215 return WriteIC(make_pair(key, type),
id);
221 return EraseIC(make_pair(key, type));
227 std::vector<unsigned char> key;
228 key.reserve(pubkey.
size() + privkey.size());
229 key.insert(key.end(), pubkey.
begin(), pubkey.
end());
230 key.insert(key.end(), privkey.begin(), privkey.end());
252 xpub.
Encode(ser_xpub.data());
259 xpub.
Encode(ser_xpub.data());
266 xpub.
Encode(ser_xpub.data());
278 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
308 if (!vchPubKey.IsValid())
310 strErr =
"Error reading wallet database: CPubKey corrupt";
328 catch (
const std::ios_base::failure&) {}
330 bool fSkipCheck =
false;
335 std::vector<unsigned char> vchKey;
336 vchKey.reserve(vchPubKey.size() + pkey.size());
337 vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
338 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
340 if (
Hash(vchKey) != hash)
342 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
349 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
351 strErr =
"Error reading wallet database: CPrivKey corrupt";
356 strErr =
"Error reading wallet database: LegacyScriptPubKeyMan::LoadKey failed";
359 }
catch (
const std::exception& e) {
360 if (strErr.empty()) {
374 if (!vchPubKey.IsValid())
376 strErr =
"Error reading wallet database: CPubKey corrupt";
379 std::vector<unsigned char> vchPrivKey;
380 ssValue >> vchPrivKey;
383 bool checksum_valid =
false;
384 if (!ssValue.
eof()) {
387 if (!(checksum_valid =
Hash(vchPrivKey) == checksum)) {
388 strErr =
"Error reading wallet database: Encrypted key corrupt";
395 strErr =
"Error reading wallet database: LegacyScriptPubKeyMan::LoadCryptedKey failed";
398 }
catch (
const std::exception& e) {
399 if (strErr.empty()) {
415 ssValue >> kMasterKey;
418 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
425 }
catch (
const std::exception& e) {
426 if (strErr.empty()) {
441 }
catch (
const std::exception& e) {
442 if (strErr.empty()) {
457 pwallet->LoadMinVersion(nMinVersion);
467 if (!pwallet->LoadWalletFlags(
flags)) {
468 pwallet->WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
481 using LoadFunc = std::function<DBErrors(CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err)>;
491 pwallet->
WalletLogPrintf(
"Error getting database cursor for '%s' records\n", key);
501 pwallet->
WalletLogPrintf(
"Error reading next '%s' record for wallet database\n", key);
509 DBErrors record_res = load_func(pwallet, ssKey, ssValue,
error);
539 std::unique_ptr<DatabaseCursor> cursor = batch.GetNewPrefixCursor(
prefix);
541 pwallet->WalletLogPrintf(
"Error getting database cursor for '%s' records\n", type);
547 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());
561 result = std::max(result, hd_chain_res.
m_result);
568 result = std::max(result, key_res.
m_result);
575 result = std::max(result, ckey_res.
m_result);
586 strErr =
"Error reading wallet database: LegacyScriptPubKeyMan::LoadCScript failed";
591 result = std::max(result, script_res.
m_result);
600 std::map<uint160, CHDChain> hd_chains;
614 bool internal =
false;
616 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
617 std::vector<uint32_t> path;
618 if (keyMeta.has_key_origin) {
620 path = keyMeta.key_origin.path;
624 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
633 if (path.size() != 3) {
634 strErr =
"Error reading wallet database: keymeta found with unexpected path";
637 if (path[0] != 0x80000000) {
638 strErr =
strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
641 if (path[1] != 0x80000000 && path[1] != (1 | 0x80000000)) {
642 strErr =
strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
645 if ((path[2] & 0x80000000) == 0) {
646 strErr =
strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
649 internal = path[1] == (1 | 0x80000000);
650 index = path[2] & ~0x80000000;
654 auto [ins, inserted] = hd_chains.emplace(keyMeta.hd_seed_id,
CHDChain());
659 chain.
seed_id = keyMeta.hd_seed_id;
670 result = std::max(result, keymeta_res.
m_result);
673 if (!hd_chains.empty()) {
676 for (
const auto& [hd_seed_id, chain] : hd_chains) {
682 pwallet->
WalletLogPrintf(
"Inactive HD Chains found but no Legacy ScriptPubKeyMan\n");
699 result = std::max(result, watch_script_res.
m_result);
711 result = std::max(result, watch_meta_res.
m_result);
723 result = std::max(result, pool_res.
m_result);
735 value >> default_pubkey;
736 }
catch (
const std::exception& e) {
740 if (!default_pubkey.
IsValid()) {
741 err =
"Error reading wallet database: Default Key corrupt";
746 result = std::max(result, default_key_res.
m_result);
751 err =
"Found unsupported 'wkey' record, try loading with version 0.18";
754 result = std::max(result, wkey_res.
m_result);
758 pwallet->
WalletLogPrintf(
"Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
765 LOCK(spk_man->cs_KeyStore);
766 spk_man->UpdateTimeFirstKey(1);
774 template<
typename... Args>
798 }
catch (
const std::ios_base::failure& e) {
799 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
800 strErr += (last_client >
CLIENT_VERSION) ?
"The wallet might had been created on a newer version. " :
801 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
802 strErr +=
"Please try running the latest software version";
804 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
811 strErr =
"The descriptor ID calculated by the wallet differs from the one in DB";
823 uint32_t key_exp_index;
827 key >> key_exp_index;
840 xpub.
Decode(ser_xpub.data());
848 result = std::max(result, key_cache_res.
m_result);
855 uint32_t key_exp_index;
858 key >> key_exp_index;
863 xpub.
Decode(ser_xpub.data());
867 result = std::max(result, lh_cache_res.
m_result);
872 spk_man->SetCache(cache);
883 if (!pubkey.IsValid())
885 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
896 std::vector<unsigned char> to_hash;
897 to_hash.reserve(pubkey.size() + pkey.size());
898 to_hash.insert(to_hash.end(), pubkey.begin(), pubkey.end());
899 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
901 if (
Hash(to_hash) != hash)
903 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
907 if (!privkey.
Load(pkey, pubkey,
true))
909 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
912 spk_man->AddKey(pubkey.GetID(), privkey);
915 result = std::max(result, key_res.
m_result);
927 if (!pubkey.IsValid())
929 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
932 std::vector<unsigned char> privkey;
935 spk_man->AddCryptedKey(pubkey.GetID(), pubkey, privkey);
938 result = std::max(result, ckey_res.
m_result);
946 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
947 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
961 std::string strAddress;
965 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
966 return DBErrors::LOAD_OK;
968 result = std::max(result, name_res.
m_result);
973 std::string strAddress;
975 std::string purpose_str;
976 value >> purpose_str;
977 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
979 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
984 result = std::max(result, purpose_res.m_result);
989 std::string strAddress, strKey, strValue;
993 const CTxDestination& dest{DecodeDestination(strAddress)};
994 if (strKey.compare(
"used") == 0) {
1001 pwallet->LoadAddressPreviouslySpent(dest);
1002 }
else if (strKey.compare(0, 2,
"rr") == 0) {
1005 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
1009 result = std::max(result, dest_res.m_result);
1017 DBErrors result = DBErrors::LOAD_OK;
1020 any_unordered =
false;
1023 DBErrors result = DBErrors::LOAD_OK;
1028 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
1031 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1032 result = DBErrors::CORRUPT;
1036 if (wtx.GetHash() != hash)
1040 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
1046 std::string unused_string;
1047 value >> fTmp >> fUnused >> unused_string;
1048 pwallet->WalletLogPrintf(
"LoadWallet() upgrading tx ver=%d %d %s\n",
1049 wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
1050 wtx.fTimeReceivedIsTxTime = fTmp;
1054 pwallet->WalletLogPrintf(
"LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString());
1055 wtx.fTimeReceivedIsTxTime = 0;
1057 upgraded_txs.push_back(hash);
1060 if (wtx.nOrderPos == -1)
1061 any_unordered = true;
1067 result = std::max(result, DBErrors::NEED_RESCAN);
1071 result = std::max(result, tx_res.m_result);
1080 pwallet->LockCoin(COutPoint(hash, n));
1081 return DBErrors::LOAD_OK;
1083 result = std::max(result, locked_utxo_res.m_result);
1090 value >> pwallet->nOrderPosNext;
1091 }
catch (
const std::exception& e) {
1093 return DBErrors::NONCRITICAL_ERROR;
1095 return DBErrors::LOAD_OK;
1097 result = std::max(result, order_pos_res.m_result);
1105 DBErrors result = DBErrors::LOAD_OK;
1108 std::set<std::pair<OutputType, bool>> seen_spks;
1112 uint8_t output_type;
1118 auto [it,
insert] = seen_spks.emplace(static_cast<OutputType>(output_type),
internal);
1120 strErr =
"Multiple ScriptpubKeyMans specified for a single type";
1121 return DBErrors::CORRUPT;
1124 return DBErrors::LOAD_OK;
1126 result = std::max(result, spkm_res.
m_result);
1139 return DBErrors::CORRUPT;
1141 return DBErrors::LOAD_OK;
1148 DBErrors result = DBErrors::LOAD_OK;
1149 bool any_unordered =
false;
1150 std::vector<uint256> upgraded_txs;
1160 if ((result =
LoadMinVersion(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1164 if ((result =
LoadWalletFlags(pwallet, *m_batch)) != DBErrors::LOAD_OK)
return result;
1166 #ifndef ENABLE_EXTERNAL_SIGNER 1168 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
1169 return DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED;
1181 if (result == DBErrors::UNKNOWN_DESCRIPTOR)
return result;
1187 result = std::max(
LoadTxRecords(pwallet, *m_batch, upgraded_txs, any_unordered), result);
1197 result = DBErrors::CORRUPT;
1202 if (result != DBErrors::LOAD_OK)
1205 for (
const uint256& hash : upgraded_txs)
1206 WriteTx(pwallet->mapWallet.at(hash));
1219 result = DBErrors::CORRUPT;
1227 result = DBErrors::CORRUPT;
1233 DBErrors WalletBatch::FindWalletTxHashes(std::vector<uint256>& tx_hashes)
1235 DBErrors result = DBErrors::LOAD_OK;
1238 int nMinVersion = 0;
1241 return DBErrors::TOO_NEW;
1245 std::unique_ptr<DatabaseCursor> cursor = m_batch->GetNewCursor();
1248 LogPrintf(
"Error getting wallet database cursor\n");
1249 return DBErrors::CORRUPT;
1258 if (status == DatabaseCursor::Status::DONE) {
1260 }
else if (status == DatabaseCursor::Status::FAIL) {
1261 LogPrintf(
"Error reading next record from wallet database\n");
1262 return DBErrors::CORRUPT;
1265 std::string strType;
1270 tx_hashes.push_back(hash);
1274 result = DBErrors::CORRUPT;
1280 DBErrors WalletBatch::ZapSelectTx(std::vector<uint256>& vTxHashIn, std::vector<uint256>& vTxHashOut)
1283 std::vector<uint256> vTxHash;
1284 DBErrors err = FindWalletTxHashes(vTxHash);
1285 if (err != DBErrors::LOAD_OK) {
1289 std::sort(vTxHash.begin(), vTxHash.end());
1290 std::sort(vTxHashIn.begin(), vTxHashIn.end());
1293 bool delerror =
false;
1294 std::vector<uint256>::iterator it = vTxHashIn.begin();
1295 for (
const uint256& hash : vTxHash) {
1296 while (it < vTxHashIn.end() && (*it) < hash) {
1299 if (it == vTxHashIn.end()) {
1302 else if ((*it) == hash) {
1303 if(!EraseTx(hash)) {
1304 LogPrint(
BCLog::WALLETDB,
"Transaction was found for deletion but returned database error: %s\n", hash.GetHex());
1307 vTxHashOut.push_back(hash);
1312 return DBErrors::CORRUPT;
1314 return DBErrors::LOAD_OK;
1319 static std::atomic<bool> fOneThread(
false);
1320 if (fOneThread.exchange(
true)) {
1344 bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1347 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1350 bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1355 bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1364 return m_batch->ErasePrefix(
prefix);
1372 bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1377 bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1380 if (!m_batch->TxnBegin())
return false;
1383 std::unique_ptr<DatabaseCursor> cursor = m_batch->GetNewCursor();
1395 if (status == DatabaseCursor::Status::DONE) {
1397 }
else if (status == DatabaseCursor::Status::FAIL) {
1398 cursor.reset(
nullptr);
1399 m_batch->TxnAbort();
1409 if (types.count(type) > 0) {
1410 if (!m_batch->Erase(
Span{key_data})) {
1411 cursor.reset(
nullptr);
1412 m_batch->TxnAbort();
1418 cursor.reset(
nullptr);
1419 return m_batch->TxnCommit();
1422 bool WalletBatch::TxnBegin()
1424 return m_batch->TxnBegin();
1427 bool WalletBatch::TxnCommit()
1429 return m_batch->TxnCommit();
1432 bool WalletBatch::TxnAbort()
1434 return m_batch->TxnAbort();
1441 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1442 }
catch (
const fs::filesystem_error& e) {
1444 status = DatabaseStatus::FAILED_BAD_PATH;
1448 std::optional<DatabaseFormat>
format;
1451 format = DatabaseFormat::BERKELEY;
1456 status = DatabaseStatus::FAILED_BAD_FORMAT;
1459 format = DatabaseFormat::SQLITE;
1463 status = DatabaseStatus::FAILED_NOT_FOUND;
1469 status = DatabaseStatus::FAILED_BAD_FORMAT;
1475 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1482 status = DatabaseStatus::FAILED_BAD_FORMAT;
1492 format = DatabaseFormat::SQLITE;
1495 format = DatabaseFormat::BERKELEY;
1499 if (
format == DatabaseFormat::SQLITE) {
1504 status = DatabaseStatus::FAILED_BAD_FORMAT;
1512 status = DatabaseStatus::FAILED_BAD_FORMAT;
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
const std::string MASTER_KEY
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key...
std::optional< DatabaseFormat > require_format
const std::string BESTBLOCK_NOMERKLE
const std::string SETTINGS
const std::string CRYPTED_KEY
static DBErrors LoadDescriptorWalletRecords(CWallet *pwallet, DatabaseBatch &batch, int last_client) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
const std::string HDCHAIN
const CHDChain & GetHDChain() const
#define LogPrint(category,...)
const std::string ACENTRY
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
const std::string VERSION
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) ...
void UpgradeDescriptorCache() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade DescriptorCaches.
bool LoadToWallet(const uint256 &hash, const UpdateWalletTxFn &fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
const std::string DESTDATA
static DBErrors LoadAddressBookRecords(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
std::unique_ptr< SQLiteDatabase > MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
DBErrors
Error statuses for the wallet database.
const std::string WALLETDESCRIPTORCKEY
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
const std::string BESTBLOCK
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
bool WriteCryptedDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const std::vector< unsigned char > &secret)
uint32_t nExternalChainCounter
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)
static DataStream PrefixStream(const Args &... args)
bool IsLegacy() const
Determine if we are a legacy wallet.
const std::string WALLETDESCRIPTOR
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
virtual std::unique_ptr< DatabaseCursor > GetNewPrefixCursor(Span< const std::byte > prefix)=0
MasterKeyMap mapMasterKeys
static DBErrors LoadLegacyWalletRecords(CWallet *pwallet, DatabaseBatch &batch, int last_client) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
bool LoadHDChain(CWallet *pwallet, DataStream &ssValue, std::string &strErr)
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
RecursiveMutex cs_wallet
Main wallet lock.
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
bool EraseWatchOnly(const CScript &script)
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
std::function< DBErrors(CWallet *pwallet, DataStream &key, CDataStream &value, std::string &err)> LoadFunc
bool WriteLockedUTXO(const COutPoint &output)
bool WriteMinVersion(int nVersion)
bool WritePool(int64_t nPool, const CKeyPool &keypool)
ScriptPubKeyMan * GetScriptPubKeyMan(const OutputType &type, bool internal) const
Get the ScriptPubKeyMan for the given OutputType and internal/external chain.
A key from a CWallet's keypool.
const std::string CSCRIPT
static DBErrors LoadActiveSPKMs(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
bool WriteOrderPosNext(int64_t nOrderPosNext)
bool ReadBestBlock(CBlockLocator &locator)
const std::string PURPOSE
std::atomic< unsigned int > nUpdateCounter
const std::string MINVERSION
LegacyScriptPubKeyMan * GetLegacyScriptPubKeyMan() const
Get the LegacyScriptPubKeyMan which is used for all types, internal, and external.
std::unique_ptr< DatabaseBatch > m_batch
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
const std::string WALLETDESCRIPTORKEY
RAII class that provides access to a WalletDatabase.
const unsigned char * begin() const
const std::unordered_set< std::string > LEGACY_TYPES
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, const bool overwrite)
fs::path SQLiteDataFile(const fs::path &path)
void MaybeCompactWalletDB(WalletContext &context)
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
static DBErrors LoadTxRecords(CWallet *pwallet, DatabaseBatch &batch, std::vector< uint256 > &upgraded_txs, bool &any_unordered) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
bool WriteBestBlock(const CBlockLocator &locator)
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.
int64_t nLastWalletUpdate
static DBErrors LoadWalletFlags(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
CPrivKey is a serialized private key, with all parameters included (SIZE bytes)
void LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor &desc)
Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it.
A transaction with a bunch of additional info that only the owner cares about.
const std::string WATCHMETA
bool EraseName(const std::string &strAddress)
DescriptorScriptPubKeyMan * GetDescriptorScriptPubKeyMan(const WalletDescriptor &desc) const
Return the DescriptorScriptPubKeyMan for a WalletDescriptor if it is already in the wallet...
Indicates that the wallet needs an external signer.
bool LoadEncryptionKey(CWallet *pwallet, DataStream &ssKey, DataStream &ssValue, std::string &strErr)
const_iterator end() const
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
static std::string PathToString(const path &path)
Convert path object to a byte string.
bool IsBDBFile(const fs::path &path)
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256 &id, bool internal)
const unsigned char * end() const
bool ReadPool(int64_t nPool, CKeyPool &keypool)
bool WriteDescriptorDerivedCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index, uint32_t der_index)
bool LoadCryptedKey(CWallet *pwallet, DataStream &ssKey, DataStream &ssValue, std::string &strErr)
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
Double ended buffer combining vector and stream-like interfaces.
std::vector< std::byte, zero_after_free_allocator< std::byte > > SerializeData
Byte-vector that clears its contents before deletion.
bool WriteTx(const CWalletTx &wtx)
unsigned int nLastFlushed
uint256 GetID() const override
An encapsulated public key.
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
Indicate that this wallet supports DescriptorScriptPubKeyMan.
uint32_t nInternalChainCounter
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
std::vector< uint256 > vHave
bool IsWalletFlagSet(uint64_t flag) const override
check if a certain wallet flag is set
An outpoint - a combination of a transaction hash and an index n into its vout.
static DBErrors LoadMinVersion(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
constexpr bool IsNull() const
virtual bool PeriodicFlush()=0
#define Assume(val)
Assume is the identity function.
bool ErasePurpose(const std::string &strAddress)
bool ErasePool(int64_t nPool)
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) ...
Descriptor with some wallet metadata.
const std::string ACTIVEINTERNALSPK
const std::string KEYMETA
bool WriteDescriptorParentCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index)
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
const_iterator begin() const
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
std::string get_filesystem_error_message(const fs::filesystem_error &e)
bool LoadKey(CWallet *pwallet, DataStream &ssKey, DataStream &ssValue, std::string &strErr)
catch(const std::exception &e)
const std::string WALLETDESCRIPTORCACHE
bool EraseIC(const K &key)
void WalletLogPrintf(const char *fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
const std::string ACTIVEEXTERNALSPK
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0'/2000".
bool error(const char *fmt, const Args &... args)
Cache for single descriptor's derived extended pubkeys.
Serialized script, used inside transaction inputs and outputs.
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Loads an active ScriptPubKeyMan for the specified type and internal.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
const unsigned int BIP32_EXTKEY_SIZE
fs::path BDBDataFile(const fs::path &wallet_path)
static LoadResult LoadRecords(CWallet *pwallet, DatabaseBatch &batch, const std::string &key, DataStream &prefix, LoadFunc load_func)
const uint256 & GetHash() const
bool EraseTx(uint256 hash)
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
WalletContext struct containing references to state shared between CWallet instances, like the reference to the chain interface, and the list of opened wallets.
DBErrors ReorderTransactions()
const std::string LOCKED_UTXO
bool IsSQLiteFile(const fs::path &path)
static const int VERSION_HD_BASE
void AddInactiveHDChain(const CHDChain &chain)
A reference to a CScript: the Hash160 of its serialization.
const std::string WALLETDESCRIPTORLHCACHE
bool WriteName(const std::string &strAddress, const std::string &strName)
std::string EncodeDestination(const CTxDestination &dest)
void SerializeMany(Stream &s, const Args &... args)
Support for (un)serializing many things at once.
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
int GetVersion() const
get the current wallet format (the oldest client version guaranteed to understand this wallet) ...
bool WriteIC(const K &key, const T &value, bool fOverwrite=true)
const std::string DEFAULTKEY
An encapsulated private key.
A Span is an object that can refer to a contiguous sequence of objects.
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
bool EraseLockedUTXO(const COutPoint &output)
static bool exists(const path &p)
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal)
const std::string ORDERPOSNEXT
unsigned int nMasterKeyMaxID
int64_t GetTime()
DEPRECATED, see GetTime.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
CKeyID seed_id
seed hash160
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
An instance of this class represents one database.
const std::string OLD_KEY
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
static LoadResult LoadRecords(CWallet *pwallet, DatabaseBatch &batch, const std::string &key, LoadFunc load_func)
static DBErrors LoadDecryptionKeys(CWallet *pwallet, DatabaseBatch &batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
bool WriteDescriptorLastHardenedCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index)
bool Load(const CPrivKey &privkey, const CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
static const int VERSION_HD_CHAIN_SPLIT