Skip to content

Commit 31c033e

Browse files
committed
walletdb: refactor defaultkey and wkey loading
Instead of dealing with these records when iterating the entire database, find and handle them explicitly. Loading of OLD_KEY records is bumped up to a LOAD_FAIL error as we will not be able to use these types of keys which can lead to users missing funds.
1 parent c978c6d commit 31c033e

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

src/wallet/walletdb.cpp

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -476,22 +476,12 @@ ReadKeyValue(CWallet* pwallet, DataStream& ssKey, CDataStream& ssValue,
476476
} else if (strType == DBKeys::KEYMETA) {
477477
} else if (strType == DBKeys::WATCHMETA) {
478478
} else if (strType == DBKeys::DEFAULTKEY) {
479-
// We don't want or need the default key, but if there is one set,
480-
// we want to make sure that it is valid so that we can detect corruption
481-
CPubKey vchPubKey;
482-
ssValue >> vchPubKey;
483-
if (!vchPubKey.IsValid()) {
484-
strErr = "Error reading wallet database: Default Key corrupt";
485-
return false;
486-
}
487479
} else if (strType == DBKeys::POOL) {
488480
} else if (strType == DBKeys::CSCRIPT) {
489481
} else if (strType == DBKeys::ORDERPOSNEXT) {
490482
} else if (strType == DBKeys::DESTDATA) {
491483
} else if (strType == DBKeys::HDCHAIN) {
492484
} else if (strType == DBKeys::OLD_KEY) {
493-
strErr = "Found unsupported 'wkey' record, try loading with version 0.18";
494-
return false;
495485
} else if (strType == DBKeys::ACTIVEEXTERNALSPK || strType == DBKeys::ACTIVEINTERNALSPK) {
496486
} else if (strType == DBKeys::WALLETDESCRIPTOR) {
497487
} else if (strType == DBKeys::WALLETDESCRIPTORCACHE) {
@@ -794,6 +784,37 @@ static DBErrors LoadLegacyWalletRecords(CWallet* pwallet, DatabaseBatch& batch,
794784
});
795785
result = std::max(result, pool_res.m_result);
796786

787+
// Deal with old "wkey" and "defaultkey" records.
788+
// These are not actually loaded, but we need to check for them
789+
790+
// We don't want or need the default key, but if there is one set,
791+
// we want to make sure that it is valid so that we can detect corruption
792+
// Note: There should only be one DEFAULTKEY with nothing trailing the type
793+
LoadResult default_key_res = LoadRecords(pwallet, batch, DBKeys::DEFAULTKEY,
794+
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
795+
CPubKey default_pubkey;
796+
try {
797+
value >> default_pubkey;
798+
} catch (const std::exception& e) {
799+
err = e.what();
800+
return DBErrors::CORRUPT;
801+
}
802+
if (!default_pubkey.IsValid()) {
803+
err = "Error reading wallet database: Default Key corrupt";
804+
return DBErrors::CORRUPT;
805+
}
806+
return DBErrors::LOAD_OK;
807+
});
808+
result = std::max(result, default_key_res.m_result);
809+
810+
// "wkey" records are unsupported, if we see any, throw an error
811+
LoadResult wkey_res = LoadRecords(pwallet, batch, DBKeys::OLD_KEY,
812+
[] (CWallet* pwallet, DataStream& key, CDataStream& value, std::string& err) {
813+
err = "Found unsupported 'wkey' record, try loading with version 0.18";
814+
return DBErrors::LOAD_FAIL;
815+
});
816+
result = std::max(result, wkey_res.m_result);
817+
797818
if (result <= DBErrors::NONCRITICAL_ERROR) {
798819
// Only do logging and time first key update if there were no critical errors
799820
pwallet->WalletLogPrintf("Legacy Wallet Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total.\n",
@@ -1237,8 +1258,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
12371258
{
12381259
// losing keys is considered a catastrophic error, anything else
12391260
// we assume the user can live with:
1240-
if (strType == DBKeys::MASTER_KEY ||
1241-
strType == DBKeys::DEFAULTKEY) {
1261+
if (strType == DBKeys::MASTER_KEY) {
12421262
result = DBErrors::CORRUPT;
12431263
} else {
12441264
// Leave other errors alone, if we try to fix them we might make things worse.

0 commit comments

Comments
 (0)