This commit adds a new signal to the autopilot agent, meant to signal
when any of the available heuristics has gotten an update.
We currently use this to trigger a new channel opening after the
external scores have been updated.
To make the autopilot able to account for fees, we let it use the
subtractFees option when opening channels.
This makes sure that each channel we attempt to open will eat at most
Amt out of our budget. Previously fees would eat into our funds in
addition, causing us to deplete our funds more than expected on each
channel opening.
This commit moves the logic querying the available heuristics out of the
autopilot agent and into the autopilot manager. This lets us query the
heuristic without the autopilot agent being active.
If called without the agent being active, the current set of channels
will be considered by the heuristics. If the agent is active also the
pending channels will be considered.
This commit fixes a regression in how we allocate funds to attempted
channels. We would earlier stay within the channel size limits, but we
wouldn't account for funds consumed by other channels being opened in
parallel.
We fix this by introducing a loop which greadily tries to distribute the
funds among the channels to open, and reduces the number of channels to
open in case not enough funds are available to satisfy the channel size
limits.
To ensure a call to ConnectToPeer doesn't block the agent from
shutting down, we'll launch it in a non-waitgrouped goroutine, that
will signal when a result is returned.
Since NodeScores no longer returns fully populated AttachmentDirectives,
we make this explicit by defining a new type NodeScore that includes a
subset of what the AttachmentDirective does.
We create a new type NodeScore which is a tuple (NodeID, score). The
weightedChoice and chooseN algorithms are altered to expect this type.
This is done in order to simplify the types we are using, since we were
only using a subset of the fields in AttachmentDirective.
Since we want to combine scores from multiple heuristics, things get
complicated if the heuristics report their own individual channel sizes.
Therefore we change the NodeScores interface slightly, letting the agent
specify the wanted channel size, and let the heuristic score the nodes
accordingly.
We let the agent call ChannelBudget on its constraints directly, and
not go through the heuristic. This is needed since when we want to have
multiple active heuristics concurrently, it won't make sense anymore to
ask each of the heuristics.
The mockConstraints are also updated to act as the mockHeuristic did
before, by making it possible to control the responses it gives by
sending them on the contained channels.
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 makes the autopilot agent use the new NodeScores heuristic
API to select channel candiates, instead of the Select API. The result
will be similar, but instead of selecting a set of nodes to open
channels to, we get a score based results which can later be used
together with other heuristics to choose nodes to open channels to.
This commit also makes the existing autopilot agent tests compatible
with the new NodeScores API.
This commit modifies the autopilot agent to track
all pending connection requests, and forgo further
attempts if a connection is already present.
Previously, the agent would try and establish
hundreds of requests to a node, especially if the
connections were timing out and not returning.
This resulted in an OOM OMM when cranking up
maxchannels to 200, since there would be close
to 10k pending connections before the program was
terminated. The issue was compounded by periodic
batch timeouts, causing autopilot to try and
process thousands of triggers for failing
connections to the same peer.
With these fixes, autopilot will skip nodes that we
are trying to connect to during heuristic selection.
The CPU and memory utilization have been significantly
reduced as a result.
We do this to avoid a huge amount of goroutines piling up when autopilot
is trying to open many channels, as they will all block trying to send
the update on the stateUpdates channel. Now we instead send them on a
buffered channel, similar to what is done with the nodeUpdates.
We do this to avoid a huge amount of goroutines piling up on initial
graph sync, as they will all block trying to send the node update on the
stateUpdates channel. Now we instead make a new buffered channel
nodeUpdates, and just return immediately if there is already a signal in
the channel waiting to be processed.
In this commit, we modify the balanceUpdate autopilot signal to update
the balance according to what's returned to the WalletBalance callback
rather than explicitly tracking the balance. This gives the agent a
better sense of what the wallet's balance actually is.
Adds a new external signal alerting autopilot that
new nodes have been added to the channel graph or
an existing node has modified its channel
announcment. This allows autopilot to examine its
current state, and attempt to open channels if our
target state is not yet met.
In this commit, we refactor the existing connection logic outside of the
ChanController's OpenChannel method. We do this as previously it was
possible for peers to stall us while attempting to connect to them. In
order to remedy this, we now attempt to connect the peer before tracking
them in our set of pending opens.
In this commit, we fix an existing bug that would at times cause us to
spiral out of control and potentially created thousands of outbound
connections. Our fix is simple: limit the total number of outstanding
channel establishment attempts. Without this limit, we have no way to
bound the number of active goroutines.
Fixes#772.
In this commit, we fix a regression introduced by a recent change which
would allow the agent to detect a channel as failed, and blacklist the
node, promising faster convergence with the ideal state of the
heuristic.
The source of this bug is that we would use the set of blacklisted
nodes in order to compute how many additional channels we should open.
If 10 failures happened, then we would think that we had opened up 10
channels, and stop much earlier than we actually should.
To fix this, while ensuring we don’t retry to failed peers, the
NeedMoreChans method will now return *how* anymore channels to open,
and the Select method will take in how many channels it should try to
open *exactly*.