Skip to content

feat(loop): add multi-channel outgoing support for Loop Out - #54

Merged
TrezorHannes merged 6 commits into
mainfrom
feat/loop-out-multi-channel
Sep 21, 2026
Merged

TrezorHannes merged 6 commits into
mainfrom
feat/loop-out-multi-channel

Conversation

@TrezorHannes

@TrezorHannes TrezorHannes commented Sep 21, 2026 •

Copy link
Copy Markdown
Owner

Summary of Changes

  • Multi-Channel Outgoing Route Selection (--channel <id1>,<id2>...):
    • Leverages Loop daemon's native outgoing_chan_set support, allowing node operators to activate multiple outgoing channel candidates for a Loop Out swap.
    • Enables LND to utilize Multi-Path Payments (MPP) or alternative routing paths across the selected peers.
    • Prevents single-channel bottlenecks, avoiding stranded prepayments if a single peer experiences churn or mass channel closures.
  • Fixed Swap Sum:
    • The defined --amt (e.g. 3,000,000 sats) remains fixed as the total swap volume. Selecting multiple channels activates alternative outbound routes rather than multiplying the swap volume.
  • Dynamic Cost & PPM Range:
    • When multiple channels are selected, the effective cost is dynamically displayed as a range from the cheapest candidate up to the most expensive candidate (e.g. 3,569 – 4,570 ppm / 10,706 – 13,709 sats).
  • Bounded Routing Fee Budget:
    • Computes the off-chain routing fee ceiling passed to --max_swap_routing_fee from the maximum probed routing fee among selected candidates (max(probed_routing_fee) + leeway) rather than summing all fees, giving LND sufficient fee room without overpaying.
  • Interactive UI with Multi-Select:
    • TTY mode: [Space] toggles checkboxes ([✓] / [ ]), [a] toggles all up to --max-channels, and [Enter] confirms the batch with real-time fixed swap size and Net PPM range display.
    • Non-TTY mode: Automatically constructs greedy multi-channel batches to fulfill target amounts.
  • Configuration & Documentation:
    • Added max_channels = 3 to config.ini.example.
    • Added --max-channels and --channel / --channels CLI options.
    • Updated README.md and comprehensively documented multi-channel workflows in Other/swap_out-loop.md.
  • Bug Fixes:
    • Fixed post-swap logger TypeError in main() when multi-channel lists are selected, allowing foreground monitor_loop() to stream cleanly.
    • Eliminated duplicated (2 chans) (2 chans) in the litloop label.

Verification

  • Unit Tests (TDD): Expanded tests/Other/test_swap_out_loop.py to 30 unit tests covering multi-channel candidate pooling, argument parsing, non-TTY greedy batching, comma input, real command formatting, logging safety, and fixed amount with max fee budget (30/30 passed).
  • Full Suite Regression: 104/104 tests passing repository-wide (100% pass rate).
  • Live Host Validation: Tested on Debian NUC directly with litd / loopd.

- Support comma-separated channel lists (--channel id1,id2...) natively supported by loopd/litloop out.
- Enable liquidity pooling across up to --max-channels candidate channels when target swap amount exceeds single channel capacity.
- Add Spacebar multi-select toggling and select-all [a] to interactive terminal UI, with real-time combined swap size and aggregate PPM calculation.
- Add greedy multi-channel batching fallback for non-interactive/headless environments.
- Compute cumulative routing fee budget with configured leeway across all selected outgoing channels to prevent off-chain routing failures.
- Update config.ini.example with max_channels default (3) and expand documentation in Other/swap_out-loop.md.
- Add full unit test coverage for multi-channel pooling, argument parsing, non-TTY greedy batching, and command construction (28/28 tests passing).
@TrezorHannes TrezorHannes self-assigned this Sep 21, 2026
…d menu size capping

- Fix TypeError in main() when logging initiated multi-channel swap by using alias_str and chan_ids_str instead of indexing selected dict.
- Fix duplicated '(X chans) (X chans)' in litloop label by removing redundant channel count suffix in main().
- Cap displayed combined swap size in interactive menu footer to target_amt when explicitly specified.
- Add regression unit test test_main_multi_channel_logging_success.
…outbound candidates

- Keep the defined loop out sum fixed to target_amt (--amt) when selecting multiple outbound channels, activating channel combinations for MPP and route diversity rather than multiplying the swap volume.
- Display cost as an effective PPM and satoshi range (from cheapest candidate to most expensive candidate) in both the interactive UI footer and batch summary.
- Bound the routing fee budget to the maximum probed routing fee among selected candidates plus leeway (max(fee) + leeway) rather than summing all fees.
- Update documentation in Other/swap_out-loop.md and add test_multi_channel_fixed_amount_and_max_fee_budget test.
@TrezorHannes TrezorHannes added enhancement New feature or request python Pull requests that update python code labels Sep 21, 2026
@TrezorHannes
TrezorHannes merged commit 1d05e02 into main Sep 21, 2026
7 checks passed
@TrezorHannes
TrezorHannes deleted the feat/loop-out-multi-channel branch September 21, 2026 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request python Pull requests that update python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant