fix: refresh lightning activity on retry - #1282
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
jvsena42
left a comment
There was a problem hiding this comment.
Approved — no HIGH/MEDIUM findings at head da30e5580. (Posted as a comment because GitHub does not allow approving your own PR.)
Checked: Traced LightningActivity.withPaymentUpdate (app/src/main/java/to/bitkit/services/CoreService.kt:334-346) and its only caller processBolt11 (CoreService.kt:769-775): the fields now overwritten on an existing row are value, fee and preimage, each guarded with ?: so a null LDK value keeps the stored one; status/updatedAt/contact behave as on master and message/invoice/timestamp/createdAt/seenAt are untouched. Enumerated every writer of Lightning rows at the PR head: LDK sync (this path), setContact/clearContact (copy contact + updatedAt=now, so the pre-existing guard at CoreService.kt:756 skips the next sync), markAsSeen (seenAt only), gift SuccessWithoutLiquidity (id is the funding txid/order id, never a payment hash, so sync cannot match it; the with-liquidity gift path inserts no row and relies on LDK), CJIT insert (funding txid id) and RN migration upserts (ldk-node's payment store is not populated by migrated channel monitors, so no hash overlap). No writer stores an LNURL comment or any value/fee/preimage that LDK's PaymentDetails could degrade. Checked received payments (inbound PENDING skipped; SUCCEEDED carries the claimed amount and preimage, fee null keeps 0), pending->failed (amount unchanged, fee/preimage null keep stored), a retry that fails synchronously (ldk-node records a FAILED row with the new amount, guard passes on newer timestamp, value updated to the new attempt), and zero-amount invoices (outbound amount always set by ldk-node at send; inbound amount set on claim). Rounding is consistent with row creation (amountSats ceil, msatFloorOf fee). ServiceQueue.CORE is a single-thread dispatcher, so the only interleaving is the pre-existing stale-list status regression between a full sync and handlePaymentEvent, which this PR does not worsen and the next sync repairs. The linked issue's retry path (FAILED 300k -> PENDING/SUCCEEDED 22 sats via handlePaymentEvent or full sync) now lands the final attempt's amount, fee and preimage on the same row.
There was a problem hiding this comment.
Verdict: ✅ Approve
Review: diff 3 files.
Findings:
N/A
Audit:
Audited - no findings.
Coverage:
QA: journeys and manual tests await all reviewers to approve, author can run it now via comment: @ovi-reviewer test
Reviewed by claude-opus-5-xhigh via gh-pr-review-loop skill
Commands: @ovi-reviewer test · retest · audit (author or owner)
|
QA reviewed on 8c250db. Retried a failed Lightning send with a smaller amount on the same invoice. The activity row now shows the new amount; the old failed amount is gone. No findings. Checked and clean
QA LGTM |
Fixes #1042
Related to #1275
This PR fixes Lightning activity rows keeping the failed attempt's amount after a retry of the same invoice succeeds.
Description
Out of Scope
Design
N/A — no UI changes.
Preview
N/A. The activity screens do not change. The fix changes which amount is stored, and the repro needs a second node to issue an amountless invoice plus a forced asynchronous route failure, so no recording was made.
QA Notes
Manual Tests
ROUTE_NOT_FOUND) → Activity: row shows Failed with 300,000 sats.regression:Send to an LNURL-pay address with a comment → Activity Detail after it succeeds: the comment is still shown.regression:Receive an LN payment → Activity: amount and status are correct.These steps were not run on a device. The fix is covered by unit tests only, and the call from the activity sync into the new update step was checked by code review.
Automated Checks
CoreServiceTest.kt: a failed 300,000 sat row retried as a succeeded 22 sat payment takes the new amount, fee (1,999 msat rounds down to 1 sat), preimage, status, update time and contact; untouched fields stay the same even when the retry reports a different invoice; a missing fee, amount or preimage keeps the stored value; the stored message survives a description hash and a different description.just test file CoreServiceTestis rejected by an existing guard inapp/build.gradle.kts, so the class was run withjust test file to.bitkit.services.CoreServiceTest.just compile,just testandjust lintpassed.