mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
liquidity: fix tests for autoloop sticky loop out
This commit is contained in:
parent
af7a470aea
commit
c17e5a6fc6
2 changed files with 176 additions and 42 deletions
|
|
@ -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
|
||||
// swap to be dispatched for each channel.
|
||||
step := &autoloopStep{
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
quotesOut: quotes,
|
||||
expectedOut: loopOuts,
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
quotesOut: quotes,
|
||||
expectedOut: loopOuts,
|
||||
existingOutSingle: singleLoopOut,
|
||||
}
|
||||
|
||||
c.autoloop(step)
|
||||
|
||||
// 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{
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
existingOut: existing,
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
existingOut: existing,
|
||||
existingOutSingle: singleLoopOut,
|
||||
}
|
||||
c.autoloop(step)
|
||||
|
||||
|
|
@ -278,11 +293,12 @@ func TestAutoLoopEnabled(t *testing.T) {
|
|||
// still has balances which reflect that we need to swap), but nothing
|
||||
// for channel 2, since it has had a failure.
|
||||
step = &autoloopStep{
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
existingOut: existing,
|
||||
quotesOut: quotes,
|
||||
expectedOut: loopOuts,
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
existingOut: existing,
|
||||
quotesOut: quotes,
|
||||
expectedOut: loopOuts,
|
||||
existingOutSingle: singleLoopOut,
|
||||
}
|
||||
c.autoloop(step)
|
||||
|
||||
|
|
@ -299,10 +315,11 @@ func TestAutoLoopEnabled(t *testing.T) {
|
|||
}
|
||||
|
||||
step = &autoloopStep{
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
existingOut: existing,
|
||||
quotesOut: quotes,
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
existingOut: existing,
|
||||
quotesOut: quotes,
|
||||
existingOutSingle: singleLoopOut,
|
||||
}
|
||||
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{
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
quotesOut: quotes,
|
||||
expectedOut: loopOuts,
|
||||
minAmt: 1,
|
||||
maxAmt: amt + 1,
|
||||
quotesOut: quotes,
|
||||
expectedOut: loopOuts,
|
||||
existingOutSingle: singleLoopOut,
|
||||
keepDestAddr: true,
|
||||
}
|
||||
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
|
||||
|
|
@ -613,10 +656,11 @@ func TestCompositeRules(t *testing.T) {
|
|||
// maximum to be greater than the swap amount for our peer swap (which
|
||||
// is the larger of the two swaps).
|
||||
step := &autoloopStep{
|
||||
minAmt: 1,
|
||||
maxAmt: peerAmount + 1,
|
||||
quotesOut: quotes,
|
||||
expectedOut: loopOuts,
|
||||
minAmt: 1,
|
||||
maxAmt: peerAmount + 1,
|
||||
quotesOut: quotes,
|
||||
expectedOut: loopOuts,
|
||||
existingOutSingle: singleLoopOut,
|
||||
}
|
||||
c.autoloop(step)
|
||||
|
||||
|
|
@ -928,6 +972,18 @@ func TestAutoloopBothTypes(t *testing.T) {
|
|||
Label: labels.AutoloopLabel(swap.TypeIn),
|
||||
Initiator: autoloopSwapInitiator,
|
||||
}
|
||||
|
||||
singleLoopOut = &loopdb.LoopOut{
|
||||
Loop: loopdb.Loop{
|
||||
Events: []*loopdb.LoopEvent{
|
||||
{
|
||||
SwapStateData: loopdb.SwapStateData{
|
||||
State: loopdb.StateHtlcPublished,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
step := &autoloopStep{
|
||||
|
|
@ -961,6 +1017,7 @@ func TestAutoloopBothTypes(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
existingOutSingle: singleLoopOut,
|
||||
}
|
||||
c.autoloop(step)
|
||||
c.stop()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ package liquidity
|
|||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/lightninglabs/lndclient"
|
||||
|
|
@ -11,8 +13,10 @@ import (
|
|||
"github.com/lightninglabs/loop/swap"
|
||||
"github.com/lightninglabs/loop/test"
|
||||
"github.com/lightningnetwork/lnd/clock"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/ticker"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type autoloopTestCtx struct {
|
||||
|
|
@ -45,9 +49,17 @@ type autoloopTestCtx struct {
|
|||
// loopOuts is a channel that we get existing loop out swaps on.
|
||||
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 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 chan *Restrictions
|
||||
|
||||
|
|
@ -131,6 +143,9 @@ func newAutoloopTestCtx(t *testing.T, parameters Parameters,
|
|||
ListLoopOut: func() ([]*loopdb.LoopOut, error) {
|
||||
return <-testCtx.loopOuts, nil
|
||||
},
|
||||
GetLoopOut: func(hash lntypes.Hash) (*loopdb.LoopOut, error) {
|
||||
return testCtx.loopOutSingle, nil
|
||||
},
|
||||
ListLoopIn: func() ([]*loopdb.LoopIn, error) {
|
||||
return <-testCtx.loopIns, nil
|
||||
},
|
||||
|
|
@ -188,6 +203,10 @@ func newAutoloopTestCtx(t *testing.T, parameters Parameters,
|
|||
testCtx.manager = NewManager(cfg)
|
||||
err := testCtx.manager.setParameters(context.Background(), parameters)
|
||||
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
|
||||
return testCtx
|
||||
}
|
||||
|
|
@ -241,14 +260,17 @@ type loopInRequestResp struct {
|
|||
// autoloopStep contains all of the information to required to step
|
||||
// through an autoloop tick.
|
||||
type autoloopStep struct {
|
||||
minAmt btcutil.Amount
|
||||
maxAmt btcutil.Amount
|
||||
existingOut []*loopdb.LoopOut
|
||||
existingIn []*loopdb.LoopIn
|
||||
quotesOut []quoteRequestResp
|
||||
quotesIn []quoteInRequestResp
|
||||
expectedOut []loopOutRequestResp
|
||||
expectedIn []loopInRequestResp
|
||||
minAmt btcutil.Amount
|
||||
maxAmt btcutil.Amount
|
||||
existingOut []*loopdb.LoopOut
|
||||
existingOutSingle *loopdb.LoopOut
|
||||
existingIn []*loopdb.LoopIn
|
||||
existingInSingle *loopdb.LoopIn
|
||||
quotesOut []quoteRequestResp
|
||||
quotesIn []quoteInRequestResp
|
||||
expectedOut []loopOutRequestResp
|
||||
expectedIn []loopInRequestResp
|
||||
keepDestAddr bool
|
||||
}
|
||||
|
||||
// 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.loopIns <- step.existingIn
|
||||
|
||||
c.loopOutSingle = step.existingOutSingle
|
||||
c.loopInSingle = step.existingInSingle
|
||||
|
||||
// Assert that we query the server for a quote for each of our
|
||||
// recommended swaps. Note that this differs from our set of expected
|
||||
// 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
|
||||
}
|
||||
|
||||
// Assert that we dispatch the expected set of swaps.
|
||||
for _, expected := range step.expectedOut {
|
||||
require.True(c.t, c.matchLoopOuts(step.expectedOut, step.keepDestAddr))
|
||||
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
|
||||
|
||||
// Set our destination address to nil so that we do not need to
|
||||
// provide the address that is obtained by the mock wallet kit.
|
||||
if expected.request.DestAddr == nil {
|
||||
if !keepDestAddr {
|
||||
actual.DestAddr = nil
|
||||
}
|
||||
|
||||
assert.Equal(c.t, expected.request, actual)
|
||||
c.loopOut <- expected.response
|
||||
inner:
|
||||
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
|
||||
|
||||
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…
Add table
Add a link
Reference in a new issue