 |
Bitcoin Core
22.99.0
P2P Digital Currency
|
Go to the documentation of this file.
40 const std::string
FLAGS{
"flags"};
43 const std::string
KEY{
"key"};
47 const std::string
NAME{
"name"};
50 const std::string
POOL{
"pool"};
53 const std::string
TX{
"tx"};
112 std::vector<unsigned char> vchKey;
113 vchKey.reserve(vchPubKey.
size() + vchPrivKey.size());
114 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
115 vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
121 const std::vector<unsigned char>& vchCryptedSecret,
132 if (!
WriteIC(key, std::make_pair(vchCryptedSecret, checksum),
false)) {
134 std::vector<unsigned char> val;
135 if (!
m_batch->Read(key, val)) {
138 if (!
WriteIC(key, std::make_pair(val, checksum),
true)) {
212 return WriteIC(make_pair(key, type),
id);
218 return EraseIC(make_pair(key, type));
224 std::vector<unsigned char> key;
225 key.reserve(pubkey.
size() + privkey.size());
226 key.insert(key.end(), pubkey.
begin(), pubkey.
end());
227 key.insert(key.end(), privkey.begin(), privkey.end());
249 xpub.
Encode(ser_xpub.data());
256 xpub.
Encode(ser_xpub.data());
263 xpub.
Encode(ser_xpub.data());
275 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
331 if (filter_fn && !filter_fn(strType)) {
335 std::string strAddress;
341 std::string strAddress;
349 auto fill_wtx = [&](
CWalletTx& wtx,
bool new_tx) {
358 if (wtx.GetHash() != hash)
362 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
364 if (!ssValue.
empty())
368 std::string unused_string;
369 ssValue >> fTmp >> fUnused >> unused_string;
370 strErr =
strprintf(
"LoadWallet() upgrading tx ver=%d %d %s",
371 wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
372 wtx.fTimeReceivedIsTxTime = fTmp;
376 strErr =
strprintf(
"LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString());
377 wtx.fTimeReceivedIsTxTime = 0;
382 if (wtx.nOrderPos == -1)
402 if (!vchPubKey.IsValid())
404 strErr =
"Error reading wallet database: CPubKey corrupt";
423 catch (
const std::ios_base::failure&) {}
425 bool fSkipCheck =
false;
430 std::vector<unsigned char> vchKey;
431 vchKey.reserve(vchPubKey.size() + pkey.size());
432 vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
433 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
435 if (
Hash(vchKey) != hash)
437 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
444 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
446 strErr =
"Error reading wallet database: CPrivKey corrupt";
451 strErr =
"Error reading wallet database: LegacyScriptPubKeyMan::LoadKey failed";
459 ssValue >> kMasterKey;
462 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
471 if (!vchPubKey.IsValid())
473 strErr =
"Error reading wallet database: CPubKey corrupt";
476 std::vector<unsigned char> vchPrivKey;
477 ssValue >> vchPrivKey;
480 bool checksum_valid =
false;
481 if (!ssValue.
eof()) {
484 if ((checksum_valid =
Hash(vchPrivKey) != checksum)) {
485 strErr =
"Error reading wallet database: Encrypted key corrupt";
494 strErr =
"Error reading wallet database: LegacyScriptPubKeyMan::LoadCryptedKey failed";
511 bool internal =
false;
513 if (keyMeta.hdKeypath !=
"s" && keyMeta.hdKeypath !=
"m") {
514 std::vector<uint32_t> path;
515 if (keyMeta.has_key_origin) {
517 path = keyMeta.key_origin.path;
521 strErr =
"Error reading wallet database: keymeta with invalid HD keypath";
530 if (path.size() != 3) {
531 strErr =
"Error reading wallet database: keymeta found with unexpected path";
534 if (path[0] != 0x80000000) {
535 strErr =
strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000) for the element at index 0", path[0]);
538 if (path[1] != 0x80000000 && path[1] != (1 | 0x80000000)) {
539 strErr =
strprintf(
"Unexpected path index of 0x%08x (expected 0x80000000 or 0x80000001) for the element at index 1", path[1]);
542 if ((path[2] & 0x80000000) == 0) {
543 strErr =
strprintf(
"Unexpected path index of 0x%08x (expected to be greater than or equal to 0x80000000)", path[2]);
546 internal = path[1] == (1 | 0x80000000);
547 index = path[2] & ~0x80000000;
552 CHDChain& chain = ins.first->second;
556 chain.
seed_id = keyMeta.hd_seed_id;
576 ssValue >> vchPubKey;
577 if (!vchPubKey.IsValid()) {
578 strErr =
"Error reading wallet database: Default Key corrupt";
595 strErr =
"Error reading wallet database: LegacyScriptPubKeyMan::LoadCScript failed";
599 ssValue >> pwallet->nOrderPosNext;
601 std::string strAddress, strKey, strValue;
611 strErr =
"Found unsupported 'wkey' record, try loading with version 0.18";
621 if (spk_mans.count(
static_cast<OutputType>(type)) > 0) {
622 strErr =
"Multiple ScriptPubKeyMans specified for a single type";
638 uint32_t key_exp_index;
641 ssKey >> key_exp_index;
654 xpub.
Decode(ser_xpub.data());
662 uint32_t key_exp_index;
664 ssKey >> key_exp_index;
669 xpub.
Decode(ser_xpub.data());
676 if (!pubkey.IsValid())
678 strErr =
"Error reading wallet database: CPubKey corrupt";
690 std::vector<unsigned char> to_hash;
691 to_hash.reserve(pubkey.size() + pkey.size());
692 to_hash.insert(to_hash.end(), pubkey.begin(), pubkey.end());
693 to_hash.insert(to_hash.end(), pkey.begin(), pkey.end());
695 if (
Hash(to_hash) != hash)
697 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
701 if (!key.
Load(pkey, pubkey,
true))
703 strErr =
"Error reading wallet database: CPrivKey corrupt";
706 wss.
m_descriptor_keys.insert(std::make_pair(std::make_pair(desc_id, pubkey.GetID()), key));
712 if (!pubkey.IsValid())
714 strErr =
"Error reading wallet database: CPubKey corrupt";
717 std::vector<unsigned char> privkey;
721 wss.
m_descriptor_crypt_keys.insert(std::make_pair(std::make_pair(desc_id, pubkey.GetID()), std::make_pair(pubkey, privkey)));
735 }
catch (
const std::exception& e) {
736 if (strErr.empty()) {
741 if (strErr.empty()) {
742 strErr =
"Caught unknown exception in ReadKeyValue";
753 return ReadKeyValue(pwallet, ssKey, ssValue, dummy_wss, strType, strErr, filter_fn);
765 bool fNoncriticalErrors =
false;
766 bool rescan_required =
false;
783 pwallet->
WalletLogPrintf(
"Error reading wallet database: Unknown non-tolerable wallet flags found\n");
788 #ifndef ENABLE_EXTERNAL_SIGNER
790 pwallet->
WalletLogPrintf(
"Error: External signer wallet being loaded without external signer support compiled\n");
808 bool ret =
m_batch->ReadAtCursor(ssKey, ssValue, complete);
815 pwallet->
WalletLogPrintf(
"Error reading next record from wallet database\n");
820 std::string strType, strErr;
821 if (!
ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr))
831 pwallet->
WalletLogPrintf(
"Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.\n");
837 fNoncriticalErrors =
true;
840 rescan_required =
true;
873 ((
DescriptorScriptPubKeyMan*)spk_man)->AddCryptedKey(desc_key_pair.first.second, desc_key_pair.second.first, desc_key_pair.second.second);
892 pwallet->
WalletLogPrintf(
"Wallet File Version = %d\n", wallet_version > 0 ? wallet_version : last_client);
894 pwallet->
WalletLogPrintf(
"Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total. Unknown wallet records: %u\n",
901 LOCK(spk_man->cs_KeyStore);
902 spk_man->UpdateTimeFirstKey(1);
907 WriteTx(pwallet->mapWallet.at(hash));
910 if (wss.
fIsEncrypted && (last_client == 40000 || last_client == 50000))
939 pwallet->
WalletLogPrintf(
"Inactive HD Chains found but no Legacy ScriptPubKeyMan\n");
966 LogPrintf(
"Error getting wallet database cursor\n");
976 bool ret =
m_batch->ReadAtCursor(ssKey, ssValue, complete);
981 LogPrintf(
"Error reading next record from wallet database\n");
990 vTxHash.push_back(hash);
992 ssValue >> vWtx.back();
1006 std::vector<uint256> vTxHash;
1007 std::list<CWalletTx> vWtx;
1013 std::sort(vTxHash.begin(), vTxHash.end());
1014 std::sort(vTxHashIn.begin(), vTxHashIn.end());
1017 bool delerror =
false;
1018 std::vector<uint256>::iterator it = vTxHashIn.begin();
1019 for (
const uint256& hash : vTxHash) {
1020 while (it < vTxHashIn.end() && (*it) < hash) {
1023 if (it == vTxHashIn.end()) {
1026 else if ((*it) == hash) {
1028 LogPrint(
BCLog::WALLETDB,
"Transaction was found for deletion but returned database error: %s\n", hash.GetHex());
1031 vTxHashOut.push_back(hash);
1043 static std::atomic<bool> fOneThread(
false);
1044 if (fOneThread.exchange(
true)) {
1108 exists = fs::symlink_status(path).type() != fs::file_type::not_found;
1109 }
catch (
const fs::filesystem_error& e) {
1115 std::optional<DatabaseFormat>
format;
1186 return std::make_unique<DummyDatabase>();
1193 return std::make_unique<SQLiteDatabase>(
"",
"",
true);
1195 return std::make_unique<BerkeleyDatabase>(std::make_shared<BerkeleyEnvironment>(),
"");
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
void LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Adds a destination data tuple to the store, without saving it to disk.
An instance of this class represents one database.
const unsigned int BIP32_EXTKEY_SIZE
bool WriteDescriptorCacheItems(const uint256 &desc_id, const DescriptorCache &cache)
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.
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
const uint256 & GetHash() const
void AddInactiveHDChain(const CHDChain &chain)
const std::string HDCHAIN
const std::string ACENTRY
const std::string DESTDATA
static bool exists(const path &p)
const std::string VERSION
bool WriteCryptedDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const std::vector< unsigned char > &secret)
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
bool LoadToWallet(const uint256 &hash, const UpdateWalletTxFn &fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
const std::string MASTER_KEY
std::vector< uint256 > vWalletUpgrade
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
const std::string WALLETDESCRIPTORCKEY
const std::string CRYPTED_KEY
int GetVersion() const
get the current wallet format (the oldest client version guaranteed to understand this wallet)
const std::string BESTBLOCK_NOMERKLE
const std::string SETTINGS
void WalletLogPrintf(std::string fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
bool WriteDescriptorLastHardenedCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index)
fs::path BDBDataFile(const fs::path &wallet_path)
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
bool WriteMinVersion(int nVersion)
A key from a CWallet's keypool.
std::string get_filesystem_error_message(const fs::filesystem_error &e)
const std::string WALLETDESCRIPTOR
const ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
bool WriteLockedUTXO(const COutPoint &output)
bool WriteDescriptorKey(const uint256 &desc_id, const CPubKey &pubkey, const CPrivKey &privkey)
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
CPrivKey is a serialized private key, with all parameters included (SIZE bytes)
bool WritePool(int64_t nPool, const CKeyPool &keypool)
bool WriteOrderPosNext(int64_t nOrderPosNext)
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)
int64_t GetTime()
DEPRECATED Use either GetTimeSeconds (not mockable) or GetTime<T> (mockable)
bool WriteBestBlock(const CBlockLocator &locator)
const std::string BESTBLOCK
const std::string MINVERSION
std::function< bool(const std::string &)> KeyFilterFn
Callback for filtering key types to deserialize in ReadKeyValue.
DBErrors
Error statuses for the wallet database.
const std::string PURPOSE
const std::string CSCRIPT
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
const std::string WALLETDESCRIPTORKEY
bool IsSQLiteFile(const fs::path &path)
static const int VERSION_HD_BASE
static std::string PathToString(const path &path)
Convert path object to a byte string.
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
bool TxnAbort()
Abort current transaction.
int64_t nLastWalletUpdate
DBErrors FindWalletTx(std::vector< uint256 > &vTxHash, std::list< CWalletTx > &vWtx)
bool LoadWalletFlags(uint64_t flags)
Loads the flags into the wallet.
A transaction with a bunch of additional info that only the owner cares about.
bool EraseName(const std::string &strAddress)
bool LockCoin(const COutPoint &output, WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
unsigned int nMasterKeyMaxID
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256 &id, bool internal)
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
std::map< OutputType, uint256 > m_active_external_spks
bool ReadPool(int64_t nPool, CKeyPool &keypool)
bool EraseWatchOnly(const CScript &script)
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
std::unique_ptr< WalletDatabase > CreateDummyWalletDatabase()
Return object for accessing dummy database with no read/write capabilities.
const std::string WATCHMETA
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
@ WALLET_FLAG_EXTERNAL_SIGNER
Indicates that the wallet needs an external signer.
const unsigned char * begin() const
static const int VERSION_HD_CHAIN_SPLIT
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
bool TxnCommit()
Commit current transaction.
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
MasterKeyMap mapMasterKeys
bool IsLegacy() const
Determine if we are a legacy wallet.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
std::unique_ptr< DatabaseBatch > m_batch
void LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor &desc)
Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it.
bool ReadBestBlock(CBlockLocator &locator)
bool WriteWalletFlags(const uint64_t flags)
const unsigned char * end() const
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
bool WriteKeyMetadata(const CKeyMetadata &meta, const CPubKey &pubkey, const bool overwrite)
std::optional< DatabaseFormat > require_format
DBErrors ReorderTransactions()
DBErrors LoadWallet(CWallet *pwallet)
std::map< uint160, CHDChain > m_hd_chains
bool ErasePool(int64_t nPool)
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Loads an active ScriptPubKeyMan for the specified type and internal.
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key.
bool WriteDescriptorDerivedCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index, uint32_t der_index)
std::map< std::pair< uint256, CKeyID >, CKey > m_descriptor_keys
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
CKeyID seed_id
seed hash160
bool WriteTx(const CWalletTx &wtx)
#define LogPrint(category,...)
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
Serialized script, used inside transaction inputs and outputs.
std::map< OutputType, uint256 > m_active_internal_spks
const std::string KEYMETA
std::unique_ptr< WalletDatabase > CreateMockWalletDatabase()
Return object for accessing temporary in-memory database.
void UpgradeDescriptorCache() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade DescriptorCaches.
std::map< std::pair< uint256, CKeyID >, std::pair< CPubKey, std::vector< unsigned char > > > m_descriptor_crypt_keys
const ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
Cache for single descriptor's derived extended pubkeys.
RecursiveMutex cs_wallet
Main wallet lock.
const CHDChain & GetHDChain() const
bool EraseTx(uint256 hash)
std::atomic< unsigned int > nUpdateCounter
bool TxnBegin()
Begin a new transaction.
State of transaction not confirmed or conflicting with a known block and not in the mempool.
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
An encapsulated public key.
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
ScriptPubKeyMan * GetScriptPubKeyMan(const OutputType &type, bool internal) const
Get the ScriptPubKeyMan for the given OutputType and internal/external chain.
const std::string ACTIVEINTERNALSPK
An encapsulated private key.
LegacyScriptPubKeyMan * GetLegacyScriptPubKeyMan() const
Get the LegacyScriptPubKeyMan which is used for all types, internal, and external.
uint32_t nExternalChainCounter
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< uint256 > vHave
static bool IsKeyType(const std::string &strType)
bool WriteName(const std::string &strAddress, const std::string &strName)
bool WriteDescriptorParentCache(const CExtPubKey &xpub, const uint256 &desc_id, uint32_t key_exp_index)
bool EraseLockedUTXO(const COutPoint &output)
bool ErasePurpose(const std::string &strAddress)
bool LoadCScript(const CScript &redeemScript)
Adds a CScript to the store.
void LoadScriptMetadata(const CScriptID &script_id, const CKeyMetadata &metadata)
const std::string WALLETDESCRIPTORCACHE
const std::string WALLETDESCRIPTORLHCACHE
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
virtual bool PeriodicFlush()=0
std::unique_ptr< SQLiteDatabase > MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
bool WriteIC(const K &key, const T &value, bool fOverwrite=true)
const std::string ACTIVEEXTERNALSPK
bool EraseIC(const K &key)
unsigned int m_unknown_records
static bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, CDataStream &ssValue, CWalletScanState &wss, std::string &strType, std::string &strErr, const KeyFilterFn &filter_fn=nullptr) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
bool IsBDBFile(const fs::path &path)
Double ended buffer combining vector and stream-like interfaces.
bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal)
Descriptor with some wallet metadata.
An outpoint - a combination of a transaction hash and an index n into its vout.
const std::string LOCKED_UTXO
bool Load(const CPrivKey &privkey, const CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
WalletContext struct containing references to state shared between CWallet instances,...
bool error(const char *fmt, const Args &... args)
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0'/2000".
void MaybeCompactWalletDB(WalletContext &context)
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
const std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
const std::string OLD_KEY
A reference to a CScript: the Hash160 of its serialization (see script.h)
uint32_t nInternalChainCounter
void LoadHDChain(const CHDChain &chain)
Load a HD chain model (used by LoadWallet)
bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
const std::string DEFAULTKEY
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
const std::string ORDERPOSNEXT
unsigned int nLastFlushed
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
fs::path SQLiteDataFile(const fs::path &path)
std::map< uint256, DescriptorCache > m_descriptor_caches