diff --git a/mutiny-core/Cargo.toml b/mutiny-core/Cargo.toml index 0e0066de8..51dc0e96c 100644 --- a/mutiny-core/Cargo.toml +++ b/mutiny-core/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://mutinywallet.com" repository = "https://github.com/mutinywallet/mutiny-node" [dependencies] -lnurl-rs = { version = "=0.2.4", default-features = false, features = ["async", "async-https"] } +lnurl-rs = { git = "https://github.com/TonyGiorgio/lnurl-rs.git", branch = "ldk-116-0d107", default-features = false, features = ["async", "async-https"] } cfg-if = "1.0.0" bip39 = { version = "2.0.0" } @@ -26,9 +26,9 @@ serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1.0" } uuid = { version = "1.1.2", features = ["v4"] } esplora-client = { version = "0.5", default-features = false } -lightning = { version = "0.0.115", default-features = false, features = ["max_level_trace", "grind_signatures", "no-std"] } -lightning-invoice = { version = "0.23", default-features = false, features = ["no-std"] } -lightning-rapid-gossip-sync = { version = "0.0.115", default-features = false, features = ["no-std"] } +lightning = { git = "https://github.com/lightningdevkit/rust-lightning.git", rev = "0d1072b7c3fb5366742473c38069c421cdd60b87", default-features = false, features = ["max_level_trace", "grind_signatures", "no-std"] } +lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning.git", rev = "0d1072b7c3fb5366742473c38069c421cdd60b87", default-features = false, features = ["no-std"] } +lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning.git", rev = "0d1072b7c3fb5366742473c38069c421cdd60b87", default-features = false, features = ["no-std"] } chrono = "0.4.22" futures-util = { version = "0.3", default-features = false } reqwest = { version = "0.11", default-features = false, features = ["json"] } diff --git a/mutiny-core/src/background.rs b/mutiny-core/src/background.rs index a2757762a..17947f680 100644 --- a/mutiny-core/src/background.rs +++ b/mutiny-core/src/background.rs @@ -24,15 +24,14 @@ extern crate lightning_rapid_gossip_sync; use lightning::chain; use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator}; use lightning::chain::chainmonitor::{ChainMonitor, Persist}; -use lightning::chain::keysinterface::{EntropySource, NodeSigner, SignerProvider}; use lightning::events::{Event, PathFailure}; use lightning::ln::channelmanager::ChannelManager; -use lightning::ln::msgs::{ChannelMessageHandler, OnionMessageHandler, RoutingMessageHandler}; -use lightning::ln::peer_handler::{CustomMessageHandler, PeerManager, SocketDescriptor}; +use lightning::ln::peer_handler::APeerManager; use lightning::routing::gossip::{NetworkGraph, P2PGossipSync}; use lightning::routing::router::Router; use lightning::routing::scoring::{Score, WriteableScore}; use lightning::routing::utxo::UtxoLookup; +use lightning::sign::{EntropySource, NodeSigner, SignerProvider}; use lightning::util::logger::Logger; use lightning::util::persist::Persister; use lightning_rapid_gossip_sync::RapidGossipSync; @@ -59,7 +58,7 @@ const PING_TIMER: u64 = 1; const NETWORK_PRUNE_TIMER: u64 = 60 * 60; #[cfg(not(test))] -const SCORER_PERSIST_TIMER: u64 = 30; +const SCORER_PERSIST_TIMER: u64 = 60 * 60; #[cfg(test)] const SCORER_PERSIST_TIMER: u64 = 1; @@ -165,14 +164,7 @@ impl< R: Deref>, G: Deref>, L: Deref, - > - GossipSync< - &P2PGossipSync, - R, - G, - &'a (dyn UtxoLookup + Send + Sync), - L, - > + > GossipSync<&P2PGossipSync, R, G, &'a (dyn UtxoLookup), L> where L::Target: Logger, { @@ -185,10 +177,10 @@ where /// This is not exported to bindings users as the bindings concretize everything and have constructors for us impl<'a, L: Deref> GossipSync< - &P2PGossipSync<&'a NetworkGraph, &'a (dyn UtxoLookup + Send + Sync), L>, + &P2PGossipSync<&'a NetworkGraph, &'a (dyn UtxoLookup), L>, &RapidGossipSync<&'a NetworkGraph, L>, &'a NetworkGraph, - &'a (dyn UtxoLookup + Send + Sync), + &'a (dyn UtxoLookup), L, > where @@ -215,10 +207,12 @@ where } } +/// Updates scorer based on event and returns whether an update occurred so we can decide whether +/// to persist. fn update_scorer<'a, S: 'static + Deref, SC: 'a + WriteableScore<'a>>( scorer: &'a S, event: &Event, -) { +) -> bool { let mut score = scorer.lock(); match event { Event::PaymentPathFailed { @@ -250,8 +244,9 @@ fn update_scorer<'a, S: 'static + Deref, SC: 'a + WriteableScore<'a } => { score.probe_failed(path, *scid); } - _ => {} + _ => return false, } + true } macro_rules! define_run_body { @@ -288,7 +283,7 @@ macro_rules! define_run_body { // ChannelManager, we want to minimize methods blocking on a ChannelManager // generally, and as a fallback place such blocking only immediately before // persistence. - $peer_manager.process_events(); + $peer_manager.as_ref().process_events(); // Exit the loop if the background processor was requested to stop. if $loop_exit_check { @@ -333,28 +328,29 @@ macro_rules! define_run_body { // more than a handful of seconds to complete, and shouldn't disconnect all our // peers. log_trace!($logger, "100ms sleep took more than a second, disconnecting peers."); - $peer_manager.disconnect_all_peers(); + $peer_manager.as_ref().disconnect_all_peers(); last_ping_call = $get_timer(PING_TIMER); } else if $timer_elapsed(&mut last_ping_call, PING_TIMER) { log_trace!($logger, "Calling PeerManager's timer_tick_occurred"); - $peer_manager.timer_tick_occurred(); + $peer_manager.as_ref().timer_tick_occurred(); last_ping_call = $get_timer(PING_TIMER); } // Note that we want to run a graph prune once not long after startup before // falling back to our usual hourly prunes. This avoids short-lived clients never // pruning their network graph. We run once 60 seconds after startup before - // continuing our normal cadence. + // continuing our normal cadence. For RGS, since 60 seconds is likely too long, + // we prune after an initial sync completes. let prune_timer = if have_pruned { NETWORK_PRUNE_TIMER } else { FIRST_NETWORK_PRUNE_TIMER }; - if $timer_elapsed(&mut last_prune_call, prune_timer) { + let prune_timer_elapsed = $timer_elapsed(&mut last_prune_call, prune_timer); + let should_prune = match $gossip_sync { + GossipSync::Rapid(_) => !have_pruned || prune_timer_elapsed, + _ => prune_timer_elapsed, + }; + if should_prune { // The network graph must not be pruned while rapid sync completion is pending if let Some(network_graph) = $gossip_sync.prunable_network_graph() { - #[cfg(feature = "std")] { - log_trace!($logger, "Pruning and persisting network graph."); - network_graph.remove_stale_channels_and_tracking(); - } #[cfg(not(feature = "std"))] { - // log_warn!($logger, "Not pruning network graph, consider enabling `std` or doing so manually with remove_stale_channels_and_tracking_with_time."); log_trace!($logger, "Persisting network graph."); } @@ -404,7 +400,7 @@ macro_rules! define_run_body { } } } -pub(crate) mod bg_futures_util { +pub(crate) mod futures_util { use core::future::Future; use core::marker::Unpin; use core::pin::Pin; @@ -475,27 +471,9 @@ pub(crate) mod bg_futures_util { unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &DUMMY_WAKER_VTABLE)) } } } -use bg_futures_util::{dummy_waker, Selector, SelectorOutput}; +use crate::background::futures_util::{dummy_waker, Selector, SelectorOutput}; use core::task; -/// Processes background events in a future. -/// -/// `sleeper` should return a future which completes in the given amount of time and returns a -/// boolean indicating whether the background processing should exit. Once `sleeper` returns a -/// future which outputs `true`, the loop will exit and this function's future will complete. -/// The `sleeper` future is free to return early after it has triggered the exit condition. -/// -/// See [`BackgroundProcessor::start`] for information on which actions this handles. -/// -/// Requires the `futures` feature. Note that while this method is available without the `std` -/// feature, doing so will skip calling [`NetworkGraph::remove_stale_channels_and_tracking`], -/// you should call [`NetworkGraph::remove_stale_channels_and_tracking_with_time`] regularly -/// manually instead. -/// -/// The `mobile_interruptable_platform` flag should be set if we're currently running on a -/// mobile device, where we may need to check for interruption of the application regularly. If you -/// are unsure, you should set the flag, as the performance impact of it is minimal unless there -/// are hundreds or thousands of simultaneous process calls running. pub async fn process_events_async< 'a, UL: 'static + Deref, @@ -510,10 +488,6 @@ pub async fn process_events_async< G: 'static + Deref>, L: 'static + Deref, P: 'static + Deref, - Descriptor: 'static + SocketDescriptor, - CMH: 'static + Deref, - RMH: 'static + Deref, - OMH: 'static + Deref, EventHandlerFuture: core::future::Future, EventHandler: Fn(Event) -> EventHandlerFuture, PS: 'static + Deref, @@ -521,8 +495,8 @@ pub async fn process_events_async< CM: 'static + Deref>, PGS: 'static + Deref>, RGS: 'static + Deref>, - UMH: 'static + Deref, - PM: 'static + Deref>, + APM: APeerManager, + PM: 'static + Deref, S: 'static + Deref, SC: for<'b> WriteableScore<'b>, SleepFuture: core::future::Future + core::marker::Unpin, @@ -551,10 +525,6 @@ where R::Target: 'static + Router, L::Target: 'static + Logger, P::Target: 'static + Persist<::Signer>, - CMH::Target: 'static + ChannelMessageHandler, - OMH::Target: 'static + OnionMessageHandler, - RMH::Target: 'static + RoutingMessageHandler, - UMH::Target: 'static + CustomMessageHandler, PS::Target: 'static + Persister<'a, CW, T, ES, NS, SP, F, R, L, SC>, { let mut should_break = false; @@ -562,12 +532,23 @@ where let network_graph = gossip_sync.network_graph(); let event_handler = &event_handler; let scorer = &scorer; + let logger = &logger; + let persister = &persister; async move { if let Some(network_graph) = network_graph { handle_network_graph_update(network_graph, &event) } if let Some(ref scorer) = scorer { - update_scorer(scorer, &event); + if update_scorer(scorer, &event) { + log_trace!(logger, "Persisting scorer after update"); + if let Err(e) = persister.persist_scorer(&scorer) { + log_error!( + logger, + "Error: Failed to persist scorer, check your disk and permissions {}", + e + ) + } + } } event_handler(event).await; } diff --git a/mutiny-core/src/chain.rs b/mutiny-core/src/chain.rs index 16154ed5d..63edbe6bf 100644 --- a/mutiny-core/src/chain.rs +++ b/mutiny-core/src/chain.rs @@ -43,13 +43,18 @@ impl Filter for MutinyChain { } impl BroadcasterInterface for MutinyChain { - fn broadcast_transaction(&self, tx: &Transaction) { - let tx_clone = tx.clone(); + fn broadcast_transactions(&self, txs: &[&Transaction]) { + let txs_clone = txs + .iter() + .map(|tx| (*tx).clone()) + .collect::>(); let wallet = self.wallet.clone(); let logger = self.logger.clone(); utils::spawn(async move { - if let Err(e) = wallet.broadcast_transaction(tx_clone).await { - log_warn!(logger, "Error broadcasting transaction: {e}") + for tx in txs_clone { + if let Err(e) = wallet.broadcast_transaction(tx).await { + log_warn!(logger, "Error broadcasting transaction: {e}") + } } }); } diff --git a/mutiny-core/src/esplora.rs b/mutiny-core/src/esplora.rs index 950eeee7b..75e6cbd37 100644 --- a/mutiny-core/src/esplora.rs +++ b/mutiny-core/src/esplora.rs @@ -145,8 +145,8 @@ use lightning::{log_debug, log_error, log_info, log_trace}; use bitcoin::{BlockHash, Script, Txid}; -use esplora_client::r#async::AsyncClient; -use esplora_client::Builder; +use bdk_esplora::esplora_client::r#async::AsyncClient; +use bdk_esplora::esplora_client::Builder; use core::ops::Deref; use std::collections::HashSet; diff --git a/mutiny-core/src/event.rs b/mutiny-core/src/event.rs index c161bebc4..b68cb3cf7 100644 --- a/mutiny-core/src/event.rs +++ b/mutiny-core/src/event.rs @@ -11,8 +11,8 @@ use anyhow::anyhow; use bitcoin::hashes::hex::ToHex; use bitcoin::secp256k1::PublicKey; use bitcoin::secp256k1::Secp256k1; -use lightning::chain::keysinterface::SpendableOutputDescriptor; use lightning::events::{Event, PaymentPurpose}; +use lightning::sign::SpendableOutputDescriptor; use lightning::{ chain::chaininterface::{ConfirmationTarget, FeeEstimator}, log_debug, log_error, log_info, log_warn, @@ -547,6 +547,7 @@ impl EventHandler { } } Event::HTLCIntercepted { .. } => {} + Event::BumpTransaction(_) => {} // we do not support anchors } } diff --git a/mutiny-core/src/gossip.rs b/mutiny-core/src/gossip.rs index b2b289cbf..4d9d9994f 100644 --- a/mutiny-core/src/gossip.rs +++ b/mutiny-core/src/gossip.rs @@ -4,11 +4,12 @@ use std::sync::Arc; use bitcoin::hashes::hex::{FromHex, ToHex}; use bitcoin::Network; -use lightning::ln::msgs::NodeAnnouncement; use lightning::routing::gossip::NodeId; -use lightning::routing::scoring::ProbabilisticScoringParameters; use lightning::util::logger::Logger; use lightning::util::ser::{ReadableArgs, Writeable}; +use lightning::{ + ln::msgs::NodeAnnouncement, routing::scoring::ProbabilisticScoringDecayParameters, +}; use lightning::{log_debug, log_error, log_info, log_warn}; use reqwest::Client; use serde::{Deserialize, Serialize}; @@ -67,7 +68,7 @@ async fn get_gossip_data( Some(prob_scorer_str) => { let prob_scorer_bytes: Vec = Vec::from_hex(&prob_scorer_str)?; let mut readable_bytes = lightning::io::Cursor::new(prob_scorer_bytes); - let params = ProbabilisticScoringParameters::default(); + let params = ProbabilisticScoringDecayParameters::default(); let args = (params, Arc::clone(&network_graph), Arc::clone(&logger)); ProbScorer::read(&mut readable_bytes, args) } @@ -142,7 +143,7 @@ pub async fn get_gossip_sync( let prob_scorer = match gossip_data.scorer { Some(scorer) => scorer, None => { - let params = ProbabilisticScoringParameters::default(); + let params = ProbabilisticScoringDecayParameters::default(); ProbScorer::new(params, gossip_data.network_graph.clone(), logger.clone()) } }; diff --git a/mutiny-core/src/keymanager.rs b/mutiny-core/src/keymanager.rs index b69b8f3e6..37c74bb32 100644 --- a/mutiny-core/src/keymanager.rs +++ b/mutiny-core/src/keymanager.rs @@ -12,14 +12,14 @@ use bitcoin::secp256k1::ecdsa::Signature; use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, Signing}; use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey}; use bitcoin::{Script, Transaction, TxOut}; -use lightning::chain::keysinterface::{ +use lightning::ln::msgs::{DecodeError, UnsignedGossipMessage}; +use lightning::ln::script::ShutdownScript; +use lightning::log_warn; +use lightning::sign::{ EntropySource, InMemorySigner, KeyMaterial, NodeSigner, PhantomKeysManager as LdkPhantomKeysManager, Recipient, SignerProvider, SpendableOutputDescriptor, }; -use lightning::ln::msgs::{DecodeError, UnsignedGossipMessage}; -use lightning::ln::script::ShutdownScript; -use lightning::log_warn; use lightning::util::logger::Logger; use std::sync::Arc; @@ -69,6 +69,7 @@ impl PhantomKeysManager { outputs, address.script_pubkey(), feerate_sat_per_1000_weight, + None, // tx locktime of 0 secp_ctx, ); @@ -156,21 +157,21 @@ impl SignerProvider for PhantomKeysManager { self.inner.read_chan_signer(reader) } - fn get_destination_script(&self) -> Script { - let mut wallet = self.wallet.wallet.try_write().unwrap(); - wallet + fn get_destination_script(&self) -> Result { + let mut wallet = self.wallet.wallet.try_write().map_err(|_| ())?; + Ok(wallet .get_address(AddressIndex::New) .address - .script_pubkey() + .script_pubkey()) } - fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { - let mut wallet = self.wallet.wallet.try_write().unwrap(); + fn get_shutdown_scriptpubkey(&self) -> Result { + let mut wallet = self.wallet.wallet.try_write().map_err(|_| ())?; let script = wallet .get_address(AddressIndex::New) .address .script_pubkey(); - ShutdownScript::try_from(script).unwrap() + ShutdownScript::try_from(script).map_err(|_| ()) } } diff --git a/mutiny-core/src/ldkstorage.rs b/mutiny-core/src/ldkstorage.rs index 9929f99ba..5aaf6b933 100644 --- a/mutiny-core/src/ldkstorage.rs +++ b/mutiny-core/src/ldkstorage.rs @@ -17,9 +17,6 @@ use bitcoin::Network; use bitcoin::{BlockHash, Transaction}; use futures::{try_join, TryFutureExt}; use lightning::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate}; -use lightning::chain::keysinterface::{ - InMemorySigner, SpendableOutputDescriptor, WriteableEcdsaChannelSigner, -}; use lightning::chain::transaction::OutPoint; use lightning::chain::BestBlock; use lightning::io::Cursor; @@ -27,6 +24,7 @@ use lightning::ln::channelmanager::{ self, ChainParameters, ChannelManager as LdkChannelManager, ChannelManagerReadArgs, }; use lightning::ln::PaymentHash; +use lightning::sign::{InMemorySigner, SpendableOutputDescriptor, WriteableEcdsaChannelSigner}; use lightning::util::logger::Logger; use lightning::util::persist::Persister; use lightning::util::ser::{Readable, ReadableArgs, Writeable}; @@ -257,6 +255,7 @@ impl MutinyNodePersister { keys_manager, default_user_config(), chain_params, + utils::now().as_secs() as u32, ); Ok(ReadChannelManager { diff --git a/mutiny-core/src/lnurlauth.rs b/mutiny-core/src/lnurlauth.rs index 3cbc77654..7a2e5f4b4 100644 --- a/mutiny-core/src/lnurlauth.rs +++ b/mutiny-core/src/lnurlauth.rs @@ -51,7 +51,7 @@ impl SigningProfile { xprivkey: ExtendedPrivKey, url: Url, ) -> Result { - let path = lnurl::get_derivation_path(self.hashing_key.secret_bytes(), url)?; + let path = lnurl::get_derivation_path(self.hashing_key.secret_bytes(), &url)?; let key = xprivkey .derive_priv(context, &path) .map_err(|e| MutinyError::Other(anyhow!("Error deriving key for path {path}: {e}")))?; diff --git a/mutiny-core/src/node.rs b/mutiny-core/src/node.rs index a4d45de4e..652832c51 100644 --- a/mutiny-core/src/node.rs +++ b/mutiny-core/src/node.rs @@ -32,18 +32,17 @@ use bitcoin::secp256k1::rand; use bitcoin::{hashes::Hash, secp256k1::PublicKey, BlockHash, Network, OutPoint}; use core::time::Duration; use lightning::chain::channelmonitor::ChannelMonitor; -use lightning::ln::channelmanager::{RecipientOnionFields, RetryableSendFailure}; use lightning::util::ser::{ReadableArgs, Writeable}; use lightning::{ chain::chaininterface::{ConfirmationTarget, FeeEstimator}, + ln::channelmanager::{RecipientOnionFields, RetryableSendFailure}, + routing::scoring::ProbabilisticScoringFeeParameters, util::config::ChannelConfig, }; + +use lightning::sign::{EntropySource, InMemorySigner}; use lightning::{ - chain::{ - chainmonitor, - keysinterface::{EntropySource, InMemorySigner}, - Filter, Watch, - }, + chain::{chainmonitor, Filter, Watch}, ln::{ channelmanager::{PaymentId, PhantomRouteHints, Retry}, peer_handler::{IgnoringMessageHandler, MessageHandler as LdkMessageHandler}, @@ -89,6 +88,7 @@ pub(crate) type MessageHandler = LdkMessageHandler< Arc>, Arc>, Arc, + Arc, >; pub(crate) type ChainMonitor = chainmonitor::ChainMonitor< @@ -100,8 +100,13 @@ pub(crate) type ChainMonitor = chainmonitor::ChainMonitor< Arc>, >; -pub(crate) type Router = - DefaultRouter, Arc, Arc>>; +pub(crate) type Router = DefaultRouter< + Arc, + Arc, + Arc>, + ProbabilisticScoringFeeParameters, + ProbScorer, +>; pub(crate) type ProbScorer = ProbabilisticScorer, Arc>; @@ -223,6 +228,7 @@ impl Node { logger.clone(), keys_manager.clone().get_secure_random_bytes(), scorer.clone(), + ProbabilisticScoringFeeParameters::default(), )); // init channel manager @@ -295,12 +301,13 @@ impl Node { }); // init peer manager + let scb_message_handler = Arc::new(SCBMessageHandler::new()); let ln_msg_handler = MessageHandler { chan_handler: channel_manager.clone(), route_handler, onion_message_handler: Arc::new(IgnoringMessageHandler {}), + custom_message_handler: scb_message_handler.clone(), }; - let scb_message_handler = Arc::new(SCBMessageHandler::new()); log_info!(logger, "creating lsp client"); let lsp_client: Option = match node_index.lsp { @@ -335,7 +342,6 @@ impl Node { let peer_man = Arc::new(create_peer_manager( keys_manager.clone(), ln_msg_handler, - scb_message_handler.clone(), logger.clone(), )); @@ -1087,7 +1093,8 @@ impl Node { let amt_msats = amt_sats * 1000; - let payment_params = PaymentParameters::for_keysend(to_node, 40); + // TODO retry with allow_mpp false just in case recipient does not support + let payment_params = PaymentParameters::for_keysend(to_node, 40, true); let route_params: RouteParameters = RouteParameters { final_value_msat: amt_msats, payment_params, @@ -1639,7 +1646,6 @@ fn stop_component(stopped_components: &Arc>>) { pub(crate) fn create_peer_manager( km: Arc>, lightning_msg_handler: MessageHandler, - scb_message_handler: Arc, logger: Arc, ) -> PeerManagerImpl { let now = utils::now().as_secs(); @@ -1651,7 +1657,6 @@ pub(crate) fn create_peer_manager( now as u32, &ephemeral_bytes, logger, - scb_message_handler, km, ) } diff --git a/mutiny-core/src/nodemanager.rs b/mutiny-core/src/nodemanager.rs index e54ec4f2b..22fe747fd 100644 --- a/mutiny-core/src/nodemanager.rs +++ b/mutiny-core/src/nodemanager.rs @@ -1,4 +1,5 @@ use anyhow::anyhow; +use lightning::sign::{NodeSigner, Recipient}; use std::sync::atomic::{AtomicBool, Ordering}; use std::{collections::HashMap, ops::Deref, sync::Arc}; @@ -46,8 +47,6 @@ use bitcoin::{Address, Network, OutPoint, Transaction, Txid}; use core::time::Duration; use futures::{future::join_all, lock::Mutex}; use lightning::chain::chaininterface::{ConfirmationTarget, FeeEstimator}; -use lightning::chain::channelmonitor::Balance; -use lightning::chain::keysinterface::{NodeSigner, Recipient}; use lightning::chain::Confirm; use lightning::events::ClosureReason; use lightning::io::Read; @@ -1280,31 +1279,7 @@ impl NodeManager { let ignored_channels: Vec<&ChannelDetails> = channels.iter().collect(); n.chain_monitor.get_claimable_balances(&ignored_channels) }) - .map(|bal| match bal { - Balance::ClaimableOnChannelClose { - claimable_amount_satoshis, - } => claimable_amount_satoshis, - Balance::ClaimableAwaitingConfirmations { - claimable_amount_satoshis, - .. - } => claimable_amount_satoshis, - Balance::ContentiousClaimable { - claimable_amount_satoshis, - .. - } => claimable_amount_satoshis, - Balance::MaybeTimeoutClaimableHTLC { - claimable_amount_satoshis, - .. - } => claimable_amount_satoshis, - Balance::MaybePreimageClaimableHTLC { - claimable_amount_satoshis, - .. - } => claimable_amount_satoshis, - Balance::CounterpartyRevokedOutputClaimable { - claimable_amount_satoshis, - .. - } => claimable_amount_satoshis, - }) + .map(|bal| bal.claimable_amount_satoshis()) .sum(); Ok(MutinyBalance { diff --git a/mutiny-core/src/peermanager.rs b/mutiny-core/src/peermanager.rs index 1373279ff..79133f8f3 100644 --- a/mutiny-core/src/peermanager.rs +++ b/mutiny-core/src/peermanager.rs @@ -224,10 +224,7 @@ impl RoutingMessageHandler for GossipMessageHandler { ) -> Result { // because we got the channel, may as well update our network graph self.network_graph - .update_channel_from_unsigned_announcement::>( - &msg.contents, - &None, - )?; + .update_channel_from_announcement_no_lookup(msg)?; Ok(false) } diff --git a/mutiny-core/src/scb/message_handler.rs b/mutiny-core/src/scb/message_handler.rs index fc633aeeb..c5fcb3d11 100644 --- a/mutiny-core/src/scb/message_handler.rs +++ b/mutiny-core/src/scb/message_handler.rs @@ -1,9 +1,12 @@ use crate::utils::Mutex; use bitcoin::secp256k1::PublicKey; -use lightning::ln::msgs::{ChannelReestablish, OptionalField}; -use lightning::ln::msgs::{DecodeError, LightningError}; use lightning::ln::peer_handler::CustomMessageHandler; use lightning::ln::wire::CustomMessageReader; +use lightning::ln::{ + features::InitFeatures, + msgs::{DecodeError, LightningError}, +}; +use lightning::ln::{features::NodeFeatures, msgs::ChannelReestablish}; use std::collections::VecDeque; /// Custom message handler for Static Channel Backups. @@ -32,11 +35,16 @@ impl SCBMessageHandler { /// sent right away, but only when the LDK /// [`lightning::ln::peer_handler::PeerManager::process_events`] is next called. pub fn request_channel_close(&self, node_id: PublicKey, channel_id: [u8; 32]) { + let mut pk = [2; 33]; + pk[1] = 0xff; + let dummy_pubkey = PublicKey::from_slice(&pk).unwrap(); let msg = ChannelReestablish { channel_id, next_local_commitment_number: 0, next_remote_commitment_number: 0, - data_loss_protect: OptionalField::Absent, + your_last_per_commitment_secret: [0; 32], + my_current_per_commitment_point: dummy_pubkey, + next_funding_txid: None, }; self.msg_events.lock().unwrap().push_back((node_id, msg)); } @@ -75,4 +83,15 @@ impl CustomMessageHandler for SCBMessageHandler { fn get_and_clear_pending_msg(&self) -> Vec<(PublicKey, Self::CustomMessage)> { self.msg_events.lock().unwrap().drain(..).collect() } + + fn provided_node_features(&self) -> lightning::ln::features::NodeFeatures { + NodeFeatures::empty() + } + + fn provided_init_features( + &self, + _their_node_id: &PublicKey, + ) -> lightning::ln::features::InitFeatures { + InitFeatures::empty() + } } diff --git a/mutiny-core/src/utils.rs b/mutiny-core/src/utils.rs index f438f9713..8356be61e 100644 --- a/mutiny-core/src/utils.rs +++ b/mutiny-core/src/utils.rs @@ -92,6 +92,8 @@ impl<'a, T: 'a + Score> LockableScore<'a> for Mutex { fn lock(&'a self) -> MutexGuard<'a, T> { Mutex::lock(self).expect("Failed to lock mutex") } + + type Score = T; } impl Writeable for Mutex { diff --git a/mutiny-wasm/Cargo.toml b/mutiny-wasm/Cargo.toml index 55ad3a5a2..7dee48996 100644 --- a/mutiny-wasm/Cargo.toml +++ b/mutiny-wasm/Cargo.toml @@ -24,11 +24,11 @@ wasm-bindgen-futures = "0.4.33" serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1.0" } bitcoin = { version = "0.29.2", default-features = false, features = ["serde", "secp-recovery", "rand"] } -lightning = { version = "0.0.115", default-features = false, features = ["no-std"] } -lightning-invoice = { version = "0.23", default-features = false, features = ["no-std"] } +lightning = { git = "https://github.com/lightningdevkit/rust-lightning.git", rev = "0d1072b7c3fb5366742473c38069c421cdd60b87", default-features = false, features = ["no-std"] } +lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning.git", rev = "0d1072b7c3fb5366742473c38069c421cdd60b87", default-features = false, features = ["no-std"] } thiserror = "1.0" instant = { version = "0.1", features = ["wasm-bindgen"] } -lnurl-rs = { version = "0.2.2", default-features = false } +lnurl-rs = { git = "https://github.com/TonyGiorgio/lnurl-rs.git", branch = "ldk-116-0d107", default-features = false } wasm-logger = "0.2.0" log = "0.4.17" rexie = "0.4"