Skip to content

Commit 1681aaf

Browse files
authored
Merge pull request #362 from carlaKC/autoloop-includepeers
autoloop: include peer rules for inflight/budget limits
2 parents 2e2b38d + cc10d5b commit 1681aaf

File tree

4 files changed

+90
-4
lines changed

4 files changed

+90
-4
lines changed

liquidity/interface.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/lightninglabs/loop"
66
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
77
"github.com/lightningnetwork/lnd/lnwire"
8+
"github.com/lightningnetwork/lnd/routing/route"
89
)
910

1011
// FeeLimit is an interface implemented by different strategies for limiting
@@ -43,8 +44,17 @@ type swapSuggestion interface {
4344

4445
// channels returns the set of channels involved in the swap.
4546
channels() []lnwire.ShortChannelID
47+
48+
// peers returns the set of peers involved in the swap, taking a map
49+
// of known channel IDs to peers as an argument so that channel peers
50+
// can be looked up.
51+
peers(knownChans map[uint64]route.Vertex) []route.Vertex
4652
}
4753

54+
// Compile-time assertion that loopOutSwapSuggestion satisfies the
55+
// swapSuggestion interface.
56+
var _ swapSuggestion = (*loopOutSwapSuggestion)(nil)
57+
4858
type loopOutSwapSuggestion struct {
4959
loop.OutRequest
5060
}
@@ -69,3 +79,26 @@ func (l *loopOutSwapSuggestion) channels() []lnwire.ShortChannelID {
6979

7080
return channels
7181
}
82+
83+
// peers returns the set of peers that the loop out swap is restricted to.
84+
func (l *loopOutSwapSuggestion) peers(
85+
knownChans map[uint64]route.Vertex) []route.Vertex {
86+
87+
peers := make(map[route.Vertex]struct{}, len(knownChans))
88+
89+
for _, channel := range l.OutgoingChanSet {
90+
peer, ok := knownChans[channel]
91+
if !ok {
92+
log.Warnf("peer for channel: %v unknown", channel)
93+
}
94+
95+
peers[peer] = struct{}{}
96+
}
97+
98+
peerList := make([]route.Vertex, 0, len(peers))
99+
for peer := range peers {
100+
peerList = append(peerList, peer)
101+
}
102+
103+
return peerList
104+
}

liquidity/liquidity.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,8 +685,13 @@ func (m *Manager) SuggestSwaps(ctx context.Context, autoloop bool) (
685685
return nil, err
686686
}
687687

688+
// Collect a map of channel IDs to peer pubkeys, and a set of per-peer
689+
// balances which we will use for peer-level liquidity rules.
690+
channelPeers := make(map[uint64]route.Vertex)
688691
peerChannels := make(map[route.Vertex]*balances)
689692
for _, channel := range channels {
693+
channelPeers[channel.ChannelID] = channel.PubKeyBytes
694+
690695
bal, ok := peerChannels[channel.PubKeyBytes]
691696
if !ok {
692697
bal = &balances{}
@@ -777,6 +782,15 @@ func (m *Manager) SuggestSwaps(ctx context.Context, autoloop bool) (
777782
// setReason is a helper that adds a swap's channels to our disqualified
778783
// list with the reason provided.
779784
setReason := func(reason Reason, swap swapSuggestion) {
785+
for _, peer := range swap.peers(channelPeers) {
786+
_, ok := m.params.PeerRules[peer]
787+
if !ok {
788+
continue
789+
}
790+
791+
resp.DisqualifiedPeers[peer] = reason
792+
}
793+
780794
for _, channel := range swap.channels() {
781795
_, ok := m.params.ChannelRules[channel]
782796
if !ok {

liquidity/liquidity_test.go

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,10 @@ func TestInFlightLimit(t *testing.T) {
10981098
name string
10991099
maxInFlight int
11001100
existingSwaps []*loopdb.LoopOut
1101-
suggestions *Suggestions
1101+
// peerRules will only be set (instead of test default values)
1102+
// is it is non-nil.
1103+
peerRules map[route.Vertex]*ThresholdRule
1104+
suggestions *Suggestions
11021105
}{
11031106
{
11041107
name: "none in flight, extra space",
@@ -1175,6 +1178,31 @@ func TestInFlightLimit(t *testing.T) {
11751178
DisqualifiedPeers: noPeersDisqualified,
11761179
},
11771180
},
1181+
{
1182+
name: "peer rules max swaps exceeded",
1183+
maxInFlight: 2,
1184+
existingSwaps: []*loopdb.LoopOut{
1185+
{
1186+
Contract: autoOutContract,
1187+
},
1188+
},
1189+
// Create two peer-level rules, both in need of a swap,
1190+
// but peer 1 needs a larger swap so will be
1191+
// prioritized.
1192+
peerRules: map[route.Vertex]*ThresholdRule{
1193+
peer1: NewThresholdRule(50, 0),
1194+
peer2: NewThresholdRule(40, 0),
1195+
},
1196+
suggestions: &Suggestions{
1197+
OutSwaps: []loop.OutRequest{
1198+
chan1Rec,
1199+
},
1200+
DisqualifiedChans: noneDisqualified,
1201+
DisqualifiedPeers: map[route.Vertex]Reason{
1202+
peer2: ReasonInFlight,
1203+
},
1204+
},
1205+
},
11781206
}
11791207

11801208
for _, testCase := range tests {
@@ -1191,10 +1219,17 @@ func TestInFlightLimit(t *testing.T) {
11911219
}
11921220

11931221
params := defaultParameters
1194-
params.ChannelRules = map[lnwire.ShortChannelID]*ThresholdRule{
1195-
chanID1: chanRule,
1196-
chanID2: chanRule,
1222+
1223+
if testCase.peerRules != nil {
1224+
params.PeerRules = testCase.peerRules
1225+
} else {
1226+
params.ChannelRules =
1227+
map[lnwire.ShortChannelID]*ThresholdRule{
1228+
chanID1: chanRule,
1229+
chanID2: chanRule,
1230+
}
11971231
}
1232+
11981233
params.MaxAutoInFlight = testCase.maxInFlight
11991234

12001235
// By default we only have budget for one swap, increase

release_notes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ This file tracks release notes for the loop client.
2929
#### Breaking Changes
3030

3131
#### Bug Fixes
32+
* A bug that would not list autoloop rules set on a per-peer basis when they
33+
were excluded due to insufficient budget, or the number of swaps in flight
34+
has been corrected. These rules will now be included in the output of
35+
`suggestswaps` with other autoloop peer rules.

0 commit comments

Comments
 (0)