Skip to content

fix: drain counter E counts only in-flight bond payouts - #943

Merged
grunch merged 1 commit into
mainfrom
fix/drain-counter-inflight-bond-payouts
Sep 2, 2026
Merged

fix: drain counter E counts only in-flight bond payouts#943
grunch merged 1 commit into
mainfrom
fix/drain-counter-inflight-bond-payouts

Conversation

@grunch

@grunch grunch commented Sep 2, 2026

Copy link
Copy Markdown
Member

Summary

Follow-up to #940 (counter A) with the same reasoning applied to counter E.

A pending-payout bond 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 every pending-payout row blocked drained for up to payout_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_cycle reconciles payout_payment_hash with track_payment_v2 on 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).
  • Docs: §1.3 inventory row E in MAINTENANCE_MODE_LN_MIGRATION.md, counter table in LIGHTNING_OPS.md, comment on pending_bond_payouts in proto/admin.proto (field number and name unchanged, wire-compatible).
  • Test drain_counters_reflects_each_predicate: a pending-payout bond 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

    • Maintenance mode now excludes bond payouts still awaiting the winner’s invoice from node-switching blockers.
    • Pending bond payouts are counted only after payout processing has been dispatched and a payment hash is available.
    • Added coverage to verify that undispatched payouts do not prevent switching nodes.
  • Documentation

    • Updated maintenance-mode guidance and field descriptions to clarify which bond payouts remain tied to the old node.

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
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T12:10:10.836362Z 8dce3ab PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 5315a37a-a6d2-4d4b-bcf3-07122c0d83f1

📥 Commits

Reviewing files that changed from the base of the PR and between d076529 and 8dce3ab.

📒 Files selected for processing (4)
  • docs/LIGHTNING_OPS.md
  • docs/MAINTENANCE_MODE_LN_MIGRATION.md
  • proto/admin.proto
  • src/app/maintenance.rs

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


Walkthrough

The pending bond payout counter now counts only pending-payout bonds with a dispatched payment hash. Documentation, protocol comments, the maintenance query, and tests use this definition.

Changes

Pending bond payout counter

Layer / File(s) Summary
Align counter definition and documentation
docs/MAINTENANCE_MODE_LN_MIGRATION.md, proto/admin.proto, docs/LIGHTNING_OPS.md, src/app/maintenance.rs
The counter definition now requires payout_payment_hash IS NOT NULL. Documentation states that payouts awaiting an invoice are excluded from node-bound counters.
Filter and validate pending payouts
src/app/maintenance.rs
The maintenance query excludes undispatched payouts. Tests verify that these payouts do not prevent counter draining.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 8dce3

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: arkanoider

Poem

A rabbit checks the payout trail,
With hashes stamped on every sail.
Unsent invoices wait aside,
While dispatched bonds remain tied.
The counters drain, neat and bright.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: drain counter E now counts only in-flight bond payouts.
Docstring Coverage ✅ Passed 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 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

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
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/drain-counter-inflight-bond-payouts

Warning

Some tools did not complete. Review the errors below.

🔧 Buf (1.72.0)
proto/admin.proto

fatal: 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
fatal: could not fetch 604d2e2247179bbdfcd71b68e41abf87a5f2a72d from promisor remote


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@grunch
grunch merged commit 468d4c8 into main Sep 2, 2026
11 checks passed
@grunch
grunch deleted the fix/drain-counter-inflight-bond-payouts branch September 2, 2026 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant