liquidity: fix tests for autoloop sticky loop out

pull/548/head
George Tsagkarelis 1 year ago
parent af7a470aea
commit c17e5a6fc6
No known key found for this signature in database
GPG Key ID: 0807D1013F48208A

@ -199,16 +199,30 @@ func TestAutoLoopEnabled(t *testing.T) {
}, },
}, },
} }
singleLoopOut = &loopdb.LoopOut{
Loop: loopdb.Loop{
Events: []*loopdb.LoopEvent{
{
SwapStateData: loopdb.SwapStateData{
State: loopdb.StateInitiated,
},
},
},
},
}
) )
// Tick our autolooper with no existing swaps, we expect a loop out // Tick our autolooper with no existing swaps, we expect a loop out
// swap to be dispatched for each channel. // swap to be dispatched for each channel.
step := &autoloopStep{ step := &autoloopStep{
minAmt: 1, minAmt: 1,
maxAmt: amt + 1, maxAmt: amt + 1,
quotesOut: quotes, quotesOut: quotes,
expectedOut: loopOuts, expectedOut: loopOuts,
existingOutSingle: singleLoopOut,
} }
c.autoloop(step) c.autoloop(step)
// Tick again with both of our swaps in progress. We haven't shifted our // Tick again with both of our swaps in progress. We haven't shifted our
@ -220,9 +234,10 @@ func TestAutoLoopEnabled(t *testing.T) {
} }
step = &autoloopStep{ step = &autoloopStep{
minAmt: 1, minAmt: 1,
maxAmt: amt + 1, maxAmt: amt + 1,
existingOut: existing, existingOut: existing,
existingOutSingle: singleLoopOut,
} }
c.autoloop(step) c.autoloop(step)
@ -278,11 +293,12 @@ func TestAutoLoopEnabled(t *testing.T) {
// still has balances which reflect that we need to swap), but nothing // still has balances which reflect that we need to swap), but nothing
// for channel 2, since it has had a failure. // for channel 2, since it has had a failure.
step = &autoloopStep{ step = &autoloopStep{
minAmt: 1, minAmt: 1,
maxAmt: amt + 1, maxAmt: amt + 1,
existingOut: existing, existingOut: existing,
quotesOut: quotes, quotesOut: quotes,
expectedOut: loopOuts, expectedOut: loopOuts,
existingOutSingle: singleLoopOut,
} }
c.autoloop(step) c.autoloop(step)
@ -299,10 +315,11 @@ func TestAutoLoopEnabled(t *testing.T) {
} }
step = &autoloopStep{ step = &autoloopStep{
minAmt: 1, minAmt: 1,
maxAmt: amt + 1, maxAmt: amt + 1,
existingOut: existing, existingOut: existing,
quotesOut: quotes, quotesOut: quotes,
existingOutSingle: singleLoopOut,
} }
c.autoloop(step) c.autoloop(step)
@ -446,13 +463,27 @@ func TestAutoloopAddress(t *testing.T) {
}, },
}, },
} }
singleLoopOut = &loopdb.LoopOut{
Loop: loopdb.Loop{
Events: []*loopdb.LoopEvent{
{
SwapStateData: loopdb.SwapStateData{
State: loopdb.StateHtlcPublished,
},
},
},
},
}
) )
step := &autoloopStep{ step := &autoloopStep{
minAmt: 1, minAmt: 1,
maxAmt: amt + 1, maxAmt: amt + 1,
quotesOut: quotes, quotesOut: quotes,
expectedOut: loopOuts, expectedOut: loopOuts,
existingOutSingle: singleLoopOut,
keepDestAddr: true,
} }
c.autoloop(step) c.autoloop(step)
@ -606,6 +637,18 @@ func TestCompositeRules(t *testing.T) {
}, },
}, },
} }
singleLoopOut = &loopdb.LoopOut{
Loop: loopdb.Loop{
Events: []*loopdb.LoopEvent{
{
SwapStateData: loopdb.SwapStateData{
State: loopdb.StateHtlcPublished,
},
},
},
},
}
) )
// Tick our autolooper with no existing swaps, we expect a loop out // Tick our autolooper with no existing swaps, we expect a loop out
@ -613,10 +656,11 @@ func TestCompositeRules(t *testing.T) {
// maximum to be greater than the swap amount for our peer swap (which // maximum to be greater than the swap amount for our peer swap (which
// is the larger of the two swaps). // is the larger of the two swaps).
step := &autoloopStep{ step := &autoloopStep{
minAmt: 1, minAmt: 1,
maxAmt: peerAmount + 1, maxAmt: peerAmount + 1,
quotesOut: quotes, quotesOut: quotes,
expectedOut: loopOuts, expectedOut: loopOuts,
existingOutSingle: singleLoopOut,
} }
c.autoloop(step) c.autoloop(step)
@ -928,6 +972,18 @@ func TestAutoloopBothTypes(t *testing.T) {
Label: labels.AutoloopLabel(swap.TypeIn), Label: labels.AutoloopLabel(swap.TypeIn),
Initiator: autoloopSwapInitiator, Initiator: autoloopSwapInitiator,
} }
singleLoopOut = &loopdb.LoopOut{
Loop: loopdb.Loop{
Events: []*loopdb.LoopEvent{
{
SwapStateData: loopdb.SwapStateData{
State: loopdb.StateHtlcPublished,
},
},
},
},
}
) )
step := &autoloopStep{ step := &autoloopStep{
@ -961,6 +1017,7 @@ func TestAutoloopBothTypes(t *testing.T) {
}, },
}, },
}, },
existingOutSingle: singleLoopOut,
} }
c.autoloop(step) c.autoloop(step)
c.stop() c.stop()

@ -2,7 +2,9 @@ package liquidity
import ( import (
"context" "context"
"reflect"
"testing" "testing"
"time"
"github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil"
"github.com/lightninglabs/lndclient" "github.com/lightninglabs/lndclient"
@ -11,8 +13,10 @@ import (
"github.com/lightninglabs/loop/swap" "github.com/lightninglabs/loop/swap"
"github.com/lightninglabs/loop/test" "github.com/lightninglabs/loop/test"
"github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/ticker" "github.com/lightningnetwork/lnd/ticker"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
type autoloopTestCtx struct { type autoloopTestCtx struct {
@ -45,9 +49,17 @@ type autoloopTestCtx struct {
// loopOuts is a channel that we get existing loop out swaps on. // loopOuts is a channel that we get existing loop out swaps on.
loopOuts chan []*loopdb.LoopOut loopOuts chan []*loopdb.LoopOut
// loopOutSingle is the single loop out returned from fetching a single
// swap from store.
loopOutSingle *loopdb.LoopOut
// loopIns is a channel that we get existing loop in swaps on. // loopIns is a channel that we get existing loop in swaps on.
loopIns chan []*loopdb.LoopIn loopIns chan []*loopdb.LoopIn
// loopInSingle is the single loop in returned from fetching a single
// swap from store.
loopInSingle *loopdb.LoopIn
// restrictions is a channel that we get swap restrictions on. // restrictions is a channel that we get swap restrictions on.
restrictions chan *Restrictions restrictions chan *Restrictions
@ -131,6 +143,9 @@ func newAutoloopTestCtx(t *testing.T, parameters Parameters,
ListLoopOut: func() ([]*loopdb.LoopOut, error) { ListLoopOut: func() ([]*loopdb.LoopOut, error) {
return <-testCtx.loopOuts, nil return <-testCtx.loopOuts, nil
}, },
GetLoopOut: func(hash lntypes.Hash) (*loopdb.LoopOut, error) {
return testCtx.loopOutSingle, nil
},
ListLoopIn: func() ([]*loopdb.LoopIn, error) { ListLoopIn: func() ([]*loopdb.LoopIn, error) {
return <-testCtx.loopIns, nil return <-testCtx.loopIns, nil
}, },
@ -188,6 +203,10 @@ func newAutoloopTestCtx(t *testing.T, parameters Parameters,
testCtx.manager = NewManager(cfg) testCtx.manager = NewManager(cfg)
err := testCtx.manager.setParameters(context.Background(), parameters) err := testCtx.manager.setParameters(context.Background(), parameters)
assert.NoError(t, err) assert.NoError(t, err)
// Override the payments check interval for the tests in order to not
// timeout.
testCtx.manager.params.CustomPaymentCheckInterval =
150 * time.Millisecond
<-done <-done
return testCtx return testCtx
} }
@ -241,14 +260,17 @@ type loopInRequestResp struct {
// autoloopStep contains all of the information to required to step // autoloopStep contains all of the information to required to step
// through an autoloop tick. // through an autoloop tick.
type autoloopStep struct { type autoloopStep struct {
minAmt btcutil.Amount minAmt btcutil.Amount
maxAmt btcutil.Amount maxAmt btcutil.Amount
existingOut []*loopdb.LoopOut existingOut []*loopdb.LoopOut
existingIn []*loopdb.LoopIn existingOutSingle *loopdb.LoopOut
quotesOut []quoteRequestResp existingIn []*loopdb.LoopIn
quotesIn []quoteInRequestResp existingInSingle *loopdb.LoopIn
expectedOut []loopOutRequestResp quotesOut []quoteRequestResp
expectedIn []loopInRequestResp quotesIn []quoteInRequestResp
expectedOut []loopOutRequestResp
expectedIn []loopInRequestResp
keepDestAddr bool
} }
// autoloop walks our test context through the process of triggering our // autoloop walks our test context through the process of triggering our
@ -269,6 +291,9 @@ func (c *autoloopTestCtx) autoloop(step *autoloopStep) {
c.loopOuts <- step.existingOut c.loopOuts <- step.existingOut
c.loopIns <- step.existingIn c.loopIns <- step.existingIn
c.loopOutSingle = step.existingOutSingle
c.loopInSingle = step.existingInSingle
// Assert that we query the server for a quote for each of our // Assert that we query the server for a quote for each of our
// recommended swaps. Note that this differs from our set of expected // recommended swaps. Note that this differs from our set of expected
// swaps because we may get quotes for suggested swaps but then just // swaps because we may get quotes for suggested swaps but then just
@ -299,25 +324,77 @@ func (c *autoloopTestCtx) autoloop(step *autoloopStep) {
c.quotes <- expected.quote c.quotes <- expected.quote
} }
// Assert that we dispatch the expected set of swaps. require.True(c.t, c.matchLoopOuts(step.expectedOut, step.keepDestAddr))
for _, expected := range step.expectedOut { require.True(c.t, c.matchLoopIns(step.expectedIn))
}
// matchLoopOuts checks that the actual loop out requests we got match the
// expected ones. The argument keepDestAddr is used to indicate whether we keep
// the actual loops destination address for the comparison. This is useful
// because we don't want to compare the destination address generated by the
// wallet mock. We want to compare the destination address when testing the
// autoloop DestAddr parameter for loop outs.
func (c *autoloopTestCtx) matchLoopOuts(swaps []loopOutRequestResp,
keepDestAddr bool) bool {
swapsCopy := make([]loopOutRequestResp, len(swaps))
copy(swapsCopy, swaps)
length := len(swapsCopy)
for i := 0; i < length; i++ {
actual := <-c.outRequest actual := <-c.outRequest
// Set our destination address to nil so that we do not need to if !keepDestAddr {
// provide the address that is obtained by the mock wallet kit.
if expected.request.DestAddr == nil {
actual.DestAddr = nil actual.DestAddr = nil
} }
assert.Equal(c.t, expected.request, actual) inner:
c.loopOut <- expected.response for index, swap := range swapsCopy {
equal := reflect.DeepEqual(swap.request, actual)
if equal {
c.loopOut <- swap.response
swapsCopy = append(
swapsCopy[:index],
swapsCopy[index+1:]...,
)
break inner
}
}
} }
for _, expected := range step.expectedIn { return len(swapsCopy) == 0
}
// matchLoopIns checks that the actual loop in requests we got match the
// expected ones.
func (c *autoloopTestCtx) matchLoopIns(
swaps []loopInRequestResp) bool {
swapsCopy := make([]loopInRequestResp, len(swaps))
copy(swapsCopy, swaps)
for i := 0; i < len(swapsCopy); i++ {
actual := <-c.inRequest actual := <-c.inRequest
assert.Equal(c.t, expected.request, actual) inner:
for i, swap := range swapsCopy {
equal := reflect.DeepEqual(swap.request, actual)
c.loopIn <- expected.response if equal {
c.loopIn <- swap.response
swapsCopy = append(
swapsCopy[:i], swapsCopy[i+1:]...,
)
break inner
}
}
} }
return len(swapsCopy) == 0
} }

Loading…
Cancel
Save