github.com/decred/dcrlnd@v0.7.6/lnrpc/routerrpc/router_server.go (about)

     1  package routerrpc
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"sync/atomic"
    11  	"time"
    12  
    13  	"github.com/decred/dcrd/dcrutil/v4"
    14  	"github.com/decred/dcrd/wire"
    15  	"github.com/decred/dcrlnd/channeldb"
    16  	"github.com/decred/dcrlnd/lnrpc"
    17  	"github.com/decred/dcrlnd/lntypes"
    18  	"github.com/decred/dcrlnd/lnwire"
    19  	"github.com/decred/dcrlnd/macaroons"
    20  	"github.com/decred/dcrlnd/routing"
    21  	"github.com/decred/dcrlnd/routing/route"
    22  	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
    23  	"google.golang.org/grpc"
    24  	"google.golang.org/grpc/codes"
    25  	"google.golang.org/grpc/status"
    26  	"gopkg.in/macaroon-bakery.v2/bakery"
    27  )
    28  
    29  const (
    30  	// subServerName is the name of the sub rpc server. We'll use this name
    31  	// to register ourselves, and we also require that the main
    32  	// SubServerConfigDispatcher instance recognize as the name of our
    33  	subServerName = "RouterRPC"
    34  )
    35  
    36  var (
    37  	errServerShuttingDown = errors.New("routerrpc server shutting down")
    38  
    39  	// ErrInterceptorAlreadyExists is an error returned when the a new stream
    40  	// is opened and there is already one active interceptor.
    41  	// The user must disconnect prior to open another stream.
    42  	ErrInterceptorAlreadyExists = errors.New("interceptor already exists")
    43  
    44  	// macaroonOps are the set of capabilities that our minted macaroon (if
    45  	// it doesn't already exist) will have.
    46  	macaroonOps = []bakery.Op{
    47  		{
    48  			Entity: "offchain",
    49  			Action: "read",
    50  		},
    51  		{
    52  			Entity: "offchain",
    53  			Action: "write",
    54  		},
    55  	}
    56  
    57  	// macPermissions maps RPC calls to the permissions they require.
    58  	macPermissions = map[string][]bakery.Op{
    59  		"/routerrpc.Router/SendPaymentV2": {{
    60  			Entity: "offchain",
    61  			Action: "write",
    62  		}},
    63  		"/routerrpc.Router/SendToRouteV2": {{
    64  			Entity: "offchain",
    65  			Action: "write",
    66  		}},
    67  		"/routerrpc.Router/SendToRoute": {{
    68  			Entity: "offchain",
    69  			Action: "write",
    70  		}},
    71  		"/routerrpc.Router/TrackPaymentV2": {{
    72  			Entity: "offchain",
    73  			Action: "read",
    74  		}},
    75  		"/routerrpc.Router/EstimateRouteFee": {{
    76  			Entity: "offchain",
    77  			Action: "read",
    78  		}},
    79  		"/routerrpc.Router/QueryMissionControl": {{
    80  			Entity: "offchain",
    81  			Action: "read",
    82  		}},
    83  		"/routerrpc.Router/XImportMissionControl": {{
    84  			Entity: "offchain",
    85  			Action: "write",
    86  		}},
    87  		"/routerrpc.Router/GetMissionControlConfig": {{
    88  			Entity: "offchain",
    89  			Action: "read",
    90  		}},
    91  		"/routerrpc.Router/SetMissionControlConfig": {{
    92  			Entity: "offchain",
    93  			Action: "write",
    94  		}},
    95  		"/routerrpc.Router/QueryProbability": {{
    96  			Entity: "offchain",
    97  			Action: "read",
    98  		}},
    99  		"/routerrpc.Router/ResetMissionControl": {{
   100  			Entity: "offchain",
   101  			Action: "write",
   102  		}},
   103  		"/routerrpc.Router/BuildRoute": {{
   104  			Entity: "offchain",
   105  			Action: "read",
   106  		}},
   107  		"/routerrpc.Router/SubscribeHtlcEvents": {{
   108  			Entity: "offchain",
   109  			Action: "read",
   110  		}},
   111  		"/routerrpc.Router/SendPayment": {{
   112  			Entity: "offchain",
   113  			Action: "write",
   114  		}},
   115  		"/routerrpc.Router/TrackPayment": {{
   116  			Entity: "offchain",
   117  			Action: "read",
   118  		}},
   119  		"/routerrpc.Router/HtlcInterceptor": {{
   120  			Entity: "offchain",
   121  			Action: "write",
   122  		}},
   123  		"/routerrpc.Router/UpdateChanStatus": {{
   124  			Entity: "offchain",
   125  			Action: "write",
   126  		}},
   127  	}
   128  
   129  	// DefaultRouterMacFilename is the default name of the router macaroon
   130  	// that we expect to find via a file handle within the main
   131  	// configuration file in this package.
   132  	DefaultRouterMacFilename = "router.macaroon"
   133  )
   134  
   135  // ServerShell a is shell struct holding a reference to the actual sub-server.
   136  // It is used to register the gRPC sub-server with the root server before we
   137  // have the necessary dependencies to populate the actual sub-server.
   138  type ServerShell struct {
   139  	RouterServer
   140  }
   141  
   142  // Server is a stand alone sub RPC server which exposes functionality that
   143  // allows clients to route arbitrary payment through the Lightning Network.
   144  type Server struct {
   145  	started                  int32 // To be used atomically.
   146  	shutdown                 int32 // To be used atomically.
   147  	forwardInterceptorActive int32 // To be used atomically.
   148  
   149  	cfg *Config
   150  
   151  	quit chan struct{}
   152  }
   153  
   154  // A compile time check to ensure that Server fully implements the RouterServer
   155  // gRPC service.
   156  var _ RouterServer = (*Server)(nil)
   157  
   158  // New creates a new instance of the RouterServer given a configuration struct
   159  // that contains all external dependencies. If the target macaroon exists, and
   160  // we're unable to create it, then an error will be returned. We also return
   161  // the set of permissions that we require as a server. At the time of writing
   162  // of this documentation, this is the same macaroon as as the admin macaroon.
   163  func New(cfg *Config) (*Server, lnrpc.MacaroonPerms, error) {
   164  	// If the path of the router macaroon wasn't generated, then we'll
   165  	// assume that it's found at the default network directory.
   166  	if cfg.RouterMacPath == "" {
   167  		cfg.RouterMacPath = filepath.Join(
   168  			cfg.NetworkDir, DefaultRouterMacFilename,
   169  		)
   170  	}
   171  
   172  	// Now that we know the full path of the router macaroon, we can check
   173  	// to see if we need to create it or not. If stateless_init is set
   174  	// then we don't write the macaroons.
   175  	macFilePath := cfg.RouterMacPath
   176  	if cfg.MacService != nil && !cfg.MacService.StatelessInit &&
   177  		!lnrpc.FileExists(macFilePath) {
   178  
   179  		log.Infof("Making macaroons for Router RPC Server at: %v",
   180  			macFilePath)
   181  
   182  		// At this point, we know that the router macaroon doesn't yet,
   183  		// exist, so we need to create it with the help of the main
   184  		// macaroon service.
   185  		routerMac, err := cfg.MacService.NewMacaroon(
   186  			context.Background(), macaroons.DefaultRootKeyID,
   187  			macaroonOps...,
   188  		)
   189  		if err != nil {
   190  			return nil, nil, err
   191  		}
   192  		routerMacBytes, err := routerMac.M().MarshalBinary()
   193  		if err != nil {
   194  			return nil, nil, err
   195  		}
   196  		err = ioutil.WriteFile(macFilePath, routerMacBytes, 0644)
   197  		if err != nil {
   198  			_ = os.Remove(macFilePath)
   199  			return nil, nil, err
   200  		}
   201  	}
   202  
   203  	routerServer := &Server{
   204  		cfg:  cfg,
   205  		quit: make(chan struct{}),
   206  	}
   207  
   208  	return routerServer, macPermissions, nil
   209  }
   210  
   211  // Start launches any helper goroutines required for the rpcServer to function.
   212  //
   213  // NOTE: This is part of the lnrpc.SubServer interface.
   214  func (s *Server) Start() error {
   215  	if atomic.AddInt32(&s.started, 1) != 1 {
   216  		return nil
   217  	}
   218  
   219  	return nil
   220  }
   221  
   222  // Stop signals any active goroutines for a graceful closure.
   223  //
   224  // NOTE: This is part of the lnrpc.SubServer interface.
   225  func (s *Server) Stop() error {
   226  	if atomic.AddInt32(&s.shutdown, 1) != 1 {
   227  		return nil
   228  	}
   229  
   230  	close(s.quit)
   231  	return nil
   232  }
   233  
   234  // Name returns a unique string representation of the sub-server. This can be
   235  // used to identify the sub-server and also de-duplicate them.
   236  //
   237  // NOTE: This is part of the lnrpc.SubServer interface.
   238  func (s *Server) Name() string {
   239  	return subServerName
   240  }
   241  
   242  // RegisterWithRootServer will be called by the root gRPC server to direct a
   243  // sub RPC server to register itself with the main gRPC root server. Until this
   244  // is called, each sub-server won't be able to have requests routed towards it.
   245  //
   246  // NOTE: This is part of the lnrpc.GrpcHandler interface.
   247  func (r *ServerShell) RegisterWithRootServer(grpcServer *grpc.Server) error {
   248  	// We make sure that we register it with the main gRPC server to ensure
   249  	// all our methods are routed properly.
   250  	RegisterRouterServer(grpcServer, r)
   251  
   252  	log.Debugf("Router RPC server successfully register with root gRPC " +
   253  		"server")
   254  
   255  	return nil
   256  }
   257  
   258  // RegisterWithRestServer will be called by the root REST mux to direct a sub
   259  // RPC server to register itself with the main REST mux server. Until this is
   260  // called, each sub-server won't be able to have requests routed towards it.
   261  //
   262  // NOTE: This is part of the lnrpc.GrpcHandler interface.
   263  func (r *ServerShell) RegisterWithRestServer(ctx context.Context,
   264  	mux *runtime.ServeMux, dest string, opts []grpc.DialOption) error {
   265  
   266  	// We make sure that we register it with the main REST server to ensure
   267  	// all our methods are routed properly.
   268  	err := RegisterRouterHandlerFromEndpoint(ctx, mux, dest, opts)
   269  	if err != nil {
   270  		log.Errorf("Could not register Router REST server "+
   271  			"with root REST server: %v", err)
   272  		return err
   273  	}
   274  
   275  	log.Debugf("Router REST server successfully registered with " +
   276  		"root REST server")
   277  	return nil
   278  }
   279  
   280  // CreateSubServer populates the subserver's dependencies using the passed
   281  // SubServerConfigDispatcher. This method should fully initialize the
   282  // sub-server instance, making it ready for action. It returns the macaroon
   283  // permissions that the sub-server wishes to pass on to the root server for all
   284  // methods routed towards it.
   285  //
   286  // NOTE: This is part of the lnrpc.GrpcHandler interface.
   287  func (r *ServerShell) CreateSubServer(configRegistry lnrpc.SubServerConfigDispatcher) (
   288  	lnrpc.SubServer, lnrpc.MacaroonPerms, error) {
   289  
   290  	subServer, macPermissions, err := createNewSubServer(configRegistry)
   291  	if err != nil {
   292  		return nil, nil, err
   293  	}
   294  
   295  	r.RouterServer = subServer
   296  	return subServer, macPermissions, nil
   297  }
   298  
   299  // SendPaymentV2 attempts to route a payment described by the passed
   300  // PaymentRequest to the final destination. If we are unable to route the
   301  // payment, or cannot find a route that satisfies the constraints in the
   302  // PaymentRequest, then an error will be returned. Otherwise, the payment
   303  // pre-image, along with the final route will be returned.
   304  func (s *Server) SendPaymentV2(req *SendPaymentRequest,
   305  	stream Router_SendPaymentV2Server) error {
   306  
   307  	payment, err := s.cfg.RouterBackend.extractIntentFromSendRequest(req)
   308  	if err != nil {
   309  		return err
   310  	}
   311  
   312  	err = s.cfg.Router.SendPaymentAsync(payment)
   313  	if err != nil {
   314  		// Transform user errors to grpc code.
   315  		if err == channeldb.ErrPaymentInFlight ||
   316  			err == channeldb.ErrAlreadyPaid {
   317  
   318  			log.Debugf("SendPayment async result for payment %x: %v",
   319  				payment.Identifier(), err)
   320  
   321  			return status.Error(
   322  				codes.AlreadyExists, err.Error(),
   323  			)
   324  		}
   325  
   326  		log.Errorf("SendPayment async error for payment %x: %v",
   327  			payment.Identifier(), err)
   328  
   329  		return err
   330  	}
   331  
   332  	return s.trackPayment(payment.Identifier(), stream, req.NoInflightUpdates)
   333  }
   334  
   335  // EstimateRouteFee allows callers to obtain a lower bound w.r.t how much it
   336  // may cost to send an HTLC to the target end destination.
   337  func (s *Server) EstimateRouteFee(ctx context.Context,
   338  	req *RouteFeeRequest) (*RouteFeeResponse, error) {
   339  
   340  	if len(req.Dest) != 33 {
   341  		return nil, errors.New("invalid length destination key")
   342  	}
   343  	var destNode route.Vertex
   344  	copy(destNode[:], req.Dest)
   345  
   346  	// Next, we'll convert the amount in satoshis to mSAT, which are the
   347  	// native unit of LN.
   348  	amtMat := lnwire.NewMAtomsFromAtoms(dcrutil.Amount(req.AmtAtoms))
   349  
   350  	// Pick a fee limit
   351  	//
   352  	// TODO: Change this into behaviour that makes more sense.
   353  	feeLimit := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin)
   354  
   355  	// Finally, we'll query for a route to the destination that can carry
   356  	// that target amount, we'll only request a single route. Set a
   357  	// restriction for the default CLTV limit, otherwise we can find a route
   358  	// that exceeds it and is useless to us.
   359  	mc := s.cfg.RouterBackend.MissionControl
   360  	route, err := s.cfg.Router.FindRoute(
   361  		s.cfg.RouterBackend.SelfNode, destNode, amtMat,
   362  		&routing.RestrictParams{
   363  			FeeLimit:          feeLimit,
   364  			CltvLimit:         s.cfg.RouterBackend.MaxTotalTimelock,
   365  			ProbabilitySource: mc.GetProbability,
   366  		}, nil, nil, s.cfg.RouterBackend.DefaultFinalCltvDelta,
   367  	)
   368  	if err != nil {
   369  		return nil, err
   370  	}
   371  
   372  	return &RouteFeeResponse{
   373  		RoutingFeeMatoms: int64(route.TotalFees()),
   374  		TimeLockDelay:    int64(route.TotalTimeLock),
   375  	}, nil
   376  }
   377  
   378  // SendToRouteV2 sends a payment through a predefined route. The response of this
   379  // call contains structured error information.
   380  func (s *Server) SendToRouteV2(ctx context.Context,
   381  	req *SendToRouteRequest) (*lnrpc.HTLCAttempt, error) {
   382  
   383  	if req.Route == nil {
   384  		return nil, fmt.Errorf("unable to send, no routes provided")
   385  	}
   386  
   387  	route, err := s.cfg.RouterBackend.UnmarshallRoute(req.Route)
   388  	if err != nil {
   389  		return nil, err
   390  	}
   391  
   392  	hash, err := lntypes.MakeHash(req.PaymentHash)
   393  	if err != nil {
   394  		return nil, err
   395  	}
   396  
   397  	// Pass route to the router. This call returns the full htlc attempt
   398  	// information as it is stored in the database. It is possible that both
   399  	// the attempt return value and err are non-nil. This can happen when
   400  	// the attempt was already initiated before the error happened. In that
   401  	// case, we give precedence to the attempt information as stored in the
   402  	// db.
   403  	attempt, err := s.cfg.Router.SendToRoute(hash, route)
   404  	if attempt != nil {
   405  		rpcAttempt, err := s.cfg.RouterBackend.MarshalHTLCAttempt(
   406  			*attempt,
   407  		)
   408  		if err != nil {
   409  			return nil, err
   410  		}
   411  		return rpcAttempt, nil
   412  	}
   413  
   414  	// Transform user errors to grpc code.
   415  	if err == channeldb.ErrPaymentInFlight ||
   416  		err == channeldb.ErrAlreadyPaid {
   417  
   418  		return nil, status.Error(codes.AlreadyExists, err.Error())
   419  	}
   420  
   421  	return nil, err
   422  }
   423  
   424  // ResetMissionControl clears all mission control state and starts with a clean
   425  // slate.
   426  func (s *Server) ResetMissionControl(ctx context.Context,
   427  	req *ResetMissionControlRequest) (*ResetMissionControlResponse, error) {
   428  
   429  	err := s.cfg.RouterBackend.MissionControl.ResetHistory()
   430  	if err != nil {
   431  		return nil, err
   432  	}
   433  
   434  	return &ResetMissionControlResponse{}, nil
   435  }
   436  
   437  // GetMissionControlConfig returns our current mission control config.
   438  func (s *Server) GetMissionControlConfig(ctx context.Context,
   439  	req *GetMissionControlConfigRequest) (*GetMissionControlConfigResponse,
   440  	error) {
   441  
   442  	cfg := s.cfg.RouterBackend.MissionControl.GetConfig()
   443  	return &GetMissionControlConfigResponse{
   444  		Config: &MissionControlConfig{
   445  			HalfLifeSeconds:             uint64(cfg.PenaltyHalfLife.Seconds()),
   446  			HopProbability:              float32(cfg.AprioriHopProbability),
   447  			Weight:                      float32(cfg.AprioriWeight),
   448  			MaximumPaymentResults:       uint32(cfg.MaxMcHistory),
   449  			MinimumFailureRelaxInterval: uint64(cfg.MinFailureRelaxInterval.Seconds()),
   450  		},
   451  	}, nil
   452  }
   453  
   454  // SetMissionControlConfig returns our current mission control config.
   455  func (s *Server) SetMissionControlConfig(ctx context.Context,
   456  	req *SetMissionControlConfigRequest) (*SetMissionControlConfigResponse,
   457  	error) {
   458  
   459  	cfg := &routing.MissionControlConfig{
   460  		ProbabilityEstimatorCfg: routing.ProbabilityEstimatorCfg{
   461  			PenaltyHalfLife: time.Duration(
   462  				req.Config.HalfLifeSeconds,
   463  			) * time.Second,
   464  			AprioriHopProbability: float64(req.Config.HopProbability),
   465  			AprioriWeight:         float64(req.Config.Weight),
   466  		},
   467  		MaxMcHistory: int(req.Config.MaximumPaymentResults),
   468  		MinFailureRelaxInterval: time.Duration(
   469  			req.Config.MinimumFailureRelaxInterval,
   470  		) * time.Second,
   471  	}
   472  
   473  	return &SetMissionControlConfigResponse{},
   474  		s.cfg.RouterBackend.MissionControl.SetConfig(cfg)
   475  }
   476  
   477  // QueryMissionControl exposes the internal mission control state to callers. It
   478  // is a development feature.
   479  func (s *Server) QueryMissionControl(ctx context.Context,
   480  	req *QueryMissionControlRequest) (*QueryMissionControlResponse, error) {
   481  
   482  	snapshot := s.cfg.RouterBackend.MissionControl.GetHistorySnapshot()
   483  
   484  	rpcPairs := make([]*PairHistory, 0, len(snapshot.Pairs))
   485  	for _, p := range snapshot.Pairs {
   486  		// Prevent binding to loop variable.
   487  		pair := p
   488  
   489  		rpcPair := PairHistory{
   490  			NodeFrom: pair.Pair.From[:],
   491  			NodeTo:   pair.Pair.To[:],
   492  			History:  toRPCPairData(&pair.TimedPairResult),
   493  		}
   494  
   495  		rpcPairs = append(rpcPairs, &rpcPair)
   496  	}
   497  
   498  	response := QueryMissionControlResponse{
   499  		Pairs: rpcPairs,
   500  	}
   501  
   502  	return &response, nil
   503  }
   504  
   505  // toRPCPairData marshalls mission control pair data to the rpc struct.
   506  func toRPCPairData(data *routing.TimedPairResult) *PairData {
   507  	rpcData := PairData{
   508  		FailAmtAtoms:     int64(data.FailAmt.ToAtoms()),
   509  		FailAmtMAtoms:    int64(data.FailAmt),
   510  		SuccessAmtAtoms:  int64(data.SuccessAmt.ToAtoms()),
   511  		SuccessAmtMAtoms: int64(data.SuccessAmt),
   512  	}
   513  
   514  	if !data.FailTime.IsZero() {
   515  		rpcData.FailTime = data.FailTime.Unix()
   516  	}
   517  
   518  	if !data.SuccessTime.IsZero() {
   519  		rpcData.SuccessTime = data.SuccessTime.Unix()
   520  	}
   521  
   522  	return &rpcData
   523  }
   524  
   525  // XImportMissionControl imports the state provided to our internal mission
   526  // control. Only entries that are fresher than our existing state will be used.
   527  func (s *Server) XImportMissionControl(ctx context.Context,
   528  	req *XImportMissionControlRequest) (*XImportMissionControlResponse,
   529  	error) {
   530  
   531  	if len(req.Pairs) == 0 {
   532  		return nil, errors.New("at least one pair required for import")
   533  	}
   534  
   535  	snapshot := &routing.MissionControlSnapshot{
   536  		Pairs: make(
   537  			[]routing.MissionControlPairSnapshot, len(req.Pairs),
   538  		),
   539  	}
   540  
   541  	for i, pairResult := range req.Pairs {
   542  		pairSnapshot, err := toPairSnapshot(pairResult)
   543  		if err != nil {
   544  			return nil, err
   545  		}
   546  
   547  		snapshot.Pairs[i] = *pairSnapshot
   548  	}
   549  
   550  	err := s.cfg.RouterBackend.MissionControl.ImportHistory(
   551  		snapshot, req.Force,
   552  	)
   553  	if err != nil {
   554  		return nil, err
   555  	}
   556  
   557  	return &XImportMissionControlResponse{}, nil
   558  }
   559  
   560  func toPairSnapshot(pairResult *PairHistory) (*routing.MissionControlPairSnapshot,
   561  	error) {
   562  
   563  	from, err := route.NewVertexFromBytes(pairResult.NodeFrom)
   564  	if err != nil {
   565  		return nil, err
   566  	}
   567  
   568  	to, err := route.NewVertexFromBytes(pairResult.NodeTo)
   569  	if err != nil {
   570  		return nil, err
   571  	}
   572  
   573  	pairPrefix := fmt.Sprintf("pair: %v -> %v:", from, to)
   574  
   575  	if from == to {
   576  		return nil, fmt.Errorf("%v source and destination node must "+
   577  			"differ", pairPrefix)
   578  	}
   579  
   580  	failAmt, failTime, err := getPair(
   581  		lnwire.MilliAtom(pairResult.History.FailAmtMAtoms),
   582  		dcrutil.Amount(pairResult.History.FailAmtAtoms),
   583  		pairResult.History.FailTime,
   584  	)
   585  	if err != nil {
   586  		return nil, fmt.Errorf("%v invalid failure: %v", pairPrefix,
   587  			err)
   588  	}
   589  
   590  	successAmt, successTime, err := getPair(
   591  		lnwire.MilliAtom(pairResult.History.SuccessAmtMAtoms),
   592  		dcrutil.Amount(pairResult.History.SuccessAmtAtoms),
   593  		pairResult.History.SuccessTime,
   594  	)
   595  	if err != nil {
   596  		return nil, fmt.Errorf("%v invalid success: %v", pairPrefix,
   597  			err)
   598  	}
   599  
   600  	if successAmt == 0 && failAmt == 0 {
   601  		return nil, fmt.Errorf("%v: either success or failure result "+
   602  			"required", pairPrefix)
   603  	}
   604  
   605  	pair := routing.NewDirectedNodePair(from, to)
   606  
   607  	result := &routing.TimedPairResult{
   608  		FailAmt:     failAmt,
   609  		FailTime:    failTime,
   610  		SuccessAmt:  successAmt,
   611  		SuccessTime: successTime,
   612  	}
   613  
   614  	return &routing.MissionControlPairSnapshot{
   615  		Pair:            pair,
   616  		TimedPairResult: *result,
   617  	}, nil
   618  }
   619  
   620  // getPair validates the values provided for a mission control result and
   621  // returns the msat amount and timestamp for it.
   622  func getPair(amtMAtoms lnwire.MilliAtom, amtAtoms dcrutil.Amount,
   623  	timestamp int64) (lnwire.MilliAtom, time.Time, error) {
   624  
   625  	amt, err := getMsatPairValue(amtMAtoms, amtAtoms)
   626  	if err != nil {
   627  		return 0, time.Time{}, err
   628  	}
   629  
   630  	var (
   631  		timeSet   = timestamp != 0
   632  		amountSet = amt != 0
   633  	)
   634  
   635  	switch {
   636  	case timeSet && amountSet:
   637  		return amt, time.Unix(timestamp, 0), nil
   638  
   639  	case timeSet && !amountSet:
   640  		return 0, time.Time{}, errors.New("non-zero timestamp " +
   641  			"requires non-zero amount")
   642  
   643  	case !timeSet && amountSet:
   644  		return 0, time.Time{}, errors.New("non-zero amount requires " +
   645  			"non-zero timestamp")
   646  
   647  	default:
   648  		return 0, time.Time{}, nil
   649  	}
   650  }
   651  
   652  // getMsatPairValue checks the msat and sat values set for a pair and ensures
   653  // that the values provided are either the same, or only a single value is set.
   654  func getMsatPairValue(msatValue lnwire.MilliAtom,
   655  	satValue dcrutil.Amount) (lnwire.MilliAtom, error) {
   656  
   657  	// If our msat value converted to sats equals our sat value, we just
   658  	// return the msat value, since the values are the same.
   659  	if msatValue.ToAtoms() == satValue {
   660  		return msatValue, nil
   661  	}
   662  
   663  	// If we have no msatValue, we can just return our sate value even if
   664  	// it is zero, because it's impossible that we have mismatched values.
   665  	if msatValue == 0 {
   666  		return lnwire.MilliAtom(satValue * 1000), nil
   667  	}
   668  
   669  	// Likewise, we can just use msat value if we have no sat value set.
   670  	if satValue == 0 {
   671  		return msatValue, nil
   672  	}
   673  
   674  	// If our values are non-zero but not equal, we have invalid amounts
   675  	// set, so we fail.
   676  	return 0, fmt.Errorf("msat: %v and sat: %v values not equal", msatValue,
   677  		satValue)
   678  }
   679  
   680  // QueryProbability returns the current success probability estimate for a
   681  // given node pair and amount.
   682  func (s *Server) QueryProbability(ctx context.Context,
   683  	req *QueryProbabilityRequest) (*QueryProbabilityResponse, error) {
   684  
   685  	fromNode, err := route.NewVertexFromBytes(req.FromNode)
   686  	if err != nil {
   687  		return nil, err
   688  	}
   689  
   690  	toNode, err := route.NewVertexFromBytes(req.ToNode)
   691  	if err != nil {
   692  		return nil, err
   693  	}
   694  
   695  	amt := lnwire.MilliAtom(req.AmtMAtoms)
   696  
   697  	mc := s.cfg.RouterBackend.MissionControl
   698  	prob := mc.GetProbability(fromNode, toNode, amt)
   699  	history := mc.GetPairHistorySnapshot(fromNode, toNode)
   700  
   701  	return &QueryProbabilityResponse{
   702  		Probability: prob,
   703  		History:     toRPCPairData(&history),
   704  	}, nil
   705  }
   706  
   707  // TrackPaymentV2 returns a stream of payment state updates. The stream is
   708  // closed when the payment completes.
   709  func (s *Server) TrackPaymentV2(request *TrackPaymentRequest,
   710  	stream Router_TrackPaymentV2Server) error {
   711  
   712  	paymentHash, err := lntypes.MakeHash(request.PaymentHash)
   713  	if err != nil {
   714  		return err
   715  	}
   716  
   717  	log.Debugf("TrackPayment called for payment %v", paymentHash)
   718  
   719  	return s.trackPayment(paymentHash, stream, request.NoInflightUpdates)
   720  }
   721  
   722  // trackPayment writes payment status updates to the provided stream.
   723  func (s *Server) trackPayment(identifier lntypes.Hash,
   724  	stream Router_TrackPaymentV2Server, noInflightUpdates bool) error {
   725  
   726  	router := s.cfg.RouterBackend
   727  
   728  	// Subscribe to the outcome of this payment.
   729  	subscription, err := router.Tower.SubscribePayment(
   730  		identifier,
   731  	)
   732  	switch {
   733  	case err == channeldb.ErrPaymentNotInitiated:
   734  		return status.Error(codes.NotFound, err.Error())
   735  	case err != nil:
   736  		return err
   737  	}
   738  	defer subscription.Close()
   739  
   740  	// Stream updates back to the client. The first update is always the
   741  	// current state of the payment.
   742  	for {
   743  		select {
   744  		case item, ok := <-subscription.Updates:
   745  			if !ok {
   746  				// No more payment updates.
   747  				return nil
   748  			}
   749  			result := item.(*channeldb.MPPayment)
   750  
   751  			// Skip in-flight updates unless requested.
   752  			if noInflightUpdates &&
   753  				result.Status == channeldb.StatusInFlight {
   754  
   755  				continue
   756  			}
   757  
   758  			rpcPayment, err := router.MarshallPayment(result)
   759  			if err != nil {
   760  				return err
   761  			}
   762  
   763  			// Send event to the client.
   764  			err = stream.Send(rpcPayment)
   765  			if err != nil {
   766  				return err
   767  			}
   768  
   769  		case <-s.quit:
   770  			return errServerShuttingDown
   771  
   772  		case <-stream.Context().Done():
   773  			log.Debugf("Payment status stream %v canceled", identifier)
   774  			return stream.Context().Err()
   775  		}
   776  	}
   777  }
   778  
   779  // BuildRoute builds a route from a list of hop addresses.
   780  func (s *Server) BuildRoute(ctx context.Context,
   781  	req *BuildRouteRequest) (*BuildRouteResponse, error) {
   782  
   783  	// Unmarshall hop list.
   784  	hops := make([]route.Vertex, len(req.HopPubkeys))
   785  	for i, pubkeyBytes := range req.HopPubkeys {
   786  		pubkey, err := route.NewVertexFromBytes(pubkeyBytes)
   787  		if err != nil {
   788  			return nil, err
   789  		}
   790  		hops[i] = pubkey
   791  	}
   792  
   793  	// Prepare BuildRoute call parameters from rpc request.
   794  	var amt *lnwire.MilliAtom
   795  	if req.AmtMAtoms != 0 {
   796  		rpcAmt := lnwire.MilliAtom(req.AmtMAtoms)
   797  		amt = &rpcAmt
   798  	}
   799  
   800  	var outgoingChan *uint64
   801  	if req.OutgoingChanId != 0 {
   802  		outgoingChan = &req.OutgoingChanId
   803  	}
   804  
   805  	var payAddr *[32]byte
   806  	if len(req.PaymentAddr) != 0 {
   807  		var backingPayAddr [32]byte
   808  		copy(backingPayAddr[:], req.PaymentAddr)
   809  
   810  		payAddr = &backingPayAddr
   811  	}
   812  
   813  	// Build the route and return it to the caller.
   814  	route, err := s.cfg.Router.BuildRoute(
   815  		amt, hops, outgoingChan, req.FinalCltvDelta, payAddr,
   816  	)
   817  	if err != nil {
   818  		return nil, err
   819  	}
   820  
   821  	rpcRoute, err := s.cfg.RouterBackend.MarshallRoute(route)
   822  	if err != nil {
   823  		return nil, err
   824  	}
   825  
   826  	routeResp := &BuildRouteResponse{
   827  		Route: rpcRoute,
   828  	}
   829  
   830  	return routeResp, nil
   831  }
   832  
   833  // SubscribeHtlcEvents creates a uni-directional stream from the server to
   834  // the client which delivers a stream of htlc events.
   835  func (s *Server) SubscribeHtlcEvents(req *SubscribeHtlcEventsRequest,
   836  	stream Router_SubscribeHtlcEventsServer) error {
   837  
   838  	htlcClient, err := s.cfg.RouterBackend.SubscribeHtlcEvents()
   839  	if err != nil {
   840  		return err
   841  	}
   842  	defer htlcClient.Cancel()
   843  
   844  	for {
   845  		select {
   846  		case event := <-htlcClient.Updates():
   847  			rpcEvent, err := rpcHtlcEvent(event)
   848  			if err != nil {
   849  				return err
   850  			}
   851  
   852  			if err := stream.Send(rpcEvent); err != nil {
   853  				return err
   854  			}
   855  
   856  		// If the stream's context is cancelled, return an error.
   857  		case <-stream.Context().Done():
   858  			log.Debugf("htlc event stream cancelled")
   859  			return stream.Context().Err()
   860  
   861  		// If the subscribe client terminates, exit with an error.
   862  		case <-htlcClient.Quit():
   863  			return errors.New("htlc event subscription terminated")
   864  
   865  		// If the server has been signalled to shut down, exit.
   866  		case <-s.quit:
   867  			return errServerShuttingDown
   868  		}
   869  	}
   870  }
   871  
   872  // HtlcInterceptor is a bidirectional stream for streaming interception
   873  // requests to the caller.
   874  // Upon connection it does the following:
   875  // 1. Check if there is already a live stream, if yes it rejects the request.
   876  // 2. Regsitered a ForwardInterceptor
   877  // 3. Delivers to the caller every √√ and detect his answer.
   878  // It uses a local implementation of holdForwardsStore to keep all the hold
   879  // forwards and find them when manual resolution is later needed.
   880  func (s *Server) HtlcInterceptor(stream Router_HtlcInterceptorServer) error {
   881  	// We ensure there is only one interceptor at a time.
   882  	if !atomic.CompareAndSwapInt32(&s.forwardInterceptorActive, 0, 1) {
   883  		return ErrInterceptorAlreadyExists
   884  	}
   885  	defer atomic.CompareAndSwapInt32(&s.forwardInterceptorActive, 1, 0)
   886  
   887  	// run the forward interceptor.
   888  	return newForwardInterceptor(s, stream).run()
   889  }
   890  
   891  func extractOutPoint(req *UpdateChanStatusRequest) (*wire.OutPoint, error) {
   892  	chanPoint := req.GetChanPoint()
   893  	txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
   894  	if err != nil {
   895  		return nil, err
   896  	}
   897  	index := chanPoint.OutputIndex
   898  	return wire.NewOutPoint(txid, index, wire.TxTreeRegular), nil
   899  }
   900  
   901  // UpdateChanStatus allows channel state to be set manually.
   902  func (s *Server) UpdateChanStatus(ctx context.Context,
   903  	req *UpdateChanStatusRequest) (*UpdateChanStatusResponse, error) {
   904  
   905  	outPoint, err := extractOutPoint(req)
   906  	if err != nil {
   907  		return nil, err
   908  	}
   909  
   910  	action := req.GetAction()
   911  
   912  	log.Debugf("UpdateChanStatus called for channel(%v) with "+
   913  		"action %v", outPoint, action)
   914  
   915  	switch action {
   916  	case ChanStatusAction_ENABLE:
   917  		err = s.cfg.RouterBackend.SetChannelEnabled(*outPoint)
   918  	case ChanStatusAction_DISABLE:
   919  		err = s.cfg.RouterBackend.SetChannelDisabled(*outPoint)
   920  	case ChanStatusAction_AUTO:
   921  		err = s.cfg.RouterBackend.SetChannelAuto(*outPoint)
   922  	default:
   923  		err = fmt.Errorf("unrecognized ChannelStatusAction %v", action)
   924  	}
   925  
   926  	if err != nil {
   927  		return nil, err
   928  	}
   929  	return &UpdateChanStatusResponse{}, nil
   930  }