Skip to content

circular: add circular rebalancing plugin with bLIP-18 support - #932

Merged
daywalker90 merged 1 commit into
lightningd:masterfrom
btweenthebars:add-circular
Aug 28, 2026
Merged

circular: add circular rebalancing plugin with bLIP-18 support#932
daywalker90 merged 1 commit into
lightningd:masterfrom
btweenthebars:add-circular

Conversation

@btweenthebars

Copy link
Copy Markdown

Summary

This PR adds circular, a high-performance Core Lightning plugin written in Go for routing nodes to rebalance channels efficiently and cost-effectively.

Key Features:

  • bLIP-18 Inbound Fee Aware: Dynamically parses gossip TLV type 55555 for inbound fees, computing exact net fees (max(0, outbound + inbound)) via edge-keyed backwards Dijkstra to discover routes with negative fee discounts.
  • Failure-Informed Pathfinding: Automatically excludes failing channels across retry attempts so the pathfinder avoids recurring bottlenecks.
  • Parallel Multi-Channel Rebalancing: Simultaneously pull into or push out of target channels across multiple peers (circular-pull and circular-push) with fee-aware candidate selection.
  • In-Flight Payment Tracking: Real-time visibility into active parallel rebalancing operations via circular-active.
  • Cryptographically Secure & Concurrency Hardened: Uses crypto/rand for preimage generation, atomic state flags, non-blocking channels, and panic-resilient background routines.

Repository: https://github.com/btweenthebars/CLN-circular

@daywalker90

Copy link
Copy Markdown
Collaborator

You can ignore the failing circular-reckless test, but the normal circular test is also failing. You can check the logs here. Apparently circular exits because there is no gossip/channels ?

Btw. we will replace reckless probably in v26.12 and people using that plugin manager to install your plugin will have to call it "CLN-circular" as that is your repos name.

@btweenthebars

Copy link
Copy Markdown
Author

Thanks for the pointer @daywalker90!

The root cause was in glightning.ListChannels(): when there are 0 channels in gossip (as on a clean regtest test node), glightning returns "No channel found for short channel id ", which was previously treated as a fatal startup error by Init.

Fixed in the latest commit:

  1. Handled "No channel found" as an empty channel slice rather than an error.
  2. Made initial refreshGraph and refreshPeers in Init() non-fatal so the plugin starts and registers cleanly even before gossip has arrived.
  3. Enhanced the integration test in tests/test_circular.py to verify circular-stats RPC execution.

Submodule pointer updated to 2d2d1a6.

@daywalker90

Copy link
Copy Markdown
Collaborator

I fixed up the README and Reckless markdown files (alphabetical ordering and badge links) and squashed the commmits.

@daywalker90
daywalker90 merged commit ca2bfe9 into lightningd:master Aug 28, 2026
1 of 7 checks passed
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.

2 participants