mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
swap: pass in MuSig2 version when creating taproot HTLCs
This commit adds the MuSig2 version as an input parameter when creating Taproot htlcs. This will allow us to create both old and new MuSig2 Taproot HTLCs correctly.
This commit is contained in:
parent
476f47275b
commit
e8cfe4cea9
5 changed files with 73 additions and 31 deletions
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/lightninglabs/loop/loopdb"
|
||||
"github.com/lightninglabs/loop/swap"
|
||||
"github.com/lightninglabs/loop/test"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -285,6 +286,7 @@ func testLoopOutResume(t *testing.T, confs uint32, expired, preimageRevealed,
|
|||
|
||||
case swap.HtlcV3:
|
||||
htlc, err = swap.NewHtlcV3(
|
||||
input.MuSig2Version040,
|
||||
pendingSwap.Contract.CltvExpiry, senderKey,
|
||||
receiverKey, senderKey, receiverKey, hash,
|
||||
&chaincfg.TestNet3Params,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/lightninglabs/loop/swap"
|
||||
"github.com/lightninglabs/loop/test"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
invpkg "github.com/lightningnetwork/lnd/invoices"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -459,6 +460,7 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool,
|
|||
|
||||
case swap.HtlcV3:
|
||||
htlc, err = swap.NewHtlcV3(
|
||||
input.MuSig2Version040,
|
||||
contract.CltvExpiry, contract.SenderKey,
|
||||
contract.ReceiverKey, contract.SenderKey,
|
||||
contract.ReceiverKey, testPreimage.Hash(),
|
||||
|
|
|
|||
2
swap.go
2
swap.go
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/lightninglabs/lndclient"
|
||||
"github.com/lightninglabs/loop/loopdb"
|
||||
"github.com/lightninglabs/loop/swap"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
)
|
||||
|
||||
|
|
@ -82,6 +83,7 @@ func GetHtlc(hash lntypes.Hash, contract *loopdb.SwapContract,
|
|||
|
||||
case swap.HtlcV3:
|
||||
return swap.NewHtlcV3(
|
||||
input.MuSig2Version040,
|
||||
contract.CltvExpiry, contract.SenderKey,
|
||||
contract.ReceiverKey, contract.SenderKey,
|
||||
contract.ReceiverKey, hash,
|
||||
|
|
|
|||
79
swap/htlc.go
79
swap/htlc.go
|
|
@ -122,8 +122,8 @@ var (
|
|||
// QuoteHtlcP2TR is a template script just used for sweep fee
|
||||
// estimation.
|
||||
QuoteHtlcP2TR, _ = NewHtlcV3(
|
||||
^int32(0), dummyPubKey, dummyPubKey, dummyPubKey, dummyPubKey,
|
||||
quoteHash, &chaincfg.MainNetParams,
|
||||
input.MuSig2Version100RC2, ^int32(0), dummyPubKey, dummyPubKey,
|
||||
dummyPubKey, dummyPubKey, quoteHash, &chaincfg.MainNetParams,
|
||||
)
|
||||
|
||||
// ErrInvalidScriptVersion is returned when an unknown htlc version
|
||||
|
|
@ -188,13 +188,13 @@ func NewHtlcV2(cltvExpiry int32, senderKey, receiverKey [33]byte,
|
|||
|
||||
// NewHtlcV3 returns a new V3 HTLC (P2TR) instance. Internal pubkey generated
|
||||
// by both participants must be provided.
|
||||
func NewHtlcV3(cltvExpiry int32, senderInternalKey, receiverInternalKey,
|
||||
senderKey, receiverKey [33]byte, hash lntypes.Hash,
|
||||
chainParams *chaincfg.Params) (*Htlc, error) {
|
||||
func NewHtlcV3(muSig2Version input.MuSig2Version, cltvExpiry int32,
|
||||
senderInternalKey, receiverInternalKey, senderKey, receiverKey [33]byte,
|
||||
hash lntypes.Hash, chainParams *chaincfg.Params) (*Htlc, error) {
|
||||
|
||||
htlc, err := newHTLCScriptV3(
|
||||
cltvExpiry, senderInternalKey, receiverInternalKey,
|
||||
senderKey, receiverKey, hash,
|
||||
muSig2Version, cltvExpiry, senderInternalKey,
|
||||
receiverInternalKey, senderKey, receiverKey, hash,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -504,17 +504,37 @@ type HtlcScriptV3 struct {
|
|||
RootHash chainhash.Hash
|
||||
}
|
||||
|
||||
// newHTLCScriptV3 constructs a HtlcScipt with the HTLC V3 taproot script.
|
||||
func newHTLCScriptV3(cltvExpiry int32, senderInternalKey, receiverInternalKey,
|
||||
senderHtlcKey, receiverHtlcKey [33]byte,
|
||||
swapHash lntypes.Hash) (*HtlcScriptV3, error) {
|
||||
// parsePubKey will parse a serialized public key into a btcec.PublicKey
|
||||
// depending on the passed MuSig2 version.
|
||||
func parsePubKey(muSig2Version input.MuSig2Version, key [33]byte) (
|
||||
*btcec.PublicKey, error) {
|
||||
|
||||
senderPubKey, err := schnorr.ParsePubKey(senderHtlcKey[1:])
|
||||
// Make sure that we have the correct public keys depending on the
|
||||
// MuSig2 version.
|
||||
switch muSig2Version {
|
||||
case input.MuSig2Version100RC2:
|
||||
return btcec.ParsePubKey(key[:])
|
||||
|
||||
case input.MuSig2Version040:
|
||||
return schnorr.ParsePubKey(key[1:])
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported MuSig2 version: %v",
|
||||
muSig2Version)
|
||||
}
|
||||
}
|
||||
|
||||
// newHTLCScriptV3 constructs a HtlcScipt with the HTLC V3 taproot script.
|
||||
func newHTLCScriptV3(muSig2Version input.MuSig2Version, cltvExpiry int32,
|
||||
senderInternalKey, receiverInternalKey, senderHtlcKey,
|
||||
receiverHtlcKey [33]byte, swapHash lntypes.Hash) (*HtlcScriptV3, error) {
|
||||
|
||||
senderPubKey, err := parsePubKey(muSig2Version, senderHtlcKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
receiverPubKey, err := schnorr.ParsePubKey(receiverHtlcKey[1:])
|
||||
receiverPubKey, err := parsePubKey(muSig2Version, receiverHtlcKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -548,38 +568,41 @@ func newHTLCScriptV3(cltvExpiry int32, senderInternalKey, receiverInternalKey,
|
|||
// Parse the pub keys used in the internal aggregate key. They are
|
||||
// optional and may just be the same keys that are used for the script
|
||||
// paths.
|
||||
senderInternalPubKey, err := schnorr.ParsePubKey(senderInternalKey[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
receiverInternalPubKey, err := schnorr.ParsePubKey(
|
||||
receiverInternalKey[1:],
|
||||
senderInternalPubKey, err := parsePubKey(
|
||||
muSig2Version, senderInternalKey,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
receiverInternalPubKey, err := parsePubKey(
|
||||
muSig2Version, receiverInternalKey,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var aggregateKey *musig2.AggregateKey
|
||||
// Calculate the internal aggregate key.
|
||||
aggregateKey, _, _, err := musig2.AggregateKeys(
|
||||
aggregateKey, err = input.MuSig2CombineKeys(
|
||||
muSig2Version,
|
||||
[]*btcec.PublicKey{
|
||||
senderInternalPubKey, receiverInternalPubKey,
|
||||
}, true,
|
||||
},
|
||||
true,
|
||||
&input.MuSig2Tweaks{
|
||||
TaprootTweak: rootHash[:],
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Calculate top level taproot key.
|
||||
taprootKey := txscript.ComputeTaprootOutputKey(
|
||||
aggregateKey.PreTweakedKey, rootHash[:],
|
||||
)
|
||||
|
||||
return &HtlcScriptV3{
|
||||
timeoutScript: timeoutPathScript,
|
||||
successScript: successPathScript,
|
||||
InternalPubKey: aggregateKey.PreTweakedKey,
|
||||
TaprootKey: taprootKey,
|
||||
TaprootKey: aggregateKey.FinalKey,
|
||||
RootHash: rootHash,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -335,6 +335,19 @@ func TestHtlcV2(t *testing.T) {
|
|||
|
||||
// TestHtlcV3 tests the HTLC V3 script success and timeout spend cases.
|
||||
func TestHtlcV3(t *testing.T) {
|
||||
versions := map[string]input.MuSig2Version{
|
||||
"MuSig2 0.4": input.MuSig2Version040,
|
||||
"MuSig2 1.0RC2": input.MuSig2Version100RC2,
|
||||
}
|
||||
|
||||
for name, version := range versions {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
testHtlcV3(t, version)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testHtlcV3(t *testing.T, muSig2Version input.MuSig2Version) {
|
||||
var (
|
||||
receiverKey [33]byte
|
||||
senderKey [33]byte
|
||||
|
|
@ -355,8 +368,8 @@ func TestHtlcV3(t *testing.T) {
|
|||
copy(senderKey[:], senderPubKey.SerializeCompressed())
|
||||
|
||||
htlc, err := NewHtlcV3(
|
||||
cltvExpiry, senderKey, receiverKey, senderKey, receiverKey,
|
||||
hashedPreimage, &chaincfg.MainNetParams,
|
||||
muSig2Version, cltvExpiry, senderKey, receiverKey, senderKey,
|
||||
receiverKey, hashedPreimage, &chaincfg.MainNetParams,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
@ -538,7 +551,7 @@ func TestHtlcV3(t *testing.T) {
|
|||
)
|
||||
|
||||
htlc, err := NewHtlcV3(
|
||||
cltvExpiry, senderKey,
|
||||
muSig2Version, cltvExpiry, senderKey,
|
||||
receiverKey, bogusKeyBytes, receiverKey,
|
||||
hashedPreimage, &chaincfg.MainNetParams,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue