fix(history): keep shielded txs in date order (they were stuck at the top)
History looked unsorted because every merged "shield" row carried confirmations=0, and the list sorts 0-conf (pending) transactions to the very top. So long-confirmed shielding transactions floated above newer ones — and when the type filter was switched off "All" they vanished (shield rows only match the "Sent" filter), which read as "transactions disappear when sorting". Root cause: the autoshield merge set the row's confirmations to min(send, recv). Both legs are the SAME transaction (one real confirmation count), but the send leg (parsed from z_viewtransaction) routinely arrives with confirmations=0, so min() picked 0. Use max() to take the populated value. Also give the sort a txid tiebreak so same-block transactions keep a stable order instead of reshuffling every time a new block bumps confirmations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -425,7 +425,12 @@ void RenderTransactionsTab(App* app)
|
||||
dtx.is_shield = true;
|
||||
dtx.amount = rtx.amount; // positive receive amount
|
||||
dtx.timestamp = std::max(stx.timestamp, rtx.timestamp);
|
||||
dtx.confirmations = std::min(stx.confirmations, rtx.confirmations);
|
||||
// Both legs are the SAME transaction, so they share one real confirmation
|
||||
// count — but the send leg (from z_viewtransaction) often comes through
|
||||
// with confirmations=0. min() would then make a long-confirmed shield look
|
||||
// pending (conf==0), which the sort floats to the very top, out of date
|
||||
// order. Take the populated value.
|
||||
dtx.confirmations = std::max(stx.confirmations, rtx.confirmations);
|
||||
dtx.address = rtx.address; // shielded destination
|
||||
dtx.from_address = stx.address.empty() ? stx.from_address : stx.address;
|
||||
dtx.memo = rtx.memo.empty() ? stx.memo : rtx.memo;
|
||||
@@ -456,13 +461,16 @@ void RenderTransactionsTab(App* app)
|
||||
}
|
||||
}
|
||||
|
||||
// Sort: pending (0-conf) transactions first, then by timestamp descending
|
||||
// Sort: pending (0-conf) transactions first, then newest-first by timestamp, with txid as
|
||||
// a final deterministic tiebreak so same-block transactions keep a stable order across
|
||||
// rebuilds (otherwise equal timestamps reorder every time a new block bumps confirmations).
|
||||
std::sort(display_txns.begin(), display_txns.end(),
|
||||
[](const DisplayTx& a, const DisplayTx& b) {
|
||||
bool aPending = (a.confirmations == 0);
|
||||
bool bPending = (b.confirmations == 0);
|
||||
if (aPending != bPending) return aPending;
|
||||
return a.timestamp > b.timestamp;
|
||||
if (a.timestamp != b.timestamp) return a.timestamp > b.timestamp;
|
||||
return a.txid > b.txid;
|
||||
});
|
||||
|
||||
s_display_cache_key = displayKey;
|
||||
|
||||
Reference in New Issue
Block a user