Skip to content

Commit 48a02e5

Browse files
authored
Merge pull request #79 from Anyitechs/introduce-SendingParameters
2 parents 0d02e50 + ebb776d commit 48a02e5

File tree

7 files changed

+198
-10
lines changed

7 files changed

+198
-10
lines changed

ldk-server-cli/src/main.rs

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,20 @@ use ldk_server_client::ldk_server_protos::api::{
1010
ListChannelsRequest, ListPaymentsRequest, OnchainReceiveRequest, OnchainSendRequest,
1111
OpenChannelRequest, SpliceInRequest, SpliceOutRequest,
1212
};
13+
use ldk_server_client::ldk_server_protos::types::RouteParametersConfig;
1314
use ldk_server_client::ldk_server_protos::types::{
1415
bolt11_invoice_description, channel_config, Bolt11InvoiceDescription, ChannelConfig, PageToken,
1516
Payment,
1617
};
1718
use std::fmt::Debug;
1819

20+
// Having these default values as constants in the Proto file and
21+
// importing/reusing them here might be better, but Proto3 removed
22+
// the ability to set default values.
23+
const DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA: u32 = 1008;
24+
const DEFAULT_MAX_PATH_COUNT: u32 = 10;
25+
const DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF: u32 = 2;
26+
1927
#[derive(Parser, Debug)]
2028
#[command(version, about, long_about = None)]
2129
struct Cli {
@@ -56,6 +64,14 @@ enum Commands {
5664
invoice: String,
5765
#[arg(long)]
5866
amount_msat: Option<u64>,
67+
#[arg(long)]
68+
max_total_routing_fee_msat: Option<u64>,
69+
#[arg(long)]
70+
max_total_cltv_expiry_delta: Option<u32>,
71+
#[arg(long)]
72+
max_path_count: Option<u32>,
73+
#[arg(long)]
74+
max_channel_saturation_power_of_half: Option<u32>,
5975
},
6076
Bolt12Receive {
6177
#[arg(short, long)]
@@ -76,6 +92,14 @@ enum Commands {
7692
quantity: Option<u64>,
7793
#[arg(short, long)]
7894
payer_note: Option<String>,
95+
#[arg(long)]
96+
max_total_routing_fee_msat: Option<u64>,
97+
#[arg(long)]
98+
max_total_cltv_expiry_delta: Option<u32>,
99+
#[arg(long)]
100+
max_path_count: Option<u32>,
101+
#[arg(long)]
102+
max_channel_saturation_power_of_half: Option<u32>,
79103
},
80104
CloseChannel {
81105
#[arg(short, long)]
@@ -196,9 +220,30 @@ async fn main() {
196220

197221
handle_response_result(client.bolt11_receive(request).await);
198222
},
199-
Commands::Bolt11Send { invoice, amount_msat } => {
223+
Commands::Bolt11Send {
224+
invoice,
225+
amount_msat,
226+
max_total_routing_fee_msat,
227+
max_total_cltv_expiry_delta,
228+
max_path_count,
229+
max_channel_saturation_power_of_half,
230+
} => {
231+
let route_parameters = RouteParametersConfig {
232+
max_total_routing_fee_msat,
233+
max_total_cltv_expiry_delta: max_total_cltv_expiry_delta
234+
.unwrap_or(DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA),
235+
max_path_count: max_path_count.unwrap_or(DEFAULT_MAX_PATH_COUNT),
236+
max_channel_saturation_power_of_half: max_channel_saturation_power_of_half
237+
.unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF),
238+
};
200239
handle_response_result(
201-
client.bolt11_send(Bolt11SendRequest { invoice, amount_msat }).await,
240+
client
241+
.bolt11_send(Bolt11SendRequest {
242+
invoice,
243+
amount_msat,
244+
route_parameters: Some(route_parameters),
245+
})
246+
.await,
202247
);
203248
},
204249
Commands::Bolt12Receive { description, amount_msat, expiry_secs, quantity } => {
@@ -213,10 +258,34 @@ async fn main() {
213258
.await,
214259
);
215260
},
216-
Commands::Bolt12Send { offer, amount_msat, quantity, payer_note } => {
261+
Commands::Bolt12Send {
262+
offer,
263+
amount_msat,
264+
quantity,
265+
payer_note,
266+
max_total_routing_fee_msat,
267+
max_total_cltv_expiry_delta,
268+
max_path_count,
269+
max_channel_saturation_power_of_half,
270+
} => {
271+
let route_parameters = RouteParametersConfig {
272+
max_total_routing_fee_msat,
273+
max_total_cltv_expiry_delta: max_total_cltv_expiry_delta
274+
.unwrap_or(DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA),
275+
max_path_count: max_path_count.unwrap_or(DEFAULT_MAX_PATH_COUNT),
276+
max_channel_saturation_power_of_half: max_channel_saturation_power_of_half
277+
.unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF),
278+
};
279+
217280
handle_response_result(
218281
client
219-
.bolt12_send(Bolt12SendRequest { offer, amount_msat, quantity, payer_note })
282+
.bolt12_send(Bolt12SendRequest {
283+
offer,
284+
amount_msat,
285+
quantity,
286+
payer_note,
287+
route_parameters: Some(route_parameters),
288+
})
220289
.await,
221290
);
222291
},

ldk-server-protos/src/api.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ pub struct Bolt11SendRequest {
141141
/// This operation will fail if the amount specified is less than the value required by the given invoice.
142142
#[prost(uint64, optional, tag = "2")]
143143
pub amount_msat: ::core::option::Option<u64>,
144+
/// Configuration options for payment routing and pathfinding.
145+
#[prost(message, optional, tag = "3")]
146+
pub route_parameters: ::core::option::Option<super::types::RouteParametersConfig>,
144147
}
145148
/// The response `content` for the `Bolt11Send` API, when HttpStatusCode is OK (200).
146149
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
@@ -205,6 +208,9 @@ pub struct Bolt12SendRequest {
205208
/// If set, it will be seen by the recipient and reflected back in the invoice.
206209
#[prost(string, optional, tag = "4")]
207210
pub payer_note: ::core::option::Option<::prost::alloc::string::String>,
211+
/// Configuration options for payment routing and pathfinding.
212+
#[prost(message, optional, tag = "5")]
213+
pub route_parameters: ::core::option::Option<super::types::RouteParametersConfig>,
208214
}
209215
/// The response `content` for the `Bolt12Send` API, when HttpStatusCode is OK (200).
210216
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.

ldk-server-protos/src/proto/api.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ message Bolt11SendRequest {
138138
// amount paid to be determined by the user.
139139
// This operation will fail if the amount specified is less than the value required by the given invoice.
140140
optional uint64 amount_msat = 2;
141+
142+
// Configuration options for payment routing and pathfinding.
143+
optional types.RouteParametersConfig route_parameters = 3;
141144

142145
}
143146

@@ -199,6 +202,9 @@ message Bolt12SendRequest {
199202

200203
// If set, it will be seen by the recipient and reflected back in the invoice.
201204
optional string payer_note = 4;
205+
206+
// Configuration options for payment routing and pathfinding.
207+
optional types.RouteParametersConfig route_parameters = 5;
202208
}
203209

204210
// The response `content` for the `Bolt12Send` API, when HttpStatusCode is OK (200).

ldk-server-protos/src/proto/types.proto

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,3 +683,24 @@ message Bolt11InvoiceDescription {
683683
string hash = 2;
684684
}
685685
}
686+
687+
// Configuration options for payment routing and pathfinding.
688+
// See https://docs.rs/lightning/0.2.0/lightning/routing/router/struct.RouteParametersConfig.html for more details on each field.
689+
message RouteParametersConfig {
690+
// The maximum total fees, in millisatoshi, that may accrue during route finding.
691+
// Defaults to 1% of the payment amount + 50 sats
692+
optional uint64 max_total_routing_fee_msat = 1;
693+
694+
// The maximum total CLTV delta we accept for the route.
695+
// Defaults to 1008.
696+
uint32 max_total_cltv_expiry_delta = 2;
697+
698+
// The maximum number of paths that may be used by (MPP) payments.
699+
// Defaults to 10.
700+
uint32 max_path_count = 3;
701+
702+
// Selects the maximum share of a channel's total capacity which will be
703+
// sent over a channel, as a power of 1/2.
704+
// Default value: 2
705+
uint32 max_channel_saturation_power_of_half = 4;
706+
}

ldk-server-protos/src/types.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,29 @@ pub mod bolt11_invoice_description {
779779
Hash(::prost::alloc::string::String),
780780
}
781781
}
782+
/// Configuration options for payment routing and pathfinding.
783+
/// See <https://docs.rs/lightning/0.2.0/lightning/routing/router/struct.RouteParametersConfig.html> for more details on each field.
784+
#[allow(clippy::derive_partial_eq_without_eq)]
785+
#[derive(Clone, PartialEq, ::prost::Message)]
786+
pub struct RouteParametersConfig {
787+
/// The maximum total fees, in millisatoshi, that may accrue during route finding.
788+
/// Defaults to 1% of the payment amount + 50 sats
789+
#[prost(uint64, optional, tag = "1")]
790+
pub max_total_routing_fee_msat: ::core::option::Option<u64>,
791+
/// The maximum total CLTV delta we accept for the route.
792+
/// Defaults to 1008.
793+
#[prost(uint32, tag = "2")]
794+
pub max_total_cltv_expiry_delta: u32,
795+
/// The maximum number of paths that may be used by (MPP) payments.
796+
/// Defaults to 10.
797+
#[prost(uint32, tag = "3")]
798+
pub max_path_count: u32,
799+
/// Selects the maximum share of a channel's total capacity which will be
800+
/// sent over a channel, as a power of 1/2.
801+
/// Default value: 2
802+
#[prost(uint32, tag = "4")]
803+
pub max_channel_saturation_power_of_half: u32,
804+
}
782805
/// Represents the direction of a payment.
783806
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
784807
#[repr(i32)]

ldk-server/src/api/bolt11_send.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::api::error::LdkServerError;
2+
use crate::api::error::LdkServerErrorCode::InvalidRequestError;
23
use crate::service::Context;
4+
use ldk_node::lightning::routing::router::RouteParametersConfig;
35
use ldk_node::lightning_invoice::Bolt11Invoice;
46
use ldk_server_protos::api::{Bolt11SendRequest, Bolt11SendResponse};
57
use std::str::FromStr;
@@ -10,10 +12,38 @@ pub(crate) fn handle_bolt11_send_request(
1012
let invoice = Bolt11Invoice::from_str(&request.invoice.as_str())
1113
.map_err(|_| ldk_node::NodeError::InvalidInvoice)?;
1214

15+
let route_parameters = match request.route_parameters {
16+
Some(params) => {
17+
let max_path_count: u8 = params.max_path_count.try_into().map_err(|_| {
18+
LdkServerError::new(
19+
InvalidRequestError,
20+
format!("Invalid max_path_count, must be between 0 and {}", u8::MAX),
21+
)
22+
})?;
23+
let max_channel_saturation_power_of_half: u8 =
24+
params.max_channel_saturation_power_of_half.try_into().map_err(|_| {
25+
LdkServerError::new(
26+
InvalidRequestError,
27+
format!(
28+
"Invalid max_channel_saturation_power_of_half, must be between 0 and {}",
29+
u8::MAX
30+
),
31+
)
32+
})?;
33+
Some(RouteParametersConfig {
34+
max_total_routing_fee_msat: params.max_total_routing_fee_msat,
35+
max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta,
36+
max_path_count,
37+
max_channel_saturation_power_of_half,
38+
})
39+
},
40+
None => None,
41+
};
42+
1343
let payment_id = match request.amount_msat {
14-
None => context.node.bolt11_payment().send(&invoice, None),
44+
None => context.node.bolt11_payment().send(&invoice, route_parameters),
1545
Some(amount_msat) => {
16-
context.node.bolt11_payment().send_using_amount(&invoice, amount_msat, None)
46+
context.node.bolt11_payment().send_using_amount(&invoice, amount_msat, route_parameters)
1747
},
1848
}?;
1949

ldk-server/src/api/bolt12_send.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::api::error::LdkServerError;
2+
use crate::api::error::LdkServerErrorCode::InvalidRequestError;
23
use crate::service::Context;
34
use ldk_node::lightning::offers::offer::Offer;
5+
use ldk_node::lightning::routing::router::RouteParametersConfig;
46
use ldk_server_protos::api::{Bolt12SendRequest, Bolt12SendResponse};
57
use std::str::FromStr;
68

@@ -10,16 +12,47 @@ pub(crate) fn handle_bolt12_send_request(
1012
let offer =
1113
Offer::from_str(&request.offer.as_str()).map_err(|_| ldk_node::NodeError::InvalidOffer)?;
1214

13-
let payment_id = match request.amount_msat {
14-
None => {
15-
context.node.bolt12_payment().send(&offer, request.quantity, request.payer_note, None)
15+
let route_parameters = match request.route_parameters {
16+
Some(params) => {
17+
let max_path_count = params.max_path_count.try_into().map_err(|_| {
18+
LdkServerError::new(
19+
InvalidRequestError,
20+
format!("Invalid max_path_count, must be between 0 and {}", u8::MAX),
21+
)
22+
})?;
23+
let max_channel_saturation_power_of_half =
24+
params.max_channel_saturation_power_of_half.try_into().map_err(|_| {
25+
LdkServerError::new(
26+
InvalidRequestError,
27+
format!(
28+
"Invalid max_channel_saturation_power_of_half, must be between 0 and {}",
29+
u8::MAX
30+
),
31+
)
32+
})?;
33+
Some(RouteParametersConfig {
34+
max_total_routing_fee_msat: params.max_total_routing_fee_msat,
35+
max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta,
36+
max_path_count,
37+
max_channel_saturation_power_of_half,
38+
})
1639
},
40+
None => None,
41+
};
42+
43+
let payment_id = match request.amount_msat {
44+
None => context.node.bolt12_payment().send(
45+
&offer,
46+
request.quantity,
47+
request.payer_note,
48+
route_parameters,
49+
),
1750
Some(amount_msat) => context.node.bolt12_payment().send_using_amount(
1851
&offer,
1952
amount_msat,
2053
request.quantity,
2154
request.payer_note,
22-
None,
55+
route_parameters,
2356
),
2457
}?;
2558

0 commit comments

Comments
 (0)