routing: remove route hop maps
Hop maps were used in a test to verify the population of the hop map itself and further only in a single function (getFailedChannelID). Rewrote that function and removed the hop maps completely.
This commit is contained in:
parent
42debc6c12
commit
8b8e82a171
@ -146,6 +146,10 @@ type Route struct {
|
|||||||
// amount of fees.
|
// amount of fees.
|
||||||
TotalAmount lnwire.MilliSatoshi
|
TotalAmount lnwire.MilliSatoshi
|
||||||
|
|
||||||
|
// SourcePubKey is the pubkey of the node where this route originates
|
||||||
|
// from.
|
||||||
|
SourcePubKey Vertex
|
||||||
|
|
||||||
// Hops contains details concerning the specific forwarding details at
|
// Hops contains details concerning the specific forwarding details at
|
||||||
// each hop.
|
// each hop.
|
||||||
Hops []*Hop
|
Hops []*Hop
|
||||||
@ -158,16 +162,6 @@ type Route struct {
|
|||||||
// is present in this route or not. Channels are identified by the
|
// is present in this route or not. Channels are identified by the
|
||||||
// uint64 version of the short channel ID.
|
// uint64 version of the short channel ID.
|
||||||
chanIndex map[uint64]struct{}
|
chanIndex map[uint64]struct{}
|
||||||
|
|
||||||
// nextHop maps a node, to the next channel that it will pass the HTLC
|
|
||||||
// off to. With this map, we can easily look up the next outgoing
|
|
||||||
// channel or node for pruning purposes.
|
|
||||||
nextHopMap map[Vertex]*Hop
|
|
||||||
|
|
||||||
// prevHop maps a node, to the channel that was directly before it
|
|
||||||
// within the route. With this map, we can easily look up the previous
|
|
||||||
// channel or node for pruning purposes.
|
|
||||||
prevHopMap map[Vertex]*Hop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HopFee returns the fee charged by the route hop indicated by hopIndex.
|
// HopFee returns the fee charged by the route hop indicated by hopIndex.
|
||||||
@ -183,29 +177,6 @@ func (r *Route) HopFee(hopIndex int) lnwire.MilliSatoshi {
|
|||||||
return incomingAmt - r.Hops[hopIndex].AmtToForward
|
return incomingAmt - r.Hops[hopIndex].AmtToForward
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextHopVertex returns the next hop (by Vertex) after the target node. If the
|
|
||||||
// target node is not found in the route, then false is returned.
|
|
||||||
func (r *Route) nextHopVertex(n *btcec.PublicKey) (Vertex, bool) {
|
|
||||||
hop, ok := r.nextHopMap[NewVertex(n)]
|
|
||||||
return Vertex(hop.PubKeyBytes), ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// nextHopChannel returns the uint64 channel ID of the next hop after the
|
|
||||||
// target node. If the target node is not found in the route, then false is
|
|
||||||
// returned.
|
|
||||||
func (r *Route) nextHopChannel(n *btcec.PublicKey) (*Hop, bool) {
|
|
||||||
hop, ok := r.nextHopMap[NewVertex(n)]
|
|
||||||
return hop, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// prevHopChannel returns the uint64 channel ID of the before hop after the
|
|
||||||
// target node. If the target node is not found in the route, then false is
|
|
||||||
// returned.
|
|
||||||
func (r *Route) prevHopChannel(n *btcec.PublicKey) (*Hop, bool) {
|
|
||||||
hop, ok := r.prevHopMap[NewVertex(n)]
|
|
||||||
return hop, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// containsNode returns true if a node is present in the target route, and
|
// containsNode returns true if a node is present in the target route, and
|
||||||
// false otherwise.
|
// false otherwise.
|
||||||
func (r *Route) containsNode(v Vertex) bool {
|
func (r *Route) containsNode(v Vertex) bool {
|
||||||
@ -381,31 +352,21 @@ func NewRouteFromHops(amtToSend lnwire.MilliSatoshi, timeLock uint32,
|
|||||||
// that is send from the source and the final amount that is received
|
// that is send from the source and the final amount that is received
|
||||||
// by the destination.
|
// by the destination.
|
||||||
route := &Route{
|
route := &Route{
|
||||||
|
SourcePubKey: sourceVertex,
|
||||||
Hops: hops,
|
Hops: hops,
|
||||||
TotalTimeLock: timeLock,
|
TotalTimeLock: timeLock,
|
||||||
TotalAmount: amtToSend,
|
TotalAmount: amtToSend,
|
||||||
TotalFees: amtToSend - hops[len(hops)-1].AmtToForward,
|
TotalFees: amtToSend - hops[len(hops)-1].AmtToForward,
|
||||||
nodeIndex: make(map[Vertex]struct{}),
|
nodeIndex: make(map[Vertex]struct{}),
|
||||||
chanIndex: make(map[uint64]struct{}),
|
chanIndex: make(map[uint64]struct{}),
|
||||||
nextHopMap: make(map[Vertex]*Hop),
|
|
||||||
prevHopMap: make(map[Vertex]*Hop),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then we'll update the node and channel index, to indicate that this
|
// Then we'll update the node and channel index, to indicate that this
|
||||||
// Vertex and incoming channel link are present within this route.
|
// Vertex and incoming channel link are present within this route.
|
||||||
// Also, the prev and next hop maps will be populated.
|
for _, hop := range hops {
|
||||||
prevNode := sourceVertex
|
|
||||||
for i := 0; i < len(hops); i++ {
|
|
||||||
hop := hops[i]
|
|
||||||
|
|
||||||
v := Vertex(hop.PubKeyBytes)
|
v := Vertex(hop.PubKeyBytes)
|
||||||
|
|
||||||
route.nodeIndex[v] = struct{}{}
|
route.nodeIndex[v] = struct{}{}
|
||||||
route.chanIndex[hop.ChannelID] = struct{}{}
|
route.chanIndex[hop.ChannelID] = struct{}{}
|
||||||
route.prevHopMap[v] = hop
|
|
||||||
route.nextHopMap[prevNode] = hop
|
|
||||||
|
|
||||||
prevNode = v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return route
|
return route
|
||||||
|
@ -845,35 +845,6 @@ func testBasicGraphPathFindingCase(t *testing.T, graphInstance *testGraphInstanc
|
|||||||
t.Fatalf("expected time lock of %v, instead have %v", 2,
|
t.Fatalf("expected time lock of %v, instead have %v", 2,
|
||||||
route.TotalTimeLock)
|
route.TotalTimeLock)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The next and prev hop maps should be properly set.
|
|
||||||
for i := 0; i < expectedHopCount; i++ {
|
|
||||||
prevChan, ok := route.prevHopChannel(aliases[expectedHops[i].alias])
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("hop didn't have prev chan but should have")
|
|
||||||
}
|
|
||||||
if prevChan.ChannelID != route.Hops[i].ChannelID {
|
|
||||||
t.Fatalf("incorrect prev chan: expected %v, got %v",
|
|
||||||
prevChan.ChannelID, route.Hops[i].ChannelID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < expectedHopCount-1; i++ {
|
|
||||||
nextChan, ok := route.nextHopChannel(aliases[expectedHops[i].alias])
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("hop didn't have prev chan but should have")
|
|
||||||
}
|
|
||||||
if nextChan.ChannelID != route.Hops[i+1].ChannelID {
|
|
||||||
t.Fatalf("incorrect prev chan: expected %v, got %v",
|
|
||||||
nextChan.ChannelID, route.Hops[i+1].ChannelID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Final hop shouldn't have a next chan
|
|
||||||
if _, ok := route.nextHopChannel(aliases[expectedHops[lastHopIndex].alias]); ok {
|
|
||||||
t.Fatalf("incorrect next hop map, no vertexes should " +
|
|
||||||
"be after sophon")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPathFindingWithAdditionalEdges(t *testing.T) {
|
func TestPathFindingWithAdditionalEdges(t *testing.T) {
|
||||||
|
@ -1760,7 +1760,9 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
|
|||||||
|
|
||||||
// Always determine chan id ourselves, because a channel
|
// Always determine chan id ourselves, because a channel
|
||||||
// update with id may not be available.
|
// update with id may not be available.
|
||||||
failedChanID, err := getFailedChannelID(route, errSource)
|
failedChanID, err := getFailedChannelID(
|
||||||
|
route, errVertex,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return preImage, nil, err
|
return preImage, nil, err
|
||||||
}
|
}
|
||||||
@ -1966,28 +1968,40 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
|
|||||||
// getFailedChannelID tries to locate the failing channel given a route and the
|
// getFailedChannelID tries to locate the failing channel given a route and the
|
||||||
// pubkey of the node that sent the error. It will assume that the error is
|
// pubkey of the node that sent the error. It will assume that the error is
|
||||||
// associated with the outgoing channel of the error node.
|
// associated with the outgoing channel of the error node.
|
||||||
func getFailedChannelID(route *Route, errSource *btcec.PublicKey) (
|
func getFailedChannelID(route *Route, errSource Vertex) (
|
||||||
uint64, error) {
|
uint64, error) {
|
||||||
|
|
||||||
// As this error indicates that the target channel was unable to carry
|
// If the error originates from ourselves, report our outgoing channel
|
||||||
// this HTLC (for w/e reason), we'll query the index to find the
|
// as failing.
|
||||||
// _outgoing_ channel the source of the error was meant to pass the
|
if errSource == route.SourcePubKey {
|
||||||
// HTLC along to.
|
return route.Hops[0].ChannelID, nil
|
||||||
if badChan, ok := route.nextHopChannel(errSource); ok {
|
|
||||||
return badChan.ChannelID, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we weren't able to find the hop *after* this node, then we'll
|
hopCount := len(route.Hops)
|
||||||
// attempt to disable the previous channel.
|
for i, hop := range route.Hops {
|
||||||
|
if errSource != hop.PubKeyBytes {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the errSource is the final hop, we assume that the
|
||||||
|
// failing channel is the incoming channel.
|
||||||
//
|
//
|
||||||
// TODO(joostjager): errSource must be the final hop then? In that case,
|
// TODO(joostjager): In this case, certain types of
|
||||||
// certain types of errors are not expected. For example
|
// errors are not expected. For example
|
||||||
// FailUnknownNextPeer. This could be a reason to prune the node?
|
// FailUnknownNextPeer. This could be a reason to prune
|
||||||
if prevChan, ok := route.prevHopChannel(errSource); ok {
|
// the node?
|
||||||
return prevChan.ChannelID, nil
|
if i == hopCount-1 {
|
||||||
|
return route.Hops[i].ChannelID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, fmt.Errorf("cannot find channel in route")
|
// As this error indicates that the target channel was
|
||||||
|
// unable to carry this HTLC (for w/e reason), we'll
|
||||||
|
// query return the _outgoing_ channel that the source
|
||||||
|
// of the error was meant to pass the HTLC along to.
|
||||||
|
return route.Hops[i+1].ChannelID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, fmt.Errorf("cannot find error source node in route")
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyChannelUpdate validates a channel update and if valid, applies it to the
|
// applyChannelUpdate validates a channel update and if valid, applies it to the
|
||||||
|
Loading…
Reference in New Issue
Block a user