lnd.xprv/autopilot/agent_constraints.go

152 lines
5.5 KiB
Go
Raw Normal View History

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
}