Skip to content

Commit ff741c2

Browse files
authored
Merge branch 'main' into add-probing-service
2 parents 3bd8a6f + a555133 commit ff741c2

File tree

12 files changed

+379
-117
lines changed

12 files changed

+379
-117
lines changed

Cargo.toml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ default = []
3939
#lightning-liquidity = { version = "0.2.0", features = ["std"] }
4040
#lightning-macros = { version = "0.2.0" }
4141

42-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245", features = ["std"] }
43-
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245" }
44-
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245", features = ["std"] }
45-
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245" }
46-
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245", features = ["tokio"] }
47-
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245" }
48-
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245" }
49-
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245", features = ["rest-client", "rpc-client", "tokio"] }
50-
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
51-
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245", features = ["std"] }
52-
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245" }
42+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953", features = ["std"] }
43+
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953" }
44+
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953", features = ["std"] }
45+
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953" }
46+
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953", features = ["tokio"] }
47+
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953" }
48+
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953" }
49+
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953", features = ["rest-client", "rpc-client", "tokio"] }
50+
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
51+
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953", features = ["std"] }
52+
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953" }
5353

5454
bdk_chain = { version = "0.23.0", default-features = false, features = ["std"] }
5555
bdk_esplora = { version = "0.22.0", default-features = false, features = ["async-https-rustls", "tokio"]}
@@ -79,13 +79,13 @@ async-trait = { version = "0.1", default-features = false }
7979
vss-client = { package = "vss-client-ng", version = "0.5" }
8080
prost = { version = "0.11.6", default-features = false}
8181
#bitcoin-payment-instructions = { version = "0.6" }
82-
bitcoin-payment-instructions = { git = "https://github.com/jkczyz/bitcoin-payment-instructions", rev = "869fd348c3ca0c78f439d2f31181f4d798c6b20e" }
82+
bitcoin-payment-instructions = { git = "https://github.com/tnull/bitcoin-payment-instructions", rev = "e9d7c07d7affc7714b023c853a65771e45277467" }
8383

8484
[target.'cfg(windows)'.dependencies]
8585
winapi = { version = "0.3", features = ["winbase"] }
8686

8787
[dev-dependencies]
88-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "98501d6e5134228c41460dcf786ab53337e41245", features = ["std", "_test_utils"] }
88+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "49912057895ddfbd69d503de67c80d5576c09953", features = ["std", "_test_utils"] }
8989
rand = { version = "0.9.2", default-features = false, features = ["std", "thread_rng", "os_rng"] }
9090
proptest = "1.0.0"
9191
regex = "1.5.6"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ fn main() {
2727
builder.set_network(Network::Testnet);
2828
builder.set_chain_source_esplora("https://blockstream.info/testnet/api".to_string(), None);
2929
builder.set_gossip_source_rgs(
30-
"https://rapidsync.lightningdevkit.org/testnet/snapshot".to_string(),
30+
"https://rapidsync.lightningdevkit.org/testnet/v2/snapshot".to_string(),
3131
);
3232

3333

bindings/ldk_node.udl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ typedef dictionary EsploraSyncConfig;
99

1010
typedef dictionary ElectrumSyncConfig;
1111

12+
typedef dictionary TorConfig;
13+
1214
typedef interface NodeEntropy;
1315

1416
typedef enum WordCount;
@@ -53,6 +55,8 @@ interface Builder {
5355
[Throws=BuildError]
5456
void set_announcement_addresses(sequence<SocketAddress> announcement_addresses);
5557
[Throws=BuildError]
58+
void set_tor_config(TorConfig tor_config);
59+
[Throws=BuildError]
5660
void set_node_alias(string node_alias);
5761
[Throws=BuildError]
5862
void set_async_payments_role(AsyncPaymentsRole? role);
@@ -296,6 +300,7 @@ dictionary LSPS1ChannelInfo {
296300
[Remote]
297301
enum LSPS1PaymentState {
298302
"ExpectPayment",
303+
"Hold",
299304
"Paid",
300305
"Refunded",
301306
};

src/builder.rs

Lines changed: 118 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use vss_client::headers::VssHeaderProvider;
4646
use crate::chain::ChainSource;
4747
use crate::config::{
4848
default_user_config, may_announce_channel, AnnounceError, AsyncPaymentsRole,
49-
BitcoindRestClientConfig, Config, ElectrumSyncConfig, EsploraSyncConfig,
49+
BitcoindRestClientConfig, Config, ElectrumSyncConfig, EsploraSyncConfig, TorConfig,
5050
DEFAULT_ESPLORA_SERVER_URL, DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL,
5151
DEFAULT_MAX_PROBE_AMOUNT_MSAT, DEFAULT_MAX_PROBE_LOCKED_MSAT, DEFAULT_PROBING_INTERVAL_SECS,
5252
MIN_PROBE_AMOUNT_MSAT,
@@ -201,6 +201,8 @@ pub enum BuildError {
201201
InvalidListeningAddresses,
202202
/// The given announcement addresses are invalid, e.g. too many were passed.
203203
InvalidAnnouncementAddresses,
204+
/// The given tor proxy address is invalid, e.g. an onion address was passed.
205+
InvalidTorProxyAddress,
204206
/// The provided alias is invalid.
205207
InvalidNodeAlias,
206208
/// An attempt to setup a runtime has failed.
@@ -242,6 +244,7 @@ impl fmt::Display for BuildError {
242244
Self::InvalidAnnouncementAddresses => {
243245
write!(f, "Given announcement addresses are invalid.")
244246
},
247+
Self::InvalidTorProxyAddress => write!(f, "Given Tor proxy address is invalid."),
245248
Self::RuntimeSetupFailed => write!(f, "Failed to setup a runtime."),
246249
Self::ReadFailed => write!(f, "Failed to read from store."),
247250
Self::WriteFailed => write!(f, "Failed to write to store."),
@@ -269,9 +272,40 @@ impl std::error::Error for BuildError {}
269272
/// the getgo.
270273
///
271274
/// ### Defaults
272-
/// - Wallet entropy is sourced from a `keys_seed` file located under [`Config::storage_dir_path`]
275+
/// - See [`Config`] for the default values of all configuration options.
273276
/// - Chain data is sourced from the Esplora endpoint `https://blockstream.info/api`
274277
/// - Gossip data is sourced via the peer-to-peer network
278+
/// - Logs are written to the filesystem (see [Logging] below)
279+
///
280+
/// ### Storage
281+
///
282+
/// Several `build` methods are available depending on the desired storage backend:
283+
/// - [`build`] uses an SQLite database (recommended default).
284+
/// - [`build_with_fs_store`] uses a filesystem-based store.
285+
/// - [`build_with_vss_store`] and variants use a [VSS] remote store (**experimental**).
286+
/// - [`build_with_store`] allows providing a custom [`KVStore`] implementation.
287+
///
288+
/// ### Logging
289+
///
290+
/// By default, logs are written to the filesystem via an internal file logger at
291+
/// [`DEFAULT_LOG_LEVEL`]. The log file path and level can be customized via
292+
/// [`set_filesystem_logger`].
293+
///
294+
/// Alternatively, logs can be written to the [`log`] facade via [`set_log_facade_logger`], or to
295+
/// a custom [`LogWriter`] via [`set_custom_logger`].
296+
///
297+
/// [`build`]: Self::build
298+
/// [`build_with_fs_store`]: Self::build_with_fs_store
299+
/// [`build_with_vss_store`]: Self::build_with_vss_store
300+
/// [`build_with_store`]: Self::build_with_store
301+
/// [VSS]: https://github.com/lightningdevkit/vss-server/blob/main/README.md
302+
/// [`KVStore`]: lightning::util::persist::KVStore
303+
/// [`DEFAULT_LOG_LEVEL`]: crate::config::DEFAULT_LOG_LEVEL
304+
/// [`set_filesystem_logger`]: Self::set_filesystem_logger
305+
/// [`set_log_facade_logger`]: Self::set_log_facade_logger
306+
/// [`set_custom_logger`]: Self::set_custom_logger
307+
/// [`log`]: https://crates.io/crates/log
308+
/// [Logging]: #logging
275309
#[derive(Debug)]
276310
pub struct NodeBuilder {
277311
config: Config,
@@ -512,6 +546,10 @@ impl NodeBuilder {
512546
/// If set, the `max_log_level` sets the maximum log level. Otherwise, the latter defaults to
513547
/// [`DEFAULT_LOG_LEVEL`].
514548
///
549+
/// **Note:** Log rotation and pruning are the responsibility of the user and are not handled
550+
/// internally. For example, UNIX system tooling such as `logrotate` and `cron` can be used to
551+
/// manage log file sizes and retention.
552+
///
515553
/// [`DEFAULT_LOG_FILENAME`]: crate::config::DEFAULT_LOG_FILENAME
516554
pub fn set_filesystem_logger(
517555
&mut self, log_file_path: Option<String>, max_log_level: Option<LogLevel>,
@@ -566,6 +604,23 @@ impl NodeBuilder {
566604
Ok(self)
567605
}
568606

607+
/// Configures the [`Node`] instance to use a Tor SOCKS proxy for outbound connections to peers with OnionV3 addresses.
608+
/// Connections to clearnet addresses are not affected, and are not made over Tor.
609+
/// The proxy address must not itself be an onion address.
610+
///
611+
/// **Note**: If unset, connecting to peer OnionV3 addresses will fail.
612+
pub fn set_tor_config(&mut self, tor_config: TorConfig) -> Result<&mut Self, BuildError> {
613+
match tor_config.proxy_address {
614+
SocketAddress::OnionV2 { .. } | SocketAddress::OnionV3 { .. } => {
615+
return Err(BuildError::InvalidTorProxyAddress);
616+
},
617+
_ => {},
618+
}
619+
620+
self.config.tor_config = Some(tor_config);
621+
Ok(self)
622+
}
623+
569624
/// Sets the node alias that will be used when broadcasting announcements to the gossip
570625
/// network.
571626
///
@@ -870,9 +925,41 @@ impl NodeBuilder {
870925
/// the getgo.
871926
///
872927
/// ### Defaults
873-
/// - Wallet entropy is sourced from a `keys_seed` file located under [`Config::storage_dir_path`]
928+
/// - See [`Config`] for the default values of all configuration options.
874929
/// - Chain data is sourced from the Esplora endpoint `https://blockstream.info/api`
875930
/// - Gossip data is sourced via the peer-to-peer network
931+
/// - Logs are written to the filesystem (see [Logging] below)
932+
///
933+
/// ### Storage
934+
///
935+
/// Several `build` methods are available depending on the desired storage backend:
936+
/// - [`build`] uses an SQLite database (recommended default).
937+
/// - [`build_with_fs_store`] uses a filesystem-based store.
938+
/// - [`build_with_vss_store`] and variants use a [VSS] remote store (**experimental**).
939+
/// - [`build_with_store`] allows providing a custom [`KVStore`] implementation.
940+
///
941+
/// ### Logging
942+
///
943+
/// By default, logs are written to the filesystem via an internal file logger at
944+
/// [`DEFAULT_LOG_LEVEL`]. The log file path and level can be customized via
945+
/// [`set_filesystem_logger`].
946+
///
947+
/// Alternatively, logs can be written to the [`log`] facade via [`set_log_facade_logger`], or to
948+
/// a custom [`LogWriter`] via [`set_custom_logger`].
949+
///
950+
/// [`build`]: Self::build
951+
/// [`build_with_fs_store`]: Self::build_with_fs_store
952+
/// [`build_with_vss_store`]: Self::build_with_vss_store
953+
/// [`build_with_store`]: Self::build_with_store
954+
/// [VSS]: https://github.com/lightningdevkit/vss-server/blob/main/README.md
955+
/// [`KVStore`]: lightning::util::persist::KVStore
956+
/// [`DEFAULT_LOG_LEVEL`]: crate::config::DEFAULT_LOG_LEVEL
957+
/// [`set_filesystem_logger`]: Self::set_filesystem_logger
958+
/// [`set_log_facade_logger`]: Self::set_log_facade_logger
959+
/// [`set_custom_logger`]: Self::set_custom_logger
960+
/// [`log`]: https://crates.io/crates/log
961+
/// [Logging]: #logging
962+
/// [Storage]: #storage
876963
#[derive(Debug)]
877964
#[cfg(feature = "uniffi")]
878965
pub struct ArcedNodeBuilder {
@@ -1043,6 +1130,10 @@ impl ArcedNodeBuilder {
10431130
/// If set, the `max_log_level` sets the maximum log level. Otherwise, the latter defaults to
10441131
/// [`DEFAULT_LOG_LEVEL`].
10451132
///
1133+
/// **Note:** Log rotation and pruning are the responsibility of the user and are not handled
1134+
/// internally. For example, UNIX system tooling such as `logrotate` and `cron` can be used to
1135+
/// manage log file sizes and retention.
1136+
///
10461137
/// [`DEFAULT_LOG_FILENAME`]: crate::config::DEFAULT_LOG_FILENAME
10471138
pub fn set_filesystem_logger(
10481139
&self, log_file_path: Option<String>, log_level: Option<LogLevel>,
@@ -1083,6 +1174,15 @@ impl ArcedNodeBuilder {
10831174
self.inner.write().unwrap().set_announcement_addresses(announcement_addresses).map(|_| ())
10841175
}
10851176

1177+
/// Configures the [`Node`] instance to use a Tor SOCKS proxy for outbound connections to peers with OnionV3 addresses.
1178+
/// Connections to clearnet addresses are not affected, and are not made over Tor.
1179+
/// The proxy address must not itself be an onion address.
1180+
///
1181+
/// **Note**: If unset, connecting to peer OnionV3 addresses will fail.
1182+
pub fn set_tor_config(&self, tor_config: TorConfig) -> Result<(), BuildError> {
1183+
self.inner.write().unwrap().set_tor_config(tor_config).map(|_| ())
1184+
}
1185+
10861186
/// Sets the node alias that will be used when broadcasting announcements to the gossip
10871187
/// network.
10881188
///
@@ -1278,6 +1378,15 @@ fn build_with_store_internal(
12781378
}
12791379
}
12801380

1381+
if let Some(tor_config) = &config.tor_config {
1382+
match tor_config.proxy_address {
1383+
SocketAddress::OnionV2 { .. } | SocketAddress::OnionV3 { .. } => {
1384+
return Err(BuildError::InvalidTorProxyAddress);
1385+
},
1386+
_ => {},
1387+
}
1388+
}
1389+
12811390
let tx_broadcaster = Arc::new(TransactionBroadcaster::new(Arc::clone(&logger)));
12821391
let fee_estimator = Arc::new(OnchainFeeEstimator::new());
12831392

@@ -1822,7 +1931,6 @@ fn build_with_store_internal(
18221931
Arc::clone(&wallet),
18231932
Arc::clone(&channel_manager),
18241933
Arc::clone(&keys_manager),
1825-
Arc::clone(&chain_source),
18261934
Arc::clone(&tx_broadcaster),
18271935
Arc::clone(&kv_store),
18281936
Arc::clone(&config),
@@ -1914,8 +2022,12 @@ fn build_with_store_internal(
19142022

19152023
liquidity_source.as_ref().map(|l| l.set_peer_manager(Arc::downgrade(&peer_manager)));
19162024

1917-
let connection_manager =
1918-
Arc::new(ConnectionManager::new(Arc::clone(&peer_manager), Arc::clone(&logger)));
2025+
let connection_manager = Arc::new(ConnectionManager::new(
2026+
Arc::clone(&peer_manager),
2027+
config.tor_config.clone(),
2028+
Arc::clone(&keys_manager),
2029+
Arc::clone(&logger),
2030+
));
19192031

19202032
let output_sweeper = match sweeper_bytes_res {
19212033
Ok(output_sweeper) => Arc::new(output_sweeper),

src/config.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,15 @@ pub(crate) const LNURL_AUTH_TIMEOUT_SECS: u64 = 15;
123123
/// | Parameter | Value |
124124
/// |----------------------------------------|--------------------|
125125
/// | `storage_dir_path` | /tmp/ldk_node/ |
126-
/// | `log_dir_path` | None |
127126
/// | `network` | Bitcoin |
128127
/// | `listening_addresses` | None |
128+
/// | `announcement_addresses` | None |
129129
/// | `node_alias` | None |
130-
/// | `default_cltv_expiry_delta` | 144 |
131-
/// | `onchain_wallet_sync_interval_secs` | 80 |
132-
/// | `wallet_sync_interval_secs` | 30 |
133-
/// | `fee_rate_cache_update_interval_secs` | 600 |
134130
/// | `trusted_peers_0conf` | [] |
135131
/// | `probing_liquidity_limit_multiplier` | 3 |
136-
/// | `log_level` | Debug |
137132
/// | `anchor_channels_config` | Some(..) |
138-
/// | `route_parameters` | None |
133+
/// | `route_parameters` | None |
134+
/// | `tor_config` | None |
139135
///
140136
/// See [`AnchorChannelsConfig`] and [`RouteParametersConfig`] for more information regarding their
141137
/// respective default values.
@@ -200,6 +196,13 @@ pub struct Config {
200196
/// **Note:** If unset, default parameters will be used, and you will be able to override the
201197
/// parameters on a per-payment basis in the corresponding method calls.
202198
pub route_parameters: Option<RouteParametersConfig>,
199+
/// Configuration options for enabling peer connections via the Tor network.
200+
///
201+
/// Setting [`TorConfig`] enables connecting to peers with OnionV3 addresses. No other connections
202+
/// are routed via Tor. Please refer to [`TorConfig`] for further information.
203+
///
204+
/// **Note**: If unset, connecting to peer OnionV3 addresses will fail.
205+
pub tor_config: Option<TorConfig>,
203206
}
204207

205208
impl Default for Config {
@@ -212,6 +215,7 @@ impl Default for Config {
212215
trusted_peers_0conf: Vec::new(),
213216
probing_liquidity_limit_multiplier: DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER,
214217
anchor_channels_config: Some(AnchorChannelsConfig::default()),
218+
tor_config: None,
215219
route_parameters: None,
216220
node_alias: None,
217221
}
@@ -268,7 +272,7 @@ pub struct AnchorChannelsConfig {
268272
/// [`AnchorChannelsConfig::trusted_peers_no_reserve`], we will always try to spend the Anchor
269273
/// outputs with *any* on-chain funds available, i.e., the total reserve value as well as any
270274
/// spendable funds available in the on-chain wallet. Therefore, this per-channel multiplier is
271-
/// really a emergency reserve that we maintain at all time to reduce reduce the risk of
275+
/// really an emergency reserve that we maintain at all time to reduce the risk of
272276
/// insufficient funds at time of a channel closure. To this end, we will refuse to open
273277
/// outbound or accept inbound channels if we don't have sufficient on-chain funds available to
274278
/// cover the additional reserve requirement.
@@ -491,6 +495,16 @@ pub struct BitcoindRestClientConfig {
491495
pub rest_port: u16,
492496
}
493497

498+
/// Configuration for connecting to peers via the Tor Network.
499+
#[derive(Debug, Clone)]
500+
#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
501+
pub struct TorConfig {
502+
/// Tor daemon SOCKS proxy address. Only connections to OnionV3 peers will be made
503+
/// via this proxy; other connections (IPv4 peers, Electrum server) will not be
504+
/// routed over Tor.
505+
pub proxy_address: SocketAddress,
506+
}
507+
494508
/// Options which apply on a per-channel basis and may change at runtime or based on negotiation
495509
/// with our counterparty.
496510
#[derive(Copy, Clone, Debug, PartialEq, Eq)]

0 commit comments

Comments
 (0)