|
|
|
@ -27,10 +27,21 @@ type autoloopTestCtx struct {
|
|
|
|
|
// quotes is a channel that we get loop out quote requests on.
|
|
|
|
|
quotes chan *loop.LoopOutQuote
|
|
|
|
|
|
|
|
|
|
// quoteRequestIn is a channel that requests for loop in quotes are
|
|
|
|
|
// pushed into.
|
|
|
|
|
quoteRequestIn chan *loop.LoopInQuoteRequest
|
|
|
|
|
|
|
|
|
|
// quotesIn is a channel that we get loop in quote responses on.
|
|
|
|
|
quotesIn chan *loop.LoopInQuote
|
|
|
|
|
|
|
|
|
|
// loopOutRestrictions is a channel that we get the server's
|
|
|
|
|
// restrictions on.
|
|
|
|
|
loopOutRestrictions chan *Restrictions
|
|
|
|
|
|
|
|
|
|
// loopInRestrictions is a channel that we get the server's
|
|
|
|
|
// loop in restrictions on.
|
|
|
|
|
loopInRestrictions chan *Restrictions
|
|
|
|
|
|
|
|
|
|
// loopOuts is a channel that we get existing loop out swaps on.
|
|
|
|
|
loopOuts chan []*loopdb.LoopOut
|
|
|
|
|
|
|
|
|
@ -47,6 +58,13 @@ type autoloopTestCtx struct {
|
|
|
|
|
// loopOut is a channel that we return loop out responses on.
|
|
|
|
|
loopOut chan *loop.LoopOutSwapInfo
|
|
|
|
|
|
|
|
|
|
// inRequest is a channel that requests to dispatch loop in swaps are
|
|
|
|
|
// pushed into.
|
|
|
|
|
inRequest chan *loop.LoopInRequest
|
|
|
|
|
|
|
|
|
|
// loopIn is a channel that we return loop in responses on.
|
|
|
|
|
loopIn chan *loop.LoopInSwapInfo
|
|
|
|
|
|
|
|
|
|
// errChan is a channel that we send run errors into.
|
|
|
|
|
errChan chan error
|
|
|
|
|
|
|
|
|
@ -80,14 +98,18 @@ func newAutoloopTestCtx(t *testing.T, parameters Parameters,
|
|
|
|
|
|
|
|
|
|
quoteRequest: make(chan *loop.LoopOutQuoteRequest),
|
|
|
|
|
quotes: make(chan *loop.LoopOutQuote),
|
|
|
|
|
quoteRequestIn: make(chan *loop.LoopInQuoteRequest),
|
|
|
|
|
quotesIn: make(chan *loop.LoopInQuote),
|
|
|
|
|
loopOutRestrictions: make(chan *Restrictions),
|
|
|
|
|
loopInRestrictions: make(chan *Restrictions),
|
|
|
|
|
loopOuts: make(chan []*loopdb.LoopOut),
|
|
|
|
|
loopIns: make(chan []*loopdb.LoopIn),
|
|
|
|
|
restrictions: make(chan *Restrictions),
|
|
|
|
|
outRequest: make(chan *loop.OutRequest),
|
|
|
|
|
loopOut: make(chan *loop.LoopOutSwapInfo),
|
|
|
|
|
|
|
|
|
|
errChan: make(chan error, 1),
|
|
|
|
|
inRequest: make(chan *loop.LoopInRequest),
|
|
|
|
|
loopIn: make(chan *loop.LoopInSwapInfo),
|
|
|
|
|
errChan: make(chan error, 1),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set lnd's channels to equal the set of channels we want for our
|
|
|
|
@ -96,10 +118,14 @@ func newAutoloopTestCtx(t *testing.T, parameters Parameters,
|
|
|
|
|
|
|
|
|
|
cfg := &Config{
|
|
|
|
|
AutoloopTicker: ticker.NewForce(DefaultAutoloopTicker),
|
|
|
|
|
Restrictions: func(context.Context, swap.Type) (*Restrictions,
|
|
|
|
|
Restrictions: func(_ context.Context, swapType swap.Type) (*Restrictions,
|
|
|
|
|
error) {
|
|
|
|
|
|
|
|
|
|
return <-testCtx.loopOutRestrictions, nil
|
|
|
|
|
if swapType == swap.TypeOut {
|
|
|
|
|
return <-testCtx.loopOutRestrictions, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return <-testCtx.loopInRestrictions, nil
|
|
|
|
|
},
|
|
|
|
|
ListLoopOut: func() ([]*loopdb.LoopOut, error) {
|
|
|
|
|
return <-testCtx.loopOuts, nil
|
|
|
|
@ -123,6 +149,20 @@ func newAutoloopTestCtx(t *testing.T, parameters Parameters,
|
|
|
|
|
|
|
|
|
|
return <-testCtx.loopOut, nil
|
|
|
|
|
},
|
|
|
|
|
LoopInQuote: func(_ context.Context,
|
|
|
|
|
req *loop.LoopInQuoteRequest) (*loop.LoopInQuote, error) {
|
|
|
|
|
|
|
|
|
|
testCtx.quoteRequestIn <- req
|
|
|
|
|
|
|
|
|
|
return <-testCtx.quotesIn, nil
|
|
|
|
|
},
|
|
|
|
|
LoopIn: func(_ context.Context,
|
|
|
|
|
req *loop.LoopInRequest) (*loop.LoopInSwapInfo, error) {
|
|
|
|
|
|
|
|
|
|
testCtx.inRequest <- req
|
|
|
|
|
|
|
|
|
|
return <-testCtx.loopIn, nil
|
|
|
|
|
},
|
|
|
|
|
MinimumConfirmations: loop.DefaultSweepConfTarget,
|
|
|
|
|
Lnd: &testCtx.lnd.LndServices,
|
|
|
|
|
Clock: testCtx.testClock,
|
|
|
|
@ -177,31 +217,70 @@ type loopOutRequestResp struct {
|
|
|
|
|
response *loop.LoopOutSwapInfo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// quoteInRequestResp pairs an expected loop in quote request with the response
|
|
|
|
|
// we would like to provide the manager with.
|
|
|
|
|
type quoteInRequestResp struct {
|
|
|
|
|
request *loop.LoopInQuoteRequest
|
|
|
|
|
quote *loop.LoopInQuote
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// loopInRequestResp pairs and expected loop in request with the response we
|
|
|
|
|
// would like the mocked server to respond with.
|
|
|
|
|
type loopInRequestResp struct {
|
|
|
|
|
request *loop.LoopInRequest
|
|
|
|
|
response *loop.LoopInSwapInfo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// autoloop walks our test context through the process of triggering our
|
|
|
|
|
// autoloop functionality, providing mocked values as required. The set of
|
|
|
|
|
// quotes provided indicates that we expect swap suggestions to be made (since
|
|
|
|
|
// we will query for a quote for each suggested swap). The set of expected
|
|
|
|
|
// swaps indicates whether we expect any of these swap suggestions to actually
|
|
|
|
|
// be dispatched by the autolooper.
|
|
|
|
|
func (c *autoloopTestCtx) autoloop(minAmt, maxAmt btcutil.Amount,
|
|
|
|
|
existingOut []*loopdb.LoopOut, quotes []quoteRequestResp,
|
|
|
|
|
expectedSwaps []loopOutRequestResp) {
|
|
|
|
|
|
|
|
|
|
func (c *autoloopTestCtx) autoloop(step *autoloopStep) {
|
|
|
|
|
// Tick our autoloop ticker to force assessing whether we want to loop.
|
|
|
|
|
c.manager.cfg.AutoloopTicker.Force <- testTime
|
|
|
|
|
|
|
|
|
|
// Send a mocked response from the server with the swap size limits.
|
|
|
|
|
c.loopOutRestrictions <- NewRestrictions(minAmt, maxAmt)
|
|
|
|
|
c.loopOutRestrictions <- NewRestrictions(step.minAmt, step.maxAmt)
|
|
|
|
|
c.loopInRestrictions <- NewRestrictions(step.minAmt, step.maxAmt)
|
|
|
|
|
|
|
|
|
|
// Provide the liquidity manager with our desired existing set of swaps.
|
|
|
|
|
c.loopOuts <- existingOut
|
|
|
|
|
c.loopIns <- nil
|
|
|
|
|
c.loopOuts <- step.existingOut
|
|
|
|
|
c.loopIns <- step.existingIn
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
// log them.
|
|
|
|
|
for _, expected := range quotes {
|
|
|
|
|
for _, expected := range step.quotesIn {
|
|
|
|
|
request := <-c.quoteRequestIn
|
|
|
|
|
assert.Equal(
|
|
|
|
|
c.t, expected.request.Amount, request.Amount,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert.Equal(
|
|
|
|
|
c.t, expected.request.HtlcConfTarget,
|
|
|
|
|
request.HtlcConfTarget,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
c.quotesIn <- expected.quote
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, expected := range step.quotesOut {
|
|
|
|
|
request := <-c.quoteRequest
|
|
|
|
|
assert.Equal(
|
|
|
|
|
c.t, expected.request.Amount, request.Amount,
|
|
|
|
@ -214,7 +293,7 @@ func (c *autoloopTestCtx) autoloop(minAmt, maxAmt btcutil.Amount,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Assert that we dispatch the expected set of swaps.
|
|
|
|
|
for _, expected := range expectedSwaps {
|
|
|
|
|
for _, expected := range step.expectedOut {
|
|
|
|
|
actual := <-c.outRequest
|
|
|
|
|
|
|
|
|
|
// Set our destination address to nil so that we do not need to
|
|
|
|
@ -224,4 +303,12 @@ func (c *autoloopTestCtx) autoloop(minAmt, maxAmt btcutil.Amount,
|
|
|
|
|
assert.Equal(c.t, expected.request, actual)
|
|
|
|
|
c.loopOut <- expected.response
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, expected := range step.expectedIn {
|
|
|
|
|
actual := <-c.inRequest
|
|
|
|
|
|
|
|
|
|
assert.Equal(c.t, expected.request, actual)
|
|
|
|
|
|
|
|
|
|
c.loopIn <- expected.response
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|