Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/walletdb.cpp
Show All 38 Lines | |||||
const std::string ORDERPOSNEXT{"orderposnext"}; | const std::string ORDERPOSNEXT{"orderposnext"}; | ||||
const std::string POOL{"pool"}; | const std::string POOL{"pool"}; | ||||
const std::string PURPOSE{"purpose"}; | const std::string PURPOSE{"purpose"}; | ||||
const std::string SETTINGS{"settings"}; | const std::string SETTINGS{"settings"}; | ||||
const std::string TX{"tx"}; | const std::string TX{"tx"}; | ||||
const std::string VERSION{"version"}; | const std::string VERSION{"version"}; | ||||
const std::string WALLETDESCRIPTOR{"walletdescriptor"}; | const std::string WALLETDESCRIPTOR{"walletdescriptor"}; | ||||
const std::string WALLETDESCRIPTORCACHE{"walletdescriptorcache"}; | const std::string WALLETDESCRIPTORCACHE{"walletdescriptorcache"}; | ||||
const std::string WALLETDESCRIPTORCKEY{"walletdescriptorckey"}; | |||||
const std::string WALLETDESCRIPTORKEY{"walletdescriptorkey"}; | |||||
const std::string WATCHMETA{"watchmeta"}; | const std::string WATCHMETA{"watchmeta"}; | ||||
const std::string WATCHS{"watchs"}; | const std::string WATCHS{"watchs"}; | ||||
} // namespace DBKeys | } // namespace DBKeys | ||||
// | // | ||||
// WalletBatch | // WalletBatch | ||||
// | // | ||||
▲ Show 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | public: | ||||
unsigned int nKeyMeta{0}; | unsigned int nKeyMeta{0}; | ||||
unsigned int m_unknown_records{0}; | unsigned int m_unknown_records{0}; | ||||
bool fIsEncrypted{false}; | bool fIsEncrypted{false}; | ||||
bool fAnyUnordered{false}; | bool fAnyUnordered{false}; | ||||
std::vector<TxId> vWalletUpgrade; | std::vector<TxId> vWalletUpgrade; | ||||
std::map<OutputType, uint256> m_active_external_spks; | std::map<OutputType, uint256> m_active_external_spks; | ||||
std::map<OutputType, uint256> m_active_internal_spks; | std::map<OutputType, uint256> m_active_internal_spks; | ||||
std::map<uint256, DescriptorCache> m_descriptor_caches; | std::map<uint256, DescriptorCache> m_descriptor_caches; | ||||
std::map<std::pair<uint256, CKeyID>, CKey> m_descriptor_keys; | |||||
std::map<std::pair<uint256, CKeyID>, | |||||
std::pair<CPubKey, std::vector<uint8_t>>> | |||||
m_descriptor_crypt_keys; | |||||
CWalletScanState() {} | CWalletScanState() {} | ||||
}; | }; | ||||
static bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, | static bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, | ||||
CDataStream &ssValue, CWalletScanState &wss, | CDataStream &ssValue, CWalletScanState &wss, | ||||
std::string &strType, std::string &strErr) | std::string &strType, std::string &strErr) | ||||
EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { | EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { | ||||
▲ Show 20 Lines • Show All 272 Lines • ▼ Show 20 Lines | try { | ||||
} | } | ||||
if (parent) { | if (parent) { | ||||
wss.m_descriptor_caches[desc_id].CacheParentExtPubKey( | wss.m_descriptor_caches[desc_id].CacheParentExtPubKey( | ||||
key_exp_index, xpub); | key_exp_index, xpub); | ||||
} else { | } else { | ||||
wss.m_descriptor_caches[desc_id].CacheDerivedExtPubKey( | wss.m_descriptor_caches[desc_id].CacheDerivedExtPubKey( | ||||
key_exp_index, der_index, xpub); | key_exp_index, der_index, xpub); | ||||
} | } | ||||
} else if (strType == DBKeys::WALLETDESCRIPTORKEY) { | |||||
uint256 desc_id; | |||||
CPubKey pubkey; | |||||
ssKey >> desc_id; | |||||
ssKey >> pubkey; | |||||
if (!pubkey.IsValid()) { | |||||
strErr = "Error reading wallet database: CPubKey corrupt"; | |||||
return false; | |||||
} | |||||
CKey key; | |||||
CPrivKey pkey; | |||||
uint256 hash; | |||||
wss.nKeys++; | |||||
ssValue >> pkey; | |||||
ssValue >> hash; | |||||
// hash pubkey/privkey to accelerate wallet load | |||||
std::vector<uint8_t> to_hash; | |||||
to_hash.reserve(pubkey.size() + pkey.size()); | |||||
to_hash.insert(to_hash.end(), pubkey.begin(), pubkey.end()); | |||||
to_hash.insert(to_hash.end(), pkey.begin(), pkey.end()); | |||||
if (Hash(to_hash.begin(), to_hash.end()) != hash) { | |||||
strErr = | |||||
"Error reading wallet database: CPubKey/CPrivKey corrupt"; | |||||
return false; | |||||
} | |||||
if (!key.Load(pkey, pubkey, true)) { | |||||
strErr = "Error reading wallet database: CPrivKey corrupt"; | |||||
return false; | |||||
} | |||||
wss.m_descriptor_keys.insert( | |||||
std::make_pair(std::make_pair(desc_id, pubkey.GetID()), key)); | |||||
} else if (strType == DBKeys::WALLETDESCRIPTORCKEY) { | |||||
uint256 desc_id; | |||||
CPubKey pubkey; | |||||
ssKey >> desc_id; | |||||
ssKey >> pubkey; | |||||
if (!pubkey.IsValid()) { | |||||
strErr = "Error reading wallet database: CPubKey corrupt"; | |||||
return false; | |||||
} | |||||
std::vector<uint8_t> privkey; | |||||
ssValue >> privkey; | |||||
wss.nCKeys++; | |||||
wss.m_descriptor_crypt_keys.insert( | |||||
std::make_pair(std::make_pair(desc_id, pubkey.GetID()), | |||||
std::make_pair(pubkey, privkey))); | |||||
wss.fIsEncrypted = true; | |||||
} else if (strType != DBKeys::BESTBLOCK && | } else if (strType != DBKeys::BESTBLOCK && | ||||
strType != DBKeys::BESTBLOCK_NOMERKLE && | strType != DBKeys::BESTBLOCK_NOMERKLE && | ||||
strType != DBKeys::MINVERSION && | strType != DBKeys::MINVERSION && | ||||
strType != DBKeys::ACENTRY && strType != DBKeys::VERSION && | strType != DBKeys::ACENTRY && strType != DBKeys::VERSION && | ||||
strType != DBKeys::SETTINGS) { | strType != DBKeys::SETTINGS) { | ||||
wss.m_unknown_records++; | wss.m_unknown_records++; | ||||
} | } | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | DBErrors WalletBatch::LoadWallet(CWallet *pwallet) { | ||||
// Set the descriptor caches | // Set the descriptor caches | ||||
for (auto desc_cache_pair : wss.m_descriptor_caches) { | for (auto desc_cache_pair : wss.m_descriptor_caches) { | ||||
auto spk_man = pwallet->GetScriptPubKeyMan(desc_cache_pair.first); | auto spk_man = pwallet->GetScriptPubKeyMan(desc_cache_pair.first); | ||||
assert(spk_man); | assert(spk_man); | ||||
((DescriptorScriptPubKeyMan *)spk_man) | ((DescriptorScriptPubKeyMan *)spk_man) | ||||
->SetCache(desc_cache_pair.second); | ->SetCache(desc_cache_pair.second); | ||||
} | } | ||||
// Set the descriptor keys | |||||
for (auto desc_key_pair : wss.m_descriptor_keys) { | |||||
auto spk_man = pwallet->GetScriptPubKeyMan(desc_key_pair.first.first); | |||||
((DescriptorScriptPubKeyMan *)spk_man) | |||||
->AddKey(desc_key_pair.first.second, desc_key_pair.second); | |||||
} | |||||
for (auto desc_key_pair : wss.m_descriptor_crypt_keys) { | |||||
auto spk_man = pwallet->GetScriptPubKeyMan(desc_key_pair.first.first); | |||||
((DescriptorScriptPubKeyMan *)spk_man) | |||||
->AddCryptedKey(desc_key_pair.first.second, | |||||
desc_key_pair.second.first, | |||||
desc_key_pair.second.second); | |||||
} | |||||
if (fNoncriticalErrors && result == DBErrors::LOAD_OK) { | if (fNoncriticalErrors && result == DBErrors::LOAD_OK) { | ||||
result = DBErrors::NONCRITICAL_ERROR; | result = DBErrors::NONCRITICAL_ERROR; | ||||
} | } | ||||
// Any wallet corruption at all: skip any rewriting or upgrading, we don't | // Any wallet corruption at all: skip any rewriting or upgrading, we don't | ||||
// want to make it worse. | // want to make it worse. | ||||
if (result != DBErrors::LOAD_OK) { | if (result != DBErrors::LOAD_OK) { | ||||
return result; | return result; | ||||
▲ Show 20 Lines • Show All 299 Lines • Show Last 20 Lines |