Repository navigation
Backport async reestablish point (upstream 1f7b24900) + keep uncached points non-fatal (on zeus-0.2.6) - #2
Merged
Conversation
`HolderCommitmentPoint` currently tracks the current and next point used on counterparty commitments, which are unrevoked. When we reestablish a channel, the counterparty sends us the commitment height, along with the corresponding secret, for the state they believe to be the latest. We compare said secret to the derived point we fetch from the signer to know if the peer is being honest. Since the protocol does not allow peers (assuming no data loss) to be behind the current state by more than one update, we can cache the two latest revoked commitment points alongside `HolderCommitmentPoint`, such that we no longer need to reach the signer asynchronously when handling `channel_reestablish` messages throughout the happy path. By doing so, we avoid complexity in needing to pause the state machine (which may also result in needing to stash any update messages from the counterparty) while the signer response is pending. The only remaining case left to handle is when the counterparty presents a `channel_reestablish` with a state later than what we know. This can only result in two terminal cases: either they provided a valid commitment secret proving we are behind and we need to panic, or they lied and we force close the channel. This is the only case we choose to handle asynchronously as it's relatively trivial to handle. [ZEUS backport to 0.2: check_closed_event takes is_check_discard_funding in the async_signer_tests case.] (cherry picked from commit 1f7b249)
The backported reestablish fix derives the two cached revoked points from the signer when reading a channel persisted before the cache existed, and expects the result. With VLS, a signer that lost or has not restored the channel refuses, which would abort every node restart while reading the ChannelManager. Leave the point unset instead; at channel_reestablish, ask the signer for an uncached point and disconnect with a warning if it cannot answer, so the peer retries. The channel stays open, and the next ChannelManager read tries the derivation again until a write persists the points. Tests: reestablish needs no signer call when the points are cached; with the cache cleared and the signer refusing, reestablish disconnects without panicking or closing, and a later reconnect succeeds.
kaloudis
force-pushed
the
zeus-0.2-async-reestablish-point
branch
from
September 24, 2026 22:38
051b916 to
1b22c62
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backports upstream
1f7b24900(Wilmer Paulino, "Support async fetching of commitment point during channel reestablish") tozeus-0.2.6, plus one ZEUS change for remote signers.Base:
zeus-0.2.6(new): upstreamv0.2.6with the five Zeus patches fromzeus-0.2cherry-picked unchanged (LSPS7 client, coop-close feerate floor, route-hints override + its test, LSPS5 test fix).zeus-0.2is untouched, so ZEUS mobile's pin keeps working; it can move tozeus-0.2.6when ready. Onzeus-0.2.6alone:cargo test -p lightning --lib1211 passed,-p lightning-liquidityall passed.Why
With a remote signer (VLS in lnrod),
channel_reestablishasked the signer for the point matching the peer'syour_last_per_commitment_secretand.expect()ed it ("TODO: async signing is not yet supported…"). When vlsd was behind LDK after an enclave restart, the refusal panicked lnrod on every reconnect: the 2026-09-23 acme incident (54 crash-loops) and the last abort path left open by zeus-vls lightningdevkit#246/lightningdevkit#248.Commits
1f7b24900(clean cherry-pick).HolderCommitmentPointcaches the last two revoked points (persisted as TLVs 71/73, same numbers as upstream 0.3), so a reestablish from a peer at our state or one behind is verified without the signer. Only a peer claiming a state ahead of ours asks the signer; if it cannot answer, the peer is disconnected with a warning and the check finishes insigner_unblocked(stale-state panic if proven, force close if the secret is bogus, as upstream). Adaptation: one test call gains 0.2'sis_check_discard_fundingargument.expects them. With VLS, a signer that lost or has not restored the channel refuses, which would abort every node restart. This leaves the point unset instead; at reestablish an uncached point is fetched from the signer and a refusal disconnects with a warning (no close, no panic). The next ChannelManager read retries the derivation until a write persists the points.Effect on in-memory signers (ZEUS mobile)
None beyond upstream's:
get_per_commitment_pointnever fails there, so the ZEUS fallback is never taken. The new TLVs are odd, so older readers ignore them, and they match upstream 0.3's.Tests
cargo test -p lightning --lib: 1215 passed, 0 failed (onzeus-0.2.6+ these two commits).test_reestablish_needs_no_signer_point_when_cached(signer refusing every point, reconnect succeeds, payments continue) andtest_reestablish_disconnects_when_uncached_point_is_refused(cache cleared + signer refusing: warning + disconnect, channel stays open, reconnect succeeds after the signer answers; panics with upstream'sexpectrestored).test_async_panic_on_stale_stateandtest_async_force_close_on_invalid_secret_for_stale_statepass.Consumer: ZeusLN/zeus-vls#251 pins this branch's head (
1b22c622). Please merge with a merge commit or fast-forward, not squash, so that rev stays onzeus-0.2.6.