utils: add htlc & swap related helpers

pull/634/head
George Tsagkarelis 6 months ago
parent a9be69b281
commit b43fa11cc1
No known key found for this signature in database
GPG Key ID: E08DEA9B12B66AF6

@ -17,6 +17,7 @@ import (
"github.com/lightninglabs/loop/loopdb" "github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/swap" "github.com/lightninglabs/loop/swap"
"github.com/lightninglabs/loop/sweep" "github.com/lightninglabs/loop/sweep"
"github.com/lightninglabs/loop/utils"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/routing/route"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -232,7 +233,7 @@ func (s *Client) FetchSwaps(ctx context.Context) ([]*SwapInfo, error) {
LastUpdate: swp.LastUpdateTime(), LastUpdate: swp.LastUpdateTime(),
} }
htlc, err := GetHtlc( htlc, err := utils.GetHtlc(
swp.Hash, &swp.Contract.SwapContract, swp.Hash, &swp.Contract.SwapContract,
s.lndServices.ChainParams, s.lndServices.ChainParams,
) )
@ -265,7 +266,7 @@ func (s *Client) FetchSwaps(ctx context.Context) ([]*SwapInfo, error) {
LastUpdate: swp.LastUpdateTime(), LastUpdate: swp.LastUpdateTime(),
} }
htlc, err := GetHtlc( htlc, err := utils.GetHtlc(
swp.Hash, &swp.Contract.SwapContract, swp.Hash, &swp.Contract.SwapContract,
s.lndServices.ChainParams, s.lndServices.ChainParams,
) )
@ -540,7 +541,7 @@ func (s *Client) getLoopOutSweepFee(ctx context.Context, confTarget int32) (
return 0, err return 0, err
} }
scriptVersion := GetHtlcScriptVersion( scriptVersion := utils.GetHtlcScriptVersion(
loopdb.CurrentProtocolVersion(), loopdb.CurrentProtocolVersion(),
) )
@ -731,7 +732,7 @@ func (s *Client) estimateFee(ctx context.Context, amt btcutil.Amount,
// Generate a dummy address for fee estimation. // Generate a dummy address for fee estimation.
witnessProg := [32]byte{} witnessProg := [32]byte{}
scriptVersion := GetHtlcScriptVersion( scriptVersion := utils.GetHtlcScriptVersion(
loopdb.CurrentProtocolVersion(), loopdb.CurrentProtocolVersion(),
) )

@ -8,6 +8,7 @@ import (
"github.com/lightninglabs/lndclient" "github.com/lightninglabs/lndclient"
"github.com/lightninglabs/loop" "github.com/lightninglabs/loop"
"github.com/lightninglabs/loop/loopdb" "github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/utils"
) )
// view prints all swaps currently in the database. // view prints all swaps currently in the database.
@ -56,7 +57,7 @@ func viewOut(swapClient *loop.Client, chainParams *chaincfg.Params) error {
for _, s := range swaps { for _, s := range swaps {
s := s s := s
htlc, err := loop.GetHtlc( htlc, err := utils.GetHtlc(
s.Hash, &s.Contract.SwapContract, chainParams, s.Hash, &s.Contract.SwapContract, chainParams,
) )
if err != nil { if err != nil {
@ -107,7 +108,7 @@ func viewIn(swapClient *loop.Client, chainParams *chaincfg.Params) error {
for _, s := range swaps { for _, s := range swaps {
s := s s := s
htlc, err := loop.GetHtlc( htlc, err := utils.GetHtlc(
s.Hash, &s.Contract.SwapContract, chainParams, s.Hash, &s.Contract.SwapContract, chainParams,
) )
if err != nil { if err != nil {

@ -18,6 +18,7 @@ import (
"github.com/lightninglabs/loop/labels" "github.com/lightninglabs/loop/labels"
"github.com/lightninglabs/loop/loopdb" "github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/swap" "github.com/lightninglabs/loop/swap"
"github.com/lightninglabs/loop/utils"
"github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs"
invpkg "github.com/lightningnetwork/lnd/invoices" invpkg "github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
@ -442,7 +443,7 @@ func validateLoopInContract(height int32, response *newLoopInResponse) error {
// initHtlcs creates and updates the native and nested segwit htlcs of the // initHtlcs creates and updates the native and nested segwit htlcs of the
// loopInSwap. // loopInSwap.
func (s *loopInSwap) initHtlcs() error { func (s *loopInSwap) initHtlcs() error {
htlc, err := GetHtlc( htlc, err := utils.GetHtlc(
s.hash, &s.SwapContract, s.swapKit.lnd.ChainParams, s.hash, &s.SwapContract, s.swapKit.lnd.ChainParams,
) )
if err != nil { if err != nil {

@ -22,12 +22,12 @@ import (
"github.com/lightninglabs/loop/loopdb" "github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/swap" "github.com/lightninglabs/loop/swap"
"github.com/lightninglabs/loop/sweep" "github.com/lightninglabs/loop/sweep"
"github.com/lightninglabs/loop/utils"
"github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/zpay32"
) )
const ( const (
@ -207,7 +207,7 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
swapKit.lastUpdateTime = initiationTime swapKit.lastUpdateTime = initiationTime
// Create the htlc. // Create the htlc.
htlc, err := GetHtlc( htlc, err := utils.GetHtlc(
swapKit.hash, swapKit.contract, swapKit.lnd.ChainParams, swapKit.hash, swapKit.contract, swapKit.lnd.ChainParams,
) )
if err != nil { if err != nil {
@ -220,7 +220,9 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
// Obtain the payment addr since we'll need it later for routing plugin // Obtain the payment addr since we'll need it later for routing plugin
// recommendation and possibly for cancel. // recommendation and possibly for cancel.
paymentAddr, err := obtainSwapPaymentAddr(contract.SwapInvoice, cfg) paymentAddr, err := utils.ObtainSwapPaymentAddr(
contract.SwapInvoice, cfg.lnd.ChainParams,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -263,7 +265,7 @@ func resumeLoopOutSwap(cfg *swapConfig, pend *loopdb.LoopOut,
) )
// Create the htlc. // Create the htlc.
htlc, err := GetHtlc( htlc, err := utils.GetHtlc(
swapKit.hash, swapKit.contract, swapKit.lnd.ChainParams, swapKit.hash, swapKit.contract, swapKit.lnd.ChainParams,
) )
if err != nil { if err != nil {
@ -275,8 +277,8 @@ func resumeLoopOutSwap(cfg *swapConfig, pend *loopdb.LoopOut,
// Obtain the payment addr since we'll need it later for routing plugin // Obtain the payment addr since we'll need it later for routing plugin
// recommendation and possibly for cancel. // recommendation and possibly for cancel.
paymentAddr, err := obtainSwapPaymentAddr( paymentAddr, err := utils.ObtainSwapPaymentAddr(
pend.Contract.SwapInvoice, cfg, pend.Contract.SwapInvoice, cfg.lnd.ChainParams,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -302,24 +304,6 @@ func resumeLoopOutSwap(cfg *swapConfig, pend *loopdb.LoopOut,
return swap, nil return swap, nil
} }
// obtainSwapPaymentAddr will retrieve the payment addr from the passed invoice.
func obtainSwapPaymentAddr(swapInvoice string, cfg *swapConfig) (
*[32]byte, error) {
swapPayReq, err := zpay32.Decode(
swapInvoice, cfg.lnd.ChainParams,
)
if err != nil {
return nil, err
}
if swapPayReq.PaymentAddr == nil {
return nil, fmt.Errorf("expected payment address for invoice")
}
return swapPayReq.PaymentAddr, nil
}
// sendUpdate reports an update to the swap state. // sendUpdate reports an update to the swap state.
func (s *loopOutSwap) sendUpdate(ctx context.Context) error { func (s *loopOutSwap) sendUpdate(ctx context.Context) error {
info := s.swapInfo() info := s.swapInfo()

@ -4,11 +4,10 @@ import (
"context" "context"
"time" "time"
"github.com/btcsuite/btcd/chaincfg"
"github.com/lightninglabs/lndclient" "github.com/lightninglabs/lndclient"
"github.com/lightninglabs/loop/loopdb" "github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/swap" "github.com/lightninglabs/loop/swap"
"github.com/lightningnetwork/lnd/input" "github.com/lightninglabs/loop/utils"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
) )
@ -50,59 +49,10 @@ func newSwapKit(hash lntypes.Hash, swapType swap.Type, cfg *swapConfig,
} }
} }
// GetHtlcScriptVersion returns the correct HTLC script version for the passed
// protocol version.
func GetHtlcScriptVersion(
protocolVersion loopdb.ProtocolVersion) swap.ScriptVersion {
// If the swap was initiated before we had our v3 script, use v2.
if protocolVersion < loopdb.ProtocolVersionHtlcV3 ||
protocolVersion == loopdb.ProtocolVersionUnrecorded {
return swap.HtlcV2
}
return swap.HtlcV3
}
// IsTaproot returns true if the swap referenced by the passed swap contract // IsTaproot returns true if the swap referenced by the passed swap contract
// uses the v3 (taproot) htlc. // uses the v3 (taproot) htlc.
func IsTaprootSwap(swapContract *loopdb.SwapContract) bool { func IsTaprootSwap(swapContract *loopdb.SwapContract) bool {
return GetHtlcScriptVersion(swapContract.ProtocolVersion) == swap.HtlcV3 return utils.GetHtlcScriptVersion(swapContract.ProtocolVersion) == swap.HtlcV3
}
// GetHtlc composes and returns the on-chain swap script.
func GetHtlc(hash lntypes.Hash, contract *loopdb.SwapContract,
chainParams *chaincfg.Params) (*swap.Htlc, error) {
switch GetHtlcScriptVersion(contract.ProtocolVersion) {
case swap.HtlcV2:
return swap.NewHtlcV2(
contract.CltvExpiry, contract.HtlcKeys.SenderScriptKey,
contract.HtlcKeys.ReceiverScriptKey, hash,
chainParams,
)
case swap.HtlcV3:
// Swaps that implement the new MuSig2 protocol will be expected
// to use the 1.0RC2 MuSig2 key derivation scheme.
muSig2Version := input.MuSig2Version040
if contract.ProtocolVersion >= loopdb.ProtocolVersionMuSig2 {
muSig2Version = input.MuSig2Version100RC2
}
return swap.NewHtlcV3(
muSig2Version,
contract.CltvExpiry,
contract.HtlcKeys.SenderInternalPubKey,
contract.HtlcKeys.ReceiverInternalPubKey,
contract.HtlcKeys.SenderScriptKey,
contract.HtlcKeys.ReceiverScriptKey,
hash, chainParams,
)
}
return nil, swap.ErrInvalidScriptVersion
} }
// swapInfo constructs and returns a filled SwapInfo from // swapInfo constructs and returns a filled SwapInfo from

@ -0,0 +1,77 @@
package utils
import (
"fmt"
"github.com/btcsuite/btcd/chaincfg"
"github.com/lightninglabs/loop/loopdb"
"github.com/lightninglabs/loop/swap"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/zpay32"
)
// GetHtlc composes and returns the on-chain swap script.
func GetHtlc(hash lntypes.Hash, contract *loopdb.SwapContract,
chainParams *chaincfg.Params) (*swap.Htlc, error) {
switch GetHtlcScriptVersion(contract.ProtocolVersion) {
case swap.HtlcV2:
return swap.NewHtlcV2(
contract.CltvExpiry, contract.HtlcKeys.SenderScriptKey,
contract.HtlcKeys.ReceiverScriptKey, hash,
chainParams,
)
case swap.HtlcV3:
// Swaps that implement the new MuSig2 protocol will be expected
// to use the 1.0RC2 MuSig2 key derivation scheme.
muSig2Version := input.MuSig2Version040
if contract.ProtocolVersion >= loopdb.ProtocolVersionMuSig2 {
muSig2Version = input.MuSig2Version100RC2
}
return swap.NewHtlcV3(
muSig2Version,
contract.CltvExpiry,
contract.HtlcKeys.SenderInternalPubKey,
contract.HtlcKeys.ReceiverInternalPubKey,
contract.HtlcKeys.SenderScriptKey,
contract.HtlcKeys.ReceiverScriptKey,
hash, chainParams,
)
}
return nil, swap.ErrInvalidScriptVersion
}
// GetHtlcScriptVersion returns the correct HTLC script version for the passed
// protocol version.
func GetHtlcScriptVersion(
protocolVersion loopdb.ProtocolVersion) swap.ScriptVersion {
// If the swap was initiated before we had our v3 script, use v2.
if protocolVersion < loopdb.ProtocolVersionHtlcV3 ||
protocolVersion == loopdb.ProtocolVersionUnrecorded {
return swap.HtlcV2
}
return swap.HtlcV3
}
// ObtainSwapPaymentAddr will retrieve the payment addr from the passed invoice.
func ObtainSwapPaymentAddr(swapInvoice string, chainParams *chaincfg.Params) (
*[32]byte, error) {
swapPayReq, err := zpay32.Decode(swapInvoice, chainParams)
if err != nil {
return nil, err
}
if swapPayReq.PaymentAddr == nil {
return nil, fmt.Errorf("expected payment address for invoice")
}
return swapPayReq.PaymentAddr, nil
}
Loading…
Cancel
Save