6 #include <bitcoin-build-config.h> 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)) {
234 return WriteIC(make_pair(key, type),
id);
240 return EraseIC(make_pair(key, type));
246 std::vector<unsigned char> key;
247 key.reserve(pubkey.
size() + privkey.size());
248 key.insert(key.end(), pubkey.
begin(), pubkey.
end());
249 key.insert(key.end(), privkey.begin(), privkey.end());
271 xpub.
Encode(ser_xpub.data());
278 xpub.
Encode(ser_xpub.data());
285 xpub.
Encode(ser_xpub.data());
297 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
327 if (!vchPubKey.IsValid())
329 strErr =
"Error reading wallet database: CPubKey corrupt";
347 catch (
const std::ios_base::failure&) {}
349 bool fSkipCheck =
false;
354 std::vector<unsigned char> vchKey;
355 vchKey.reserve(vchPubKey.size() + pkey.size());
356 vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
357 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
359 if (
Hash(vchKey) != hash)
361 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
368 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
370 strErr =
"Error reading wallet database: CPrivKey corrupt";
375 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadKey failed";
378 }
catch (
const std::exception& e) {
379 if (strErr.empty()) {
393 if (!vchPubKey.IsValid())
395 strErr =
"Error reading wallet database: CPubKey corrupt";
398 std::vector<unsigned char> vchPrivKey;
399 ssValue >> vchPrivKey;
402 bool checksum_valid =
false;
403 if (!ssValue.
eof()) {
406 if (!(checksum_valid =
Hash(vchPrivKey) == checksum)) {
407 strErr =
"Error reading wallet database: Encrypted key corrupt";
414 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCryptedKey failed";
417 }
catch (
const std::exception& e) {
418 if (strErr.empty()) {
434 ssValue >> kMasterKey;
437 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
444 }
catch (
const std::exception& e) {
445 if (strErr.empty()) {
460 }
catch (
const std::exception& e) {
461 if (strErr.empty()) {
474 pwallet->WalletLogPrintf(
"Wallet file version = %d\n", nMinVersion);
477 pwallet->LoadMinVersion(nMinVersion);
487 if (!pwallet->LoadWalletFlags(
flags)) {
488 pwallet->WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
501 using LoadFunc = std::function<DBErrors(CWallet* pwallet, DataStream& key, DataStream& value, std::string& err)>;
511 pwallet->
WalletLogPrintf(
"Error getting database cursor for '%s' records\n", key);
521 pwallet->
WalletLogPrintf(
"Error reading next '%s' record for wallet database\n", key);
529 DBErrors record_res = load_func(pwallet, ssKey, ssValue, error);
533 result.m_result = std::max(
result.m_result, record_res);
559 std::unique_ptr<DatabaseCursor> cursor = batch.GetNewPrefixCursor(
prefix);
561 pwallet->WalletLogPrintf(
"Error getting database cursor for '%s' records\n", type);
567 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());
606 strErr =
"Error reading wallet database: LegacyDataSPKM::LoadCScript failed";
620 std::map<uint160, CHDChain> hd_chains;
634 bool internal =
false;
636 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
637 std::vector<uint32_t> path;
638 if (keyMeta.has_key_origin) {
640 path = keyMeta.key_origin.path;
644 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
653 if (path.size() != 3) {
654 strErr =
"Error reading wallet database: keymeta found with unexpected path";
657 if (path[0] != 0x80000000) {
658 strErr =
strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
661 if (path[1] != 0x80000000 && path[1] != (1 | 0x80000000)) {
662 strErr =
strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
665 if ((path[2] & 0x80000000) == 0) {
666 strErr =
strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
669 internal = path[1] == (1 | 0x80000000);
670 index = path[2] & ~0x80000000;
674 auto [ins, inserted] = hd_chains.emplace(keyMeta.hd_seed_id,
CHDChain());
679 chain.
seed_id = keyMeta.hd_seed_id;
693 if (!hd_chains.empty()) {
696 for (
const auto& [hd_seed_id, chain] : hd_chains) {
702 pwallet->
WalletLogPrintf(
"Inactive HD Chains found but no Legacy ScriptPubKeyMan\n");
755 value >> default_pubkey;
756 }
catch (
const std::exception& e) {
760 if (!default_pubkey.
IsValid()) {
761 err =
"Error reading wallet database: Default Key corrupt";
771 err =
"Found unsupported 'wkey' record, try loading with version 0.18";
778 pwallet->
WalletLogPrintf(
"Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
785 LOCK(spk_man->cs_KeyStore);
786 spk_man->UpdateTimeFirstKey(1);
794 template<
typename... Args>
818 }
catch (
const std::ios_base::failure& e) {
819 strErr =
strprintf(
"Error: Unrecognized descriptor found in wallet %s. ", pwallet->
GetName());
820 strErr += (last_client >
CLIENT_VERSION) ?
"The wallet might had been created on a newer version. " :
821 "The database might be corrupted or the software version is not compatible with one of your wallet descriptors. ";
822 strErr +=
"Please try running the latest software version";
824 strErr =
strprintf(
"%s\nDetails: %s", strErr, e.what());
830 if (
id != spkm.
GetID()) {
831 strErr =
"The descriptor ID calculated by the wallet differs from the one in DB";
843 uint32_t key_exp_index;
847 key >> key_exp_index;
860 xpub.
Decode(ser_xpub.data());
875 uint32_t key_exp_index;
878 key >> key_exp_index;
883 xpub.
Decode(ser_xpub.data());
892 spk_man->SetCache(cache);
903 if (!pubkey.IsValid())
905 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey corrupt";
916 std::vector<unsigned char> to_hash;
917 to_hash.reserve(pubkey.size() + pkey.size());
918 to_hash.insert(to_hash.end(), pubkey.begin(), pubkey.end());
919 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
921 if (
Hash(to_hash) != hash)
923 strErr =
"Error reading wallet database: descriptor unencrypted key CPubKey/CPrivKey corrupt";
927 if (!privkey.
Load(pkey, pubkey,
true))
929 strErr =
"Error reading wallet database: descriptor unencrypted key CPrivKey corrupt";
932 spk_man->AddKey(pubkey.GetID(), privkey);
947 if (!pubkey.IsValid())
949 err =
"Error reading wallet database: descriptor encrypted key CPubKey corrupt";
952 std::vector<unsigned char> privkey;
955 spk_man->AddCryptedKey(pubkey.GetID(), pubkey, privkey);
966 pwallet->
WalletLogPrintf(
"Descriptors: %u, Descriptor Keys: %u plaintext, %u encrypted, %u total.\n",
967 desc_res.
m_records, num_keys, num_ckeys, num_keys + num_ckeys);
981 std::string strAddress;
985 pwallet->m_address_book[DecodeDestination(strAddress)].SetLabel(label);
986 return DBErrors::LOAD_OK;
993 std::string strAddress;
995 std::string purpose_str;
996 value >> purpose_str;
997 std::optional<AddressPurpose> purpose{PurposeFromString(purpose_str)};
999 pwallet->
WalletLogPrintf(
"Warning: nonstandard purpose string '%s' for address '%s'\n", purpose_str, strAddress);
1009 std::string strAddress, strKey, strValue;
1013 const CTxDestination& dest{DecodeDestination(strAddress)};
1014 if (strKey.compare(
"used") == 0) {
1021 pwallet->LoadAddressPreviouslySpent(dest);
1022 }
else if (strKey.starts_with(
"rr")) {
1025 pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
1040 any_unordered =
false;
1043 DBErrors result = DBErrors::LOAD_OK;
1048 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
1051 err =
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.";
1052 result = DBErrors::CORRUPT;
1056 if (wtx.GetHash() != hash)
1060 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
1066 std::string unused_string;
1067 value >> fTmp >> fUnused >> unused_string;
1068 pwallet->WalletLogPrintf(
"LoadWallet() upgrading tx ver=%d %d %s\n",
1069 wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
1070 wtx.fTimeReceivedIsTxTime = fTmp;
1074 pwallet->WalletLogPrintf(
"LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString());
1075 wtx.fTimeReceivedIsTxTime = 0;
1077 upgraded_txs.push_back(hash);
1080 if (wtx.nOrderPos == -1)
1081 any_unordered = true;
1100 pwallet->LockCoin(COutPoint(hash, n));
1101 return DBErrors::LOAD_OK;
1110 value >> pwallet->nOrderPosNext;
1111 }
catch (
const std::exception& e) {
1113 return DBErrors::NONCRITICAL_ERROR;
1115 return DBErrors::LOAD_OK;
1121 for (
auto& [
id, wtx] : pwallet->mapWallet) {
1122 if (wtx.IsCoinBase() && wtx.isInactive()) {
1123 pwallet->AbandonTransaction(wtx);
1136 std::set<std::pair<OutputType, bool>> seen_spks;
1140 uint8_t output_type;
1146 auto [it,
insert] = seen_spks.emplace(static_cast<OutputType>(output_type),
internal);
1148 strErr =
"Multiple ScriptpubKeyMans specified for a single type";
1149 return DBErrors::CORRUPT;
1152 return DBErrors::LOAD_OK;
1167 return DBErrors::CORRUPT;
1169 return DBErrors::LOAD_OK;
1177 bool any_unordered =
false;
1178 std::vector<uint256> upgraded_txs;
1185 if (has_last_client) pwallet->
WalletLogPrintf(
"Last client version = %d\n", last_client);
1194 #ifndef ENABLE_EXTERNAL_SIGNER 1196 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
1197 return DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED;
1209 if (
result == DBErrors::UNKNOWN_DESCRIPTOR)
return result;
1225 result = DBErrors::CORRUPT;
1230 if (
result != DBErrors::LOAD_OK)
1233 for (
const uint256& hash : upgraded_txs)
1234 WriteTx(pwallet->mapWallet.at(hash));
1247 result = DBErrors::CORRUPT;
1255 result = DBErrors::CORRUPT;
1263 pwallet->
WalletLogPrintf(
"Detected extraneous encryption keys in this wallet without private keys. Removing extraneous encryption keys.\n");
1265 if (!EraseMasterKey(
id)) {
1266 pwallet->
WalletLogPrintf(
"Error: Unable to remove extraneous encryption key '%u'. Wallet corrupt.\n",
id);
1267 return DBErrors::CORRUPT;
1307 static std::atomic<bool> fOneThread(
false);
1308 if (fOneThread.exchange(
true)) {
1312 for (
const std::shared_ptr<CWallet>& pwallet :
GetWallets(context)) {
1332 bool WalletBatch::WriteAddressPreviouslySpent(
const CTxDestination& dest,
bool previously_spent)
1335 return previously_spent ? WriteIC(key, std::string(
"1")) : EraseIC(key);
1338 bool WalletBatch::WriteAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& receive_request)
1343 bool WalletBatch::EraseAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id)
1352 return m_batch->ErasePrefix(
prefix);
1360 bool WalletBatch::WriteWalletFlags(
const uint64_t
flags)
1365 bool WalletBatch::EraseRecords(
const std::unordered_set<std::string>& types)
1367 return std::all_of(types.begin(), types.end(), [&](
const std::string& type) {
1368 return m_batch->ErasePrefix(
DataStream() << type);
1372 bool WalletBatch::TxnBegin()
1374 return m_batch->TxnBegin();
1377 bool WalletBatch::TxnCommit()
1379 bool res = m_batch->TxnCommit();
1381 for (
const auto& listener : m_txn_listeners) {
1382 listener.on_commit();
1385 m_txn_listeners.clear();
1390 bool WalletBatch::TxnAbort()
1392 bool res = m_batch->TxnAbort();
1394 for (
const auto& listener : m_txn_listeners) {
1395 listener.on_abort();
1398 m_txn_listeners.clear();
1405 assert(m_batch->HasActiveTxn());
1406 m_txn_listeners.emplace_back(l);
1413 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1414 }
catch (
const fs::filesystem_error& e) {
1416 status = DatabaseStatus::FAILED_BAD_PATH;
1420 std::optional<DatabaseFormat>
format;
1423 format = DatabaseFormat::BERKELEY;
1428 status = DatabaseStatus::FAILED_BAD_FORMAT;
1431 format = DatabaseFormat::SQLITE;
1435 status = DatabaseStatus::FAILED_NOT_FOUND;
1441 status = DatabaseStatus::FAILED_BAD_FORMAT;
1447 status = DatabaseStatus::FAILED_ALREADY_EXISTS;
1453 format = DatabaseFormat::BERKELEY_RO;
1459 status = DatabaseStatus::FAILED_BAD_FORMAT;
1469 format = DatabaseFormat::SQLITE;
1472 format = DatabaseFormat::BERKELEY;
1476 if (
format == DatabaseFormat::SQLITE) {
1478 if constexpr (
true) {
1484 status = DatabaseStatus::FAILED_BAD_FORMAT;
1489 if (
format == DatabaseFormat::BERKELEY_RO) {
1494 if constexpr (
true) {
1500 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
bool HasEncryptionKeys() const override
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.
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
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)
DBErrors
Error statuses for the wallet database.
const std::string WALLETDESCRIPTORCKEY
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
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.
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)
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
static DataStream PrefixStream(const Args &... args)
std::function< DBErrors(CWallet *pwallet, DataStream &key, DataStream &value, std::string &err)> LoadFunc
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
bool TxnAbort()
Abort current transaction.
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)
RecursiveMutex cs_wallet
Main wallet lock.
void AddInactiveHDChain(const CHDChain &chain)
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)
bool WriteLockedUTXO(const COutPoint &output)
bool WriteMinVersion(int nVersion)
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
Access to the wallet database.
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
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
consteval auto _(util::TranslatedLiteral str)
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 LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) ...
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)
A transaction with a bunch of additional info that only the owner cares about.
const std::string WATCHMETA
bool EraseName(const std::string &strAddress)
Indicates that the wallet needs an external signer.
bool LoadEncryptionKey(CWallet *pwallet, DataStream &ssKey, DataStream &ssValue, std::string &strErr)
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])
bool TxnCommit()
Commit current transaction.
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)
Double ended buffer combining vector and stream-like interfaces.
bool WriteTx(const CWalletTx &wtx)
unsigned int nLastFlushed
uint256 GetID() const override
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.
An encapsulated public key.
LegacyDataSPKM * GetOrCreateLegacyDataSPKM()
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) ...
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
virtual void LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
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)
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.
virtual void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
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)
const Txid & GetHash() const LIFETIMEBOUND
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
#define LogDebug(category,...)
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".
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.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
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)
bool TxnBegin()
Begin a new transaction.
bool HaveCryptedKeys() 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
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.
bool WriteIC(const K &key, const T &value, bool fOverwrite=true)
const std::string DEFAULTKEY
An encapsulated private key.
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
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
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.
const CHDChain & GetHDChain() const
bool EraseMasterKey(unsigned int id)
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
CKeyID seed_id
seed hash160
LegacyDataSPKM * GetLegacyDataSPKM() const
DescriptorScriptPubKeyMan & LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor &desc)
Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it.
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.
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.
static const int VERSION_HD_CHAIN_SPLIT