Skip to content

lightningd: delay dataloss error after channel_reestablish reply - #9563

Open
daywalker90 wants to merge 2 commits into
ElementsProject:masterfrom
daywalker90:fix-test-dataloss-protection-flake
Open

daywalker90 wants to merge 2 commits into
ElementsProject:masterfrom
daywalker90:fix-test-dataloss-protection-flake

Conversation

@daywalker90

Copy link
Copy Markdown
Collaborator

Fixes: #9519

Hopefully entirely this time.

@daywalker90
daywalker90 force-pushed the fix-test-dataloss-protection-flake branch from 8d85a93 to e421761 Compare September 24, 2026 17:22
Andezion
Andezion previously approved these changes Sep 24, 2026

@Andezion Andezion left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

before this change, a non cln peer (LND, LDK, Eclair) got our stale reestablish. The spec says it "SHOULD send an error and fail the channel", so it could force-close on that alone. Now it depends only on our error. Have you checked that the main implementations force close on an error for a channel when the channel_id matches?

@daywalker90

Copy link
Copy Markdown
Collaborator Author

before this change, a non cln peer (LND, LDK, Eclair) got our stale reestablish. The spec says it "SHOULD send an error and fail the channel", so it could force-close on that alone. Now it depends only on our error. Have you checked that the main implementations force close on an error for a channel when the channel_id matches?

LDK and eclair do, lnd does not

test_dataloss_protection only exercises the reconnect rescue when the
first ERROR loses the race with l1's channeld exiting, so the resend
path itself is almost never tested.  Drop l2's first WIRE_ERROR with
dev-disconnect (as test_dataloss_protection_no_broadcast does), then
reconnect: l2 must resend channel->error for l1 to drop to chain.

xfail(strict) for now: l2 currently replies with a stale
channel_reestablish before the canned error, l1's channeld exits on
the stale reply (peer-in-the-past warning) without reading the error,
and l1 never goes onchain.

Changelog-None
@daywalker90
daywalker90 force-pushed the fix-test-dataloss-protection-flake branch from e421761 to fe7140a Compare September 28, 2026 12:10
@daywalker90 daywalker90 changed the title lightningd: don't send stale channel_reestablish after data loss lightningd: delay dataloss error after channel_reestablish reply Sep 28, 2026
@daywalker90

Copy link
Copy Markdown
Collaborator Author

Reworked the approach to no break force-close behaviour with lnd

handle_peer_spoke() replies to channel_reestablish for a closed channel
and then immediately sends that channel's canned error.  We must keep
the reestablish reply: LND's force-close on data loss is triggered by
it (syncChanStates/ProcessChanSyncMsg sees our claimed tail is in the
past and returns ErrCommitSyncRemoteDataLoss, which leads to
LinkFailureForceClose), not by our error, which LND treats as
non-permanent.  LDK and Eclair do force-close on our error.

Back-to-back, however, a CLN peer loses the error: its channeld warns
and exits on our stale reestablish (peer-in-the-past revocation
number), and the immediately-following error is fed to that dying
channeld and discarded, so the peer never drops to chain.  That is
what flaked test_dataloss_protection after 946f700: when the first
ERROR lost the race with the peer's channeld exiting, the reconnect
rescue answered reestablish-then-error and hit the same loss, so
l1.wait_for_channel_onchain() timed out:

  >       l1.wait_for_channel_onchain(l2.info['id'])
  ValueError: Timeout while waiting for <lambda>

Send the error (and any disconnect) shortly after the reestablish
reply, like channeld's own sleep() before peer_failed_err(), so the
peer's channeld has exited and lightningd handles the error via
handle_peer_spoke() instead.

Changelog-Fixed: Protocol: a peer reconnecting to a channel where we
lost state now reliably force-closes it, instead of our error racing
their channeld exiting.
@daywalker90
daywalker90 force-pushed the fix-test-dataloss-protection-flake branch from fe7140a to 3e1e8fd Compare September 28, 2026 12:18

This branch has not been deployed

No deployments
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.

CI flake test_dataloss_protection

2 participants