|
|
|
@ -50,15 +50,12 @@ var (
|
|
|
|
|
chanRule = NewThresholdRule(50, 0)
|
|
|
|
|
|
|
|
|
|
testQuote = &loop.LoopOutQuote{
|
|
|
|
|
SwapFee: btcutil.Amount(1),
|
|
|
|
|
PrepayAmount: btcutil.Amount(500),
|
|
|
|
|
MinerFee: btcutil.Amount(50),
|
|
|
|
|
SwapFee: btcutil.Amount(5),
|
|
|
|
|
PrepayAmount: btcutil.Amount(50),
|
|
|
|
|
MinerFee: btcutil.Amount(1),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
prepayFee = ppmToSat(
|
|
|
|
|
testQuote.PrepayAmount, defaultPrepayRoutingFeePPM,
|
|
|
|
|
)
|
|
|
|
|
routingFee = ppmToSat(7500, defaultRoutingFeePPM)
|
|
|
|
|
prepayFee, routingFee = testPPMFees(defaultFeePPM, testQuote, 7500)
|
|
|
|
|
|
|
|
|
|
// chan1Rec is the suggested swap for channel 1 when we use chanRule.
|
|
|
|
|
chan1Rec = loop.OutRequest{
|
|
|
|
@ -66,7 +63,7 @@ var (
|
|
|
|
|
OutgoingChanSet: loopdb.ChannelSet{chanID1.ToUint64()},
|
|
|
|
|
MaxPrepayRoutingFee: prepayFee,
|
|
|
|
|
MaxSwapRoutingFee: routingFee,
|
|
|
|
|
MaxMinerFee: defaultMaximumMinerFee,
|
|
|
|
|
MaxMinerFee: scaleMinerFee(testQuote.MinerFee),
|
|
|
|
|
MaxSwapFee: testQuote.SwapFee,
|
|
|
|
|
MaxPrepayAmount: testQuote.PrepayAmount,
|
|
|
|
|
SweepConfTarget: loop.DefaultSweepConfTarget,
|
|
|
|
@ -79,7 +76,7 @@ var (
|
|
|
|
|
OutgoingChanSet: loopdb.ChannelSet{chanID2.ToUint64()},
|
|
|
|
|
MaxPrepayRoutingFee: prepayFee,
|
|
|
|
|
MaxSwapRoutingFee: routingFee,
|
|
|
|
|
MaxMinerFee: defaultMaximumMinerFee,
|
|
|
|
|
MaxMinerFee: scaleMinerFee(testQuote.MinerFee),
|
|
|
|
|
MaxPrepayAmount: testQuote.PrepayAmount,
|
|
|
|
|
MaxSwapFee: testQuote.SwapFee,
|
|
|
|
|
SweepConfTarget: loop.DefaultSweepConfTarget,
|
|
|
|
@ -164,6 +161,21 @@ func testPPMFees(ppm uint64, quote *loop.LoopOutQuote,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// applyFeeCategoryQuote returns a copy of the loop out request provided with
|
|
|
|
|
// fee categories updated to the quote and routing settings provided.
|
|
|
|
|
// nolint:unparam
|
|
|
|
|
func applyFeeCategoryQuote(req loop.OutRequest, minerFee btcutil.Amount,
|
|
|
|
|
prepayPPM, routingPPM uint64, quote loop.LoopOutQuote) loop.OutRequest {
|
|
|
|
|
|
|
|
|
|
req.MaxPrepayRoutingFee = ppmToSat(quote.PrepayAmount, prepayPPM)
|
|
|
|
|
req.MaxSwapRoutingFee = ppmToSat(req.Amount, routingPPM)
|
|
|
|
|
req.MaxSwapFee = quote.SwapFee
|
|
|
|
|
req.MaxPrepayAmount = quote.PrepayAmount
|
|
|
|
|
req.MaxMinerFee = minerFee
|
|
|
|
|
|
|
|
|
|
return req
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TestParameters tests getting and setting of parameters for our manager.
|
|
|
|
|
func TestParameters(t *testing.T) {
|
|
|
|
|
cfg, _ := newTestConfig()
|
|
|
|
@ -547,6 +559,12 @@ func TestRestrictedSuggestions(t *testing.T) {
|
|
|
|
|
// TestSweepFeeLimit tests getting of swap suggestions when our estimated sweep
|
|
|
|
|
// fee is above and below the configured limit.
|
|
|
|
|
func TestSweepFeeLimit(t *testing.T) {
|
|
|
|
|
quote := &loop.LoopOutQuote{
|
|
|
|
|
SwapFee: btcutil.Amount(1),
|
|
|
|
|
PrepayAmount: btcutil.Amount(500),
|
|
|
|
|
MinerFee: btcutil.Amount(50),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
feeRate chainfee.SatPerKWeight
|
|
|
|
@ -557,7 +575,11 @@ func TestSweepFeeLimit(t *testing.T) {
|
|
|
|
|
feeRate: defaultSweepFeeRateLimit,
|
|
|
|
|
suggestions: &Suggestions{
|
|
|
|
|
OutSwaps: []loop.OutRequest{
|
|
|
|
|
chan1Rec,
|
|
|
|
|
applyFeeCategoryQuote(
|
|
|
|
|
chan1Rec, defaultMaximumMinerFee,
|
|
|
|
|
defaultPrepayRoutingFeePPM,
|
|
|
|
|
defaultRoutingFeePPM, *quote,
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
DisqualifiedChans: noneDisqualified,
|
|
|
|
|
DisqualifiedPeers: noPeersDisqualified,
|
|
|
|
@ -581,6 +603,13 @@ func TestSweepFeeLimit(t *testing.T) {
|
|
|
|
|
t.Run(testCase.name, func(t *testing.T) {
|
|
|
|
|
cfg, lnd := newTestConfig()
|
|
|
|
|
|
|
|
|
|
cfg.LoopOutQuote = func(_ context.Context,
|
|
|
|
|
_ *loop.LoopOutQuoteRequest) (*loop.LoopOutQuote,
|
|
|
|
|
error) {
|
|
|
|
|
|
|
|
|
|
return quote, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set our test case's fee rate for our mock lnd.
|
|
|
|
|
lnd.SetFeeEstimate(
|
|
|
|
|
loop.DefaultSweepConfTarget, testCase.feeRate,
|
|
|
|
@ -591,6 +620,8 @@ func TestSweepFeeLimit(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
params := defaultParameters
|
|
|
|
|
params.FeeLimit = defaultFeeCategoryLimit()
|
|
|
|
|
|
|
|
|
|
params.ChannelRules = map[lnwire.ShortChannelID]*ThresholdRule{
|
|
|
|
|
chanID1: chanRule,
|
|
|
|
|
}
|
|
|
|
@ -610,6 +641,9 @@ func TestSuggestSwaps(t *testing.T) {
|
|
|
|
|
channel1,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expectedAmt := btcutil.Amount(10000)
|
|
|
|
|
prepay, routing := testPPMFees(defaultFeePPM, testQuote, expectedAmt)
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
channels []lndclient.ChannelInfo
|
|
|
|
@ -681,20 +715,14 @@ func TestSuggestSwaps(t *testing.T) {
|
|
|
|
|
suggestions: &Suggestions{
|
|
|
|
|
OutSwaps: []loop.OutRequest{
|
|
|
|
|
{
|
|
|
|
|
Amount: 10000,
|
|
|
|
|
Amount: expectedAmt,
|
|
|
|
|
OutgoingChanSet: loopdb.ChannelSet{
|
|
|
|
|
chanID1.ToUint64(),
|
|
|
|
|
chanID2.ToUint64(),
|
|
|
|
|
},
|
|
|
|
|
MaxPrepayRoutingFee: ppmToSat(
|
|
|
|
|
testQuote.PrepayAmount,
|
|
|
|
|
defaultPrepayRoutingFeePPM,
|
|
|
|
|
),
|
|
|
|
|
MaxSwapRoutingFee: ppmToSat(
|
|
|
|
|
10000,
|
|
|
|
|
defaultRoutingFeePPM,
|
|
|
|
|
),
|
|
|
|
|
MaxMinerFee: defaultMaximumMinerFee,
|
|
|
|
|
MaxPrepayRoutingFee: prepay,
|
|
|
|
|
MaxSwapRoutingFee: routing,
|
|
|
|
|
MaxMinerFee: scaleMinerFee(testQuote.MinerFee),
|
|
|
|
|
MaxSwapFee: testQuote.SwapFee,
|
|
|
|
|
MaxPrepayAmount: testQuote.PrepayAmount,
|
|
|
|
|
SweepConfTarget: loop.DefaultSweepConfTarget,
|
|
|
|
@ -736,6 +764,12 @@ func TestSuggestSwaps(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
// TestFeeLimits tests limiting of swap suggestions by fees.
|
|
|
|
|
func TestFeeLimits(t *testing.T) {
|
|
|
|
|
quote := &loop.LoopOutQuote{
|
|
|
|
|
SwapFee: btcutil.Amount(1),
|
|
|
|
|
PrepayAmount: btcutil.Amount(500),
|
|
|
|
|
MinerFee: btcutil.Amount(50),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
quote *loop.LoopOutQuote
|
|
|
|
@ -743,10 +777,14 @@ func TestFeeLimits(t *testing.T) {
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "fees ok",
|
|
|
|
|
quote: testQuote,
|
|
|
|
|
quote: quote,
|
|
|
|
|
suggestions: &Suggestions{
|
|
|
|
|
OutSwaps: []loop.OutRequest{
|
|
|
|
|
chan1Rec,
|
|
|
|
|
applyFeeCategoryQuote(
|
|
|
|
|
chan1Rec, defaultMaximumMinerFee,
|
|
|
|
|
defaultPrepayRoutingFeePPM,
|
|
|
|
|
defaultRoutingFeePPM, *quote,
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
DisqualifiedChans: noneDisqualified,
|
|
|
|
|
DisqualifiedPeers: noPeersDisqualified,
|
|
|
|
@ -813,7 +851,10 @@ func TestFeeLimits(t *testing.T) {
|
|
|
|
|
channel1,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set our params to use individual fee limits.
|
|
|
|
|
params := defaultParameters
|
|
|
|
|
params.FeeLimit = defaultFeeCategoryLimit()
|
|
|
|
|
|
|
|
|
|
params.ChannelRules = map[lnwire.ShortChannelID]*ThresholdRule{
|
|
|
|
|
chanID1: chanRule,
|
|
|
|
|
}
|
|
|
|
@ -838,6 +879,21 @@ func TestFeeLimits(t *testing.T) {
|
|
|
|
|
// amounts, we use our max miner fee to shift swap cost to values above/below
|
|
|
|
|
// our budget, fixing our other fees at 114 sat for simplicity.
|
|
|
|
|
func TestFeeBudget(t *testing.T) {
|
|
|
|
|
quote := &loop.LoopOutQuote{
|
|
|
|
|
SwapFee: btcutil.Amount(1),
|
|
|
|
|
PrepayAmount: btcutil.Amount(500),
|
|
|
|
|
MinerFee: btcutil.Amount(50),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chan1 := applyFeeCategoryQuote(
|
|
|
|
|
chan1Rec, 5000, defaultPrepayRoutingFeePPM,
|
|
|
|
|
defaultRoutingFeePPM, *quote,
|
|
|
|
|
)
|
|
|
|
|
chan2 := applyFeeCategoryQuote(
|
|
|
|
|
chan2Rec, 5000, defaultPrepayRoutingFeePPM,
|
|
|
|
|
defaultRoutingFeePPM, *quote,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
|
|
|
|
@ -862,7 +918,7 @@ func TestFeeBudget(t *testing.T) {
|
|
|
|
|
maxMinerFee: 5000,
|
|
|
|
|
suggestions: &Suggestions{
|
|
|
|
|
OutSwaps: []loop.OutRequest{
|
|
|
|
|
chan1Rec, chan2Rec,
|
|
|
|
|
chan1, chan2,
|
|
|
|
|
},
|
|
|
|
|
DisqualifiedChans: noneDisqualified,
|
|
|
|
|
DisqualifiedPeers: noPeersDisqualified,
|
|
|
|
@ -876,7 +932,7 @@ func TestFeeBudget(t *testing.T) {
|
|
|
|
|
maxMinerFee: 5000,
|
|
|
|
|
suggestions: &Suggestions{
|
|
|
|
|
OutSwaps: []loop.OutRequest{
|
|
|
|
|
chan1Rec,
|
|
|
|
|
chan1,
|
|
|
|
|
},
|
|
|
|
|
DisqualifiedChans: map[lnwire.ShortChannelID]Reason{
|
|
|
|
|
chanID2: ReasonBudgetInsufficient,
|
|
|
|
@ -895,7 +951,7 @@ func TestFeeBudget(t *testing.T) {
|
|
|
|
|
},
|
|
|
|
|
suggestions: &Suggestions{
|
|
|
|
|
OutSwaps: []loop.OutRequest{
|
|
|
|
|
chan1Rec, chan2Rec,
|
|
|
|
|
chan1, chan2,
|
|
|
|
|
},
|
|
|
|
|
DisqualifiedChans: noneDisqualified,
|
|
|
|
|
DisqualifiedPeers: noPeersDisqualified,
|
|
|
|
@ -912,7 +968,7 @@ func TestFeeBudget(t *testing.T) {
|
|
|
|
|
},
|
|
|
|
|
suggestions: &Suggestions{
|
|
|
|
|
OutSwaps: []loop.OutRequest{
|
|
|
|
|
chan1Rec,
|
|
|
|
|
chan1,
|
|
|
|
|
},
|
|
|
|
|
DisqualifiedChans: map[lnwire.ShortChannelID]Reason{
|
|
|
|
|
chanID2: ReasonBudgetInsufficient,
|
|
|
|
@ -977,6 +1033,13 @@ func TestFeeBudget(t *testing.T) {
|
|
|
|
|
return swaps, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg.LoopOutQuote = func(_ context.Context,
|
|
|
|
|
_ *loop.LoopOutQuoteRequest) (*loop.LoopOutQuote,
|
|
|
|
|
error) {
|
|
|
|
|
|
|
|
|
|
return quote, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set two channels that need swaps.
|
|
|
|
|
lnd.Channels = []lndclient.ChannelInfo{
|
|
|
|
|
channel1,
|
|
|
|
@ -1141,14 +1204,13 @@ func TestSizeRestrictions(t *testing.T) {
|
|
|
|
|
Maximum: 10000,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
prepay, routing = testPPMFees(defaultFeePPM, testQuote, 7000)
|
|
|
|
|
outSwap = loop.OutRequest{
|
|
|
|
|
Amount: 7000,
|
|
|
|
|
OutgoingChanSet: loopdb.ChannelSet{chanID1.ToUint64()},
|
|
|
|
|
MaxPrepayRoutingFee: prepayFee,
|
|
|
|
|
MaxSwapRoutingFee: ppmToSat(
|
|
|
|
|
7000, defaultRoutingFeePPM,
|
|
|
|
|
),
|
|
|
|
|
MaxMinerFee: defaultMaximumMinerFee,
|
|
|
|
|
MaxPrepayRoutingFee: prepay,
|
|
|
|
|
MaxSwapRoutingFee: routing,
|
|
|
|
|
MaxMinerFee: scaleMinerFee(testQuote.MinerFee),
|
|
|
|
|
MaxSwapFee: testQuote.SwapFee,
|
|
|
|
|
MaxPrepayAmount: testQuote.PrepayAmount,
|
|
|
|
|
SweepConfTarget: loop.DefaultSweepConfTarget,
|
|
|
|
|