mirror of
https://github.com/lightninglabs/loop
synced 2024-11-09 19:10:47 +00:00
Merge pull request #362 from carlaKC/autoloop-includepeers
autoloop: include peer rules for inflight/budget limits
This commit is contained in:
commit
1681aafade
@ -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,6 +1098,9 @@ func TestInFlightLimit(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
maxInFlight int
|
maxInFlight int
|
||||||
existingSwaps []*loopdb.LoopOut
|
existingSwaps []*loopdb.LoopOut
|
||||||
|
// peerRules will only be set (instead of test default values)
|
||||||
|
// is it is non-nil.
|
||||||
|
peerRules map[route.Vertex]*ThresholdRule
|
||||||
suggestions *Suggestions
|
suggestions *Suggestions
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -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{
|
|
||||||
|
if testCase.peerRules != nil {
|
||||||
|
params.PeerRules = testCase.peerRules
|
||||||
|
} else {
|
||||||
|
params.ChannelRules =
|
||||||
|
map[lnwire.ShortChannelID]*ThresholdRule{
|
||||||
chanID1: chanRule,
|
chanID1: chanRule,
|
||||||
chanID2: 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…
Reference in New Issue
Block a user