Skip to content
Draft
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
24 changes: 12 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,17 @@ default = []
#lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }
#lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }

lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab", features = ["std"] }
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab" }
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab", features = ["std"] }
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab" }
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab" }
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab" }
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab" }
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab", features = ["rest-client", "rpc-client", "tokio"] }
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab", features = ["esplora-async-https", "electrum-rustls-ring", "time"] }
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab" }
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab" }
lightning = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045", features = ["std"] }
lightning-types = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045" }
lightning-invoice = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045", features = ["std"] }
lightning-net-tokio = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045" }
lightning-persister = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045" }
lightning-background-processor = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045" }
lightning-rapid-gossip-sync = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045" }
lightning-block-sync = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045", features = ["rest-client", "rpc-client", "tokio"] }
lightning-transaction-sync = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045", features = ["esplora-async-https", "electrum-rustls-ring", "time"] }
lightning-liquidity = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045" }
lightning-macros = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045" }

#lightning = { path = "../rust-lightning/lightning", features = ["std"] }
#lightning-types = { path = "../rust-lightning/lightning-types" }
Expand Down Expand Up @@ -109,7 +109,7 @@ winapi = { version = "0.3", features = ["winbase"] }
[dev-dependencies]
#lightning = { version = "0.1.0", features = ["std", "_test_utils"] }
#lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["std", "_test_utils"] }
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "4e32d85249359d8ef8ece97d89848e40154363ab", features = ["std", "_test_utils"] }
lightning = { git = "https://github.com/valentinewallace/rust-lightning", rev = "6b2f95cb7b18742777c5aa0135fa27b88d5f4045", features = ["std", "_test_utils"] }
#lightning = { path = "../rust-lightning/lightning", features = ["std", "_test_utils"] }
proptest = "1.0.0"
regex = "1.5.6"
Expand Down
9 changes: 9 additions & 0 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dictionary Config {
u64 probing_liquidity_limit_multiplier;
AnchorChannelsConfig? anchor_channels_config;
RouteParametersConfig? route_parameters;
boolean async_payment_services_enabled;
};

dictionary AnchorChannelsConfig {
Expand Down Expand Up @@ -209,6 +210,12 @@ interface Bolt12Payment {
Bolt12Invoice request_refund_payment([ByRef]Refund refund);
[Throws=NodeError]
Refund initiate_refund(u64 amount_msat, u32 expiry_secs, u64? quantity, string? payer_note);
[Throws=NodeError]
Offer receive_async();
[Throws=NodeError]
void set_paths_to_static_invoice_server(bytes paths);
[Throws=NodeError]
bytes blinded_paths_for_async_recipient(bytes recipient_id);
};

interface SpontaneousPayment {
Expand Down Expand Up @@ -311,6 +318,8 @@ enum NodeError {
"InsufficientFunds",
"LiquiditySourceUnavailable",
"LiquidityFeeTooHigh",
"InvalidBlindedPaths",
"AsyncPaymentServicesDisabled",
};

dictionary NodeStatus {
Expand Down
44 changes: 33 additions & 11 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use crate::liquidity::{
};
use crate::logger::{log_error, LdkLogger, LogLevel, LogWriter, Logger};
use crate::message_handler::NodeCustomMessageHandler;
use crate::om_mailbox::OnionMessageMailbox;
use crate::peer_store::PeerStore;
use crate::runtime::Runtime;
use crate::tx_broadcaster::TransactionBroadcaster;
Expand Down Expand Up @@ -1378,6 +1379,10 @@ fn build_with_store_internal(
100;
}

if config.async_payment_services_enabled {
user_config.accept_forwards_to_priv_channels = true;
}

let message_router =
Arc::new(MessageRouter::new(Arc::clone(&network_graph), Arc::clone(&keys_manager)));

Expand Down Expand Up @@ -1448,17 +1453,31 @@ fn build_with_store_internal(
}

// Initialize the PeerManager
let onion_messenger: Arc<OnionMessenger> = Arc::new(OnionMessenger::new(
Arc::clone(&keys_manager),
Arc::clone(&keys_manager),
Arc::clone(&logger),
Arc::clone(&channel_manager),
message_router,
Arc::clone(&channel_manager),
IgnoringMessageHandler {},
IgnoringMessageHandler {},
IgnoringMessageHandler {},
));
let onion_messenger: Arc<OnionMessenger> = if config.async_payment_services_enabled {
Arc::new(OnionMessenger::new_with_offline_peer_interception(
Arc::clone(&keys_manager),
Arc::clone(&keys_manager),
Arc::clone(&logger),
Arc::clone(&channel_manager),
message_router,
Arc::clone(&channel_manager),
Arc::clone(&channel_manager),
IgnoringMessageHandler {},
IgnoringMessageHandler {},
))
} else {
Arc::new(OnionMessenger::new(
Arc::clone(&keys_manager),
Arc::clone(&keys_manager),
Arc::clone(&logger),
Arc::clone(&channel_manager),
message_router,
Arc::clone(&channel_manager),
Arc::clone(&channel_manager),
IgnoringMessageHandler {},
IgnoringMessageHandler {},
))
};
let ephemeral_bytes: [u8; 32] = keys_manager.get_secure_random_bytes();

// Initialize the GossipSource
Expand Down Expand Up @@ -1645,6 +1664,8 @@ fn build_with_store_internal(
},
};

let om_mailbox = Arc::new(OnionMessageMailbox::new());

let (stop_sender, _) = tokio::sync::watch::channel(());
let (background_processor_stop_sender, _) = tokio::sync::watch::channel(());
let is_running = Arc::new(RwLock::new(false));
Expand Down Expand Up @@ -1677,6 +1698,7 @@ fn build_with_store_internal(
is_running,
is_listening,
node_metrics,
om_mailbox,
})
}

Expand Down
5 changes: 5 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ pub struct Config {
/// **Note:** If unset, default parameters will be used, and you will be able to override the
/// parameters on a per-payment basis in the corresponding method calls.
pub route_parameters: Option<RouteParametersConfig>,
/// Whether to enable the static invoice service to support async payment reception for clients.
pub async_payment_services_enabled: bool,
}

impl Default for Config {
Expand All @@ -193,6 +195,7 @@ impl Default for Config {
anchor_channels_config: Some(AnchorChannelsConfig::default()),
route_parameters: None,
node_alias: None,
async_payment_services_enabled: false,
}
}
}
Expand Down Expand Up @@ -327,6 +330,8 @@ pub(crate) fn default_user_config(config: &Config) -> UserConfig {
user_config.channel_handshake_limits.force_announced_channel_preference = true;
}

user_config.enable_htlc_hold = true;

user_config
}

Expand Down
8 changes: 8 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ pub enum Error {
LiquiditySourceUnavailable,
/// The given operation failed due to the LSP's required opening fee being too high.
LiquidityFeeTooHigh,
/// The given blinded paths are invalid.
InvalidBlindedPaths,
/// Asynchronous payment services are disabled.
AsyncPaymentServicesDisabled,
}

impl fmt::Display for Error {
Expand Down Expand Up @@ -193,6 +197,10 @@ impl fmt::Display for Error {
Self::LiquidityFeeTooHigh => {
write!(f, "The given operation failed due to the LSP's required opening fee being too high.")
},
Self::InvalidBlindedPaths => write!(f, "The given blinded paths are invalid."),
Self::AsyncPaymentServicesDisabled => {
write!(f, "Asynchronous payment services are disabled.")
},
}
}
}
Expand Down
74 changes: 62 additions & 12 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
// accordance with one or both of these licenses.

use crate::types::{CustomTlvRecord, DynStore, PaymentStore, Sweeper, Wallet};

use crate::om_mailbox::OnionMessageMailbox;
use crate::types::{CustomTlvRecord, DynStore, OnionMessenger, PaymentStore, Sweeper, Wallet};
use crate::{
hex_utils, BumpTransactionEventHandler, ChannelManager, Error, Graph, PeerInfo, PeerStore,
UserChannelId,
Expand All @@ -19,6 +19,7 @@ use crate::fee_estimator::ConfirmationTarget;
use crate::liquidity::LiquiditySource;
use crate::logger::Logger;

use crate::payment::asynchronous::static_invoice_store::StaticInvoiceStore;
use crate::payment::store::{
PaymentDetails, PaymentDetailsUpdate, PaymentDirection, PaymentKind, PaymentStatus,
};
Expand Down Expand Up @@ -458,6 +459,9 @@ where
runtime: Arc<Runtime>,
logger: L,
config: Arc<Config>,
static_invoice_store: Option<StaticInvoiceStore>,
onion_messenger: Arc<OnionMessenger>,
om_mailbox: Arc<OnionMessageMailbox>,
}

impl<L: Deref + Clone + Sync + Send + 'static> EventHandler<L>
Expand All @@ -470,8 +474,10 @@ where
channel_manager: Arc<ChannelManager>, connection_manager: Arc<ConnectionManager<L>>,
output_sweeper: Arc<Sweeper>, network_graph: Arc<Graph>,
liquidity_source: Option<Arc<LiquiditySource<Arc<Logger>>>>,
payment_store: Arc<PaymentStore>, peer_store: Arc<PeerStore<L>>, runtime: Arc<Runtime>,
logger: L, config: Arc<Config>,
payment_store: Arc<PaymentStore>, peer_store: Arc<PeerStore<L>>,
static_invoice_store: Option<StaticInvoiceStore>, onion_messenger: Arc<OnionMessenger>,
om_mailbox: Arc<OnionMessageMailbox>, runtime: Arc<Runtime>, logger: L,
config: Arc<Config>,
) -> Self {
Self {
event_queue,
Expand All @@ -487,6 +493,9 @@ where
logger,
runtime,
config,
static_invoice_store,
onion_messenger,
om_mailbox,
}
}

Expand Down Expand Up @@ -1488,17 +1497,58 @@ where

self.bump_tx_event_handler.handle_event(&bte).await;
},
LdkEvent::OnionMessageIntercepted { .. } => {
debug_assert!(false, "We currently don't support onion message interception, so this event should never be emitted.");
LdkEvent::OnionMessageIntercepted { peer_node_id, message } => {
self.om_mailbox.onion_message_intercepted(peer_node_id, message);
},
LdkEvent::OnionMessagePeerConnected { .. } => {
debug_assert!(false, "We currently don't support onion message interception, so this event should never be emitted.");
LdkEvent::OnionMessagePeerConnected { peer_node_id } => {
let messages = self.om_mailbox.onion_message_peer_connected(peer_node_id);

for message in messages {
let _ = self.onion_messenger.forward_onion_message(message, &peer_node_id);
}
},
LdkEvent::PersistStaticInvoice { .. } => {
debug_assert!(false, "We currently don't support static invoice persistence, so this event should never be emitted.");

LdkEvent::PersistStaticInvoice {
invoice,
invoice_slot,
recipient_id,
invoice_persisted_path,
} => {
if let Some(store) = self.static_invoice_store.as_ref() {
match store
.handle_persist_static_invoice(invoice, invoice_slot, recipient_id)
.await
{
Ok(_) => {
self.channel_manager.static_invoice_persisted(invoice_persisted_path);
},
Err(e) => {
log_error!(self.logger, "Failed to persist static invoice: {}", e);
return Err(ReplayEvent());
},
};
}
},
LdkEvent::StaticInvoiceRequested { .. } => {
debug_assert!(false, "We currently don't support static invoice persistence, so this event should never be emitted.");
LdkEvent::StaticInvoiceRequested { recipient_id, invoice_slot, reply_path } => {
if let Some(store) = self.static_invoice_store.as_ref() {
let invoice =
store.handle_static_invoice_requested(&recipient_id, invoice_slot).await;

match invoice {
Ok(Some(invoice)) => {
if let Err(e) =
self.channel_manager.send_static_invoice(invoice, reply_path)
{
log_error!(self.logger, "Failed to send static invoice: {:?}", e);
}
},
Ok(None) => {},
Err(e) => {
log_error!(self.logger, "Failed to retrieve static invoice: {}", e);
return Err(ReplayEvent());
},
}
}
},
LdkEvent::FundingTransactionReadyForSigning { .. } => {
debug_assert!(false, "We currently don't support interactive-tx, so this event should never be emitted.");
Expand Down
5 changes: 5 additions & 0 deletions src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,8 @@ pub(crate) const BDK_WALLET_TX_GRAPH_KEY: &str = "tx_graph";
pub(crate) const BDK_WALLET_INDEXER_PRIMARY_NAMESPACE: &str = "bdk_wallet";
pub(crate) const BDK_WALLET_INDEXER_SECONDARY_NAMESPACE: &str = "";
pub(crate) const BDK_WALLET_INDEXER_KEY: &str = "indexer";

/// [`StaticInvoice`]s will be persisted under this key.
///
/// [`StaticInvoice`]: lightning::offers::static_invoice::StaticInvoice
pub(crate) const STATIC_INVOICE_STORE_PRIMARY_NAMESPACE: &str = "static_invoices";
Loading
Loading