cmd/commands: add taproot-final to lncli open command
What changed, and why it matters
This commit adds a new command-line option called 'taproot-final' for opening Lightning channels. It is a feature addition that exposes an already-existing protocol commitment type through the lncli user interface. There is no indication in the commit that it fixes a security bug or vulnerability.
No security action required. Treat as a normal feature/cleanup commit. Reviewers may verify that SIMPLE_TAPROOT_FINAL is already fully implemented server-side before exposing it in the CLI.
Security signals we found
No security-relevant code changes identified
Feature exposure of existing SIMPLE_TAPROOT_FINAL commitment type
Comment and formatting-only changes in input/witnessgen.go
Minor API additions (WithCustomSigningRand) for test reproducibility
Evidence from the diff
The patch wires up the SIMPLE_TAPROOT_FINAL commitment type in the lncli openchannel command, adds a matching witness-size constant, reformats comments for final taproot witness types, and makes minor cleanups in lnwallet/peer (custom signing randomness option and HTLC validator plumbing). The changes are additive and cosmetic; no cryptographic or consensus logic is altered in a security-relevant way.
Changed components
cmd/commands/cmd_open_channel.goinput/size.goinput/witnessgen.golnwallet/channel.gopeer/brontide.goInspect captured patch +57 / −30
diff --git a/cmd/commands/cmd_open_channel.go b/cmd/commands/cmd_open_channel.go
index 3b00862..289d69b 100644
--- a/cmd/commands/cmd_open_channel.go
+++ b/cmd/commands/cmd_open_channel.go
@@ -59,9 +59,10 @@ Signed base64 encoded PSBT or hex encoded raw wire TX (or path to file): `
// of memory issues or other weird errors.
psbtMaxFileSize = 1024 * 1024
- channelTypeTweakless = "tweakless"
- channelTypeAnchors = "anchors"
- channelTypeSimpleTaproot = "taproot"
+ channelTypeTweakless = "tweakless"
+ channelTypeAnchors = "anchors"
+ channelTypeSimpleTaproot = "taproot"
+ channelTypeSimpleTaprootFinal = "taproot-final"
)
// TODO(roasbeef): change default number of confirmations.
@@ -254,9 +255,9 @@ var openChannelCommand = cli.Command{
cli.StringFlag{
Name: "channel_type",
Usage: fmt.Sprintf("(optional) the type of channel to "+
- "propose to the remote peer (%q, %q, %q)",
+ "propose to the remote peer (%q, %q, %q, %q)",
channelTypeTweakless, channelTypeAnchors,
- channelTypeSimpleTaproot),
+ channelTypeSimpleTaproot, channelTypeSimpleTaprootFinal),
},
cli.BoolFlag{
Name: "zero_conf",
@@ -447,6 +448,8 @@ func openChannel(ctx *cli.Context) error {
req.CommitmentType = lnrpc.CommitmentType_ANCHORS
case channelTypeSimpleTaproot:
req.CommitmentType = lnrpc.CommitmentType_SIMPLE_TAPROOT
+ case channelTypeSimpleTaprootFinal:
+ req.CommitmentType = lnrpc.CommitmentType_SIMPLE_TAPROOT_FINAL
default:
return fmt.Errorf("unsupported channel type %v", channelType)
}
diff --git a/input/size.go b/input/size.go
index e88a934..97e251a 100644
--- a/input/size.go
+++ b/input/size.go
@@ -792,7 +792,8 @@ const (
TaprootHtlcOfferedRemoteTimeoutScriptSize + 1 +
TaprootBaseControlBlockWitnessSize + 32
- // TaprootHtlcOfferedRemoteTimeoutWitnessSizeFinal: 174 bytes (production scripts)
+ // TaprootHtlcOfferedRemoteTimeoutWitnessSizeFinal: 174 bytes
+ // (production scripts).
TaprootHtlcOfferedRemoteTimeoutWitnessSizeFinal = 1 + 1 + 65 + 1 +
TaprootHtlcOfferedRemoteTimeoutScriptSizeFinal + 1 +
TaprootBaseControlBlockWitnessSize + 32
diff --git a/input/witnessgen.go b/input/witnessgen.go
index aa23493..eae3f5f 100644
--- a/input/witnessgen.go
+++ b/input/witnessgen.go
@@ -256,39 +256,51 @@ const (
// revoked taproot commitment transaction.
TaprootCommitmentRevoke StandardWitnessType = 34
- // TaprootLocalCommitSpendFinal is a witness type that allows us to spend
- // our settled local commitment after a CSV delay when we force close
- // a final taproot channel (using production scripts).
+ // TaprootLocalCommitSpendFinal is a witness type that
+ // allows us to spend our settled local commitment after
+ // a CSV delay when we force close a final taproot
+ // channel (using production scripts).
TaprootLocalCommitSpendFinal StandardWitnessType = 35
- // TaprootRemoteCommitSpendFinal is a witness type that allows us to spend
- // our settled remote commitment after a CSV delay when the remote party
- // has force closed a final taproot channel (using production scripts).
+ // TaprootRemoteCommitSpendFinal is a witness type that
+ // allows us to spend our settled remote commitment
+ // after a CSV delay when the remote party has force
+ // closed a final taproot channel (using production
+ // scripts).
TaprootRemoteCommitSpendFinal StandardWitnessType = 36
- // TaprootHtlcOfferedTimeoutSecondLevelFinal is a witness that allows us to
- // timeout an HTLC we offered to the remote party on our commitment
- // transaction for final taproot channels (using production scripts).
+ // TaprootHtlcOfferedTimeoutSecondLevelFinal is a
+ // witness that allows us to timeout an HTLC we offered
+ // to the remote party on our commitment transaction
+ // for final taproot channels (using production
+ // scripts).
TaprootHtlcOfferedTimeoutSecondLevelFinal StandardWitnessType = 37
- // TaprootHtlcAcceptedSuccessSecondLevelFinal is a witness that allows us to
- // sweep an HTLC we accepted on our commitment transaction after we go
- // to the second level on chain for final taproot channels (using production scripts).
+ // TaprootHtlcAcceptedSuccessSecondLevelFinal is a
+ // witness that allows us to sweep an HTLC we accepted
+ // on our commitment transaction after we go to the
+ // second level on chain for final taproot channels
+ // (using production scripts).
TaprootHtlcAcceptedSuccessSecondLevelFinal StandardWitnessType = 38
- // TaprootHtlcOfferedRemoteTimeoutFinal is a witness that allows us to sweep
- // an HTLC we offered to the remote party that lies on the commitment
- // transaction for the remote party for final taproot channels (using production scripts).
+ // TaprootHtlcOfferedRemoteTimeoutFinal is a witness
+ // that allows us to sweep an HTLC we offered to the
+ // remote party that lies on the commitment transaction
+ // for the remote party for final taproot channels
+ // (using production scripts).
TaprootHtlcOfferedRemoteTimeoutFinal StandardWitnessType = 39
- // TaprootHtlcAcceptedRemoteSuccessFinal is a witness that allows us to
- // sweep an HTLC that was offered to us by the remote party for final
- // taproot channels (using production scripts).
+ // TaprootHtlcAcceptedRemoteSuccessFinal is a witness
+ // that allows us to sweep an HTLC that was offered to
+ // us by the remote party for final taproot channels
+ // (using production scripts).
TaprootHtlcAcceptedRemoteSuccessFinal StandardWitnessType = 40
- // TaprootCommitmentRevokeFinal is a witness that allows us to sweep the
- // settled output of a malicious counterparty's who broadcasts a
- // revoked final taproot commitment transaction (using production scripts).
+ // TaprootCommitmentRevokeFinal is a witness that
+ // allows us to sweep the settled output of a malicious
+ // counterparty's who broadcasts a revoked final
+ // taproot commitment transaction (using production
+ // scripts).
TaprootCommitmentRevokeFinal StandardWitnessType = 41
)
diff --git a/lnwallet/channel.go b/lnwallet/channel.go
index 5312ae9..52310a6 100644
--- a/lnwallet/channel.go
+++ b/lnwallet/channel.go
@@ -921,11 +921,21 @@ func WithAuxResolver(resolver AuxContractResolver) ChannelOpt {
}
}
+// WithCustomSigningRand is used to provide a custom random source for
+// generating deterministic JIT signing nonces in MuSig2 sessions. This should
+// only be used in tests that need reproducible MuSig2 signatures.
+func WithCustomSigningRand(rand io.Reader) ChannelOpt {
+ return func(o *channelOpts) {
+ o.customSigningRand = fn.Some[io.Reader](rand)
+ }
+}
+
// WithAuxHtlcValidator is used to specify a custom HTLC validator for the
-// channel.
+// channel. This allows external components to perform additional validation on
+// HTLCs before they are added to the channel state.
func WithAuxHtlcValidator(validator AuxHtlcValidator) ChannelOpt {
return func(o *channelOpts) {
- o.auxHtlcValidator = fn.Some[AuxHtlcValidator](validator)
+ o.auxHtlcValidator = fn.Some(validator)
}
}
diff --git a/peer/brontide.go b/peer/brontide.go
index 93d0f71..90cb138 100644
--- a/peer/brontide.go
+++ b/peer/brontide.go
@@ -5367,7 +5367,8 @@ func (p *Brontide) addActiveChannel(c *lnpeer.NewChannel) error {
func(ts htlcswitch.AuxTrafficShaper) {
val := p.createHtlcValidator(c.OpenChannel, ts)
chanOpts = append(
- chanOpts, lnwallet.WithAuxHtlcValidator(val),
+ chanOpts,
+ lnwallet.WithAuxHtlcValidator(val),
)
},
)
Why this scored 17/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.