Skip to content

funding: require explicit taproot channel negotiation#10820

Open
yyforyongyu wants to merge 7 commits into
lightningnetwork:masterfrom
yyforyongyu:fix-channel-open
Open

funding: require explicit taproot channel negotiation#10820
yyforyongyu wants to merge 7 commits into
lightningnetwork:masterfrom
yyforyongyu:fix-channel-open

Conversation

@yyforyongyu
Copy link
Copy Markdown
Member

Summary

  • keep implicit channel type negotiation on anchors/static/legacy, even when both peers advertise simple taproot channel support
  • reject explicit public taproot opens locally on the initiator before sending OpenChannel
  • add initiator/responder regression tests and document the default-open behavior

Fixes #10819.

Tests

  • GOWORK=off go test ./funding -run 'TestCommitmentTypeNegotiation|TestFundingManagerRejectPublicTaprootInitiator|TestFundingManagerRejectPublicTaprootResponder'\n- GOWORK=off go test ./funding

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request modifies the channel negotiation logic to prevent taproot channels from being selected implicitly. It enforces that taproot channels must be explicitly requested by the user, while also adding safety guards to prevent the creation of public taproot channels, which are not yet fully supported. These changes ensure more predictable channel type selection and prevent potential issues with unsupported public taproot configurations.

Highlights

  • Implicit Negotiation Update: Updated implicit channel negotiation to exclude taproot types, ensuring that taproot channels must now be explicitly requested.
  • Public Taproot Enforcement: Added local validation to reject public taproot channel requests on both the initiator and responder sides.
  • Regression Testing: Implemented new test cases to verify that public taproot channel requests are correctly rejected by both initiators and responders.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions github-actions Bot added the severity-critical Requires expert review - security/consensus critical label May 19, 2026
@github-actions
Copy link
Copy Markdown

🔴 PR Severity: CRITICAL

Automated classification | 3 files (excl. tests) | 44 lines changed (excl. tests)

🔴 Critical (2 files)
  • funding/commitment_type_negotiation.go - Channel funding workflow coordination (funding/*)
  • funding/manager.go - Channel funding workflow coordination (funding/*)
🟢 Low (1 file)
  • docs/release-notes/release-notes-0.21.0.md - Release notes documentation

Analysis

This PR modifies the funding package, specifically commitment_type_negotiation.go and manager.go. The funding/* package handles the channel funding workflow coordination — including commitment type negotiation between peers — which is classified as CRITICAL because errors here can result in funds being locked, channels being funded with incorrect parameters, or protocol mismatches during channel establishment.

The change is relatively small (44 non-test lines), touching commitment type negotiation logic and the funding manager. Despite the modest size, the sensitivity of the funding package warrants expert review to ensure correctness of any negotiation logic changes.


To override, add a severity-override-{critical,high,medium,low} label.
<!-- pr-severity-bot -->

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the commitment type negotiation logic to prefer anchor channels over taproot for implicit opens, requiring taproot to be explicitly requested. It also adds a safeguard to reject public taproot channels at the funding manager level and includes new unit tests to verify these changes. I have no feedback to provide.

Copy link
Copy Markdown
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

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

LGTM (pending linter fixes)

@kaloudis not sure if that touches you but default channel opens for private channels will not be taproot with this change.

remote *lnwire.FeatureVector) (*lnwire.ChannelType,
lnwallet.CommitmentType) {

// Taproot channels are checked before anchors intentionally: when both
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.

Let's add a TODO to enable it as soon as public taproot channels are available ?

@ziggie1984
Copy link
Copy Markdown
Collaborator

Small docs nit: the new release note says taproot must be requested via --commitment_type=simple_taproot_final / simple_taproot, but the lncli openchannel user-facing flag is --channel_type, with values taproot-final and taproot.

Maybe adjust this to:

Taproot must be requested explicitly via `--channel_type=taproot-final`
(or `taproot` for staging).

If the intent is to document the raw RPC enum rather than lncli, then I think the --flag syntax should be avoided so users do not try a non-existent CLI option.

Comment thread funding/manager_test.go
openChannelReq, ok := msg.(*lnwire.OpenChannel)
require.True(t, ok)

// Flip the captured wire message to public so the responder path is
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this comment should be folded into bd2d0de

Comment thread funding/manager_test.go
openChannelReq.ChannelFlags = lnwire.FFAnnounceChannel
bob.fundingMgr.ProcessFundingMsg(openChannelReq, alice)

// The specific taproot/public failure is logged locally; the wire error
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

same here, fold into bd2d0de

Comment thread funding/commitment_type_negotiation.go Outdated
remote *lnwire.FeatureVector) (*lnwire.ChannelType,
lnwallet.CommitmentType) {

// Taproot channels must be requested explicitly. This keeps implicit
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this comment is introduced then deleted - we should instead remove it in bd2d0de

RBF close state machine does not yet thread through the `AuxCloser` hook
that overlay channels rely on to build aux-aware close transactions.

* Fixed default channel opens between peers that both advertise simple taproot
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

there is no need for a release note here, given that this PR just restores the behavior in 0.20?

@yyforyongyu yyforyongyu force-pushed the fix-channel-open branch 3 times, most recently from dfdcf53 to 5569db3 Compare May 20, 2026 05:37
@ziggie1984 ziggie1984 added this to v0.21 May 20, 2026
@ziggie1984 ziggie1984 added this to the v0.21.0 milestone May 20, 2026
@saubyk saubyk moved this to In review in v0.21 May 20, 2026
@saubyk saubyk added the backport-v0.21.x-branch This label triggers a backport to branch `v0.21.x-branch ` label May 20, 2026
@saubyk saubyk requested a review from calvinrzachman May 20, 2026 17:22
Copy link
Copy Markdown
Collaborator

@calvinrzachman calvinrzachman left a comment

Choose a reason for hiding this comment

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

Gave this a spin locally against our integration test suite with loop. Cherry-picked the three PR commits onto the v0.21.x-branch, and removed the explicit --commitment_type=anchors workaround I had been running with. Public channel opens now succeed without the need to explicitly specify a commitment type. LGTM.

@Roasbeef Roasbeef force-pushed the fix-channel-open branch from 5569db3 to abae492 Compare May 20, 2026 22:44
@github-actions github-actions Bot added severity-critical Requires expert review - security/consensus critical and removed severity-critical Requires expert review - security/consensus critical labels May 20, 2026
In this commit, we shuffle the CLI and RPC names so the bare "taproot"
identifier refers to the production taproot channel type (final
scripts, feature bits 80/81), i.e. the variant new integrations should
actually be using. Before this commit, "taproot" on the CLI mapped to
the staging bits, and anyone who wanted a real production taproot
channel had to spell out "taproot-final" on `lncli openchannel` or
`SIMPLE_TAPROOT_FINAL` over RPC. The recommended choice was hidden
behind the longer name.

On the CLI (`lncli openchannel --channel_type=...`):

  - "taproot" now selects the production variant (it used to mean
    staging).
  - "taproot-staging" is added for the legacy development bits, for
    peers that haven't moved over yet.
  - "taproot-final" stays as a deprecated alias for "taproot" so
    existing scripts don't break.

On the RPC (`CommitmentType`):

  - `TAPROOT = 7` is added as the canonical name for the production
    type. `SIMPLE_TAPROOT_FINAL = 7` is kept as a deprecated alias via
    `option allow_alias = true`, so existing clients keep compiling
    against the same Go constant and the wire value doesn't change.
  - `SIMPLE_TAPROOT = 5` (staging) is unchanged.
  - `SIMPLE_TAPROOT_OVERLAY = 6` is unchanged. The taproot-assets
    daemon hard-codes this distinct enum value, so it's unaffected.

Wire compat is preserved end-to-end: only the comments, enum entry
order, and the CLI string-to-enum mapping change. The numeric values
and the existing generated Go identifiers stay stable.
@Roasbeef Roasbeef force-pushed the fix-channel-open branch from 2a5b7fd to 5bcc525 Compare May 20, 2026 23:25
@github-actions github-actions Bot added severity-high Requires knowledgeable engineer review and removed severity-critical Requires expert review - security/consensus critical labels May 20, 2026
@github-actions
Copy link
Copy Markdown

⚠️ Severity changed: severity-criticalseverity-high (files changed since last classification)

🟠 PR Severity: HIGH

Automated classification | 6 files | 119 lines changed

🟠 High (4 files)
  • funding/commitment_type_negotiation.go - channel funding workflow coordination
  • funding/manager.go - channel funding workflow coordination
  • lnrpc/lightning.proto - RPC/API definitions in lnrpc/*
  • lnrpc/lightning.swagger.json - RPC/API definitions in lnrpc/*
🟡 Medium (1 file)
  • cmd/commands/cmd_open_channel.go - CLI client command (cmd/* is always MEDIUM per classification rules, regardless of filename keywords)
🟢 Low (1 file)
  • docs/release-notes/release-notes-0.21.0.md - documentation/release notes

Analysis

The highest-severity files in this PR are in funding/* and lnrpc/*, both of which map to HIGH. No CRITICAL-tier packages (lnwallet/*, htlcswitch/*, contractcourt/*, channeldb/*, etc.) are touched.

The previous severity-critical label did not reflect the actual file paths — funding/* is HIGH (channel funding workflow coordination), not CRITICAL. The cmd/commands/cmd_open_channel.go file is CLI client code under cmd/* and stays MEDIUM per classification rules, even though its name references a server-side concept.

Bump conditions checked:

  • Files changed (excl. tests/generated): 6 — not >20
  • Lines changed (excl. tests/generated): ~119 — not >500
  • Multiple distinct critical packages: none
  • No severity bump applied.

To override, add a severity-override-{critical,high,medium,low} label.
<!-- pr-severity-bot -->

Roasbeef added 3 commits May 20, 2026 18:15
fixup! funding: require explicit taproot channel negotiation
fixup! funding: reject public taproot opens before sending
fixup! multi: rename taproot channel type to mean production variant
@github-actions github-actions Bot added severity-critical Requires expert review - security/consensus critical and removed severity-high Requires knowledgeable engineer review labels May 21, 2026
@github-actions
Copy link
Copy Markdown

⚠️ Severity changed: severity-highseverity-critical (files changed since last classification)

🔴 PR Severity: CRITICAL

Automated classification | 6 files | 119 lines changed (excluding tests and auto-generated)

🔴 Critical (2 files)
  • funding/commitment_type_negotiation.go - channel funding workflow: commitment type negotiation logic
  • funding/manager.go - channel funding workflow: funding manager coordination
🟠 High (2 files)
  • lnrpc/lightning.proto - RPC/API definition changes (lnrpc/*)
  • lnrpc/lightning.swagger.json - RPC/API swagger spec (lnrpc/*)
🟡 Medium (1 file)
  • cmd/commands/cmd_open_channel.go - CLI client command (cmd/* = always MEDIUM)
🟢 Low (1 file)
  • docs/release-notes/release-notes-0.21.0.md - release notes documentation

Analysis

This PR touches the funding/ package, which handles the channel funding workflow coordination — a CRITICAL area of the codebase. Specifically:

  • funding/commitment_type_negotiation.go modifies commitment type negotiation logic, which directly affects how channel commitment transactions are structured and agreed upon between peers.
  • funding/manager.go changes to the funding manager affect the core lifecycle of channel establishment.

The accompanying lnrpc/ proto and swagger changes indicate this exposes new or modified API surface for these funding behaviors, raising additional review importance.

Severity bump checks:

  • File count: 6 non-excluded files (threshold: >20) — no bump
  • Lines changed: 119 non-excluded lines (threshold: >500) — no bump
  • Distinct critical packages: 1 (funding/) — no bump

The funding/ package alone is sufficient to classify this PR as CRITICAL, requiring expert review.


To override, add a severity-override-{critical,high,medium,low} label.
<!-- pr-severity-bot -->

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

Labels

backport-v0.21.x-branch This label triggers a backport to branch `v0.21.x-branch ` no-changelog severity-critical Requires expert review - security/consensus critical

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

funding: no fallback when taproot negotiated for public channel

5 participants