Skip to content

tapchannel: no passive assets in funding proofs#1943

Merged
jtobin merged 2 commits intolightninglabs:mainfrom
jtobin:issue1932
Jan 15, 2026
Merged

tapchannel: no passive assets in funding proofs#1943
jtobin merged 2 commits intolightninglabs:mainfrom
jtobin:issue1932

Conversation

@jtobin
Copy link
Member

@jtobin jtobin commented Jan 9, 2026

This is a copy of #1940, which was tombstoned by GitHub for some reason.

@gemini-code-assist
Copy link

Summary of Changes

Hello @jtobin, 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 addresses a bug that led to passive assets being incorrectly incorporated into channel funding proofs. The changes introduce a new utility function to accurately identify funding-related virtual outputs and update the proof generation logic to ensure only these active funding outputs are included, thereby preventing the erroneous inclusion of passive assets.

Highlights

  • Bug Fix: Corrects an issue where passive assets were mistakenly included in channel funding proofs, which should only contain active funding outputs.
  • Code Refinement: Introduces a new helper function, isFundingOutput, to precisely identify which virtual outputs should contribute to channel funding proofs based on their type and anchor output index.
  • Proof Filtering Logic: Modifies the anchorVPackets function to leverage the new isFundingOutput helper, ensuring that only outputs destined for the primary funding output (index 0) are included in the funding proofs, thereby excluding passive assets.

🧠 New Feature in Public Preview: You can now enable Memory 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 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 counter productive. 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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

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.

Copy link

@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 addresses a bug where passive assets were incorrectly included in channel funding proofs. The fix introduces a new helper function, isFundingOutput, which correctly identifies outputs destined for the funding transaction by checking that the output type is TypeSimple and the anchor output index is 0. This function is now used in anchorVPackets, making the logic clearer and more robust. The corresponding release notes have also been updated. The changes are correct and improve the codebase.

@jtobin jtobin linked an issue Jan 9, 2026 that may be closed by this pull request
@coveralls
Copy link

coveralls commented Jan 9, 2026

Pull Request Test Coverage Report for Build 21032103406

Details

  • 0 of 7 (0.0%) changed or added relevant lines in 1 file are covered.
  • 56 unchanged lines in 13 files lost coverage.
  • Overall coverage decreased (-0.006%) to 56.931%

Changes Missing Coverage Covered Lines Changed/Added Lines %
tapchannel/aux_funding_controller.go 0 7 0.0%
Files with Coverage Reduction New Missed Lines %
asset/group_key.go 2 72.15%
commitment/tap.go 2 85.42%
tapdb/universe.go 2 80.81%
itest/assertions.go 3 87.05%
itest/multisig.go 3 97.88%
tapdb/sqlerrors.go 3 70.71%
universe/archive.go 3 81.74%
authmailbox/receive_subscription.go 4 76.07%
rpcserver.go 4 61.52%
tapgarden/caretaker.go 4 76.97%
Totals Coverage Status
Change from base Build 21031713177: -0.006%
Covered Lines: 65502
Relevant Lines: 115056

💛 - Coveralls

@jtobin jtobin requested a review from ffranr January 12, 2026 12:47
@jtobin jtobin self-assigned this Jan 12, 2026
Copy link
Contributor

@darioAnongba darioAnongba left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Collaborator

@ffranr ffranr left a comment

Choose a reason for hiding this comment

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

If we have time, i think it would be good to add test coverage for this. Some possibilities:

  • Unit-level: add a test around anchorVPackets in tapchannel/aux_funding_controller.go that builds vPackets with:
    • one TypeSimple output anchored to index 0 (funding),
    • one or more TypeSimple outputs anchored to index >= 1 (passive),
    • optional split-root/change output.
      Assert:
    • fundingProofs only contains proofs for AnchorOutputIndex == 0,
    • every output still has a ProofSuffix (passive proofs are still created).
  • Integration: end-to-end channel funding with passive assets present:
    • responder accepts funding proofs,
    • passive assets are still recoverable locally after the anchor tx confirms (proofs imported to local archive),
    • no change in behavior when there are no passive assets.

// Only include outputs destined for the funding output
// (index 0). Passive assets go to separate anchor
// outputs and should not be included in funding proofs.
if isFundingOutput(vPkt.Outputs[vOutIdx]) {
Copy link
Member

Choose a reason for hiding this comment

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

What was the next effect of this? Invalid proofs?

In my mind this could only happen if we had an exactly sized input (enough to pay for fees, etc) and we did a full value fund (entire asset amount utilized). In other words, we should always have a change output where the passive assets would live.

Copy link
Member Author

Choose a reason for hiding this comment

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

No invalid proofs; the effect observed in the wild was the one described in #1932, i.e. that displayed channel capacity was inflated by passive assets that weren't filtered out during funding. It's IMO entirely possible that other strange problems could manifest from this.

@jtobin
Copy link
Member Author

jtobin commented Jan 14, 2026

If we have time, i think it would be good to add test coverage for this.

I've since made lightninglabs/lightning-terminal#1198, which adds an itest for this. I can confirm that it fails locally without the fix here, and passes when the fix is applied. 👍

// transfer.
if vPkt.Outputs[vOutIdx].Type == tappsbt.TypeSimple {
// Only include outputs destined for the funding output
// (index 0). Passive assets go to separate anchor
Copy link
Collaborator

Choose a reason for hiding this comment

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

IMO better not to hardcode the index 0 in the comment

@github-project-automation github-project-automation bot moved this from 🆕 New to 👀 In review in Taproot-Assets Project Board Jan 15, 2026
@jtobin jtobin added the bug fix label Jan 15, 2026
Previously, anchorVPackets included all "TypeSimple" outputs in the
funding proofs sent to a responder. Passive assets (viz. those located
in the same UTXO, but not selected for funding) also have default output
type TypeSimple, which caused them to be included incorrectly.

The fix is to also check that AnchorOutputIndex == 0, since passive
assets are always assigned to anchor outputs at index >= 1.
@jtobin jtobin enabled auto-merge January 15, 2026 12:58
@jtobin jtobin added this pull request to the merge queue Jan 15, 2026
Merged via the queue into lightninglabs:main with commit 66105b3 Jan 15, 2026
34 checks passed
@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in Taproot-Assets Project Board Jan 15, 2026
jtobin added a commit to jtobin/taproot-assets that referenced this pull request Jan 15, 2026
tapchannel: no passive assets in funding proofs
(cherry picked from commit 66105b3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

[bug]: Incorrect Asset Channel Capacity Display

5 participants