Merge pull request #362 from carlaKC/autoloop-includepeers

autoloop: include peer rules for inflight/budget limits
pull/363/head
Carla Kirk-Cohen 3 years ago committed by GitHub
commit 1681aafade
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,6 +5,7 @@ import (
"github.com/lightninglabs/loop" "github.com/lightninglabs/loop"
"github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwallet/chainfee"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/route"
) )
// FeeLimit is an interface implemented by different strategies for limiting // FeeLimit is an interface implemented by different strategies for limiting
@ -43,8 +44,17 @@ type swapSuggestion interface {
// channels returns the set of channels involved in the swap. // channels returns the set of channels involved in the swap.
channels() []lnwire.ShortChannelID channels() []lnwire.ShortChannelID
// peers returns the set of peers involved in the swap, taking a map
// of known channel IDs to peers as an argument so that channel peers
// can be looked up.
peers(knownChans map[uint64]route.Vertex) []route.Vertex
} }
// Compile-time assertion that loopOutSwapSuggestion satisfies the
// swapSuggestion interface.
var _ swapSuggestion = (*loopOutSwapSuggestion)(nil)
type loopOutSwapSuggestion struct { type loopOutSwapSuggestion struct {
loop.OutRequest loop.OutRequest
} }
@ -69,3 +79,26 @@ func (l *loopOutSwapSuggestion) channels() []lnwire.ShortChannelID {
return channels return channels
} }
// peers returns the set of peers that the loop out swap is restricted to.
func (l *loopOutSwapSuggestion) peers(
knownChans map[uint64]route.Vertex) []route.Vertex {
peers := make(map[route.Vertex]struct{}, len(knownChans))
for _, channel := range l.OutgoingChanSet {
peer, ok := knownChans[channel]
if !ok {
log.Warnf("peer for channel: %v unknown", channel)
}
peers[peer] = struct{}{}
}
peerList := make([]route.Vertex, 0, len(peers))
for peer := range peers {
peerList = append(peerList, peer)
}
return peerList
}

@ -685,8 +685,13 @@ func (m *Manager) SuggestSwaps(ctx context.Context, autoloop bool) (
return nil, err return nil, err
} }
// Collect a map of channel IDs to peer pubkeys, and a set of per-peer
// balances which we will use for peer-level liquidity rules.
channelPeers := make(map[uint64]route.Vertex)
peerChannels := make(map[route.Vertex]*balances) peerChannels := make(map[route.Vertex]*balances)
for _, channel := range channels { for _, channel := range channels {
channelPeers[channel.ChannelID] = channel.PubKeyBytes
bal, ok := peerChannels[channel.PubKeyBytes] bal, ok := peerChannels[channel.PubKeyBytes]
if !ok { if !ok {
bal = &balances{} bal = &balances{}
@ -777,6 +782,15 @@ func (m *Manager) SuggestSwaps(ctx context.Context, autoloop bool) (
// setReason is a helper that adds a swap's channels to our disqualified // setReason is a helper that adds a swap's channels to our disqualified
// list with the reason provided. // list with the reason provided.
setReason := func(reason Reason, swap swapSuggestion) { setReason := func(reason Reason, swap swapSuggestion) {
for _, peer := range swap.peers(channelPeers) {
_, ok := m.params.PeerRules[peer]
if !ok {
continue
}
resp.DisqualifiedPeers[peer] = reason
}
for _, channel := range swap.channels() { for _, channel := range swap.channels() {
_, ok := m.params.ChannelRules[channel] _, ok := m.params.ChannelRules[channel]
if !ok { if !ok {

@ -1098,7 +1098,10 @@ func TestInFlightLimit(t *testing.T) {
name string name string
maxInFlight int maxInFlight int
existingSwaps []*loopdb.LoopOut existingSwaps []*loopdb.LoopOut
suggestions *Suggestions // peerRules will only be set (instead of test default values)
// is it is non-nil.
peerRules map[route.Vertex]*ThresholdRule
suggestions *Suggestions
}{ }{
{ {
name: "none in flight, extra space", name: "none in flight, extra space",
@ -1175,6 +1178,31 @@ func TestInFlightLimit(t *testing.T) {
DisqualifiedPeers: noPeersDisqualified, DisqualifiedPeers: noPeersDisqualified,
}, },
}, },
{
name: "peer rules max swaps exceeded",
maxInFlight: 2,
existingSwaps: []*loopdb.LoopOut{
{
Contract: autoOutContract,
},
},
// Create two peer-level rules, both in need of a swap,
// but peer 1 needs a larger swap so will be
// prioritized.
peerRules: map[route.Vertex]*ThresholdRule{
peer1: NewThresholdRule(50, 0),
peer2: NewThresholdRule(40, 0),
},
suggestions: &Suggestions{
OutSwaps: []loop.OutRequest{
chan1Rec,
},
DisqualifiedChans: noneDisqualified,
DisqualifiedPeers: map[route.Vertex]Reason{
peer2: ReasonInFlight,
},
},
},
} }
for _, testCase := range tests { for _, testCase := range tests {
@ -1191,10 +1219,17 @@ func TestInFlightLimit(t *testing.T) {
} }
params := defaultParameters params := defaultParameters
params.ChannelRules = map[lnwire.ShortChannelID]*ThresholdRule{
chanID1: chanRule, if testCase.peerRules != nil {
chanID2: chanRule, params.PeerRules = testCase.peerRules
} else {
params.ChannelRules =
map[lnwire.ShortChannelID]*ThresholdRule{
chanID1: chanRule,
chanID2: chanRule,
}
} }
params.MaxAutoInFlight = testCase.maxInFlight params.MaxAutoInFlight = testCase.maxInFlight
// By default we only have budget for one swap, increase // By default we only have budget for one swap, increase

@ -29,3 +29,7 @@ This file tracks release notes for the loop client.
#### Breaking Changes #### Breaking Changes
#### Bug Fixes #### Bug Fixes
* A bug that would not list autoloop rules set on a per-peer basis when they
were excluded due to insufficient budget, or the number of swaps in flight
has been corrected. These rules will now be included in the output of
`suggestswaps` with other autoloop peer rules.

Loading…
Cancel
Save