From 1514d33862e40110c4b93426cfc02fac499e66d8 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Mon, 23 Sep 2024 17:13:20 +0700 Subject: [PATCH 1/7] feat: get encoded channel monitors --- bindings/ldk_node.udl | 7 +++++++ src/lib.rs | 25 ++++++++++++++++++++++++- src/types.rs | 9 +++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index 50c3cc704..8b01e79cd 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -90,6 +90,8 @@ interface Node { [Throws=NodeError] string sign_message([ByRef]sequence msg); boolean verify_signature([ByRef]sequence msg, [ByRef]string sig, [ByRef]PublicKey pkey); + [Throws=NodeError] + sequence get_encoded_channel_monitors(); }; interface Bolt11Payment { @@ -424,6 +426,11 @@ dictionary TlvEntry { sequence value; }; +dictionary KeyValue { + string key; + sequence value; +}; + interface NetworkGraph { sequence list_channels(); ChannelInfo? channel(u64 short_channel_id); diff --git a/src/lib.rs b/src/lib.rs index 030b31cff..2475828b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -140,7 +140,7 @@ use types::{ Broadcaster, BumpTransactionEventHandler, ChainMonitor, ChannelManager, DynStore, FeeEstimator, Graph, KeysManager, PeerManager, Router, Scorer, Sweeper, Wallet, }; -pub use types::{ChannelDetails, ChannelType, PeerDetails, TlvEntry, UserChannelId}; +pub use types::{ChannelDetails, ChannelType, KeyValue, PeerDetails, TlvEntry, UserChannelId}; use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger}; @@ -1539,6 +1539,29 @@ impl Node { self.payment_store.remove(&payment_id) } + /// Alby: Return encoded channel monitors for a recovery of last resort + pub fn get_encoded_channel_monitors(&self) -> Result, Error> { + let channel_monitor_store = Arc::clone(&self.kv_store); + let channel_monitor_logger = Arc::clone(&self.logger); + // TODO: error handling + let keys = channel_monitor_store.list("monitors", "").unwrap_or_else(|e| { + log_error!(channel_monitor_logger, "Failed to get monitor keys: {}", e); + return Vec::new(); + }); + let mut entries = Vec::new(); + + for key in keys { + // TODO: error handling + let value = channel_monitor_store.read("monitors", "", &key).unwrap_or_else(|e| { + log_error!(channel_monitor_logger, "Failed to get monitor value: {}", e); + return Vec::new(); + }); + entries.push(KeyValue { key, value }) + } + + return Ok(entries); + } + /// Retrieves an overview of all known balances. pub fn list_balances(&self) -> BalanceDetails { let cur_anchor_reserve_sats = diff --git a/src/types.rs b/src/types.rs index 151de9c38..5f9814cb0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -492,3 +492,12 @@ impl_writeable_tlv_based!(TlvEntry, { (0, r#type, required), (1, value, required), }); + +/// KeyValue from LDK node DB +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct KeyValue { + /// Key. + pub key: String, + /// Serialized value. + pub value: Vec, +} From eab0e5b488062d3339b8a87913ad895b1585dbf7 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Tue, 24 Sep 2024 11:22:16 +0700 Subject: [PATCH 2/7] feat: add force close all channels function, add error handling to get_encoded_channel_monitors --- bindings/ldk_node.udl | 1 + src/lib.rs | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index 8b01e79cd..ca8c12f30 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -92,6 +92,7 @@ interface Node { boolean verify_signature([ByRef]sequence msg, [ByRef]string sig, [ByRef]PublicKey pkey); [Throws=NodeError] sequence get_encoded_channel_monitors(); + void force_close_all_channels_without_broadcasting_txn(); }; interface Bolt11Payment { diff --git a/src/lib.rs b/src/lib.rs index 2475828b3..219d21ded 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1539,23 +1539,28 @@ impl Node { self.payment_store.remove(&payment_id) } + /// Alby: Used to recover funds after restoring static channel backup + pub fn force_close_all_channels_without_broadcasting_txn(&self) { + self.channel_manager.force_close_all_channels_without_broadcasting_txn(); + } + /// Alby: Return encoded channel monitors for a recovery of last resort pub fn get_encoded_channel_monitors(&self) -> Result, Error> { let channel_monitor_store = Arc::clone(&self.kv_store); let channel_monitor_logger = Arc::clone(&self.logger); - // TODO: error handling - let keys = channel_monitor_store.list("monitors", "").unwrap_or_else(|e| { + let keys = channel_monitor_store.list("monitors", "").map_err(|e| { log_error!(channel_monitor_logger, "Failed to get monitor keys: {}", e); - return Vec::new(); - }); + Error::ConnectionFailed + })?; + let mut entries = Vec::new(); for key in keys { // TODO: error handling - let value = channel_monitor_store.read("monitors", "", &key).unwrap_or_else(|e| { + let value = channel_monitor_store.read("monitors", "", &key).map_err(|e| { log_error!(channel_monitor_logger, "Failed to get monitor value: {}", e); - return Vec::new(); - }); + Error::ConnectionFailed + })?; entries.push(KeyValue { key, value }) } From e863459f39d92858d8d156da29eaca5fcbc18757 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Tue, 24 Sep 2024 12:40:37 +0700 Subject: [PATCH 3/7] feat: restore encoded channel monitors --- bindings/ldk_node.udl | 2 ++ src/lib.rs | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index ca8c12f30..4b69fd032 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -92,6 +92,8 @@ interface Node { boolean verify_signature([ByRef]sequence msg, [ByRef]string sig, [ByRef]PublicKey pkey); [Throws=NodeError] sequence get_encoded_channel_monitors(); + [Throws=NodeError] + void restore_encoded_channel_monitors(sequence monitors); void force_close_all_channels_without_broadcasting_txn(); }; diff --git a/src/lib.rs b/src/lib.rs index 219d21ded..d12c4f50b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1556,7 +1556,6 @@ impl Node { let mut entries = Vec::new(); for key in keys { - // TODO: error handling let value = channel_monitor_store.read("monitors", "", &key).map_err(|e| { log_error!(channel_monitor_logger, "Failed to get monitor value: {}", e); Error::ConnectionFailed @@ -1567,6 +1566,23 @@ impl Node { return Ok(entries); } + /// Alby: Restore encoded channel monitors for a recovery of last resort + pub fn restore_encoded_channel_monitors(&self, monitors: Vec) -> Result<(), Error> { + let channel_monitor_store = Arc::clone(&self.kv_store); + let channel_monitor_logger = Arc::clone(&self.logger); + + for monitor in monitors { + channel_monitor_store.write("monitors", "", &monitor.key, &monitor.value).map_err( + |e| { + log_error!(channel_monitor_logger, "Failed to restore monitor: {}", e); + Error::ConnectionFailed + }, + )?; + } + + return Ok(()); + } + /// Retrieves an overview of all known balances. pub fn list_balances(&self) -> BalanceDetails { let cur_anchor_reserve_sats = From 227c447da83ad9035d82ce19d7eca4c2abb08582 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Tue, 24 Sep 2024 13:52:19 +0700 Subject: [PATCH 4/7] chore: move restoring monitors to node builder --- bindings/ldk_node.udl | 3 +-- src/builder.rs | 30 ++++++++++++++++++++++++++++-- src/lib.rs | 17 ----------------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index 4b69fd032..463277571 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -43,6 +43,7 @@ interface Builder { Node build(); [Throws=BuildError] Node build_with_fs_store(); + void restore_encoded_channel_monitors(sequence monitors); }; interface Node { @@ -92,8 +93,6 @@ interface Node { boolean verify_signature([ByRef]sequence msg, [ByRef]string sig, [ByRef]PublicKey pkey); [Throws=NodeError] sequence get_encoded_channel_monitors(); - [Throws=NodeError] - void restore_encoded_channel_monitors(sequence monitors); void force_close_all_channels_without_broadcasting_txn(); }; diff --git a/src/builder.rs b/src/builder.rs index 56f3f3730..ad2c38c7a 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -15,8 +15,8 @@ use crate::payment::store::PaymentStore; use crate::peer_store::PeerStore; use crate::tx_broadcaster::TransactionBroadcaster; use crate::types::{ - ChainMonitor, ChannelManager, DynStore, GossipSync, Graph, KeysManager, MessageRouter, - OnionMessenger, PeerManager, + ChainMonitor, ChannelManager, DynStore, GossipSync, Graph, KeyValue, KeysManager, + MessageRouter, OnionMessenger, PeerManager, }; use crate::wallet::Wallet; use crate::{LogLevel, Node}; @@ -172,6 +172,7 @@ pub struct NodeBuilder { chain_data_source_config: Option, gossip_source_config: Option, liquidity_source_config: Option, + monitors_to_restore: Option>, } impl NodeBuilder { @@ -187,15 +188,23 @@ impl NodeBuilder { let chain_data_source_config = None; let gossip_source_config = None; let liquidity_source_config = None; + let monitors_to_restore = None; Self { config, entropy_source_config, chain_data_source_config, gossip_source_config, liquidity_source_config, + monitors_to_restore, } } + /// Alby: set monitors to restore when restoring SCB + pub fn restore_encoded_channel_monitors(&mut self, monitors: Vec) -> &mut Self { + self.monitors_to_restore = Some(monitors); + self + } + /// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk. /// /// If the given file does not exist a new random seed file will be generated and @@ -316,6 +325,7 @@ impl NodeBuilder { ) .map_err(|_| BuildError::KVStoreSetupFailed)?, ); + self.build_with_store(kv_store) } @@ -381,6 +391,17 @@ impl NodeBuilder { )?; let config = Arc::new(self.config.clone()); + // Alby: Restore encoded channel monitors for a recovery of last resort + if self.monitors_to_restore.is_some() { + let monitors = self.monitors_to_restore.clone().unwrap(); + for monitor in monitors { + let result = kv_store.write("monitors", "", &monitor.key, &monitor.value); + if result.is_err() { + log_error!(logger, "Failed to restore monitor: {}", result.unwrap_err()); + } + } + } + build_with_store_internal( config, self.chain_data_source_config.as_ref(), @@ -420,6 +441,11 @@ impl ArcedNodeBuilder { Self { inner } } + /// Alby: set monitors to restore when restoring SCB + pub fn restore_encoded_channel_monitors(&self, monitors: Vec) { + self.inner.write().unwrap().restore_encoded_channel_monitors(monitors); + } + /// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk. /// /// If the given file does not exist a new random seed file will be generated and diff --git a/src/lib.rs b/src/lib.rs index d12c4f50b..9db31e572 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1566,23 +1566,6 @@ impl Node { return Ok(entries); } - /// Alby: Restore encoded channel monitors for a recovery of last resort - pub fn restore_encoded_channel_monitors(&self, monitors: Vec) -> Result<(), Error> { - let channel_monitor_store = Arc::clone(&self.kv_store); - let channel_monitor_logger = Arc::clone(&self.logger); - - for monitor in monitors { - channel_monitor_store.write("monitors", "", &monitor.key, &monitor.value).map_err( - |e| { - log_error!(channel_monitor_logger, "Failed to restore monitor: {}", e); - Error::ConnectionFailed - }, - )?; - } - - return Ok(()); - } - /// Retrieves an overview of all known balances. pub fn list_balances(&self) -> BalanceDetails { let cur_anchor_reserve_sats = From 9af682361417821d0be7e75e166c9c2e247971db Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Tue, 24 Sep 2024 14:25:05 +0700 Subject: [PATCH 5/7] chore: try to fix build --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 46bb48143..7202784e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,9 @@ categories = ["cryptography::cryptocurrencies"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(vss)'] } + [lib] crate-type = ["lib", "staticlib", "cdylib"] name = "ldk_node" From d7d509418b8a79f93e183204d1a57907fc42f2eb Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Tue, 24 Sep 2024 14:26:01 +0700 Subject: [PATCH 6/7] chore: try to fix build --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7202784e0..37c9190a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ categories = ["cryptography::cryptocurrencies"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(vss)'] } +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(vss)', 'cfg(vss_test)'] } [lib] crate-type = ["lib", "staticlib", "cdylib"] From b9b59d05cb937fbba16f3d110c8b81d5fbeb0520 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Tue, 24 Sep 2024 14:32:16 +0700 Subject: [PATCH 7/7] chore: undo cargo.toml changes --- Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 37c9190a4..46bb48143 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,9 +13,6 @@ categories = ["cryptography::cryptocurrencies"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(vss)', 'cfg(vss_test)'] } - [lib] crate-type = ["lib", "staticlib", "cdylib"] name = "ldk_node"