Skip to content

funding: add coverage-guided fuzz harness for the channel-opening state machine - #10972

Open
MPins wants to merge 2 commits into
lightningnetwork:masterfrom
MPins:fuzz_funding_manager
Open

funding: add coverage-guided fuzz harness for the channel-opening state machine#10972
MPins wants to merge 2 commits into
lightningnetwork:masterfrom
MPins:fuzz_funding_manager

Conversation

@MPins

@MPins MPins commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR adds FuzzFundingManagerFSM, a native Go coverage-guided fuzz harness that exercises the funding manager's channel-opening state machine end to end. It decodes the corpus byte stream into a sequence of
events driving one or more concurrent funding flows against the manager.

Design

  • Single shared SUT, per-flow counterparty. Alice (the system under test) is one shared *Manager; each flow gets its own counterparty (Bob) manager. The SUT is what we're testing, so all adversarial or inconsistent values are imposed by the counterparty and the SUT must validate/reject them — as originator the SUT only ever emits valid values.
  • FSM over a byte stream. Events (start-as-funder, start-as-fundee, switch-flow, peer-interaction, confirm-funding-tx, …) and their parameters are read from the fuzz input, so the fuzzer explores interleavings of concurrent flows.
  • Deterministic oracles. Reservation counts are asserted at fixed handshake barriers; adversarial injections must never advance the live handshake; a premature channel_ready must be parked, not opened.

@github-actions github-actions Bot added the severity-low Best-effort review label Jul 15, 2026
@github-actions

Copy link
Copy Markdown

🟢 PR Severity: LOW

Classified from file diff | 1 file | 2034 lines changed

🟢 Low (1 file)
  • funding/fuzz_test.go - New fuzz test file (*_test.go); test-only change, no production code touched

Analysis

This PR consists solely of a new file, funding/fuzz_test.go, adding 2034 lines with no deletions. Although funding/* is normally a CRITICAL package (channel funding workflow coordination), the file matches the *_test.go pattern, which the classification rules explicitly designate as test-only content regardless of package path — placing it in the LOW severity tier ("best-effort review").

Since this is the only file in the diff and it's a test file, it's also excluded from the file-count/line-count bump calculation (0 non-test files, 0 non-test lines changed), so no severity bump applies.

No production code in funding/* is modified — this PR only adds fuzzing coverage for that package.


To override, add a severity-override-{critical,high,medium,low} label.

@MPins
MPins marked this pull request as draft July 15, 2026 17:28
@MPins
MPins force-pushed the fuzz_funding_manager branch from a0fcd4f to 3143430 Compare August 4, 2026 12:01
@MPins
MPins marked this pull request as ready for review August 4, 2026 12:01
@MPins
MPins force-pushed the fuzz_funding_manager branch 6 times, most recently from 13523ab to e094463 Compare August 7, 2026 19:53
MPins added 2 commits August 7, 2026 17:30
Add FuzzFundingManagerFSM, a native Go fuzz harness that drives the
funding manager's channel-opening state machine. A single shared SUT
(Alice) is exercised against a per-flow counterparty manager (Bob),
with the corpus byte stream decoded into a sequence of events over one
or more concurrent funding flows.

The harness treats the SUT as the system under test and imposes all
adversarial/inconsistent values from the counterparty side, so the SUT
validates and rejects them while, as originator, only ever emitting
valid values.
createTestFundingManager takes a privKey but hardcoded alicePrivKey for
the wallet controller, the signer and the secret key ring, so every
manager derived funding and commitment keys from Alice's root key
regardless of the identity it presented.

chanIDSeed was likewise left as 32 zero bytes, making every manager
produce the same pending channel ID sequence. Since lnwallet keys
fundingIntents by pending channel ID alone and not by peer, that
collides in a manager acting as funder for one channel and fundee for
another, compiling the funder's reservation against the fundee's
coinless intent.

Use privKey for all three components and seed chanIDSeed from it.
@MPins
MPins force-pushed the fuzz_funding_manager branch from e094463 to e68ba03 Compare August 7, 2026 20:31

@Bartok9 Bartok9 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review

Thanks for investing in a real coverage-guided funding-state fuzz harness — this is high-value (channel open is a classic adversarial surface) and matches the spirit of growing fuzz coverage rather than only happy-path unit tests.

Concept ACK on the direction: event enum (funder/fundee, peer adversarial modes, conf/reorg, disconnect/reconnect) is the right shape for a state-machine fuzzer.

Please clarify before a full ACK

  1. Default CI / developer cost — Is the fuzz target skipped in plain go test ./funding (build tags, short mode, or fuzz-only entrypoints)? A ~3kLOC harness is worth it if day-to-day tests stay fast; please document the intended go test -fuzz=... -fuzztime= invocation in the PR body or funding package comment.
  2. Failure oracle — Beyond panics, which invariants are checked (e.g. consistent chan IDs after confirm, no progress after fatal remote errors, funding tx / short chan id agreement across roles)? A short bullet list would help reviewers trust the harness.
  3. Entropy — Confirm peer/crypto/timing inputs are derived from fuzz data (no unintended wall-clock flakiness except explicit timeout paths).
  4. go.mod alignment — On a quick skim the new file imports look sensitive to btcd module paths; CI on this branch is the source of truth — green module build is enough.

Happy to re-review after the CI/skip + oracle notes land. Not requesting changes on concept — just wanting the operational story explicit for maintainers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

severity-low Best-effort review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants