autopilot/prefattach: use HeuristicConstraints
This commit makes the pref attach heuristic and the agent use the HeuristicConstraints internally.
This commit is contained in:
parent
e98d859882
commit
35f4ec84d1
@ -51,11 +51,9 @@ type Config struct {
|
|||||||
// within the graph.
|
// within the graph.
|
||||||
Graph ChannelGraph
|
Graph ChannelGraph
|
||||||
|
|
||||||
// MaxPendingOpens is the maximum number of pending channel
|
// Constraints is the set of constraints the autopilot must adhere to
|
||||||
// establishment goroutines that can be lingering. We cap this value in
|
// when opening channels.
|
||||||
// order to control the level of parallelism caused by the autopilot
|
Constraints *HeuristicConstraints
|
||||||
// agent.
|
|
||||||
MaxPendingOpens uint16
|
|
||||||
|
|
||||||
// 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
|
||||||
@ -525,12 +523,12 @@ func (a *Agent) controller() {
|
|||||||
// connections succeed, we will they will be ignored and made
|
// connections succeed, we will they will be ignored and made
|
||||||
// available to future heuristic selections.
|
// available to future heuristic selections.
|
||||||
pendingMtx.Lock()
|
pendingMtx.Lock()
|
||||||
if uint16(len(pendingOpens)) >= a.cfg.MaxPendingOpens {
|
if uint16(len(pendingOpens)) >= a.cfg.Constraints.MaxPendingOpens {
|
||||||
pendingMtx.Unlock()
|
pendingMtx.Unlock()
|
||||||
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.MaxPendingOpens)
|
a.cfg.Constraints.MaxPendingOpens)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,7 +585,7 @@ func (a *Agent) controller() {
|
|||||||
// finished first.
|
// finished first.
|
||||||
pendingMtx.Lock()
|
pendingMtx.Lock()
|
||||||
if uint16(len(pendingOpens)) >=
|
if uint16(len(pendingOpens)) >=
|
||||||
a.cfg.MaxPendingOpens {
|
a.cfg.Constraints.MaxPendingOpens {
|
||||||
// Since we've reached our max number of
|
// Since we've reached our max number of
|
||||||
// pending opens, we'll disconnect this
|
// pending opens, we'll disconnect this
|
||||||
// peer and exit. However, if we were
|
// peer and exit. However, if we were
|
||||||
|
@ -167,8 +167,10 @@ func TestAgentChannelOpenSignal(t *testing.T) {
|
|||||||
DisconnectPeer: func(*btcec.PublicKey) error {
|
DisconnectPeer: func(*btcec.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Graph: memGraph,
|
Graph: memGraph,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
initialChans := []Channel{}
|
initialChans := []Channel{}
|
||||||
agent, err := New(testCfg, initialChans)
|
agent, err := New(testCfg, initialChans)
|
||||||
@ -288,8 +290,10 @@ func TestAgentChannelFailureSignal(t *testing.T) {
|
|||||||
DisconnectPeer: func(*btcec.PublicKey) error {
|
DisconnectPeer: func(*btcec.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Graph: memGraph,
|
Graph: memGraph,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
initialChans := []Channel{}
|
initialChans := []Channel{}
|
||||||
@ -389,8 +393,10 @@ func TestAgentChannelCloseSignal(t *testing.T) {
|
|||||||
DisconnectPeer: func(*btcec.PublicKey) error {
|
DisconnectPeer: func(*btcec.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Graph: memGraph,
|
Graph: memGraph,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll start the agent with two channels already being active.
|
// We'll start the agent with two channels already being active.
|
||||||
@ -503,8 +509,10 @@ func TestAgentBalanceUpdate(t *testing.T) {
|
|||||||
DisconnectPeer: func(*btcec.PublicKey) error {
|
DisconnectPeer: func(*btcec.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Graph: memGraph,
|
Graph: memGraph,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
initialChans := []Channel{}
|
initialChans := []Channel{}
|
||||||
agent, err := New(testCfg, initialChans)
|
agent, err := New(testCfg, initialChans)
|
||||||
@ -608,8 +616,10 @@ func TestAgentImmediateAttach(t *testing.T) {
|
|||||||
DisconnectPeer: func(*btcec.PublicKey) error {
|
DisconnectPeer: func(*btcec.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Graph: memGraph,
|
Graph: memGraph,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
initialChans := []Channel{}
|
initialChans := []Channel{}
|
||||||
agent, err := New(testCfg, initialChans)
|
agent, err := New(testCfg, initialChans)
|
||||||
@ -743,8 +753,10 @@ func TestAgentPrivateChannels(t *testing.T) {
|
|||||||
DisconnectPeer: func(*btcec.PublicKey) error {
|
DisconnectPeer: func(*btcec.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Graph: memGraph,
|
Graph: memGraph,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
agent, err := New(cfg, nil)
|
agent, err := New(cfg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -866,8 +878,10 @@ func TestAgentPendingChannelState(t *testing.T) {
|
|||||||
DisconnectPeer: func(*btcec.PublicKey) error {
|
DisconnectPeer: func(*btcec.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Graph: memGraph,
|
Graph: memGraph,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
initialChans := []Channel{}
|
initialChans := []Channel{}
|
||||||
agent, err := New(testCfg, initialChans)
|
agent, err := New(testCfg, initialChans)
|
||||||
@ -1035,8 +1049,10 @@ 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,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
agent, err := New(cfg, nil)
|
agent, err := New(cfg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1118,8 +1134,10 @@ 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,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
agent, err := New(cfg, nil)
|
agent, err := New(cfg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1232,8 +1250,10 @@ func TestAgentSkipPendingConns(t *testing.T) {
|
|||||||
DisconnectPeer: func(*btcec.PublicKey) error {
|
DisconnectPeer: func(*btcec.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Graph: memGraph,
|
Graph: memGraph,
|
||||||
MaxPendingOpens: 10,
|
Constraints: &HeuristicConstraints{
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
initialChans := []Channel{}
|
initialChans := []Channel{}
|
||||||
agent, err := New(testCfg, initialChans)
|
agent, err := New(testCfg, initialChans)
|
||||||
|
@ -22,28 +22,20 @@ import (
|
|||||||
//
|
//
|
||||||
// TODO(roasbeef): BA, with k=-3
|
// TODO(roasbeef): BA, with k=-3
|
||||||
type ConstrainedPrefAttachment struct {
|
type ConstrainedPrefAttachment struct {
|
||||||
minChanSize btcutil.Amount
|
constraints *HeuristicConstraints
|
||||||
maxChanSize btcutil.Amount
|
|
||||||
|
|
||||||
chanLimit uint16
|
|
||||||
|
|
||||||
threshold float64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConstrainedPrefAttachment creates a new instance of a
|
// NewConstrainedPrefAttachment creates a new instance of a
|
||||||
// ConstrainedPrefAttachment heuristics given bounds on allowed channel sizes,
|
// ConstrainedPrefAttachment heuristics given bounds on allowed channel sizes,
|
||||||
// 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(minChanSize, maxChanSize btcutil.Amount,
|
func NewConstrainedPrefAttachment(
|
||||||
chanLimit uint16, allocation float64) *ConstrainedPrefAttachment {
|
cfg *HeuristicConstraints) *ConstrainedPrefAttachment {
|
||||||
|
|
||||||
prand.Seed(time.Now().Unix())
|
prand.Seed(time.Now().Unix())
|
||||||
|
|
||||||
return &ConstrainedPrefAttachment{
|
return &ConstrainedPrefAttachment{
|
||||||
minChanSize: minChanSize,
|
constraints: cfg,
|
||||||
chanLimit: chanLimit,
|
|
||||||
maxChanSize: maxChanSize,
|
|
||||||
threshold: allocation,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,45 +53,11 @@ var _ AttachmentHeuristic = (*ConstrainedPrefAttachment)(nil)
|
|||||||
func (p *ConstrainedPrefAttachment) NeedMoreChans(channels []Channel,
|
func (p *ConstrainedPrefAttachment) NeedMoreChans(channels []Channel,
|
||||||
funds btcutil.Amount) (btcutil.Amount, uint32, bool) {
|
funds btcutil.Amount) (btcutil.Amount, uint32, bool) {
|
||||||
|
|
||||||
// If we're already over our maximum allowed number of channels, then
|
// We'll try to open more channels as long as the constraints allow it.
|
||||||
// we'll instruct the controller not to create any more channels.
|
availableFunds, availableChans := p.constraints.availableChans(
|
||||||
if len(channels) >= int(p.chanLimit) {
|
channels, funds,
|
||||||
return 0, 0, false
|
)
|
||||||
}
|
return availableFunds, availableChans, availableChans > 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(p.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 < p.threshold
|
|
||||||
if !needMore {
|
|
||||||
return 0, 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) * p.threshold)
|
|
||||||
fundsAvailable := targetAllocation - totalChanAllocation
|
|
||||||
return fundsAvailable, numAdditionalChans, true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeID is a simple type that holds an EC public key serialized in compressed
|
// NodeID is a simple type that holds an EC public key serialized in compressed
|
||||||
@ -150,7 +108,7 @@ func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph
|
|||||||
|
|
||||||
var directives []AttachmentDirective
|
var directives []AttachmentDirective
|
||||||
|
|
||||||
if fundsAvailable < p.minChanSize {
|
if fundsAvailable < p.constraints.MinChanSize {
|
||||||
return directives, nil
|
return directives, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,9 +221,9 @@ func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph
|
|||||||
// If we have enough available funds to distribute the maximum channel
|
// If we have enough available funds to distribute the maximum channel
|
||||||
// size for each of the selected peers to attach to, then we'll
|
// size for each of the selected peers to attach to, then we'll
|
||||||
// allocate the maximum amount to each peer.
|
// allocate the maximum amount to each peer.
|
||||||
case int64(fundsAvailable) >= numSelectedNodes*int64(p.maxChanSize):
|
case int64(fundsAvailable) >= numSelectedNodes*int64(p.constraints.MaxChanSize):
|
||||||
for i := 0; i < int(numSelectedNodes); i++ {
|
for i := 0; i < int(numSelectedNodes); i++ {
|
||||||
directives[i].ChanAmt = p.maxChanSize
|
directives[i].ChanAmt = p.constraints.MaxChanSize
|
||||||
}
|
}
|
||||||
|
|
||||||
return directives, nil
|
return directives, nil
|
||||||
@ -273,14 +231,14 @@ func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph
|
|||||||
// Otherwise, we'll greedily allocate our funds to the channels
|
// Otherwise, we'll greedily allocate our funds to the channels
|
||||||
// successively until we run out of available funds, or can't create a
|
// successively until we run out of available funds, or can't create a
|
||||||
// channel above the min channel size.
|
// channel above the min channel size.
|
||||||
case int64(fundsAvailable) < numSelectedNodes*int64(p.maxChanSize):
|
case int64(fundsAvailable) < numSelectedNodes*int64(p.constraints.MaxChanSize):
|
||||||
i := 0
|
i := 0
|
||||||
for fundsAvailable > p.minChanSize {
|
for fundsAvailable > p.constraints.MinChanSize {
|
||||||
// We'll attempt to allocate the max channel size
|
// We'll attempt to allocate the max channel size
|
||||||
// initially. If we don't have enough funds to do this,
|
// initially. If we don't have enough funds to do this,
|
||||||
// then we'll allocate the remainder of the funds
|
// then we'll allocate the remainder of the funds
|
||||||
// available to the channel.
|
// available to the channel.
|
||||||
delta := p.maxChanSize
|
delta := p.constraints.MaxChanSize
|
||||||
if fundsAvailable-delta < 0 {
|
if fundsAvailable-delta < 0 {
|
||||||
delta = fundsAvailable
|
delta = fundsAvailable
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,13 @@ func TestConstrainedPrefAttachmentNeedMoreChan(t *testing.T) {
|
|||||||
threshold = 0.5
|
threshold = 0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
constraints := &HeuristicConstraints{
|
||||||
|
MinChanSize: minChanSize,
|
||||||
|
MaxChanSize: maxChanSize,
|
||||||
|
ChanLimit: chanLimit,
|
||||||
|
Allocation: threshold,
|
||||||
|
}
|
||||||
|
|
||||||
randChanID := func() lnwire.ShortChannelID {
|
randChanID := func() lnwire.ShortChannelID {
|
||||||
return lnwire.NewShortChanIDFromInt(uint64(prand.Int63()))
|
return lnwire.NewShortChanIDFromInt(uint64(prand.Int63()))
|
||||||
}
|
}
|
||||||
@ -146,8 +153,7 @@ func TestConstrainedPrefAttachmentNeedMoreChan(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
prefAttach := NewConstrainedPrefAttachment(minChanSize, maxChanSize,
|
prefAttach := NewConstrainedPrefAttachment(constraints)
|
||||||
chanLimit, threshold)
|
|
||||||
|
|
||||||
for i, testCase := range testCases {
|
for i, testCase := range testCases {
|
||||||
amtToAllocate, numMore, needMore := prefAttach.NeedMoreChans(
|
amtToAllocate, numMore, needMore := prefAttach.NeedMoreChans(
|
||||||
@ -236,14 +242,20 @@ func TestConstrainedPrefAttachmentSelectEmptyGraph(t *testing.T) {
|
|||||||
threshold = 0.5
|
threshold = 0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
constraints := &HeuristicConstraints{
|
||||||
|
MinChanSize: minChanSize,
|
||||||
|
MaxChanSize: maxChanSize,
|
||||||
|
ChanLimit: chanLimit,
|
||||||
|
Allocation: threshold,
|
||||||
|
}
|
||||||
|
|
||||||
// First, we'll generate a random key that represents "us", and create
|
// First, we'll generate a random key that represents "us", and create
|
||||||
// a new instance of the heuristic with our set parameters.
|
// a new instance of the heuristic with our set parameters.
|
||||||
self, err := randKey()
|
self, err := randKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to generate self key: %v", err)
|
t.Fatalf("unable to generate self key: %v", err)
|
||||||
}
|
}
|
||||||
prefAttach := NewConstrainedPrefAttachment(minChanSize, maxChanSize,
|
prefAttach := NewConstrainedPrefAttachment(constraints)
|
||||||
chanLimit, threshold)
|
|
||||||
|
|
||||||
skipNodes := make(map[NodeID]struct{})
|
skipNodes := make(map[NodeID]struct{})
|
||||||
for _, graph := range chanGraphs {
|
for _, graph := range chanGraphs {
|
||||||
@ -296,6 +308,12 @@ func TestConstrainedPrefAttachmentSelectTwoVertexes(t *testing.T) {
|
|||||||
threshold = 0.5
|
threshold = 0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
constraints := &HeuristicConstraints{
|
||||||
|
MinChanSize: minChanSize,
|
||||||
|
MaxChanSize: maxChanSize,
|
||||||
|
ChanLimit: chanLimit,
|
||||||
|
Allocation: threshold,
|
||||||
|
}
|
||||||
skipNodes := make(map[NodeID]struct{})
|
skipNodes := make(map[NodeID]struct{})
|
||||||
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) {
|
||||||
@ -314,8 +332,7 @@ func TestConstrainedPrefAttachmentSelectTwoVertexes(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t1.Fatalf("unable to generate self key: %v", err)
|
t1.Fatalf("unable to generate self key: %v", err)
|
||||||
}
|
}
|
||||||
prefAttach := NewConstrainedPrefAttachment(minChanSize, maxChanSize,
|
prefAttach := NewConstrainedPrefAttachment(constraints)
|
||||||
chanLimit, threshold)
|
|
||||||
|
|
||||||
// For this set, we'll load the memory graph with two
|
// For this set, we'll load the memory graph with two
|
||||||
// nodes, and a random channel connecting them.
|
// nodes, and a random channel connecting them.
|
||||||
@ -386,6 +403,13 @@ func TestConstrainedPrefAttachmentSelectInsufficientFunds(t *testing.T) {
|
|||||||
threshold = 0.5
|
threshold = 0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
constraints := &HeuristicConstraints{
|
||||||
|
MinChanSize: minChanSize,
|
||||||
|
MaxChanSize: maxChanSize,
|
||||||
|
ChanLimit: chanLimit,
|
||||||
|
Allocation: threshold,
|
||||||
|
}
|
||||||
|
|
||||||
skipNodes := make(map[NodeID]struct{})
|
skipNodes := make(map[NodeID]struct{})
|
||||||
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) {
|
||||||
@ -404,9 +428,7 @@ func TestConstrainedPrefAttachmentSelectInsufficientFunds(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t1.Fatalf("unable to generate self key: %v", err)
|
t1.Fatalf("unable to generate self key: %v", err)
|
||||||
}
|
}
|
||||||
prefAttach := NewConstrainedPrefAttachment(
|
prefAttach := NewConstrainedPrefAttachment(constraints)
|
||||||
minChanSize, maxChanSize, chanLimit, threshold,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Next, we'll attempt to select a set of candidates,
|
// Next, we'll attempt to select a set of candidates,
|
||||||
// passing zero for the amount of wallet funds. This
|
// passing zero for the amount of wallet funds. This
|
||||||
@ -445,6 +467,13 @@ func TestConstrainedPrefAttachmentSelectGreedyAllocation(t *testing.T) {
|
|||||||
threshold = 0.5
|
threshold = 0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
constraints := &HeuristicConstraints{
|
||||||
|
MinChanSize: minChanSize,
|
||||||
|
MaxChanSize: maxChanSize,
|
||||||
|
ChanLimit: chanLimit,
|
||||||
|
Allocation: threshold,
|
||||||
|
}
|
||||||
|
|
||||||
skipNodes := make(map[NodeID]struct{})
|
skipNodes := make(map[NodeID]struct{})
|
||||||
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) {
|
||||||
@ -463,9 +492,7 @@ func TestConstrainedPrefAttachmentSelectGreedyAllocation(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t1.Fatalf("unable to generate self key: %v", err)
|
t1.Fatalf("unable to generate self key: %v", err)
|
||||||
}
|
}
|
||||||
prefAttach := NewConstrainedPrefAttachment(
|
prefAttach := NewConstrainedPrefAttachment(constraints)
|
||||||
minChanSize, maxChanSize, chanLimit, threshold,
|
|
||||||
)
|
|
||||||
|
|
||||||
const chanCapacity = btcutil.SatoshiPerBitcoin
|
const chanCapacity = btcutil.SatoshiPerBitcoin
|
||||||
|
|
||||||
@ -581,6 +608,13 @@ func TestConstrainedPrefAttachmentSelectSkipNodes(t *testing.T) {
|
|||||||
threshold = 0.5
|
threshold = 0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
constraints := &HeuristicConstraints{
|
||||||
|
MinChanSize: minChanSize,
|
||||||
|
MaxChanSize: maxChanSize,
|
||||||
|
ChanLimit: chanLimit,
|
||||||
|
Allocation: 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) {
|
||||||
skipNodes := make(map[NodeID]struct{})
|
skipNodes := make(map[NodeID]struct{})
|
||||||
@ -600,9 +634,7 @@ func TestConstrainedPrefAttachmentSelectSkipNodes(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t1.Fatalf("unable to generate self key: %v", err)
|
t1.Fatalf("unable to generate self key: %v", err)
|
||||||
}
|
}
|
||||||
prefAttach := NewConstrainedPrefAttachment(
|
prefAttach := NewConstrainedPrefAttachment(constraints)
|
||||||
minChanSize, maxChanSize, chanLimit, threshold,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Next, we'll create a simple topology of two nodes,
|
// Next, we'll create a simple topology of two nodes,
|
||||||
// with a single channel connecting them.
|
// with a single channel connecting them.
|
||||||
|
17
pilot.go
17
pilot.go
@ -85,12 +85,19 @@ var _ autopilot.ChannelController = (*chanController)(nil)
|
|||||||
func initAutoPilot(svr *server, cfg *autoPilotConfig) (*autopilot.Agent, error) {
|
func initAutoPilot(svr *server, cfg *autoPilotConfig) (*autopilot.Agent, error) {
|
||||||
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.
|
||||||
|
atplConstraints := &autopilot.HeuristicConstraints{
|
||||||
|
MinChanSize: btcutil.Amount(cfg.MinChannelSize),
|
||||||
|
MaxChanSize: btcutil.Amount(cfg.MaxChannelSize),
|
||||||
|
ChanLimit: uint16(cfg.MaxChannels),
|
||||||
|
Allocation: cfg.Allocation,
|
||||||
|
MaxPendingOpens: 10,
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
prefAttachment := autopilot.NewConstrainedPrefAttachment(
|
prefAttachment := autopilot.NewConstrainedPrefAttachment(
|
||||||
btcutil.Amount(cfg.MinChannelSize),
|
atplConstraints,
|
||||||
btcutil.Amount(cfg.MaxChannelSize),
|
|
||||||
uint16(cfg.MaxChannels), cfg.Allocation,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// With the heuristic itself created, we can now populate the remainder
|
// With the heuristic itself created, we can now populate the remainder
|
||||||
@ -107,8 +114,8 @@ func initAutoPilot(svr *server, cfg *autoPilotConfig) (*autopilot.Agent, error)
|
|||||||
WalletBalance: func() (btcutil.Amount, error) {
|
WalletBalance: func() (btcutil.Amount, error) {
|
||||||
return svr.cc.wallet.ConfirmedBalance(cfg.MinConfs)
|
return svr.cc.wallet.ConfirmedBalance(cfg.MinConfs)
|
||||||
},
|
},
|
||||||
Graph: autopilot.ChannelGraphFromDatabase(svr.chanDB.ChannelGraph()),
|
Graph: autopilot.ChannelGraphFromDatabase(svr.chanDB.ChannelGraph()),
|
||||||
MaxPendingOpens: 10,
|
Constraints: atplConstraints,
|
||||||
ConnectToPeer: func(target *btcec.PublicKey, addrs []net.Addr) (bool, error) {
|
ConnectToPeer: func(target *btcec.PublicKey, addrs []net.Addr) (bool, error) {
|
||||||
// First, we'll check if we're already connected to the
|
// First, we'll check if we're already connected to the
|
||||||
// target peer. If we are, we can exit early. Otherwise,
|
// target peer. If we are, we can exit early. Otherwise,
|
||||||
|
Loading…
Reference in New Issue
Block a user