mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-23 14:40:30 +01:00
lncli: add blinded route cli flags to query routes
Note: This commit can be dropped before merge, it's mostly added to make the PR easier to manually test against other implementations that have bolt 12 invoices implemented already!
This commit is contained in:
parent
b42a621438
commit
32ea77b96b
1 changed files with 144 additions and 9 deletions
|
@ -99,6 +99,47 @@ var (
|
||||||
Name: "time_pref",
|
Name: "time_pref",
|
||||||
Usage: "(optional) expresses time preference (range -1 to 1)",
|
Usage: "(optional) expresses time preference (range -1 to 1)",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
introductionNodeFlag = cli.StringFlag{
|
||||||
|
Name: "introduction_node",
|
||||||
|
Usage: "(blinded paths) the hex encoded, cleartext node ID " +
|
||||||
|
"of the node to use for queries to a blinded route",
|
||||||
|
}
|
||||||
|
|
||||||
|
blindingPointFlag = cli.StringFlag{
|
||||||
|
Name: "blinding_point",
|
||||||
|
Usage: "(blinded paths) the hex encoded blinding point to " +
|
||||||
|
"use if querying a route to a blinded path, this " +
|
||||||
|
"value *must* be set for queries to a blinded path",
|
||||||
|
}
|
||||||
|
|
||||||
|
blindedHopsFlag = cli.StringSliceFlag{
|
||||||
|
Name: "blinded_hops",
|
||||||
|
Usage: "(blinded paths) the blinded hops to include in the " +
|
||||||
|
"query, formatted as <blinded_node_id>:" +
|
||||||
|
"<hex_encrypted_data>. These hops must be provided " +
|
||||||
|
"*in order* starting with the introduction point and " +
|
||||||
|
"ending with the receiving node",
|
||||||
|
}
|
||||||
|
|
||||||
|
blindedBaseFlag = cli.Uint64Flag{
|
||||||
|
Name: "blinded_base_fee",
|
||||||
|
Usage: "(blinded paths) the aggregate base fee for the " +
|
||||||
|
"blinded portion of the route, expressed in msat",
|
||||||
|
}
|
||||||
|
|
||||||
|
blindedPPMFlag = cli.Uint64Flag{
|
||||||
|
Name: "blinded_ppm_fee",
|
||||||
|
Usage: "(blinded paths) the aggregate proportional fee for " +
|
||||||
|
"the blinded portion of the route, expressed in " +
|
||||||
|
"parts per million",
|
||||||
|
}
|
||||||
|
|
||||||
|
blindedCLTVFlag = cli.Uint64Flag{
|
||||||
|
Name: "blinded_cltv",
|
||||||
|
Usage: "(blinded paths) the total cltv delay for the " +
|
||||||
|
"blinded portion of the route",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// paymentFlags returns common flags for sendpayment and payinvoice.
|
// paymentFlags returns common flags for sendpayment and payinvoice.
|
||||||
|
@ -1056,6 +1097,12 @@ var queryRoutesCommand = cli.Command{
|
||||||
},
|
},
|
||||||
timePrefFlag,
|
timePrefFlag,
|
||||||
cltvLimitFlag,
|
cltvLimitFlag,
|
||||||
|
introductionNodeFlag,
|
||||||
|
blindingPointFlag,
|
||||||
|
blindedHopsFlag,
|
||||||
|
blindedBaseFlag,
|
||||||
|
blindedPPMFlag,
|
||||||
|
blindedCLTVFlag,
|
||||||
},
|
},
|
||||||
Action: actionDecorator(queryRoutes),
|
Action: actionDecorator(queryRoutes),
|
||||||
}
|
}
|
||||||
|
@ -1076,9 +1123,15 @@ func queryRoutes(ctx *cli.Context) error {
|
||||||
switch {
|
switch {
|
||||||
case ctx.IsSet("dest"):
|
case ctx.IsSet("dest"):
|
||||||
dest = ctx.String("dest")
|
dest = ctx.String("dest")
|
||||||
|
|
||||||
case args.Present():
|
case args.Present():
|
||||||
dest = args.First()
|
dest = args.First()
|
||||||
args = args.Tail()
|
args = args.Tail()
|
||||||
|
|
||||||
|
// If we have a blinded path set, we don't have to specify a
|
||||||
|
// destination.
|
||||||
|
case ctx.IsSet(introductionNodeFlag.Name):
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("dest argument missing")
|
return fmt.Errorf("dest argument missing")
|
||||||
}
|
}
|
||||||
|
@ -1125,16 +1178,22 @@ func queryRoutes(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blindedRoutes, err := parseBlindedPaymentParameters(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
req := &lnrpc.QueryRoutesRequest{
|
req := &lnrpc.QueryRoutesRequest{
|
||||||
PubKey: dest,
|
PubKey: dest,
|
||||||
Amt: amt,
|
Amt: amt,
|
||||||
FeeLimit: feeLimit,
|
FeeLimit: feeLimit,
|
||||||
FinalCltvDelta: int32(ctx.Int("final_cltv_delta")),
|
FinalCltvDelta: int32(ctx.Int("final_cltv_delta")),
|
||||||
UseMissionControl: ctx.Bool("use_mc"),
|
UseMissionControl: ctx.Bool("use_mc"),
|
||||||
CltvLimit: uint32(ctx.Uint64(cltvLimitFlag.Name)),
|
CltvLimit: uint32(ctx.Uint64(cltvLimitFlag.Name)),
|
||||||
OutgoingChanId: ctx.Uint64("outgoing_chan_id"),
|
OutgoingChanId: ctx.Uint64("outgoing_chan_id"),
|
||||||
TimePref: ctx.Float64(timePrefFlag.Name),
|
TimePref: ctx.Float64(timePrefFlag.Name),
|
||||||
IgnoredPairs: ignoredPairs,
|
IgnoredPairs: ignoredPairs,
|
||||||
|
BlindedPaymentPaths: blindedRoutes,
|
||||||
}
|
}
|
||||||
|
|
||||||
route, err := client.QueryRoutes(ctxc, req)
|
route, err := client.QueryRoutes(ctxc, req)
|
||||||
|
@ -1146,6 +1205,82 @@ func queryRoutes(ctx *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseBlindedPaymentParameters(ctx *cli.Context) (
|
||||||
|
[]*lnrpc.BlindedPaymentPath, error) {
|
||||||
|
|
||||||
|
// Return nil if we don't have a blinding set, as we don't have a
|
||||||
|
// blinded path.
|
||||||
|
if !ctx.IsSet(blindingPointFlag.Name) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If any one of our blinding related flags is set, we expect the
|
||||||
|
// full set to be set and we'll error out accordingly.
|
||||||
|
introNode, err := route.NewVertexFromStr(
|
||||||
|
ctx.String(introductionNodeFlag.Name),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("decode introduction node: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blindingPoint, err := route.NewVertexFromStr(ctx.String(
|
||||||
|
blindingPointFlag.Name,
|
||||||
|
))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("decode blinding point: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blindedHops := ctx.StringSlice(blindedHopsFlag.Name)
|
||||||
|
|
||||||
|
pmt := &lnrpc.BlindedPaymentPath{
|
||||||
|
BlindedPath: &lnrpc.BlindedPath{
|
||||||
|
IntroductionNode: introNode[:],
|
||||||
|
BlindingPoint: blindingPoint[:],
|
||||||
|
BlindedHops: make(
|
||||||
|
[]*lnrpc.BlindedHop, len(blindedHops),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
BaseFeeMsat: ctx.Uint64(
|
||||||
|
blindedBaseFlag.Name,
|
||||||
|
),
|
||||||
|
ProportionalFeeMsat: ctx.Uint64(
|
||||||
|
blindedPPMFlag.Name,
|
||||||
|
),
|
||||||
|
TotalCltvDelta: uint32(ctx.Uint64(
|
||||||
|
blindedCLTVFlag.Name,
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, hop := range blindedHops {
|
||||||
|
parts := strings.Split(hop, ":")
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return nil, fmt.Errorf("blinded hops should be "+
|
||||||
|
"expressed as "+
|
||||||
|
"blinded_node_id:hex_encrypted_data, got: %v",
|
||||||
|
hop)
|
||||||
|
}
|
||||||
|
|
||||||
|
hop, err := route.NewVertexFromStr(parts[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("hop: %v node: %w", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := hex.DecodeString(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("hop: %v data: %w", i, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pmt.BlindedPath.BlindedHops[i] = &lnrpc.BlindedHop{
|
||||||
|
BlindedNode: hop[:],
|
||||||
|
EncryptedData: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return []*lnrpc.BlindedPaymentPath{
|
||||||
|
pmt,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// retrieveFeeLimitLegacy retrieves the fee limit based on the different fee
|
// retrieveFeeLimitLegacy retrieves the fee limit based on the different fee
|
||||||
// limit flags passed. This function will eventually disappear in favor of
|
// limit flags passed. This function will eventually disappear in favor of
|
||||||
// retrieveFeeLimit and the new payment rpc.
|
// retrieveFeeLimit and the new payment rpc.
|
||||||
|
|
Loading…
Add table
Reference in a new issue