Skip to content

Commit 159f853

Browse files
Roasbeefguggero
authored andcommitted
input: add new tapscript root func op to GenTaprootFundingScript
This'll allow us to create a funding output that uses musig2, but uses a tapscript tweak rather than a normal BIP 86 tweak.
1 parent 89cf4c2 commit 159f853

File tree

1 file changed

+43
-9
lines changed

1 file changed

+43
-9
lines changed

input/script_utils.go

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import (
1111
"github.com/btcsuite/btcd/btcec/v2/schnorr"
1212
"github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
1313
"github.com/btcsuite/btcd/btcutil"
14+
"github.com/btcsuite/btcd/chaincfg/chainhash"
1415
"github.com/btcsuite/btcd/txscript"
1516
"github.com/btcsuite/btcd/wire"
17+
"github.com/lightningnetwork/lnd/fn"
1618
"github.com/lightningnetwork/lnd/lnutils"
1719
"golang.org/x/crypto/ripemd160"
1820
)
@@ -197,27 +199,59 @@ func GenFundingPkScript(aPub, bPub []byte, amt int64) ([]byte, *wire.TxOut, erro
197199
return witnessScript, wire.NewTxOut(amt, pkScript), nil
198200
}
199201

202+
// fundingScriptOpts is a functional option that can be used to modify the way
203+
// the funding pkScript is created.
204+
type fundingScriptOpts struct {
205+
tapscriptRoot fn.Option[chainhash.Hash]
206+
}
207+
208+
// FundingScriptOpt is a functional option that can be used to modify the way
209+
// the funding script is created.
210+
type FundingScriptOpt func(*fundingScriptOpts)
211+
212+
// defaultFundingScriptOpts returns a new instance of the default
213+
// fundingScriptOpts.
214+
func defaultFundingScriptOpts() *fundingScriptOpts {
215+
return &fundingScriptOpts{}
216+
}
217+
218+
// WithTapscriptRoot is a functional option that can be used to specify the
219+
// tapscript root for a MuSig2 funding output.
220+
func WithTapscriptRoot(root chainhash.Hash) FundingScriptOpt {
221+
return func(o *fundingScriptOpts) {
222+
o.tapscriptRoot = fn.Some(root)
223+
}
224+
}
225+
200226
// GenTaprootFundingScript constructs the taproot-native funding output that
201-
// uses musig2 to create a single aggregated key to anchor the channel.
227+
// uses MuSig2 to create a single aggregated key to anchor the channel.
202228
func GenTaprootFundingScript(aPub, bPub *btcec.PublicKey,
203-
amt int64) ([]byte, *wire.TxOut, error) {
229+
amt int64, opts ...FundingScriptOpt) ([]byte, *wire.TxOut, error) {
230+
231+
options := defaultFundingScriptOpts()
232+
for _, optFunc := range opts {
233+
optFunc(options)
234+
}
235+
236+
muSig2Opt := musig2.WithBIP86KeyTweak()
237+
options.tapscriptRoot.WhenSome(func(scriptRoot chainhash.Hash) {
238+
muSig2Opt = musig2.WithTaprootKeyTweak(scriptRoot[:])
239+
})
204240

205241
// Similar to the existing p2wsh funding script, we'll always make sure
206242
// we sort the keys before any major operations. In order to ensure
207243
// that there's no other way this output can be spent, we'll use a BIP
208-
// 86 tweak here during aggregation.
209-
//
210-
// TODO(roasbeef): revisit if BIP 86 is needed here?
244+
// 86 tweak here during aggregation, unless the user has explicitly
245+
// specified a tapscript root.
211246
combinedKey, _, _, err := musig2.AggregateKeys(
212-
[]*btcec.PublicKey{aPub, bPub}, true,
213-
musig2.WithBIP86KeyTweak(),
247+
[]*btcec.PublicKey{aPub, bPub}, true, muSig2Opt,
214248
)
215249
if err != nil {
216250
return nil, nil, fmt.Errorf("unable to combine keys: %w", err)
217251
}
218252

219253
// Now that we have the combined key, we can create a taproot pkScript
220-
// from this, and then make the txout given the amount.
254+
// from this, and then make the txOut given the amount.
221255
pkScript, err := PayToTaprootScript(combinedKey.FinalKey)
222256
if err != nil {
223257
return nil, nil, fmt.Errorf("unable to make taproot "+
@@ -227,7 +261,7 @@ func GenTaprootFundingScript(aPub, bPub *btcec.PublicKey,
227261
txOut := wire.NewTxOut(amt, pkScript)
228262

229263
// For the "witness program" we just return the raw pkScript since the
230-
// output we create can _only_ be spent with a musig2 signature.
264+
// output we create can _only_ be spent with a MuSig2 signature.
231265
return pkScript, txOut, nil
232266
}
233267

0 commit comments

Comments
 (0)