github.com/decred/dcrlnd@v0.7.6/cmd/dcrlncli/cmd_mission_control.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  
     7  	"github.com/decred/dcrd/dcrutil/v4"
     8  	"github.com/decred/dcrlnd/lnrpc/routerrpc"
     9  	"github.com/decred/dcrlnd/lnwire"
    10  	"github.com/decred/dcrlnd/routing/route"
    11  	"github.com/urfave/cli"
    12  )
    13  
    14  var getCfgCommand = cli.Command{
    15  	Name:     "getmccfg",
    16  	Category: "Mission Control",
    17  	Usage:    "Display mission control's config.",
    18  	Description: `
    19  	Returns the config currently being used by mission control.
    20  	`,
    21  	Action: actionDecorator(getCfg),
    22  }
    23  
    24  func getCfg(ctx *cli.Context) error {
    25  	ctxc := getContext()
    26  	conn := getClientConn(ctx, false)
    27  	defer conn.Close()
    28  
    29  	client := routerrpc.NewRouterClient(conn)
    30  
    31  	resp, err := client.GetMissionControlConfig(
    32  		ctxc, &routerrpc.GetMissionControlConfigRequest{},
    33  	)
    34  	if err != nil {
    35  		return err
    36  	}
    37  
    38  	printRespJSON(resp)
    39  
    40  	return nil
    41  }
    42  
    43  var setCfgCommand = cli.Command{
    44  	Name:     "setmccfg",
    45  	Category: "Mission Control",
    46  	Usage:    "Set mission control's config.",
    47  	Description: `
    48  	Update the config values being used by mission control to calculate
    49  	the probability that payment routes will succeed.
    50  	`,
    51  	Flags: []cli.Flag{
    52  		cli.DurationFlag{
    53  			Name: "halflife",
    54  			Usage: "the amount of time taken to restore a node " +
    55  				"or channel to 50% probability of success.",
    56  		},
    57  		cli.Float64Flag{
    58  			Name: "hopprob",
    59  			Usage: "the probability of success assigned " +
    60  				"to hops that we have no information about",
    61  		},
    62  		cli.Float64Flag{
    63  			Name: "weight",
    64  			Usage: "the degree to which mission control should " +
    65  				"rely on historical results, expressed as " +
    66  				"value in [0;1]",
    67  		}, cli.UintFlag{
    68  			Name: "pmtnr",
    69  			Usage: "the number of payments mission control " +
    70  				"should store",
    71  		},
    72  		cli.DurationFlag{
    73  			Name: "failrelax",
    74  			Usage: "the amount of time to wait after a failure " +
    75  				"before raising failure amount",
    76  		},
    77  	},
    78  	Action: actionDecorator(setCfg),
    79  }
    80  
    81  func setCfg(ctx *cli.Context) error {
    82  	ctxc := getContext()
    83  	conn := getClientConn(ctx, false)
    84  	defer conn.Close()
    85  
    86  	client := routerrpc.NewRouterClient(conn)
    87  
    88  	resp, err := client.GetMissionControlConfig(
    89  		ctxc, &routerrpc.GetMissionControlConfigRequest{},
    90  	)
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	var haveValue bool
    96  
    97  	if ctx.IsSet("halflife") {
    98  		haveValue = true
    99  		resp.Config.HalfLifeSeconds = uint64(ctx.Duration(
   100  			"halflife",
   101  		).Seconds())
   102  	}
   103  
   104  	if ctx.IsSet("hopprob") {
   105  		haveValue = true
   106  		resp.Config.HopProbability = float32(ctx.Float64("hopprob"))
   107  	}
   108  
   109  	if ctx.IsSet("weight") {
   110  		haveValue = true
   111  		resp.Config.Weight = float32(ctx.Float64("weight"))
   112  	}
   113  
   114  	if ctx.IsSet("pmtnr") {
   115  		haveValue = true
   116  		resp.Config.MaximumPaymentResults = uint32(ctx.Int("pmtnr"))
   117  	}
   118  
   119  	if ctx.IsSet("failrelax") {
   120  		haveValue = true
   121  		resp.Config.MinimumFailureRelaxInterval = uint64(ctx.Duration(
   122  			"failrelax",
   123  		).Seconds())
   124  	}
   125  
   126  	if !haveValue {
   127  		return cli.ShowCommandHelp(ctx, "setmccfg")
   128  	}
   129  
   130  	_, err = client.SetMissionControlConfig(
   131  		ctxc, &routerrpc.SetMissionControlConfigRequest{
   132  			Config: resp.Config,
   133  		},
   134  	)
   135  	return err
   136  }
   137  
   138  var queryMissionControlCommand = cli.Command{
   139  	Name:     "querymc",
   140  	Category: "Mission Control",
   141  	Usage:    "Query the internal mission control state.",
   142  	Action:   actionDecorator(queryMissionControl),
   143  }
   144  
   145  func queryMissionControl(ctx *cli.Context) error {
   146  	ctxc := getContext()
   147  	conn := getClientConn(ctx, false)
   148  	defer conn.Close()
   149  
   150  	client := routerrpc.NewRouterClient(conn)
   151  
   152  	req := &routerrpc.QueryMissionControlRequest{}
   153  	snapshot, err := client.QueryMissionControl(ctxc, req)
   154  	if err != nil {
   155  		return err
   156  	}
   157  
   158  	printRespJSON(snapshot)
   159  
   160  	return nil
   161  }
   162  
   163  var queryProbCommand = cli.Command{
   164  	Name:      "queryprob",
   165  	Category:  "Mission Control",
   166  	Usage:     "Estimate a success probability.",
   167  	ArgsUsage: "from-node to-node amt",
   168  	Action:    actionDecorator(queryProb),
   169  }
   170  
   171  func queryProb(ctx *cli.Context) error {
   172  	ctxc := getContext()
   173  	args := ctx.Args()
   174  
   175  	if len(args) != 3 {
   176  		return cli.ShowCommandHelp(ctx, "queryprob")
   177  	}
   178  
   179  	fromNode, err := route.NewVertexFromStr(args.Get(0))
   180  	if err != nil {
   181  		return fmt.Errorf("invalid from node key: %v", err)
   182  	}
   183  
   184  	toNode, err := route.NewVertexFromStr(args.Get(1))
   185  	if err != nil {
   186  		return fmt.Errorf("invalid to node key: %v", err)
   187  	}
   188  
   189  	amtAtoms, err := strconv.ParseUint(args.Get(2), 10, 64)
   190  	if err != nil {
   191  		return fmt.Errorf("invalid amt: %v", err)
   192  	}
   193  
   194  	amtMAtoms := lnwire.NewMAtomsFromAtoms(
   195  		dcrutil.Amount(amtAtoms),
   196  	)
   197  
   198  	conn := getClientConn(ctx, false)
   199  	defer conn.Close()
   200  
   201  	client := routerrpc.NewRouterClient(conn)
   202  
   203  	req := &routerrpc.QueryProbabilityRequest{
   204  		FromNode:  fromNode[:],
   205  		ToNode:    toNode[:],
   206  		AmtMAtoms: int64(amtMAtoms),
   207  	}
   208  
   209  	response, err := client.QueryProbability(ctxc, req)
   210  	if err != nil {
   211  		return err
   212  	}
   213  
   214  	printRespJSON(response)
   215  
   216  	return nil
   217  }
   218  
   219  var resetMissionControlCommand = cli.Command{
   220  	Name:     "resetmc",
   221  	Category: "Mission Control",
   222  	Usage:    "Reset internal mission control state.",
   223  	Action:   actionDecorator(resetMissionControl),
   224  }
   225  
   226  func resetMissionControl(ctx *cli.Context) error {
   227  	ctxc := getContext()
   228  	conn := getClientConn(ctx, false)
   229  	defer conn.Close()
   230  
   231  	client := routerrpc.NewRouterClient(conn)
   232  
   233  	req := &routerrpc.ResetMissionControlRequest{}
   234  	_, err := client.ResetMissionControl(ctxc, req)
   235  	return err
   236  }