Merge pull request #1888 from joostjager/routestruct

lnrpc+routing: fix unmarshallRoute and simplify route structure
This commit is contained in:
Olaoluwa Osuntokun authored and GitHub committed 2018-10-23 17:07:23 -07:00
commit fbd91feace
6 files changed
+269 -276

No files matched your search

+54 -39
View File
@@ -1904,7 +1904,7 @@ func (r *rpcServer) savePayment(route *routing.Route,
paymentPath := make([][33]byte, len(route.Hops))
for i, hop := range route.Hops {
hopPub := hop.Channel.Node.PubKeyBytes
hopPub := hop.PubKeyBytes
copy(paymentPath[i][:], hopPub[:])
}
@@ -2023,7 +2023,7 @@ func (r *rpcServer) SendToRoute(stream lnrpc.Lightning_SendToRouteServer) error
routes := make([]*routing.Route, len(req.Routes))
for i, rpcroute := range req.Routes {
route, err := unmarshallRoute(rpcroute, graph)
route, err := r.unmarshallRoute(rpcroute, graph)
if err != nil {
return nil, err
}
@@ -2437,7 +2437,7 @@ func (r *rpcServer) sendPayment(stream *paymentStream) error {
return
}
marshalledRouted := marshallRoute(resp.Route)
marshalledRouted := r.marshallRoute(resp.Route)
err := stream.send(&lnrpc.SendResponse{
PaymentPreimage: resp.Preimage[:],
PaymentRoute: marshalledRouted,
@@ -2478,7 +2478,7 @@ func (r *rpcServer) SendToRouteSync(ctx context.Context,
routes := make([]*routing.Route, len(req.Routes))
for i, route := range req.Routes {
route, err := unmarshallRoute(route, graph)
route, err := r.unmarshallRoute(route, graph)
if err != nil {
return nil, err
}
@@ -2528,7 +2528,7 @@ func (r *rpcServer) sendPaymentSync(ctx context.Context,
return &lnrpc.SendResponse{
PaymentPreimage: resp.Preimage[:],
PaymentRoute: marshallRoute(resp.Route),
PaymentRoute: r.marshallRoute(resp.Route),
}, nil
}
@@ -3406,14 +3406,14 @@ func (r *rpcServer) QueryRoutes(ctx context.Context,
}
for i := int32(0); i < numRoutes; i++ {
routeResp.Routes = append(
routeResp.Routes, marshallRoute(routes[i]),
routeResp.Routes, r.marshallRoute(routes[i]),
)
}
return routeResp, nil
}
func marshallRoute(route *routing.Route) *lnrpc.Route {
func (r *rpcServer) marshallRoute(route *routing.Route) *lnrpc.Route {
resp := &lnrpc.Route{
TotalTimeLock: route.TotalTimeLock,
TotalFees: int64(route.TotalFees.ToSatoshis()),
@@ -3422,72 +3422,87 @@ func marshallRoute(route *routing.Route) *lnrpc.Route {
TotalAmtMsat: int64(route.TotalAmount),
Hops: make([]*lnrpc.Hop, len(route.Hops)),
}
graph := r.server.chanDB.ChannelGraph()
incomingAmt := route.TotalAmount
for i, hop := range route.Hops {
fee := route.HopFee(i)
// Channel capacity is not a defining property of a route. For
// backwards RPC compatibility, we retrieve it here from the
// graph.
var chanCapacity btcutil.Amount
info, _, _, err := graph.FetchChannelEdgesByID(hop.ChannelID)
if err == nil {
chanCapacity = info.Capacity
} else {
// If capacity cannot be retrieved, this may be a
// not-yet-received or private channel. Then report
// amount that is sent through the channel as capacity.
chanCapacity = incomingAmt.ToSatoshis()
}
resp.Hops[i] = &lnrpc.Hop{
ChanId: hop.Channel.ChannelID,
ChanCapacity: int64(hop.Channel.Bandwidth.ToSatoshis()),
ChanId: hop.ChannelID,
ChanCapacity: int64(chanCapacity),
AmtToForward: int64(hop.AmtToForward.ToSatoshis()),
AmtToForwardMsat: int64(hop.AmtToForward),
Fee: int64(hop.Fee.ToSatoshis()),
FeeMsat: int64(hop.Fee),
Fee: int64(fee.ToSatoshis()),
FeeMsat: int64(fee),
Expiry: uint32(hop.OutgoingTimeLock),
}
incomingAmt = hop.AmtToForward
}
return resp
}
func unmarshallRoute(rpcroute *lnrpc.Route,
func (r *rpcServer) unmarshallRoute(rpcroute *lnrpc.Route,
graph *channeldb.ChannelGraph) (*routing.Route, error) {
route := &routing.Route{
TotalTimeLock: rpcroute.TotalTimeLock,
TotalFees: lnwire.MilliSatoshi(rpcroute.TotalFeesMsat),
TotalAmount: lnwire.MilliSatoshi(rpcroute.TotalAmtMsat),
Hops: make([]*routing.Hop, len(rpcroute.Hops)),
}
node, 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[:]
hops := make([]*routing.Hop, len(rpcroute.Hops))
for i, hop := range rpcroute.Hops {
edgeInfo, c1, c2, err := graph.FetchChannelEdgesByID(hop.ChanId)
// 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 for hop (%d): %v", i, err)
}
var channelEdgePolicy *channeldb.ChannelEdgePolicy
var pubKeyBytes [33]byte
switch {
case bytes.Equal(node.PubKeyBytes[:], c1.Node.PubKeyBytes[:]):
channelEdgePolicy = c2
node = c2.Node
case bytes.Equal(node.PubKeyBytes[:], c2.Node.PubKeyBytes[:]):
channelEdgePolicy = c1
node = c1.Node
case bytes.Equal(nodePubKeyBytes[:], edgeInfo.NodeKey1Bytes[:]):
pubKeyBytes = edgeInfo.NodeKey2Bytes
case bytes.Equal(nodePubKeyBytes[:], edgeInfo.NodeKey2Bytes[:]):
pubKeyBytes = edgeInfo.NodeKey1Bytes
default:
return nil, fmt.Errorf("could not find channel edge for hop=%d", i)
return nil, fmt.Errorf("channel edge does not match expected node")
}
routingHop := &routing.ChannelHop{
ChannelEdgePolicy: channelEdgePolicy,
Bandwidth: lnwire.NewMSatFromSatoshis(
btcutil.Amount(hop.ChanCapacity)),
Chain: edgeInfo.ChainHash,
}
route.Hops[i] = &routing.Hop{
Channel: routingHop,
hops[i] = &routing.Hop{
OutgoingTimeLock: hop.Expiry,
AmtToForward: lnwire.MilliSatoshi(hop.AmtToForwardMsat),
Fee: lnwire.MilliSatoshi(hop.FeeMsat),
PubKeyBytes: pubKeyBytes,
ChannelID: edgeInfo.ChannelID,
}
nodePubKeyBytes = pubKeyBytes[:]
}
route := routing.NewRouteFromHops(
lnwire.MilliSatoshi(rpcroute.TotalAmtMsat),
rpcroute.TotalTimeLock,
node.PubKeyBytes,
hops,
)
return route, nil
}