Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chanbackup, server, rpcserver: put close unsigned tx, remote signature and commit height to SCB #8183

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

starius
Copy link
Collaborator

@starius starius commented Nov 16, 2023

Change Description

In this PR I'm implementing the proposal from #7658 (comment)

I changed chanbackup to add CloseTxInputs optional field to chanbackup.Single structure. When the field is present, the version byte is XORed with closeTxVersion = 128. When this bit is present in the version byte, the field is properly extracted when decoding packaged single backup.

I added chantools scbforceclose command to extract and sign closing tx. lightninglabs/chantools#95

Implemented:

  • add global and maybe also lncli flags enabling close tx in SCB (now it is always on)
    • documentation for the flag and the feature
  • tests for new features of chanbackup
  • integration tests
  • lines wrap at 80
  • commit structure
  • when LND shuts down, update channel.backup with latest close tx inputs

Steps to Test

I tested the following scenario on testnet:

  • lncli openchannel
  • lncli exportchanbackup --chan_point xxx:x --output_file single.backup
  • lncli stop
  • chantools --testnet scbforceclose --single_backup xxx
  • Manually broadcasted the tx
  • Started LND from scratch on another machine
  • lncli create. Use existing seed, recover onchain funds.
  • lncli restorechanbackup --single_file single.backup
  • find the channel in lncli pendingchannels, total_limbo_balance is equal to channel balance minus fees

Pull Request Checklist

Testing

  • Your PR passes all CI checks.
  • Tests covering the positive and negative (error paths) are included.
  • Bug fixes contain tests triggering the bug to prevent regressions.

Code Style and Documentation

📝 Please see our Contribution Guidelines for further guidance.

Summary by CodeRabbit

  • New Features
    • Enhanced backup configuration flexibility with BackupOption parameters.
    • Added support for force close transaction data in backups.
    • Updated backup commands to include an option for force close transaction inputs.
    • Introduced a new option in LND for including data for unilateral channel closure in an SCB file.
    • Added a new parameter for controlling backup behavior in channel restoration scenarios.
    • Included an option to specify inclusion of inputs of the latest force close transaction in channel backups.
  • Bug Fixes
    • Fixed a typo in the log message within the SetupStandbyNodes function.
  • Refactor
    • Refined backup creation and serialization/deserialization logic to accommodate new backup options.
    • Updated LightningChannel to use a more modular approach for signing commitment transactions.
  • Documentation
    • Improved explanations on commitment transaction sweeping in various scenarios.

Copy link
Collaborator

@guggero guggero left a comment

Choose a reason for hiding this comment

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

Took a first look. I think the general idea is nice, this should help in some extreme edge cases.
Though the way we currently update those channels the commitment TX within the backup would be outdated very quickly for normal channels. So as a safety precaution we should not include a signature to make it hard for people to accidentally breach themselves.

chanbackup/single.go Outdated Show resolved Hide resolved
chanbackup/single.go Outdated Show resolved Hide resolved
contractcourt/commit_sweep_resolver.go Outdated Show resolved Hide resolved
chanbackup/backup.go Outdated Show resolved Hide resolved
chanbackup/backup.go Outdated Show resolved Hide resolved
chanbackup/backup.go Outdated Show resolved Hide resolved
starius added a commit to starius/chantools that referenced this pull request Dec 30, 2023
starius added a commit to starius/chantools that referenced this pull request Dec 31, 2023
@starius starius force-pushed the close-tx-in-static-backup branch 2 times, most recently from eebf352 to e7bc2ea Compare December 31, 2023 18:56
starius added a commit to starius/chantools that referenced this pull request Dec 31, 2023
@starius starius changed the title [WIP] chanbackup, server, rpcserver: put close tx to SCB [WIP] chanbackup, server, rpcserver: put close unsigned tx, remote signature and commit height to SCB Dec 31, 2023
@starius
Copy link
Collaborator Author

starius commented Dec 31, 2023

@guggero Thank you for feedback! Happy New Year!

I updated both PRs and also their descriptions. SCB file now contains unsigned CommitTx, CommitSig of remote party, and for taproot channels also CommitHeight. I kept unresolved the comments where further acctention may be needed.

Please take another look!

@starius starius requested a review from guggero December 31, 2023 20:27
starius added a commit to starius/chantools that referenced this pull request Jan 2, 2024
@starius
Copy link
Collaborator Author

starius commented Jan 2, 2024

I fixed few bugs in this PR.

  1. Integration test failed. I reproduced the failure using the following command (bitcoind binary is needed in PATH):
make itest icase=channel_backup_restore_basic backend=bitcoind

I found the root cause in log file itest/.logs-tranche0/4-channel_backup_restore_basic-dave-021bb9a5.log .

panic stack trace
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x21ec98]

goroutine 1 [running]:
github.com/btcsuite/btcd/wire.(*MsgTx).BtcEncode(0x0, {0x14691a0, 0x4001c3f500?}, 0x26a2832?, 0x2)
/root/go/pkg/mod/github.com/btcsuite/btcd@v0.23.5-0.20230905170901-80f5a0ffdf36/wire/msgtx.go:736 +0x38
github.com/btcsuite/btcd/wire.(*MsgTx).Serialize(...)
/root/go/pkg/mod/github.com/btcsuite/btcd@v0.23.5-0.20230905170901-80f5a0ffdf36/wire/msgtx.go:828
github.com/lightningnetwork/lnd/chanbackup.(*Single).Serialize(0x40004141a0, {0x14691a0?, 0x4001c3f470})
/root/lnd/chanbackup/single.go:363 +0x560
github.com/lightningnetwork/lnd/chanbackup.Multi.PackToWriter({0xa8?, {0x4000414000?, 0x400000d110?, 0x4000169f88?}}, {0x14691a0, 0x4001c3f440}, {0xffff6c95df30, 0x400000d110})
/root/lnd/chanbackup/multi.go:84 +0x240
github.com/lightningnetwork/lnd/chanbackup.(*SubSwapper).updateBackupFile(0x40001e40e0, {0x0, 0x0, 0x0?})
/root/lnd/chanbackup/pubsub.go:238 +0x48c
github.com/lightningnetwork/lnd/chanbackup.(*SubSwapper).Start.func1()
/root/lnd/chanbackup/pubsub.go:157 +0x6c
sync.(*Once).doSlow(0x4000716c60?, 0x0?)
/usr/local/go/src/sync/once.go:74 +0x100
sync.(*Once).Do(...)
/usr/local/go/src/sync/once.go:65
github.com/lightningnetwork/lnd/chanbackup.(*SubSwapper).Start(0x400049a420?)
/root/lnd/chanbackup/pubsub.go:151 +0x50
github.com/lightningnetwork/lnd.(*server).Start.func1()
/root/lnd/server.go:2072 +0x2120
sync.(*Once).doSlow(0x4?, 0x11b931e?)
/usr/local/go/src/sync/once.go:74 +0x100
sync.(*Once).Do(...)
/usr/local/go/src/sync/once.go:65
github.com/lightningnetwork/lnd.(*server).Start(0x1bf?)
/root/lnd/server.go:1864 +0x6c
github.com/lightningnetwork/lnd.Main(0x400002ab00, {{0x0?, 0x40001822a0?, 0x4000182300?}}, 0x400010f080, {0x40001a2480, 0x40001822a0, 0x4000182300, 0x40001823c0, {0x0}})
/root/lnd/lnd.go:684 +0x3164
main.main()
/root/lnd/cmd/lnd/main.go:38 +0x198

LND panicked trying to serialize a backup with nil CommitTx inside non-nil CloseTxInputs. This is possible when DLP is active and this is exactly what is tested in the failing test (channel_backup_restore_basic).

I changed buildCloseTxInputs to return nil *CloseTxInputs producing classic SCB file in this case.

  1. Also I found a mistake in error handling in Single.Serialize, returning nil instead of error. Fixed it.

  2. Also I figured out that wire.MsgTx can be serialized directly to io.Writer, without a temp buffer. Putting length of its serialization is redundant. I changed it to read and write tx directly.

@Roasbeef
Copy link
Member

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Feb 14, 2024

Important

Review skipped

Auto reviews are limited to specific labels.

Labels to auto review (1)
  • llm-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This update introduces a new feature allowing the inclusion of close transaction inputs in channel backups, enhancing data recovery options. It involves adding a BackupConfig structure, modifying functions to accept backup options, and updating serialization/deserialization logic to handle the new CloseTxInputs data. Additionally, it refactors signing logic in LightningChannel for better modularity and clarity, and corrects minor issues across the codebase.

Changes

Files Change Summary
chanbackup/backup.go, chanbackup/pubsub.go, rpcserver.go, server.go Introduced BackupConfig and BackupOption for configurable backup creation; added support for including close transaction inputs.
chanbackup/single.go, chanbackup/single_test.go Added CloseTxInputs struct and updated serialization/deserialization logic; added tests for new backup version.
cmd/lncli/commands.go Changed ChanBackup field type and modified value assignment.
contractcourt/commit_sweep_resolver.go Enhanced explanations on commitment sweeping scenarios.
docs/recovery.md Added information on --backupclosetxinputs option for SCB files and fund recovery.
lnrpc/lightning.proto Added with_close_tx_inputs field to specify force close transaction inclusion.
lnwallet/channel.go Refactored signing logic for commitment transactions and added taproot channel support.

🐇✨
In the land of code and byte,
A rabbit hopped with sheer delight.
"New backups," it squeaked, "are here to stay,
With close tx inputs, hooray, hooray!
Through refactor and tweak, we hop along,
Ensuring our data's robust and strong."
🌟🐾

Possibly related issues


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    -- I pushed a fix in commit <commit_id>, please review it.
    -- Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    -- @coderabbitai generate unit testing code for this file.
    -- @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    -- @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    -- @coderabbitai read src/utils.ts and generate unit testing code.
    -- @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    -- @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 4

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 4d8fa34 and a1b38f8.
Files selected for processing (10)
  • chanbackup/backup.go (3 hunks)
  • chanbackup/pubsub.go (3 hunks)
  • chanbackup/single.go (6 hunks)
  • chanbackup/single_test.go (4 hunks)
  • cmd/lncli/commands.go (1 hunks)
  • contractcourt/commit_sweep_resolver.go (1 hunks)
  • lntest/harness.go (1 hunks)
  • lnwallet/channel.go (4 hunks)
  • rpcserver.go (3 hunks)
  • server.go (1 hunks)
Files not reviewed due to errors (1)
  • server.go (Error: unable to parse review)
Files skipped from review due to trivial changes (1)
  • lntest/harness.go
Additional comments: 21
chanbackup/backup.go (3)
  • 89-98: The WithCloseTxInputs function correctly implements the BackupOption type to modify BackupConfig. Verify that all calls to this function correctly reflect the user's intention regarding the inclusion of CloseTxInputs.
  • 53-112: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [104-130]

In FetchBackupForChan, the handling of includeCloseTxInputs option is correct. Ensure that the buildCloseTxInputs function is robust and handles all edge cases, especially since it directly affects the backup's content based on this option.

  • 124-145: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [137-164]

In FetchStaticChanBackups, the handling of includeCloseTxInputs option is consistent with FetchBackupForChan. Double-check that the iteration over channels and the conditional inclusion of CloseTxInputs are correctly implemented and tested.

chanbackup/pubsub.go (3)
  • 101-103: The addition of the includeCloseTxInputs field in the SubSwapper struct is consistent with the overall feature addition. Ensure that this field is used appropriately in all relevant backup operations within SubSwapper.
  • 97-120: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [111-144]

The NewSubSwapper function correctly processes BackupOption parameters to configure the SubSwapper instance. Confirm that all instances of SubSwapper creation throughout the codebase are updated to pass the necessary BackupOption parameters.

  • 280-289: The conditional inclusion of CloseTxInputs based on the includeCloseTxInputs field within the backupUpdater method is correctly implemented. Verify that the buildCloseTxInputs function correctly handles all channel types and scenarios.
chanbackup/single_test.go (3)
  • 5-5: The addition of the encoding/hex import is necessary for the new test cases involving hex encoding. Confirm that it's used appropriately in all test cases.
  • 99-132: The modifications to assertSingleEqual to include checks for CloseTxInputs are correct. Ensure that all relevant test cases now properly account for CloseTxInputs when comparing Single instances.
  • 292-375: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [248-366]

The new test cases in TestSinglePackUnpack for different versions with CloseTxInputs are well-structured. Verify that these cases cover all scenarios, including edge cases for CloseTxInputs handling.

contractcourt/commit_sweep_resolver.go (1)
  • 28-35: The added comments provide clear explanations of the logic for handling CSV delays and CLTV expiration. This enhances code readability and maintainability.
chanbackup/single.go (5)
  • 55-58: Introduced closeTxVersionMask to indicate the presence of CloseTxInputs in backups. This approach allows backward compatibility and future extensibility.
  • 145-152: Added CloseTxInputs struct to Single for storing force close transaction data. This is crucial for enhancing the robustness of SCBs by including necessary data for force-closing channels.
  • 358-383: In Serialize, the conditional inclusion of CloseTxInputs based on its presence and version-specific handling for CommitHeight is correctly implemented. Ensure that future versions also consider compatibility with this feature.
  • 485-487: In Deserialize, correctly handling the version mask to determine the presence of CloseTxInputs. This ensures backward compatibility and correct parsing of new backup formats.
  • 600-628: The deserialization logic for CloseTxInputs correctly handles the conditional parsing based on the version and the presence of CloseTxInputs. This maintains the integrity of the backup data structure.
cmd/lncli/commands.go (1)
  • 2418-2421: The change from []byte to string for the ChanBackup field and the use of hex.EncodeToString for chanBackup.ChanBackup is observed. Ensure that all related serialization, deserialization, and cryptographic operations are correctly updated to handle the string type without loss of data or functionality.
lnwallet/channel.go (5)
  • 6224-6251: The definition of SignedCommitTxInputs and TaprootSignedCommitTxInputs structures is clear and well-documented. However, ensure that all fields, especially those involving cryptographic operations (OurKey, TheirKey, SignDesc), are securely handled throughout their lifecycle to prevent any potential security vulnerabilities.
  • 6265-6285: In GetSignedCommitTx, the handling of taproot channels involves re-deriving the local nonce using channeldb.NewMusigVerificationNonce. Ensure that error handling for this operation is robust, as failure in nonce derivation could lead to critical issues in transaction signing.
  • 6295-6301: The creation of the musig session with NewPartialMusigSession and decoding of the remote signature with remoteSig.Decode are critical operations. Verify that the error handling for Decode is comprehensive and that the musig session creation is securely managed, especially in terms of key handling and nonce generation.
  • 6347-6365: For non-taproot channels, the generation of the witness stack in default case uses ecdsa.ParseDERSignature and signer.SignOutputRaw. Ensure that the cryptographic operations are secure and that the generated witness stack correctly adheres to the expected format for multi-sig spends. Additionally, verify that SignOutputRaw is called with the correct parameters, particularly SignDesc, to prevent any issues in signature generation.
  • 6374-6397: The refactoring of getSignedCommitTx to use SignedCommitTxInputs and potentially TaprootSignedCommitTxInputs is a significant change. Ensure that this refactoring does not introduce any regressions, especially in the handling of taproot and non-taproot channels. Verify that the GetSignedCommitTx function is called with the correct inputs and that the channel's state is correctly used to populate these inputs.

rpcserver.go Outdated Show resolved Hide resolved
rpcserver.go Outdated Show resolved Hide resolved
rpcserver.go Outdated Show resolved Hide resolved
chanbackup/backup.go Outdated Show resolved Hide resolved
@starius
Copy link
Collaborator Author

starius commented Mar 28, 2024

I addressed feedback from @coderabbitai

  • added options to API requests and LND option to explicitly enable inclusion of CloseTxInputs into backups
    • when LND shuts down, update channel.backup with latest close tx inputs - DONE
  • documented new options
  • changed itest/lnd_channel_backup_test to run the tests in both modes (with the feature enabled/disabled via backupclosetxinputs flag of LND)

Copy link
Contributor

coderabbitai bot commented Mar 28, 2024

@starius, thank you for addressing the feedback and making those updates. It's great to see the inclusion of options for enabling the CloseTxInputs feature in backups, the documentation of these new options, and the adjustment of integration tests to cover both enabled and disabled states of the feature.

I'll review the changes to ensure everything aligns with best practices and the objectives of the PR. If there are any specific areas you'd like me to focus on or if there's additional context that might help with the review, please let me know.

Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

coderabbitai bot commented Mar 28, 2024

Tip

For best results, initiate chat on the files or code changes.

@starius, it's great to hear that you've made these updates based on the feedback. Adding options for enabling the CloseTxInputs feature, updating the channel.backup file upon LND shutdown, documenting the new options, and adjusting the integration tests to cover both enabled and disabled states of the feature are significant improvements.

Given the detailed updates you've provided, I'll proceed with reviewing the changes based on the descriptions you've shared. If there are specific files or sections of code you'd like me to focus on, please let me know, and I'll be happy to take a closer look.

Keep up the excellent work, and feel free to reach out if you have any questions or need further assistance.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 10

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b76f733 and 4163908b7ff4b6f5a77a874649f94a297ac67393.
Files ignored due to path filters (3)
  • lnrpc/lightning.pb.go is excluded by !**/*.pb.go
  • lnrpc/lightning.pb.gw.go is excluded by !**/*.pb.gw.go
  • lnrpc/lightning.swagger.json is excluded by !**/*.json
Files selected for processing (13)
  • chanbackup/backup.go (3 hunks)
  • chanbackup/pubsub.go (3 hunks)
  • chanbackup/single.go (6 hunks)
  • chanbackup/single_test.go (4 hunks)
  • cmd/lncli/commands.go (7 hunks)
  • config.go (1 hunks)
  • contractcourt/commit_sweep_resolver.go (1 hunks)
  • docs/recovery.md (2 hunks)
  • itest/lnd_channel_backup_test.go (10 hunks)
  • lnrpc/lightning.proto (3 hunks)
  • lnwallet/channel.go (4 hunks)
  • rpcserver.go (4 hunks)
  • server.go (3 hunks)
Learnings (1)
rpcserver.go (1)
Added flags `lncli exportchanbackup --with_close_tx_inputs` and `lnd --backupclosetxinputs` enable inclusion of `CloseTxInputs` in backups. Documentation updated in docs/recovery.md.
Additional comments (36)
chanbackup/backup.go (2)
  • 82-87: The introduction of the BackupConfig struct with the includeCloseTxInputs field is a good addition for configuring backup creation. This allows for flexibility in including or excluding close transaction inputs in backups, which can be useful depending on the user's needs or storage constraints.
  • 89-98: The WithCloseTxInputs function is a well-implemented BackupOption that enables users to specify whether SCBs should contain inputs needed for force-closing channels. This is a valuable feature for enhancing the robustness of SCBs, especially in scenarios where unilateral channel closure is required.
chanbackup/pubsub.go (3)
  • 101-103: Adding the includeCloseTxInputs field to SubSwapper is a logical extension of the backup configuration options introduced in backup.go. This field allows the backup subsystem to be aware of whether close transaction inputs should be included in backups, which is crucial for the new chantools scbforceclose functionality.
  • 97-120: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [111-144]

The modification of NewSubSwapper to handle BackupOption variadic parameters is a good design choice, as it aligns with the changes made in backup.go and allows for consistent backup configuration across different parts of the system. The initialization of includeCloseTxInputs based on BackupConfig ensures that the backup subsystem's behavior is configurable and flexible.

  • 281-291: Updating backupUpdater to conditionally include CloseTxInputs in Single creation based on the includeCloseTxInputs field is a necessary change to support the new backup configuration options. This ensures that the backup subsystem can create backups that are consistent with the user's configuration preferences.
chanbackup/single_test.go (2)
  • 99-132: Adding checks and comparisons for CloseTxInputs fields in assertSingleEqual is crucial for ensuring that the new functionality works as expected. This update ensures that tests will accurately verify the presence and correctness of CloseTxInputs in SCBs, which is essential for the reliability of channel backups.
  • 292-375: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [248-366]

The addition of test cases with CloseTxInputs in versionTestCases is a thorough approach to testing the new SCB functionality. These cases cover various scenarios, including different versions and the presence of CloseTxInputs, ensuring comprehensive test coverage for the changes introduced in this PR.

contractcourt/commit_sweep_resolver.go (1)
  • 28-36: The detailed explanations provided in the commitSweepResolver about the conditions under which commitments can be swept are valuable for understanding the logic behind the resolution process. It's important to ensure that these conditions are accurately represented in the code and that the resolver behaves as expected under various scenarios, including CSV delays and channel leases.
Verification successful

To further verify the handling of CSV delays and channel leases in the commitSweepResolver, we need to inspect the methods within this resolver that implement the logic described in the comments. Specifically, we should look for methods that calculate delays or check conditions before sweeping commitments.


To accurately verify the handling of CSV delays and channel leases in the commitSweepResolver, we need to inspect the implementation details of the getCommitTxConfHeight and hasCLTV methods. These methods appear to be directly related to the conditions described in the comments.


The analysis of the getCommitTxConfHeight and hasCLTV methods confirms that the commitSweepResolver implements logic that matches the detailed explanations provided in the comments regarding handling CSV delays and channel leases. The getCommitTxConfHeight method is used to wait for the necessary block confirmations before proceeding, and the hasCLTV method checks for the presence of a CLTV condition for channel leases. This verifies that the resolver's implementation accurately represents the conditions under which commitments can be swept, as described.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that the logic for handling CSV delays and channel leases in the
# commitSweepResolver matches the detailed explanations.
ast-grep --lang go --pattern $'commitSweepResolver { $$$ }'

Length of output: 1398



Script:

#!/bin/bash
# Search for methods within commitSweepResolver that handle CSV delays and channel leases
rg --type go "func \(c \*commitSweepResolver\) " ./contractcourt/commit_sweep_resolver.go

Length of output: 658



Script:

#!/bin/bash
# Inspect the getCommitTxConfHeight and hasCLTV methods for handling CSV delays and channel leases
rg --type go -A 10 "func \(c \*commitSweepResolver\) getCommitTxConfHeight\(" ./contractcourt/commit_sweep_resolver.go
echo "-----"
rg --type go -A 5 "func \(c \*commitSweepResolver\) hasCLTV\(" ./contractcourt/commit_sweep_resolver.go

Length of output: 785

chanbackup/single.go (6)
  • 56-58: The addition of the closeTxVersionMask constant is correctly implemented and follows a common pattern for encoding additional information within a byte. This approach allows for backward compatibility and future extensibility.
  • 155-175: The CloseTxInputs struct is well-designed and aligns with the objectives of enhancing SCB functionality. The inclusion of CommitHeight specifically for taproot channels is a thoughtful consideration for future channel types.
  • 145-152: The addition of the CloseTxInputs field to the Single struct is well-executed, with clear documentation and consideration for backward compatibility. This change is crucial for the PR's objectives and is correctly integrated into the existing structure.
  • 358-382: The updates to the Serialize method to handle CloseTxInputs are mostly correct. However, consider refining the error handling for the CommitTx serialization to ensure that any serialization failure is appropriately managed.
  • 597-632: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [485-628]

The updates to the Deserialize method to handle CloseTxInputs are correctly implemented. The method appropriately uses the closeTxVersionMask to detect the presence of CloseTxInputs and handles their deserialization efficiently, ensuring backward compatibility.

  • 142-178: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-629]

Overall, the changes to the chanbackup/single.go file are well-implemented, with clear documentation and adherence to coding standards. The introduction of CloseTxInputs and the corresponding updates to serialization and deserialization logic are crucial for enhancing SCB functionality and are executed with consideration for backward compatibility and future extensibility.

itest/lnd_channel_backup_test.go (7)
  • 81-90: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [59-87]

The introduction of the backupclosetxinputs flag to control backup behavior is well-implemented. However, it's crucial to ensure that this flag's effect is thoroughly tested across different scenarios within this test suite, especially in the context of SCBs and force-closing channels.

  • 420-434: The loop to test both states of the backupclosetxinputs flag (true and false) is a good approach to ensure that the new functionality works as expected under different configurations. This pattern is consistently applied throughout the test file, which is excellent for coverage.
  • 444-449: The newChanRestoreScenario function correctly incorporates the backupclosetxinputs flag into the node arguments. This ensures that the nodes being tested are initialized with the intended backup behavior, which is crucial for the validity of the tests.
  • 470-497: Testing the channel backup and restore functionality for unconfirmed channels with both states of the backupclosetxinputs flag is a comprehensive approach. It's important to verify that the system behaves correctly in scenarios where channels might not be fully established before a backup is needed.
  • 627-641: The loop to test different commitment types and zero-conf channels with both states of the backupclosetxinputs flag is thorough. It ensures that the backup and restore functionalities are compatible with various channel configurations, which is essential for the robustness of the feature.
  • 1178-1185: The testDataLossProtection function's approach to testing data loss protection with both states of the backupclosetxinputs flag is commendable. It's crucial to ensure that the system can handle scenarios where a node loses state, especially in the context of the new backup functionality.
  • 1206-1210: The conditional inclusion of the --backupclosetxinputs flag based on the test parameter is correctly implemented. This ensures that the node Dave is tested under both configurations, which is necessary for verifying the feature's impact on data loss protection scenarios.
cmd/lncli/commands.go (1)
  • 2412-2421: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [2393-2436]

The addition of the --with_close_tx_inputs flag to the exportChanBackupCommand is correctly implemented. The flag's description clearly explains its purpose, which aligns with the PR objectives to enhance SCB functionality by including essential data for force-closing channels. The logic to check if the flag is set and pass this information to the ExportChannelBackup and ExportAllChannelBackups RPC calls is correctly implemented. This change should enable users to include the necessary data for force-closing channels in their SCB exports, improving the robustness of channel backups.

config.go (5)
  • 354-355: The addition of the BackupCloseTxInputs boolean field to the Config struct introduces a new configuration option for including inputs in the backup to produce the latest force close transaction. This change aligns with the PR's objective to enhance SCB functionality. Ensure that documentation and user guides are updated to reflect this new option and its implications for channel backup and recovery processes.
  • 351-358: > 📝 NOTE

This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [2024-2048]

The supplyEnvValue function introduces a mechanism to handle environment variables within configuration values, supporting various formats including default values. This enhancement improves flexibility in configuration management. However, ensure that the documentation clearly explains how to use this feature, including examples of supported formats, to help users correctly configure their environment variables.

  • 351-358: > 📝 NOTE

This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [2024-2048]

The supplyEnvValue function includes logic to redact sensitive information such as passwords when logging configuration values. This is a good security practice to prevent accidental exposure of sensitive data in logs. Continue to apply this approach consistently across all logging of configuration values to enhance security.

  • 351-358: > 📝 NOTE

This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [2024-2048]

The use of regular expressions in functions like extractBtcdRPCParams and extractBitcoindRPCParams for parsing configuration files is appropriate for the use case. Given that these operations are performed once at startup, the impact on performance is minimal. However, consider precompiling regular expressions that are used multiple times or in loops to optimize performance in future enhancements.

  • 351-358: > 📝 NOTE

This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [2024-2048]

The configuration parsing and validation logic is well-structured, with clear separation of concerns and comprehensive error handling. The use of reflective programming to flatten the configuration struct into a map for easier processing of deprecated options is a clever approach. Ensure that error messages are clear and informative, providing users with actionable guidance on resolving configuration issues.

lnrpc/lightning.proto (3)
  • 4469-4472: The addition of the with_close_tx_inputs field to ExportChannelBackupRequest is consistent with the PR's objective to enhance SCBs by including additional data for force-closing channels. This field allows users to specify whether they want the backup to include inputs of the latest force close transaction, which can be crucial for recovering funds without counterparty cooperation.
  • 4506-4508: The addition of the with_close_tx_inputs field to ChanBackupExportRequest aligns with the enhancement of SCBs. This change enables the inclusion of close transaction inputs in the backup, providing more comprehensive data for channel recovery processes.
  • 4550-4552: Including the with_close_tx_inputs field in ChannelBackupSubscription is a valuable addition for subscribing to channel backup updates. This enables subscribers to receive backups that contain the inputs of the latest force close transaction, enhancing the robustness of the backup data.
rpcserver.go (4)
  • 7267-7267: The addition of chanbackup.WithCloseTxInputs(in.WithCloseTxInputs) in the ExportChannelBackup function correctly implements the feature to include close transaction inputs in the backup. This aligns with the PR's objective to enhance SCB functionality.
  • 7438-7438: Similarly, the inclusion of chanbackup.WithCloseTxInputs(in.WithCloseTxInputs) in the ExportAllChannelBackups function is consistent with the PR's goal to improve backup robustness by allowing the inclusion of close transaction inputs.
  • 7538-7539: The introduction of the closeTx variable in the SubscribeChannelBackups function to handle close transaction inputs is a thoughtful addition. It ensures that the functionality to include close transaction inputs is efficiently managed within the subscription logic.
  • 7570-7570: The use of chanbackup.WithCloseTxInputs(closeTx) in the SubscribeChannelBackups function's internal call to FetchStaticChanBackups is appropriate and ensures that the close transaction inputs are included in the backups as per the user's request. This is a crucial part of implementing the new feature as described in the PR.
lnwallet/channel.go (2)
  • 6461-6488: The introduction of the SignedCommitTxInputs struct is a positive change for code modularity and clarity. It encapsulates all necessary inputs for signing a commitment transaction, which aligns well with the principles of clean code and separation of concerns. This change should make the codebase more maintainable and easier to understand for new contributors.
  • 6490-6500: The TaprootSignedCommitTxInputs struct is well-defined and serves a specific purpose for taproot channels, which is a good practice in terms of code organization and clarity. However, it's important to ensure that all necessary fields are included and accurately documented for future reference and maintenance.

lnwallet/channel.go Show resolved Hide resolved
lnwallet/channel.go Show resolved Hide resolved
lnwallet/channel.go Show resolved Hide resolved
lnwallet/channel.go Show resolved Hide resolved
lnwallet/channel.go Outdated Show resolved Hide resolved
docs/recovery.md Outdated Show resolved Hide resolved
docs/recovery.md Outdated Show resolved Hide resolved
chanbackup/backup.go Outdated Show resolved Hide resolved
chanbackup/backup.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
@starius
Copy link
Collaborator Author

starius commented Mar 28, 2024

There are no tests that the backup with CloseTxInputs can be used to produce a commit transaction. To add such tests, the code signing commit tx should be available to such a test. Currently the code is in lightninglabs/chantools#95 in file cmd/chantools/scbforceclose.go in function signCloseTx. One approach is to move the function to LND and test it here, unit tests and itest. Another approach is to make an optional itest depending on chantools which runs chantools scbforceclose command. Any ideas on should this be tested in the first place and which of the options is preferred?

@guggero
Copy link
Collaborator

guggero commented Apr 22, 2024

@saubyk this is a nice security/recovery feature. Should we prioritize it for v0.19?

@starius, removing my request for review until prioritized (same for lightninglabs/chantools#95).

@guggero guggero removed their request for review April 22, 2024 12:35
@bhandras bhandras self-requested a review July 17, 2024 14:54
Copy link
Collaborator

@yyforyongyu yyforyongyu left a comment

Choose a reason for hiding this comment

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

Nice tests! I only looked at the itest related changes and have several questions.

return currentKey, nil
}

type hdKeyRing struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

why do we need this hdKeyRing? By searching DeriveNextKey it seems we've already had several implementations already, can we use one of those instead? Also isn't there an RPC service RPCKeyRing we can use?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can you elaborate on this, please? I can't find a suitable in-memory implementation of keychain.KeyRing, keychain.ECDHRing, and input.Signer (the types I need in SignCloseTx) which could be created from seed and passphrase.

To create RPCKeyRing, the following objects are needed: keychain.SecretKeyRing, lnwallet.WalletController, and *lncfg.RemoteSigner. I don't know how to make them from seed and passphrase.

I copy-pasted these two types from chantools. If there is a better way to create them, we can consider using that approach in chantools as well.

"github.com/lightningnetwork/lnd/keychain"
)

type hdSigner struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

same question re this, why do we need another input.Signer?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Same as above: I don't know how to create input.Signer from seed and passphrase using existing types :)

// Use the latest SCB to produce force close tx.
scbForCloseTx = backupAfterShutdown
}
crs.forceCloseTx, err = chanbackup.SignCloseTx(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of creating key rings and signers outside of the SignCloseTx, I think it should be handled inside the method. This way we only need to pass scbForCloseTx and mnemonic and password, and the chanbackup handles the creation of signers and king rings.

Also by looking at this method alone it's not an RPC point? If it's a method meant to be imported by other packages to be used, I'm not sure if it should be tested in integration tests.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If we make it too easy for the user to make signed transactions, they are more likely to misuse the feature and get funds lost. Currently it is not trivial to use the function outside of chantools, where we warn the user many times. The implementations of dependencies (keychain.KeyRing, keychain.ECDHRing, and input.Signer) live as private types in itest and are not directly usable from outside.

This function is intended to be used from chantools only. We don't have chantools in itest, so the only way of emulating using chantools in itest is to call the function directly. The code in chantools is really a wrapper around this function: lightninglabs/chantools@1fe8248

Copy link
Collaborator

Choose a reason for hiding this comment

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

In that case we should add unit tests for this method, not itest. You can import the lntest package in chantools to build the exact same test, and we should not use the itest in lnd to test programs importing it.

ht.EnsureConnected(carol, dave)

// Wait for Carol to publish a penalty transaction.
require.Eventually(ht, func() bool {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think MineBlocksAndAssertNumTxes already waits the tx?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Great catch!

I added require.Eventually because I got a failure in CI in ht.MineBlocksAndAssertNumTxes(1, 1) call (it got 0 txs), I wrote a comment about it and thought mistakenly that MineBlocksAndAssertNumTxes doesn't wait.

I checked the code of MineBlocksAndAssertNumTxes and AssertNumTxsInMempool and now I see that it was not the reason of that failure, because AssertNumTxsInMempool waits for 1 minute. I don't know why there were no transactions in mempool in that run of the test. Penalty transaction has to be there... I'll try to undo require.Eventually and reproduce it locally and debug.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I rebased the PR and fixed itest build errors (changes in ht interface and chanRestoreViaRPC function).

Also removed waiting for tx in mempool and added waiting for ClosedChannels call next to it, since it failed sometimes, because a channel was still closing during the call (so it saw 0 closed channels).

However I can't reproduce the original failure locally. For some reason Carol node didn't issue a justice transaction in that run in CI. Do you have any ideas why it could happen?

@starius
Copy link
Collaborator Author

starius commented Jul 25, 2024

I rebased the PR and fixed itest build errors (changes in ht interface and chanRestoreViaRPC function).

Also removed waiting for tx in mempool and added waiting for ClosedChannels call next to it, since it failed sometimes, because a channel was still closing during the call (so it saw 0 closed channels).

Added commit "lntest: fix typo".

Copy link
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.

Great work on this feature, definitely important work 👌

Well thought through code design only had minor comment on this one.

Regarding the itest however I am in doubt whether we need this test in general because it introduces a lot of new code regarding the signer, keyring etc. Moreover I think most of the tests here are already covered in other itests, for example the sweeping logic or the penalty case. Would it maybe possible to move all this tests into the chantools repo instead ?
I want to outline that these itests definiitly took a lot of work and are very detailed in general so kudos for this work 💪. I am brining this discussion up because when for example changing the anchor sweeper logic we realised that we had to change the itests in so many different places which took a lot of work and IMO was quite unnecessary. Thats why I want to avoid to many itests which basically test the same thing.

SignDesc *input.SignDescriptor

// Taproot holds fields needed in case of a taproot channel.
// If and only if the channel is of taproot type, this field is filled.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: Iff the channel => instead of (If and only if )

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

CommitSig []byte

// OurKey is our key to be used within the 2-of-2 output script
// for the owner of this channel config.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: what do you mean by this channel config ? Maybe cpy&paste relict ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, this was a copy-paste relict. Fixed.

// the total number of commitment updates to this point. This can be
// viewed as sort of a "commitment height" as this number is
// monotonically increasing.
CommitHeight uint64
Copy link
Collaborator

Choose a reason for hiding this comment

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

Q: why do we need the commitment height only for taproot channels only ? Probably to find the Nonce in the shachain ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. I added a comment in the code:

        // CommitHeight is the update number that this ChannelDelta represents
        // the total number of commitment updates to this point. This can be
        // viewed as sort of a "commitment height" as this number is
        // monotonically increasing. This number is used to make a signature
        // for a taproot channel, since it is used by shachain nonce producer
        // (TaprootNonceProducer).
        CommitHeight uint64

@@ -6473,29 +6473,72 @@ func (lc *LightningChannel) AbsoluteThawHeight() (uint32, error) {
return lc.channelState.AbsoluteThawHeight()
}

// getSignedCommitTx function take the latest commitment transaction and
Copy link
Collaborator

Choose a reason for hiding this comment

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

not sure I understand the comment, but don't we need to store "TheirSig" in the SCB ? In CloseTxInputs ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We store their part of the signature in the field CommitSig.

localCommit := lc.channelState.LocalCommitment

inputs := SignedCommitTxInputs{
CommitTx: localCommit.CommitTx,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if it is considered good design in general to pass pointer in a function which alter the underlying value of the pointer ? Not referring to this case here but more a general question, because I think we should always discourage this or are there some advantages to it ?

// let's start up Carol again.
require.NoError(ht, restartCarol(), "restart carol failed")
if c.forceCloseTx == nil {
// DLP case.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: Move the comment above the if clause

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed


// Upon reconnection, the nodes should detect that Dave is out of sync.
// Carol should force close the channel using her latest commitment.
// For scbforceclose case: we detect the manually broadcasts Dave's tx.
Copy link
Collaborator

Choose a reason for hiding this comment

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

According to the test it looks to me that assertFundsRecoveredStartCarol is only called in the scbforceclose case ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed. It was a relict of my original approach trying to have a single "assert" function for all cases. The function became too branched and complicated and I split it into separate "assert" functions, but forgot to update this comment.

// are uneconomical.
ht.AssertNumPendingSweeps(dave, 1)

// Carol has two sweeps.
Copy link
Collaborator

Choose a reason for hiding this comment

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

can you add which sweep Carol has here in addition to the anchor ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

// Carol has two sweeps: an anchor and her balance from the
// channel. Carol's funds are available immediately, as they are
// not timelocked.

Comment on lines 2126 to 2164
// After Carol's output matures, she should also reclaim her
// funds.
//
// The commit sweep resolver publishes the sweep tx at
// defaultCSV-1 and we already mined one block after the
// commitmment was published, so take that into account.
ht.MineEmptyBlocks(int(defaultCSV - blocksMined))

// Carol should have two sweep requests - one for her commit
// output and the other for her anchor.
ht.AssertNumPendingSweeps(carol, 2)

// Mine a block to trigger the sweep in Carol.
ht.MineEmptyBlocks(1)
ht.MineBlocksAndAssertNumTxes(1, 1)

// Now the channel should be fully closed also from
// Carol's POV.
ht.AssertNumPendingForceClose(carol, 0)

// We'll now mine the remaining blocks to prompt Dave to sweep
// his CLTV-constrained output.
resp := dave.RPC.PendingChannels()
blocksTilMaturity :=
resp.PendingForceClosingChannels[0].BlocksTilMaturity
require.Positive(ht, blocksTilMaturity)

ht.MineEmptyBlocks(int(blocksTilMaturity))

// Dave should have two sweep requests - one for his commit
// output and the other for his anchor.
ht.AssertNumPendingSweeps(dave, 2)

// Mine a block to trigger the sweep.
ht.MineEmptyBlocks(1)
ht.MineBlocksAndAssertNumTxes(1, 1)

// Now Dave should consider the channel fully closed.
ht.AssertNumPendingForceClose(dave, 0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think there is no need to test the sweeper here again imo, checking whether the sweeps where requested is sufficient enough.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed. Removed extra checks.

Comment on lines 2165 to 2216
} else {
// Carol should sweep her funds immediately, as they are not
// timelocked. We also expect Carol and Dave sweep their anchors
// if it's an anchor channel. Dave's funds are timelocked, so
// expect just one sweep.
if lntest.CommitTypeHasAnchors(commitType) {
ht.AssertNumPendingSweeps(carol, 2)
} else {
ht.AssertNumPendingSweeps(carol, 1)
}
ht.AssertNumPendingSweeps(dave, 1)

// Mine one block to trigger the sweeper to sweep.
ht.MineEmptyBlocks(1)
blocksMined++

// Expect one tx - the commitment sweep from Carol. For
// anchor channels, we expect the two anchor sweeping
// txns to be failed due they are uneconomical.
ht.MineBlocksAndAssertNumTxes(1, 1)
blocksMined++

// Now Carol should consider the channel fully closed.
ht.AssertNumPendingForceClose(carol, 0)

// After Dave's output matures, he should also reclaim his
// funds.
//
// The commit sweep resolver publishes the sweep tx at
// defaultCSV-1 and we already have blocks mined after the
// commitmment was published, so take that into account.
ht.MineEmptyBlocks(int(defaultCSV - blocksMined))

// Mine one block to trigger the sweeper to sweep.
ht.MineEmptyBlocks(1)

// Dave's sweeper swept the outputs of force close tx.
if lntest.CommitTypeHasAnchors(commitType) {
ht.AssertNumPendingSweeps(dave, 2)
} else {
ht.AssertNumPendingSweeps(dave, 1)
}

// Assert the sweeping tx is mined.
ht.MineBlocksAndAssertNumTxes(1, 1)

// Funds are now in Dave's wallet.
ht.AssertNumPendingForceClose(dave, 0)

// Now the channel should be fully closed also from
// Carol's POV.
ht.AssertNumPendingForceClose(carol, 0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here, I think we can reduce the test quite a bit, because if something changes for example with the anchor sweep all those tests would need to be changed, so I think we should not repeat tests wdyt ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed

@ziggie1984
Copy link
Collaborator

Would love to see a follow-up PR with the HTLC-Sigs included for the outgoing HTLCs 😊

Copy link
Collaborator

@yyforyongyu yyforyongyu 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 decide to support the feature of signing close tx in lnd, then we should make it into a RPC endpoint. If we decide to only make it a method that can be imported by other projects, i.e., the SignCloseTx method introduced here, then it should be only affecting the module chanbackup (ideally we should package it but that's beyond the scope), which means we should write unit tests, not itest.

We can easily duplicate the itest written in this PR since lntest is made for that. This is also how other services like loop/naut build their tests, not the other way around.

// Use the latest SCB to produce force close tx.
scbForCloseTx = backupAfterShutdown
}
crs.forceCloseTx, err = chanbackup.SignCloseTx(
Copy link
Collaborator

Choose a reason for hiding this comment

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

In that case we should add unit tests for this method, not itest. You can import the lntest package in chantools to build the exact same test, and we should not use the itest in lnd to test programs importing it.

@bhandras bhandras removed their request for review September 9, 2024 18:10
@lightninglabs-deploy
Copy link

@starius, remember to re-request review from reviewers when ready

@starius
Copy link
Collaborator Author

starius commented Sep 19, 2024

I rebased the PR, made chanbackup package TapscriptRoot channels aware. Added new backup version for TapscriptRoot channels and made changes needed to force-close such channels.

I addressed @ziggie1984 's feedback, in particular used fn.Option for optional parts of the backup and removed includeCloseTxInputs from chanbackup code. It is always on for new backups generated.

starius added a commit to starius/chantools that referenced this pull request Sep 20, 2024
It used to be base64, which is not compatible with verifychanbackup,
expecting hex.
It is used for sweeping time-locked outputs as well as non time-locked outputs.
This pure function creates signed commit transaction, using various
inputs passed as struct TaprootSignedCommitTxInputs and a signer.

This is needed to be able to store the inputs without a signature
in SCB and sign the transaction in chantools scbforceclose.

See https://github.com/lightningnetwork/lnd/pull/8183/files#r1423959791
The field is optional. It stores inputs needed to produce signed commit tx using
chantools scbforceclose, which calls function GetSignedCommitTx. New backups
have this field filled if commit tx is available (for all cases except when DLP
is active). If a backup has this data, the field is filled from it, otherwise it
is kept empty.
This method inserts channel updates and waits for them to be processed. It will
be used to update channel.backup upon LND shutdown.
This is needed to keep channel.backup up-to-date if the node is stopped.
starius added a commit to starius/chantools that referenced this pull request Sep 20, 2024
@starius
Copy link
Collaborator Author

starius commented Sep 20, 2024

@yyforyongyu I removed function SignCloseTx and the itest from this PR.
I added added the function SignCloseTx to chantools and added unit tests there: lightninglabs/chantools#95

Please take another look!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backups SCB Related to static channel backup
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

7 participants