liquidity: fail suggest swaps when no rules are set

In an effort to surface more information about why autoloop is not
executing, we add an error when suggest swaps is called with no rules.
In other cases we can surface a reason enum with each rule that is set,
but in the case where we have no rules, there are no results to
accompany with reasons.
pull/332/head
carla 3 years ago
parent 67f417188d
commit 7ba1821696
No known key found for this signature in database
GPG Key ID: 4CA7FE54A6213C91

@ -2,12 +2,15 @@ package main
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"strconv" "strconv"
"github.com/lightninglabs/loop/liquidity" "github.com/lightninglabs/loop/liquidity"
"github.com/lightninglabs/loop/looprpc" "github.com/lightninglabs/loop/looprpc"
"github.com/urfave/cli" "github.com/urfave/cli"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
var getLiquidityParamsCommand = cli.Command{ var getLiquidityParamsCommand = cli.Command{
@ -411,11 +414,22 @@ func suggestSwap(ctx *cli.Context) error {
resp, err := client.SuggestSwaps( resp, err := client.SuggestSwaps(
context.Background(), &looprpc.SuggestSwapsRequest{}, context.Background(), &looprpc.SuggestSwapsRequest{},
) )
if err != nil { if err == nil {
printJSON(resp)
return nil
}
// If we got an error because no rules are set, we want to display a
// friendly message.
rpcErr, ok := status.FromError(err)
if !ok {
return err return err
} }
printJSON(resp) if rpcErr.Code() != codes.FailedPrecondition {
return err
}
return nil return errors.New("no rules set for autolooper, please set rules " +
"using the setrule command")
} }

@ -178,6 +178,9 @@ var (
// less than the server minimum. // less than the server minimum.
ErrMinLessThanServer = errors.New("minimum swap amount is less than " + ErrMinLessThanServer = errors.New("minimum swap amount is less than " +
"server minimum") "server minimum")
// ErrNoRules is returned when no rules are set for swap suggestions.
ErrNoRules = errors.New("no rules set for autoloop")
) )
// Config contains the external functionality required to run the // Config contains the external functionality required to run the
@ -439,7 +442,14 @@ func (m *Manager) Run(ctx context.Context) error {
for { for {
select { select {
case <-m.cfg.AutoloopTicker.Ticks(): case <-m.cfg.AutoloopTicker.Ticks():
if err := m.autoloop(ctx); err != nil { err := m.autoloop(ctx)
switch err {
case ErrNoRules:
log.Debugf("No rules configured for autoloop")
case nil:
default:
log.Errorf("autoloop failed: %v", err) log.Errorf("autoloop failed: %v", err)
} }
@ -562,7 +572,7 @@ func (m *Manager) SuggestSwaps(ctx context.Context, autoloop bool) (
// If we have no rules set, exit early to avoid unnecessary calls to // If we have no rules set, exit early to avoid unnecessary calls to
// lnd and the server. // lnd and the server.
if len(m.params.ChannelRules) == 0 { if len(m.params.ChannelRules) == 0 {
return nil, nil return nil, ErrNoRules
} }
// If our start date is in the future, we interpret this as meaning that // If our start date is in the future, we interpret this as meaning that

@ -496,10 +496,12 @@ func TestSuggestSwaps(t *testing.T) {
name string name string
rules map[lnwire.ShortChannelID]*ThresholdRule rules map[lnwire.ShortChannelID]*ThresholdRule
swaps []loop.OutRequest swaps []loop.OutRequest
err error
}{ }{
{ {
name: "no rules", name: "no rules",
rules: map[lnwire.ShortChannelID]*ThresholdRule{}, rules: map[lnwire.ShortChannelID]*ThresholdRule{},
err: ErrNoRules,
}, },
{ {
name: "loop out", name: "loop out",
@ -534,7 +536,7 @@ func TestSuggestSwaps(t *testing.T) {
testSuggestSwaps( testSuggestSwaps(
t, newSuggestSwapsSetup(cfg, lnd, params), t, newSuggestSwapsSetup(cfg, lnd, params),
testCase.swaps, nil, testCase.swaps, testCase.err,
) )
}) })
} }

@ -21,6 +21,8 @@ import (
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/queue" "github.com/lightningnetwork/lnd/queue"
"github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/routing/route"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) )
const ( const (
@ -703,7 +705,13 @@ func (s *swapClientServer) SuggestSwaps(ctx context.Context,
_ *looprpc.SuggestSwapsRequest) (*looprpc.SuggestSwapsResponse, error) { _ *looprpc.SuggestSwapsRequest) (*looprpc.SuggestSwapsResponse, error) {
swaps, err := s.liquidityMgr.SuggestSwaps(ctx, false) swaps, err := s.liquidityMgr.SuggestSwaps(ctx, false)
if err != nil { switch err {
case liquidity.ErrNoRules:
return nil, status.Error(codes.FailedPrecondition, err.Error())
case nil:
default:
return nil, err return nil, err
} }

@ -31,5 +31,8 @@ This file tracks release notes for the loop client.
been renamed to `Autoloop`, `AutoloopBudgetSat` and `AutoloopBudgetStartSec`. been renamed to `Autoloop`, `AutoloopBudgetSat` and `AutoloopBudgetStartSec`.
* The `autoout` flag for enabling automatic dispatch of loop out swaps has been * The `autoout` flag for enabling automatic dispatch of loop out swaps has been
renamed to `autoloop` so that it can cover loop out and loop in. renamed to `autoloop` so that it can cover loop out and loop in.
* The `SuggestSwaps` rpc call will now fail with a `FailedPrecondition` grpc
error code if no rules are configured for the autolooper. Previously the rpc
would return an empty response.
#### Bug Fixes #### Bug Fixes

Loading…
Cancel
Save