Skip to content

Conversation

@Roasbeef
Copy link
Member

@Roasbeef Roasbeef commented Dec 4, 2025

In this PR, we address a fault tolerance gap in the current logic. Today the initaitor will attempt to import the proofs for the funding outputs (called funding inputs at times) after we send our last message to lnd. However, if we crash right before that, as the funding aux controller doesn't have any persistence of its own (not a proper durable state machine), then we may never import these proofs.

In the aux sweeper, we currently skip importing the funding outputs under the assumption that we already imported then during the funding process. However this is a faulty assumption, based on the above.

We fix this by always importing the funding proofs in the aux sweeper. We then add an existence check to make sure we don't end up with duplicate proofs, etc.

Previously, the funding output proofs were only imported during force
close handling if we were the channel responder. However, this could
lead to issues if the channel initiator failed to properly import the
funding proofs after the funding transaction confirmed.

This change removes the responder-only check and always attempts to
import the funding output proofs during force close handling. This
ensures that both parties can properly recognize and spend the funding
outputs regardless of any prior import failures.
Now that we always attempt to import funding output proofs during force
close handling (not just for responders), we may encounter proofs that
have already been imported. This change adds an early check using
HasProof to detect already-imported proofs and skip the expensive work
of fetching from the courier, decoding, and re-importing.

The fundingLocator is now constructed early in the loop and reused for
both the existence check and the final ImportProofs call, eliminating
redundant locator construction.
@gemini-code-assist
Copy link

Summary of Changes

Hello @Roasbeef, 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 significantly enhances the robustness of the channel funding process by ensuring that critical funding proofs are always imported, even in scenarios where the initiating node might crash before completing the import. By removing a conditional import logic and introducing a check for already existing proofs, the system becomes more resilient to transient failures, preventing potential issues with unrecorded funding outputs and improving overall system reliability.

Highlights

  • Fault Tolerance Improvement: This PR addresses a fault tolerance gap where the channel initiator might fail to import funding proofs after sending the final message, potentially leading to unrecorded funding outputs.
  • Unconditional Proof Import: The aux_sweeper now unconditionally attempts to import funding proofs, removing a faulty assumption that the initiator would have already completed this step.
  • Duplicate Proof Prevention: An existence check has been added before importing proofs to prevent redundant imports and ensure data integrity within the proof archive.
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 correctly addresses a fault tolerance gap for the channel initiator by ensuring funding proofs are always imported in the auxiliary sweeper. The addition of an existence check to prevent duplicate proofs is a necessary and well-implemented safeguard for this change. The code is clean, and the refactoring improves maintainability. I've found one potential issue regarding a panic on an empty slice, which should be addressed.

Comment on lines +1599 to 1607
err = importOutputProofs(
req.ShortChanID, maps.Values(fundingInputProofs),
a.cfg.DefaultCourierAddr, a.cfg.ProofFetcher,
a.cfg.ChainBridge, vCtx, a.cfg.ProofArchive,
)
if err != nil {
return fmt.Errorf("unable to import output "+
"proofs: %w", err)
}

Choose a reason for hiding this comment

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

high

The importOutputProofs function logs the first element of outputProofs without checking if the slice is empty. If fundingInputProofs is an empty map, maps.Values will produce an empty slice, causing a panic. It's safer to check if there are any proofs to import before calling the function.

outputProofs := maps.Values(fundingInputProofs)
if len(outputProofs) > 0 {
	err = importOutputProofs(
		req.ShortChanID, outputProofs,
		a.cfg.DefaultCourierAddr, a.cfg.ProofFetcher,
		a.cfg.ChainBridge, vCtx, a.cfg.ProofArchive,
	)
	if err != nil {
		return fmt.Errorf("unable to import output "+
			"proofs: %w", err)
	}
}

Copy link
Contributor

Choose a reason for hiding this comment

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

should be non-empty by assertion right? I personally don't like extra validation for things that should never happen by definition but I'm not sure if fundingInputProofs can be empty.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 19913768812

Details

  • 0 of 34 (0.0%) changed or added relevant lines in 1 file are covered.
  • 39 unchanged lines in 13 files lost coverage.
  • Overall coverage increased (+0.007%) to 56.615%

Changes Missing Coverage Covered Lines Changed/Added Lines %
tapchannel/aux_sweeper.go 0 34 0.0%
Files with Coverage Reduction New Missed Lines %
tapchannel/aux_sweeper.go 1 1.41%
address/mock.go 2 88.59%
mssmt/compacted_tree.go 2 78.57%
rfqmsg/records.go 2 70.8%
tapdb/mssmt.go 2 90.45%
tapdb/sqlc/transfers.sql.go 2 82.65%
itest/assertions.go 3 87.42%
itest/multisig.go 3 97.94%
universe/archive.go 3 79.22%
tapdb/universe.go 4 81.27%
Totals Coverage Status
Change from base Build 19823124678: 0.007%
Covered Lines: 64839
Relevant Lines: 114527

💛 - Coveralls

Copy link
Member

@GeorgeTsagk GeorgeTsagk left a comment

Choose a reason for hiding this comment

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

LGTM

missing release note (or tag to skip)

also the gemini feedback is worth checking

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, small comment on the Gemini review.

@github-project-automation github-project-automation bot moved this from 🆕 New to 👀 In review in Taproot-Assets Project Board Dec 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

5 participants