routing: eliminate nested db transactions by using new FetchOtherNode method

This commit is contained in:
Olaoluwa Osuntokun 2018-08-09 20:47:56 -07:00
parent 0f3c0ccf85
commit 3438baaf0c
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21

@ -490,8 +490,8 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// traversal. // traversal.
var nodeHeap distanceHeap var nodeHeap distanceHeap
// For each node in the graph, we create an entry in the distance // For each node in the graph, we create an entry in the distance map
// map for the node set with a distance of "infinity". graph.ForEachNode // for the node set with a distance of "infinity". graph.ForEachNode
// also returns the source node, so there is no need to add the source // also returns the source node, so there is no need to add the source
// node explictly. // node explictly.
distance := make(map[Vertex]nodeWithDist) distance := make(map[Vertex]nodeWithDist)
@ -509,16 +509,16 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
additionalEdgesWithSrc := make(map[Vertex][]*edgePolicyWithSource) additionalEdgesWithSrc := make(map[Vertex][]*edgePolicyWithSource)
for vertex, outgoingEdgePolicies := range additionalEdges { for vertex, outgoingEdgePolicies := range additionalEdges {
// We'll also include all the nodes found within the additional edges // We'll also include all the nodes found within the additional
// that are not known to us yet in the distance map. // edges that are not known to us yet in the distance map.
node := &channeldb.LightningNode{PubKeyBytes: vertex} node := &channeldb.LightningNode{PubKeyBytes: vertex}
distance[vertex] = nodeWithDist{ distance[vertex] = nodeWithDist{
dist: infinity, dist: infinity,
node: node, node: node,
} }
// Build reverse lookup to find incoming edges. Needed // Build reverse lookup to find incoming edges. Needed because
// because search is taken place from target to source. // search is taken place from target to source.
for _, outgoingEdgePolicy := range outgoingEdgePolicies { for _, outgoingEdgePolicy := range outgoingEdgePolicies {
toVertex := outgoingEdgePolicy.Node.PubKeyBytes toVertex := outgoingEdgePolicy.Node.PubKeyBytes
incomingEdgePolicy := &edgePolicyWithSource{ incomingEdgePolicy := &edgePolicyWithSource{
@ -536,10 +536,10 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// We can't always assume that the end destination is publicly // We can't always assume that the end destination is publicly
// advertised to the network and included in the graph.ForEachNode call // advertised to the network and included in the graph.ForEachNode call
// above, so we'll manually include the target node. The target // above, so we'll manually include the target node. The target node
// node charges no fee. Distance is set to 0, because this is the // charges no fee. Distance is set to 0, because this is the starting
// starting point of the graph traversal. We are searching backwards to // point of the graph traversal. We are searching backwards to get the
// get the fees first time right and correctly match channel bandwidth. // fees first time right and correctly match channel bandwidth.
targetVertex := NewVertex(target) targetVertex := NewVertex(target)
targetNode := &channeldb.LightningNode{PubKeyBytes: targetVertex} targetNode := &channeldb.LightningNode{PubKeyBytes: targetVertex}
distance[targetVertex] = nodeWithDist{ distance[targetVertex] = nodeWithDist{
@ -569,8 +569,8 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
return return
} }
// If this vertex or edge has been black listed, then we'll skip // If this vertex or edge has been black listed, then we'll
// exploring this edge. // skip exploring this edge.
if _, ok := ignoredNodes[fromVertex]; ok { if _, ok := ignoredNodes[fromVertex]; ok {
return return
} }
@ -588,8 +588,8 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
return return
} }
// If the amountToSend is less than the minimum required amount, // If the amountToSend is less than the minimum required
// return. // amount, return.
if amountToSend < edge.MinHTLC { if amountToSend < edge.MinHTLC {
return return
} }
@ -598,12 +598,12 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// amount that needs to be sent to the next node in the route. // amount that needs to be sent to the next node in the route.
// //
// Source node has no precedessor to pay a fee. Therefore set // Source node has no precedessor to pay a fee. Therefore set
// fee to zero, because it should not be included in the // fee to zero, because it should not be included in the fee
// fee limit check and edge weight. // limit check and edge weight.
// //
// Also determine the time lock delta that will be added to // Also determine the time lock delta that will be added to the
// the route if fromNode is selected. If fromNode is the // route if fromNode is selected. If fromNode is the source
// source node, no additional timelock is required. // node, no additional timelock is required.
var fee lnwire.MilliSatoshi var fee lnwire.MilliSatoshi
var timeLockDelta uint16 var timeLockDelta uint16
if fromVertex != sourceVertex { if fromVertex != sourceVertex {
@ -611,15 +611,15 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
timeLockDelta = edge.TimeLockDelta timeLockDelta = edge.TimeLockDelta
} }
// amountToReceive is the amount that the node that // amountToReceive is the amount that the node that is added to
// is added to the distance map needs to receive from // the distance map needs to receive from a (to be found)
// a (to be found) previous node in the route. That // previous node in the route. That previous node will need to
// previous node will need to pay the amount that this // pay the amount that this node forwards plus the fee it
// node forwards plus the fee it charges. // charges.
amountToReceive := amountToSend + fee amountToReceive := amountToSend + fee
// Check if accumulated fees would exceed fee limit when // Check if accumulated fees would exceed fee limit when this
// this node would be added to the path. // node would be added to the path.
totalFee := amountToReceive - amt totalFee := amountToReceive - amt
if totalFee > feeLimit { if totalFee > feeLimit {
return return
@ -627,13 +627,13 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// By adding fromNode in the route, there will be an extra // By adding fromNode in the route, there will be an extra
// weight composed of the fee that this node will charge and // weight composed of the fee that this node will charge and
// the amount that will be locked for timeLockDelta blocks // the amount that will be locked for timeLockDelta blocks in
// in the HTLC that is handed out to fromNode. // the HTLC that is handed out to fromNode.
weight := edgeWeight(amountToReceive, fee, timeLockDelta) weight := edgeWeight(amountToReceive, fee, timeLockDelta)
// Compute the tentative distance to this new channel/edge which // Compute the tentative distance to this new channel/edge
// is the distance from our toNode to the target node plus the // which is the distance from our toNode to the target node
// weight of this edge. // plus the weight of this edge.
tempDist := toNodeDist.dist + weight tempDist := toNodeDist.dist + weight
// If this new tentative distance is not better than the current // If this new tentative distance is not better than the current
@ -654,8 +654,8 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// All conditions are met and this new tentative distance is // All conditions are met and this new tentative distance is
// better than the current best known distance to this node. // better than the current best known distance to this node.
// The new better distance is recorded, and also our // The new better distance is recorded, and also our "next hop"
// "next hop" map is populated with this edge. // map is populated with this edge.
distance[fromVertex] = nodeWithDist{ distance[fromVertex] = nodeWithDist{
dist: tempDist, dist: tempDist,
node: fromNode, node: fromNode,
@ -722,34 +722,20 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
) )
} }
// Lookup the source node at the other side of the // Before we can process the edge, we'll need to fetch
// channel via edgeInfo. This is necessary because this // the node on the _other_ end of this channel as we
// information is not present in inEdge. // may later need to iterate over the incoming edges of
channelSourcePubKeyBytes, err := edgeInfo.OtherNodeKeyBytes(pivot[:]) // this node if we explore it further.
channelSource, err := edgeInfo.FetchOtherNode(
tx, pivot[:],
)
if err != nil { if err != nil {
return err return err
} }
channelSourcePubKey, err := btcec.ParsePubKey( // Check if this candidate node is better than what we
channelSourcePubKeyBytes[:], btcec.S256()) // already have.
if err != nil {
return err
}
// Lookup the full node details in order to be able to
// later iterate over all incoming edges of the source
// node.
channelSource, err := graph.FetchLightningNode(channelSourcePubKey)
if err != nil {
return err
}
// Check if this candidate node is better than what
// we already have.
processEdge(channelSource, inEdge, edgeBandwidth, pivot) processEdge(channelSource, inEdge, edgeBandwidth, pivot)
// TODO(roasbeef): return min HTLC as error in end?
return nil return nil
}) })
if err != nil { if err != nil {