Skip to content

Commit c978c6d

Browse files
committed
walletdb: refactor active spkm loading
Instead of loading active spkm records as we come across them when iterating the database, load them explicitly. Due to exception handling changes, deserialization errors are now treated as critical.
1 parent 6fabb7f commit c978c6d

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed

src/wallet/walletdb.cpp

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,6 @@ bool WalletBatch::EraseLockedUTXO(const COutPoint& output)
301301
class CWalletScanState {
302302
public:
303303
unsigned int m_unknown_records{0};
304-
std::map<OutputType, uint256> m_active_external_spks;
305-
std::map<OutputType, uint256> m_active_internal_spks;
306304

307305
CWalletScanState() = default;
308306
};
@@ -495,18 +493,6 @@ ReadKeyValue(CWallet* pwallet, DataStream& ssKey, CDataStream& ssValue,
495493
strErr = "Found unsupported 'wkey' record, try loading with version 0.18";
496494
return false;
497495
} else if (strType == DBKeys::ACTIVEEXTERNALSPK || strType == DBKeys::ACTIVEINTERNALSPK) {
498-
uint8_t type;
499-
ssKey >> type;
500-
uint256 id;
501-
ssValue >> id;
502-
503-
bool internal = strType == DBKeys::ACTIVEINTERNALSPK;
504-
auto& spk_mans = internal ? wss.m_active_internal_spks : wss.m_active_external_spks;
505-
if (spk_mans.count(static_cast<OutputType>(type)) > 0) {
506-
strErr = "Multiple ScriptPubKeyMans specified for a single type";
507-
return false;
508-
}
509-
spk_mans[static_cast<OutputType>(type)] = id;
510496
} else if (strType == DBKeys::WALLETDESCRIPTOR) {
511497
} else if (strType == DBKeys::WALLETDESCRIPTORCACHE) {
512498
} else if (strType == DBKeys::WALLETDESCRIPTORLHCACHE) {
@@ -1146,6 +1132,35 @@ static DBErrors LoadTxRecords(CWallet* pwallet, DatabaseBatch& batch, std::vecto
11461132
return result;
11471133
}
11481134

1135+
static DBErrors LoadActiveSPKMs(CWallet* pwallet, DatabaseBatch& batch) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
1136+
{
1137+
AssertLockHeld(pwallet->cs_wallet);
1138+
DBErrors result = DBErrors::LOAD_OK;
1139+
1140+
// Load spk records
1141+
std::set<std::pair<OutputType, bool>> seen_spks;
1142+
for (const auto& spk_key : {DBKeys::ACTIVEEXTERNALSPK, DBKeys::ACTIVEINTERNALSPK}) {
1143+
LoadResult spkm_res = LoadRecords(pwallet, batch, spk_key,
1144+
[&seen_spks, &spk_key] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& strErr) {
1145+
uint8_t output_type;
1146+
key >> output_type;
1147+
uint256 id;
1148+
value >> id;
1149+
1150+
bool internal = spk_key == DBKeys::ACTIVEINTERNALSPK;
1151+
auto [it, insert] = seen_spks.emplace(static_cast<OutputType>(output_type), internal);
1152+
if (!insert) {
1153+
strErr = "Multiple ScriptpubKeyMans specified for a single type";
1154+
return DBErrors::CORRUPT;
1155+
}
1156+
pwallet->LoadActiveScriptPubKeyMan(id, static_cast<OutputType>(output_type), /*internal=*/internal);
1157+
return DBErrors::LOAD_OK;
1158+
});
1159+
result = std::max(result, spkm_res.m_result);
1160+
}
1161+
return result;
1162+
}
1163+
11491164
DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
11501165
{
11511166
CWalletScanState wss;
@@ -1191,6 +1206,9 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
11911206
// Load tx records
11921207
result = std::max(LoadTxRecords(pwallet, *m_batch, upgraded_txs, any_unordered), result);
11931208

1209+
// Load SPKMs
1210+
result = std::max(LoadActiveSPKMs(pwallet, *m_batch), result);
1211+
11941212
// Get cursor
11951213
std::unique_ptr<DatabaseCursor> cursor = m_batch->GetNewCursor();
11961214
if (!cursor)
@@ -1236,14 +1254,6 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
12361254
result = DBErrors::CORRUPT;
12371255
}
12381256

1239-
// Set the active ScriptPubKeyMans
1240-
for (auto spk_man_pair : wss.m_active_external_spks) {
1241-
pwallet->LoadActiveScriptPubKeyMan(spk_man_pair.second, spk_man_pair.first, /*internal=*/false);
1242-
}
1243-
for (auto spk_man_pair : wss.m_active_internal_spks) {
1244-
pwallet->LoadActiveScriptPubKeyMan(spk_man_pair.second, spk_man_pair.first, /*internal=*/true);
1245-
}
1246-
12471257
if (fNoncriticalErrors && result == DBErrors::LOAD_OK) {
12481258
result = DBErrors::NONCRITICAL_ERROR;
12491259
}

0 commit comments

Comments
 (0)