Skip to content

lnwallet: fix rebalancing/pathfinding regression, add unittests #10653

Merged
SomberNight merged 5 commits into
spesmilo:masterfrom
f321x:fix_gossip_rebalance
May 20, 2026
Merged

lnwallet: fix rebalancing/pathfinding regression, add unittests #10653
SomberNight merged 5 commits into
spesmilo:masterfrom
f321x:fix_gossip_rebalance

Conversation

@f321x
Copy link
Copy Markdown
Member

@f321x f321x commented May 18, 2026

Don't exclude r_tags for frozen channels from the route creation in
create_route_for_single_htlc if the start_node of the routing hint is not our node id.

When doing a rebalance from us (chan_1) -> bob -> us (chan_2, frozen for sending),
we would exclude the invoice r_tag for chan_2 because the chan
is our chan and frozen for sending, resulting in us being unable to find a route back to us trough bob.

This is a regression from #9692 (964ffbd).

Also prevents rebalancing if the required channel direction is frozen as this can lead to
opaque failures somewhere downstream (e.g. in the pathfinding).

@f321x f321x added the bug 🐞 label May 18, 2026
@f321x f321x force-pushed the fix_gossip_rebalance branch from 56ad5fd to b76d951 Compare May 18, 2026 12:50
Comment thread tests/test_lnwallet.py Outdated
Comment on lines +24 to +61
async def _connect_two_lnwallets(alice: 'MockLNWallet', bob: 'MockLNWallet') -> tuple[PeerInTests, PeerInTests]:
"""Mock transports and add the wallets as Peers to each others lnpeermgr."""
t_ab, t_ba = transport_pair(
alice.node_keypair,
bob.node_keypair,
name1=f"{alice.name}->{bob.name}",
name2=f"{bob.name}->{alice.name}",
)
peer_ab = PeerInTests(alice, bob.node_keypair.pubkey, t_ab)
peer_ba = PeerInTests(bob, alice.node_keypair.pubkey, t_ba)
alice.lnpeermgr._peers[bob.node_keypair.pubkey] = peer_ab
bob.lnpeermgr._peers[alice.node_keypair.pubkey] = peer_ba
await alice.lnpeermgr.taskgroup.spawn(peer_ab.main_loop())
await bob.lnpeermgr.taskgroup.spawn(peer_ba.main_loop())
return peer_ab, peer_ba


def _add_channels_to_peers(
peer_ab: 'PeerInTests',
peer_ba: 'PeerInTests',
*,
local_msat: Optional[int] = None,
remote_msat: Optional[int] = None,
) -> tuple[Channel, Channel]:
"""Create channels for given peers and mark them open"""
chan_ab, chan_ba = create_test_channels(
alice_lnwallet=peer_ab.lnworker,
bob_lnwallet=peer_ba.lnworker,
local_msat=local_msat,
remote_msat=remote_msat,
)
peer_ab.lnworker._add_channel(chan_ab)
peer_ba.lnworker._add_channel(chan_ba)
chan_ab._state = ChannelState.FUNDED
chan_ba._state = ChannelState.FUNDED
peer_ab.mark_open(chan_ab)
peer_ba.mark_open(chan_ba)
return chan_ab, chan_ba
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why you are adding this, but I don't like it.

It is mostly just duplicating test_lnpeer.TestPeer.prepare_chans_and_peers_in_graph. We should de-dupe it somehow.

We could split that off into a new module and reuse it. Except we also need to extend graph_definition to allow multiple direct channels between a given pair of nodes - but that could come in handy for other things too anyway.

I hacked together something along those lines:
master...SomberNight:electrum:202605_tests_lnhelpers_2 (b8491bd)

but my approach is also a bit ugly :(

idk, what do you think?

Copy link
Copy Markdown
Member Author

@f321x f321x May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I was already considering including the test in test_lnpeer.py but it felt misplaced to test the LNWallet logic there.

I looked at your approach, i think it makes sense to have a shared helper module as there are quite some similarities between the setups required in test_lnpeer and test_lnwallet. I cherry-picked it into this branch so we can move forward with this.

Should we move the graph definitions and the create_test_channels() function into lnhelpers.py as well? Or did you consider them too specific to move them into lnhelpers?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move the graph definitions

atm they are mostly used from lnpeer, we could wait to see if it spreads more

Should we move [...] create_test_channels()

you're right, that seems to be used from all over

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll move more stuff

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(ref #10660)

@f321x f321x force-pushed the fix_gossip_rebalance branch from b76d951 to 962dfaa Compare May 20, 2026 09:18
SomberNight and others added 5 commits May 20, 2026 11:19
Don't exclude r_tags for frozen channels from the route creation in
create_route_for_single_htlc if the start_node of the routing hint
is unequal to our node id.

When doing a rebalance us (chan_1) -> bob -> us (chan_2, frozen for sending),
we would exclude the invoice r_tag for chan_2 because the chan
is our chan and frozen for sending,
resulting in us being unable to find a route back to us trough bob.

This is a regression from spesmilo#9692 (964ffbd).
Don't allow rebalancing through a channel if it is frozen for the
direction required for the rebalance.
If this is allowed by the gui it creates opaque failures as then
pathfinding potentially fails downstream.
Add some unittest coverage for the channel rebalance flow.

Co-authored-by: SomberNight <somber.night@protonmail.com>
@f321x f321x force-pushed the fix_gossip_rebalance branch from 962dfaa to b183a52 Compare May 20, 2026 09:19
@SomberNight SomberNight merged commit c4f84af into spesmilo:master May 20, 2026
16 of 17 checks passed
@f321x f321x deleted the fix_gossip_rebalance branch May 20, 2026 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants