Skip to content

Commit ab7cc70

Browse files
authored
Merge pull request #351 from tnull/2024-08-336-followup
#336 followups
2 parents 398ece5 + b282d42 commit ab7cc70

File tree

8 files changed

+124
-146
lines changed

8 files changed

+124
-146
lines changed

bindings/ldk_node.udl

+18-13
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ dictionary Config {
88
string? log_dir_path;
99
Network network;
1010
sequence<SocketAddress>? listening_addresses;
11-
u32 default_cltv_expiry_delta;
1211
u64 onchain_wallet_sync_interval_secs;
1312
u64 wallet_sync_interval_secs;
1413
u64 fee_rate_cache_update_interval_secs;
1514
sequence<PublicKey> trusted_peers_0conf;
1615
u64 probing_liquidity_limit_multiplier;
1716
LogLevel log_level;
1817
AnchorChannelsConfig? anchor_channels_config;
19-
SendingParameters? sending_parameters_config;
18+
SendingParameters? sending_parameters;
2019
};
2120

2221
dictionary AnchorChannelsConfig {
@@ -151,10 +150,10 @@ interface OnchainPayment {
151150
};
152151

153152
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);
153+
[Throws=NodeError]
154+
string receive(u64 amount_sats, [ByRef]string message, u32 expiry_sec);
155+
[Throws=NodeError]
156+
QrPaymentResult send([ByRef]string uri_str);
158157
};
159158

160159
[Error]
@@ -290,9 +289,9 @@ interface PaymentKind {
290289

291290
[Enum]
292291
interface QrPaymentResult {
293-
Onchain(Txid txid);
294-
Bolt11(PaymentId payment_id);
295-
Bolt12(PaymentId payment_id);
292+
Onchain(Txid txid);
293+
Bolt11(PaymentId payment_id);
294+
Bolt12(PaymentId payment_id);
296295
};
297296

298297
enum PaymentDirection {
@@ -321,10 +320,16 @@ dictionary PaymentDetails {
321320
};
322321

323322
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;
323+
MaxTotalRoutingFeeLimit? max_total_routing_fee_msat;
324+
u32? max_total_cltv_expiry_delta;
325+
u8? max_path_count;
326+
u8? max_channel_saturation_power_of_half;
327+
};
328+
329+
[Enum]
330+
interface MaxTotalRoutingFeeLimit {
331+
None ();
332+
Some ( u64 amount_msat );
328333
};
329334

330335
[NonExhaustive]

bindings/python/src/ldk_node/test_ldk_node.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def test_channel_full_cycle(self):
186186
node_2.event_handled()
187187

188188
invoice = node_2.bolt11_payment().receive(2500000, "asdf", 9217)
189-
node_1.bolt11_payment().send(invoice)
189+
node_1.bolt11_payment().send(invoice, None)
190190

191191
payment_successful_event_1 = node_1.wait_next_event()
192192
assert isinstance(payment_successful_event_1, Event.PAYMENT_SUCCESSFUL)

src/config.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::time::Duration;
2-
31
use crate::payment::SendingParameters;
42

53
use lightning::ln::msgs::SocketAddress;
@@ -9,10 +7,11 @@ use lightning::util::logger::Level as LogLevel;
97
use bitcoin::secp256k1::PublicKey;
108
use bitcoin::Network;
119

10+
use std::time::Duration;
11+
1212
// Config defaults
1313
const DEFAULT_STORAGE_DIR_PATH: &str = "/tmp/ldk_node/";
1414
const DEFAULT_NETWORK: Network = Network::Bitcoin;
15-
const DEFAULT_CLTV_EXPIRY_DELTA: u32 = 144;
1615
const DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS: u64 = 80;
1716
const DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS: u64 = 30;
1817
const DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS: u64 = 60 * 10;
@@ -88,9 +87,10 @@ pub(crate) const WALLET_KEYS_SEED_LEN: usize = 64;
8887
/// | `probing_liquidity_limit_multiplier` | 3 |
8988
/// | `log_level` | Debug |
9089
/// | `anchor_channels_config` | Some(..) |
91-
/// | `sending_parameters_config` | None |
90+
/// | `sending_parameters` | None |
9291
///
93-
/// See [`AnchorChannelsConfig`] for more information on its respective default values.
92+
/// See [`AnchorChannelsConfig`] and [`SendingParameters`] for more information regarding their
93+
/// respective default values.
9494
///
9595
/// [`Node`]: crate::Node
9696
pub struct Config {
@@ -104,8 +104,6 @@ pub struct Config {
104104
pub network: Network,
105105
/// The addresses on which the node will listen for incoming connections.
106106
pub listening_addresses: Option<Vec<SocketAddress>>,
107-
/// The default CLTV expiry delta to be used for payments.
108-
pub default_cltv_expiry_delta: u32,
109107
/// The time in-between background sync attempts of the onchain wallet, in seconds.
110108
///
111109
/// **Note:** A minimum of 10 seconds is always enforced.
@@ -150,12 +148,14 @@ pub struct Config {
150148
/// closure. We *will* however still try to get the Anchor spending transactions confirmed
151149
/// on-chain with the funds available.
152150
pub anchor_channels_config: Option<AnchorChannelsConfig>,
153-
154151
/// Configuration options for payment routing and pathfinding.
155152
///
156153
/// Setting the `SendingParameters` provides flexibility to customize how payments are routed,
157154
/// including setting limits on routing fees, CLTV expiry, and channel utilization.
158-
pub sending_parameters_config: Option<SendingParameters>,
155+
///
156+
/// **Note:** If unset, default parameters will be used, and you will be able to override the
157+
/// parameters on a per-payment basis in the corresponding method calls.
158+
pub sending_parameters: Option<SendingParameters>,
159159
}
160160

161161
impl Default for Config {
@@ -165,15 +165,14 @@ impl Default for Config {
165165
log_dir_path: None,
166166
network: DEFAULT_NETWORK,
167167
listening_addresses: None,
168-
default_cltv_expiry_delta: DEFAULT_CLTV_EXPIRY_DELTA,
169168
onchain_wallet_sync_interval_secs: DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS,
170169
wallet_sync_interval_secs: DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS,
171170
fee_rate_cache_update_interval_secs: DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS,
172171
trusted_peers_0conf: Vec::new(),
173172
probing_liquidity_limit_multiplier: DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER,
174173
log_level: DEFAULT_LOG_LEVEL,
175174
anchor_channels_config: Some(AnchorChannelsConfig::default()),
176-
sending_parameters_config: None,
175+
sending_parameters: None,
177176
}
178177
}
179178
}

src/payment/bolt11.rs

+32-74
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,8 @@ impl Bolt11Payment {
7171

7272
/// Send a payment given an invoice.
7373
///
74-
/// If [`SendingParameters`] are provided they will override the node's default routing parameters
75-
/// on a per-field basis. Each field in `SendingParameters` that is set replaces the corresponding
76-
/// default value. Fields that are not set fall back to the node's configured defaults. If no
77-
/// `SendingParameters` are provided, the method fully relies on these defaults.
74+
/// If `sending_parameters` are provided they will override the default as well as the
75+
/// node-wide parameters configured via [`Config::sending_parameters`] on a per-field basis.
7876
pub fn send(
7977
&self, invoice: &Bolt11Invoice, sending_parameters: Option<SendingParameters>,
8078
) -> Result<PaymentId, Error> {
@@ -98,39 +96,20 @@ impl Bolt11Payment {
9896
}
9997
}
10098

101-
if let Some(user_set_params) = sending_parameters {
102-
if let Some(mut default_params) =
103-
self.config.sending_parameters_config.as_ref().cloned()
104-
{
105-
default_params.max_total_routing_fee_msat = user_set_params
106-
.max_total_routing_fee_msat
107-
.or(default_params.max_total_routing_fee_msat);
108-
default_params.max_total_cltv_expiry_delta = user_set_params
109-
.max_total_cltv_expiry_delta
110-
.or(default_params.max_total_cltv_expiry_delta);
111-
default_params.max_path_count =
112-
user_set_params.max_path_count.or(default_params.max_path_count);
113-
default_params.max_channel_saturation_power_of_half = user_set_params
114-
.max_channel_saturation_power_of_half
115-
.or(default_params.max_channel_saturation_power_of_half);
116-
117-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
118-
route_params.payment_params.max_total_cltv_expiry_delta =
119-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
120-
route_params.payment_params.max_path_count =
121-
default_params.max_path_count.unwrap_or_default();
122-
route_params.payment_params.max_channel_saturation_power_of_half =
123-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
124-
}
125-
} else if let Some(default_params) = &self.config.sending_parameters_config {
126-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
127-
route_params.payment_params.max_total_cltv_expiry_delta =
128-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
129-
route_params.payment_params.max_path_count =
130-
default_params.max_path_count.unwrap_or_default();
131-
route_params.payment_params.max_channel_saturation_power_of_half =
132-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
133-
}
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+
};
134113

135114
let payment_secret = Some(*invoice.payment_secret());
136115
let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
@@ -197,10 +176,8 @@ impl Bolt11Payment {
197176
/// This can be used to pay a so-called "zero-amount" invoice, i.e., an invoice that leaves the
198177
/// amount paid to be determined by the user.
199178
///
200-
/// If [`SendingParameters`] are provided they will override the node's default routing parameters
201-
/// on a per-field basis. Each field in `SendingParameters` that is set replaces the corresponding
202-
/// default value. Fields that are not set fall back to the node's configured defaults. If no
203-
/// `SendingParameters` are provided, the method fully relies on these defaults.
179+
/// If `sending_parameters` are provided they will override the default as well as the
180+
/// node-wide parameters configured via [`Config::sending_parameters`] on a per-field basis.
204181
pub fn send_using_amount(
205182
&self, invoice: &Bolt11Invoice, amount_msat: u64,
206183
sending_parameters: Option<SendingParameters>,
@@ -247,39 +224,20 @@ impl Bolt11Payment {
247224
let mut route_params =
248225
RouteParameters::from_payment_params_and_value(payment_params, amount_msat);
249226

250-
if let Some(user_set_params) = sending_parameters {
251-
if let Some(mut default_params) =
252-
self.config.sending_parameters_config.as_ref().cloned()
253-
{
254-
default_params.max_total_routing_fee_msat = user_set_params
255-
.max_total_routing_fee_msat
256-
.or(default_params.max_total_routing_fee_msat);
257-
default_params.max_total_cltv_expiry_delta = user_set_params
258-
.max_total_cltv_expiry_delta
259-
.or(default_params.max_total_cltv_expiry_delta);
260-
default_params.max_path_count =
261-
user_set_params.max_path_count.or(default_params.max_path_count);
262-
default_params.max_channel_saturation_power_of_half = user_set_params
263-
.max_channel_saturation_power_of_half
264-
.or(default_params.max_channel_saturation_power_of_half);
265-
266-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
267-
route_params.payment_params.max_total_cltv_expiry_delta =
268-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
269-
route_params.payment_params.max_path_count =
270-
default_params.max_path_count.unwrap_or_default();
271-
route_params.payment_params.max_channel_saturation_power_of_half =
272-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
273-
}
274-
} else if let Some(default_params) = &self.config.sending_parameters_config {
275-
route_params.max_total_routing_fee_msat = default_params.max_total_routing_fee_msat;
276-
route_params.payment_params.max_total_cltv_expiry_delta =
277-
default_params.max_total_cltv_expiry_delta.unwrap_or_default();
278-
route_params.payment_params.max_path_count =
279-
default_params.max_path_count.unwrap_or_default();
280-
route_params.payment_params.max_channel_saturation_power_of_half =
281-
default_params.max_channel_saturation_power_of_half.unwrap_or_default();
282-
}
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+
};
283241

284242
let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
285243
let recipient_fields = RecipientOnionFields::secret_only(*payment_secret);

src/payment/mod.rs

+40-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub use spontaneous::SpontaneousPayment;
1414
pub use store::{LSPFeeLimits, PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus};
1515
pub use unified_qr::{QrPaymentResult, UnifiedQrPayment};
1616

17-
/// Represents information used to route a payment.
17+
/// Represents information used to send a payment.
1818
#[derive(Clone, Debug, PartialEq)]
1919
pub struct SendingParameters {
2020
/// The maximum total fees, in millisatoshi, that may accrue during route finding.
@@ -23,22 +23,28 @@ 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>,
27-
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>,
2836
/// The maximum total CLTV delta we accept for the route.
2937
///
3038
/// Defaults to [`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`].
3139
///
3240
/// [`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`]: lightning::routing::router::DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA
3341
pub max_total_cltv_expiry_delta: Option<u32>,
34-
3542
/// The maximum number of paths that may be used by (MPP) payments.
3643
///
3744
/// Defaults to [`DEFAULT_MAX_PATH_COUNT`].
3845
///
3946
/// [`DEFAULT_MAX_PATH_COUNT`]: lightning::routing::router::DEFAULT_MAX_PATH_COUNT
4047
pub max_path_count: Option<u8>,
41-
4248
/// Selects the maximum share of a channel's total capacity which will be sent over a channel,
4349
/// as a power of 1/2.
4450
///
@@ -62,3 +68,32 @@ pub struct SendingParameters {
6268
/// Default value: 2
6369
pub max_channel_saturation_power_of_half: Option<u8>,
6470
}
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+
}

0 commit comments

Comments
 (0)