Skip to content

Commit

Permalink
Merge pull request #49 from getAlby/feat/get-encoded-channel-monitors
Browse files Browse the repository at this point in the history
feat: get encoded channel monitors
  • Loading branch information
rolznz committed Sep 24, 2024
2 parents 955b763 + b9b59d0 commit 62cad89
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 3 deletions.
9 changes: 9 additions & 0 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface Builder {
Node build();
[Throws=BuildError]
Node build_with_fs_store();
void restore_encoded_channel_monitors(sequence<KeyValue> monitors);
};

interface Node {
Expand Down Expand Up @@ -90,6 +91,9 @@ interface Node {
[Throws=NodeError]
string sign_message([ByRef]sequence<u8> msg);
boolean verify_signature([ByRef]sequence<u8> msg, [ByRef]string sig, [ByRef]PublicKey pkey);
[Throws=NodeError]
sequence<KeyValue> get_encoded_channel_monitors();
void force_close_all_channels_without_broadcasting_txn();
};

interface Bolt11Payment {
Expand Down Expand Up @@ -424,6 +428,11 @@ dictionary TlvEntry {
sequence<u8> value;
};

dictionary KeyValue {
string key;
sequence<u8> value;
};

interface NetworkGraph {
sequence<u64> list_channels();
ChannelInfo? channel(u64 short_channel_id);
Expand Down
30 changes: 28 additions & 2 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -172,6 +172,7 @@ pub struct NodeBuilder {
chain_data_source_config: Option<ChainDataSourceConfig>,
gossip_source_config: Option<GossipSourceConfig>,
liquidity_source_config: Option<LiquiditySourceConfig>,
monitors_to_restore: Option<Vec<KeyValue>>,
}

impl NodeBuilder {
Expand All @@ -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<KeyValue>) -> &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
Expand Down Expand Up @@ -316,6 +325,7 @@ impl NodeBuilder {
)
.map_err(|_| BuildError::KVStoreSetupFailed)?,
);

self.build_with_store(kv_store)
}

Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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<KeyValue>) {
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
Expand Down
29 changes: 28 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -1539,6 +1539,33 @@ 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<Vec<KeyValue>, Error> {
let channel_monitor_store = Arc::clone(&self.kv_store);
let channel_monitor_logger = Arc::clone(&self.logger);
let keys = channel_monitor_store.list("monitors", "").map_err(|e| {
log_error!(channel_monitor_logger, "Failed to get monitor keys: {}", e);
Error::ConnectionFailed
})?;

let mut entries = Vec::new();

for key in keys {
let value = channel_monitor_store.read("monitors", "", &key).map_err(|e| {
log_error!(channel_monitor_logger, "Failed to get monitor value: {}", e);
Error::ConnectionFailed
})?;
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 =
Expand Down
9 changes: 9 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>,
}

0 comments on commit 62cad89

Please sign in to comment.