Skip to content
Open
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
52 changes: 49 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::time::Duration;
use bitcoin::secp256k1::PublicKey;
use bitcoin::Network;
use lightning::ln::msgs::SocketAddress;
use lightning::ln::outbound_payment::Retry;
use lightning::routing::gossip::NodeAlias;
use lightning::routing::router::RouteParametersConfig;
use lightning::util::config::{
Expand All @@ -28,6 +29,7 @@ const DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS: u64 = 30;
const DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS: u64 = 60 * 10;
const DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER: u64 = 3;
const DEFAULT_ANCHOR_PER_CHANNEL_RESERVE_SATS: u64 = 25_000;
const DEFAULT_PAYMENT_RETRY_TIMEOUT_SECS: u64 = 10;

// The default timeout after which we abort a wallet syncing operation.
const DEFAULT_BDK_WALLET_SYNC_TIMEOUT_SECS: u64 = 60;
Expand Down Expand Up @@ -63,9 +65,6 @@ pub(crate) const BDK_CLIENT_STOP_GAP: usize = 20;
// The number of concurrent requests made against the API provider.
pub(crate) const BDK_CLIENT_CONCURRENCY: usize = 4;

// The timeout after which we abandon retrying failed payments.
pub(crate) const LDK_PAYMENT_RETRY_TIMEOUT: Duration = Duration::from_secs(10);

// The time in-between peer reconnection attempts.
pub(crate) const PEER_RECONNECTION_INTERVAL: Duration = Duration::from_secs(60);

Expand Down Expand Up @@ -131,6 +130,7 @@ pub(crate) const LNURL_AUTH_TIMEOUT_SECS: u64 = 15;
/// | `probing_liquidity_limit_multiplier` | 3 |
/// | `log_level` | Debug |
/// | `anchor_channels_config` | Some(..) |
/// | `payment_retry_strategy` | Timeout(10s) |
/// | `route_parameters` | None |
///
/// See [`AnchorChannelsConfig`] and [`RouteParametersConfig`] for more information regarding their
Expand Down Expand Up @@ -188,6 +188,12 @@ pub struct Config {
/// closure. We *will* however still try to get the Anchor spending transactions confirmed
/// on-chain with the funds available.
pub anchor_channels_config: Option<AnchorChannelsConfig>,
/// The strategy used when retrying failed payments.
///
/// When a payment fails to route, LDK will automatically retry according to this strategy.
///
/// See [`PaymentRetryStrategy`] for available options.
pub payment_retry_strategy: PaymentRetryStrategy,
/// Configuration options for payment routing and pathfinding.
///
/// Setting the [`RouteParametersConfig`] provides flexibility to customize how payments are routed,
Expand All @@ -208,6 +214,7 @@ impl Default for Config {
trusted_peers_0conf: Vec::new(),
probing_liquidity_limit_multiplier: DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER,
anchor_channels_config: Some(AnchorChannelsConfig::default()),
payment_retry_strategy: PaymentRetryStrategy::default(),
route_parameters: None,
node_alias: None,
}
Expand Down Expand Up @@ -619,6 +626,45 @@ pub enum AsyncPaymentsRole {
Server,
}

/// Strategies available to retry payment path failures.
///
/// See [`Retry`] for details.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
pub enum PaymentRetryStrategy {
/// Max number of attempts to retry payment.
///
/// Please refer to [`Retry`] for further details.
Attempts {
/// The maximum number of payment attempts.
max_attempts: u32,
},
/// Time elapsed before abandoning retries for a payment.
///
/// Please refer to [`Retry`] for further details.
Timeout {
/// The timeout in seconds after which we stop retrying.
timeout_secs: u64,
},
}

impl Default for PaymentRetryStrategy {
fn default() -> Self {
Self::Timeout { timeout_secs: DEFAULT_PAYMENT_RETRY_TIMEOUT_SECS }
}
}

impl From<PaymentRetryStrategy> for Retry {
fn from(value: PaymentRetryStrategy) -> Self {
match value {
PaymentRetryStrategy::Attempts { max_attempts } => Retry::Attempts(max_attempts),
PaymentRetryStrategy::Timeout { timeout_secs } => {
Retry::Timeout(Duration::from_secs(timeout_secs))
},
}
}
}

#[cfg(test)]
mod tests {
use std::str::FromStr;
Expand Down
8 changes: 4 additions & 4 deletions src/payment/bolt11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ use bitcoin::hashes::Hash;
use lightning::ln::channelmanager::{
Bolt11InvoiceParameters, OptionalBolt11PaymentParams, PaymentId,
};
use lightning::ln::outbound_payment::{Bolt11PaymentError, Retry, RetryableSendFailure};
use lightning::ln::outbound_payment::{Bolt11PaymentError, RetryableSendFailure};
use lightning::routing::router::{PaymentParameters, RouteParameters, RouteParametersConfig};
use lightning_invoice::{
Bolt11Invoice as LdkBolt11Invoice, Bolt11InvoiceDescription as LdkBolt11InvoiceDescription,
};
use lightning_types::payment::{PaymentHash, PaymentPreimage};

use crate::config::{Config, LDK_PAYMENT_RETRY_TIMEOUT};
use crate::config::Config;
use crate::connection::ConnectionManager;
use crate::data_store::DataStoreUpdateResult;
use crate::error::Error;
Expand Down Expand Up @@ -259,7 +259,7 @@ impl Bolt11Payment {

let route_params_config =
route_parameters.or(self.config.route_parameters).unwrap_or_default();
let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
let retry_strategy = self.config.payment_retry_strategy.into();
let payment_secret = Some(*invoice.payment_secret());

let optional_params = OptionalBolt11PaymentParams {
Expand Down Expand Up @@ -369,7 +369,7 @@ impl Bolt11Payment {

let route_params_config =
route_parameters.or(self.config.route_parameters).unwrap_or_default();
let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
let retry_strategy = self.config.payment_retry_strategy.into();
let payment_secret = Some(*invoice.payment_secret());

let optional_params = OptionalBolt11PaymentParams {
Expand Down
9 changes: 4 additions & 5 deletions src/payment/bolt12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};

use lightning::blinded_path::message::BlindedMessagePath;
use lightning::ln::channelmanager::{OptionalOfferPaymentParams, PaymentId};
use lightning::ln::outbound_payment::Retry;
use lightning::offers::offer::{Amount, Offer as LdkOffer, OfferFromHrn, Quantity};
use lightning::offers::parse::Bolt12SemanticError;
use lightning::routing::router::RouteParametersConfig;
Expand All @@ -24,7 +23,7 @@ use lightning::sign::EntropySource;
use lightning::util::ser::{Readable, Writeable};
use lightning_types::string::UntrustedString;

use crate::config::{AsyncPaymentsRole, Config, LDK_PAYMENT_RETRY_TIMEOUT};
use crate::config::{AsyncPaymentsRole, Config};
use crate::error::Error;
use crate::ffi::{maybe_deref, maybe_wrap};
use crate::logger::{log_error, log_info, LdkLogger, Logger};
Expand Down Expand Up @@ -96,7 +95,7 @@ impl Bolt12Payment {
let offer = maybe_deref(offer);

let payment_id = PaymentId(self.keys_manager.get_secure_random_bytes());
let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
let retry_strategy = self.config.payment_retry_strategy.into();
let route_parameters =
route_parameters.or(self.config.route_parameters).unwrap_or_default();

Expand Down Expand Up @@ -269,7 +268,7 @@ impl Bolt12Payment {
let offer = maybe_deref(offer);

let payment_id = PaymentId(self.keys_manager.get_secure_random_bytes());
let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
let retry_strategy = self.config.payment_retry_strategy.into();
let route_parameters =
route_parameters.or(self.config.route_parameters).unwrap_or_default();

Expand Down Expand Up @@ -475,7 +474,7 @@ impl Bolt12Payment {
let absolute_expiry = (SystemTime::now() + Duration::from_secs(expiry_secs as u64))
.duration_since(UNIX_EPOCH)
.unwrap();
let retry_strategy = Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT);
let retry_strategy = self.config.payment_retry_strategy.into();
let route_parameters =
route_parameters.or(self.config.route_parameters).unwrap_or_default();

Expand Down
6 changes: 3 additions & 3 deletions src/payment/spontaneous.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ use std::sync::{Arc, RwLock};
use bitcoin::secp256k1::PublicKey;
use lightning::ln::channelmanager::PaymentId;
use lightning::ln::outbound_payment::{
RecipientCustomTlvs, RecipientOnionFields, Retry, RetryableSendFailure,
RecipientCustomTlvs, RecipientOnionFields, RetryableSendFailure,
};
use lightning::routing::router::{PaymentParameters, RouteParameters, RouteParametersConfig};
use lightning::sign::EntropySource;
use lightning_types::payment::{PaymentHash, PaymentPreimage};

use crate::config::{Config, LDK_PAYMENT_RETRY_TIMEOUT};
use crate::config::Config;
use crate::error::Error;
use crate::logger::{log_error, log_info, LdkLogger, Logger};
use crate::payment::store::{PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus};
Expand Down Expand Up @@ -113,7 +113,7 @@ impl SpontaneousPayment {
recipient_fields,
PaymentId(payment_hash.0),
route_params,
Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT),
self.config.payment_retry_strategy.into(),
) {
Ok(_hash) => {
log_info!(self.logger, "Initiated sending {}msat to {}.", amount_msat, node_id);
Expand Down
Loading