fix: drain counter E counts only in-flight bond payouts - #943
Conversation
A `pending-payout` bond whose payout has not been dispatched is not bound to the Lightning node: its HTLC was settled into Mostro's wallet at slash time and the winner's share can be paid from any node once they send an invoice. Counting it blocked `drained` for up to `payout_claim_window_days` (15) on a production node over a single 416-sat payout whose winner never answered 2166 invoice requests. Only a dispatched payout (`payout_payment_hash` set) is tracked on the node that sent it (`run_bond_payout_cycle` → `track_payment_v2`), so E is now `state = 'pending-payout' AND payout_payment_hash IS NOT NULL` — the bond twin of counter B. Docs, proto comment and the predicate test updated. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PWN1jHfoZxfjusDVB9n3GW
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. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review. WalkthroughThe pending bond payout counter now counts only ChangesPending bond payout counter
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to The change limits drain blocking to bond payouts already dispatched from the node while preserving protection for in-flight payouts. It is localized and merge-ready after normal checks, with no actionable merge-blocking risk remaining. Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files. (3 skipped: 3 unsupported.) ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Some tools did not complete. Review the errors below. 🔧 Buf (1.72.0)proto/admin.protofatal: unable to access 'https://github.com/MostroP2P/mostro.git/': Failed to connect to github.com port 443 via 127.0.0.1 after 0 ms: Could not connect to server Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Follow-up to #940 (counter A) with the same reasoning applied to counter E.
A
pending-payoutbond is a slashed bond: its HTLC was settled into Mostro's wallet at slash time. Until the winner sends a payout invoice nothing has left the node, and once they do the payout can be sent from any node. Counting everypending-payoutrow blockeddrainedfor up topayout_claim_window_days(15 days). A production node was held by a single 416-sat payout whose winner never answered 2166 invoice requests.What is node-bound is a payout already dispatched:
run_bond_payout_cyclereconcilespayout_payment_hashwithtrack_payment_v2on the node that sent it.Change
drain_counters: E =bonds.state = 'pending-payout' AND payout_payment_hash IS NOT NULL— the bond twin of counter B (inflight_payouts).MAINTENANCE_MODE_LN_MIGRATION.md, counter table inLIGHTNING_OPS.md, comment onpending_bond_payoutsinproto/admin.proto(field number and name unchanged, wire-compatible).drain_counters_reflects_each_predicate: apending-payoutbond without a payout hash is not counted; one with a hash still is.Full suite green (1290 passed), clippy clean.
🤖 Generated with Claude Code
https://claude.ai/code/session_01PWN1jHfoZxfjusDVB9n3GW
Summary by CodeRabbit
Bug Fixes
Documentation