autopilot: define AgentConstraints

To decouple the autopilot heuristic from the constraints, we start by
abstracting them behind an interface to make them easier to mock. We
also rename them HeuristicConstraints->AgentConstraints to make it clear
that they are now constraints the agent must adhere to.
This commit is contained in:
Johan T. Halseth 2018-12-19 14:54:53 +01:00
parent 21460c9e67
commit 1d82e12fcf
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
7 changed files with 271 additions and 168 deletions

View File

@ -57,7 +57,7 @@ type Config struct {
// Constraints is the set of constraints the autopilot must adhere to // Constraints is the set of constraints the autopilot must adhere to
// when opening channels. // when opening channels.
Constraints *HeuristicConstraints Constraints AgentConstraints
// TODO(roasbeef): add additional signals from fee rates and revenue of // TODO(roasbeef): add additional signals from fee rates and revenue of
// currently opened channels // currently opened channels
@ -573,11 +573,11 @@ func (a *Agent) openChans(availableFunds btcutil.Amount, numChans uint32,
// available to future heuristic selections. // available to future heuristic selections.
a.pendingMtx.Lock() a.pendingMtx.Lock()
defer a.pendingMtx.Unlock() defer a.pendingMtx.Unlock()
if uint16(len(a.pendingOpens)) >= a.cfg.Constraints.MaxPendingOpens { if uint16(len(a.pendingOpens)) >= a.cfg.Constraints.MaxPendingOpens() {
log.Debugf("Reached cap of %v pending "+ log.Debugf("Reached cap of %v pending "+
"channel opens, will retry "+ "channel opens, will retry "+
"after success/failure", "after success/failure",
a.cfg.Constraints.MaxPendingOpens) a.cfg.Constraints.MaxPendingOpens())
return nil return nil
} }
@ -642,7 +642,7 @@ func (a *Agent) executeDirective(directive AttachmentDirective) {
// first. // first.
a.pendingMtx.Lock() a.pendingMtx.Lock()
if uint16(len(a.pendingOpens)) >= if uint16(len(a.pendingOpens)) >=
a.cfg.Constraints.MaxPendingOpens { a.cfg.Constraints.MaxPendingOpens() {
// Since we've reached our max number of pending opens, we'll // Since we've reached our max number of pending opens, we'll
// disconnect this peer and exit. However, if we were // disconnect this peer and exit. However, if we were
// previously connected to them, then we'll make sure to // previously connected to them, then we'll make sure to

View File

@ -0,0 +1,151 @@
package autopilot
import (
"github.com/btcsuite/btcutil"
)
// AgentConstraints is an interface the agent will query to determine what
// limits it will need to stay inside when opening channels.
type AgentConstraints interface {
// ChannelBudget should, given the passed parameters, return whether
// more channels can be be opened while still staying withing the set
// constraints. If the constraints allow us to open more channels, then
// the first return value will represent the amount of additional funds
// available towards creating channels. The second return value is the
// exact *number* of additional channels available.
ChannelBudget(chans []Channel, balance btcutil.Amount) (
btcutil.Amount, uint32)
// MaxPendingOpens returns the maximum number of pending channel
// establishment goroutines that can be lingering. We cap this value in
// order to control the level of parallelism caused by the autopilot
// agent.
MaxPendingOpens() uint16
// MinChanSize returns the smallest channel that the autopilot agent
// should create.
MinChanSize() btcutil.Amount
// MaxChanSize returns largest channel that the autopilot agent should
// create.
MaxChanSize() btcutil.Amount
}
// agenConstraints is an implementation of the AgentConstraints interface that
// indicate the constraints the autopilot agent must adhere to when opening
// channels.
type agentConstraints struct {
// minChanSize is the smallest channel that the autopilot agent should
// create.
minChanSize btcutil.Amount
// maxChanSize the largest channel that the autopilot agent should
// create.
maxChanSize btcutil.Amount
// chanLimit the maximum number of channels that should be created.
chanLimit uint16
// allocation the percentage of total funds that should be committed to
// automatic channel establishment.
allocation float64
// maxPendingOpens is the maximum number of pending channel
// establishment goroutines that can be lingering. We cap this value in
// order to control the level of parallelism caused by the autopilot
// agent.
maxPendingOpens uint16
}
// A compile time assertion to ensure agentConstraints satisfies the
// AgentConstraints interface.
var _ AgentConstraints = (*agentConstraints)(nil)
// NewConstraints returns a new AgentConstraints with the given limits.
func NewConstraints(minChanSize, maxChanSize btcutil.Amount, chanLimit,
maxPendingOpens uint16, allocation float64) AgentConstraints {
return &agentConstraints{
minChanSize: minChanSize,
maxChanSize: maxChanSize,
chanLimit: chanLimit,
allocation: allocation,
maxPendingOpens: maxPendingOpens,
}
}
// ChannelBudget should, given the passed parameters, return whether more
// channels can be be opened while still staying withing the set constraints.
// If the constraints allow us to open more channels, then the first return
// value will represent the amount of additional funds available towards
// creating channels. The second return value is the exact *number* of
// additional channels available.
//
// Note: part of the AgentConstraints interface.
func (h *agentConstraints) ChannelBudget(channels []Channel,
funds btcutil.Amount) (btcutil.Amount, uint32) {
// If we're already over our maximum allowed number of channels, then
// we'll instruct the controller not to create any more channels.
if len(channels) >= int(h.chanLimit) {
return 0, 0
}
// The number of additional channels that should be opened is the
// difference between the channel limit, and the number of channels we
// already have open.
numAdditionalChans := uint32(h.chanLimit) - uint32(len(channels))
// First, we'll tally up the total amount of funds that are currently
// present within the set of active channels.
var totalChanAllocation btcutil.Amount
for _, channel := range channels {
totalChanAllocation += channel.Capacity
}
// With this value known, we'll now compute the total amount of fund
// allocated across regular utxo's and channel utxo's.
totalFunds := funds + totalChanAllocation
// Once the total amount has been computed, we then calculate the
// fraction of funds currently allocated to channels.
fundsFraction := float64(totalChanAllocation) / float64(totalFunds)
// If this fraction is below our threshold, then we'll return true, to
// indicate the controller should call Select to obtain a candidate set
// of channels to attempt to open.
needMore := fundsFraction < h.allocation
if !needMore {
return 0, 0
}
// Now that we know we need more funds, we'll compute the amount of
// additional funds we should allocate towards channels.
targetAllocation := btcutil.Amount(float64(totalFunds) * h.allocation)
fundsAvailable := targetAllocation - totalChanAllocation
return fundsAvailable, numAdditionalChans
}
// MaxPendingOpens returns the maximum number of pending channel establishment
// goroutines that can be lingering. We cap this value in order to control the
// level of parallelism caused by the autopilot agent.
//
// Note: part of the AgentConstraints interface.
func (h *agentConstraints) MaxPendingOpens() uint16 {
return h.maxPendingOpens
}
// MinChanSize returns the smallest channel that the autopilot agent should
// create.
//
// Note: part of the AgentConstraints interface.
func (h *agentConstraints) MinChanSize() btcutil.Amount {
return h.minChanSize
}
// MaxChanSize returns largest channel that the autopilot agent should create.
//
// Note: part of the AgentConstraints interface.
func (h *agentConstraints) MaxChanSize() btcutil.Amount {
return h.maxChanSize
}

View File

@ -25,6 +25,27 @@ type moreChanArg struct {
balance btcutil.Amount balance btcutil.Amount
} }
type mockConstraints struct {
}
func (m *mockConstraints) ChannelBudget(chans []Channel,
balance btcutil.Amount) (btcutil.Amount, uint32) {
return 1e8, 10
}
func (m *mockConstraints) MaxPendingOpens() uint16 {
return 10
}
func (m *mockConstraints) MinChanSize() btcutil.Amount {
return 0
}
func (m *mockConstraints) MaxChanSize() btcutil.Amount {
return 1e8
}
var _ AgentConstraints = (*mockConstraints)(nil)
type mockHeuristic struct { type mockHeuristic struct {
moreChansResps chan moreChansResp moreChansResps chan moreChansResp
moreChanArgs chan moreChanArg moreChanArgs chan moreChanArg
@ -150,6 +171,8 @@ func TestAgentChannelOpenSignal(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
chanController := &mockChanController{ chanController := &mockChanController{
openChanSignals: make(chan openChanIntent, 10), openChanSignals: make(chan openChanIntent, 10),
} }
@ -170,10 +193,8 @@ func TestAgentChannelOpenSignal(t *testing.T) {
DisconnectPeer: func(*btcec.PublicKey) error { DisconnectPeer: func(*btcec.PublicKey) error {
return nil return nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
initialChans := []Channel{} initialChans := []Channel{}
agent, err := New(testCfg, initialChans) agent, err := New(testCfg, initialChans)
@ -283,6 +304,8 @@ func TestAgentChannelFailureSignal(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
chanController := &mockFailingChanController{} chanController := &mockFailingChanController{}
memGraph, _, _ := newMemChanGraph() memGraph, _, _ := newMemChanGraph()
@ -301,10 +324,8 @@ func TestAgentChannelFailureSignal(t *testing.T) {
DisconnectPeer: func(*btcec.PublicKey) error { DisconnectPeer: func(*btcec.PublicKey) error {
return nil return nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
initialChans := []Channel{} initialChans := []Channel{}
@ -394,6 +415,8 @@ func TestAgentChannelCloseSignal(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
chanController := &mockChanController{ chanController := &mockChanController{
openChanSignals: make(chan openChanIntent), openChanSignals: make(chan openChanIntent),
} }
@ -414,10 +437,8 @@ func TestAgentChannelCloseSignal(t *testing.T) {
DisconnectPeer: func(*btcec.PublicKey) error { DisconnectPeer: func(*btcec.PublicKey) error {
return nil return nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
// We'll start the agent with two channels already being active. // We'll start the agent with two channels already being active.
@ -512,6 +533,8 @@ func TestAgentBalanceUpdate(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
chanController := &mockChanController{ chanController := &mockChanController{
openChanSignals: make(chan openChanIntent), openChanSignals: make(chan openChanIntent),
} }
@ -538,10 +561,8 @@ func TestAgentBalanceUpdate(t *testing.T) {
DisconnectPeer: func(*btcec.PublicKey) error { DisconnectPeer: func(*btcec.PublicKey) error {
return nil return nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
initialChans := []Channel{} initialChans := []Channel{}
agent, err := New(testCfg, initialChans) agent, err := New(testCfg, initialChans)
@ -630,6 +651,8 @@ func TestAgentImmediateAttach(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
chanController := &mockChanController{ chanController := &mockChanController{
openChanSignals: make(chan openChanIntent), openChanSignals: make(chan openChanIntent),
} }
@ -653,10 +676,8 @@ func TestAgentImmediateAttach(t *testing.T) {
DisconnectPeer: func(*btcec.PublicKey) error { DisconnectPeer: func(*btcec.PublicKey) error {
return nil return nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
initialChans := []Channel{} initialChans := []Channel{}
agent, err := New(testCfg, initialChans) agent, err := New(testCfg, initialChans)
@ -773,6 +794,8 @@ func TestAgentPrivateChannels(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
// The chanController should be initialized such that all of its open // The chanController should be initialized such that all of its open
// channel requests are for private channels. // channel requests are for private channels.
chanController := &mockChanController{ chanController := &mockChanController{
@ -799,10 +822,8 @@ func TestAgentPrivateChannels(t *testing.T) {
DisconnectPeer: func(*btcec.PublicKey) error { DisconnectPeer: func(*btcec.PublicKey) error {
return nil return nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
agent, err := New(cfg, nil) agent, err := New(cfg, nil)
if err != nil { if err != nil {
@ -905,6 +926,8 @@ func TestAgentPendingChannelState(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
chanController := &mockChanController{ chanController := &mockChanController{
openChanSignals: make(chan openChanIntent), openChanSignals: make(chan openChanIntent),
} }
@ -932,10 +955,8 @@ func TestAgentPendingChannelState(t *testing.T) {
DisconnectPeer: func(*btcec.PublicKey) error { DisconnectPeer: func(*btcec.PublicKey) error {
return nil return nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
initialChans := []Channel{} initialChans := []Channel{}
agent, err := New(testCfg, initialChans) agent, err := New(testCfg, initialChans)
@ -1097,6 +1118,8 @@ func TestAgentPendingOpenChannel(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
chanController := &mockChanController{ chanController := &mockChanController{
openChanSignals: make(chan openChanIntent), openChanSignals: make(chan openChanIntent),
} }
@ -1114,10 +1137,8 @@ func TestAgentPendingOpenChannel(t *testing.T) {
WalletBalance: func() (btcutil.Amount, error) { WalletBalance: func() (btcutil.Amount, error) {
return walletBalance, nil return walletBalance, nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
agent, err := New(cfg, nil) agent, err := New(cfg, nil)
if err != nil { if err != nil {
@ -1190,6 +1211,8 @@ func TestAgentOnNodeUpdates(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
chanController := &mockChanController{ chanController := &mockChanController{
openChanSignals: make(chan openChanIntent), openChanSignals: make(chan openChanIntent),
} }
@ -1207,10 +1230,8 @@ func TestAgentOnNodeUpdates(t *testing.T) {
WalletBalance: func() (btcutil.Amount, error) { WalletBalance: func() (btcutil.Amount, error) {
return walletBalance, nil return walletBalance, nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
agent, err := New(cfg, nil) agent, err := New(cfg, nil)
if err != nil { if err != nil {
@ -1303,6 +1324,8 @@ func TestAgentSkipPendingConns(t *testing.T) {
nodeScoresResps: make(chan map[NodeID]*AttachmentDirective), nodeScoresResps: make(chan map[NodeID]*AttachmentDirective),
quit: quit, quit: quit,
} }
constraints := &mockConstraints{}
chanController := &mockChanController{ chanController := &mockChanController{
openChanSignals: make(chan openChanIntent), openChanSignals: make(chan openChanIntent),
} }
@ -1341,10 +1364,8 @@ func TestAgentSkipPendingConns(t *testing.T) {
DisconnectPeer: func(*btcec.PublicKey) error { DisconnectPeer: func(*btcec.PublicKey) error {
return nil return nil
}, },
Graph: memGraph, Graph: memGraph,
Constraints: &HeuristicConstraints{ Constraints: constraints,
MaxPendingOpens: 10,
},
} }
initialChans := []Channel{} initialChans := []Channel{}
agent, err := New(testCfg, initialChans) agent, err := New(testCfg, initialChans)

View File

@ -1,76 +0,0 @@
package autopilot
import (
"github.com/btcsuite/btcutil"
)
// HeuristicConstraints is a struct that indicate the constraints an autopilot
// heuristic must adhere to when opening channels.
type HeuristicConstraints struct {
// MinChanSize is the smallest channel that the autopilot agent should
// create.
MinChanSize btcutil.Amount
// MaxChanSize the largest channel that the autopilot agent should
// create.
MaxChanSize btcutil.Amount
// ChanLimit the maximum number of channels that should be created.
ChanLimit uint16
// Allocation the percentage of total funds that should be committed to
// automatic channel establishment.
Allocation float64
// MaxPendingOpens is the maximum number of pending channel
// establishment goroutines that can be lingering. We cap this value in
// order to control the level of parallelism caused by the autopilot
// agent.
MaxPendingOpens uint16
}
// availableChans returns the funds and number of channels slots the autopilot
// has available towards new channels, and still be within the set constraints.
func (h *HeuristicConstraints) availableChans(channels []Channel,
funds btcutil.Amount) (btcutil.Amount, uint32) {
// If we're already over our maximum allowed number of channels, then
// we'll instruct the controller not to create any more channels.
if len(channels) >= int(h.ChanLimit) {
return 0, 0
}
// The number of additional channels that should be opened is the
// difference between the channel limit, and the number of channels we
// already have open.
numAdditionalChans := uint32(h.ChanLimit) - uint32(len(channels))
// First, we'll tally up the total amount of funds that are currently
// present within the set of active channels.
var totalChanAllocation btcutil.Amount
for _, channel := range channels {
totalChanAllocation += channel.Capacity
}
// With this value known, we'll now compute the total amount of fund
// allocated across regular utxo's and channel utxo's.
totalFunds := funds + totalChanAllocation
// Once the total amount has been computed, we then calculate the
// fraction of funds currently allocated to channels.
fundsFraction := float64(totalChanAllocation) / float64(totalFunds)
// If this fraction is below our threshold, then we'll return true, to
// indicate the controller should call Select to obtain a candidate set
// of channels to attempt to open.
needMore := fundsFraction < h.Allocation
if !needMore {
return 0, 0
}
// Now that we know we need more funds, we'll compute the amount of
// additional funds we should allocate towards channels.
targetAllocation := btcutil.Amount(float64(totalFunds) * h.Allocation)
fundsAvailable := targetAllocation - totalChanAllocation
return fundsAvailable, numAdditionalChans
}

View File

@ -21,7 +21,7 @@ import (
// //
// TODO(roasbeef): BA, with k=-3 // TODO(roasbeef): BA, with k=-3
type ConstrainedPrefAttachment struct { type ConstrainedPrefAttachment struct {
constraints *HeuristicConstraints constraints AgentConstraints
} }
// NewConstrainedPrefAttachment creates a new instance of a // NewConstrainedPrefAttachment creates a new instance of a
@ -29,7 +29,7 @@ type ConstrainedPrefAttachment struct {
// and an allocation amount which is interpreted as a percentage of funds that // and an allocation amount which is interpreted as a percentage of funds that
// is to be committed to channels at all times. // is to be committed to channels at all times.
func NewConstrainedPrefAttachment( func NewConstrainedPrefAttachment(
cfg *HeuristicConstraints) *ConstrainedPrefAttachment { cfg AgentConstraints) *ConstrainedPrefAttachment {
prand.Seed(time.Now().Unix()) prand.Seed(time.Now().Unix())
@ -53,7 +53,7 @@ func (p *ConstrainedPrefAttachment) NeedMoreChans(channels []Channel,
funds btcutil.Amount) (btcutil.Amount, uint32, bool) { funds btcutil.Amount) (btcutil.Amount, uint32, bool) {
// We'll try to open more channels as long as the constraints allow it. // We'll try to open more channels as long as the constraints allow it.
availableFunds, availableChans := p.constraints.availableChans( availableFunds, availableChans := p.constraints.ChannelBudget(
channels, funds, channels, funds,
) )
return availableFunds, availableChans, availableChans > 0 return availableFunds, availableChans, availableChans > 0
@ -142,7 +142,7 @@ func (p *ConstrainedPrefAttachment) NodeScores(g ChannelGraph, chans []Channel,
candidates := make(map[NodeID]*AttachmentDirective) candidates := make(map[NodeID]*AttachmentDirective)
for nID, nodeChans := range nodeChanNum { for nID, nodeChans := range nodeChanNum {
// As channel size we'll use the maximum channel size available. // As channel size we'll use the maximum channel size available.
chanSize := p.constraints.MaxChanSize chanSize := p.constraints.MaxChanSize()
if fundsAvailable-chanSize < 0 { if fundsAvailable-chanSize < 0 {
chanSize = fundsAvailable chanSize = fundsAvailable
} }
@ -159,7 +159,7 @@ func (p *ConstrainedPrefAttachment) NodeScores(g ChannelGraph, chans []Channel,
// If the amount is too small, we don't want to attempt opening // If the amount is too small, we don't want to attempt opening
// another channel. // another channel.
case chanSize == 0 || chanSize < p.constraints.MinChanSize: case chanSize == 0 || chanSize < p.constraints.MinChanSize():
continue continue
// If the node has no addresses, we cannot connect to it, so we // If the node has no addresses, we cannot connect to it, so we

View File

@ -29,12 +29,13 @@ func TestConstrainedPrefAttachmentNeedMoreChan(t *testing.T) {
threshold = 0.5 threshold = 0.5
) )
constraints := &HeuristicConstraints{ constraints := NewConstraints(
MinChanSize: minChanSize, minChanSize,
MaxChanSize: maxChanSize, maxChanSize,
ChanLimit: chanLimit, chanLimit,
Allocation: threshold, 0,
} threshold,
)
randChanID := func() lnwire.ShortChannelID { randChanID := func() lnwire.ShortChannelID {
return lnwire.NewShortChanIDFromInt(uint64(prand.Int63())) return lnwire.NewShortChanIDFromInt(uint64(prand.Int63()))
@ -242,12 +243,13 @@ func TestConstrainedPrefAttachmentSelectEmptyGraph(t *testing.T) {
threshold = 0.5 threshold = 0.5
) )
constraints := &HeuristicConstraints{ constraints := NewConstraints(
MinChanSize: minChanSize, minChanSize,
MaxChanSize: maxChanSize, maxChanSize,
ChanLimit: chanLimit, chanLimit,
Allocation: threshold, 0,
} threshold,
)
prefAttach := NewConstrainedPrefAttachment(constraints) prefAttach := NewConstrainedPrefAttachment(constraints)
@ -350,12 +352,14 @@ func TestConstrainedPrefAttachmentSelectTwoVertexes(t *testing.T) {
threshold = 0.5 threshold = 0.5
) )
constraints := &HeuristicConstraints{ constraints := NewConstraints(
MinChanSize: minChanSize, minChanSize,
MaxChanSize: maxChanSize, maxChanSize,
ChanLimit: chanLimit, chanLimit,
Allocation: threshold, 0,
} threshold,
)
for _, graph := range chanGraphs { for _, graph := range chanGraphs {
success := t.Run(graph.name, func(t1 *testing.T) { success := t.Run(graph.name, func(t1 *testing.T) {
graph, cleanup, err := graph.genFunc() graph, cleanup, err := graph.genFunc()
@ -474,12 +478,13 @@ func TestConstrainedPrefAttachmentSelectInsufficientFunds(t *testing.T) {
threshold = 0.5 threshold = 0.5
) )
constraints := &HeuristicConstraints{ constraints := NewConstraints(
MinChanSize: minChanSize, minChanSize,
MaxChanSize: maxChanSize, maxChanSize,
ChanLimit: chanLimit, chanLimit,
Allocation: threshold, 0,
} threshold,
)
for _, graph := range chanGraphs { for _, graph := range chanGraphs {
success := t.Run(graph.name, func(t1 *testing.T) { success := t.Run(graph.name, func(t1 *testing.T) {
@ -544,12 +549,13 @@ func TestConstrainedPrefAttachmentSelectGreedyAllocation(t *testing.T) {
threshold = 0.5 threshold = 0.5
) )
constraints := &HeuristicConstraints{ constraints := NewConstraints(
MinChanSize: minChanSize, minChanSize,
MaxChanSize: maxChanSize, maxChanSize,
ChanLimit: chanLimit, chanLimit,
Allocation: threshold, 0,
} threshold,
)
for _, graph := range chanGraphs { for _, graph := range chanGraphs {
success := t.Run(graph.name, func(t1 *testing.T) { success := t.Run(graph.name, func(t1 *testing.T) {
@ -711,12 +717,13 @@ func TestConstrainedPrefAttachmentSelectSkipNodes(t *testing.T) {
threshold = 0.5 threshold = 0.5
) )
constraints := &HeuristicConstraints{ constraints := NewConstraints(
MinChanSize: minChanSize, minChanSize,
MaxChanSize: maxChanSize, maxChanSize,
ChanLimit: chanLimit, chanLimit,
Allocation: threshold, 0,
} threshold,
)
for _, graph := range chanGraphs { for _, graph := range chanGraphs {
success := t.Run(graph.name, func(t1 *testing.T) { success := t.Run(graph.name, func(t1 *testing.T) {

View File

@ -87,13 +87,13 @@ func initAutoPilot(svr *server, cfg *autoPilotConfig) *autopilot.ManagerCfg {
atplLog.Infof("Instantiating autopilot with cfg: %v", spew.Sdump(cfg)) atplLog.Infof("Instantiating autopilot with cfg: %v", spew.Sdump(cfg))
// Set up the constraints the autopilot heuristics must adhere to. // Set up the constraints the autopilot heuristics must adhere to.
atplConstraints := &autopilot.HeuristicConstraints{ atplConstraints := autopilot.NewConstraints(
MinChanSize: btcutil.Amount(cfg.MinChannelSize), btcutil.Amount(cfg.MinChannelSize),
MaxChanSize: btcutil.Amount(cfg.MaxChannelSize), btcutil.Amount(cfg.MaxChannelSize),
ChanLimit: uint16(cfg.MaxChannels), uint16(cfg.MaxChannels),
Allocation: cfg.Allocation, 10,
MaxPendingOpens: 10, cfg.Allocation,
} )
// First, we'll create the preferential attachment heuristic, // First, we'll create the preferential attachment heuristic,
// initialized with the passed auto pilot configuration parameters. // initialized with the passed auto pilot configuration parameters.