Skip to content

Commit d398d19

Browse files
committed
staticutil: channel open functions
1 parent 75d6087 commit d398d19

File tree

2 files changed

+75
-24
lines changed

2 files changed

+75
-24
lines changed

staticaddr/loopin/loopin.go

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/lightninglabs/loop/staticaddr/address"
2121
"github.com/lightninglabs/loop/staticaddr/deposit"
2222
"github.com/lightninglabs/loop/staticaddr/script"
23+
"github.com/lightninglabs/loop/staticaddr/staticutil"
2324
"github.com/lightninglabs/loop/staticaddr/version"
2425
"github.com/lightninglabs/loop/swap"
2526
"github.com/lightningnetwork/lnd/input"
@@ -205,7 +206,9 @@ func (l *StaticAddressLoopIn) signMusig2Tx(ctx context.Context,
205206
musig2sessions []*input.MuSig2SessionInfo,
206207
counterPartyNonces [][musig2.PubNonceSize]byte) ([][]byte, error) {
207208

208-
prevOuts, err := l.toPrevOuts(l.Deposits, l.AddressParams.PkScript)
209+
prevOuts, err := staticutil.ToPrevOuts(
210+
l.Deposits, l.AddressParams.PkScript,
211+
)
209212
if err != nil {
210213
return nil, err
211214
}
@@ -474,29 +477,6 @@ func (l *StaticAddressLoopIn) Outpoints() []wire.OutPoint {
474477
return outpoints
475478
}
476479

477-
func (l *StaticAddressLoopIn) toPrevOuts(deposits []*deposit.Deposit,
478-
pkScript []byte) (map[wire.OutPoint]*wire.TxOut, error) {
479-
480-
prevOuts := make(map[wire.OutPoint]*wire.TxOut, len(deposits))
481-
for _, d := range deposits {
482-
outpoint := wire.OutPoint{
483-
Hash: d.Hash,
484-
Index: d.Index,
485-
}
486-
txOut := &wire.TxOut{
487-
Value: int64(d.Value),
488-
PkScript: pkScript,
489-
}
490-
if _, ok := prevOuts[outpoint]; ok {
491-
return nil, fmt.Errorf("duplicate outpoint %v",
492-
outpoint)
493-
}
494-
prevOuts[outpoint] = txOut
495-
}
496-
497-
return prevOuts, nil
498-
}
499-
500480
// GetState returns the current state of the loop-in swap.
501481
func (l *StaticAddressLoopIn) GetState() fsm.StateType {
502482
l.mu.Lock()

staticaddr/staticutil/utils.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"sort"
88

9+
"github.com/btcsuite/btcd/btcutil"
910
"github.com/btcsuite/btcd/chaincfg/chainhash"
1011
"github.com/btcsuite/btcd/wire"
1112
"github.com/lightninglabs/lndclient"
@@ -14,6 +15,7 @@ import (
1415
"github.com/lightninglabs/loop/staticaddr/script"
1516
"github.com/lightninglabs/loop/swapserverrpc"
1617
"github.com/lightningnetwork/lnd/input"
18+
"github.com/lightningnetwork/lnd/lnwallet"
1719
)
1820

1921
// ToPrevOuts converts a slice of deposits to a map of outpoints to TxOuts.
@@ -66,6 +68,36 @@ func CreateMusig2Sessions(ctx context.Context,
6668
return musig2Sessions, clientNonces, nil
6769
}
6870

71+
// CreateMusig2SessionsPerDeposit creates a musig2 session for a number of
72+
// deposits.
73+
func CreateMusig2SessionsPerDeposit(ctx context.Context,
74+
signer lndclient.SignerClient, deposits []*deposit.Deposit,
75+
addrParams *address.Parameters,
76+
staticAddress *script.StaticAddress) (
77+
map[string]*input.MuSig2SessionInfo, map[string][]byte, map[string]int,
78+
error) {
79+
80+
sessions := make(map[string]*input.MuSig2SessionInfo)
81+
nonces := make(map[string][]byte)
82+
depositToIdx := make(map[string]int)
83+
84+
// Create the musig2 sessions for the sweepless sweep tx.
85+
for i, deposit := range deposits {
86+
session, err := createMusig2Session(
87+
ctx, signer, addrParams, staticAddress,
88+
)
89+
if err != nil {
90+
return nil, nil, nil, err
91+
}
92+
93+
sessions[deposit.String()] = session
94+
nonces[deposit.String()] = session.PublicNonce[:]
95+
depositToIdx[deposit.String()] = i
96+
}
97+
98+
return sessions, nonces, depositToIdx, nil
99+
}
100+
69101
// createMusig2Session creates a musig2 session for the deposit.
70102
func createMusig2Session(ctx context.Context,
71103
signer lndclient.SignerClient, addrParams *address.Parameters,
@@ -132,3 +164,42 @@ func bip69inputLess(input1, input2 *swapserverrpc.PrevoutInfo) bool {
132164
}
133165
return bytes.Compare(ihash[:], jhash[:]) == -1
134166
}
167+
168+
// SelectDeposits sorts the deposits by amount in descending order. It then
169+
// selects the deposits that are needed to cover the amount requested without
170+
// leaving a dust change. It returns an error if the sum of deposits minus dust
171+
// is less than the requested amount.
172+
func SelectDeposits(deposits []*deposit.Deposit, amount int64) (
173+
[]*deposit.Deposit, error) {
174+
175+
// Check that sum of deposits covers the swap amount while leaving no
176+
// dust change.
177+
dustLimit := lnwallet.DustLimitForSize(input.P2TRSize)
178+
var depositSum btcutil.Amount
179+
for _, deposit := range deposits {
180+
depositSum += deposit.Value
181+
}
182+
if depositSum-dustLimit < btcutil.Amount(amount) {
183+
return nil, fmt.Errorf("insufficient funds to cover swap " +
184+
"amount, try manually selecting deposits")
185+
}
186+
187+
// Sort the deposits by amount in descending order.
188+
sort.Slice(deposits, func(i, j int) bool {
189+
return deposits[i].Value > deposits[j].Value
190+
})
191+
192+
// Select the deposits that are needed to cover the swap amount without
193+
// leaving a dust change.
194+
var selectedDeposits []*deposit.Deposit
195+
var selectedAmount btcutil.Amount
196+
for _, deposit := range deposits {
197+
if selectedAmount >= btcutil.Amount(amount)+dustLimit {
198+
break
199+
}
200+
selectedDeposits = append(selectedDeposits, deposit)
201+
selectedAmount += deposit.Value
202+
}
203+
204+
return selectedDeposits, nil
205+
}

0 commit comments

Comments
 (0)