Skip to content

Commit cd225d3

Browse files
authored
Merge pull request #1015 from hieblmi/static-fixes
staticaddr: signet testing fixes
2 parents 113f716 + 1523858 commit cd225d3

File tree

4 files changed

+99
-16
lines changed

4 files changed

+99
-16
lines changed

cmd/loop/quote.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -229,23 +229,22 @@ func printQuoteInResp(req *looprpc.QuoteRequest,
229229
resp *looprpc.InQuoteResponse, verbose bool) {
230230

231231
totalFee := resp.HtlcPublishFeeSat + resp.SwapFeeSat
232+
amt := req.Amt
233+
if amt == 0 {
234+
amt = resp.QuotedAmt
235+
}
232236

233237
if req.DepositOutpoints != nil {
234-
if req.Amt == 0 {
235-
fmt.Printf(satAmtFmt, "Previously deposited "+
236-
"on-chain:", resp.QuotedAmt)
237-
} else {
238-
fmt.Printf(satAmtFmt, "Previously deposited "+
239-
"on-chain:", req.Amt)
240-
}
238+
fmt.Printf(satAmtFmt, "Previously deposited on-chain:",
239+
amt)
241240
} else {
242-
fmt.Printf(satAmtFmt, "Send on-chain:", req.Amt)
241+
fmt.Printf(satAmtFmt, "Send on-chain:", amt)
243242
}
244-
fmt.Printf(satAmtFmt, "Receive off-chain:", req.Amt-totalFee)
243+
fmt.Printf(satAmtFmt, "Receive off-chain:", amt-totalFee)
245244

246245
switch {
247246
case req.ExternalHtlc && !verbose:
248-
// If it's external then we don't know the miner fee hence the
247+
// If it's external, then we don't know the miner fee hence the
249248
// total cost.
250249
fmt.Printf(satAmtFmt, "Loop service fee:", resp.SwapFeeSat)
251250

staticaddr/loopin/interface.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ import (
1515
"github.com/lightningnetwork/lnd/zpay32"
1616
)
1717

18+
const (
19+
// DefaultLoopInOnChainCltvDelta is the time lock relative to current
20+
// block height that swap server will accept on the swap initiation
21+
// call.
22+
DefaultLoopInOnChainCltvDelta = 1000
23+
24+
// DepositHtlcDelta is a safety buffer of blocks that needs to exist
25+
// between the deposit expiry height and the htlc expiry height.
26+
DepositHtlcDelta = 50
27+
)
28+
1829
type (
1930
// ValidateLoopInContract validates the contract parameters against our
2031
// request.

staticaddr/loopin/manager.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -862,8 +862,25 @@ func (m *Manager) GetAllSwaps(ctx context.Context) ([]*StaticAddressLoopIn,
862862
// are needed to cover the amount requested without leaving a dust change. It
863863
// returns an error if the sum of deposits minus dust is less than the requested
864864
// amount.
865-
func SelectDeposits(targetAmount btcutil.Amount, deposits []*deposit.Deposit,
866-
csvExpiry uint32, blockHeight uint32) ([]*deposit.Deposit, error) {
865+
func SelectDeposits(targetAmount btcutil.Amount,
866+
unfilteredDeposits []*deposit.Deposit, csvExpiry uint32,
867+
blockHeight uint32) ([]*deposit.Deposit, error) {
868+
869+
// Filter out deposits that are too close to expiry to be swapped.
870+
var deposits []*deposit.Deposit
871+
for _, d := range unfilteredDeposits {
872+
if !IsSwappable(
873+
uint32(d.ConfirmationHeight), blockHeight, csvExpiry,
874+
) {
875+
876+
log.Debugf("Skipping deposit %s as it expires before "+
877+
"the htlc", d.OutPoint.String())
878+
879+
continue
880+
}
881+
882+
deposits = append(deposits, d)
883+
}
867884

868885
// Sort the deposits by amount in descending order, then by
869886
// blocks-until-expiry in ascending order.
@@ -901,6 +918,25 @@ func SelectDeposits(targetAmount btcutil.Amount, deposits []*deposit.Deposit,
901918
selectedAmount, targetAmount)
902919
}
903920

921+
// IsSwappable checks if a deposit is swappable. It returns true if the deposit
922+
// is not expired and the htlc is not too close to expiry.
923+
func IsSwappable(confirmationHeight, blockHeight, csvExpiry uint32) bool {
924+
// The deposit expiry height is the confirmation height plus the csv
925+
// expiry.
926+
depositExpiryHeight := confirmationHeight + csvExpiry
927+
928+
// The htlc expiry height is the current height plus the htlc
929+
// cltv delta.
930+
htlcExpiryHeight := blockHeight + DefaultLoopInOnChainCltvDelta
931+
932+
// Ensure that the deposit doesn't expire before the htlc.
933+
if depositExpiryHeight < htlcExpiryHeight+DepositHtlcDelta {
934+
return false
935+
}
936+
937+
return true
938+
}
939+
904940
// DeduceSwapAmount calculates the swap amount based on the selected amount and
905941
// the total deposit amount. It checks if the selected amount leaves a dust
906942
// change output or exceeds the total deposits value. Note that if the selected

staticaddr/loopin/manager_test.go

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ type testCase struct {
2929
func TestSelectDeposits(t *testing.T) {
3030
d1, d2, d3, d4 := &deposit.Deposit{
3131
Value: 1_000_000,
32-
ConfirmationHeight: 1000,
32+
ConfirmationHeight: 5_000,
3333
}, &deposit.Deposit{
3434
Value: 2_000_000,
35-
ConfirmationHeight: 2000,
35+
ConfirmationHeight: 5_001,
3636
}, &deposit.Deposit{
3737
Value: 3_000_000,
38-
ConfirmationHeight: 3000,
38+
ConfirmationHeight: 5_002,
3939
}, &deposit.Deposit{
4040
Value: 3_000_000,
41-
ConfirmationHeight: 3001,
41+
ConfirmationHeight: 5_003,
4242
}
4343
d1.Hash = chainhash.Hash{1}
4444
d1.Index = 0
@@ -121,6 +121,43 @@ func TestSelectDeposits(t *testing.T) {
121121
expected: []*deposit.Deposit{d3},
122122
expectedErr: "",
123123
},
124+
{
125+
name: "prefilter filters deposits close to expiry",
126+
deposits: func() []*deposit.Deposit {
127+
// dClose expires before
128+
// htlcExpiry+DepositHtlcDelta and must be
129+
// filtered out. dOK expires exactly at the
130+
// threshold and must be eligible.
131+
dClose := &deposit.Deposit{
132+
Value: 3_000_000,
133+
ConfirmationHeight: 3000,
134+
}
135+
dClose.Hash = chainhash.Hash{5}
136+
dClose.Index = 0
137+
dOK := &deposit.Deposit{
138+
Value: 2_000_000,
139+
ConfirmationHeight: 3050,
140+
}
141+
dOK.Hash = chainhash.Hash{6}
142+
dOK.Index = 0
143+
return []*deposit.Deposit{dClose, dOK}
144+
}(),
145+
targetValue: 1_000_000,
146+
csvExpiry: 1000,
147+
blockHeight: 3000,
148+
expected: func() []*deposit.Deposit {
149+
// Only dOK should be considered.
150+
// dClose is filtered.
151+
dOK := &deposit.Deposit{
152+
Value: 2_000_000,
153+
ConfirmationHeight: 3050,
154+
}
155+
dOK.Hash = chainhash.Hash{6}
156+
dOK.Index = 0
157+
return []*deposit.Deposit{dOK}
158+
}(),
159+
expectedErr: "",
160+
},
124161
}
125162

126163
for _, tc := range testCases {

0 commit comments

Comments
 (0)