From da4bcbea10fd646e1d04f0238a6fdbd873460117 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Thu, 5 Jan 2023 18:16:05 +0100 Subject: [PATCH] loopdb: refactor the SwapContract to hold all HTLC keys This commit adds a new struct to hold all HTLC keys and refactors the SwapContract which is used by both loopin and loopout swaps to use this new struct. The newly added internal keys will for now hold the script keys to keep everything equivalent but are already stored and read back if the protocol version is set to MuSig2. --- client_test.go | 8 +- loopdb/loop.go | 39 ++++++--- loopdb/loopin.go | 8 +- loopdb/loopout.go | 8 +- loopdb/protocol_version.go | 2 +- loopdb/store.go | 172 ++++++++++++++++++++++++++++--------- loopdb/store_test.go | 48 ++++++++--- loopin.go | 29 ++++--- loopin_test.go | 24 ++++-- loopout.go | 36 ++++---- swap.go | 14 +-- 11 files changed, 273 insertions(+), 115 deletions(-) diff --git a/client_test.go b/client_test.go index 8539a88..ba3ff6e 100644 --- a/client_test.go +++ b/client_test.go @@ -240,8 +240,12 @@ func testLoopOutResume(t *testing.T, confs uint32, expired, preimageRevealed, Preimage: preimage, AmountRequested: amt, CltvExpiry: 744, - ReceiverKey: receiverKey, - SenderKey: senderKey, + HtlcKeys: loopdb.HtlcKeys{ + SenderScriptKey: senderKey, + SenderInternalPubKey: senderKey, + ReceiverScriptKey: receiverKey, + ReceiverInternalPubKey: receiverKey, + }, MaxSwapFee: 60000, MaxMinerFee: 50000, ProtocolVersion: protocolVersion, diff --git a/loopdb/loop.go b/loopdb/loop.go index e98745f..867476b 100644 --- a/loopdb/loop.go +++ b/loopdb/loop.go @@ -10,6 +10,31 @@ import ( "github.com/lightningnetwork/lnd/lntypes" ) +// HtlcKeys is a holder of all keys used when constructing the swap HTLC. Since +// it's used for both loop in and loop out swaps it may hold partial information +// about the sender or receiver depending on the swap type. +type HtlcKeys struct { + // SenderScriptKey is the sender's public key that is used in the HTLC, + // specifically when constructing the script spend scripts. + SenderScriptKey [33]byte + + // SenderInternalPubKey is the sender's internal pubkey that is used in + // taproot HTLCs as part of the aggregate internal key. + SenderInternalPubKey [33]byte + + // ReceiverScriptKey is the receiver's public key that is used in the + // HTLC, specifically when constructing the script spend scripts. + ReceiverScriptKey [33]byte + + // ReceiverInternalPubKey is the sender's internal pubkey that is used + // in taproot HTLCs as part of the aggregate internal key. + ReceiverInternalPubKey [33]byte + + // ClientScriptKeyLocator is the client's key locator for the key used + // in the HTLC script spend scripts. + ClientScriptKeyLocator keychain.KeyLocator +} + // SwapContract contains the base data that is serialized to persistent storage // for pending swaps. type SwapContract struct { @@ -19,18 +44,8 @@ type SwapContract struct { // AmountRequested is the total amount of the swap. AmountRequested btcutil.Amount - // SenderKey is the key of the sender that will be used in the on-chain - // HTLC. - SenderKey [33]byte - - // ReceiverKey is the of the receiver that will be used in the on-chain - // HTLC. - ReceiverKey [33]byte - - // ClientKeyLocator is the key locator (family and index) for the client - // key. It is for the receiver key if this is a loop out contract, or - // the sender key if this is a loop in contract. - ClientKeyLocator keychain.KeyLocator + // HtlcKeys holds all keys used in the swap HTLC construction. + HtlcKeys HtlcKeys // CltvExpiry is the total absolute CLTV expiry of the swap. CltvExpiry int32 diff --git a/loopdb/loopin.go b/loopdb/loopin.go index 7a665e2..e10e898 100644 --- a/loopdb/loopin.go +++ b/loopdb/loopin.go @@ -63,7 +63,7 @@ func serializeLoopInContract(swap *LoopInContract) ( return nil, err } - n, err := b.Write(swap.SenderKey[:]) + n, err := b.Write(swap.HtlcKeys.SenderScriptKey[:]) if err != nil { return nil, err } @@ -71,7 +71,7 @@ func serializeLoopInContract(swap *LoopInContract) ( return nil, fmt.Errorf("sender key has invalid length") } - n, err = b.Write(swap.ReceiverKey[:]) + n, err = b.Write(swap.HtlcKeys.ReceiverScriptKey[:]) if err != nil { return nil, err } @@ -161,7 +161,7 @@ func deserializeLoopInContract(value []byte) (*LoopInContract, error) { return nil, err } - n, err := r.Read(contract.SenderKey[:]) + n, err := r.Read(contract.HtlcKeys.SenderScriptKey[:]) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func deserializeLoopInContract(value []byte) (*LoopInContract, error) { return nil, fmt.Errorf("sender key has invalid length") } - n, err = r.Read(contract.ReceiverKey[:]) + n, err = r.Read(contract.HtlcKeys.ReceiverScriptKey[:]) if err != nil { return nil, err } diff --git a/loopdb/loopout.go b/loopdb/loopout.go index ad628a9..9ebb858 100644 --- a/loopdb/loopout.go +++ b/loopdb/loopout.go @@ -134,7 +134,7 @@ func deserializeLoopOutContract(value []byte, chainParams *chaincfg.Params) ( return nil, err } - n, err := r.Read(contract.SenderKey[:]) + n, err := r.Read(contract.HtlcKeys.SenderScriptKey[:]) if err != nil { return nil, err } @@ -142,7 +142,7 @@ func deserializeLoopOutContract(value []byte, chainParams *chaincfg.Params) ( return nil, fmt.Errorf("sender key has invalid length") } - n, err = r.Read(contract.ReceiverKey[:]) + n, err = r.Read(contract.HtlcKeys.ReceiverScriptKey[:]) if err != nil { return nil, err } @@ -229,7 +229,7 @@ func serializeLoopOutContract(swap *LoopOutContract) ( return nil, err } - n, err := b.Write(swap.SenderKey[:]) + n, err := b.Write(swap.HtlcKeys.SenderScriptKey[:]) if err != nil { return nil, err } @@ -237,7 +237,7 @@ func serializeLoopOutContract(swap *LoopOutContract) ( return nil, fmt.Errorf("sender key has invalid length") } - n, err = b.Write(swap.ReceiverKey[:]) + n, err = b.Write(swap.HtlcKeys.ReceiverScriptKey[:]) if err != nil { return nil, err } diff --git a/loopdb/protocol_version.go b/loopdb/protocol_version.go index 2e95eca..a9fdee8 100644 --- a/loopdb/protocol_version.go +++ b/loopdb/protocol_version.go @@ -68,7 +68,7 @@ const ( // experimentalRPCProtocolVersion defines the RPC protocol version that // includes all currently experimentally released features. - experimentalRPCProtocolVersion = looprpc.ProtocolVersion_HTLC_V3 + experimentalRPCProtocolVersion = looprpc.ProtocolVersion_MUSIG2 ) var ( diff --git a/loopdb/store.go b/loopdb/store.go index b86008d..63b4be4 100644 --- a/loopdb/store.go +++ b/loopdb/store.go @@ -112,9 +112,30 @@ var ( // value: concatenation of uint32 values [family, index]. keyLocatorKey = []byte("keylocator") + // senderInternalPubKeyKey is the key that stores the sender's internal + // public key which used when constructing the swap HTLC. + // + // path: loopInBucket/loopOutBucket -> swapBucket[hash] + // -> senderInternalPubKeyKey + // value: serialized public key. + senderInternalPubKeyKey = []byte("sender-internal-pubkey") + + // receiverInternalPubKeyKey is the key that stores the receiver's + // internal public key which is used when constructing the swap HTLC. + // + // path: loopInBucket/loopOutBucket -> swapBucket[hash] + // -> receiverInternalPubKeyKey + // value: serialized public key. + receiverInternalPubKeyKey = []byte("receiver-internal-pubkey") + byteOrder = binary.BigEndian + // keyLength is the length of a serialized public key. keyLength = 33 + + // errInvalidKey is returned when a serialized key is not the expected + // length. + errInvalidKey = fmt.Errorf("invalid serialized key") ) const ( @@ -233,6 +254,95 @@ func NewBoltSwapStore(dbPath string, chainParams *chaincfg.Params) ( }, nil } +// marshalHtlcKeys marshals the HTLC keys of the swap contract into the swap +// bucket. +func marshalHtlcKeys(swapBucket *bbolt.Bucket, contract *SwapContract) error { + var err error + + // Store the key locator for swaps that use taproot HTLCs. + if contract.ProtocolVersion >= ProtocolVersionHtlcV3 { + keyLocator, err := MarshalKeyLocator( + contract.HtlcKeys.ClientScriptKeyLocator, + ) + if err != nil { + return err + } + + err = swapBucket.Put(keyLocatorKey, keyLocator) + if err != nil { + return err + } + } + + // Store the internal keys for MuSig2 swaps. + if contract.ProtocolVersion >= ProtocolVersionMuSig2 { + // Internal pubkeys are always filled. + err = swapBucket.Put( + senderInternalPubKeyKey, + contract.HtlcKeys.SenderInternalPubKey[:], + ) + if err != nil { + return err + } + + err = swapBucket.Put( + receiverInternalPubKeyKey, + contract.HtlcKeys.ReceiverInternalPubKey[:], + ) + if err != nil { + return err + } + } + + return nil +} + +// unmarshalHtlcKeys deserializes the htlc keys from the swap bucket. +func unmarshalHtlcKeys(swapBucket *bbolt.Bucket, contract *SwapContract) error { + var err error + + // HTLC V3 contracts have the client script key locator stored. + if contract.ProtocolVersion >= ProtocolVersionHtlcV3 && + ProtocolVersionUnrecorded > contract.ProtocolVersion { + + contract.HtlcKeys.ClientScriptKeyLocator, err = + UnmarshalKeyLocator( + swapBucket.Get(keyLocatorKey), + ) + if err != nil { + return err + } + + // Default the internal scriptkeys to the sender and receiver + // keys. + contract.HtlcKeys.SenderInternalPubKey = + contract.HtlcKeys.SenderScriptKey + contract.HtlcKeys.ReceiverInternalPubKey = + contract.HtlcKeys.ReceiverScriptKey + } + + // MuSig2 contracts have the internal keys stored too. + if contract.ProtocolVersion >= ProtocolVersionMuSig2 && + ProtocolVersionUnrecorded > contract.ProtocolVersion { + + // The pubkeys used for the joint HTLC internal key are always + // present. + key := swapBucket.Get(senderInternalPubKeyKey) + if len(key) != keyLength { + return errInvalidKey + } + copy(contract.HtlcKeys.SenderInternalPubKey[:], key) + + key = swapBucket.Get(receiverInternalPubKeyKey) + if len(key) != keyLength { + return errInvalidKey + } + copy(contract.HtlcKeys.ReceiverInternalPubKey[:], key) + } + + return nil +} + // FetchLoopOutSwaps returns all loop out swaps currently in the store. // // NOTE: Part of the loopdb.SwapStore interface. @@ -435,19 +545,10 @@ func (s *boltSwapStore) CreateLoopOut(hash lntypes.Hash, return err } - // Store the key locator for swaps with taproot htlc. - if swap.ProtocolVersion >= ProtocolVersionHtlcV3 { - keyLocator, err := MarshalKeyLocator( - swap.ClientKeyLocator, - ) - if err != nil { - return err - } - - err = swapBucket.Put(keyLocatorKey, keyLocator) - if err != nil { - return err - } + // Store the htlc keys and server key locator. + err = marshalHtlcKeys(swapBucket, &swap.SwapContract) + if err != nil { + return err } // Finally, we'll create an empty updates bucket for this swap @@ -501,19 +602,10 @@ func (s *boltSwapStore) CreateLoopIn(hash lntypes.Hash, return err } - // Store the key locator for swaps with taproot htlc. - if swap.ProtocolVersion >= ProtocolVersionHtlcV3 { - keyLocator, err := MarshalKeyLocator( - swap.ClientKeyLocator, - ) - if err != nil { - return err - } - - err = swapBucket.Put(keyLocatorKey, keyLocator) - if err != nil { - return err - } + // Store the htlc keys and server key locator. + err = marshalHtlcKeys(swapBucket, &swap.SwapContract) + if err != nil { + return err } // Finally, we'll create an empty updates bucket for this swap @@ -788,14 +880,12 @@ func (s *boltSwapStore) fetchLoopOutSwap(rootBucket *bbolt.Bucket, return nil, err } - // Try to unmarshal the key locator. - if contract.ProtocolVersion >= ProtocolVersionHtlcV3 { - contract.ClientKeyLocator, err = UnmarshalKeyLocator( - swapBucket.Get(keyLocatorKey), - ) - if err != nil { - return nil, err - } + // Unmarshal HTLC keys if the contract is recent. + err = unmarshalHtlcKeys( + swapBucket, &contract.SwapContract, + ) + if err != nil { + return nil, err } loop := LoopOut{ @@ -865,14 +955,12 @@ func (s *boltSwapStore) fetchLoopInSwap(rootBucket *bbolt.Bucket, return nil, err } - // Try to unmarshal the key locator. - if contract.ProtocolVersion >= ProtocolVersionHtlcV3 { - contract.ClientKeyLocator, err = UnmarshalKeyLocator( - swapBucket.Get(keyLocatorKey), - ) - if err != nil { - return nil, err - } + // Unmarshal HTLC keys if the contract is recent. + err = unmarshalHtlcKeys( + swapBucket, &contract.SwapContract, + ) + if err != nil { + return nil, err } loop := LoopIn{ diff --git a/loopdb/store_test.go b/loopdb/store_test.go index 8d2602c..324e965 100644 --- a/loopdb/store_test.go +++ b/loopdb/store_test.go @@ -12,6 +12,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/coreos/bbolt" "github.com/lightninglabs/loop/test" + "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/routing/route" "github.com/stretchr/testify/require" @@ -28,6 +29,16 @@ var ( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, } + senderInternalKey = [33]byte{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, + } + + receiverInternalKey = [33]byte{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, + } + testPreimage = lntypes.Preimage([32]byte{ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, @@ -51,9 +62,16 @@ func TestLoopOutStore(t *testing.T) { AmountRequested: 100, Preimage: testPreimage, CltvExpiry: 144, - SenderKey: senderKey, - - ReceiverKey: receiverKey, + HtlcKeys: HtlcKeys{ + SenderScriptKey: senderKey, + ReceiverScriptKey: receiverKey, + SenderInternalPubKey: senderInternalKey, + ReceiverInternalPubKey: receiverInternalKey, + ClientScriptKeyLocator: keychain.KeyLocator{ + Family: 1, + Index: 2, + }, + }, MaxMinerFee: 10, MaxSwapFee: 20, @@ -61,7 +79,8 @@ func TestLoopOutStore(t *testing.T) { // Convert to/from unix to remove timezone, so that it // doesn't interfere with DeepEqual. - InitiationTime: time.Unix(0, initiationTime.UnixNano()), + InitiationTime: time.Unix(0, initiationTime.UnixNano()), + ProtocolVersion: ProtocolVersionMuSig2, }, MaxPrepayRoutingFee: 40, PrepayInvoice: "prepayinvoice", @@ -195,18 +214,27 @@ func TestLoopInStore(t *testing.T) { pendingSwap := LoopInContract{ SwapContract: SwapContract{ - AmountRequested: 100, - Preimage: testPreimage, - CltvExpiry: 144, - SenderKey: senderKey, - ReceiverKey: receiverKey, + AmountRequested: 100, + Preimage: testPreimage, + CltvExpiry: 144, + HtlcKeys: HtlcKeys{ + SenderScriptKey: senderKey, + ReceiverScriptKey: receiverKey, + SenderInternalPubKey: senderInternalKey, + ReceiverInternalPubKey: receiverInternalKey, + ClientScriptKeyLocator: keychain.KeyLocator{ + Family: 1, + Index: 2, + }, + }, MaxMinerFee: 10, MaxSwapFee: 20, InitiationHeight: 99, // Convert to/from unix to remove timezone, so that it // doesn't interfere with DeepEqual. - InitiationTime: time.Unix(0, initiationTime.UnixNano()), + InitiationTime: time.Unix(0, initiationTime.UnixNano()), + ProtocolVersion: ProtocolVersionMuSig2, }, HtlcConfTarget: 2, LastHop: &lastHop, diff --git a/loopin.go b/loopin.go index ae0c697..c329725 100644 --- a/loopin.go +++ b/loopin.go @@ -237,16 +237,20 @@ func newLoopInSwap(globalCtx context.Context, cfg *swapConfig, SwapContract: loopdb.SwapContract{ InitiationHeight: currentHeight, InitiationTime: initiationTime, - ReceiverKey: swapResp.receiverKey, - SenderKey: senderKey, - ClientKeyLocator: keyDesc.KeyLocator, - Preimage: swapPreimage, - AmountRequested: request.Amount, - CltvExpiry: swapResp.expiry, - MaxMinerFee: request.MaxMinerFee, - MaxSwapFee: request.MaxSwapFee, - Label: request.Label, - ProtocolVersion: loopdb.CurrentProtocolVersion(), + HtlcKeys: loopdb.HtlcKeys{ + SenderScriptKey: senderKey, + SenderInternalPubKey: senderKey, + ReceiverScriptKey: swapResp.receiverKey, + ReceiverInternalPubKey: swapResp.receiverKey, + ClientScriptKeyLocator: keyDesc.KeyLocator, + }, + Preimage: swapPreimage, + AmountRequested: request.Amount, + CltvExpiry: swapResp.expiry, + MaxMinerFee: request.MaxMinerFee, + MaxSwapFee: request.MaxSwapFee, + Label: request.Label, + ProtocolVersion: loopdb.CurrentProtocolVersion(), }, } @@ -975,8 +979,9 @@ func (s *loopInSwap) publishTimeoutTx(ctx context.Context, sequence := uint32(0) timeoutTx, err := s.sweeper.CreateSweepTx( - ctx, s.height, sequence, s.htlc, *htlcOutpoint, s.SenderKey, - redeemScript, witnessFunc, htlcValue, fee, s.timeoutAddr, + ctx, s.height, sequence, s.htlc, *htlcOutpoint, + s.HtlcKeys.SenderScriptKey, redeemScript, witnessFunc, + htlcValue, fee, s.timeoutAddr, ) if err != nil { return 0, err diff --git a/loopin_test.go b/loopin_test.go index 7bf3b8f..ca3b707 100644 --- a/loopin_test.go +++ b/loopin_test.go @@ -343,6 +343,7 @@ func TestLoopInResume(t *testing.T) { loopdb.ProtocolVersionUnrecorded, loopdb.ProtocolVersionHtlcV2, loopdb.ProtocolVersionHtlcV3, + loopdb.ProtocolVersionMuSig2, } testCases := []struct { @@ -414,8 +415,12 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool, Preimage: testPreimage, AmountRequested: 100000, CltvExpiry: 744, - ReceiverKey: receiverKey, - SenderKey: senderKey, + HtlcKeys: loopdb.HtlcKeys{ + SenderScriptKey: senderKey, + SenderInternalPubKey: senderKey, + ReceiverScriptKey: receiverKey, + ReceiverInternalPubKey: receiverKey, + }, MaxSwapFee: 60000, MaxMinerFee: 50000, ProtocolVersion: storedVersion, @@ -453,17 +458,22 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool, switch GetHtlcScriptVersion(storedVersion) { case swap.HtlcV2: htlc, err = swap.NewHtlcV2( - contract.CltvExpiry, contract.SenderKey, - contract.ReceiverKey, testPreimage.Hash(), + contract.CltvExpiry, + contract.HtlcKeys.SenderScriptKey, + contract.HtlcKeys.ReceiverScriptKey, + testPreimage.Hash(), cfg.lnd.ChainParams, ) case swap.HtlcV3: htlc, err = swap.NewHtlcV3( input.MuSig2Version040, - contract.CltvExpiry, contract.SenderKey, - contract.ReceiverKey, contract.SenderKey, - contract.ReceiverKey, testPreimage.Hash(), + contract.CltvExpiry, + contract.HtlcKeys.SenderInternalPubKey, + contract.HtlcKeys.ReceiverInternalPubKey, + contract.HtlcKeys.SenderScriptKey, + contract.HtlcKeys.ReceiverScriptKey, + testPreimage.Hash(), cfg.lnd.ChainParams, ) diff --git a/loopout.go b/loopout.go index 00654fe..ff9bd92 100644 --- a/loopout.go +++ b/loopout.go @@ -181,16 +181,20 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig, SwapContract: loopdb.SwapContract{ InitiationHeight: currentHeight, InitiationTime: initiationTime, - SenderKey: swapResp.senderKey, - ReceiverKey: receiverKey, - ClientKeyLocator: keyDesc.KeyLocator, - Preimage: swapPreimage, - AmountRequested: request.Amount, - CltvExpiry: request.Expiry, - MaxMinerFee: request.MaxMinerFee, - MaxSwapFee: request.MaxSwapFee, - Label: request.Label, - ProtocolVersion: loopdb.CurrentProtocolVersion(), + HtlcKeys: loopdb.HtlcKeys{ + SenderScriptKey: swapResp.senderKey, + SenderInternalPubKey: swapResp.senderKey, + ReceiverScriptKey: receiverKey, + ReceiverInternalPubKey: receiverKey, + ClientScriptKeyLocator: keyDesc.KeyLocator, + }, + Preimage: swapPreimage, + AmountRequested: request.Amount, + CltvExpiry: request.Expiry, + MaxMinerFee: request.MaxMinerFee, + MaxSwapFee: request.MaxSwapFee, + Label: request.Label, + ProtocolVersion: loopdb.CurrentProtocolVersion(), }, OutgoingChanSet: chanSet, } @@ -1352,7 +1356,8 @@ func (s *loopOutSwap) createMuSig2SweepTxn( } signers := [][]byte{ - s.SenderKey[1:], s.ReceiverKey[1:], + s.HtlcKeys.SenderInternalPubKey[1:], + s.HtlcKeys.ReceiverInternalPubKey[1:], } htlc, ok := s.htlc.HtlcScript.(*swap.HtlcScriptV3) @@ -1363,8 +1368,9 @@ func (s *loopOutSwap) createMuSig2SweepTxn( // Now we're creating a local MuSig2 session using the receiver key's // key locator and the htlc's root hash. musig2SessionInfo, err := s.lnd.Signer.MuSig2CreateSession( - ctx, input.MuSig2Version040, &s.ClientKeyLocator, - signers, lndclient.MuSig2TaprootTweakOpt(htlc.RootHash[:], false), + ctx, input.MuSig2Version040, + &s.HtlcKeys.ClientScriptKeyLocator, signers, + lndclient.MuSig2TaprootTweakOpt(htlc.RootHash[:], false), ) if err != nil { return nil, err @@ -1609,8 +1615,8 @@ func (s *loopOutSwap) sweep(ctx context.Context, htlcOutpoint wire.OutPoint, // Create sweep tx. sweepTx, err := s.sweeper.CreateSweepTx( ctx, s.height, s.htlc.SuccessSequence(), s.htlc, - htlcOutpoint, s.ReceiverKey, redeemScript, witnessFunc, - htlcValue, fee, s.DestAddr, + htlcOutpoint, s.contract.HtlcKeys.ReceiverScriptKey, + redeemScript, witnessFunc, htlcValue, fee, s.DestAddr, ) if err != nil { return err diff --git a/swap.go b/swap.go index 6e2d947..caa5d21 100644 --- a/swap.go +++ b/swap.go @@ -76,18 +76,20 @@ func GetHtlc(hash lntypes.Hash, contract *loopdb.SwapContract, switch GetHtlcScriptVersion(contract.ProtocolVersion) { case swap.HtlcV2: return swap.NewHtlcV2( - contract.CltvExpiry, contract.SenderKey, - contract.ReceiverKey, hash, + contract.CltvExpiry, contract.HtlcKeys.SenderScriptKey, + contract.HtlcKeys.ReceiverScriptKey, hash, chainParams, ) case swap.HtlcV3: return swap.NewHtlcV3( input.MuSig2Version040, - contract.CltvExpiry, contract.SenderKey, - contract.ReceiverKey, contract.SenderKey, - contract.ReceiverKey, hash, - chainParams, + contract.CltvExpiry, + contract.HtlcKeys.SenderInternalPubKey, + contract.HtlcKeys.ReceiverInternalPubKey, + contract.HtlcKeys.SenderScriptKey, + contract.HtlcKeys.ReceiverScriptKey, + hash, chainParams, ) }