Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions cmd/commands/cmd_payments.go
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,17 @@
"to use as the first hop. This flag can be " +
"specified multiple times in the same command.",
},
cli.StringFlag{
Name: "source",
Usage: "(optional) the 33-byte hex-encoded public key for the " +

Check failure on line 1168 in cmd/commands/cmd_payments.go

View workflow job for this annotation

GitHub Actions / Lint code

the line is 89 characters long, which exceeds the maximum of 80 characters. (ll)
"payment source. If empty, self is assumed",
},
cli.StringFlag{
Name: "last_hop",
Usage: "(optional) the 33-byte hex-encoded public key " +

Check failure on line 1173 in cmd/commands/cmd_payments.go

View workflow job for this annotation

GitHub Actions / Lint code

the line is 81 characters long, which exceeds the maximum of 80 characters. (ll)
"for the last hop (penultimate node in the path) " +

Check failure on line 1174 in cmd/commands/cmd_payments.go

View workflow job for this annotation

GitHub Actions / Lint code

the line is 84 characters long, which exceeds the maximum of 80 characters. (ll)
"to route through for this payment",
},
Comment on lines +1171 to +1176

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This new last_hop flag duplicates the functionality of the existing global lastHopFlag defined on line 46. To improve maintainability and avoid code duplication, consider reusing the existing flag here. The Usage string in this new flag is more descriptive, so it might be a good idea to update the global lastHopFlag with this improved text and use it in both places.

cli.StringSliceFlag{
Name: "ignore_pair",
Usage: "ignore directional node pair " +
Expand Down Expand Up @@ -1270,6 +1281,7 @@

req := &lnrpc.QueryRoutesRequest{
PubKey: dest,
SourcePubKey: ctx.String("source"),
Comment on lines 1282 to +1284
Copy link

Copilot AI Sep 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source parameter should have hex decoding validation similar to last_hop, rather than passing the raw string directly to the request. This ensures consistent input validation for public key parameters.

Suggested change
req := &lnrpc.QueryRoutesRequest{
PubKey: dest,
SourcePubKey: ctx.String("source"),
// Validate the source parameter if provided.
source := ctx.String("source")
if source != "" {
_, err := hex.DecodeString(source)
if err != nil {
return fmt.Errorf("invalid source pubkey: %v", err)
}
}
req := &lnrpc.QueryRoutesRequest{
PubKey: dest,
SourcePubKey: source,

Copilot uses AI. Check for mistakes.
Amt: amt,
FeeLimit: feeLimit,
FinalCltvDelta: int32(ctx.Int("final_cltv_delta")),
Expand All @@ -1286,6 +1298,14 @@
return fmt.Errorf("unable to decode outgoing_chan_id: %w", err)
}

if ctx.IsSet("last_hop") {
lastHop, err := hex.DecodeString(ctx.String("last_hop"))
if err != nil {
return fmt.Errorf("invalid last_hop argument: %w", err)
}
Copy link

Copilot AI Sep 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hex decoding validation for last_hop should include a length check to ensure it's exactly 33 bytes, similar to how other public key validations are typically handled in the codebase.

Suggested change
}
}
if len(lastHop) != 33 {
return fmt.Errorf("last_hop must be 33 bytes (compressed pubkey), got %d bytes", len(lastHop))
}

Copilot uses AI. Check for mistakes.
req.LastHopPubkey = lastHop
Comment on lines +1302 to +1306

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The public key for last_hop is decoded from hex, but its length is not validated. This could lead to malformed data being sent to the backend if a key with an incorrect length is provided. For consistency with how other public keys are handled in this file (e.g., for sendpayment), and to ensure correctness, I suggest using route.NewVertexFromStr. This function handles both hex decoding and length validation.

Suggested change
lastHop, err := hex.DecodeString(ctx.String("last_hop"))
if err != nil {
return fmt.Errorf("invalid last_hop argument: %w", err)
}
req.LastHopPubkey = lastHop
lastHop, err := route.NewVertexFromStr(ctx.String("last_hop"))
if err != nil {
return fmt.Errorf("invalid last_hop argument: %w", err)
}
req.LastHopPubkey = lastHop[:]

}

if ctx.IsSet("route_hints") {
if len(blindedRoutes) > 0 {
return fmt.Errorf("--route_hints should not be used " +
Expand Down
6 changes: 5 additions & 1 deletion docs/release-notes/release-notes-0.20.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,14 @@ circuit. The indices are only available for forwarding events saved after v0.20.
`--route_hints` flag](https://github.com/lightningnetwork/lnd/pull/9721) to
support routing through private channels.


* The `lncli fwdinghistory` command now supports two new flags:
[`--incoming_chan_ids` and `--outgoing_chan_ids`](https://github.com/lightningnetwork/lnd/pull/9356).
These filters allows to query forwarding events for specific channels.

* `lncli queryroutes` now supports two new optional parameters: `--source` to
specify the source node for the route and `--last_hop` to specify the
penultimate node in the payment path.

# Improvements
## Functional Updates

Expand Down Expand Up @@ -304,6 +307,7 @@ reader of a payment request.
* Boris Nagaev
* Elle Mouton
* Erick Cestari
* Feelancer21
* Funyug
* Mohamed Awnallah
* Olaoluwa Osuntokun
Expand Down
Loading