From 392d6ccc9f212a3c3b8fba7c9cc18864159812dc Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 2 Oct 2020 13:15:41 +0200 Subject: [PATCH 1/4] autopilot: remove unused channel field FundedAmt --- autopilot/graph.go | 7 +++---- autopilot/interface.go | 6 ------ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/autopilot/graph.go b/autopilot/graph.go index 6ef6d61da..8ea454953 100644 --- a/autopilot/graph.go +++ b/autopilot/graph.go @@ -100,10 +100,9 @@ func (d dbNode) ForEachChannel(cb func(ChannelEdge) error) error { edge := ChannelEdge{ Channel: Channel{ - ChanID: lnwire.NewShortChanIDFromInt(ep.ChannelID), - Capacity: ei.Capacity, - FundedAmt: ei.Capacity, - Node: NodeID(ep.Node.PubKeyBytes), + ChanID: lnwire.NewShortChanIDFromInt(ep.ChannelID), + Capacity: ei.Capacity, + Node: NodeID(ep.Node.PubKeyBytes), }, Peer: dbNode{ tx: tx, diff --git a/autopilot/interface.go b/autopilot/interface.go index 21c51c9f4..04de98f90 100644 --- a/autopilot/interface.go +++ b/autopilot/interface.go @@ -47,12 +47,6 @@ type Channel struct { // Capacity is the capacity of the channel expressed in satoshis. Capacity btcutil.Amount - // FundedAmt is the amount the local node funded into the target - // channel. - // - // TODO(roasbeef): need this? - FundedAmt btcutil.Amount - // Node is the peer that this channel has been established with. Node NodeID From 3e1755ee994e17ad0b9657e6d7bfb7f15e991ee5 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 2 Oct 2020 13:54:22 +0200 Subject: [PATCH 2/4] autopilot: remove unimpleneted SpliceIn/Out methods --- autopilot/agent_test.go | 16 ---------------- autopilot/interface.go | 10 ---------- pilot.go | 8 -------- 3 files changed, 34 deletions(-) diff --git a/autopilot/agent_test.go b/autopilot/agent_test.go index 9cc9366e6..4828e7d5f 100644 --- a/autopilot/agent_test.go +++ b/autopilot/agent_test.go @@ -139,14 +139,6 @@ func (m *mockChanController) OpenChannel(target *btcec.PublicKey, func (m *mockChanController) CloseChannel(chanPoint *wire.OutPoint) error { return nil } -func (m *mockChanController) SpliceIn(chanPoint *wire.OutPoint, - amt btcutil.Amount) (*Channel, error) { - return nil, nil -} -func (m *mockChanController) SpliceOut(chanPoint *wire.OutPoint, - amt btcutil.Amount) (*Channel, error) { - return nil, nil -} var _ ChannelController = (*mockChanController)(nil) @@ -391,14 +383,6 @@ func (m *mockFailingChanController) OpenChannel(target *btcec.PublicKey, func (m *mockFailingChanController) CloseChannel(chanPoint *wire.OutPoint) error { return nil } -func (m *mockFailingChanController) SpliceIn(chanPoint *wire.OutPoint, - amt btcutil.Amount) (*Channel, error) { - return nil, nil -} -func (m *mockFailingChanController) SpliceOut(chanPoint *wire.OutPoint, - amt btcutil.Amount) (*Channel, error) { - return nil, nil -} var _ ChannelController = (*mockFailingChanController)(nil) diff --git a/autopilot/interface.go b/autopilot/interface.go index 04de98f90..a443a4713 100644 --- a/autopilot/interface.go +++ b/autopilot/interface.go @@ -211,14 +211,4 @@ type ChannelController interface { // // TODO(roasbeef): add force option? CloseChannel(chanPoint *wire.OutPoint) error - - // SpliceIn attempts to add additional funds to the target channel via - // a splice in mechanism. The new channel with an updated capacity - // should be returned. - SpliceIn(chanPoint *wire.OutPoint, amt btcutil.Amount) (*Channel, error) - - // SpliceOut attempts to remove funds from an existing channels using a - // splice out mechanism. The removed funds from the channel should be - // returned to an output under the control of the backing wallet. - SpliceOut(chanPoint *wire.OutPoint, amt btcutil.Amount) (*Channel, error) } diff --git a/pilot.go b/pilot.go index 1078a43d5..03ef225f3 100644 --- a/pilot.go +++ b/pilot.go @@ -124,14 +124,6 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey, func (c *chanController) CloseChannel(chanPoint *wire.OutPoint) error { return nil } -func (c *chanController) SpliceIn(chanPoint *wire.OutPoint, - amt btcutil.Amount) (*autopilot.Channel, error) { - return nil, nil -} -func (c *chanController) SpliceOut(chanPoint *wire.OutPoint, - amt btcutil.Amount) (*autopilot.Channel, error) { - return nil, nil -} // A compile time assertion to ensure chanController meets the // autopilot.ChannelController interface. From d40cf6b59256be1ef3b03ea3c7b9ef7cf2547d26 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 2 Oct 2020 13:56:43 +0200 Subject: [PATCH 3/4] autopilot: split channel definition into LocalChannel/ChannelEdge Since non-local channels won't have a balance field, we split the definitions in anticipation of adding one. --- autopilot/agent.go | 30 +++++++++++++-------------- autopilot/agent_constraints.go | 4 ++-- autopilot/agent_constraints_test.go | 12 +++++------ autopilot/agent_test.go | 14 ++++++------- autopilot/combinedattach.go | 2 +- autopilot/externalscoreattach.go | 2 +- autopilot/graph.go | 32 ++++++++++------------------- autopilot/interface.go | 18 +++++++++------- autopilot/manager.go | 6 +++--- autopilot/prefattach.go | 2 +- autopilot/prefattach_test.go | 4 ++-- autopilot/top_centrality.go | 2 +- autopilot/top_centrality_test.go | 4 ++-- pilot.go | 6 +++--- 14 files changed, 66 insertions(+), 72 deletions(-) diff --git a/autopilot/agent.go b/autopilot/agent.go index a7e34fa98..fbe620260 100644 --- a/autopilot/agent.go +++ b/autopilot/agent.go @@ -65,11 +65,11 @@ type Config struct { // channelState is a type that represents the set of active channels of the // backing LN node that the Agent should be aware of. This type contains a few // helper utility methods. -type channelState map[lnwire.ShortChannelID]Channel +type channelState map[lnwire.ShortChannelID]LocalChannel // Channels returns a slice of all the active channels. -func (c channelState) Channels() []Channel { - chans := make([]Channel, 0, len(c)) +func (c channelState) Channels() []LocalChannel { + chans := make([]LocalChannel, 0, len(c)) for _, channel := range c { chans = append(chans, channel) } @@ -163,7 +163,7 @@ type Agent struct { // initiated, but haven't yet been confirmed as being fully opened. // This state is required as otherwise, we may go over our allotted // channel limit, or open multiple channels to the same node. - pendingOpens map[NodeID]Channel + pendingOpens map[NodeID]LocalChannel pendingMtx sync.Mutex quit chan struct{} @@ -174,10 +174,10 @@ type Agent struct { // configuration and initial channel state. The initial channel state slice // should be populated with the set of Channels that are currently opened by // the backing Lightning Node. -func New(cfg Config, initialState []Channel) (*Agent, error) { +func New(cfg Config, initialState []LocalChannel) (*Agent, error) { a := &Agent{ cfg: cfg, - chanState: make(map[lnwire.ShortChannelID]Channel), + chanState: make(map[lnwire.ShortChannelID]LocalChannel), quit: make(chan struct{}), stateUpdates: make(chan interface{}), balanceUpdates: make(chan *balanceUpdate, 1), @@ -187,7 +187,7 @@ func New(cfg Config, initialState []Channel) (*Agent, error) { pendingOpenUpdates: make(chan *chanPendingOpenUpdate, 1), failedNodes: make(map[NodeID]struct{}), pendingConns: make(map[NodeID]struct{}), - pendingOpens: make(map[NodeID]Channel), + pendingOpens: make(map[NodeID]LocalChannel), } for _, c := range initialState { @@ -249,7 +249,7 @@ type nodeUpdates struct{} // channel has been opened, either by the Agent itself (within the main // controller loop), or by an external user to the system. type chanOpenUpdate struct { - newChan Channel + newChan LocalChannel } // chanPendingOpenUpdate is a type of external state update that indicates a new @@ -294,7 +294,7 @@ func (a *Agent) OnNodeUpdates() { // OnChannelOpen is a callback that should be executed each time a new channel // is manually opened by the user or any system outside the autopilot agent. -func (a *Agent) OnChannelOpen(c Channel) { +func (a *Agent) OnChannelOpen(c LocalChannel) { a.wg.Add(1) go func() { defer a.wg.Done() @@ -356,7 +356,7 @@ func (a *Agent) OnHeuristicUpdate(h AttachmentHeuristic) { // channels open to, with the other sets of nodes that should be removed from // consideration during heuristic selection. This ensures that the Agent doesn't // attempt to open any "duplicate" channels to the same node. -func mergeNodeMaps(c map[NodeID]Channel, +func mergeNodeMaps(c map[NodeID]LocalChannel, skips ...map[NodeID]struct{}) map[NodeID]struct{} { numNodes := len(c) @@ -380,11 +380,11 @@ func mergeNodeMaps(c map[NodeID]Channel, // mergeChanState merges the Agent's set of active channels, with the set of // channels awaiting confirmation. This ensures that the agent doesn't go over // the prescribed channel limit or fund allocation limit. -func mergeChanState(pendingChans map[NodeID]Channel, - activeChans channelState) []Channel { +func mergeChanState(pendingChans map[NodeID]LocalChannel, + activeChans channelState) []LocalChannel { numChans := len(pendingChans) + len(activeChans) - totalChans := make([]Channel, 0, numChans) + totalChans := make([]LocalChannel, 0, numChans) totalChans = append(totalChans, activeChans.Channels()...) @@ -549,7 +549,7 @@ func (a *Agent) controller() { // openChans queries the agent's heuristic for a set of channel candidates, and // attempts to open channels to them. func (a *Agent) openChans(availableFunds btcutil.Amount, numChans uint32, - totalChans []Channel) error { + totalChans []LocalChannel) error { // As channel size we'll use the maximum channel size available. chanSize := a.cfg.Constraints.MaxChanSize() @@ -828,7 +828,7 @@ func (a *Agent) executeDirective(directive AttachmentDirective) { // opens. We do this here to ensure we don't stall on selecting new // peers if the connection attempt happens to take too long. delete(a.pendingConns, nodeID) - a.pendingOpens[nodeID] = Channel{ + a.pendingOpens[nodeID] = LocalChannel{ Capacity: directive.ChanAmt, Node: nodeID, } diff --git a/autopilot/agent_constraints.go b/autopilot/agent_constraints.go index 2b084e45d..fc80b2af9 100644 --- a/autopilot/agent_constraints.go +++ b/autopilot/agent_constraints.go @@ -13,7 +13,7 @@ type AgentConstraints interface { // 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) ( + ChannelBudget(chans []LocalChannel, balance btcutil.Amount) ( btcutil.Amount, uint32) // MaxPendingOpens returns the maximum number of pending channel @@ -82,7 +82,7 @@ func NewConstraints(minChanSize, maxChanSize btcutil.Amount, chanLimit, // additional channels available. // // Note: part of the AgentConstraints interface. -func (h *agentConstraints) ChannelBudget(channels []Channel, +func (h *agentConstraints) ChannelBudget(channels []LocalChannel, funds btcutil.Amount) (btcutil.Amount, uint32) { // If we're already over our maximum allowed number of channels, then diff --git a/autopilot/agent_constraints_test.go b/autopilot/agent_constraints_test.go index 4ce78245f..19cdd5d6f 100644 --- a/autopilot/agent_constraints_test.go +++ b/autopilot/agent_constraints_test.go @@ -37,7 +37,7 @@ func TestConstraintsChannelBudget(t *testing.T) { } testCases := []struct { - channels []Channel + channels []LocalChannel walletAmt btcutil.Amount needMore bool @@ -47,7 +47,7 @@ func TestConstraintsChannelBudget(t *testing.T) { // Many available funds, but already have too many active open // channels. { - []Channel{ + []LocalChannel{ { ChanID: randChanID(), Capacity: btcutil.Amount(prand.Int31()), @@ -70,7 +70,7 @@ func TestConstraintsChannelBudget(t *testing.T) { // Ratio of funds in channels and total funds meets the // threshold. { - []Channel{ + []LocalChannel{ { ChanID: randChanID(), Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), @@ -93,7 +93,7 @@ func TestConstraintsChannelBudget(t *testing.T) { // recommended. We should also request 2 more channels as the // limit is 3. { - []Channel{ + []LocalChannel{ { ChanID: randChanID(), Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), @@ -113,7 +113,7 @@ func TestConstraintsChannelBudget(t *testing.T) { // to be committed. We should only request a single additional // channel as the limit is 3. { - []Channel{ + []LocalChannel{ { ChanID: randChanID(), Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), @@ -132,7 +132,7 @@ func TestConstraintsChannelBudget(t *testing.T) { // Ratio of funds in channels and total funds is above the // threshold. { - []Channel{ + []LocalChannel{ { ChanID: randChanID(), Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), diff --git a/autopilot/agent_test.go b/autopilot/agent_test.go index 4828e7d5f..1e8420184 100644 --- a/autopilot/agent_test.go +++ b/autopilot/agent_test.go @@ -19,7 +19,7 @@ type moreChansResp struct { } type moreChanArg struct { - chans []Channel + chans []LocalChannel balance btcutil.Amount } @@ -29,7 +29,7 @@ type mockConstraints struct { quit chan struct{} } -func (m *mockConstraints) ChannelBudget(chans []Channel, +func (m *mockConstraints) ChannelBudget(chans []LocalChannel, balance btcutil.Amount) (btcutil.Amount, uint32) { if m.moreChanArgs != nil { @@ -76,7 +76,7 @@ type mockHeuristic struct { type directiveArg struct { graph ChannelGraph amt btcutil.Amount - chans []Channel + chans []LocalChannel nodes map[NodeID]struct{} } @@ -84,7 +84,7 @@ func (m *mockHeuristic) Name() string { return "mock" } -func (m *mockHeuristic) NodeScores(g ChannelGraph, chans []Channel, +func (m *mockHeuristic) NodeScores(g ChannelGraph, chans []LocalChannel, chanSize btcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error) { @@ -154,7 +154,7 @@ type testContext struct { sync.Mutex } -func setup(t *testing.T, initialChans []Channel) (*testContext, func()) { +func setup(t *testing.T, initialChans []LocalChannel) (*testContext, func()) { t.Helper() // First, we'll create all the dependencies that we'll need in order to @@ -291,7 +291,7 @@ func TestAgentChannelOpenSignal(t *testing.T) { // Next we'll signal a new channel being opened by the backing LN node, // with a capacity of 1 BTC. - newChan := Channel{ + newChan := LocalChannel{ ChanID: randChanID(), Capacity: btcutil.SatoshiPerBitcoin, } @@ -432,7 +432,7 @@ func TestAgentChannelFailureSignal(t *testing.T) { func TestAgentChannelCloseSignal(t *testing.T) { t.Parallel() // We'll start the agent with two channels already being active. - initialChans := []Channel{ + initialChans := []LocalChannel{ { ChanID: randChanID(), Capacity: btcutil.SatoshiPerBitcoin, diff --git a/autopilot/combinedattach.go b/autopilot/combinedattach.go index 80d32e656..56041d084 100644 --- a/autopilot/combinedattach.go +++ b/autopilot/combinedattach.go @@ -70,7 +70,7 @@ func (c *WeightedCombAttachment) Name() string { // is the maximum possible improvement in connectivity. // // NOTE: This is a part of the AttachmentHeuristic interface. -func (c *WeightedCombAttachment) NodeScores(g ChannelGraph, chans []Channel, +func (c *WeightedCombAttachment) NodeScores(g ChannelGraph, chans []LocalChannel, chanSize btcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error) { diff --git a/autopilot/externalscoreattach.go b/autopilot/externalscoreattach.go index 2ac9814e9..015492185 100644 --- a/autopilot/externalscoreattach.go +++ b/autopilot/externalscoreattach.go @@ -80,7 +80,7 @@ func (s *ExternalScoreAttachment) SetNodeScores(targetHeuristic string, // not known will get a score of 0. // // NOTE: This is a part of the AttachmentHeuristic interface. -func (s *ExternalScoreAttachment) NodeScores(g ChannelGraph, chans []Channel, +func (s *ExternalScoreAttachment) NodeScores(g ChannelGraph, chans []LocalChannel, chanSize btcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error) { diff --git a/autopilot/graph.go b/autopilot/graph.go index 8ea454953..72c1b091e 100644 --- a/autopilot/graph.go +++ b/autopilot/graph.go @@ -99,11 +99,8 @@ func (d dbNode) ForEachChannel(cb func(ChannelEdge) error) error { } edge := ChannelEdge{ - Channel: Channel{ - ChanID: lnwire.NewShortChanIDFromInt(ep.ChannelID), - Capacity: ei.Capacity, - Node: NodeID(ep.Node.PubKeyBytes), - }, + ChanID: lnwire.NewShortChanIDFromInt(ep.ChannelID), + Capacity: ei.Capacity, Peer: dbNode{ tx: tx, node: ep.Node, @@ -264,19 +261,15 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, } return &ChannelEdge{ - Channel: Channel{ - ChanID: chanID, - Capacity: capacity, - }, + ChanID: chanID, + Capacity: capacity, Peer: dbNode{ node: vertex1, }, }, &ChannelEdge{ - Channel: Channel{ - ChanID: chanID, - Capacity: capacity, - }, + ChanID: chanID, + Capacity: capacity, Peer: dbNode{ node: vertex2, }, @@ -424,20 +417,17 @@ func (m *memChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, } } - channel := Channel{ + edge1 := ChannelEdge{ ChanID: randChanID(), Capacity: capacity, - } - - edge1 := ChannelEdge{ - Channel: channel, - Peer: vertex2, + Peer: vertex2, } vertex1.chans = append(vertex1.chans, edge1) edge2 := ChannelEdge{ - Channel: channel, - Peer: vertex1, + ChanID: randChanID(), + Capacity: capacity, + Peer: vertex1, } vertex2.chans = append(vertex2.chans, edge2) diff --git a/autopilot/interface.go b/autopilot/interface.go index a443a4713..2b7b55090 100644 --- a/autopilot/interface.go +++ b/autopilot/interface.go @@ -36,10 +36,10 @@ type Node interface { ForEachChannel(func(ChannelEdge) error) error } -// Channel is a simple struct which contains relevant details of a particular -// channel within the channel graph. The fields in this struct may be used a -// signals for various AttachmentHeuristic implementations. -type Channel struct { +// LocalChannel is a simple struct which contains relevant details of a +// particular channel the local node has. The fields in this struct may be used +// a signals for various AttachmentHeuristic implementations. +type LocalChannel struct { // ChanID is the short channel ID for this channel as defined within // BOLT-0007. ChanID lnwire.ShortChannelID @@ -59,8 +59,12 @@ type Channel struct { // edge within the graph. The existence of this reference to the connected node // will allow callers to traverse the graph in an object-oriented manner. type ChannelEdge struct { - // Channel contains the attributes of this channel. - Channel + // ChanID is the short channel ID for this channel as defined within + // BOLT-0007. + ChanID lnwire.ShortChannelID + + // Capacity is the capacity of the channel expressed in satoshis. + Capacity btcutil.Amount // Peer is the peer that this channel creates an edge to in the channel // graph. @@ -136,7 +140,7 @@ type AttachmentHeuristic interface { // // NOTE: A NodeID not found in the returned map is implicitly given a // score of 0. - NodeScores(g ChannelGraph, chans []Channel, + NodeScores(g ChannelGraph, chans []LocalChannel, chanSize btcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error) } diff --git a/autopilot/manager.go b/autopilot/manager.go index 88f6c37d1..f1bdff87e 100644 --- a/autopilot/manager.go +++ b/autopilot/manager.go @@ -23,7 +23,7 @@ type ManagerCfg struct { // ChannelState is a function closure that returns the current set of // channels managed by this node. - ChannelState func() ([]Channel, error) + ChannelState func() ([]LocalChannel, error) // SubscribeTransactions is used to get a subscription for transactions // relevant to this node's wallet. @@ -200,7 +200,7 @@ func (m *Manager) StartAgent() error { chanID := lnwire.NewShortChanIDFromInt( edgeUpdate.ChanID, ) - edge := Channel{ + edge := LocalChannel{ ChanID: chanID, Capacity: edgeUpdate.Capacity, Node: chanNode, @@ -292,7 +292,7 @@ func (m *Manager) queryHeuristics(nodes map[NodeID]struct{}, localState bool) ( // If we want to take the local state into action when querying the // heuristics, we fetch it. If not we'll just pass an emply slice to // the heuristic. - var totalChans []Channel + var totalChans []LocalChannel var err error if localState { // Fetch the current set of channels. diff --git a/autopilot/prefattach.go b/autopilot/prefattach.go index 4068fe101..c25009d12 100644 --- a/autopilot/prefattach.go +++ b/autopilot/prefattach.go @@ -78,7 +78,7 @@ func (p *PrefAttachment) Name() string { // given to nodes already having high connectivity in the graph. // // NOTE: This is a part of the AttachmentHeuristic interface. -func (p *PrefAttachment) NodeScores(g ChannelGraph, chans []Channel, +func (p *PrefAttachment) NodeScores(g ChannelGraph, chans []LocalChannel, chanSize btcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error) { diff --git a/autopilot/prefattach_test.go b/autopilot/prefattach_test.go index a680fffa8..24934592b 100644 --- a/autopilot/prefattach_test.go +++ b/autopilot/prefattach_test.go @@ -422,10 +422,10 @@ func TestPrefAttachmentSelectSkipNodes(t *testing.T) { // We'll simulate a channel update by adding the nodes // to our set of channels. - var chans []Channel + var chans []LocalChannel for _, candidate := range scores { chans = append(chans, - Channel{ + LocalChannel{ Node: candidate.NodeID, }, ) diff --git a/autopilot/top_centrality.go b/autopilot/top_centrality.go index da6dcf388..354b20ffc 100644 --- a/autopilot/top_centrality.go +++ b/autopilot/top_centrality.go @@ -50,7 +50,7 @@ func (g *TopCentrality) Name() string { // As our current implementation of betweenness centrality is non-incremental, // NodeScores will recalculate the centrality values on every call, which is // slow for large graphs. -func (g *TopCentrality) NodeScores(graph ChannelGraph, chans []Channel, +func (g *TopCentrality) NodeScores(graph ChannelGraph, chans []LocalChannel, chanSize btcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error) { diff --git a/autopilot/top_centrality_test.go b/autopilot/top_centrality_test.go index 6069200c5..dbc627e57 100644 --- a/autopilot/top_centrality_test.go +++ b/autopilot/top_centrality_test.go @@ -16,9 +16,9 @@ func testTopCentrality(t *testing.T, graph testGraph, topCentrality := NewTopCentrality() - var channels []Channel + var channels []LocalChannel for _, ch := range channelsWith { - channels = append(channels, Channel{ + channels = append(channels, LocalChannel{ Node: NewNodeID(graphNodes[ch]), }) } diff --git a/pilot.go b/pilot.go index 03ef225f3..34ba0e812 100644 --- a/pilot.go +++ b/pilot.go @@ -249,7 +249,7 @@ func initAutoPilot(svr *server, cfg *lncfg.AutoPilot, return &autopilot.ManagerCfg{ Self: self, PilotCfg: &pilotCfg, - ChannelState: func() ([]autopilot.Channel, error) { + ChannelState: func() ([]autopilot.LocalChannel, error) { // We'll fetch the current state of open // channels from the database to use as initial // state for the auto-pilot agent. @@ -257,10 +257,10 @@ func initAutoPilot(svr *server, cfg *lncfg.AutoPilot, if err != nil { return nil, err } - chanState := make([]autopilot.Channel, + chanState := make([]autopilot.LocalChannel, len(activeChannels)) for i, channel := range activeChannels { - chanState[i] = autopilot.Channel{ + chanState[i] = autopilot.LocalChannel{ ChanID: channel.ShortChanID(), Capacity: channel.Capacity, Node: autopilot.NewNodeID( From dbeafe8832b06c8cd079bde06a407637b74b64ad Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 2 Oct 2020 14:49:02 +0200 Subject: [PATCH 4/4] autopilot: rename to Capacity to Balance, define ChannelInfo() We rename the field Capacity on local channels to Balance, define a new method ChannelInfo on the manager config that let us query the database for our latest channels state. Using this we will use the current local balance instead of the channel capacity when doing allocation calculations. --- autopilot/agent.go | 4 +-- autopilot/agent_constraints.go | 2 +- autopilot/agent_constraints_test.go | 40 ++++++++++++++--------------- autopilot/agent_test.go | 18 ++++++------- autopilot/interface.go | 4 +-- autopilot/manager.go | 25 ++++++++++-------- pilot.go | 25 +++++++++++++++--- 7 files changed, 70 insertions(+), 48 deletions(-) diff --git a/autopilot/agent.go b/autopilot/agent.go index fbe620260..182abb7fb 100644 --- a/autopilot/agent.go +++ b/autopilot/agent.go @@ -829,8 +829,8 @@ func (a *Agent) executeDirective(directive AttachmentDirective) { // peers if the connection attempt happens to take too long. delete(a.pendingConns, nodeID) a.pendingOpens[nodeID] = LocalChannel{ - Capacity: directive.ChanAmt, - Node: nodeID, + Balance: directive.ChanAmt, + Node: nodeID, } a.pendingMtx.Unlock() diff --git a/autopilot/agent_constraints.go b/autopilot/agent_constraints.go index fc80b2af9..821146d0b 100644 --- a/autopilot/agent_constraints.go +++ b/autopilot/agent_constraints.go @@ -100,7 +100,7 @@ func (h *agentConstraints) ChannelBudget(channels []LocalChannel, // present within the set of active channels. var totalChanAllocation btcutil.Amount for _, channel := range channels { - totalChanAllocation += channel.Capacity + totalChanAllocation += channel.Balance } // With this value known, we'll now compute the total amount of fund diff --git a/autopilot/agent_constraints_test.go b/autopilot/agent_constraints_test.go index 19cdd5d6f..144107a15 100644 --- a/autopilot/agent_constraints_test.go +++ b/autopilot/agent_constraints_test.go @@ -49,16 +49,16 @@ func TestConstraintsChannelBudget(t *testing.T) { { []LocalChannel{ { - ChanID: randChanID(), - Capacity: btcutil.Amount(prand.Int31()), + ChanID: randChanID(), + Balance: btcutil.Amount(prand.Int31()), }, { - ChanID: randChanID(), - Capacity: btcutil.Amount(prand.Int31()), + ChanID: randChanID(), + Balance: btcutil.Amount(prand.Int31()), }, { - ChanID: randChanID(), - Capacity: btcutil.Amount(prand.Int31()), + ChanID: randChanID(), + Balance: btcutil.Amount(prand.Int31()), }, }, btcutil.Amount(btcutil.SatoshiPerBitcoin * 10), @@ -72,12 +72,12 @@ func TestConstraintsChannelBudget(t *testing.T) { { []LocalChannel{ { - ChanID: randChanID(), - Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), + ChanID: randChanID(), + Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin), }, { - ChanID: randChanID(), - Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), + ChanID: randChanID(), + Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin), }, }, btcutil.Amount(btcutil.SatoshiPerBitcoin * 2), @@ -95,8 +95,8 @@ func TestConstraintsChannelBudget(t *testing.T) { { []LocalChannel{ { - ChanID: randChanID(), - Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), + ChanID: randChanID(), + Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin), }, }, btcutil.Amount(btcutil.SatoshiPerBitcoin * 9), @@ -115,12 +115,12 @@ func TestConstraintsChannelBudget(t *testing.T) { { []LocalChannel{ { - ChanID: randChanID(), - Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), + ChanID: randChanID(), + Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin), }, { - ChanID: randChanID(), - Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin * 3), + ChanID: randChanID(), + Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin * 3), }, }, btcutil.Amount(btcutil.SatoshiPerBitcoin * 10), @@ -134,12 +134,12 @@ func TestConstraintsChannelBudget(t *testing.T) { { []LocalChannel{ { - ChanID: randChanID(), - Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), + ChanID: randChanID(), + Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin), }, { - ChanID: randChanID(), - Capacity: btcutil.Amount(btcutil.SatoshiPerBitcoin), + ChanID: randChanID(), + Balance: btcutil.Amount(btcutil.SatoshiPerBitcoin), }, }, btcutil.Amount(btcutil.SatoshiPerBitcoin), diff --git a/autopilot/agent_test.go b/autopilot/agent_test.go index 1e8420184..b12ab792f 100644 --- a/autopilot/agent_test.go +++ b/autopilot/agent_test.go @@ -292,8 +292,8 @@ func TestAgentChannelOpenSignal(t *testing.T) { // Next we'll signal a new channel being opened by the backing LN node, // with a capacity of 1 BTC. newChan := LocalChannel{ - ChanID: randChanID(), - Capacity: btcutil.SatoshiPerBitcoin, + ChanID: randChanID(), + Balance: btcutil.SatoshiPerBitcoin, } testCtx.agent.OnChannelOpen(newChan) @@ -434,12 +434,12 @@ func TestAgentChannelCloseSignal(t *testing.T) { // We'll start the agent with two channels already being active. initialChans := []LocalChannel{ { - ChanID: randChanID(), - Capacity: btcutil.SatoshiPerBitcoin, + ChanID: randChanID(), + Balance: btcutil.SatoshiPerBitcoin, }, { - ChanID: randChanID(), - Capacity: btcutil.SatoshiPerBitcoin * 2, + ChanID: randChanID(), + Balance: btcutil.SatoshiPerBitcoin * 2, }, } @@ -730,9 +730,9 @@ func TestAgentPendingChannelState(t *testing.T) { t.Fatalf("should include pending chan in current "+ "state, instead have %v chans", len(req.chans)) } - if req.chans[0].Capacity != chanAmt { - t.Fatalf("wrong chan capacity: expected %v, got %v", - req.chans[0].Capacity, chanAmt) + if req.chans[0].Balance != chanAmt { + t.Fatalf("wrong chan balance: expected %v, got %v", + req.chans[0].Balance, chanAmt) } if req.chans[0].Node != nodeID { t.Fatalf("wrong node ID: expected %x, got %x", diff --git a/autopilot/interface.go b/autopilot/interface.go index 2b7b55090..9359489f4 100644 --- a/autopilot/interface.go +++ b/autopilot/interface.go @@ -44,8 +44,8 @@ type LocalChannel struct { // BOLT-0007. ChanID lnwire.ShortChannelID - // Capacity is the capacity of the channel expressed in satoshis. - Capacity btcutil.Amount + // Balance is the local balance of the channel expressed in satoshis. + Balance btcutil.Amount // Node is the peer that this channel has been established with. Node NodeID diff --git a/autopilot/manager.go b/autopilot/manager.go index f1bdff87e..ecdf879f6 100644 --- a/autopilot/manager.go +++ b/autopilot/manager.go @@ -5,6 +5,7 @@ import ( "sync" "github.com/btcsuite/btcd/btcec" + "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing" @@ -25,6 +26,10 @@ type ManagerCfg struct { // channels managed by this node. ChannelState func() ([]LocalChannel, error) + // ChannelInfo is a function closure that returns the channel managed + // by the node given by the passed channel point. + ChannelInfo func(wire.OutPoint) (*LocalChannel, error) + // SubscribeTransactions is used to get a subscription for transactions // relevant to this node's wallet. SubscribeTransactions func() (lnwallet.TransactionSubscription, error) @@ -194,18 +199,16 @@ func (m *Manager) StartAgent() error { // opened, then we'll convert it to the // autopilot.Channel format, and notify // the pilot of the new channel. - chanNode := NewNodeID( - edgeUpdate.ConnectingNode, - ) - chanID := lnwire.NewShortChanIDFromInt( - edgeUpdate.ChanID, - ) - edge := LocalChannel{ - ChanID: chanID, - Capacity: edgeUpdate.Capacity, - Node: chanNode, + cp := edgeUpdate.ChanPoint + edge, err := m.cfg.ChannelInfo(cp) + if err != nil { + log.Errorf("Unable to fetch "+ + "channel info for %v: "+ + "%v", cp, err) + continue } - pilot.OnChannelOpen(edge) + + pilot.OnChannelOpen(*edge) } // For each closed channel, we'll obtain diff --git a/pilot.go b/pilot.go index 34ba0e812..871481211 100644 --- a/pilot.go +++ b/pilot.go @@ -260,16 +260,35 @@ func initAutoPilot(svr *server, cfg *lncfg.AutoPilot, chanState := make([]autopilot.LocalChannel, len(activeChannels)) for i, channel := range activeChannels { + localCommit := channel.LocalCommitment + balance := localCommit.LocalBalance.ToSatoshis() + chanState[i] = autopilot.LocalChannel{ - ChanID: channel.ShortChanID(), - Capacity: channel.Capacity, + ChanID: channel.ShortChanID(), + Balance: balance, Node: autopilot.NewNodeID( - channel.IdentityPub), + channel.IdentityPub, + ), } } return chanState, nil }, + ChannelInfo: func(chanPoint wire.OutPoint) ( + *autopilot.LocalChannel, error) { + + channel, err := svr.remoteChanDB.FetchChannel(chanPoint) + if err != nil { + return nil, err + } + + localCommit := channel.LocalCommitment + return &autopilot.LocalChannel{ + ChanID: channel.ShortChanID(), + Balance: localCommit.LocalBalance.ToSatoshis(), + Node: autopilot.NewNodeID(channel.IdentityPub), + }, nil + }, SubscribeTransactions: svr.cc.wallet.SubscribeTransactions, SubscribeTopology: svr.chanRouter.SubscribeTopology, }, nil