2019-03-07 02:22:46 +00:00
|
|
|
package loop
|
2019-03-06 20:13:50 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
2022-11-16 18:01:28 +00:00
|
|
|
"github.com/btcsuite/btcd/chaincfg"
|
2020-06-17 20:25:57 +00:00
|
|
|
"github.com/lightninglabs/lndclient"
|
2019-03-07 04:32:24 +00:00
|
|
|
"github.com/lightninglabs/loop/loopdb"
|
|
|
|
"github.com/lightninglabs/loop/swap"
|
2023-01-09 17:49:26 +00:00
|
|
|
"github.com/lightningnetwork/lnd/input"
|
2019-03-06 20:13:50 +00:00
|
|
|
"github.com/lightningnetwork/lnd/lntypes"
|
|
|
|
)
|
|
|
|
|
|
|
|
type swapKit struct {
|
|
|
|
hash lntypes.Hash
|
|
|
|
|
2022-12-15 15:43:38 +00:00
|
|
|
height int32 //nolint:structcheck
|
2019-03-06 20:13:50 +00:00
|
|
|
|
2019-10-09 10:36:16 +00:00
|
|
|
log *swap.PrefixLog
|
2019-03-06 20:13:50 +00:00
|
|
|
|
|
|
|
lastUpdateTime time.Time
|
2020-04-29 17:47:27 +00:00
|
|
|
|
|
|
|
cost loopdb.SwapCost
|
|
|
|
|
|
|
|
state loopdb.SwapState
|
2019-03-06 20:13:50 +00:00
|
|
|
|
2019-03-07 04:32:24 +00:00
|
|
|
contract *loopdb.SwapContract
|
2020-04-29 17:47:27 +00:00
|
|
|
|
2019-10-09 10:36:16 +00:00
|
|
|
swapType swap.Type
|
2020-04-29 17:47:27 +00:00
|
|
|
|
|
|
|
swapConfig
|
2019-03-06 20:13:50 +00:00
|
|
|
}
|
|
|
|
|
2019-10-09 10:36:16 +00:00
|
|
|
func newSwapKit(hash lntypes.Hash, swapType swap.Type, cfg *swapConfig,
|
2020-04-29 17:47:27 +00:00
|
|
|
contract *loopdb.SwapContract) *swapKit {
|
2019-03-06 20:13:50 +00:00
|
|
|
|
2019-10-09 10:36:16 +00:00
|
|
|
log := &swap.PrefixLog{
|
2019-03-06 20:13:50 +00:00
|
|
|
Hash: hash,
|
2019-10-28 16:06:07 +00:00
|
|
|
Logger: log,
|
2019-03-06 20:13:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &swapKit{
|
|
|
|
swapConfig: *cfg,
|
|
|
|
hash: hash,
|
|
|
|
log: log,
|
2019-03-07 04:32:24 +00:00
|
|
|
state: loopdb.StateInitiated,
|
2019-03-06 20:13:50 +00:00
|
|
|
contract: contract,
|
|
|
|
swapType: swapType,
|
2020-04-29 17:47:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-23 15:30:53 +00:00
|
|
|
// GetHtlcScriptVersion returns the correct HTLC script version for the passed
|
|
|
|
// protocol version.
|
|
|
|
func GetHtlcScriptVersion(
|
|
|
|
protocolVersion loopdb.ProtocolVersion) swap.ScriptVersion {
|
|
|
|
|
2022-04-24 20:29:13 +00:00
|
|
|
// If the swap was initiated before we had our v3 script, use v2.
|
2023-04-20 06:12:09 +00:00
|
|
|
if protocolVersion < loopdb.ProtocolVersionHtlcV3 ||
|
|
|
|
protocolVersion == loopdb.ProtocolVersionUnrecorded {
|
|
|
|
|
2020-07-23 15:30:53 +00:00
|
|
|
return swap.HtlcV2
|
|
|
|
}
|
|
|
|
|
2022-04-24 20:29:13 +00:00
|
|
|
return swap.HtlcV3
|
2020-07-23 15:30:53 +00:00
|
|
|
}
|
|
|
|
|
2022-04-24 20:59:41 +00:00
|
|
|
// IsTaproot returns true if the swap referenced by the passed swap contract
|
|
|
|
// uses the v3 (taproot) htlc.
|
|
|
|
func IsTaprootSwap(swapContract *loopdb.SwapContract) bool {
|
|
|
|
return GetHtlcScriptVersion(swapContract.ProtocolVersion) == swap.HtlcV3
|
|
|
|
}
|
|
|
|
|
2022-11-16 18:01:28 +00:00
|
|
|
// 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(
|
2023-01-05 17:16:05 +00:00
|
|
|
contract.CltvExpiry, contract.HtlcKeys.SenderScriptKey,
|
|
|
|
contract.HtlcKeys.ReceiverScriptKey, hash,
|
2022-11-16 18:01:28 +00:00
|
|
|
chainParams,
|
|
|
|
)
|
|
|
|
|
|
|
|
case swap.HtlcV3:
|
2023-01-09 18:01:07 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2022-11-16 18:01:28 +00:00
|
|
|
return swap.NewHtlcV3(
|
2023-01-09 18:01:07 +00:00
|
|
|
muSig2Version,
|
2023-01-05 17:16:05 +00:00
|
|
|
contract.CltvExpiry,
|
|
|
|
contract.HtlcKeys.SenderInternalPubKey,
|
|
|
|
contract.HtlcKeys.ReceiverInternalPubKey,
|
|
|
|
contract.HtlcKeys.SenderScriptKey,
|
|
|
|
contract.HtlcKeys.ReceiverScriptKey,
|
|
|
|
hash, chainParams,
|
2022-11-16 18:01:28 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, swap.ErrInvalidScriptVersion
|
2019-03-06 20:13:50 +00:00
|
|
|
}
|
|
|
|
|
2020-04-29 17:47:27 +00:00
|
|
|
// swapInfo constructs and returns a filled SwapInfo from
|
|
|
|
// the swapKit.
|
|
|
|
func (s *swapKit) swapInfo() *SwapInfo {
|
|
|
|
return &SwapInfo{
|
2019-03-06 20:13:50 +00:00
|
|
|
SwapContract: *s.contract,
|
|
|
|
SwapHash: s.hash,
|
|
|
|
SwapType: s.swapType,
|
|
|
|
LastUpdate: s.lastUpdateTime,
|
2019-05-15 11:55:41 +00:00
|
|
|
SwapStateData: loopdb.SwapStateData{
|
|
|
|
State: s.state,
|
2019-05-15 12:01:27 +00:00
|
|
|
Cost: s.cost,
|
2019-05-15 11:55:41 +00:00
|
|
|
},
|
2019-03-06 20:13:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type genericSwap interface {
|
|
|
|
execute(mainCtx context.Context, cfg *executeConfig,
|
|
|
|
height int32) error
|
|
|
|
}
|
|
|
|
|
|
|
|
type swapConfig struct {
|
|
|
|
lnd *lndclient.LndServices
|
2019-03-07 04:32:24 +00:00
|
|
|
store loopdb.SwapStore
|
2019-03-06 20:13:50 +00:00
|
|
|
server swapServerClient
|
|
|
|
}
|
2020-06-08 10:53:07 +00:00
|
|
|
|
|
|
|
func newSwapConfig(lnd *lndclient.LndServices, store loopdb.SwapStore,
|
|
|
|
server swapServerClient) *swapConfig {
|
|
|
|
|
|
|
|
return &swapConfig{
|
|
|
|
lnd: lnd,
|
|
|
|
store: store,
|
|
|
|
server: server,
|
|
|
|
}
|
|
|
|
}
|