Skip to content

Commit 7266f8f

Browse files
committed
staticutil: channel open functions
1 parent d67c20a commit 7266f8f

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
@@ -21,6 +21,7 @@ import (
2121
"github.com/lightninglabs/loop/staticaddr/address"
2222
"github.com/lightninglabs/loop/staticaddr/deposit"
2323
"github.com/lightninglabs/loop/staticaddr/script"
24+
"github.com/lightninglabs/loop/staticaddr/staticutil"
2425
"github.com/lightninglabs/loop/staticaddr/version"
2526
"github.com/lightninglabs/loop/swap"
2627
"github.com/lightningnetwork/lnd/input"
@@ -217,7 +218,9 @@ func (l *StaticAddressLoopIn) signMusig2Tx(ctx context.Context,
217218
musig2sessions []*input.MuSig2SessionInfo,
218219
counterPartyNonces [][musig2.PubNonceSize]byte) ([][]byte, error) {
219220

220-
prevOuts, err := l.toPrevOuts(l.Deposits, l.AddressParams.PkScript)
221+
prevOuts, err := staticutil.ToPrevOuts(
222+
l.Deposits, l.AddressParams.PkScript,
223+
)
221224
if err != nil {
222225
return nil, err
223226
}
@@ -523,29 +526,6 @@ func (l *StaticAddressLoopIn) Outpoints() []wire.OutPoint {
523526
return outpoints
524527
}
525528

526-
func (l *StaticAddressLoopIn) toPrevOuts(deposits []*deposit.Deposit,
527-
pkScript []byte) (map[wire.OutPoint]*wire.TxOut, error) {
528-
529-
prevOuts := make(map[wire.OutPoint]*wire.TxOut, len(deposits))
530-
for _, d := range deposits {
531-
outpoint := wire.OutPoint{
532-
Hash: d.Hash,
533-
Index: d.Index,
534-
}
535-
txOut := &wire.TxOut{
536-
Value: int64(d.Value),
537-
PkScript: pkScript,
538-
}
539-
if _, ok := prevOuts[outpoint]; ok {
540-
return nil, fmt.Errorf("duplicate outpoint %v",
541-
outpoint)
542-
}
543-
prevOuts[outpoint] = txOut
544-
}
545-
546-
return prevOuts, nil
547-
}
548-
549529
// GetState returns the current state of the loop-in swap.
550530
func (l *StaticAddressLoopIn) GetState() fsm.StateType {
551531
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)