[WIP]: LSP support - #1623
Open
chenyukang wants to merge 117 commits into
Open
[WIP]: LSP support #1623chenyukang wants to merge 117 commits into
chenyukang wants to merge 117 commits into
Conversation
chenyukang
force-pushed
the
lsp-support
branch
from
August 11, 2026 01:55
6d369e2 to
f1c7b85
Compare
# Conflicts: # crates/fiber-lib/src/fiber/network.rs
Read cold tenant signing status without activating its runtime and reject tenant-provided settlement secrets. Resolve watchtower TLC signing keys from the verified TLC identity and original derivation index, reject missing or conflicting keys, and recover stale signing requests. Consolidate signer regression tests and include the LSP SDK in WASM linting. Validated with 141 related nextest tests, make clippy, and cargo fmt.
…rt test suites - Enforce strict signature invariant checks with assert_not_awaiting_signature - Streamline handle_signer_notification with validate_and_apply_signer_notification - Eliminate runtime continuation tail flags and replace ChannelSignerBuffers with PendingMessages - Add duplicate CommitmentSigned idempotency handling by resending cached RevokeAndAck - Replay cached AnnouncementSignatures when receiving peer signatures while already in ChannelReady - Fix channel re-establishment and closing signature handling in ShuttingDown state - Add comprehensive external signer restart test suites covering all 6 ChannelSigningTransitions for both Tenant and Signer restarts
…reuse - Enforce next_material presence for state-advancing transitions in apply_next_signer_material - Validate completeness of next_commitment_point, next_commitment_nonce, and next_revocation_nonce - Guard against cross-purpose nonce collisions and cross-slot nonce reuse (fail-closed) - Ensure transactional atomicity: only insert public material into core once all checks pass - Add requires_next_signer_material to ChannelSignatureRequest - Add comprehensive unit and integration tests covering missing/partial material, nonce collisions, and idempotency
…Ack signature When awaiting an external signature for SendRevokeAndAck, remote_commitment_number is not yet incremented and last_revoke_ack_msg is not generated. If the remote peer restarts and sends ReestablishChannel during this window, processing it prematurely leads to misaligned commitment numbers, corrupted MuSig2 nonces, or unexpected RevokeAndAck errors triggering a force close. - Prioritize is_awaiting_signature in handle_peer_message, queuing incoming ReestablishChannel and deferring outgoing reestablish - Send deferred ReestablishChannel in handle_signer_notification after external signature completion before draining queued messages - Add assertion in handle_reestablish_channel_message preventing execution while awaiting signature - Add reproduction and edge-case regression tests in channel.rs
…ate replayed TLCs When a peer disconnects or restarts while an external signature is awaiting completion: - Purge stale pending peer messages in mark_reestablishing_offline, mark_watching_chain_offline, and on_peer_reconnected to prevent old session messages from polluting the new connection - Unify pending_reestablish_send and pending message purging into on_peer_reconnected as the single source of truth for reconnection state transitions - Handle AddTlc and RemoveTlc idempotently to accommodate peer replay during channel reestablishment (resend_tlcs_on_reestablish) without failing on expected next TLC ID checks - Add reproduction and regression tests verifying pending message purging and duplicate TLC handling across peer restarts
… raw wire messages while reestablishing - In RestoreOfflineChannel, defer sending ReestablishChannel and set pending_reestablish_send when channel.signing_context.is_awaiting_signature() is true. - In finish_send_revoke_and_ack and finish_send_commitment_signed, suppress raw wire message sending while reestablishing == true so messages are not dropped by reestablishing peers. - In handle_signer_notification, ensure send_reestablish_message is only triggered when peer is not Offline, allowing on_peer_reconnected to cleanly drive reestablishment when connection is ready. - Add tests for cold tenant restart while awaiting SendRevokeAndAck and SendCommitmentSigned.
…ure requests Replace the single-slot WatchtowerExternalState with multi-request pending_requests and signed_signatures maps to prevent concurrent TLC settlement signature requests from overwriting one another. Maintain the unified WatchtowerSigner and WatchtowerSignerState abstractions across the watchtower actor, RPC handler, and store interfaces, with verified TDD reproduction test coverage.
Preserve hosted FiberActor routing and external signing while integrating shutdown settlement recovery. Resolve tenant watch snapshots from the host store and adapt reconciliation fixtures with signer and namespace regression coverage.
Derive local commitment points and public nonces on demand instead of publishing and persisting every signing round. Drop legacy local caches on restore while preserving pending requests and idempotency receipts. Keep external signer validation and material history unchanged. Cover bounded local material state, restart with legacy caches, pending signature and receipt restoration, and unchanged external material requirements.
Problem: a7a4307 made a ChannelReady public channel reply to every received AnnouncementSignatures with its own cached signatures. Reestablishment already proactively replays those signatures, so two ready peers keep replying to one another. Each duplicate also rebuilds/broadcasts the channel announcement and update. The resulting ingress flood trips peer admission limits and disconnects an otherwise recovered session, making legacy recovery, repeated restarts, MPP retries and list_peers tests fail. Fix: Treat AnnouncementSignatures as an idempotent no-op once a public channel is ChannelReady, before mutating announcement state or broadcasting gossip. Keep the public-channel check and the AwaitingChannelReady path, as well as proactive cached-signature replay during funding/reestablishment. This still lets a ready peer recover the other side's missing announcement, without responding to that peer's replay indefinitely. No wire-format, persisted-schema or admission-limit changes are needed. Regression coverage: - Replay signatures repeatedly into a ready public channel and assert no outgoing messages, no gossip broadcasts and no persisted-state changes. - Reestablish asymmetric Ready/AwaitingChannelReady peers after a lost announcement; check cached replay restores readiness and then stops. - Strengthen external announcement-signing restart coverage to check both peers recover and the exact cached remote signature is restored. Both new regression tests fail on the unmodified implementation. The focused 40-test run, including all five previously failing tests, passes with this fix. Validation: - make test: default storage 1552 passed / 9 skipped; SQLite 1550 passed / 9 skipped; fiber-types 27 passed. - make clippy: all features/targets, SQLite, fiber-types and wasm32 pass. - cargo fmt --all -- --check, changed-file typos and git diff --check pass.
The public-channel restart fixture checked get_channel_signing_status for SignChannelAnnouncement, then called try_sign_pending, which queried the status a second time. If the first response was NoSignatureRequired and the announcement request arrived before the second query, the helper signed the very request the test meant to leave pending. The channel became ready, so setup waited for a consumed checkpoint until its 30s timeout. CI run 35158563757 shows this exact sequence. Pass the already-observed ChannelSigningStatus into the signing helper. The public setup now checks and acts on one snapshot; the unconstrained recovery/private-channel callers still query once before signing. Do not change production code, RPCs, timeout budgets or retry counts. Add a deterministic regression that presents a stale idle snapshot while a real announcement signature is pending. Assert that the signer store, complete signing request and absent local announcement signature remain unchanged, then explicitly sign the observed request and recover both peers. The regression fails with the old re-query behavior. Validation with CI trace logging and RUST_TEST_THREADS=2: - All 19 external signer restart tests pass with default storage and SQLite. - Repeat the signer restart, tenant restart and new announcement snapshot tests 20 times each: all 60 executions pass without timeout. - Nextest reports intermittent non-failing leaky-test warnings in default storage runs; SQLite reports none. These warnings are not suppressed. - make clippy passes, including SQLite and wasm32; fmt, changed-file typos and git diff --check also pass.
chenyukang
marked this pull request as ready for review
September 17, 2026 02:13
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.
To resolve #1571
Implementation of #1625