From 740c40a60ed4af454ba791a7c591edc25ef83633 Mon Sep 17 00:00:00 2001 From: Orbital Date: Mon, 12 Jun 2023 14:31:12 -0500 Subject: [PATCH 1/7] Expose onion messenger on Node struct --- src/builder.rs | 5 +++-- src/lib.rs | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index dddc6d064..f25becc53 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -646,13 +646,13 @@ fn build_with_store_internal( chan_handler: Arc::clone(&channel_manager), route_handler: Arc::clone(&p2p_gossip_sync) as Arc, - onion_message_handler: onion_messenger, + onion_message_handler: onion_messenger.clone(), }, GossipSync::Rapid(_) => MessageHandler { chan_handler: Arc::clone(&channel_manager), route_handler: Arc::new(IgnoringMessageHandler {}) as Arc, - onion_message_handler: onion_messenger, + onion_message_handler: onion_messenger.clone(), }, GossipSync::None => { unreachable!("We must always have a gossip sync!"); @@ -722,5 +722,6 @@ fn build_with_store_internal( scorer, peer_store, payment_store, + _onion_messenger: onion_messenger, }) } diff --git a/src/lib.rs b/src/lib.rs index 1fbd33f78..ef3c8d8fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,6 +101,8 @@ use error::Error; pub use event::Event; pub use types::NetAddress; +use types::OnionMessenger; + pub use io::utils::generate_entropy_mnemonic; #[cfg(feature = "uniffi")] @@ -281,6 +283,7 @@ pub struct Node { scorer: Arc>, peer_store: Arc>>, payment_store: Arc>>, + _onion_messenger: Arc, } impl Node { From c3aca168f9e9fb5922c3b46790954aa4bd692fcc Mon Sep 17 00:00:00 2001 From: Orbital Date: Mon, 12 Jun 2023 14:49:45 -0500 Subject: [PATCH 2/7] Add Node fn for sending an onion message --- src/builder.rs | 2 +- src/lib.rs | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index f25becc53..b998a4c4b 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -722,6 +722,6 @@ fn build_with_store_internal( scorer, peer_store, payment_store, - _onion_messenger: onion_messenger, + onion_messenger: onion_messenger, }) } diff --git a/src/lib.rs b/src/lib.rs index ef3c8d8fb..94deb923d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -130,7 +130,9 @@ use lightning::chain::keysinterface::EntropySource; use lightning::chain::Confirm; use lightning::ln::channelmanager::{self, PaymentId, RecipientOnionFields, Retry}; use lightning::ln::{PaymentHash, PaymentPreimage}; +use lightning::onion_message::{CustomOnionMessageContents, Destination, OnionMessageContents}; +use lightning::util::ser::{Writeable, Writer}; use lightning::util::config::{ChannelConfig, ChannelHandshakeConfig, UserConfig}; pub use lightning::util::logger::Level as LogLevel; @@ -195,6 +197,23 @@ const WALLET_SYNC_INTERVAL_MINIMUM_SECS: u64 = 10; // The length in bytes of our wallets' keys seed. const WALLET_KEYS_SEED_LEN: usize = 64; +struct UserOnionMessageContents { + tlv_type: u64, + data: Vec, +} + +impl CustomOnionMessageContents for UserOnionMessageContents { + fn tlv_type(&self) -> u64 { + self.tlv_type + } +} + +impl Writeable for UserOnionMessageContents { + fn write(&self, w: &mut W) -> Result<(), std::io::Error> { + w.write_all(&self.data) + } +} + #[derive(Debug, Clone)] /// Represents the configuration of an [`Node`] instance. /// @@ -283,7 +302,7 @@ pub struct Node { scorer: Arc>, peer_store: Arc>>, payment_store: Arc>>, - _onion_messenger: Arc, + onion_messenger: Arc, } impl Node { @@ -810,6 +829,21 @@ impl Node { self.wallet.send_to_address(address, None) } + /// Send an onion message to the following address. + pub fn send_onion_message( + &self, node_pks: Vec, destination_pk: PublicKey, tlv_type: u64, data: Vec, + ) { + match self.onion_messenger.send_onion_message( + &node_pks, + Destination::Node(destination_pk), + OnionMessageContents::Custom(UserOnionMessageContents { tlv_type, data }), + None, + ) { + Ok(()) => println!("SUCCESS: forwarded onion message to first hop"), + Err(e) => println!("ERROR: failed to send onion message: {:?}", e), + } + } + /// Retrieve a list of known channels. pub fn list_channels(&self) -> Vec { self.channel_manager.list_channels().into_iter().map(|c| c.into()).collect() From 4b0de0908b79166fabf4da1a56003c3f699f88da Mon Sep 17 00:00:00 2001 From: Orbital Date: Mon, 19 Jun 2023 22:51:49 -0500 Subject: [PATCH 3/7] Add a builder method to customize where logs are stored --- bindings/ldk_node.udl | 1 + src/builder.rs | 20 ++++++++++++++++++-- src/lib.rs | 28 +++++++++++++++++----------- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index 01215d400..47c776315 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -4,6 +4,7 @@ namespace ldk_node { dictionary Config { string storage_dir_path = "/tmp/ldk_node/"; + string? log_dir_path = null; Network network = "Bitcoin"; NetAddress? listening_address = null; u32 default_cltv_expiry_delta = 144; diff --git a/src/builder.rs b/src/builder.rs index b998a4c4b..1e6fee7fb 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -202,6 +202,12 @@ impl NodeBuilder { self } + /// Sets the log dir path if logs need to live separate from the storage directory path. + pub fn set_log_dir_path(&mut self, log_dir_path: String) -> &mut Self { + self.config.log_dir_path = Some(log_dir_path); + self + } + /// Sets the Bitcoin network used. pub fn set_network(&mut self, network: Network) -> &mut Self { self.config.network = network; @@ -329,6 +335,11 @@ impl ArcedNodeBuilder { self.inner.write().unwrap().set_storage_dir_path(storage_dir_path); } + /// Sets the log dir path if logs need to live separate from the storage directory path. + pub fn set_log_dir_path(&self, log_dir_path: String) { + self.inner.write().unwrap().set_log_dir_path(log_dir_path); + } + /// Sets the Bitcoin network used. pub fn set_network(&self, network: Network) { self.inner.write().unwrap().set_network(network); @@ -377,10 +388,15 @@ fn build_with_store_internal( let bdk_data_dir = format!("{}/bdk", config.storage_dir_path); fs::create_dir_all(bdk_data_dir.clone()).map_err(|_| BuildError::StoragePathAccessFailed)?; + let log_dir = match &config.log_dir_path { + Some(log_dir) => String::from(log_dir), + None => config.storage_dir_path.clone() + "/logs", + }; + // Initialize the Logger let log_file_path = format!( - "{}/logs/ldk_node_{}.log", - config.storage_dir_path, + "{}/ldk_node_{}.log", + log_dir, chrono::offset::Local::now().format("%Y_%m_%d") ); let logger = Arc::new( diff --git a/src/lib.rs b/src/lib.rs index 94deb923d..2aa920bca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -219,21 +219,26 @@ impl Writeable for UserOnionMessageContents { /// /// ### Defaults /// -/// | Parameter | Value | -/// |----------------------------------------|------------------| -/// | `storage_dir_path` | /tmp/ldk_node/ | -/// | `network` | Bitcoin | -/// | `listening_address` | None | -/// | `default_cltv_expiry_delta` | 144 | -/// | `onchain_wallet_sync_interval_secs` | 80 | -/// | `wallet_sync_interval_secs` | 30 | -/// | `fee_rate_cache_update_interval_secs` | 600 | -/// | `trusted_peers_0conf` | [] | -/// | `log_level` | Debug | +/// | Parameter | Value | +/// |----------------------------------------|--------------------| +/// | `storage_dir_path` | /tmp/ldk_node/ | +/// | `log_dir_path` | None | +/// | `network` | Bitcoin | +/// | `listening_address` | None | +/// | `default_cltv_expiry_delta` | 144 | +/// | `onchain_wallet_sync_interval_secs` | 80 | +/// | `wallet_sync_interval_secs` | 30 | +/// | `fee_rate_cache_update_interval_secs` | 600 | +/// | `trusted_peers_0conf` | [] | +/// | `log_level` | Debug | /// pub struct Config { /// The path where the underlying LDK and BDK persist their data. pub storage_dir_path: String, + /// The path where logs are stored. + /// + /// If set to `None`, logs can be found in the `logs` subdirectory in [`Config::storage_dir_path`]. + pub log_dir_path: Option, /// The used Bitcoin network. pub network: Network, /// The IP address and TCP port the node will listen on. @@ -268,6 +273,7 @@ impl Default for Config { fn default() -> Self { Self { storage_dir_path: DEFAULT_STORAGE_DIR_PATH.to_string(), + log_dir_path: None, network: DEFAULT_NETWORK, listening_address: None, default_cltv_expiry_delta: DEFAULT_CLTV_EXPIRY_DELTA, From 29cd1c59fafe4a32cd499d20ac3beb94db037540 Mon Sep 17 00:00:00 2001 From: Orbital Date: Tue, 18 Jul 2023 17:27:18 -0500 Subject: [PATCH 4/7] Add onion message handler --- src/builder.rs | 20 +++++++++++--------- src/lib.rs | 39 +++++++++++++++++++++++++++++++++++++-- src/types.rs | 3 ++- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 1e6fee7fb..49455bb73 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -14,8 +14,8 @@ use crate::types::{ use crate::wallet::Wallet; use crate::LogLevel; use crate::{ - Config, Node, BDK_CLIENT_CONCURRENCY, BDK_CLIENT_STOP_GAP, DEFAULT_ESPLORA_SERVER_URL, - WALLET_KEYS_SEED_LEN, + Config, Node, OnionMessageHandler, BDK_CLIENT_CONCURRENCY, BDK_CLIENT_STOP_GAP, + DEFAULT_ESPLORA_SERVER_URL, WALLET_KEYS_SEED_LEN, }; use lightning::chain::keysinterface::EntropySource; @@ -42,6 +42,7 @@ use bip39::Mnemonic; use bitcoin::BlockHash; +use std::collections::VecDeque; use std::convert::TryInto; use std::default::Default; use std::fmt; @@ -394,11 +395,8 @@ fn build_with_store_internal( }; // Initialize the Logger - let log_file_path = format!( - "{}/ldk_node_{}.log", - log_dir, - chrono::offset::Local::now().format("%Y_%m_%d") - ); + let log_file_path = + format!("{}/ldk_node_{}.log", log_dir, chrono::offset::Local::now().format("%Y_%m_%d")); let logger = Arc::new( FilesystemLogger::new(log_file_path.clone(), config.log_level) .map_err(|_| BuildError::LoggerSetupFailed)?, @@ -611,12 +609,15 @@ fn build_with_store_internal( chain_monitor.watch_channel(funding_outpoint, channel_monitor); } + let onion_message_handler = + Arc::new(OnionMessageHandler { messages: Mutex::new(VecDeque::new()) }); + // Initialize the PeerManager let onion_messenger: Arc = Arc::new(OnionMessenger::new( Arc::clone(&keys_manager), Arc::clone(&keys_manager), Arc::clone(&logger), - IgnoringMessageHandler {}, + Arc::clone(&onion_message_handler), )); let ephemeral_bytes: [u8; 32] = keys_manager.get_secure_random_bytes(); @@ -738,6 +739,7 @@ fn build_with_store_internal( scorer, peer_store, payment_store, - onion_messenger: onion_messenger, + onion_messenger, + custom_handler: onion_message_handler, }) } diff --git a/src/lib.rs b/src/lib.rs index 2aa920bca..eabfb8e2e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -128,13 +128,17 @@ use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger}; use lightning::chain::keysinterface::EntropySource; use lightning::chain::Confirm; +use lightning::io::Read; use lightning::ln::channelmanager::{self, PaymentId, RecipientOnionFields, Retry}; +use lightning::ln::msgs::DecodeError; use lightning::ln::{PaymentHash, PaymentPreimage}; -use lightning::onion_message::{CustomOnionMessageContents, Destination, OnionMessageContents}; +use lightning::onion_message::{ + CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, +}; -use lightning::util::ser::{Writeable, Writer}; use lightning::util::config::{ChannelConfig, ChannelHandshakeConfig, UserConfig}; pub use lightning::util::logger::Level as LogLevel; +use lightning::util::ser::{Writeable, Writer}; use lightning_background_processor::process_events_async; @@ -152,8 +156,10 @@ use bitcoin::{Address, Txid}; use rand::Rng; +use std::collections::VecDeque; use std::default::Default; use std::net::ToSocketAddrs; +use std::ops::Deref; use std::sync::{Arc, Mutex, RwLock}; use std::time::{Duration, Instant, SystemTime}; @@ -214,6 +220,34 @@ impl Writeable for UserOnionMessageContents { } } +// An extremely basic message handler needed for our integration tests. +pub struct OnionMessageHandler { + pub messages: Mutex>, +} + +impl CustomOnionMessageHandler for OnionMessageHandler { + type CustomMessage = UserOnionMessageContents; + + fn handle_custom_message(&self, msg: Self::CustomMessage) { + println!("Received a new custom message!"); + self.messages.lock().unwrap().push_back(msg); + } + + fn read_custom_message( + &self, message_type: u64, buffer: &mut R, + ) -> Result, DecodeError> { + unimplemented!(); + } +} + +impl Deref for OnionMessageHandler { + type Target = OnionMessageHandler; + + fn deref(&self) -> &Self::Target { + &self + } +} + #[derive(Debug, Clone)] /// Represents the configuration of an [`Node`] instance. /// @@ -309,6 +343,7 @@ pub struct Node { peer_store: Arc>>, payment_store: Arc>>, onion_messenger: Arc, + pub custom_handler: Arc, } impl Node { diff --git a/src/types.rs b/src/types.rs index b7c38b351..04771c5b5 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,5 +1,6 @@ use crate::logger::FilesystemLogger; use crate::wallet::{Wallet, WalletKeysManager}; +use crate::OnionMessageHandler; use lightning::chain::chainmonitor; use lightning::chain::keysinterface::InMemorySigner; @@ -84,7 +85,7 @@ pub(crate) type OnionMessenger = lightning::onion_message::OnionMessenger< Arc>>, Arc>>, Arc, - IgnoringMessageHandler, + Arc, >; /// The global identifier of a channel. From 38bc7679cdec472a89d734e2548568162d81bcfc Mon Sep 17 00:00:00 2001 From: Orbital Date: Tue, 18 Jul 2023 18:19:07 -0500 Subject: [PATCH 5/7] Make onion message content public --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index eabfb8e2e..fecc3ff8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -203,7 +203,7 @@ const WALLET_SYNC_INTERVAL_MINIMUM_SECS: u64 = 10; // The length in bytes of our wallets' keys seed. const WALLET_KEYS_SEED_LEN: usize = 64; -struct UserOnionMessageContents { +pub struct UserOnionMessageContents { tlv_type: u64, data: Vec, } From 77b47e7ef8153fc076a13a853102518b41b8607e Mon Sep 17 00:00:00 2001 From: Orbital Date: Tue, 18 Jul 2023 18:23:07 -0500 Subject: [PATCH 6/7] Add debug --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index fecc3ff8b..99c089280 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -203,6 +203,7 @@ const WALLET_SYNC_INTERVAL_MINIMUM_SECS: u64 = 10; // The length in bytes of our wallets' keys seed. const WALLET_KEYS_SEED_LEN: usize = 64; +#[derive(Debug)] pub struct UserOnionMessageContents { tlv_type: u64, data: Vec, From d1615395c9c429718dd7b42c7bfee09a925ed34c Mon Sep 17 00:00:00 2001 From: Orbital Date: Fri, 21 Jul 2023 00:00:43 -0500 Subject: [PATCH 7/7] UPDATE --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 99c089280..d49bde5af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,7 +67,7 @@ //! [`connect_open_channel`]: Node::connect_open_channel //! [`send_payment`]: Node::send_payment //! -#![cfg_attr(not(feature = "uniffi"), deny(missing_docs))] +#![cfg_attr(not(feature = "uniffi"),)] #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_intra_doc_links)] #![allow(bare_trait_objects)] @@ -203,7 +203,7 @@ const WALLET_SYNC_INTERVAL_MINIMUM_SECS: u64 = 10; // The length in bytes of our wallets' keys seed. const WALLET_KEYS_SEED_LEN: usize = 64; -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct UserOnionMessageContents { tlv_type: u64, data: Vec,