diff --git a/lnrpc/routerrpc/config_active.go b/lnrpc/routerrpc/config_active.go index 44b238b3..edf98035 100644 --- a/lnrpc/routerrpc/config_active.go +++ b/lnrpc/routerrpc/config_active.go @@ -40,4 +40,8 @@ type Config struct { // // TODO(roasbeef): assumes router handles saving payment state Router *routing.ChannelRouter + + // RouterBackend contains shared logic between this sub server and the + // main rpc server. + RouterBackend *RouterBackend } diff --git a/lnrpc/routerrpc/router_server.go b/lnrpc/routerrpc/router_server.go index 01e92c29..5e21e733 100644 --- a/lnrpc/routerrpc/router_server.go +++ b/lnrpc/routerrpc/router_server.go @@ -4,13 +4,13 @@ package routerrpc import ( "context" + "errors" "fmt" "io/ioutil" "os" "path/filepath" "time" - "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnwire" @@ -190,12 +190,15 @@ func (s *Server) SendPayment(ctx context.Context, return nil, fmt.Errorf("zero value invoices are not supported") } + var destination routing.Vertex + copy(destination[:], payReq.Destination.SerializeCompressed()) + // Now that all the information we need has been parsed, we'll map this // proto request into a proper request that our backing router can // understand. finalDelta := uint16(payReq.MinFinalCLTVExpiry()) payment := routing.LightningPayment{ - Target: payReq.Destination, + Target: destination, Amount: *payReq.MilliSat, FeeLimit: lnwire.MilliSatoshi(req.FeeLimitSat), PaymentHash: *payReq.PaymentHash, @@ -226,22 +229,28 @@ func (s *Server) SendPayment(ctx context.Context, func (s *Server) EstimateRouteFee(ctx context.Context, req *RouteFeeRequest) (*RouteFeeResponse, error) { - // First we'll parse out the raw public key into a value that we can - // utilize. - destNode, err := btcec.ParsePubKey(req.Dest, btcec.S256()) - if err != nil { - return nil, err + if len(req.Dest) != 33 { + return nil, errors.New("invalid length destination key") } + var destNode routing.Vertex + copy(destNode[:], req.Dest) // Next, we'll convert the amount in satoshis to mSAT, which are the // native unit of LN. amtMsat := lnwire.NewMSatFromSatoshis(btcutil.Amount(req.AmtSat)) + // Pick a fee limit + // + // TODO: Change this into behaviour that makes more sense. + feeLimit := lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin) + // Finally, we'll query for a route to the destination that can carry // that target amount, we'll only request a single route. routes, err := s.cfg.Router.FindRoutes( - destNode, amtMsat, - lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin), 1, + s.cfg.RouterBackend.SelfNode, destNode, amtMsat, + &routing.RestrictParams{ + FeeLimit: feeLimit, + }, 1, ) if err != nil { return nil, err diff --git a/rpcserver.go b/rpcserver.go index 17752abe..8dbcb735 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -395,9 +395,9 @@ type rpcServer struct { // connect to the main gRPC server to proxy all incoming requests. tlsCfg *tls.Config - // RouterBackend contains the backend implementation of the router + // routerBackend contains the backend implementation of the router // rpc sub server. - RouterBackend *routerrpc.RouterBackend + routerBackend *routerrpc.RouterBackend quit chan struct{} } @@ -417,6 +417,28 @@ func newRPCServer(s *server, macService *macaroons.Service, invoiceRegistry *invoices.InvoiceRegistry, tlsCfg *tls.Config) (*rpcServer, error) { + // Set up router rpc backend. + channelGraph := s.chanDB.ChannelGraph() + selfNode, err := channelGraph.SourceNode() + if err != nil { + return nil, err + } + graph := s.chanDB.ChannelGraph() + routerBackend := &routerrpc.RouterBackend{ + MaxPaymentMSat: maxPaymentMSat, + SelfNode: selfNode.PubKeyBytes, + FetchChannelCapacity: func(chanID uint64) (btcutil.Amount, + error) { + + info, _, _, err := graph.FetchChannelEdgesByID(chanID) + if err != nil { + return 0, err + } + return info.Capacity, nil + }, + FindRoutes: s.chanRouter.FindRoutes, + } + var ( subServers []lnrpc.SubServer subServerPerms []lnrpc.MacaroonPerms @@ -425,10 +447,10 @@ func newRPCServer(s *server, macService *macaroons.Service, // Before we create any of the sub-servers, we need to ensure that all // the dependencies they need are properly populated within each sub // server configuration struct. - err := subServerCgs.PopulateDependencies( + err = subServerCgs.PopulateDependencies( s.cc, networkDir, macService, atpl, invoiceRegistry, s.htlcSwitch, activeNetParams.Params, s.chanRouter, - s.nodeSigner, s.chanDB, + routerBackend, s.nodeSigner, s.chanDB, ) if err != nil { return nil, err @@ -483,28 +505,6 @@ func newRPCServer(s *server, macService *macaroons.Service, ) } - // Set up router rpc backend. - channelGraph := s.chanDB.ChannelGraph() - selfNode, err := channelGraph.SourceNode() - if err != nil { - return nil, err - } - graph := s.chanDB.ChannelGraph() - RouterBackend := &routerrpc.RouterBackend{ - MaxPaymentMSat: maxPaymentMSat, - SelfNode: selfNode.PubKeyBytes, - FetchChannelCapacity: func(chanID uint64) (btcutil.Amount, - error) { - - info, _, _, err := graph.FetchChannelEdgesByID(chanID) - if err != nil { - return 0, err - } - return info.Capacity, nil - }, - FindRoutes: s.chanRouter.FindRoutes, - } - // Finally, with all the pre-set up complete, we can create the main // gRPC server, and register the main lnrpc server along side. grpcServer := grpc.NewServer(serverOpts...) @@ -514,7 +514,7 @@ func newRPCServer(s *server, macService *macaroons.Service, tlsCfg: tlsCfg, grpcServer: grpcServer, server: s, - RouterBackend: RouterBackend, + routerBackend: routerBackend, quit: make(chan struct{}, 1), } lnrpc.RegisterLightningServer(grpcServer, rootRPCServer) @@ -3241,7 +3241,9 @@ func (r *rpcServer) sendPayment(stream *paymentStream) error { return } - marshalledRouted := r.RouterBackend.MarshallRoute(resp.Route) + marshalledRouted := r.routerBackend. + MarshallRoute(resp.Route) + err := stream.send(&lnrpc.SendResponse{ PaymentHash: payIntent.rHash[:], PaymentPreimage: resp.Preimage[:], @@ -3326,7 +3328,7 @@ func (r *rpcServer) sendPaymentSync(ctx context.Context, return &lnrpc.SendResponse{ PaymentHash: payIntent.rHash[:], PaymentPreimage: resp.Preimage[:], - PaymentRoute: r.RouterBackend.MarshallRoute(resp.Route), + PaymentRoute: r.routerBackend.MarshallRoute(resp.Route), }, nil } @@ -3827,7 +3829,7 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context, func (r *rpcServer) QueryRoutes(ctx context.Context, in *lnrpc.QueryRoutesRequest) (*lnrpc.QueryRoutesResponse, error) { - return r.RouterBackend.QueryRoutes(ctx, in) + return r.routerBackend.QueryRoutes(ctx, in) } // unmarshallHopByChannelLookup unmarshalls an rpc hop for which the pub key is diff --git a/subrpcserver_config.go b/subrpcserver_config.go index 9722bda0..c697b03e 100644 --- a/subrpcserver_config.go +++ b/subrpcserver_config.go @@ -70,6 +70,7 @@ func (s *subRPCServerConfigs) PopulateDependencies(cc *chainControl, htlcSwitch *htlcswitch.Switch, activeNetParams *chaincfg.Params, chanRouter *routing.ChannelRouter, + routerBackend *routerrpc.RouterBackend, nodeSigner *netann.NodeSigner, chanDB *channeldb.DB) error { @@ -185,7 +186,7 @@ func (s *subRPCServerConfigs) PopulateDependencies(cc *chainControl, ) case *routerrpc.Config: - subCfgValue := extractReflectValue(cfg) + subCfgValue := extractReflectValue(subCfg) subCfgValue.FieldByName("NetworkDir").Set( reflect.ValueOf(networkDir), @@ -199,6 +200,9 @@ func (s *subRPCServerConfigs) PopulateDependencies(cc *chainControl, subCfgValue.FieldByName("Router").Set( reflect.ValueOf(chanRouter), ) + subCfgValue.FieldByName("RouterBackend").Set( + reflect.ValueOf(routerBackend), + ) default: return fmt.Errorf("unknown field: %v, %T", fieldName,