Skip to content

Commit 3316c4b

Browse files
authored
Merge pull request #205 from joostjager/channel-set
loop out: allow outbound channel set for multi-loops
2 parents 3f10407 + 23a1e33 commit 3316c4b

File tree

19 files changed

+820
-279
lines changed

19 files changed

+820
-279
lines changed

client.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,8 @@ func (s *Client) resumeSwaps(ctx context.Context,
359359
func (s *Client) LoopOut(globalCtx context.Context,
360360
request *OutRequest) (*lntypes.Hash, btcutil.Address, error) {
361361

362-
log.Infof("LoopOut %v to %v (channel: %v)",
363-
request.Amount, request.DestAddr,
364-
request.LoopOutChannel,
362+
log.Infof("LoopOut %v to %v (channels: %v)",
363+
request.Amount, request.DestAddr, request.OutgoingChanSet,
365364
)
366365

367366
if err := s.waitForInitialized(globalCtx); err != nil {

cmd/loop/loopout.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package main
33
import (
44
"context"
55
"fmt"
6+
"strconv"
7+
"strings"
68
"time"
79

810
"github.com/btcsuite/btcutil"
@@ -25,10 +27,10 @@ var loopOutCommand = cli.Command{
2527
Optionally a BASE58/bech32 encoded bitcoin destination address may be
2628
specified. If not specified, a new wallet address will be generated.`,
2729
Flags: []cli.Flag{
28-
cli.Uint64Flag{
30+
cli.StringFlag{
2931
Name: "channel",
30-
Usage: "the 8-byte compact channel ID of the channel " +
31-
"to loop out",
32+
Usage: "the comma-separated list of short " +
33+
"channel IDs of the channels to loop out",
3234
},
3335
cli.StringFlag{
3436
Name: "addr",
@@ -87,6 +89,17 @@ func loopOut(ctx *cli.Context) error {
8789
return err
8890
}
8991

92+
// Parse outgoing channel set.
93+
chanStrings := strings.Split(ctx.String("channel"), ",")
94+
var outgoingChanSet []uint64
95+
for _, chanString := range chanStrings {
96+
chanID, err := strconv.ParseUint(chanString, 10, 64)
97+
if err != nil {
98+
return err
99+
}
100+
outgoingChanSet = append(outgoingChanSet, chanID)
101+
}
102+
90103
var destAddr string
91104
switch {
92105
case ctx.IsSet("addr"):
@@ -145,11 +158,6 @@ func loopOut(ctx *cli.Context) error {
145158
return err
146159
}
147160

148-
var unchargeChannel uint64
149-
if ctx.IsSet("channel") {
150-
unchargeChannel = ctx.Uint64("channel")
151-
}
152-
153161
resp, err := client.LoopOut(context.Background(), &looprpc.LoopOutRequest{
154162
Amt: int64(amt),
155163
Dest: destAddr,
@@ -158,7 +166,7 @@ func loopOut(ctx *cli.Context) error {
158166
MaxSwapFee: int64(limits.maxSwapFee),
159167
MaxPrepayRoutingFee: int64(*limits.maxPrepayRoutingFee),
160168
MaxSwapRoutingFee: int64(*limits.maxSwapRoutingFee),
161-
LoopOutChannel: unchargeChannel,
169+
OutgoingChanSet: outgoingChanSet,
162170
SweepConfTarget: sweepConfTarget,
163171
SwapPublicationDeadline: uint64(swapDeadline.Unix()),
164172
})

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module github.com/lightninglabs/loop
22

33
require (
4-
github.com/btcsuite/btcd v0.20.1-beta
4+
github.com/btcsuite/btcd v0.20.1-beta.0.20200515232429-9f0179fd2c46
55
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
66
github.com/btcsuite/btcutil v1.0.2
77
github.com/coreos/bbolt v1.3.3
@@ -11,7 +11,7 @@ require (
1111
github.com/grpc-ecosystem/grpc-gateway v1.12.2
1212
github.com/jessevdk/go-flags v1.4.0
1313
github.com/lightninglabs/protobuf-hex-display v1.3.3-0.20191212020323-b444784ce75d
14-
github.com/lightningnetwork/lnd v0.10.0-beta.rc5
14+
github.com/lightningnetwork/lnd v0.10.1-beta.rc1
1515
github.com/lightningnetwork/lnd/queue v1.0.3
1616
github.com/urfave/cli v1.20.0
1717
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ github.com/btcsuite/btcd v0.0.0-20190629003639-c26ffa870fd8/go.mod h1:3J08xEfcug
2424
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
2525
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
2626
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
27+
github.com/btcsuite/btcd v0.20.1-beta.0.20200513120220-b470eee47728/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
28+
github.com/btcsuite/btcd v0.20.1-beta.0.20200515232429-9f0179fd2c46 h1:QyTpiR5nQe94vza2qkvf7Ns8XX2Rjh/vdIhO3RzGj4o=
29+
github.com/btcsuite/btcd v0.20.1-beta.0.20200515232429-9f0179fd2c46/go.mod h1:Yktc19YNjh/Iz2//CX0vfRTS4IJKM/RKO5YZ9Fn+Pgo=
2730
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
2831
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
2932
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
@@ -34,6 +37,8 @@ github.com/btcsuite/btcutil/psbt v1.0.2 h1:gCVY3KxdoEVU7Q6TjusPO+GANIwVgr9yTLqM+
3437
github.com/btcsuite/btcutil/psbt v1.0.2/go.mod h1:LVveMu4VaNSkIRTZu2+ut0HDBRuYjqGocxDMNS1KuGQ=
3538
github.com/btcsuite/btcwallet v0.11.1-0.20200403222202-ada7ca077ebb h1:kkq2SSCy+OrC7GVZLIqutoHVR2yW4SJQdX70jtmuLDI=
3639
github.com/btcsuite/btcwallet v0.11.1-0.20200403222202-ada7ca077ebb/go.mod h1:9fJNm1aXi4q9P5Nk23mmqppCy1Le3f2/JMWj9UXKkCc=
40+
github.com/btcsuite/btcwallet v0.11.1-0.20200515224913-e0e62245ecbe h1:0m9uXDcnUc3Fv72635O/MfLbhbW+0hfSVgRiWezpkHU=
41+
github.com/btcsuite/btcwallet v0.11.1-0.20200515224913-e0e62245ecbe/go.mod h1:9+AH3V5mcTtNXTKe+fe63fDLKGOwQbZqmvOVUef+JFE=
3742
github.com/btcsuite/btcwallet/wallet/txauthor v1.0.0 h1:KGHMW5sd7yDdDMkCZ/JpP0KltolFsQcB973brBnfj4c=
3843
github.com/btcsuite/btcwallet/wallet/txauthor v1.0.0/go.mod h1:VufDts7bd/zs3GV13f/lXc/0lXrPnvxD/NvmpG/FEKU=
3944
github.com/btcsuite/btcwallet/wallet/txrules v1.0.0 h1:2VsfS0sBedcM5KmDzRMT3+b6xobqWveZGvjb+jFez5w=
@@ -46,6 +51,8 @@ github.com/btcsuite/btcwallet/walletdb v1.3.1 h1:lW1Ac3F1jJY4K11P+YQtRNcP5jFk27A
4651
github.com/btcsuite/btcwallet/walletdb v1.3.1/go.mod h1:9cwc1Yyg4uvd4ZdfdoMnALji+V9gfWSMfxEdLdR5Vwc=
4752
github.com/btcsuite/btcwallet/wtxmgr v1.0.0 h1:aIHgViEmZmZfe0tQQqF1xyd2qBqFWxX5vZXkkbjtbeA=
4853
github.com/btcsuite/btcwallet/wtxmgr v1.0.0/go.mod h1:vc4gBprll6BP0UJ+AIGDaySoc7MdAmZf8kelfNb8CFY=
54+
github.com/btcsuite/btcwallet/wtxmgr v1.1.1-0.20200515224913-e0e62245ecbe h1:yQbJVYfsKbdqDQNLxd4hhiLSiMkIygefW5mSHMsdKpc=
55+
github.com/btcsuite/btcwallet/wtxmgr v1.1.1-0.20200515224913-e0e62245ecbe/go.mod h1:OwC0W0HhUszbWdvJvH6xvgabKSJ0lXl11YbmmqF9YXQ=
4956
github.com/btcsuite/fastsha256 v0.0.0-20160815193821-637e65642941 h1:kij1x2aL7VE6gtx8KMIt8PGPgI5GV9LgtHFG5KaEMPY=
5057
github.com/btcsuite/fastsha256 v0.0.0-20160815193821-637e65642941/go.mod h1:QcFA8DZHtuIAdYKCq/BzELOaznRsCvwf4zTPmaYwaig=
5158
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
@@ -157,6 +164,8 @@ github.com/lightningnetwork/lightning-onion v1.0.1 h1:qChGgS5+aPxFeR6JiUsGvanei1
157164
github.com/lightningnetwork/lightning-onion v1.0.1/go.mod h1:rigfi6Af/KqsF7Za0hOgcyq2PNH4AN70AaMRxcJkff4=
158165
github.com/lightningnetwork/lnd v0.10.0-beta.rc5 h1:HcX35Djwk+xoNQe/LA7HnQ11jzbq68TAcpBluhNIKqc=
159166
github.com/lightningnetwork/lnd v0.10.0-beta.rc5/go.mod h1:mEnmP+sSgiKUFBozT3I5xEOgRAREMEWd/3lcWDrB+5E=
167+
github.com/lightningnetwork/lnd v0.10.1-beta.rc1 h1:4uBkLHrxeIf6ad5AHlFhGcOhtbvmYwK4iTcDMixmLpw=
168+
github.com/lightningnetwork/lnd v0.10.1-beta.rc1/go.mod h1:mRd+8n/QOlAiolWVnt1RaTzxVvOyplT3J5uYwUb/EDw=
160169
github.com/lightningnetwork/lnd/cert v1.0.2/go.mod h1:fmtemlSMf5t4hsQmcprSoOykypAPp+9c+0d0iqTScMo=
161170
github.com/lightningnetwork/lnd/queue v1.0.1 h1:jzJKcTy3Nj5lQrooJ3aaw9Lau3I0IwvQR5sqtjdv2R0=
162171
github.com/lightningnetwork/lnd/queue v1.0.1/go.mod h1:vaQwexir73flPW43Mrm7JOgJHmcEFBWWSl9HlyASoms=
@@ -222,6 +231,8 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
222231
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
223232
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d h1:2+ZP7EfsZV7Vvmx3TIqSlSzATMkTAKqM14YGFPoSKjI=
224233
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
234+
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
235+
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
225236
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
226237
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
227238
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=

interface.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ type OutRequest struct {
6464
// client sweep tx.
6565
SweepConfTarget int32
6666

67-
// LoopOutChannel optionally specifies the short channel id of the
68-
// channel to loop out.
69-
LoopOutChannel *uint64
67+
// OutgoingChanSet optionally specifies the short channel ids of the
68+
// channels that may be used to loop out.
69+
OutgoingChanSet loopdb.ChannelSet
7070

7171
// SwapPublicationDeadline can be set by the client to allow the server
7272
// delaying publication of the swap HTLC to save on chain fees.

lndclient/lnd_services.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ var (
3131
minimalCompatibleVersion = &verrpc.Version{
3232
AppMajor: 0,
3333
AppMinor: 10,
34-
AppPatch: 0,
34+
AppPatch: 1,
3535
BuildTags: []string{
3636
"signrpc", "walletrpc", "chainrpc", "invoicesrpc",
3737
},

lndclient/router_client.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,20 @@ type SendPaymentRequest struct {
6464
// are only processed when the Invoice field is empty.
6565
Invoice string
6666

67-
MaxFee btcutil.Amount
68-
MaxCltv *int32
69-
OutgoingChannel *uint64
70-
Timeout time.Duration
67+
// MaxFee is the fee limit for this payment.
68+
MaxFee btcutil.Amount
69+
70+
// MaxCltv is the maximum timelock for this payment. If nil, there is no
71+
// maximum.
72+
MaxCltv *int32
73+
74+
// OutgoingChanIds is a restriction on the set of possible outgoing
75+
// channels. If nil or empty, there is no restriction.
76+
OutgoingChanIds []uint64
77+
78+
// Timeout is the payment loop timeout. After this time, no new payment
79+
// attempts will be started.
80+
Timeout time.Duration
7181

7282
// Target is the node in which the payment should be routed towards.
7383
Target route.Vertex
@@ -126,17 +136,16 @@ func (r *routerClient) SendPayment(ctx context.Context,
126136

127137
rpcCtx := r.routerKitMac.WithMacaroonAuth(ctx)
128138
rpcReq := &routerrpc.SendPaymentRequest{
129-
FeeLimitSat: int64(request.MaxFee),
130-
PaymentRequest: request.Invoice,
131-
TimeoutSeconds: int32(request.Timeout.Seconds()),
132-
MaxParts: request.MaxParts,
139+
FeeLimitSat: int64(request.MaxFee),
140+
PaymentRequest: request.Invoice,
141+
TimeoutSeconds: int32(request.Timeout.Seconds()),
142+
MaxParts: request.MaxParts,
143+
OutgoingChanIds: request.OutgoingChanIds,
133144
}
134145
if request.MaxCltv != nil {
135146
rpcReq.CltvLimit = *request.MaxCltv
136147
}
137-
if request.OutgoingChannel != nil {
138-
rpcReq.OutgoingChanId = *request.OutgoingChannel
139-
}
148+
140149
if request.LastHopPubkey != nil {
141150
rpcReq.LastHopPubkey = request.LastHopPubkey[:]
142151
}

loopd/start.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ var (
2424
LoopMinRequiredLndVersion = &verrpc.Version{
2525
AppMajor: 0,
2626
AppMinor: 10,
27-
AppPatch: 0,
27+
AppPatch: 1,
2828
BuildTags: []string{
2929
"signrpc", "walletrpc", "chainrpc", "invoicesrpc",
3030
},

loopd/swapclient_server.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,19 @@ func (s *swapClientServer) LoopOut(ctx context.Context,
8989
int64(in.SwapPublicationDeadline), 0,
9090
),
9191
}
92-
if in.LoopOutChannel != 0 {
93-
req.LoopOutChannel = &in.LoopOutChannel
92+
93+
switch {
94+
case in.LoopOutChannel != 0 && len(in.OutgoingChanSet) > 0:
95+
return nil, errors.New("loop_out_channel and outgoing_" +
96+
"chan_ids are mutually exclusive")
97+
98+
case in.LoopOutChannel != 0:
99+
req.OutgoingChanSet = loopdb.ChannelSet{in.LoopOutChannel}
100+
101+
default:
102+
req.OutgoingChanSet = in.OutgoingChanSet
94103
}
104+
95105
hash, htlc, err := s.impl.LoopOut(ctx, req)
96106
if err != nil {
97107
log.Errorf("LoopOut: %v", err)

loopd/view.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package loopd
22

33
import (
44
"fmt"
5-
"strconv"
65

76
"github.com/btcsuite/btcd/chaincfg"
87
"github.com/lightninglabs/loop"
@@ -64,13 +63,8 @@ func viewOut(swapClient *loop.Client, chainParams *chaincfg.Params) error {
6463
fmt.Printf(" Preimage: %v\n", s.Contract.Preimage)
6564
fmt.Printf(" Htlc address: %v\n", htlc.Address)
6665

67-
unchargeChannel := "any"
68-
if s.Contract.UnchargeChannel != nil {
69-
unchargeChannel = strconv.FormatUint(
70-
*s.Contract.UnchargeChannel, 10,
71-
)
72-
}
73-
fmt.Printf(" Uncharge channel: %v\n", unchargeChannel)
66+
fmt.Printf(" Uncharge channels: %v\n",
67+
s.Contract.OutgoingChanSet)
7468
fmt.Printf(" Dest: %v\n", s.Contract.DestAddr)
7569
fmt.Printf(" Amt: %v, Expiry: %v\n",
7670
s.Contract.AmountRequested, s.Contract.CltvExpiry,

0 commit comments

Comments
 (0)