lnrpc: extract hop unmarshall code

This commit is contained in:
Joost Jager 2018-10-29 13:07:08 +01:00
parent 68d96488cc
commit e55a678eda
No known key found for this signature in database
GPG Key ID: AE6B0D042C8E38D9

@ -3516,50 +3516,71 @@ func (r *rpcServer) marshallRoute(route *routing.Route) *lnrpc.Route {
return resp
}
// unmarshallHopByChannelLookup unmarshalls an rpc hop for which the pub key is
// not known. This function will query the channel graph with channel id to
// retrieve both endpoints and determine the hop pubkey using the previous hop
// pubkey. If the channel is unknown, an error is returned.
func unmarshallHopByChannelLookup(graph *channeldb.ChannelGraph, hop *lnrpc.Hop,
prevPubKeyBytes []byte) (*routing.Hop, error) {
// Discard edge policies, because they may be nil.
edgeInfo, _, _, err := graph.FetchChannelEdgesByID(hop.ChanId)
if err != nil {
return nil, fmt.Errorf("unable to fetch channel edges by "+
"channel ID %d: %v", hop.ChanId, err)
}
var pubKeyBytes [33]byte
switch {
case bytes.Equal(prevPubKeyBytes, edgeInfo.NodeKey1Bytes[:]):
pubKeyBytes = edgeInfo.NodeKey2Bytes
case bytes.Equal(prevPubKeyBytes, edgeInfo.NodeKey2Bytes[:]):
pubKeyBytes = edgeInfo.NodeKey1Bytes
default:
return nil, fmt.Errorf("channel edge does not match expected node")
}
return &routing.Hop{
OutgoingTimeLock: hop.Expiry,
AmtToForward: lnwire.MilliSatoshi(hop.AmtToForwardMsat),
PubKeyBytes: pubKeyBytes,
ChannelID: edgeInfo.ChannelID,
}, nil
}
// unmarshallRoute unmarshalls an rpc route. For hops that don't specify a
// pubkey, the channel graph is queried.
func (r *rpcServer) unmarshallRoute(rpcroute *lnrpc.Route,
graph *channeldb.ChannelGraph) (*routing.Route, error) {
node, err := graph.SourceNode()
sourceNode, err := graph.SourceNode()
if err != nil {
return nil, fmt.Errorf("unable to fetch source node from graph "+
"while unmarshaling route. %v", err)
}
nodePubKeyBytes := node.PubKeyBytes[:]
prevNodePubKey := sourceNode.PubKeyBytes[:]
hops := make([]*routing.Hop, len(rpcroute.Hops))
for i, hop := range rpcroute.Hops {
// Discard edge policies, because they may be nil.
edgeInfo, _, _, err := graph.FetchChannelEdgesByID(hop.ChanId)
// No hop pub key is given, so the local channel graph needs to
// be queried to complete the information necessary for routing.
routeHop, err := unmarshallHopByChannelLookup(graph,
hop, prevNodePubKey)
if err != nil {
return nil, fmt.Errorf("unable to fetch channel edges by "+
"channel ID for hop (%d): %v", i, err)
return nil, err
}
var pubKeyBytes [33]byte
switch {
case bytes.Equal(nodePubKeyBytes[:], edgeInfo.NodeKey1Bytes[:]):
pubKeyBytes = edgeInfo.NodeKey2Bytes
case bytes.Equal(nodePubKeyBytes[:], edgeInfo.NodeKey2Bytes[:]):
pubKeyBytes = edgeInfo.NodeKey1Bytes
default:
return nil, fmt.Errorf("channel edge does not match expected node")
}
hops[i] = routeHop
hops[i] = &routing.Hop{
OutgoingTimeLock: hop.Expiry,
AmtToForward: lnwire.MilliSatoshi(hop.AmtToForwardMsat),
PubKeyBytes: pubKeyBytes,
ChannelID: edgeInfo.ChannelID,
}
nodePubKeyBytes = pubKeyBytes[:]
prevNodePubKey = routeHop.PubKeyBytes[:]
}
route := routing.NewRouteFromHops(
lnwire.MilliSatoshi(rpcroute.TotalAmtMsat),
rpcroute.TotalTimeLock,
node.PubKeyBytes,
sourceNode.PubKeyBytes,
hops,
)