|
|
|
|
@@ -478,12 +478,12 @@ struct LoadResult
|
|
|
|
|
int m_records{0};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using LoadFunc = std::function<DBErrors(CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err)>;
|
|
|
|
|
using LoadFunc = std::function<DBErrors(CWallet* pwallet, DataStream& key, DataStream& value, std::string& err)>;
|
|
|
|
|
static LoadResult LoadRecords(CWallet* pwallet, DatabaseBatch& batch, const std::string& key, DataStream& prefix, LoadFunc load_func)
|
|
|
|
|
{
|
|
|
|
|
LoadResult result;
|
|
|
|
|
DataStream ssKey;
|
|
|
|
|
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
|
|
|
|
DataStream ssValue{};
|
|
|
|
|
|
|
|
|
|
Assume(!prefix.empty());
|
|
|
|
|
std::unique_ptr<DatabaseCursor> cursor = batch.GetNewPrefixCursor(prefix);
|
|
|
|
|
@@ -532,7 +532,7 @@ static DBErrors LoadLegacyWalletRecords(CWallet* pwallet, DatabaseBatch& batch,
|
|
|
|
|
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
|
|
|
|
|
for (const auto& type : DBKeys::LEGACY_TYPES) {
|
|
|
|
|
DataStream key;
|
|
|
|
|
CDataStream value(SER_DISK, CLIENT_VERSION);
|
|
|
|
|
DataStream value{};
|
|
|
|
|
|
|
|
|
|
DataStream prefix;
|
|
|
|
|
prefix << type;
|
|
|
|
|
@@ -555,28 +555,28 @@ static DBErrors LoadLegacyWalletRecords(CWallet* pwallet, DatabaseBatch& batch,
|
|
|
|
|
// Load HD Chain
|
|
|
|
|
// Note: There should only be one HDCHAIN record with no data following the type
|
|
|
|
|
LoadResult hd_chain_res = LoadRecords(pwallet, batch, DBKeys::HDCHAIN,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
return LoadHDChain(pwallet, value, err) ? DBErrors:: LOAD_OK : DBErrors::CORRUPT;
|
|
|
|
|
});
|
|
|
|
|
result = std::max(result, hd_chain_res.m_result);
|
|
|
|
|
|
|
|
|
|
// Load unencrypted keys
|
|
|
|
|
LoadResult key_res = LoadRecords(pwallet, batch, DBKeys::KEY,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
return LoadKey(pwallet, key, value, err) ? DBErrors::LOAD_OK : DBErrors::CORRUPT;
|
|
|
|
|
});
|
|
|
|
|
result = std::max(result, key_res.m_result);
|
|
|
|
|
|
|
|
|
|
// Load encrypted keys
|
|
|
|
|
LoadResult ckey_res = LoadRecords(pwallet, batch, DBKeys::CRYPTED_KEY,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
return LoadCryptedKey(pwallet, key, value, err) ? DBErrors::LOAD_OK : DBErrors::CORRUPT;
|
|
|
|
|
});
|
|
|
|
|
result = std::max(result, ckey_res.m_result);
|
|
|
|
|
|
|
|
|
|
// Load scripts
|
|
|
|
|
LoadResult script_res = LoadRecords(pwallet, batch, DBKeys::CSCRIPT,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& strErr) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& strErr) {
|
|
|
|
|
uint160 hash;
|
|
|
|
|
key >> hash;
|
|
|
|
|
CScript script;
|
|
|
|
|
@@ -599,7 +599,7 @@ static DBErrors LoadLegacyWalletRecords(CWallet* pwallet, DatabaseBatch& batch,
|
|
|
|
|
// Load keymeta
|
|
|
|
|
std::map<uint160, CHDChain> hd_chains;
|
|
|
|
|
LoadResult keymeta_res = LoadRecords(pwallet, batch, DBKeys::KEYMETA,
|
|
|
|
|
[&hd_chains] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& strErr) {
|
|
|
|
|
[&hd_chains] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& strErr) {
|
|
|
|
|
CPubKey vchPubKey;
|
|
|
|
|
key >> vchPubKey;
|
|
|
|
|
CKeyMetadata keyMeta;
|
|
|
|
|
@@ -686,7 +686,7 @@ static DBErrors LoadLegacyWalletRecords(CWallet* pwallet, DatabaseBatch& batch,
|
|
|
|
|
|
|
|
|
|
// Load watchonly scripts
|
|
|
|
|
LoadResult watch_script_res = LoadRecords(pwallet, batch, DBKeys::WATCHS,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
CScript script;
|
|
|
|
|
key >> script;
|
|
|
|
|
uint8_t fYes;
|
|
|
|
|
@@ -700,7 +700,7 @@ static DBErrors LoadLegacyWalletRecords(CWallet* pwallet, DatabaseBatch& batch,
|
|
|
|
|
|
|
|
|
|
// Load watchonly meta
|
|
|
|
|
LoadResult watch_meta_res = LoadRecords(pwallet, batch, DBKeys::WATCHMETA,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
CScript script;
|
|
|
|
|
key >> script;
|
|
|
|
|
CKeyMetadata keyMeta;
|
|
|
|
|
@@ -712,7 +712,7 @@ static DBErrors LoadLegacyWalletRecords(CWallet* pwallet, DatabaseBatch& batch,
|
|
|
|
|
|
|
|
|
|
// Load keypool
|
|
|
|
|
LoadResult pool_res = LoadRecords(pwallet, batch, DBKeys::POOL,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
int64_t nIndex;
|
|
|
|
|
key >> nIndex;
|
|
|
|
|
CKeyPool keypool;
|
|
|
|
|
@@ -729,7 +729,7 @@ static DBErrors LoadLegacyWalletRecords(CWallet* pwallet, DatabaseBatch& batch,
|
|
|
|
|
// we want to make sure that it is valid so that we can detect corruption
|
|
|
|
|
// Note: There should only be one DEFAULTKEY with nothing trailing the type
|
|
|
|
|
LoadResult default_key_res = LoadRecords(pwallet, batch, DBKeys::DEFAULTKEY,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
CPubKey default_pubkey;
|
|
|
|
|
try {
|
|
|
|
|
value >> default_pubkey;
|
|
|
|
|
@@ -747,7 +747,7 @@ static DBErrors LoadLegacyWalletRecords(CWallet* pwallet, DatabaseBatch& batch,
|
|
|
|
|
|
|
|
|
|
// "wkey" records are unsupported, if we see any, throw an error
|
|
|
|
|
LoadResult wkey_res = LoadRecords(pwallet, batch, DBKeys::OLD_KEY,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
err = "Found unsupported 'wkey' record, try loading with version 0.18";
|
|
|
|
|
return DBErrors::LOAD_FAIL;
|
|
|
|
|
});
|
|
|
|
|
@@ -787,7 +787,7 @@ static DBErrors LoadDescriptorWalletRecords(CWallet* pwallet, DatabaseBatch& bat
|
|
|
|
|
int num_keys = 0;
|
|
|
|
|
int num_ckeys= 0;
|
|
|
|
|
LoadResult desc_res = LoadRecords(pwallet, batch, DBKeys::WALLETDESCRIPTOR,
|
|
|
|
|
[&batch, &num_keys, &num_ckeys, &last_client] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& strErr) {
|
|
|
|
|
[&batch, &num_keys, &num_ckeys, &last_client] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& strErr) {
|
|
|
|
|
DBErrors result = DBErrors::LOAD_OK;
|
|
|
|
|
|
|
|
|
|
uint256 id;
|
|
|
|
|
@@ -817,7 +817,7 @@ static DBErrors LoadDescriptorWalletRecords(CWallet* pwallet, DatabaseBatch& bat
|
|
|
|
|
// Get key cache for this descriptor
|
|
|
|
|
DataStream prefix = PrefixStream(DBKeys::WALLETDESCRIPTORCACHE, id);
|
|
|
|
|
LoadResult key_cache_res = LoadRecords(pwallet, batch, DBKeys::WALLETDESCRIPTORCACHE, prefix,
|
|
|
|
|
[&id, &cache] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[&id, &cache] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
bool parent = true;
|
|
|
|
|
uint256 desc_id;
|
|
|
|
|
uint32_t key_exp_index;
|
|
|
|
|
@@ -850,7 +850,7 @@ static DBErrors LoadDescriptorWalletRecords(CWallet* pwallet, DatabaseBatch& bat
|
|
|
|
|
// Get last hardened cache for this descriptor
|
|
|
|
|
prefix = PrefixStream(DBKeys::WALLETDESCRIPTORLHCACHE, id);
|
|
|
|
|
LoadResult lh_cache_res = LoadRecords(pwallet, batch, DBKeys::WALLETDESCRIPTORLHCACHE, prefix,
|
|
|
|
|
[&id, &cache] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[&id, &cache] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
uint256 desc_id;
|
|
|
|
|
uint32_t key_exp_index;
|
|
|
|
|
key >> desc_id;
|
|
|
|
|
@@ -874,7 +874,7 @@ static DBErrors LoadDescriptorWalletRecords(CWallet* pwallet, DatabaseBatch& bat
|
|
|
|
|
// Get unencrypted keys
|
|
|
|
|
prefix = PrefixStream(DBKeys::WALLETDESCRIPTORKEY, id);
|
|
|
|
|
LoadResult key_res = LoadRecords(pwallet, batch, DBKeys::WALLETDESCRIPTORKEY, prefix,
|
|
|
|
|
[&id, &spk_man] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& strErr) {
|
|
|
|
|
[&id, &spk_man] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& strErr) {
|
|
|
|
|
uint256 desc_id;
|
|
|
|
|
CPubKey pubkey;
|
|
|
|
|
key >> desc_id;
|
|
|
|
|
@@ -918,7 +918,7 @@ static DBErrors LoadDescriptorWalletRecords(CWallet* pwallet, DatabaseBatch& bat
|
|
|
|
|
// Get encrypted keys
|
|
|
|
|
prefix = PrefixStream(DBKeys::WALLETDESCRIPTORCKEY, id);
|
|
|
|
|
LoadResult ckey_res = LoadRecords(pwallet, batch, DBKeys::WALLETDESCRIPTORCKEY, prefix,
|
|
|
|
|
[&id, &spk_man] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[&id, &spk_man] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
uint256 desc_id;
|
|
|
|
|
CPubKey pubkey;
|
|
|
|
|
key >> desc_id;
|
|
|
|
|
@@ -957,7 +957,7 @@ static DBErrors LoadAddressBookRecords(CWallet* pwallet, DatabaseBatch& batch) E
|
|
|
|
|
|
|
|
|
|
// Load name record
|
|
|
|
|
LoadResult name_res = LoadRecords(pwallet, batch, DBKeys::NAME,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
std::string strAddress;
|
|
|
|
|
key >> strAddress;
|
|
|
|
|
std::string label;
|
|
|
|
|
@@ -969,7 +969,7 @@ static DBErrors LoadAddressBookRecords(CWallet* pwallet, DatabaseBatch& batch) E
|
|
|
|
|
|
|
|
|
|
// Load purpose record
|
|
|
|
|
LoadResult purpose_res = LoadRecords(pwallet, batch, DBKeys::PURPOSE,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
std::string strAddress;
|
|
|
|
|
key >> strAddress;
|
|
|
|
|
std::string purpose_str;
|
|
|
|
|
@@ -985,7 +985,7 @@ static DBErrors LoadAddressBookRecords(CWallet* pwallet, DatabaseBatch& batch) E
|
|
|
|
|
|
|
|
|
|
// Load destination data record
|
|
|
|
|
LoadResult dest_res = LoadRecords(pwallet, batch, DBKeys::DESTDATA,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
std::string strAddress, strKey, strValue;
|
|
|
|
|
key >> strAddress;
|
|
|
|
|
key >> strKey;
|
|
|
|
|
@@ -1019,7 +1019,7 @@ static DBErrors LoadTxRecords(CWallet* pwallet, DatabaseBatch& batch, std::vecto
|
|
|
|
|
// Load tx record
|
|
|
|
|
any_unordered = false;
|
|
|
|
|
LoadResult tx_res = LoadRecords(pwallet, batch, DBKeys::TX,
|
|
|
|
|
[&any_unordered, &upgraded_txs] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
[&any_unordered, &upgraded_txs] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
DBErrors result = DBErrors::LOAD_OK;
|
|
|
|
|
uint256 hash;
|
|
|
|
|
key >> hash;
|
|
|
|
|
@@ -1072,7 +1072,7 @@ static DBErrors LoadTxRecords(CWallet* pwallet, DatabaseBatch& batch, std::vecto
|
|
|
|
|
|
|
|
|
|
// Load locked utxo record
|
|
|
|
|
LoadResult locked_utxo_res = LoadRecords(pwallet, batch, DBKeys::LOCKED_UTXO,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
Txid hash;
|
|
|
|
|
uint32_t n;
|
|
|
|
|
key >> hash;
|
|
|
|
|
@@ -1085,7 +1085,7 @@ static DBErrors LoadTxRecords(CWallet* pwallet, DatabaseBatch& batch, std::vecto
|
|
|
|
|
// Load orderposnext record
|
|
|
|
|
// Note: There should only be one ORDERPOSNEXT record with nothing trailing the type
|
|
|
|
|
LoadResult order_pos_res = LoadRecords(pwallet, batch, DBKeys::ORDERPOSNEXT,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {
|
|
|
|
|
try {
|
|
|
|
|
value >> pwallet->nOrderPosNext;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
@@ -1108,7 +1108,7 @@ static DBErrors LoadActiveSPKMs(CWallet* pwallet, DatabaseBatch& batch) EXCLUSIV
|
|
|
|
|
std::set<std::pair<OutputType, bool>> seen_spks;
|
|
|
|
|
for (const auto& spk_key : {DBKeys::ACTIVEEXTERNALSPK, DBKeys::ACTIVEINTERNALSPK}) {
|
|
|
|
|
LoadResult spkm_res = LoadRecords(pwallet, batch, spk_key,
|
|
|
|
|
[&seen_spks, &spk_key] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& strErr) {
|
|
|
|
|
[&seen_spks, &spk_key] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& strErr) {
|
|
|
|
|
uint8_t output_type;
|
|
|
|
|
key >> output_type;
|
|
|
|
|
uint256 id;
|
|
|
|
|
@@ -1134,7 +1134,7 @@ static DBErrors LoadDecryptionKeys(CWallet* pwallet, DatabaseBatch& batch) EXCLU
|
|
|
|
|
|
|
|
|
|
// Load decryption key (mkey) records
|
|
|
|
|
LoadResult mkey_res = LoadRecords(pwallet, batch, DBKeys::MASTER_KEY,
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
|
|
|
|
|
[] (CWallet* pwallet, DataStream& key, DataStream& value, std::string& err) {
|
|
|
|
|
if (!LoadEncryptionKey(pwallet, key, value, err)) {
|
|
|
|
|
return DBErrors::CORRUPT;
|
|
|
|
|
}
|
|
|
|
|
|