Code review:

- invalidate zaps flow when removeAllChildNotes clears onchainZaps
- simplify on-chain zap gallery after review
This commit is contained in:
davotoula
2026-05-19 12:58:22 +02:00
parent 91ded74636
commit cf44c092dd
3 changed files with 41 additions and 75 deletions
@@ -310,7 +310,7 @@ open class Note(
fun removeAllChildNotes(): List<Note> {
val repliesChanged = replies.isNotEmpty()
val reactionsChanged = reactions.isNotEmpty()
val zapsChanged = zaps.isNotEmpty() || zapPayments.isNotEmpty()
val zapsChanged = zaps.isNotEmpty() || zapPayments.isNotEmpty() || onchainZaps.isNotEmpty()
val boostsChanged = boosts.isNotEmpty()
val reportsChanged = reports.isNotEmpty()
@@ -435,15 +435,14 @@ open class Note(
entry: OnchainZapEntry,
): Boolean {
val existing = onchainZaps[txid]
if (existing == null) {
onchainZaps = onchainZaps + Pair(txid, entry)
return true
if (existing != null) {
// Same-state duplicate: keep the first source and amount we got.
if (existing.confirmed == entry.confirmed) return false
// Downgrade confirmed → pending: never accept. States differ here,
// so existing.confirmed alone is sufficient to identify the downgrade.
if (existing.confirmed) return false
// Else: existing pending + incoming confirmed — fall through to upgrade.
}
// Same-state duplicate: keep the first source and amount we got.
if (existing.confirmed == entry.confirmed) return false
// Downgrade confirmed → pending: never accept.
if (existing.confirmed && !entry.confirmed) return false
// Upgrade pending → confirmed: replace, so the upgrading event's source wins.
onchainZaps = onchainZaps + Pair(txid, entry)
return true
}
@@ -94,9 +94,13 @@ class NoteOnchainZapTest {
val secondSrc = sourceNote("2".repeat(64))
target.addOnchainZap(firstSrc, "tx1", 100L, confirmed = true)
target.addOnchainZap(secondSrc, "tx1", 100L, confirmed = true)
// Mismatched verifiedSats so we can detect a regression that silently
// overwrites the first entry with the second.
target.addOnchainZap(secondSrc, "tx1", 999L, confirmed = true)
assertSame(firstSrc, target.onchainZaps["tx1"]?.source)
val entry = target.onchainZaps["tx1"]
assertSame(firstSrc, entry?.source)
assertEquals(100L, entry?.verifiedSats)
assertEquals(BigDecimal.valueOf(100L), target.zapsAmount)
}