Takes up #19793
Rather than asserting, we log an error and return CORRUPT so that the user is informed. This type of error isn’t critical so it isn’t worth assert
ing.
Takes up #19793
Rather than asserting, we log an error and return CORRUPT so that the user is informed. This type of error isn’t critical so it isn’t worth assert
ing.
310@@ -311,6 +311,7 @@ class CWalletScanState {
311 std::map<std::pair<uint256, CKeyID>, CKey> m_descriptor_keys;
312 std::map<std::pair<uint256, CKeyID>, std::pair<CPubKey, std::vector<unsigned char>>> m_descriptor_crypt_keys;
313 std::map<uint160, CHDChain> m_hd_chains;
314+ bool tx_corrupt;
0 bool tx_corrupt{false};
To avoid potential use of uninitialized memory when the logic reading/writing tx_corrupt
is changed over time.
Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
Co-authored-by: Andrew Chow <achow101-github@achow101.com>
345@@ -345,7 +346,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
346 // LoadToWallet call below creates a new CWalletTx that fill_wtx
347 // callback fills with transaction metadata.
348 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
349- assert(new_tx);
350+ if(!new_tx) {
0 if (!new_tx) {
345@@ -345,7 +346,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
346 // LoadToWallet call below creates a new CWalletTx that fill_wtx
347 // callback fills with transaction metadata.
348 auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
349- assert(new_tx);
350+ if(!new_tx) {
351+ // There's some corruption here since the tx we just tried to load was already in the wallet.
352+ // We don't consider this type of corruption critical, and can fix it by removing tx data and
353+ // rescanning.
Probably I am missing context here, so feel free to ignore my question.
Why would we consider “the tx we just tried to load was already in the wallet.” as a corrupted transaction? If I am missing context here, would it be helpful to clarify this in the above comment?
Why would we consider “the tx we just tried to load was already in the wallet.” as a corrupted transaction? If I am missing context here, would it be helpful to clarify this in the above comment?
It might not be bad to update the comment above or the error message below or the tx_corrupt
variable name if you have suggestions, but this all seems ok to me. If there are multiple transactions with the same hash, the wallet is corrupt, and the transactions are maybe corrupt. In this case it is probably better to not load the wallet than to load it and make new writes, and to return a loading error instead of asserting false.
Hmm. The context I was missing then would be: !new
suggests that the wallet already loaded the transaction with the given hash.
So maybe the comment above could read something like “There’s some corruption here since the wallet already knows about a transaction with the same Txid”? That would clarify why this case is an error a little clearly.
Very much agree with this change, assert is not an error-handling mechanism.
Code review ACK 0ab4c3b27265401c59e40adc494041927dc9dbe3
Would be good to have a test for this, by the way.
Oh I see jonatack brought this up too:
A test might be good.
Do we need a “needs test” label :smile: