Merge pull request #1888 from joostjager/routestruct
lnrpc+routing: fix unmarshallRoute and simplify route structure
This commit is contained in:
6 files changed
+269
-276
No files matched your search
+54
-39
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user