walletdb: fix SQLite cursor scan dropping accounting entries

ListAccountCreditDebit kept the Berkeley-era early-break on the first
non-acentry record. The BDB cursor was sorted and pre-seeked to the
(acentry, account) prefix via DB_SET_RANGE, so breaking was correct there.
The SQLite cursor (SELECT key, value FROM main) scans the whole keyspace
in unspecified order, so the loop usually hit the version record first
and returned zero entries: every wallet silently lost its accounting
history in the UI. Skip non-matching records instead of breaking.

Fixes all 27 accounting_tests/acc_orderupgrade failures.
This commit is contained in:
Krystie
2026-07-04 14:18:58 -07:00
parent 8d4d17e7a8
commit c2e05e1305
+7 -5
View File
@@ -168,17 +168,19 @@ void CWalletDB::ListAccountCreditDebit(const std::string& strAccount, std::list<
break;
}
// Unserialize. We mirror the Berkeley read: stop at the first non-acentry
// record (which is the next record type in key order — Berkeley's
// DB_SET_RANGE/DB_NEXT loop also terminated when the prefix changed).
// Unserialize. Unlike the Berkeley cursor -- which iterated in sorted
// key order and was positioned at the ("acentry", strAccount) prefix
// via DB_SET_RANGE, so it could stop at the first non-matching record --
// the SQLite cursor scans the whole keyspace in unspecified order.
// We must therefore skip non-matching records and keep scanning.
std::string strType;
ssKey >> strType;
if (strType != "acentry")
break;
continue;
CAccountingEntry acentry;
ssKey >> acentry.strAccount;
if (!fAllAccounts && acentry.strAccount != strAccount)
break;
continue;
ssValue >> acentry;
ssKey >> acentry.nEntryNo;