Skip to content

Commit 8a432b1

Browse files
committed
Refactor max_total_routing_fee_msat to allow setting None
Previously, the `SendingParamters` field was simply an `Option<u64>`, which however means we could just override it to be `Some`. Here, we have it be `Option<Option<u64>>` which allows the `None` override. As UniFFI doesn't support `Option<Option<..>>`, we work around this via a dedicated `enum` that is only exposed under the `uniffi` feature.
1 parent 3ca42ff commit 8a432b1

File tree

6 files changed

+100
-107
lines changed

6 files changed

+100
-107
lines changed

bindings/ldk_node.udl

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,10 @@ interface OnchainPayment {
151151
};
152152

153153
interface UnifiedQrPayment {
154-
[Throws=NodeError]
155-
string receive(u64 amount_sats, [ByRef]string message, u32 expiry_sec);
156-
[Throws=NodeError]
157-
QrPaymentResult send([ByRef]string uri_str);
154+
[Throws=NodeError]
155+
string receive(u64 amount_sats, [ByRef]string message, u32 expiry_sec);
156+
[Throws=NodeError]
157+
QrPaymentResult send([ByRef]string uri_str);
158158
};
159159

160160
[Error]
@@ -290,9 +290,9 @@ interface PaymentKind {
290290

291291
[Enum]
292292
interface QrPaymentResult {
293-
Onchain(Txid txid);
294-
Bolt11(PaymentId payment_id);
295-
Bolt12(PaymentId payment_id);
293+
Onchain(Txid txid);
294+
Bolt11(PaymentId payment_id);
295+
Bolt12(PaymentId payment_id);
296296
};
297297

298298
enum PaymentDirection {
@@ -321,10 +321,16 @@ dictionary PaymentDetails {
321321
};
322322

323323
dictionary SendingParameters {
324-
u64? max_total_routing_fee_msat;
325-
u32? max_total_cltv_expiry_delta;
326-
u8? max_path_count;
327-
u8? max_channel_saturation_power_of_half;
324+
MaxTotalRoutingFeeLimit? max_total_routing_fee_msat;
325+
u32? max_total_cltv_expiry_delta;
326+
u8? max_path_count;
327+
u8? max_channel_saturation_power_of_half;
328+
};
329+
330+
[Enum]
331+
interface MaxTotalRoutingFeeLimit {
332+
None ();
333+
Some ( u64 amount_msat );
328334
};
329335

330336
[NonExhaustive]

src/payment/bolt11.rs

Lines changed: 28 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -96,37 +96,20 @@ impl Bolt11Payment {
9696
}
9797
}
9898

99-
if let Some(user_set_params) = sending_parameters {
100-
if let Some(mut default_params) = self.config.sending_parameters.as_ref().cloned() {
101-
default_params.max_total_routing_fee_msat = user_set_params
102-
.max_total_routing_fee_msat
103-
.or(default_params.max_total_routing_fee_msat);
104-
default_params.max_total_cltv_expiry_delta = user_set_params
105-
.max_total_cltv_expiry_delta
106-
.or(default_params.max_total_cltv_expiry_delta);
107-
default_params.max_path_count =
108-
user_set_params.max_path_count.or(default_params.max_path_count);
109-
default_params.max_channel_saturation_power_of_half = user_set_params
110-
.max_channel_saturation_power_of_half
111-
.or(default_params.max_channel_saturation_power_of_half);
112-
113-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
114-
route_params.payment_params.max_total_cltv_expiry_delta =
115-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
116-
route_params.payment_params.max_path_count =
117-
default_params.max_path_count.unwrap_or_default();
118-
route_params.payment_params.max_channel_saturation_power_of_half =
119-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
120-
}
121-
} else if let Some(default_params) = &self.config.sending_parameters {
122-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
123-
route_params.payment_params.max_total_cltv_expiry_delta =
124-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
125-
route_params.payment_params.max_path_count =
126-
default_params.max_path_count.unwrap_or_default();
127-
route_params.payment_params.max_channel_saturation_power_of_half =
128-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
129-
}
99+
let override_params =
100+
sending_parameters.as_ref().or(self.config.sending_parameters.as_ref());
101+
if let Some(override_params) = override_params {
102+
override_params
103+
.max_total_routing_fee_msat
104+
.map(|f| route_params.max_total_routing_fee_msat = f.into());
105+
override_params
106+
.max_total_cltv_expiry_delta
107+
.map(|d| route_params.payment_params.max_total_cltv_expiry_delta = d);
108+
override_params.max_path_count.map(|p| route_params.payment_params.max_path_count = p);
109+
override_params
110+
.max_channel_saturation_power_of_half
111+
.map(|s| route_params.payment_params.max_channel_saturation_power_of_half = s);
112+
};
130113

131114
let payment_secret = Some(*invoice.payment_secret());
132115
let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
@@ -241,37 +224,20 @@ impl Bolt11Payment {
241224
let mut route_params =
242225
RouteParameters::from_payment_params_and_value(payment_params, amount_msat);
243226

244-
if let Some(user_set_params) = sending_parameters {
245-
if let Some(mut default_params) = self.config.sending_parameters.as_ref().cloned() {
246-
default_params.max_total_routing_fee_msat = user_set_params
247-
.max_total_routing_fee_msat
248-
.or(default_params.max_total_routing_fee_msat);
249-
default_params.max_total_cltv_expiry_delta = user_set_params
250-
.max_total_cltv_expiry_delta
251-
.or(default_params.max_total_cltv_expiry_delta);
252-
default_params.max_path_count =
253-
user_set_params.max_path_count.or(default_params.max_path_count);
254-
default_params.max_channel_saturation_power_of_half = user_set_params
255-
.max_channel_saturation_power_of_half
256-
.or(default_params.max_channel_saturation_power_of_half);
257-
258-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
259-
route_params.payment_params.max_total_cltv_expiry_delta =
260-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
261-
route_params.payment_params.max_path_count =
262-
default_params.max_path_count.unwrap_or_default();
263-
route_params.payment_params.max_channel_saturation_power_of_half =
264-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
265-
}
266-
} else if let Some(default_params) = &self.config.sending_parameters {
267-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
268-
route_params.payment_params.max_total_cltv_expiry_delta =
269-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
270-
route_params.payment_params.max_path_count =
271-
default_params.max_path_count.unwrap_or_default();
272-
route_params.payment_params.max_channel_saturation_power_of_half =
273-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
274-
}
227+
let override_params =
228+
sending_parameters.as_ref().or(self.config.sending_parameters.as_ref());
229+
if let Some(override_params) = override_params {
230+
override_params
231+
.max_total_routing_fee_msat
232+
.map(|f| route_params.max_total_routing_fee_msat = f.into());
233+
override_params
234+
.max_total_cltv_expiry_delta
235+
.map(|d| route_params.payment_params.max_total_cltv_expiry_delta = d);
236+
override_params.max_path_count.map(|p| route_params.payment_params.max_path_count = p);
237+
override_params
238+
.max_channel_saturation_power_of_half
239+
.map(|s| route_params.payment_params.max_channel_saturation_power_of_half = s);
240+
};
275241

276242
let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
277243
let recipient_fields = RecipientOnionFields::secret_only(*payment_secret);

src/payment/mod.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@ pub struct SendingParameters {
2323
/// paths.
2424
///
2525
/// Note that values below a few sats may result in some paths being spuriously ignored.
26-
pub max_total_routing_fee_msat: Option<u64>,
26+
#[cfg(not(feature = "uniffi"))]
27+
pub max_total_routing_fee_msat: Option<Option<u64>>,
28+
/// The maximum total fees, in millisatoshi, that may accrue during route finding.
29+
///
30+
/// This limit also applies to the total fees that may arise while retrying failed payment
31+
/// paths.
32+
///
33+
/// Note that values below a few sats may result in some paths being spuriously ignored.
34+
#[cfg(feature = "uniffi")]
35+
pub max_total_routing_fee_msat: Option<MaxTotalRoutingFeeLimit>,
2736
/// The maximum total CLTV delta we accept for the route.
2837
///
2938
/// Defaults to [`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`].
@@ -59,3 +68,32 @@ pub struct SendingParameters {
5968
/// Default value: 2
6069
pub max_channel_saturation_power_of_half: Option<u8>,
6170
}
71+
72+
/// Represents the possible states of [`SendingParameters::max_total_routing_fee_msat`].
73+
//
74+
// Required only in bindings as UniFFI can't expose `Option<Option<..>>`.
75+
#[cfg(feature = "uniffi")]
76+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
77+
pub enum MaxTotalRoutingFeeLimit {
78+
None,
79+
Some { amount_msat: u64 },
80+
}
81+
82+
#[cfg(feature = "uniffi")]
83+
impl From<MaxTotalRoutingFeeLimit> for Option<u64> {
84+
fn from(value: MaxTotalRoutingFeeLimit) -> Self {
85+
match value {
86+
MaxTotalRoutingFeeLimit::Some { amount_msat } => Some(amount_msat),
87+
MaxTotalRoutingFeeLimit::None => None,
88+
}
89+
}
90+
}
91+
92+
#[cfg(feature = "uniffi")]
93+
impl From<Option<u64>> for MaxTotalRoutingFeeLimit {
94+
fn from(value: Option<u64>) -> Self {
95+
value.map_or(MaxTotalRoutingFeeLimit::None, |amount_msat| MaxTotalRoutingFeeLimit::Some {
96+
amount_msat,
97+
})
98+
}
99+
}

src/payment/spontaneous.rs

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -72,37 +72,20 @@ impl SpontaneousPayment {
7272
amount_msat,
7373
);
7474

75-
if let Some(user_set_params) = sending_parameters {
76-
if let Some(mut default_params) = self.config.sending_parameters.as_ref().cloned() {
77-
default_params.max_total_routing_fee_msat = user_set_params
78-
.max_total_routing_fee_msat
79-
.or(default_params.max_total_routing_fee_msat);
80-
default_params.max_total_cltv_expiry_delta = user_set_params
81-
.max_total_cltv_expiry_delta
82-
.or(default_params.max_total_cltv_expiry_delta);
83-
default_params.max_path_count =
84-
user_set_params.max_path_count.or(default_params.max_path_count);
85-
default_params.max_channel_saturation_power_of_half = user_set_params
86-
.max_channel_saturation_power_of_half
87-
.or(default_params.max_channel_saturation_power_of_half);
88-
89-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
90-
route_params.payment_params.max_total_cltv_expiry_delta =
91-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
92-
route_params.payment_params.max_path_count =
93-
default_params.max_path_count.unwrap_or_default();
94-
route_params.payment_params.max_channel_saturation_power_of_half =
95-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
96-
}
97-
} else if let Some(default_params) = &self.config.sending_parameters {
98-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
99-
route_params.payment_params.max_total_cltv_expiry_delta =
100-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
101-
route_params.payment_params.max_path_count =
102-
default_params.max_path_count.unwrap_or_default();
103-
route_params.payment_params.max_channel_saturation_power_of_half =
104-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
105-
}
75+
let override_params =
76+
sending_parameters.as_ref().or(self.config.sending_parameters.as_ref());
77+
if let Some(override_params) = override_params {
78+
override_params
79+
.max_total_routing_fee_msat
80+
.map(|f| route_params.max_total_routing_fee_msat = f.into());
81+
override_params
82+
.max_total_cltv_expiry_delta
83+
.map(|d| route_params.payment_params.max_total_cltv_expiry_delta = d);
84+
override_params.max_path_count.map(|p| route_params.payment_params.max_path_count = p);
85+
override_params
86+
.max_channel_saturation_power_of_half
87+
.map(|s| route_params.payment_params.max_channel_saturation_power_of_half = s);
88+
};
10689

10790
let recipient_fields = RecipientOnionFields::spontaneous_empty();
10891

src/uniffi_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
pub use crate::graph::{ChannelInfo, ChannelUpdateInfo, NodeAnnouncementInfo, NodeInfo};
77
pub use crate::payment::store::{LSPFeeLimits, PaymentDirection, PaymentKind, PaymentStatus};
8-
pub use crate::payment::{QrPaymentResult, SendingParameters};
8+
pub use crate::payment::{MaxTotalRoutingFeeLimit, QrPaymentResult, SendingParameters};
99

1010
pub use lightning::events::{ClosureReason, PaymentFailureReason};
1111
pub use lightning::ln::{ChannelId, PaymentHash, PaymentPreimage, PaymentSecret};

tests/integration_tests_rust.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fn multi_hop_sending() {
157157
std::thread::sleep(std::time::Duration::from_secs(1));
158158

159159
let sending_params = SendingParameters {
160-
max_total_routing_fee_msat: Some(75_000),
160+
max_total_routing_fee_msat: Some(Some(75_000).into()),
161161
max_total_cltv_expiry_delta: Some(1000),
162162
max_path_count: Some(10),
163163
max_channel_saturation_power_of_half: Some(2),

0 commit comments

Comments
 (0)