Repository navigation
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e9ed7c68f2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
[Medium impact] The change reaches a narrow wallet cancellation and on-chain send workflow. The PR appears safe to merge, with a non-blocking gap in tests for the release fallback. Findings
SummaryThis PR lets cancellation use other wallet coins when an expired payment's original coins cannot fund its release.
Diagram%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Original coins] --> B{Preparation succeeds and fee outbids?}
B -->|Yes| G[Return release for approval]
B -->|No| C[Add largest other coin]
C --> D{Preparation succeeds and fee outbids?}
D -->|Yes| G
D -->|No| E[Add all other spendable coins]
E --> F{Preparation succeeds and fee outbids?}
F -->|Yes| G
F -->|No| H[Return error]
Reviews (1) · Last reviewed commit: "fix: add wallet coins to a release the o..." · Reviewed by Greptile |
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
talosmachina
left a comment
There was a problem hiding this comment.
No findings. When the original payment's coins cannot pay the 1,000 sat output plus a fee above every candidate's, prepareRelease now retries with the wallet's largest other coin, then with every other spendable coin. Every set still has to spend each spendable original coin. Reviewed e9ed7c6, full tier (the change builds a transaction).
What I checked, and 5 candidates I ruled out
Read in full: prepareRelease, prepareOnchainSend and callOnchainSend in LightningService.kt; releaseOutbids, releaseInputSets, approveRelease/recordRelease in OnchainSendAttemptStore.kt; the caller abandonUnbroadcastOnchainPayment in PaykitPaymentProofRepo.kt and releaseExpired in SendPendingViewModel.kt; ldk-node v0.7.0-rc.76 prepare_send, validate_signed_inputs, build_transaction_psbt and get_spendable_utxos.
CI: CI / build green on this head, including testDevDebugUnitTest; lint and detekt green; the e2e-tests-local shards were still pending when I posted. Not built here.
Ruled out
- Wallet coins changing which coins the release spends:
utxosToSpendismanually_selected_onlyin ldk-node, andvalidate_signed_inputsrefuses any transaction whose inputs are not exactly the selected set. The newcontainsAll(originalCoins)check is stricter than the oldany. - Replacement rules once the release is larger: the fee rate starts at the highest candidate rate + 2 sat/vB, and
releaseOutbidsstill requires an absolute fee above every candidate's. A larger release therefore clears both the absolute-fee rule and the incremental-relay rule. - A swallowed error hiding a real failure: an error on one set falls through to the next. When every set fails, the last error is thrown, and
releaseExpiredmaps it toMayStillConfirmexactly as before. ThecheckandCancellationExceptionstill propagate (runSuspendCatching). - Fee doubling carrying over between sets:
feeRateresets at the start of each set, so a larger set starts at the lowest fee that can outbid. - An unapproved fee: whichever set wins, its receipt goes through the unchanged
Releasefee dialog and the PIN beforerecordOnchainReleaseand the broadcast.
Merge confidence: 4/5. This path builds a transaction, and no test drives the new fall-through in prepareRelease (only releaseInputSets is unit-tested).
jvsena42
left a comment
There was a problem hiding this comment.
No HIGH or MEDIUM findings. One LOW is inline, with a failing test.
I reviewed this as a funds change: the release now spends wallet coins beyond the payment's own.
Checked and clean:
- No original coin is dropped.
prepareSendToAddresswithutxosToSpendsetsmanually_selected_only,validate_signed_inputsrefuses any other input set, and thecheck(containsAll(originalCoins))atLightningService.kt:1095sits outsiderunSuspendCatching, so a violation refuses the cancel instead of falling through to the next set. releaseOutbidsis unchanged, andcandidateMiningFeessurvives a restore.- BIP125 rules 3 and 4: the rate restarts at the highest candidate rate + 2 for each set, and a larger release only widens the absolute-fee margin. Rule 2 is the LOW.
- The fee dialog still shows the whole cost: the 1,000-sat output and the change both return to the wallet.
originalCoinSpentElsewherelooks only at original coins, so extras cannot fool it.approveRelease→recordOnchainReleasebefore broadcast is unchanged.- Already raised and not repeated: Codex on cumulative subsets and dust, Greptile on a service-level fallback test, detekt on the unused
feeAttempt.
perf: not relevant (up to 3 sets × 4 prepares behind the existing sync wait).
Device gate (partial): e9ed7c6 — not run yet. Pending: piotr's case, a payment of 1,000 sats or less whose broadcast is swallowed and whose request expires, then Cancel, which should release with the original coin plus a confirmed larger coin. My loop for today ends here, so this runs on the next pass. The cancel and refused cases of #1559 passed on device today at f22c596.
Twin: synonymdev/bitkit-ios#998
Refs: #1559
Description
Out of Scope
Design
N/A — no UI changes.
Preview
N/A
QA Notes
Journeys
N/A — not drivable; see Manual Tests.
Manual Tests
Unit:
release adds wallet coins when the original coins fall shortinOnchainSendAttemptStoreTest.