X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fchannelmanager.rs;h=9407fec09b258eb5f233b36971b550984d6cdf43;hb=b9a155d75f723f0e99f7bf7faf0abe5c7b492dfd;hp=765c417f3a6856c0f56543cc84d7000655a10a54;hpb=68be3c03531667a1ecae7c67664e0ef71ea98a61;p=rust-lightning diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 765c417f..9407fec0 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -1,3 +1,13 @@ +//! The top-level channel management and payment tracking stuff lives here. +//! +//! The ChannelManager is the main chunk of logic implementing the lightning protocol and is +//! responsible for tracking which channels are open, HTLCs are in flight and reestablishing those +//! upon reconnect to the relevant peer(s). +//! +//! It does not manage routing logic (see ln::router for that) nor does it manage constructing +//! on-chain transactions (it only monitors the chain to watch for any force-closes that might +//! imply it needs to fail HTLCs/payments/channels it manages). + use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::transaction::Transaction; use bitcoin::blockdata::constants::genesis_block; @@ -16,9 +26,10 @@ use ln::channel::{Channel, ChannelKeys}; use ln::channelmonitor::ManyChannelMonitor; use ln::router::{Route,RouteHop}; use ln::msgs; -use ln::msgs::{HandleError,ChannelMessageHandler,MsgEncodable,MsgDecodable}; +use ln::msgs::{HandleError,ChannelMessageHandler}; use util::{byte_utils, events, internal_traits, rng}; use util::sha2::Sha256; +use util::ser::{Readable, Writeable}; use util::chacha20poly1305rfc::ChaCha20; use util::logger::Logger; use util::errors::APIError; @@ -32,6 +43,7 @@ use crypto::symmetriccipher::SynchronousStreamCipher; use std::{ptr, mem}; use std::collections::HashMap; use std::collections::hash_map; +use std::io::Cursor; use std::sync::{Mutex,MutexGuard,Arc}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::time::{Instant,Duration}; @@ -78,23 +90,6 @@ mod channel_held_info { Fail(HTLCFailureMsg), } - #[cfg(feature = "fuzztarget")] - impl PendingHTLCStatus { - pub fn dummy() -> Self { - let secp_ctx = ::secp256k1::Secp256k1::signing_only(); - PendingHTLCStatus::Forward(PendingForwardHTLCInfo { - onion_packet: None, - incoming_shared_secret: SharedSecret::new(&secp_ctx, - &::secp256k1::key::PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[1; 32]).unwrap()), - &SecretKey::from_slice(&secp_ctx, &[1; 32]).unwrap()), - payment_hash: [0; 32], - short_channel_id: 0, - amt_to_forward: 0, - outgoing_cltv_value: 0, - }) - } - } - /// Tracks the inbound corresponding to an outbound HTLC #[derive(Clone)] pub struct HTLCPreviousHopData { @@ -112,7 +107,7 @@ mod channel_held_info { session_priv: SecretKey, }, } - #[cfg(any(test, feature = "fuzztarget"))] + #[cfg(test)] impl HTLCSource { pub fn dummy() -> Self { HTLCSource::OutboundRoute { @@ -123,7 +118,7 @@ mod channel_held_info { } #[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug - pub enum HTLCFailReason { + pub(crate) enum HTLCFailReason { ErrorPacket { err: msgs::OnionErrorPacket, }, @@ -132,20 +127,8 @@ mod channel_held_info { data: Vec, } } - - #[cfg(feature = "fuzztarget")] - impl HTLCFailReason { - pub fn dummy() -> Self { - HTLCFailReason::Reason { - failure_code: 0, data: Vec::new(), - } - } - } } -#[cfg(feature = "fuzztarget")] -pub use self::channel_held_info::*; -#[cfg(not(feature = "fuzztarget"))] -pub(crate) use self::channel_held_info::*; +pub(super) use self::channel_held_info::*; struct MsgHandleErrInternal { err: msgs::HandleError, @@ -242,6 +225,7 @@ const ERR: () = "You need at least 32 bit pointers (well, usize, but we'll assum /// Manager which keeps track of a number of channels and sends messages to the appropriate /// channel, also tracking HTLC preimages and forwarding onion packets appropriately. +/// /// Implements ChannelMessageHandler, handling the multi-channel parts and passing things through /// to individual Channels. pub struct ChannelManager { @@ -285,6 +269,7 @@ struct OnionKeys { mu: [u8; 32], } +/// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels pub struct ChannelDetails { /// The channel's ID (prior to funding transaction generation, this is a random 32 bytes, /// thereafter this is the txid of the funding transaction xor the funding transaction output). @@ -294,17 +279,23 @@ pub struct ChannelDetails { /// The position of the funding transaction in the chain. None if the funding transaction has /// not yet been confirmed and the channel fully opened. pub short_channel_id: Option, + /// The node_id of our counterparty pub remote_network_id: PublicKey, + /// The value, in satoshis, of this channel as appears in the funding output pub channel_value_satoshis: u64, /// The user_id passed in to create_channel, or 0 if the channel was inbound. pub user_id: u64, } impl ChannelManager { - /// Constructs a new ChannelManager to hold several channels and route between them. This is - /// the main "logic hub" for all channel-related actions, and implements ChannelMessageHandler. + /// Constructs a new ChannelManager to hold several channels and route between them. + /// + /// This is the main "logic hub" for all channel-related actions, and implements + /// ChannelMessageHandler. + /// /// fee_proportional_millionths is an optional fee to charge any payments routed through us. /// Non-proportional fees are fixed according to our risk using the provided fee estimator. + /// /// panics if channel_value_satoshis is >= `MAX_FUNDING_SATOSHIS`! pub fn new(our_network_key: SecretKey, fee_proportional_millionths: u32, announce_channels_publicly: bool, network: Network, feeest: Arc, monitor: Arc, chain_monitor: Arc, tx_broadcaster: Arc, logger: Arc) -> Result, secp256k1::Error> { let secp_ctx = Secp256k1::new(); @@ -340,12 +331,15 @@ impl ChannelManager { } /// Creates a new outbound channel to the given remote node and with the given value. + /// /// user_id will be provided back as user_channel_id in FundingGenerationReady and /// FundingBroadcastSafe events to allow tracking of which events correspond with which /// create_channel call. Note that user_channel_id defaults to 0 for inbound channels, so you /// may wish to avoid using 0 for user_id here. + /// /// If successful, will generate a SendOpenChannel event, so you should probably poll /// PeerManager::process_events afterwards. + /// /// Raises APIError::APIMisuseError when channel_value_satoshis > 2**24 or push_msat being greater than channel_value_satoshis * 1k pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64) -> Result<(), APIError> { let chan_keys = if cfg!(feature = "fuzztarget") { @@ -369,11 +363,17 @@ impl ChannelManager { }; let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, push_msat, self.announce_channels_publicly, user_id, Arc::clone(&self.logger))?; - let res = channel.get_open_channel(self.genesis_hash.clone(), &*self.fee_estimator)?; + let res = channel.get_open_channel(self.genesis_hash.clone(), &*self.fee_estimator); let mut channel_state = self.channel_state.lock().unwrap(); - match channel_state.by_id.insert(channel.channel_id(), channel) { - Some(_) => panic!("RNG is bad???"), - None => {} + match channel_state.by_id.entry(channel.channel_id()) { + hash_map::Entry::Occupied(_) => { + if cfg!(feature = "fuzztarget") { + return Err(APIError::APIMisuseError { err: "Fuzzy bad RNG" }); + } else { + panic!("RNG is bad???"); + } + }, + hash_map::Entry::Vacant(entry) => { entry.insert(channel); } } let mut events = self.pending_events.lock().unwrap(); @@ -423,6 +423,7 @@ impl ChannelManager { /// Begins the process of closing a channel. After this call (plus some timeout), no new HTLCs /// will be accepted on the given channel, and after additional timeout/the closing of all /// pending HTLCs, the channel will be closed on chain. + /// /// May generate a SendShutdown event on success, which should be relayed. pub fn close_channel(&self, channel_id: &[u8; 32]) -> Result<(), HandleError> { let (mut res, node_id, chan_option) = { @@ -819,10 +820,10 @@ impl ChannelManager { let next_hop_data = { let mut decoded = [0; 65]; chacha.process(&msg.onion_routing_packet.hop_data[0..65], &mut decoded); - match msgs::OnionHopData::decode(&decoded[..]) { + match msgs::OnionHopData::read(&mut Cursor::new(&decoded[..])) { Err(err) => { let error_code = match err { - msgs::DecodeError::UnknownRealmByte => 0x4000 | 1, + msgs::DecodeError::UnknownVersion => 0x4000 | 1, // unknown realm byte _ => 0x2000 | 2, // Should never happen }; return_err!("Unable to decode our hop data", error_code, &[0;0]); @@ -963,16 +964,19 @@ impl ChannelManager { } /// Sends a payment along a given route. + /// /// Value parameters are provided via the last hop in route, see documentation for RouteHop /// fields for more info. + /// /// Note that if the payment_hash already exists elsewhere (eg you're sending a duplicative /// payment), we don't do anything to stop you! We always try to ensure that if the provided /// next hop knows the preimage to payment_hash they can claim an additional amount as /// specified in the last hop in the route! Thus, you should probably do your own /// payment_preimage tracking (which you should already be doing as they represent "proof of /// payment") and prevent double-sends yourself. - /// See-also docs on Channel::send_htlc_and_commit. + /// /// May generate a SendHTLCs event on success, which should be relayed. + /// /// Raises APIError::RoutError when invalid route or forward parameter /// (cltv_delta, fee, node public key) is specified pub fn send_payment(&self, route: Route, payment_hash: [u8; 32]) -> Result<(), APIError> { @@ -1042,6 +1046,7 @@ impl ChannelManager { update_fulfill_htlcs: Vec::new(), update_fail_htlcs: Vec::new(), update_fail_malformed_htlcs: Vec::new(), + update_fee: None, commitment_signed, }, }); @@ -1049,7 +1054,9 @@ impl ChannelManager { } /// Call this upon creation of a funding transaction for the given channel. + /// /// Panics if a funding transaction has already been provided for this channel. + /// /// May panic if the funding_txo is duplicative with some other channel (note that this should /// be trivially prevented by using unique funding transaction keys per-channel). pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) { @@ -1123,6 +1130,7 @@ impl ChannelManager { } /// Processes HTLCs which are pending waiting on random forward delay. + /// /// Should only really ever be called in response to an PendingHTLCsForwardable event. /// Will likely generate further events. pub fn process_pending_htlc_forwards(&self) { @@ -1205,6 +1213,7 @@ impl ChannelManager { update_fulfill_htlcs: Vec::new(), update_fail_htlcs: Vec::new(), update_fail_malformed_htlcs: Vec::new(), + update_fee: None, commitment_signed: commitment_msg, }, })); @@ -1218,7 +1227,7 @@ impl ChannelManager { }; match channel_state.claimable_htlcs.entry(forward_info.payment_hash) { hash_map::Entry::Occupied(mut entry) => entry.get_mut().push(prev_hop_data), - hash_map::Entry::Vacant(mut entry) => { entry.insert(vec![prev_hop_data]); }, + hash_map::Entry::Vacant(entry) => { entry.insert(vec![prev_hop_data]); }, }; new_events.push((None, events::Event::PaymentReceived { payment_hash: forward_info.payment_hash, @@ -1326,6 +1335,7 @@ impl ChannelManager { update_fulfill_htlcs: Vec::new(), update_fail_htlcs: vec![msg], update_fail_malformed_htlcs: Vec::new(), + update_fee: None, commitment_signed: commitment_msg, }, }); @@ -1339,6 +1349,7 @@ impl ChannelManager { /// Provides a payment preimage in response to a PaymentReceived event, returning true and /// generating message events for the net layer to claim the payment, if possible. Thus, you /// should probably kick the net layer to go send messages if this returns true! + /// /// May panic if called except in response to a PaymentReceived event. pub fn claim_funds(&self, payment_preimage: [u8; 32]) -> bool { let mut sha = Sha256::new(); @@ -1406,6 +1417,7 @@ impl ChannelManager { update_fulfill_htlcs: vec![msg], update_fail_htlcs: Vec::new(), update_fail_malformed_htlcs: Vec::new(), + update_fee: None, commitment_signed: commitment_msg, } }); @@ -1717,7 +1729,7 @@ impl ChannelManager { chacha.process(&packet_decrypted, &mut decryption_tmp[..]); packet_decrypted = decryption_tmp; - if let Ok(err_packet) = msgs::DecodedOnionErrorPacket::decode(&packet_decrypted) { + if let Ok(err_packet) = msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&packet_decrypted)) { if err_packet.failuremsg.len() >= 2 { let um = ChannelManager::gen_um_from_shared_secret(&shared_secret); @@ -1733,7 +1745,7 @@ impl ChannelManager { if err_packet.failuremsg.len() >= 4 { let update_len = byte_utils::slice_to_be16(&err_packet.failuremsg[2..4]) as usize; if err_packet.failuremsg.len() >= 4 + update_len { - if let Ok(chan_update) = msgs::ChannelUpdate::decode(&err_packet.failuremsg[4..4 + update_len]) { + if let Ok(chan_update) = msgs::ChannelUpdate::read(&mut Cursor::new(&err_packet.failuremsg[4..4 + update_len])) { res = Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { msg: chan_update, }); @@ -1902,7 +1914,65 @@ impl ChannelManager { Ok(()) } + fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option), MsgHandleErrInternal> { + let (res, chan_monitor) = { + let mut channel_state = self.channel_state.lock().unwrap(); + match channel_state.by_id.get_mut(&msg.channel_id) { + Some(chan) => { + if chan.get_their_node_id() != *their_node_id { + return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + } + let (funding_locked, revoke_and_ack, commitment_update, channel_monitor) = chan.channel_reestablish(msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?; + (Ok((funding_locked, revoke_and_ack, commitment_update)), channel_monitor) + }, + None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } + }; + if let Some(monitor) = chan_monitor { + if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) { + unimplemented!(); + } + } + res + } + /// Begin Update fee process. Allowed only on an outbound channel. + /// If successful, will generate a UpdateHTLCs event, so you should probably poll + /// PeerManager::process_events afterwards. + /// Note: This API is likely to change! + #[doc(hidden)] + pub fn update_fee(&self, channel_id: [u8;32], feerate_per_kw: u64) -> Result<(), APIError> { + let mut channel_state = self.channel_state.lock().unwrap(); + match channel_state.by_id.get_mut(&channel_id) { + None => return Err(APIError::APIMisuseError{err: "Failed to find corresponding channel"}), + Some(chan) => { + if !chan.is_usable() { + return Err(APIError::APIMisuseError{err: "Channel is not in usuable state"}); + } + if !chan.is_outbound() { + return Err(APIError::APIMisuseError{err: "update_fee cannot be sent for an inbound channel"}); + } + if let Some((update_fee, commitment_signed, chan_monitor)) = chan.send_update_fee_and_commit(feerate_per_kw).map_err(|e| APIError::APIMisuseError{err: e.err})? { + if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { + unimplemented!(); + } + let mut pending_events = self.pending_events.lock().unwrap(); + pending_events.push(events::Event::UpdateHTLCs { + node_id: chan.get_their_node_id(), + updates: msgs::CommitmentUpdate { + update_add_htlcs: Vec::new(), + update_fulfill_htlcs: Vec::new(), + update_fail_htlcs: Vec::new(), + update_fail_malformed_htlcs: Vec::new(), + update_fee: Some(update_fee), + commitment_signed, + }, + }); + } + }, + } + Ok(()) + } } impl events::EventsProvider for ChannelManager { @@ -2123,9 +2193,14 @@ impl ChannelMessageHandler for ChannelManager { handle_error!(self, self.internal_announcement_signatures(their_node_id, msg), their_node_id) } + fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option), HandleError> { + handle_error!(self, self.internal_channel_reestablish(their_node_id, msg), their_node_id) + } + fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool) { let mut new_events = Vec::new(); let mut failed_channels = Vec::new(); + let mut failed_payments = Vec::new(); { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = channel_state_lock.borrow_parts(); @@ -2148,13 +2223,23 @@ impl ChannelMessageHandler for ChannelManager { } }); } else { - for chan in channel_state.by_id { - if chan.1.get_their_node_id() == *their_node_id { - //TODO: mark channel disabled (and maybe announce such after a timeout). Also - //fail and wipe any uncommitted outbound HTLCs as those are considered after - //reconnect. + channel_state.by_id.retain(|_, chan| { + if chan.get_their_node_id() == *their_node_id { + //TODO: mark channel disabled (and maybe announce such after a timeout). + let failed_adds = chan.remove_uncommitted_htlcs_and_mark_paused(); + if !failed_adds.is_empty() { + let chan_update = self.get_channel_update(&chan).map(|u| u.encode_with_len()).unwrap(); // Cannot add/recv HTLCs before we have a short_id so unwrap is safe + failed_payments.push((chan_update, failed_adds)); + } + if chan.is_shutdown() { + if let Some(short_id) = chan.get_short_channel_id() { + short_to_id.remove(&short_id); + } + return false; + } } - } + true + }) } } for failure in failed_channels.drain(..) { @@ -2166,6 +2251,32 @@ impl ChannelMessageHandler for ChannelManager { pending_events.push(event); } } + for (chan_update, mut htlc_sources) in failed_payments { + for (htlc_source, payment_hash) in htlc_sources.drain(..) { + self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source, &payment_hash, HTLCFailReason::Reason { failure_code: 0x1000 | 7, data: chan_update.clone() }); + } + } + } + + fn peer_connected(&self, their_node_id: &PublicKey) -> Vec { + let mut res = Vec::new(); + let mut channel_state = self.channel_state.lock().unwrap(); + channel_state.by_id.retain(|_, chan| { + if chan.get_their_node_id() == *their_node_id { + if !chan.have_received_message() { + // If we created this (outbound) channel while we were disconnected from the + // peer we probably failed to send the open_channel message, which is now + // lost. We can't have had anything pending related to this channel, so we just + // drop it. + false + } else { + res.push(chan.get_channel_reestablish()); + true + } + } else { true } + }); + //TODO: Also re-broadcast announcement_signatures + res } fn handle_error(&self, their_node_id: &PublicKey, msg: &msgs::ErrorMessage) { @@ -2189,16 +2300,16 @@ mod tests { use ln::channelmanager::{ChannelManager,OnionKeys}; use ln::router::{Route, RouteHop, Router}; use ln::msgs; - use ln::msgs::{MsgEncodable,ChannelMessageHandler,RoutingMessageHandler}; + use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler}; use util::test_utils; use util::events::{Event, EventsProvider}; - use util::logger::Logger; use util::errors::APIError; + use util::logger::Logger; + use util::ser::Writeable; use bitcoin::util::hash::Sha256dHash; use bitcoin::blockdata::block::{Block, BlockHeader}; use bitcoin::blockdata::transaction::{Transaction, TxOut}; - use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint; use bitcoin::blockdata::constants::genesis_block; use bitcoin::network::constants::Network; use bitcoin::network::serialize::serialize; @@ -2391,6 +2502,15 @@ mod tests { network_payment_count: Rc>, network_chan_count: Rc>, } + impl Drop for Node { + fn drop(&mut self) { + if !::std::thread::panicking() { + // Check that we processed all pending events + assert_eq!(self.node.get_and_clear_pending_events().len(), 0); + assert_eq!(self.chan_monitor.added_monitors.lock().unwrap().len(), 0); + } + } + } fn create_chan_between_nodes(node_a: &Node, node_b: &Node) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) { node_a.node.create_channel(node_b.node.get_our_node_id(), 100000, 10001, 42).unwrap(); @@ -2604,10 +2724,11 @@ mod tests { impl SendEvent { fn from_event(event: Event) -> SendEvent { match event { - Event::UpdateHTLCs { node_id, updates: msgs::CommitmentUpdate { update_add_htlcs, update_fulfill_htlcs, update_fail_htlcs, update_fail_malformed_htlcs, commitment_signed } } => { + Event::UpdateHTLCs { node_id, updates: msgs::CommitmentUpdate { update_add_htlcs, update_fulfill_htlcs, update_fail_htlcs, update_fail_malformed_htlcs, update_fee, commitment_signed } } => { assert!(update_fulfill_htlcs.is_empty()); assert!(update_fail_htlcs.is_empty()); assert!(update_fail_malformed_htlcs.is_empty()); + assert!(update_fee.is_none()); SendEvent { node_id: node_id, msgs: update_add_htlcs, commitment_msg: commitment_signed } }, _ => panic!("Unexpected event type!"), @@ -2615,36 +2736,28 @@ mod tests { } } + macro_rules! check_added_monitors { + ($node: expr, $count: expr) => { + { + let mut added_monitors = $node.chan_monitor.added_monitors.lock().unwrap(); + assert_eq!(added_monitors.len(), $count); + added_monitors.clear(); + } + } + } + macro_rules! commitment_signed_dance { ($node_a: expr, $node_b: expr, $commitment_signed: expr, $fail_backwards: expr) => { { - { - let added_monitors = $node_a.chan_monitor.added_monitors.lock().unwrap(); - assert!(added_monitors.is_empty()); - } + check_added_monitors!($node_a, 0); let (as_revoke_and_ack, as_commitment_signed) = $node_a.node.handle_commitment_signed(&$node_b.node.get_our_node_id(), &$commitment_signed).unwrap(); - { - let mut added_monitors = $node_a.chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } - { - let added_monitors = $node_b.chan_monitor.added_monitors.lock().unwrap(); - assert!(added_monitors.is_empty()); - } + check_added_monitors!($node_a, 1); + check_added_monitors!($node_b, 0); assert!($node_b.node.handle_revoke_and_ack(&$node_a.node.get_our_node_id(), &as_revoke_and_ack).unwrap().is_none()); - { - let mut added_monitors = $node_b.chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } + check_added_monitors!($node_b, 1); let (bs_revoke_and_ack, bs_none) = $node_b.node.handle_commitment_signed(&$node_a.node.get_our_node_id(), &as_commitment_signed.unwrap()).unwrap(); assert!(bs_none.is_none()); - { - let mut added_monitors = $node_b.chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } + check_added_monitors!($node_b, 1); if $fail_backwards { assert!($node_a.node.get_and_clear_pending_events().is_empty()); } @@ -2663,24 +2776,26 @@ mod tests { } } + macro_rules! get_payment_preimage_hash { + ($node: expr) => { + { + let payment_preimage = [*$node.network_payment_count.borrow(); 32]; + *$node.network_payment_count.borrow_mut() += 1; + let mut payment_hash = [0; 32]; + let mut sha = Sha256::new(); + sha.input(&payment_preimage[..]); + sha.result(&mut payment_hash); + (payment_preimage, payment_hash) + } + } + } + fn send_along_route(origin_node: &Node, route: Route, expected_route: &[&Node], recv_value: u64) -> ([u8; 32], [u8; 32]) { - let our_payment_preimage = [*origin_node.network_payment_count.borrow(); 32]; - *origin_node.network_payment_count.borrow_mut() += 1; - let our_payment_hash = { - let mut sha = Sha256::new(); - sha.input(&our_payment_preimage[..]); - let mut ret = [0; 32]; - sha.result(&mut ret); - ret - }; + let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(origin_node); let mut payment_event = { origin_node.node.send_payment(route, our_payment_hash).unwrap(); - { - let mut added_monitors = origin_node.chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } + check_added_monitors!(origin_node, 1); let mut events = origin_node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); @@ -2692,11 +2807,7 @@ mod tests { assert_eq!(node.node.get_our_node_id(), payment_event.node_id); node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]).unwrap(); - { - let added_monitors = node.chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 0); - } - + check_added_monitors!(node, 0); commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false); let events_1 = node.node.get_and_clear_pending_events(); @@ -2720,11 +2831,7 @@ mod tests { _ => panic!("Unexpected event"), } } else { - { - let mut added_monitors = node.chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } + check_added_monitors!(node, 1); payment_event = SendEvent::from_event(events_2.remove(0)); assert_eq!(payment_event.msgs.len(), 1); } @@ -2735,27 +2842,19 @@ mod tests { (our_payment_preimage, our_payment_hash) } - fn claim_payment(origin_node: &Node, expected_route: &[&Node], our_payment_preimage: [u8; 32]) { + fn claim_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_preimage: [u8; 32]) { assert!(expected_route.last().unwrap().node.claim_funds(our_payment_preimage)); - { - let mut added_monitors = expected_route.last().unwrap().chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } + check_added_monitors!(expected_route.last().unwrap(), 1); let mut next_msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)> = None; macro_rules! update_fulfill_dance { ($node: expr, $prev_node: expr, $last_node: expr) => { { $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0).unwrap(); - { - let mut added_monitors = $node.chan_monitor.added_monitors.lock().unwrap(); - if $last_node { - assert_eq!(added_monitors.len(), 0); - } else { - assert_eq!(added_monitors.len(), 1); - } - added_monitors.clear(); + if $last_node { + check_added_monitors!($node, 0); + } else { + check_added_monitors!($node, 1); } commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false); } @@ -2764,40 +2863,52 @@ mod tests { let mut expected_next_node = expected_route.last().unwrap().node.get_our_node_id(); let mut prev_node = expected_route.last().unwrap(); - for node in expected_route.iter().rev() { + for (idx, node) in expected_route.iter().rev().enumerate() { assert_eq!(expected_next_node, node.node.get_our_node_id()); if next_msgs.is_some() { update_fulfill_dance!(node, prev_node, false); } let events = node.node.get_and_clear_pending_events(); + if !skip_last || idx != expected_route.len() - 1 { + assert_eq!(events.len(), 1); + match events[0] { + Event::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => { + assert!(update_add_htlcs.is_empty()); + assert_eq!(update_fulfill_htlcs.len(), 1); + assert!(update_fail_htlcs.is_empty()); + assert!(update_fail_malformed_htlcs.is_empty()); + assert!(update_fee.is_none()); + expected_next_node = node_id.clone(); + next_msgs = Some((update_fulfill_htlcs[0].clone(), commitment_signed.clone())); + }, + _ => panic!("Unexpected event"), + } + } else { + assert!(events.is_empty()); + } + if !skip_last && idx == expected_route.len() - 1 { + assert_eq!(expected_next_node, origin_node.node.get_our_node_id()); + } + + prev_node = node; + } + + if !skip_last { + update_fulfill_dance!(origin_node, expected_route.first().unwrap(), true); + let events = origin_node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - Event::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref commitment_signed } } => { - assert!(update_add_htlcs.is_empty()); - assert_eq!(update_fulfill_htlcs.len(), 1); - assert!(update_fail_htlcs.is_empty()); - assert!(update_fail_malformed_htlcs.is_empty()); - expected_next_node = node_id.clone(); - next_msgs = Some((update_fulfill_htlcs[0].clone(), commitment_signed.clone())); + Event::PaymentSent { payment_preimage } => { + assert_eq!(payment_preimage, our_payment_preimage); }, _ => panic!("Unexpected event"), - }; - - prev_node = node; + } } + } - assert_eq!(expected_next_node, origin_node.node.get_our_node_id()); - update_fulfill_dance!(origin_node, expected_route.first().unwrap(), true); - - let events = origin_node.node.get_and_clear_pending_events(); - assert_eq!(events.len(), 1); - match events[0] { - Event::PaymentSent { payment_preimage } => { - assert_eq!(payment_preimage, our_payment_preimage); - }, - _ => panic!("Unexpected event"), - } + fn claim_payment(origin_node: &Node, expected_route: &[&Node], our_payment_preimage: [u8; 32]) { + claim_payment_along_route(origin_node, expected_route, false, our_payment_preimage); } const TEST_FINAL_CLTV: u32 = 32; @@ -2819,15 +2930,7 @@ mod tests { assert_eq!(hop.pubkey, node.node.get_our_node_id()); } - let our_payment_preimage = [*origin_node.network_payment_count.borrow(); 32]; - *origin_node.network_payment_count.borrow_mut() += 1; - let our_payment_hash = { - let mut sha = Sha256::new(); - sha.input(&our_payment_preimage[..]); - let mut ret = [0; 32]; - sha.result(&mut ret); - ret - }; + let (_, our_payment_hash) = get_payment_preimage_hash!(origin_node); let err = origin_node.node.send_payment(route, our_payment_hash).err().unwrap(); match err { @@ -2841,13 +2944,9 @@ mod tests { claim_payment(&origin, expected_route, our_payment_preimage); } - fn fail_payment(origin_node: &Node, expected_route: &[&Node], our_payment_hash: [u8; 32]) { + fn fail_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_hash: [u8; 32]) { assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash)); - { - let mut added_monitors = expected_route.last().unwrap().chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } + check_added_monitors!(expected_route.last().unwrap(), 1); let mut next_msgs: Option<(msgs::UpdateFailHTLC, msgs::CommitmentSigned)> = None; macro_rules! update_fail_dance { @@ -2861,42 +2960,58 @@ mod tests { let mut expected_next_node = expected_route.last().unwrap().node.get_our_node_id(); let mut prev_node = expected_route.last().unwrap(); - for node in expected_route.iter().rev() { + for (idx, node) in expected_route.iter().rev().enumerate() { assert_eq!(expected_next_node, node.node.get_our_node_id()); if next_msgs.is_some() { - update_fail_dance!(node, prev_node, false); + // We may be the "last node" for the purpose of the commitment dance if we're + // skipping the last node (implying it is disconnected) and we're the + // second-to-last node! + update_fail_dance!(node, prev_node, skip_last && idx == expected_route.len() - 1); } let events = node.node.get_and_clear_pending_events(); - assert_eq!(events.len(), 1); - match events[0] { - Event::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref commitment_signed } } => { - assert!(update_add_htlcs.is_empty()); - assert!(update_fulfill_htlcs.is_empty()); - assert_eq!(update_fail_htlcs.len(), 1); - assert!(update_fail_malformed_htlcs.is_empty()); - expected_next_node = node_id.clone(); - next_msgs = Some((update_fail_htlcs[0].clone(), commitment_signed.clone())); - }, - _ => panic!("Unexpected event"), - }; + if !skip_last || idx != expected_route.len() - 1 { + assert_eq!(events.len(), 1); + match events[0] { + Event::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => { + assert!(update_add_htlcs.is_empty()); + assert!(update_fulfill_htlcs.is_empty()); + assert_eq!(update_fail_htlcs.len(), 1); + assert!(update_fail_malformed_htlcs.is_empty()); + assert!(update_fee.is_none()); + expected_next_node = node_id.clone(); + next_msgs = Some((update_fail_htlcs[0].clone(), commitment_signed.clone())); + }, + _ => panic!("Unexpected event"), + } + } else { + assert!(events.is_empty()); + } + if !skip_last && idx == expected_route.len() - 1 { + assert_eq!(expected_next_node, origin_node.node.get_our_node_id()); + } prev_node = node; } - assert_eq!(expected_next_node, origin_node.node.get_our_node_id()); - update_fail_dance!(origin_node, expected_route.first().unwrap(), true); + if !skip_last { + update_fail_dance!(origin_node, expected_route.first().unwrap(), true); - let events = origin_node.node.get_and_clear_pending_events(); - assert_eq!(events.len(), 1); - match events[0] { - Event::PaymentFailed { payment_hash } => { - assert_eq!(payment_hash, our_payment_hash); - }, - _ => panic!("Unexpected event"), + let events = origin_node.node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::PaymentFailed { payment_hash } => { + assert_eq!(payment_hash, our_payment_hash); + }, + _ => panic!("Unexpected event"), + } } } + fn fail_payment(origin_node: &Node, expected_route: &[&Node], our_payment_hash: [u8; 32]) { + fail_payment_along_route(origin_node, expected_route, false, our_payment_hash); + } + fn create_network(node_count: usize) -> Vec { let mut nodes = Vec::new(); let mut rng = thread_rng(); @@ -2927,6 +3042,425 @@ mod tests { nodes } + #[test] + fn test_async_inbound_update_fee() { + let mut nodes = create_network(2); + let chan = create_announced_chan_between_nodes(&nodes, 0, 1); + let channel_id = chan.2; + + macro_rules! get_feerate { + ($node: expr) => {{ + let chan_lock = $node.node.channel_state.lock().unwrap(); + let chan = chan_lock.by_id.get(&channel_id).unwrap(); + chan.get_feerate() + }} + } + + // balancing + send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000); + + // A B + // update_fee -> + // send (1) commitment_signed -. + // <- update_add_htlc/commitment_signed + // send (2) RAA (awaiting remote revoke) -. + // (1) commitment_signed is delivered -> + // .- send (3) RAA (awaiting remote revoke) + // (2) RAA is delivered -> + // .- send (4) commitment_signed + // <- (3) RAA is delivered + // send (5) commitment_signed -. + // <- (4) commitment_signed is delivered + // send (6) RAA -. + // (5) commitment_signed is delivered -> + // <- RAA + // (6) RAA is delivered -> + + // First nodes[0] generates an update_fee + nodes[0].node.update_fee(channel_id, get_feerate!(nodes[0]) + 20).unwrap(); + check_added_monitors!(nodes[0], 1); + + let events_0 = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events_0.len(), 1); + let (update_msg, commitment_signed) = match events_0[0] { // (1) + Event::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, ref commitment_signed, .. }, .. } => { + (update_fee.as_ref(), commitment_signed) + }, + _ => panic!("Unexpected event"), + }; + + nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg.unwrap()).unwrap(); + + // ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]... + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + nodes[1].node.send_payment(nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 40000, TEST_FINAL_CLTV).unwrap(), our_payment_hash).unwrap(); + check_added_monitors!(nodes[1], 1); + + let payment_event = { + let mut events_1 = nodes[1].node.get_and_clear_pending_events(); + assert_eq!(events_1.len(), 1); + SendEvent::from_event(events_1.remove(0)) + }; + assert_eq!(payment_event.node_id, nodes[0].node.get_our_node_id()); + assert_eq!(payment_event.msgs.len(), 1); + + // ...now when the messages get delivered everyone should be happy + nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]).unwrap(); + let (as_revoke_msg, as_commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &payment_event.commitment_msg).unwrap(); // (2) + assert!(as_commitment_signed.is_none()); // nodes[0] is awaiting nodes[1] revoke_and_ack + check_added_monitors!(nodes[0], 1); + + // deliver(1), generate (3): + let (bs_revoke_msg, bs_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); + assert!(bs_commitment_signed.is_none()); // nodes[1] is awaiting nodes[0] revoke_and_ack + check_added_monitors!(nodes[1], 1); + + let bs_update = nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_msg).unwrap(); // deliver (2) + assert!(bs_update.as_ref().unwrap().update_add_htlcs.is_empty()); // (4) + assert!(bs_update.as_ref().unwrap().update_fulfill_htlcs.is_empty()); // (4) + assert!(bs_update.as_ref().unwrap().update_fail_htlcs.is_empty()); // (4) + assert!(bs_update.as_ref().unwrap().update_fail_malformed_htlcs.is_empty()); // (4) + assert!(bs_update.as_ref().unwrap().update_fee.is_none()); // (4) + check_added_monitors!(nodes[1], 1); + + let as_update = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_msg).unwrap(); // deliver (3) + assert!(as_update.as_ref().unwrap().update_add_htlcs.is_empty()); // (5) + assert!(as_update.as_ref().unwrap().update_fulfill_htlcs.is_empty()); // (5) + assert!(as_update.as_ref().unwrap().update_fail_htlcs.is_empty()); // (5) + assert!(as_update.as_ref().unwrap().update_fail_malformed_htlcs.is_empty()); // (5) + assert!(as_update.as_ref().unwrap().update_fee.is_none()); // (5) + check_added_monitors!(nodes[0], 1); + + let (as_second_revoke, as_second_commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_update.unwrap().commitment_signed).unwrap(); // deliver (4) + assert!(as_second_commitment_signed.is_none()); // only (6) + check_added_monitors!(nodes[0], 1); + + let (bs_second_revoke, bs_second_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_update.unwrap().commitment_signed).unwrap(); // deliver (5) + assert!(bs_second_commitment_signed.is_none()); + check_added_monitors!(nodes[1], 1); + + assert!(nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_revoke).unwrap().is_none()); + check_added_monitors!(nodes[0], 1); + + let events_2 = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events_2.len(), 1); + match events_2[0] { + Event::PendingHTLCsForwardable {..} => {}, // If we actually processed we'd receive the payment + _ => panic!("Unexpected event"), + } + + assert!(nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_revoke).unwrap().is_none()); // deliver (6) + check_added_monitors!(nodes[1], 1); + } + + #[test] + fn test_update_fee_unordered_raa() { + // Just the intro to the previous test followed by an out-of-order RAA (which caused a + // crash in an earlier version of the update_fee patch) + let mut nodes = create_network(2); + let chan = create_announced_chan_between_nodes(&nodes, 0, 1); + let channel_id = chan.2; + + macro_rules! get_feerate { + ($node: expr) => {{ + let chan_lock = $node.node.channel_state.lock().unwrap(); + let chan = chan_lock.by_id.get(&channel_id).unwrap(); + chan.get_feerate() + }} + } + + // balancing + send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000); + + // First nodes[0] generates an update_fee + nodes[0].node.update_fee(channel_id, get_feerate!(nodes[0]) + 20).unwrap(); + check_added_monitors!(nodes[0], 1); + + let events_0 = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events_0.len(), 1); + let update_msg = match events_0[0] { // (1) + Event::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, .. }, .. } => { + update_fee.as_ref() + }, + _ => panic!("Unexpected event"), + }; + + nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg.unwrap()).unwrap(); + + // ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]... + let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); + nodes[1].node.send_payment(nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 40000, TEST_FINAL_CLTV).unwrap(), our_payment_hash).unwrap(); + check_added_monitors!(nodes[1], 1); + + let payment_event = { + let mut events_1 = nodes[1].node.get_and_clear_pending_events(); + assert_eq!(events_1.len(), 1); + SendEvent::from_event(events_1.remove(0)) + }; + assert_eq!(payment_event.node_id, nodes[0].node.get_our_node_id()); + assert_eq!(payment_event.msgs.len(), 1); + + // ...now when the messages get delivered everyone should be happy + nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]).unwrap(); + let (as_revoke_msg, as_commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &payment_event.commitment_msg).unwrap(); // (2) + assert!(as_commitment_signed.is_none()); // nodes[0] is awaiting nodes[1] revoke_and_ack + check_added_monitors!(nodes[0], 1); + + assert!(nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_msg).unwrap().is_none()); // deliver (2) + check_added_monitors!(nodes[1], 1); + + // We can't continue, sadly, because our (1) now has a bogus signature + } + + #[test] + fn test_update_fee_vanilla() { + let nodes = create_network(2); + let chan = create_announced_chan_between_nodes(&nodes, 0, 1); + let channel_id = chan.2; + + macro_rules! get_feerate { + ($node: expr) => {{ + let chan_lock = $node.node.channel_state.lock().unwrap(); + let chan = chan_lock.by_id.get(&channel_id).unwrap(); + chan.get_feerate() + }} + } + + let feerate = get_feerate!(nodes[0]); + nodes[0].node.update_fee(channel_id, feerate+20).unwrap(); + + let events_0 = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events_0.len(), 1); + let (update_msg, commitment_signed) = match events_0[0] { + Event::UpdateHTLCs { node_id:_, updates: msgs::CommitmentUpdate { update_add_htlcs:_, update_fulfill_htlcs:_, update_fail_htlcs:_, update_fail_malformed_htlcs:_, ref update_fee, ref commitment_signed } } => { + (update_fee.as_ref(), commitment_signed) + }, + _ => panic!("Unexpected event"), + }; + nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg.unwrap()).unwrap(); + + let (revoke_msg, commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); + let commitment_signed = commitment_signed.unwrap(); + check_added_monitors!(nodes[0], 1); + check_added_monitors!(nodes[1], 1); + + let resp_option = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(resp_option.is_none()); + check_added_monitors!(nodes[0], 1); + + let (revoke_msg, commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed).unwrap(); + assert!(commitment_signed.is_none()); + check_added_monitors!(nodes[0], 1); + + let resp_option = nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(resp_option.is_none()); + check_added_monitors!(nodes[1], 1); + } + + #[test] + fn test_update_fee_with_fundee_update_add_htlc() { + let mut nodes = create_network(2); + let chan = create_announced_chan_between_nodes(&nodes, 0, 1); + let channel_id = chan.2; + + macro_rules! get_feerate { + ($node: expr) => {{ + let chan_lock = $node.node.channel_state.lock().unwrap(); + let chan = chan_lock.by_id.get(&channel_id).unwrap(); + chan.get_feerate() + }} + } + + // balancing + send_payment(&nodes[0], &vec!(&nodes[1])[..], 8000000); + + let feerate = get_feerate!(nodes[0]); + nodes[0].node.update_fee(channel_id, feerate+20).unwrap(); + + let events_0 = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events_0.len(), 1); + let (update_msg, commitment_signed) = match events_0[0] { + Event::UpdateHTLCs { node_id:_, updates: msgs::CommitmentUpdate { update_add_htlcs:_, update_fulfill_htlcs:_, update_fail_htlcs:_, update_fail_malformed_htlcs:_, ref update_fee, ref commitment_signed } } => { + (update_fee.as_ref(), commitment_signed) + }, + _ => panic!("Unexpected event"), + }; + nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg.unwrap()).unwrap(); + check_added_monitors!(nodes[0], 1); + let (revoke_msg, commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); + let commitment_signed = commitment_signed.unwrap(); + check_added_monitors!(nodes[1], 1); + + let route = nodes[1].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 800000, TEST_FINAL_CLTV).unwrap(); + + let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(nodes[1]); + + // nothing happens since node[1] is in AwaitingRemoteRevoke + nodes[1].node.send_payment(route, our_payment_hash).unwrap(); + { + let mut added_monitors = nodes[0].chan_monitor.added_monitors.lock().unwrap(); + assert_eq!(added_monitors.len(), 0); + added_monitors.clear(); + } + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 0); + // node[1] has nothing to do + + let resp_option = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(resp_option.is_none()); + check_added_monitors!(nodes[0], 1); + + let (revoke_msg, commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed).unwrap(); + assert!(commitment_signed.is_none()); + check_added_monitors!(nodes[0], 1); + let resp_option = nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke_msg).unwrap(); + // AwaitingRemoteRevoke ends here + + let commitment_update = resp_option.unwrap(); + assert_eq!(commitment_update.update_add_htlcs.len(), 1); + assert_eq!(commitment_update.update_fulfill_htlcs.len(), 0); + assert_eq!(commitment_update.update_fail_htlcs.len(), 0); + assert_eq!(commitment_update.update_fail_malformed_htlcs.len(), 0); + assert_eq!(commitment_update.update_fee.is_none(), true); + + nodes[0].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &commitment_update.update_add_htlcs[0]).unwrap(); + let (revoke, commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_update.commitment_signed).unwrap(); + check_added_monitors!(nodes[0], 1); + check_added_monitors!(nodes[1], 1); + let commitment_signed = commitment_signed.unwrap(); + let resp_option = nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke).unwrap(); + check_added_monitors!(nodes[1], 1); + assert!(resp_option.is_none()); + + let (revoke, commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &commitment_signed).unwrap(); + check_added_monitors!(nodes[1], 1); + assert!(commitment_signed.is_none()); + let resp_option = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &revoke).unwrap(); + check_added_monitors!(nodes[0], 1); + assert!(resp_option.is_none()); + + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::PendingHTLCsForwardable { .. } => { }, + _ => panic!("Unexpected event"), + }; + nodes[0].node.channel_state.lock().unwrap().next_forward = Instant::now(); + nodes[0].node.process_pending_htlc_forwards(); + + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::PaymentReceived { .. } => { }, + _ => panic!("Unexpected event"), + }; + + claim_payment(&nodes[1], &vec!(&nodes[0])[..], our_payment_preimage); + + send_payment(&nodes[1], &vec!(&nodes[0])[..], 800000); + send_payment(&nodes[0], &vec!(&nodes[1])[..], 800000); + close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true); + } + + #[test] + fn test_update_fee() { + let nodes = create_network(2); + let chan = create_announced_chan_between_nodes(&nodes, 0, 1); + let channel_id = chan.2; + + macro_rules! get_feerate { + ($node: expr) => {{ + let chan_lock = $node.node.channel_state.lock().unwrap(); + let chan = chan_lock.by_id.get(&channel_id).unwrap(); + chan.get_feerate() + }} + } + + // A B + // (1) update_fee/commitment_signed -> + // <- (2) revoke_and_ack + // .- send (3) commitment_signed + // (4) update_fee/commitment_signed -> + // .- send (5) revoke_and_ack (no CS as we're awaiting a revoke) + // <- (3) commitment_signed delivered + // send (6) revoke_and_ack -. + // <- (5) deliver revoke_and_ack + // (6) deliver revoke_and_ack -> + // .- send (7) commitment_signed in response to (4) + // <- (7) deliver commitment_signed + // revoke_and_ack -> + + // Create and deliver (1)... + let feerate = get_feerate!(nodes[0]); + nodes[0].node.update_fee(channel_id, feerate+20).unwrap(); + + let events_0 = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events_0.len(), 1); + let (update_msg, commitment_signed) = match events_0[0] { + Event::UpdateHTLCs { node_id:_, updates: msgs::CommitmentUpdate { update_add_htlcs:_, update_fulfill_htlcs:_, update_fail_htlcs:_, update_fail_malformed_htlcs:_, ref update_fee, ref commitment_signed } } => { + (update_fee.as_ref(), commitment_signed) + }, + _ => panic!("Unexpected event"), + }; + nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg.unwrap()).unwrap(); + + // Generate (2) and (3): + let (revoke_msg, commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); + let commitment_signed_0 = commitment_signed.unwrap(); + check_added_monitors!(nodes[0], 1); + check_added_monitors!(nodes[1], 1); + + // Deliver (2): + let resp_option = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(resp_option.is_none()); + check_added_monitors!(nodes[0], 1); + + // Create and deliver (4)... + nodes[0].node.update_fee(channel_id, feerate+30).unwrap(); + let events_0 = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events_0.len(), 1); + let (update_msg, commitment_signed) = match events_0[0] { + Event::UpdateHTLCs { node_id:_, updates: msgs::CommitmentUpdate { update_add_htlcs:_, update_fulfill_htlcs:_, update_fail_htlcs:_, update_fail_malformed_htlcs:_, ref update_fee, ref commitment_signed } } => { + (update_fee.as_ref(), commitment_signed) + }, + _ => panic!("Unexpected event"), + }; + nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg.unwrap()).unwrap(); + + let (revoke_msg, commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); + // ... creating (5) + assert!(commitment_signed.is_none()); + check_added_monitors!(nodes[0], 1); + check_added_monitors!(nodes[1], 1); + + // Handle (3), creating (6): + let (revoke_msg_0, commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed_0).unwrap(); + assert!(commitment_signed.is_none()); + check_added_monitors!(nodes[0], 1); + + // Deliver (5): + let resp_option = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(resp_option.is_none()); + check_added_monitors!(nodes[0], 1); + + // Deliver (6), creating (7): + let resp_option = nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke_msg_0).unwrap(); + let commitment_signed = resp_option.unwrap().commitment_signed; + check_added_monitors!(nodes[1], 1); + + // Deliver (7) + let (revoke_msg, commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed).unwrap(); + assert!(commitment_signed.is_none()); + check_added_monitors!(nodes[0], 1); + let resp_option = nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(resp_option.is_none()); + check_added_monitors!(nodes[1], 1); + + assert_eq!(get_feerate!(nodes[0]), feerate + 30); + assert_eq!(get_feerate!(nodes[1]), feerate + 30); + close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true); + } + #[test] fn fake_network_test() { // Simple test which builds a network of ChannelManagers, connects them to each other, and @@ -3037,12 +3571,6 @@ mod tests { close_channel(&nodes[2], &nodes[3], &chan_3.2, chan_3.3, true); close_channel(&nodes[1], &nodes[3], &chan_4.2, chan_4.3, false); close_channel(&nodes[1], &nodes[3], &chan_5.2, chan_5.3, false); - - // Check that we processed all pending events - for node in nodes { - assert_eq!(node.node.get_and_clear_pending_events().len(), 0); - assert_eq!(node.chan_monitor.added_monitors.lock().unwrap().len(), 0); - } } #[test] @@ -3245,11 +3773,7 @@ mod tests { ($node: expr, $prev_node: expr, $preimage: expr) => { { assert!($node.node.claim_funds($preimage)); - { - let mut added_monitors = $node.chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } + check_added_monitors!($node, 1); let events = $node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); @@ -3352,12 +3876,6 @@ mod tests { get_announce_close_broadcast_events(&nodes, 0, 1); assert_eq!(nodes[0].node.list_channels().len(), 0); assert_eq!(nodes[1].node.list_channels().len(), 0); - - // Check that we processed all pending events - for node in nodes { - assert_eq!(node.node.get_and_clear_pending_events().len(), 0); - assert_eq!(node.chan_monitor.added_monitors.lock().unwrap().len(), 0); - } } #[test] @@ -3411,23 +3929,11 @@ mod tests { let route = nodes[0].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 1000000, 42).unwrap(); - let our_payment_preimage = [*nodes[0].network_payment_count.borrow(); 32]; - *nodes[0].network_payment_count.borrow_mut() += 1; - let our_payment_hash = { - let mut sha = Sha256::new(); - sha.input(&our_payment_preimage[..]); - let mut ret = [0; 32]; - sha.result(&mut ret); - ret - }; + let (our_payment_preimage, our_payment_hash) = get_payment_preimage_hash!(nodes[0]); let mut payment_event = { nodes[0].node.send_payment(route, our_payment_hash).unwrap(); - { - let mut added_monitors = nodes[0].chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } + check_added_monitors!(nodes[0], 1); let mut events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); @@ -3452,20 +3958,10 @@ mod tests { payment_event = SendEvent::from_event(events_2.remove(0)); assert_eq!(payment_event.msgs.len(), 1); - { - let mut added_monitors = nodes[1].chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } - + check_added_monitors!(nodes[1], 1); nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &payment_event.msgs[0]).unwrap(); nodes[2].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &payment_event.commitment_msg).unwrap(); - - { - let mut added_monitors = nodes[2].chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - added_monitors.clear(); - } + check_added_monitors!(nodes[2], 1); // nodes[2] now has the latest commitment transaction, but hasn't revoked its previous // state or updated nodes[1]' state. Now force-close and broadcast that commitment/HTLC @@ -3542,11 +4038,156 @@ mod tests { while !headers.is_empty() { nodes[0].node.block_disconnected(&headers.pop().unwrap()); } + { + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 1); + match events[0] { + Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { + assert_eq!(flags & 0b10, 0b10); + }, + _ => panic!("Unexpected event"), + } + } let channel_state = nodes[0].node.channel_state.lock().unwrap(); assert_eq!(channel_state.by_id.len(), 0); assert_eq!(channel_state.short_to_id.len(), 0); } + fn reconnect_nodes(node_a: &Node, node_b: &Node, pre_all_htlcs: bool, pending_htlc_claims: (usize, usize), pending_htlc_fails: (usize, usize)) { + let reestablish_1 = node_a.node.peer_connected(&node_b.node.get_our_node_id()); + let reestablish_2 = node_b.node.peer_connected(&node_a.node.get_our_node_id()); + + let mut resp_1 = Vec::new(); + for msg in reestablish_1 { + resp_1.push(node_b.node.handle_channel_reestablish(&node_a.node.get_our_node_id(), &msg).unwrap()); + } + if pending_htlc_claims.0 != 0 || pending_htlc_fails.0 != 0 { + check_added_monitors!(node_b, 1); + } else { + check_added_monitors!(node_b, 0); + } + + let mut resp_2 = Vec::new(); + for msg in reestablish_2 { + resp_2.push(node_a.node.handle_channel_reestablish(&node_b.node.get_our_node_id(), &msg).unwrap()); + } + if pending_htlc_claims.1 != 0 || pending_htlc_fails.1 != 0 { + check_added_monitors!(node_a, 1); + } else { + check_added_monitors!(node_a, 0); + } + + // We dont yet support both needing updates, as that would require a different commitment dance: + assert!((pending_htlc_claims.0 == 0 && pending_htlc_fails.0 == 0) || (pending_htlc_claims.1 == 0 && pending_htlc_fails.1 == 0)); + + for chan_msgs in resp_1.drain(..) { + if pre_all_htlcs { + let _announcement_sigs_opt = node_a.node.handle_funding_locked(&node_b.node.get_our_node_id(), &chan_msgs.0.unwrap()).unwrap(); + //TODO: Test announcement_sigs re-sending when we've implemented it + } else { + assert!(chan_msgs.0.is_none()); + } + assert!(chan_msgs.1.is_none()); + if pending_htlc_claims.0 != 0 || pending_htlc_fails.0 != 0 { + let commitment_update = chan_msgs.2.unwrap(); + assert!(commitment_update.update_add_htlcs.is_empty()); // We can't relay while disconnected + assert_eq!(commitment_update.update_fulfill_htlcs.len(), pending_htlc_claims.0); + assert_eq!(commitment_update.update_fail_htlcs.len(), pending_htlc_fails.0); + assert!(commitment_update.update_fail_malformed_htlcs.is_empty()); + for update_fulfill in commitment_update.update_fulfill_htlcs { + node_a.node.handle_update_fulfill_htlc(&node_b.node.get_our_node_id(), &update_fulfill).unwrap(); + } + for update_fail in commitment_update.update_fail_htlcs { + node_a.node.handle_update_fail_htlc(&node_b.node.get_our_node_id(), &update_fail).unwrap(); + } + + commitment_signed_dance!(node_a, node_b, commitment_update.commitment_signed, false); + } else { + assert!(chan_msgs.2.is_none()); + } + } + + for chan_msgs in resp_2.drain(..) { + if pre_all_htlcs { + let _announcement_sigs_opt = node_b.node.handle_funding_locked(&node_a.node.get_our_node_id(), &chan_msgs.0.unwrap()).unwrap(); + //TODO: Test announcement_sigs re-sending when we've implemented it + } else { + assert!(chan_msgs.0.is_none()); + } + assert!(chan_msgs.1.is_none()); + if pending_htlc_claims.1 != 0 || pending_htlc_fails.1 != 0 { + let commitment_update = chan_msgs.2.unwrap(); + assert!(commitment_update.update_add_htlcs.is_empty()); // We can't relay while disconnected + assert_eq!(commitment_update.update_fulfill_htlcs.len(), pending_htlc_claims.0); + assert_eq!(commitment_update.update_fail_htlcs.len(), pending_htlc_fails.0); + assert!(commitment_update.update_fail_malformed_htlcs.is_empty()); + for update_fulfill in commitment_update.update_fulfill_htlcs { + node_b.node.handle_update_fulfill_htlc(&node_a.node.get_our_node_id(), &update_fulfill).unwrap(); + } + for update_fail in commitment_update.update_fail_htlcs { + node_b.node.handle_update_fail_htlc(&node_a.node.get_our_node_id(), &update_fail).unwrap(); + } + + commitment_signed_dance!(node_b, node_a, commitment_update.commitment_signed, false); + } else { + assert!(chan_msgs.2.is_none()); + } + } + } + + #[test] + fn test_simple_peer_disconnect() { + // Test that we can reconnect when there are no lost messages + let nodes = create_network(3); + create_announced_chan_between_nodes(&nodes, 0, 1); + create_announced_chan_between_nodes(&nodes, 1, 2); + + nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); + nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); + reconnect_nodes(&nodes[0], &nodes[1], true, (0, 0), (0, 0)); + + let payment_preimage_1 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0; + let payment_hash_2 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1; + fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_hash_2); + claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_preimage_1); + + nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); + nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); + reconnect_nodes(&nodes[0], &nodes[1], false, (0, 0), (0, 0)); + + let payment_preimage_3 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0; + let payment_preimage_4 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).0; + let payment_hash_5 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1; + let payment_hash_6 = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 1000000).1; + + nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); + nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); + + claim_payment_along_route(&nodes[0], &vec!(&nodes[1], &nodes[2]), true, payment_preimage_3); + fail_payment_along_route(&nodes[0], &[&nodes[1], &nodes[2]], true, payment_hash_5); + + reconnect_nodes(&nodes[0], &nodes[1], false, (1, 0), (1, 0)); + { + let events = nodes[0].node.get_and_clear_pending_events(); + assert_eq!(events.len(), 2); + match events[0] { + Event::PaymentSent { payment_preimage } => { + assert_eq!(payment_preimage, payment_preimage_3); + }, + _ => panic!("Unexpected event"), + } + match events[1] { + Event::PaymentFailed { payment_hash } => { + assert_eq!(payment_hash, payment_hash_5); + }, + _ => panic!("Unexpected event"), + } + } + + claim_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_preimage_4); + fail_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), payment_hash_6); + } + #[test] fn test_invalid_channel_announcement() { //Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs