From 8c235d9e28da0bcdb1d68166fc771e0c83a7b2fc Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Fri, 19 Oct 2018 02:44:40 +0000 Subject: [PATCH 01/15] Generate Events from ChannelMonitor to indicate spendable ouputs Extend KeyStorage with delayed_payment_base_key and per_commitment_point to derive local_delayed private key --- src/chain/keysinterface.rs | 36 +++++ src/chain/mod.rs | 1 + src/ln/channel.rs | 6 +- src/ln/channelmonitor.rs | 264 ++++++++++++++++++++++++++++--------- src/ln/peer_handler.rs | 1 + src/util/events.rs | 8 ++ 6 files changed, 249 insertions(+), 67 deletions(-) create mode 100644 src/chain/keysinterface.rs diff --git a/src/chain/keysinterface.rs b/src/chain/keysinterface.rs new file mode 100644 index 00000000000..bab21fd2b0b --- /dev/null +++ b/src/chain/keysinterface.rs @@ -0,0 +1,36 @@ +//! keysinterface provides keys into rust-lightning and defines some useful enums which describe +//! spendable on-chain outputs which the user owns and is responsible for using just as any other +//! on-chain output which is theirs. + +use bitcoin::blockdata::transaction::{OutPoint, TxOut}; +use bitcoin::blockdata::script::Script; + +use secp256k1::key::SecretKey; + +/// When on-chain outputs are created by rust-lightning an event is generated which informs the +/// user thereof. This enum describes the format of the output and provides the OutPoint. +pub enum SpendableOutputDescriptor { + /// Outpoint with an output to a script which was provided via KeysInterface, thus you should + /// have stored somewhere how to spend script_pubkey! + /// Outputs from a justice tx, claim tx or preimage tx + StaticOutput { + /// The outpoint spendable by user wallet + outpoint: OutPoint, + /// The output which is referenced by the given outpoint + output: TxOut, + }, + /// Outpoint commits to a P2WSH, should be spend by the following witness : + /// 0 + /// With input nSequence set to_self_delay. + /// Outputs from a HTLC-Success/Timeout tx + DynamicOutput { + /// Outpoint spendable by user wallet + outpoint: OutPoint, + /// local_delayedkey = delayed_payment_basepoint_secret + SHA256(per_commitment_point || delayed_payment_basepoint + local_delayedkey: SecretKey, + /// witness redeemScript encumbering output + witness_script: Script, + /// nSequence input must commit to self_delay to satisfy script's OP_CSV + to_self_delay: u16, + } +} diff --git a/src/chain/mod.rs b/src/chain/mod.rs index 95fdce81727..ffa5ed968be 100644 --- a/src/chain/mod.rs +++ b/src/chain/mod.rs @@ -2,3 +2,4 @@ pub mod chaininterface; pub mod transaction; +pub mod keysinterface; diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 6b1511387d6..e8d7f538fd9 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -489,8 +489,7 @@ impl Channel { let secp_ctx = Secp256k1::new(); let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).serialize()); let our_channel_monitor_claim_script = Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script(); - let channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, - &PublicKey::from_secret_key(&secp_ctx, &chan_keys.delayed_payment_base_key), + let channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key, &chan_keys.htlc_base_key, BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script); @@ -651,8 +650,7 @@ impl Channel { let secp_ctx = Secp256k1::new(); let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).serialize()); let our_channel_monitor_claim_script = Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script(); - let mut channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, - &PublicKey::from_secret_key(&secp_ctx, &chan_keys.delayed_payment_base_key), + let mut channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key, &chan_keys.htlc_base_key, BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script); channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint); diff --git a/src/ln/channelmonitor.rs b/src/ln/channelmonitor.rs index 60cb9c91583..5adfe926ce2 100644 --- a/src/ln/channelmonitor.rs +++ b/src/ln/channelmonitor.rs @@ -30,13 +30,14 @@ use ln::chan_utils; use ln::chan_utils::HTLCOutputInCommitment; use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInterface}; use chain::transaction::OutPoint; +use chain::keysinterface::SpendableOutputDescriptor; use util::ser::{Readable, Writer}; use util::sha2::Sha256; -use util::byte_utils; +use util::{byte_utils, events}; use std::collections::HashMap; use std::sync::{Arc,Mutex}; -use std::{hash,cmp}; +use std::{hash,cmp, mem}; /// An error enum representing a failure to persist a channel monitor update. #[derive(Clone)] @@ -106,20 +107,31 @@ pub struct SimpleManyChannelMonitor { #[cfg(not(test))] monitors: Mutex>, chain_monitor: Arc, - broadcaster: Arc + broadcaster: Arc, + pending_events: Mutex>, } impl ChainListener for SimpleManyChannelMonitor { fn block_connected(&self, _header: &BlockHeader, height: u32, txn_matched: &[&Transaction], _indexes_of_txn_matched: &[u32]) { - let monitors = self.monitors.lock().unwrap(); - for monitor in monitors.values() { - let txn_outputs = monitor.block_connected(txn_matched, height, &*self.broadcaster); - for (ref txid, ref outputs) in txn_outputs { - for (idx, output) in outputs.iter().enumerate() { - self.chain_monitor.install_watch_outpoint((txid.clone(), idx as u32), &output.script_pubkey); + let mut new_events: Vec = Vec::with_capacity(0); + { + let monitors = self.monitors.lock().unwrap(); + for monitor in monitors.values() { + let (txn_outputs, spendable_outputs) = monitor.block_connected(txn_matched, height, &*self.broadcaster); + if spendable_outputs.len() > 0 { + new_events.push(events::Event::SpendableOutputs { + outputs: spendable_outputs, + }); + } + for (ref txid, ref outputs) in txn_outputs { + for (idx, output) in outputs.iter().enumerate() { + self.chain_monitor.install_watch_outpoint((txid.clone(), idx as u32), &output.script_pubkey); + } } } } + let mut pending_events = self.pending_events.lock().unwrap(); + pending_events.append(&mut new_events); } fn block_disconnected(&self, _: &BlockHeader) { } @@ -132,7 +144,8 @@ impl SimpleManyChannelMonitor let res = Arc::new(SimpleManyChannelMonitor { monitors: Mutex::new(HashMap::new()), chain_monitor, - broadcaster + broadcaster, + pending_events: Mutex::new(Vec::new()), }); let weak_res = Arc::downgrade(&res); res.chain_monitor.register_listener(weak_res); @@ -167,6 +180,15 @@ impl ManyChannelMonitor for SimpleManyChannelMonitor { } } +impl events::EventsProvider for SimpleManyChannelMonitor { + fn get_and_clear_pending_events(&self) -> Vec { + let mut pending_events = self.pending_events.lock().unwrap(); + let mut ret = Vec::new(); + mem::swap(&mut ret, &mut *pending_events); + ret + } +} + /// If an HTLC expires within this many blocks, don't try to claim it in a shared transaction, /// instead claiming it in its own individual transaction. const CLTV_SHARED_CLAIM_BUFFER: u32 = 12; @@ -185,6 +207,9 @@ enum KeyStorage { PrivMode { revocation_base_key: SecretKey, htlc_base_key: SecretKey, + delayed_payment_base_key: SecretKey, + prev_latest_per_commitment_point: Option, + latest_per_commitment_point: Option, }, SigsMode { revocation_base_key: PublicKey, @@ -219,7 +244,6 @@ pub struct ChannelMonitor { commitment_transaction_number_obscure_factor: u64, key_storage: KeyStorage, - delayed_payment_base_key: PublicKey, their_htlc_base_key: Option, their_delayed_payment_base_key: Option, // first is the idx of the first of the two revocation points @@ -261,7 +285,6 @@ impl Clone for ChannelMonitor { commitment_transaction_number_obscure_factor: self.commitment_transaction_number_obscure_factor.clone(), key_storage: self.key_storage.clone(), - delayed_payment_base_key: self.delayed_payment_base_key.clone(), their_htlc_base_key: self.their_htlc_base_key.clone(), their_delayed_payment_base_key: self.their_delayed_payment_base_key.clone(), their_cur_revocation_points: self.their_cur_revocation_points.clone(), @@ -293,7 +316,6 @@ impl PartialEq for ChannelMonitor { if self.funding_txo != other.funding_txo || self.commitment_transaction_number_obscure_factor != other.commitment_transaction_number_obscure_factor || self.key_storage != other.key_storage || - self.delayed_payment_base_key != other.delayed_payment_base_key || self.their_htlc_base_key != other.their_htlc_base_key || self.their_delayed_payment_base_key != other.their_delayed_payment_base_key || self.their_cur_revocation_points != other.their_cur_revocation_points || @@ -321,7 +343,7 @@ impl PartialEq for ChannelMonitor { } impl ChannelMonitor { - pub(super) fn new(revocation_base_key: &SecretKey, delayed_payment_base_key: &PublicKey, htlc_base_key: &SecretKey, our_to_self_delay: u16, destination_script: Script) -> ChannelMonitor { + pub(super) fn new(revocation_base_key: &SecretKey, delayed_payment_base_key: &SecretKey, htlc_base_key: &SecretKey, our_to_self_delay: u16, destination_script: Script) -> ChannelMonitor { ChannelMonitor { funding_txo: None, commitment_transaction_number_obscure_factor: 0, @@ -329,8 +351,10 @@ impl ChannelMonitor { key_storage: KeyStorage::PrivMode { revocation_base_key: revocation_base_key.clone(), htlc_base_key: htlc_base_key.clone(), + delayed_payment_base_key: delayed_payment_base_key.clone(), + prev_latest_per_commitment_point: None, + latest_per_commitment_point: None, }, - delayed_payment_base_key: delayed_payment_base_key.clone(), their_htlc_base_key: None, their_delayed_payment_base_key: None, their_cur_revocation_points: None, @@ -469,6 +493,8 @@ impl ChannelMonitor { /// is important that any clones of this channel monitor (including remote clones) by kept /// up-to-date as our local commitment transaction is updated. /// Panics if set_their_to_self_delay has never been called. + /// Also update KeyStorage with latest local per_commitment_point to derive local_delayedkey in + /// case of onchain HTLC tx pub(super) fn provide_latest_local_commitment_tx_info(&mut self, signed_commitment_tx: Transaction, local_keys: chan_utils::TxCreationKeys, feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Signature, Signature)>) { assert!(self.their_to_self_delay.is_some()); self.prev_local_signed_commitment_tx = self.current_local_signed_commitment_tx.take(); @@ -482,6 +508,15 @@ impl ChannelMonitor { feerate_per_kw, htlc_outputs, }); + self.key_storage = if let KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key, ref delayed_payment_base_key, prev_latest_per_commitment_point: _, ref latest_per_commitment_point } = self.key_storage { + KeyStorage::PrivMode { + revocation_base_key: *revocation_base_key, + htlc_base_key: *htlc_base_key, + delayed_payment_base_key: *delayed_payment_base_key, + prev_latest_per_commitment_point: *latest_per_commitment_point, + latest_per_commitment_point: Some(local_keys.per_commitment_point), + } + } else { unimplemented!(); }; } /// Provides a payment_hash->payment_preimage mapping. Will be automatically pruned when all @@ -587,15 +622,28 @@ impl ChannelMonitor { writer.write_all(&byte_utils::be48_to_array(self.commitment_transaction_number_obscure_factor))?; match self.key_storage { - KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key } => { + KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key, ref delayed_payment_base_key, ref prev_latest_per_commitment_point, ref latest_per_commitment_point } => { writer.write_all(&[0; 1])?; writer.write_all(&revocation_base_key[..])?; writer.write_all(&htlc_base_key[..])?; + writer.write_all(&delayed_payment_base_key[..])?; + if let Some(ref prev_latest_per_commitment_point) = *prev_latest_per_commitment_point { + writer.write_all(&[1; 1])?; + writer.write_all(&prev_latest_per_commitment_point.serialize())?; + } else { + writer.write_all(&[0; 1])?; + } + if let Some(ref latest_per_commitment_point) = *latest_per_commitment_point { + writer.write_all(&[1; 1])?; + writer.write_all(&latest_per_commitment_point.serialize())?; + } else { + writer.write_all(&[0; 1])?; + } + }, KeyStorage::SigsMode { .. } => unimplemented!(), } - writer.write_all(&self.delayed_payment_base_key.serialize())?; writer.write_all(&self.their_htlc_base_key.as_ref().unwrap().serialize())?; writer.write_all(&self.their_delayed_payment_base_key.as_ref().unwrap().serialize())?; @@ -748,11 +796,12 @@ impl ChannelMonitor { /// data in remote_claimable_outpoints. Will directly claim any HTLC outputs which expire at a /// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for /// HTLC-Success/HTLC-Timeout transactions. - fn check_spend_remote_transaction(&self, tx: &Transaction, height: u32) -> (Vec, (Sha256dHash, Vec)) { + fn check_spend_remote_transaction(&self, tx: &Transaction, height: u32) -> (Vec, (Sha256dHash, Vec), Vec) { // Most secp and related errors trying to create keys means we have no hope of constructing // a spend transaction...so we return no transactions to broadcast let mut txn_to_broadcast = Vec::new(); let mut watch_outputs = Vec::new(); + let mut spendable_outputs = Vec::new(); let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers! let per_commitment_option = self.remote_claimable_outpoints.get(&commitment_txid); @@ -761,7 +810,7 @@ impl ChannelMonitor { ( $thing : expr ) => { match $thing { Ok(a) => a, - Err(_) => return (txn_to_broadcast, (commitment_txid, watch_outputs)) + Err(_) => return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs) } }; } @@ -771,7 +820,7 @@ impl ChannelMonitor { let secret = self.get_secret(commitment_number).unwrap(); let per_commitment_key = ignore_error!(SecretKey::from_slice(&self.secp_ctx, &secret)); let (revocation_pubkey, b_htlc_key) = match self.key_storage { - KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key } => { + KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key, .. } => { let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key); (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key))), ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &PublicKey::from_secret_key(&self.secp_ctx, &htlc_base_key)))) @@ -784,7 +833,7 @@ impl ChannelMonitor { }; let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.their_delayed_payment_base_key.unwrap())); let a_htlc_key = match self.their_htlc_base_key { - None => return (txn_to_broadcast, (commitment_txid, watch_outputs)), + None => return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs), Some(their_htlc_base_key) => ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &their_htlc_base_key)), }; @@ -851,7 +900,7 @@ impl ChannelMonitor { if htlc.transaction_output_index as usize >= tx.output.len() || tx.output[htlc.transaction_output_index as usize].value != htlc.amount_msat / 1000 || tx.output[htlc.transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() { - return (txn_to_broadcast, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user + return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs); // Corrupted per_commitment_data, fuck this user } let input = TxIn { previous_output: BitcoinOutPoint { @@ -889,7 +938,7 @@ impl ChannelMonitor { watch_outputs.append(&mut tx.output.clone()); self.remote_commitment_txn_on_chain.lock().unwrap().insert(commitment_txid, commitment_number); } - if inputs.is_empty() { return (txn_to_broadcast, (commitment_txid, watch_outputs)); } // Nothing to be done...probably a false positive/local tx + if inputs.is_empty() { return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs); } // Nothing to be done...probably a false positive/local tx let outputs = vec!(TxOut { script_pubkey: self.destination_script.clone(), @@ -910,6 +959,10 @@ impl ChannelMonitor { sign_input!(sighash_parts, input, htlc_idx, value); } + spendable_outputs.push(SpendableOutputDescriptor::StaticOutput { + outpoint: BitcoinOutPoint { txid: spend_tx.txid(), vout: 0 }, + output: spend_tx.output[0].clone(), + }); txn_to_broadcast.push(spend_tx); } else if let Some(per_commitment_data) = per_commitment_option { // While this isn't useful yet, there is a potential race where if a counterparty @@ -930,7 +983,7 @@ impl ChannelMonitor { } else { None }; if let Some(revocation_point) = revocation_point_option { let (revocation_pubkey, b_htlc_key) = match self.key_storage { - KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key } => { + KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key, .. } => { (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, revocation_point, &PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key))), ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &PublicKey::from_secret_key(&self.secp_ctx, &htlc_base_key)))) }, @@ -940,7 +993,7 @@ impl ChannelMonitor { }, }; let a_htlc_key = match self.their_htlc_base_key { - None => return (txn_to_broadcast, (commitment_txid, watch_outputs)), + None => return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs), Some(their_htlc_base_key) => ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &their_htlc_base_key)), }; @@ -998,12 +1051,16 @@ impl ChannelMonitor { }; let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx); sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.to_vec()); + spendable_outputs.push(SpendableOutputDescriptor::StaticOutput { + outpoint: BitcoinOutPoint { txid: single_htlc_tx.txid(), vout: 0 }, + output: single_htlc_tx.output[0].clone(), + }); txn_to_broadcast.push(single_htlc_tx); } } } - if inputs.is_empty() { return (txn_to_broadcast, (commitment_txid, watch_outputs)); } // Nothing to be done...probably a false positive/local tx + if inputs.is_empty() { return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs); } // Nothing to be done...probably a false positive/local tx let outputs = vec!(TxOut { script_pubkey: self.destination_script.clone(), @@ -1024,25 +1081,29 @@ impl ChannelMonitor { sign_input!(sighash_parts, input, value.0, value.1.to_vec()); } + spendable_outputs.push(SpendableOutputDescriptor::StaticOutput { + outpoint: BitcoinOutPoint { txid: spend_tx.txid(), vout: 0 }, + output: spend_tx.output[0].clone(), + }); txn_to_broadcast.push(spend_tx); } } } - (txn_to_broadcast, (commitment_txid, watch_outputs)) + (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs) } /// Attempst to claim a remote HTLC-Success/HTLC-Timeout s outputs using the revocation key - fn check_spend_remote_htlc(&self, tx: &Transaction, commitment_number: u64) -> Option { + fn check_spend_remote_htlc(&self, tx: &Transaction, commitment_number: u64) -> (Option, Option) { if tx.input.len() != 1 || tx.output.len() != 1 { - return None; + return (None, None) } macro_rules! ignore_error { ( $thing : expr ) => { match $thing { Ok(a) => a, - Err(_) => return None + Err(_) => return (None, None) } }; } @@ -1059,7 +1120,7 @@ impl ChannelMonitor { }, }; let delayed_key = match self.their_delayed_payment_base_key { - None => return None, + None => return (None, None), Some(their_delayed_payment_base_key) => ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &their_delayed_payment_base_key)), }; let redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.their_to_self_delay.unwrap(), &delayed_key); @@ -1112,12 +1173,15 @@ impl ChannelMonitor { spend_tx.input[0].witness.push(vec!(1)); spend_tx.input[0].witness.push(redeemscript.into_bytes()); - Some(spend_tx) - } else { None } + let outpoint = BitcoinOutPoint { txid: spend_tx.txid(), vout: 0 }; + let output = spend_tx.output[0].clone(); + (Some(spend_tx), Some(SpendableOutputDescriptor::StaticOutput { outpoint, output })) + } else { (None, None) } } - fn broadcast_by_local_state(&self, local_tx: &LocalSignedTx) -> Vec { + fn broadcast_by_local_state(&self, local_tx: &LocalSignedTx, per_commitment_point: &Option, delayed_payment_base_key: &Option) -> (Vec, Vec) { let mut res = Vec::with_capacity(local_tx.htlc_outputs.len()); + let mut spendable_outputs = Vec::with_capacity(local_tx.htlc_outputs.len()); for &(ref htlc, ref their_sig, ref our_sig) in local_tx.htlc_outputs.iter() { if htlc.offered { @@ -1133,6 +1197,18 @@ impl ChannelMonitor { htlc_timeout_tx.input[0].witness.push(Vec::new()); htlc_timeout_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_bytes()); + if let Some(ref per_commitment_point) = *per_commitment_point { + if let Some(ref delayed_payment_base_key) = *delayed_payment_base_key { + if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, per_commitment_point, delayed_payment_base_key) { + spendable_outputs.push(SpendableOutputDescriptor::DynamicOutput { + outpoint: BitcoinOutPoint { txid: htlc_timeout_tx.txid(), vout: 0 }, + local_delayedkey, + witness_script: chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.our_to_self_delay, &local_tx.delayed_payment_key), + to_self_delay: self.our_to_self_delay + }); + } + } + } res.push(htlc_timeout_tx); } else { if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) { @@ -1148,34 +1224,61 @@ impl ChannelMonitor { htlc_success_tx.input[0].witness.push(payment_preimage.to_vec()); htlc_success_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_bytes()); + if let Some(ref per_commitment_point) = *per_commitment_point { + if let Some(ref delayed_payment_base_key) = *delayed_payment_base_key { + if let Ok(local_delayedkey) = chan_utils::derive_private_key(&self.secp_ctx, per_commitment_point, delayed_payment_base_key) { + spendable_outputs.push(SpendableOutputDescriptor::DynamicOutput { + outpoint: BitcoinOutPoint { txid: htlc_success_tx.txid(), vout: 0 }, + local_delayedkey, + witness_script: chan_utils::get_revokeable_redeemscript(&local_tx.revocation_key, self.our_to_self_delay, &local_tx.delayed_payment_key), + to_self_delay: self.our_to_self_delay + }); + } + } + } res.push(htlc_success_tx); } } } - res + (res, spendable_outputs) } /// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet) /// revoked using data in local_claimable_outpoints. /// Should not be used if check_spend_revoked_transaction succeeds. - fn check_spend_local_transaction(&self, tx: &Transaction, _height: u32) -> Vec { + fn check_spend_local_transaction(&self, tx: &Transaction, _height: u32) -> (Vec, Vec) { let commitment_txid = tx.txid(); if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx { if local_tx.txid == commitment_txid { - return self.broadcast_by_local_state(local_tx); + match self.key_storage { + KeyStorage::PrivMode { revocation_base_key: _, htlc_base_key: _, ref delayed_payment_base_key, prev_latest_per_commitment_point: _, ref latest_per_commitment_point } => { + return self.broadcast_by_local_state(local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key)); + }, + KeyStorage::SigsMode { .. } => { + return self.broadcast_by_local_state(local_tx, &None, &None); + } + } } } if let &Some(ref local_tx) = &self.prev_local_signed_commitment_tx { if local_tx.txid == commitment_txid { - return self.broadcast_by_local_state(local_tx); + match self.key_storage { + KeyStorage::PrivMode { revocation_base_key: _, htlc_base_key: _, ref delayed_payment_base_key, ref prev_latest_per_commitment_point, .. } => { + return self.broadcast_by_local_state(local_tx, prev_latest_per_commitment_point, &Some(*delayed_payment_base_key)); + }, + KeyStorage::SigsMode { .. } => { + return self.broadcast_by_local_state(local_tx, &None, &None); + } + } } } - Vec::new() + (Vec::new(), Vec::new()) } - fn block_connected(&self, txn_matched: &[&Transaction], height: u32, broadcaster: &BroadcasterInterface)-> Vec<(Sha256dHash, Vec)> { + fn block_connected(&self, txn_matched: &[&Transaction], height: u32, broadcaster: &BroadcasterInterface)-> (Vec<(Sha256dHash, Vec)>, Vec) { let mut watch_outputs = Vec::new(); + let mut spendable_outputs = Vec::new(); for tx in txn_matched { if tx.input.len() == 1 { // Assuming our keys were not leaked (in which case we're screwed no matter what), @@ -1185,20 +1288,27 @@ impl ChannelMonitor { let prevout = &tx.input[0].previous_output; let mut txn: Vec = Vec::new(); if self.funding_txo.is_none() || (prevout.txid == self.funding_txo.as_ref().unwrap().0.txid && prevout.vout == self.funding_txo.as_ref().unwrap().0.index as u32) { - let (remote_txn, new_outputs) = self.check_spend_remote_transaction(tx, height); + let (remote_txn, new_outputs, mut spendable_output) = self.check_spend_remote_transaction(tx, height); txn = remote_txn; + spendable_outputs.append(&mut spendable_output); if !new_outputs.1.is_empty() { watch_outputs.push(new_outputs); } if txn.is_empty() { - txn = self.check_spend_local_transaction(tx, height); + let (remote_txn, mut outputs) = self.check_spend_local_transaction(tx, height); + spendable_outputs.append(&mut outputs); + txn = remote_txn; } } else { let remote_commitment_txn_on_chain = self.remote_commitment_txn_on_chain.lock().unwrap(); if let Some(commitment_number) = remote_commitment_txn_on_chain.get(&prevout.txid) { - if let Some(tx) = self.check_spend_remote_htlc(tx, *commitment_number) { + let (tx, spendable_output) = self.check_spend_remote_htlc(tx, *commitment_number); + if let Some(tx) = tx { txn.push(tx); } + if let Some(spendable_output) = spendable_output { + spendable_outputs.push(spendable_output); + } } } for tx in txn.iter() { @@ -1209,12 +1319,25 @@ impl ChannelMonitor { if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx { if self.would_broadcast_at_height(height) { broadcaster.broadcast_transaction(&cur_local_tx.tx); - for tx in self.broadcast_by_local_state(&cur_local_tx) { - broadcaster.broadcast_transaction(&tx); + match self.key_storage { + KeyStorage::PrivMode { revocation_base_key: _, htlc_base_key: _, ref delayed_payment_base_key, prev_latest_per_commitment_point: _, ref latest_per_commitment_point } => { + let (txs, mut outputs) = self.broadcast_by_local_state(&cur_local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key)); + spendable_outputs.append(&mut outputs); + for tx in txs { + broadcaster.broadcast_transaction(&tx); + } + }, + KeyStorage::SigsMode { .. } => { + let (txs, mut outputs) = self.broadcast_by_local_state(&cur_local_tx, &None, &None); + spendable_outputs.append(&mut outputs); + for tx in txs { + broadcaster.broadcast_transaction(&tx); + } + } } } } - watch_outputs + (watch_outputs, spendable_outputs) } pub(super) fn would_broadcast_at_height(&self, height: u32) -> bool { @@ -1299,15 +1422,34 @@ impl Readable for ChannelMonitor { let key_storage = match read_bytes!(1)[0] { 0 => { + let revocation_base_key = unwrap_obj!(SecretKey::from_slice(&secp_ctx, read_bytes!(32))); + let htlc_base_key = unwrap_obj!(SecretKey::from_slice(&secp_ctx, read_bytes!(32))); + let delayed_payment_base_key = unwrap_obj!(SecretKey::from_slice(&secp_ctx, read_bytes!(32))); + let prev_latest_per_commitment_point = match read_bytes!(1)[0] { + 0 => None, + 1 => { + Some(unwrap_obj!(PublicKey::from_slice(&secp_ctx, read_bytes!(33)))) + }, + _ => return Err(DecodeError::InvalidValue), + }; + let latest_per_commitment_point = match read_bytes!(1)[0] { + 0 => None, + 1 => { + Some(unwrap_obj!(PublicKey::from_slice(&secp_ctx, read_bytes!(33)))) + }, + _ => return Err(DecodeError::InvalidValue), + }; KeyStorage::PrivMode { - revocation_base_key: unwrap_obj!(SecretKey::from_slice(&secp_ctx, read_bytes!(32))), - htlc_base_key: unwrap_obj!(SecretKey::from_slice(&secp_ctx, read_bytes!(32))), + revocation_base_key, + htlc_base_key, + delayed_payment_base_key, + prev_latest_per_commitment_point, + latest_per_commitment_point, } }, _ => return Err(DecodeError::InvalidValue), }; - let delayed_payment_base_key = unwrap_obj!(PublicKey::from_slice(&secp_ctx, read_bytes!(33))); let their_htlc_base_key = Some(unwrap_obj!(PublicKey::from_slice(&secp_ctx, read_bytes!(33)))); let their_delayed_payment_base_key = Some(unwrap_obj!(PublicKey::from_slice(&secp_ctx, read_bytes!(33)))); @@ -1470,7 +1612,6 @@ impl Readable for ChannelMonitor { commitment_transaction_number_obscure_factor, key_storage, - delayed_payment_base_key, their_htlc_base_key, their_delayed_payment_base_key, their_cur_revocation_points, @@ -1527,11 +1668,9 @@ mod tests { }; } - let delayed_payment_base_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap()); - { // insert_secret correct sequence - monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); secrets.clear(); secrets.push([0; 32]); @@ -1577,7 +1716,7 @@ mod tests { { // insert_secret #1 incorrect - monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); secrets.clear(); secrets.push([0; 32]); @@ -1593,7 +1732,7 @@ mod tests { { // insert_secret #2 incorrect (#1 derived from incorrect) - monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); secrets.clear(); secrets.push([0; 32]); @@ -1619,7 +1758,7 @@ mod tests { { // insert_secret #3 incorrect - monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); secrets.clear(); secrets.push([0; 32]); @@ -1645,7 +1784,7 @@ mod tests { { // insert_secret #4 incorrect (1,2,3 derived from incorrect) - monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); secrets.clear(); secrets.push([0; 32]); @@ -1691,7 +1830,7 @@ mod tests { { // insert_secret #5 incorrect - monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); secrets.clear(); secrets.push([0; 32]); @@ -1727,7 +1866,7 @@ mod tests { { // insert_secret #6 incorrect (5 derived from incorrect) - monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); secrets.clear(); secrets.push([0; 32]); @@ -1773,7 +1912,7 @@ mod tests { { // insert_secret #7 incorrect - monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); secrets.clear(); secrets.push([0; 32]); @@ -1819,7 +1958,7 @@ mod tests { { // insert_secret #8 incorrect - monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); secrets.clear(); secrets.push([0; 32]); @@ -1937,8 +2076,7 @@ mod tests { // Prune with one old state and a local commitment tx holding a few overlaps with the // old state. - let delayed_payment_base_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap()); - let mut monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new()); + let mut monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), &SecretKey::from_slice(&secp_ctx, &[44; 32]).unwrap(), 0, Script::new()); monitor.set_their_to_self_delay(10); monitor.provide_latest_local_commitment_tx_info(dummy_tx.clone(), dummy_keys!(), 0, preimages_to_local_htlcs!(preimages[0..10])); diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 94cdef9e41f..82784efe5fc 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -796,6 +796,7 @@ impl PeerManager { Event::PaymentSent {..} => { /* Hand upstream */ }, Event::PaymentFailed {..} => { /* Hand upstream */ }, Event::PendingHTLCsForwardable {..} => { /* Hand upstream */ }, + Event::SpendableOutputs { .. } => { /* Hand upstream */ }, Event::SendOpenChannel { ref node_id, ref msg } => { log_trace!(self, "Handling SendOpenChannel event in peer_handler for node {} for channel {}", diff --git a/src/util/events.rs b/src/util/events.rs index ccfe0f8ac15..3a077a4b5ba 100644 --- a/src/util/events.rs +++ b/src/util/events.rs @@ -14,6 +14,7 @@ use ln::msgs; use chain::transaction::OutPoint; +use chain::keysinterface::SpendableOutputDescriptor; use bitcoin::blockdata::script::Script; @@ -89,6 +90,13 @@ pub enum Event { /// The earliest time at which process_pending_htlc_forwards should be called. time_forwardable: Instant, }, + /// Used to indicate that an output was generated on-chain which you should know how to spend. + /// Such an output will *not* ever be spent by rust-lightning, so you need to store them + /// somewhere and spend them when you create on-chain spends. + SpendableOutputs { + /// The outputs which you should store as spendable by you. + outputs: Vec, + }, // Events indicating the network loop should send a message to a peer: // TODO: Move these into a separate struct and make a top-level enum From d33cb3cca560ec33b33542c1ef6e47f15b35e30a Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Fri, 26 Oct 2018 11:15:55 -0400 Subject: [PATCH 02/15] Add a KeysInterface which provides keys from user Move ChannelKeys into keysinterface for generate a set of it from master_seed and change return type to panic on bogus data --- src/chain/keysinterface.rs | 85 +++++++++++++++++++++++++++++++++++++- src/ln/channel.rs | 56 +------------------------ src/ln/channelmanager.rs | 13 ++---- 3 files changed, 89 insertions(+), 65 deletions(-) diff --git a/src/chain/keysinterface.rs b/src/chain/keysinterface.rs index bab21fd2b0b..568b91e82b5 100644 --- a/src/chain/keysinterface.rs +++ b/src/chain/keysinterface.rs @@ -5,7 +5,12 @@ use bitcoin::blockdata::transaction::{OutPoint, TxOut}; use bitcoin::blockdata::script::Script; -use secp256k1::key::SecretKey; +use secp256k1::key::{SecretKey, PublicKey}; +use secp256k1::Secp256k1; + +use crypto::hkdf::{hkdf_extract,hkdf_expand}; + +use util::sha2::Sha256; /// When on-chain outputs are created by rust-lightning an event is generated which informs the /// user thereof. This enum describes the format of the output and provides the OutPoint. @@ -34,3 +39,81 @@ pub enum SpendableOutputDescriptor { to_self_delay: u16, } } + +/// A trait to describe an object which can get user secrets and key material. +pub trait KeysInterface: Send + Sync { + /// Get node secret key (aka node_id or network_key) + fn get_node_secret(&self) -> SecretKey; + /// Get destination redeemScript to encumber static protocol exit points. + fn get_destination_script(&self) -> Script; + /// Get shutdown_pubkey to use as PublicKey at channel closure + fn get_shutdown_pubkey(&self) -> PublicKey; + /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you + /// restarted with some stale data! + fn get_channel_keys(&self, inbound: bool) -> ChannelKeys; +} + +/// Set of lightning keys needed to operate a channel as described in BOLT 3 +pub struct ChannelKeys { + /// Private key of anchor tx + pub funding_key: SecretKey, + /// Local secret key for blinded revocation pubkey + pub revocation_base_key: SecretKey, + /// Local secret key used in commitment tx htlc outputs + pub payment_base_key: SecretKey, + /// Local secret key used in HTLC tx + pub delayed_payment_base_key: SecretKey, + /// Local htlc secret key used in commitment tx htlc outputs + pub htlc_base_key: SecretKey, + /// Local secret key used for closing tx + pub channel_close_key: SecretKey, + /// Local secret key used in justice tx, claim tx and preimage tx outputs + pub channel_monitor_claim_key: SecretKey, + /// Commitment seed + pub commitment_seed: [u8; 32], +} + +impl ChannelKeys { + /// Generate a set of lightning keys needed to operate a channel by HKDF-expanding a given + /// random 32-byte seed + pub fn new_from_seed(seed: &[u8; 32]) -> ChannelKeys { + let mut prk = [0; 32]; + hkdf_extract(Sha256::new(), b"rust-lightning key gen salt", seed, &mut prk); + let secp_ctx = Secp256k1::without_caps(); + + let mut okm = [0; 32]; + hkdf_expand(Sha256::new(), &prk, b"rust-lightning funding key info", &mut okm); + let funding_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning revocation base key info", &mut okm); + let revocation_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning payment base key info", &mut okm); + let payment_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning delayed payment base key info", &mut okm); + let delayed_payment_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning htlc base key info", &mut okm); + let htlc_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel close key info", &mut okm); + let channel_close_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel monitor claim key info", &mut okm); + let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning local commitment seed info", &mut okm); + + ChannelKeys { + funding_key: funding_key, + revocation_base_key: revocation_base_key, + payment_base_key: payment_base_key, + delayed_payment_base_key: delayed_payment_base_key, + htlc_base_key: htlc_base_key, + channel_close_key: channel_close_key, + channel_monitor_claim_key: channel_monitor_claim_key, + commitment_seed: okm + } + } +} diff --git a/src/ln/channel.rs b/src/ln/channel.rs index e8d7f538fd9..8f73ab59a9e 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -11,7 +11,6 @@ use secp256k1::{Secp256k1,Message,Signature}; use secp256k1; use crypto::digest::Digest; -use crypto::hkdf::{hkdf_extract,hkdf_expand}; use ln::msgs; use ln::msgs::{ErrorAction, HandleError, RAACommitmentOrder}; @@ -21,6 +20,7 @@ use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGH use ln::chan_utils; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; use chain::transaction::OutPoint; +use chain::keysinterface::ChannelKeys; use util::{transaction_utils,rng}; use util::ser::Writeable; use util::sha2::Sha256; @@ -33,17 +33,6 @@ use std::{cmp,mem}; use std::time::Instant; use std::sync::{Arc}; -pub struct ChannelKeys { - pub funding_key: SecretKey, - pub revocation_base_key: SecretKey, - pub payment_base_key: SecretKey, - pub delayed_payment_base_key: SecretKey, - pub htlc_base_key: SecretKey, - pub channel_close_key: SecretKey, - pub channel_monitor_claim_key: SecretKey, - pub commitment_seed: [u8; 32], -} - #[cfg(test)] pub struct ChannelValueStat { pub value_to_self_msat: u64, @@ -55,49 +44,6 @@ pub struct ChannelValueStat { pub their_max_htlc_value_in_flight_msat: u64, // outgoing } -impl ChannelKeys { - pub fn new_from_seed(seed: &[u8; 32]) -> Result { - let mut prk = [0; 32]; - hkdf_extract(Sha256::new(), b"rust-lightning key gen salt", seed, &mut prk); - let secp_ctx = Secp256k1::without_caps(); - - let mut okm = [0; 32]; - hkdf_expand(Sha256::new(), &prk, b"rust-lightning funding key info", &mut okm); - let funding_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning revocation base key info", &mut okm); - let revocation_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning payment base key info", &mut okm); - let payment_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning delayed payment base key info", &mut okm); - let delayed_payment_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning htlc base key info", &mut okm); - let htlc_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel close key info", &mut okm); - let channel_close_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel monitor claim key info", &mut okm); - let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning local commitment seed info", &mut okm); - - Ok(ChannelKeys { - funding_key: funding_key, - revocation_base_key: revocation_base_key, - payment_base_key: payment_base_key, - delayed_payment_base_key: delayed_payment_base_key, - htlc_base_key: htlc_base_key, - channel_close_key: channel_close_key, - channel_monitor_claim_key: channel_monitor_claim_key, - commitment_seed: okm - }) - } -} - enum InboundHTLCRemovalReason { FailRelay(msgs::OnionErrorPacket), FailMalformed(([u8; 32], u16)), diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 7e736ba15d2..badde7f618a 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -22,11 +22,12 @@ use secp256k1; use chain::chaininterface::{BroadcasterInterface,ChainListener,ChainWatchInterface,FeeEstimator}; use chain::transaction::OutPoint; -use ln::channel::{Channel, ChannelError, ChannelKeys}; +use ln::channel::{Channel, ChannelError}; use ln::channelmonitor::{ChannelMonitorUpdateErr, ManyChannelMonitor, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS}; use ln::router::{Route,RouteHop}; use ln::msgs; use ln::msgs::{ChannelMessageHandler, HandleError, RAACommitmentOrder}; +use chain::keysinterface::ChannelKeys; use util::{byte_utils, events, internal_traits, rng}; use util::sha2::Sha256; use util::ser::{Readable, Writeable}; @@ -432,10 +433,7 @@ impl ChannelManager { } else { let mut key_seed = [0u8; 32]; rng::fill_bytes(&mut key_seed); - match ChannelKeys::new_from_seed(&key_seed) { - Ok(key) => key, - Err(_) => panic!("RNG is busted!") - } + ChannelKeys::new_from_seed(&key_seed) }; 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))?; @@ -1689,10 +1687,7 @@ impl ChannelManager { } else { let mut key_seed = [0u8; 32]; rng::fill_bytes(&mut key_seed); - match ChannelKeys::new_from_seed(&key_seed) { - Ok(key) => key, - Err(_) => panic!("RNG is busted!") - } + ChannelKeys::new_from_seed(&key_seed) }; let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger)) From 6d5dc6c9b49b8ddffe8110fefffcc8f313a9c10b Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Fri, 26 Oct 2018 11:21:33 -0400 Subject: [PATCH 03/15] Implement KeysInterface for KeysManager util --- src/chain/keysinterface.rs | 87 +++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/src/chain/keysinterface.rs b/src/chain/keysinterface.rs index 568b91e82b5..3e4ff0e3699 100644 --- a/src/chain/keysinterface.rs +++ b/src/chain/keysinterface.rs @@ -3,14 +3,22 @@ //! on-chain output which is theirs. use bitcoin::blockdata::transaction::{OutPoint, TxOut}; -use bitcoin::blockdata::script::Script; +use bitcoin::blockdata::script::{Script, Builder}; +use bitcoin::blockdata::opcodes; +use bitcoin::network::constants::Network; +use bitcoin::util::hash::Hash160; +use bitcoin::util::bip32::{ExtendedPrivKey, ExtendedPubKey, ChildNumber}; use secp256k1::key::{SecretKey, PublicKey}; use secp256k1::Secp256k1; +use secp256k1; use crypto::hkdf::{hkdf_extract,hkdf_expand}; use util::sha2::Sha256; +use util::logger::Logger; + +use std::sync::Arc; /// When on-chain outputs are created by rust-lightning an event is generated which informs the /// user thereof. This enum describes the format of the output and provides the OutPoint. @@ -117,3 +125,80 @@ impl ChannelKeys { } } } + +/// Simple KeysInterface implementor that takes a 32-byte seed for use as a BIP 32 extended key +/// and derives keys from that. +/// +/// Your node_id is seed/0' +/// ChannelMonitor closes may use seed/1' +/// Cooperative closes may use seed/2' +/// The two close keys may be needed to claim on-chain funds! +pub struct KeysManager { + secp_ctx: Secp256k1, + node_secret: SecretKey, + destination_script: Script, + shutdown_pubkey: PublicKey, + channel_master_key: ExtendedPrivKey, + + logger: Arc, +} + +impl KeysManager { + /// Constructs a KeysManager from a 32-byte seed. If the seed is in some way biased (eg your + /// RNG is busted) this may panic. + pub fn new(seed: &[u8; 32], network: Network, logger: Arc) -> KeysManager { + let secp_ctx = Secp256k1::new(); + match ExtendedPrivKey::new_master(&secp_ctx, network.clone(), seed) { + Ok(master_key) => { + let node_secret = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0)).expect("Your RNG is busted").secret_key; + let destination_script = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(1)) { + Ok(destination_key) => { + let pubkey_hash160 = Hash160::from_data(&ExtendedPubKey::from_private(&secp_ctx, &destination_key).public_key.serialize()[..]); + Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0) + .push_slice(pubkey_hash160.as_bytes()) + .into_script() + }, + Err(_) => panic!("Your RNG is busted"), + }; + let shutdown_pubkey = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(2)) { + Ok(shutdown_key) => ExtendedPubKey::from_private(&secp_ctx, &shutdown_key).public_key, + Err(_) => panic!("Your RNG is busted"), + }; + let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3)).expect("Your RNG is busted"); + KeysManager { + secp_ctx, + node_secret, + destination_script, + shutdown_pubkey, + channel_master_key, + + logger, + } + }, + Err(_) => panic!("Your rng is busted"), + } + } +} + +impl KeysInterface for KeysManager { + fn get_node_secret(&self) -> SecretKey { + self.node_secret.clone() + } + + fn get_destination_script(&self) -> Script { + self.destination_script.clone() + } + + fn get_shutdown_pubkey(&self) -> PublicKey { + self.shutdown_pubkey.clone() + } + + fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys { + let channel_pubkey = ExtendedPubKey::from_private(&self.secp_ctx, &self. channel_master_key); + let mut seed = [0; 32]; + for (arr, slice) in seed.iter_mut().zip((&channel_pubkey.public_key.serialize()[0..32]).iter()) { + *arr = *slice; + } + ChannelKeys::new_from_seed(&seed) + } +} From e361fed0f1a2f1502051c9cc5d9c52914391e349 Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Fri, 26 Oct 2018 11:40:01 -0400 Subject: [PATCH 04/15] Integrate KeysInterface to ChannelManager with Arc --- fuzz/fuzz_targets/full_stack_target.rs | 59 ++++++++++++++++++++++-- src/chain/keysinterface.rs | 1 + src/ln/channel.rs | 24 ++++++++-- src/ln/channelmanager.rs | 62 +++++++------------------- 4 files changed, 92 insertions(+), 54 deletions(-) diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index d990ca7afe0..3222252ef2e 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -5,15 +5,17 @@ extern crate secp256k1; use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::transaction::{Transaction, TxOut}; -use bitcoin::blockdata::script::Script; +use bitcoin::blockdata::script::{Builder, Script}; +use bitcoin::blockdata::opcodes; use bitcoin::network::constants::Network; use bitcoin::network::serialize::{deserialize, serialize, BitcoinHash}; -use bitcoin::util::hash::Sha256dHash; +use bitcoin::util::hash::{Sha256dHash, Hash160}; use crypto::digest::Digest; use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil}; use lightning::chain::transaction::OutPoint; +use lightning::chain::keysinterface::{ChannelKeys, KeysInterface}; use lightning::ln::channelmonitor; use lightning::ln::channelmanager::{ChannelManager, PaymentFailReason}; use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor}; @@ -196,6 +198,54 @@ impl<'a> Drop for MoneyLossDetector<'a> { } } +struct KeyProvider { + node_secret: SecretKey, +} +impl KeysInterface for KeyProvider { + fn get_node_secret(&self) -> SecretKey { + self.node_secret.clone() + } + + fn get_destination_script(&self) -> Script { + let secp_ctx = Secp256k1::signing_only(); + let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); + let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); + Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script() + } + + fn get_shutdown_pubkey(&self) -> PublicKey { + let secp_ctx = Secp256k1::signing_only(); + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap()) + } + + fn get_channel_keys(&self, inbound: bool) -> ChannelKeys { + let secp_ctx = Secp256k1::without_caps(); + if inbound { + ChannelKeys { + funding_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]).unwrap(), + revocation_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0]).unwrap(), + payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0]).unwrap(), + delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]).unwrap(), + htlc_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0]).unwrap(), + channel_close_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0]).unwrap(), + channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0]).unwrap(), + commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + } + } else { + ChannelKeys { + funding_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + revocation_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + htlc_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + channel_close_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), + commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + } + } + } +} + #[inline] pub fn do_test(data: &[u8], logger: &Arc) { reset_rng_state(); @@ -236,8 +286,9 @@ pub fn do_test(data: &[u8], logger: &Arc) { let broadcast = Arc::new(TestBroadcaster{}); let monitor = channelmonitor::SimpleManyChannelMonitor::new(watch.clone(), broadcast.clone()); - let channelmanager = ChannelManager::new(our_network_key, slice_to_be32(get_slice!(4)), get_slice!(1)[0] != 0, Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger)).unwrap(); - let router = Arc::new(Router::new(PublicKey::from_secret_key(&secp_ctx, &our_network_key), watch.clone(), Arc::clone(&logger))); + let keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone() }); + let channelmanager = ChannelManager::new(slice_to_be32(get_slice!(4)), get_slice!(1)[0] != 0, Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone()).unwrap(); + let router = Arc::new(Router::new(PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), watch.clone(), Arc::clone(&logger))); let peers = RefCell::new([false; 256]); let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), PeerManager::new(MessageHandler { diff --git a/src/chain/keysinterface.rs b/src/chain/keysinterface.rs index 3e4ff0e3699..3a5ca6942c6 100644 --- a/src/chain/keysinterface.rs +++ b/src/chain/keysinterface.rs @@ -62,6 +62,7 @@ pub trait KeysInterface: Send + Sync { } /// Set of lightning keys needed to operate a channel as described in BOLT 3 +#[derive(Clone)] pub struct ChannelKeys { /// Private key of anchor tx pub funding_key: SecretKey, diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 8f73ab59a9e..a889e2ecad6 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -20,7 +20,7 @@ use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGH use ln::chan_utils; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; use chain::transaction::OutPoint; -use chain::keysinterface::ChannelKeys; +use chain::keysinterface::{ChannelKeys, KeysInterface}; use util::{transaction_utils,rng}; use util::ser::Writeable; use util::sha2::Sha256; @@ -415,7 +415,9 @@ impl Channel { } // Constructors: - pub fn new_outbound(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, announce_publicly: bool, user_id: u64, logger: Arc) -> Result { + pub fn new_outbound(fee_estimator: &FeeEstimator, keys_provider: &Arc, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, announce_publicly: bool, user_id: u64, logger: Arc) -> Result { + let chan_keys = keys_provider.get_channel_keys(false); + if channel_value_satoshis >= MAX_FUNDING_SATOSHIS { return Err(APIError::APIMisuseError{err: "funding value > 2^24"}); } @@ -524,7 +526,9 @@ impl Channel { /// Creates a new channel from a remote sides' request for one. /// Assumes chain_hash has already been checked and corresponds with what we expect! - pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, require_announce: bool, allow_announce: bool, logger: Arc) -> Result { + pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, require_announce: bool, allow_announce: bool, logger: Arc) -> Result { + let chan_keys = keys_provider.get_channel_keys(true); + // Check sanity of message fields: if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS { return Err(ChannelError::Close("funding value > 2^24")); @@ -3236,6 +3240,7 @@ mod tests { use ln::channel::MAX_FUNDING_SATOSHIS; use ln::chan_utils; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; + use chain::keysinterface::KeysInterface; use chain::transaction::OutPoint; use util::test_utils; use util::logger::Logger; @@ -3260,6 +3265,16 @@ mod tests { "MAX_FUNDING_SATOSHIS is greater than all satoshis on existence"); } + struct Keys { + chan_keys: ChannelKeys, + } + impl KeysInterface for Keys { + fn get_node_secret(&self) -> SecretKey { panic!(); } + fn get_destination_script(&self) -> Script { panic!(); } + fn get_shutdown_pubkey(&self) -> PublicKey { panic!(); } + fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys { self.chan_keys.clone() } + } + #[test] fn outbound_commitment_test() { // Test vectors from BOLT 3 Appendix C: @@ -3281,9 +3296,10 @@ mod tests { }; assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan_keys.funding_key).serialize()[..], hex::decode("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]); + let keys_provider: Arc = Arc::new(Keys { chan_keys }); let their_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap()); - let mut chan = Channel::new_outbound(&feeest, chan_keys, their_node_id, 10000000, 100000, false, 42, Arc::clone(&logger)).unwrap(); // Nothing uses their network key in this test + let mut chan = Channel::new_outbound(&feeest, &keys_provider, their_node_id, 10000000, 100000, false, 42, Arc::clone(&logger)).unwrap(); // Nothing uses their network key in this test chan.their_to_self_delay = 144; chan.our_dust_limit_satoshis = 546; diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index badde7f618a..c71013f950d 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -27,7 +27,7 @@ use ln::channelmonitor::{ChannelMonitorUpdateErr, ManyChannelMonitor, CLTV_CLAIM use ln::router::{Route,RouteHop}; use ln::msgs; use ln::msgs::{ChannelMessageHandler, HandleError, RAACommitmentOrder}; -use chain::keysinterface::ChannelKeys; +use chain::keysinterface::KeysInterface; use util::{byte_utils, events, internal_traits, rng}; use util::sha2::Sha256; use util::ser::{Readable, Writeable}; @@ -302,6 +302,8 @@ pub struct ChannelManager { pending_events: Mutex>, + keys_manager: Arc, + logger: Arc, } @@ -374,7 +376,7 @@ impl ChannelManager { /// 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> { + pub fn new(fee_proportional_millionths: u32, announce_channels_publicly: bool, network: Network, feeest: Arc, monitor: Arc, chain_monitor: Arc, tx_broadcaster: Arc, logger: Arc, keys_manager: Arc) -> Result, secp256k1::Error> { let secp_ctx = Secp256k1::new(); let res = Arc::new(ChannelManager { @@ -396,10 +398,12 @@ impl ChannelManager { forward_htlcs: HashMap::new(), claimable_htlcs: HashMap::new(), }), - our_network_key, + our_network_key: keys_manager.get_node_secret(), pending_events: Mutex::new(Vec::new()), + keys_manager, + logger, }); let weak_res = Arc::downgrade(&res); @@ -419,24 +423,7 @@ impl ChannelManager { /// /// 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") { - ChannelKeys { - funding_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - revocation_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - delayed_payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - htlc_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - channel_close_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - channel_monitor_claim_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - } - } else { - let mut key_seed = [0u8; 32]; - rng::fill_bytes(&mut key_seed); - ChannelKeys::new_from_seed(&key_seed) - }; - - 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 channel = Channel::new_outbound(&*self.fee_estimator, &self.keys_manager, 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 mut channel_state = self.channel_state.lock().unwrap(); match channel_state.by_id.entry(channel.channel_id()) { @@ -1673,24 +1660,7 @@ impl ChannelManager { return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision!", msg.temporary_channel_id.clone())); } - let chan_keys = if cfg!(feature = "fuzztarget") { - ChannelKeys { - funding_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]).unwrap(), - revocation_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0]).unwrap(), - payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0]).unwrap(), - delayed_payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]).unwrap(), - htlc_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0]).unwrap(), - channel_close_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0]).unwrap(), - channel_monitor_claim_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0]).unwrap(), - commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - } - } else { - let mut key_seed = [0u8; 32]; - rng::fill_bytes(&mut key_seed); - ChannelKeys::new_from_seed(&key_seed) - }; - - let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger)) + let channel = Channel::new_from_req(&*self.fee_estimator, &self.keys_manager, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger)) .map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.temporary_channel_id))?; let accept_msg = channel.get_accept_channel(); channel_state.by_id.insert(channel.channel_id(), channel); @@ -2680,6 +2650,8 @@ mod tests { use chain::chaininterface; use chain::transaction::OutPoint; use chain::chaininterface::ChainListener; + use chain::keysinterface::KeysInterface; + use chain::keysinterface; use ln::channelmanager::{ChannelManager,OnionKeys,PaymentFailReason}; use ln::channelmonitor::{ChannelMonitorUpdateErr, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS}; use ln::router::{Route, RouteHop, Router}; @@ -3452,14 +3424,12 @@ mod tests { let feeest = Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 }); let chain_monitor = Arc::new(chaininterface::ChainWatchInterfaceUtil::new(Network::Testnet, Arc::clone(&logger))); let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}); + let mut seed = [0; 32]; + rng.fill_bytes(&mut seed); + let keys_manager = Arc::new(keysinterface::KeysManager::new(&seed, Network::Testnet, Arc::clone(&logger))); let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone())); - let node_id = { - let mut key_slice = [0; 32]; - rng.fill_bytes(&mut key_slice); - SecretKey::from_slice(&secp_ctx, &key_slice).unwrap() - }; - let node = ChannelManager::new(node_id.clone(), 0, true, Network::Testnet, feeest.clone(), chan_monitor.clone(), chain_monitor.clone(), tx_broadcaster.clone(), Arc::clone(&logger)).unwrap(); - let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &node_id), chain_monitor.clone(), Arc::clone(&logger)); + let node = ChannelManager::new(0, true, Network::Testnet, feeest.clone(), chan_monitor.clone(), chain_monitor.clone(), tx_broadcaster.clone(), Arc::clone(&logger), keys_manager.clone()).unwrap(); + let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), chain_monitor.clone(), Arc::clone(&logger)); nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router, network_payment_count: payment_count.clone(), network_chan_count: chan_count.clone(), From 32a937890956a459c499e76767671050b357f29a Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Fri, 26 Oct 2018 13:35:57 -0400 Subject: [PATCH 05/15] Integrate shutdown_pubkey from KeysInterface in ChannelManager/Channel Drop channel_close_key from ChannelKeys --- fuzz/fuzz_targets/full_stack_target.rs | 2 -- src/chain/keysinterface.rs | 6 ------ src/ln/channel.rs | 14 +++++++++++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index 3222252ef2e..765479a40dc 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -227,7 +227,6 @@ impl KeysInterface for KeyProvider { payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0]).unwrap(), delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]).unwrap(), htlc_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0]).unwrap(), - channel_close_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0]).unwrap(), channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0]).unwrap(), commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], } @@ -238,7 +237,6 @@ impl KeysInterface for KeyProvider { payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), htlc_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - channel_close_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], } diff --git a/src/chain/keysinterface.rs b/src/chain/keysinterface.rs index 3a5ca6942c6..84ebde34252 100644 --- a/src/chain/keysinterface.rs +++ b/src/chain/keysinterface.rs @@ -74,8 +74,6 @@ pub struct ChannelKeys { pub delayed_payment_base_key: SecretKey, /// Local htlc secret key used in commitment tx htlc outputs pub htlc_base_key: SecretKey, - /// Local secret key used for closing tx - pub channel_close_key: SecretKey, /// Local secret key used in justice tx, claim tx and preimage tx outputs pub channel_monitor_claim_key: SecretKey, /// Commitment seed @@ -106,9 +104,6 @@ impl ChannelKeys { hkdf_expand(Sha256::new(), &prk, b"rust-lightning htlc base key info", &mut okm); let htlc_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); - hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel close key info", &mut okm); - let channel_close_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); - hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel monitor claim key info", &mut okm); let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); @@ -120,7 +115,6 @@ impl ChannelKeys { payment_base_key: payment_base_key, delayed_payment_base_key: delayed_payment_base_key, htlc_base_key: htlc_base_key, - channel_close_key: channel_close_key, channel_monitor_claim_key: channel_monitor_claim_key, commitment_seed: okm } diff --git a/src/ln/channel.rs b/src/ln/channel.rs index a889e2ecad6..2f73cd3c5d4 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -238,6 +238,7 @@ pub(super) struct Channel { channel_value_satoshis: u64, local_keys: ChannelKeys, + shutdown_pubkey: PublicKey, // Our commitment numbers start at 2^48-1 and count down, whereas the ones used in transaction // generation start at 0 and count up...this simplifies some parts of implementation at the @@ -452,6 +453,7 @@ impl Channel { channel_value_satoshis: channel_value_satoshis, local_keys: chan_keys, + shutdown_pubkey: keys_provider.get_shutdown_pubkey(), cur_local_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER, cur_remote_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER, value_to_self_msat: channel_value_satoshis * 1000 - push_msat, @@ -616,6 +618,7 @@ impl Channel { announce_publicly: their_announce, local_keys: chan_keys, + shutdown_pubkey: keys_provider.get_shutdown_pubkey(), cur_local_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER, cur_remote_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER, value_to_self_msat: msg.push_msat, @@ -898,7 +901,7 @@ impl Channel { #[inline] fn get_closing_scriptpubkey(&self) -> Script { - let our_channel_close_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.channel_close_key).serialize()); + let our_channel_close_key_hash = Hash160::from_data(&self.shutdown_pubkey.serialize()); Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_close_key_hash[..]).into_script() } @@ -3271,7 +3274,13 @@ mod tests { impl KeysInterface for Keys { fn get_node_secret(&self) -> SecretKey { panic!(); } fn get_destination_script(&self) -> Script { panic!(); } - fn get_shutdown_pubkey(&self) -> PublicKey { panic!(); } + + fn get_shutdown_pubkey(&self) -> PublicKey { + let secp_ctx = Secp256k1::signing_only(); + let channel_close_key = SecretKey::from_slice(&secp_ctx, &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); + PublicKey::from_secret_key(&secp_ctx, &channel_close_key) + } + fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys { self.chan_keys.clone() } } @@ -3290,7 +3299,6 @@ mod tests { // These aren't set in the test vectors: revocation_base_key: SecretKey::from_slice(&secp_ctx, &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(), - channel_close_key: SecretKey::from_slice(&secp_ctx, &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(), channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(), commitment_seed: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], }; From 5180686b1d210fe085d58dd89f63ff1072d548dd Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Fri, 26 Oct 2018 13:41:07 -0400 Subject: [PATCH 06/15] Integrate destination_script from KeysInterface in ChannelManager/Channel Drop channel_monitor_claim_key from ChannelKeys --- fuzz/fuzz_targets/full_stack_target.rs | 2 -- src/chain/keysinterface.rs | 6 ------ src/ln/channel.rs | 25 +++++++++++++------------ 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index 765479a40dc..ed5001a3e08 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -227,7 +227,6 @@ impl KeysInterface for KeyProvider { payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0]).unwrap(), delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]).unwrap(), htlc_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0]).unwrap(), - channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0]).unwrap(), commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], } } else { @@ -237,7 +236,6 @@ impl KeysInterface for KeyProvider { payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), delayed_payment_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), htlc_base_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), - channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(), commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], } } diff --git a/src/chain/keysinterface.rs b/src/chain/keysinterface.rs index 84ebde34252..b3823e21561 100644 --- a/src/chain/keysinterface.rs +++ b/src/chain/keysinterface.rs @@ -74,8 +74,6 @@ pub struct ChannelKeys { pub delayed_payment_base_key: SecretKey, /// Local htlc secret key used in commitment tx htlc outputs pub htlc_base_key: SecretKey, - /// Local secret key used in justice tx, claim tx and preimage tx outputs - pub channel_monitor_claim_key: SecretKey, /// Commitment seed pub commitment_seed: [u8; 32], } @@ -104,9 +102,6 @@ impl ChannelKeys { hkdf_expand(Sha256::new(), &prk, b"rust-lightning htlc base key info", &mut okm); let htlc_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); - hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel monitor claim key info", &mut okm); - let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); - hkdf_expand(Sha256::new(), &prk, b"rust-lightning local commitment seed info", &mut okm); ChannelKeys { @@ -115,7 +110,6 @@ impl ChannelKeys { payment_base_key: payment_base_key, delayed_payment_base_key: delayed_payment_base_key, htlc_base_key: htlc_base_key, - channel_monitor_claim_key: channel_monitor_claim_key, commitment_seed: okm } } diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 2f73cd3c5d4..6fd6afe8e36 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -436,11 +436,9 @@ impl Channel { let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal); let secp_ctx = Secp256k1::new(); - let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).serialize()); - let our_channel_monitor_claim_script = Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script(); let channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key, - &chan_keys.htlc_base_key, - BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script); + &chan_keys.htlc_base_key, BREAKDOWN_TIMEOUT, + keys_provider.get_destination_script()); Ok(Channel { user_id: user_id, @@ -600,11 +598,9 @@ impl Channel { } let secp_ctx = Secp256k1::new(); - let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &chan_keys.channel_monitor_claim_key).serialize()); - let our_channel_monitor_claim_script = Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script(); let mut channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key, - &chan_keys.htlc_base_key, - BREAKDOWN_TIMEOUT, our_channel_monitor_claim_script); + &chan_keys.htlc_base_key, BREAKDOWN_TIMEOUT, + keys_provider.get_destination_script()); channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint); channel_monitor.set_their_to_self_delay(msg.to_self_delay); @@ -3232,11 +3228,12 @@ impl Channel { #[cfg(test)] mod tests { - use bitcoin::util::hash::Sha256dHash; + use bitcoin::util::hash::{Sha256dHash, Hash160}; use bitcoin::util::bip143; use bitcoin::network::serialize::serialize; - use bitcoin::blockdata::script::Script; + use bitcoin::blockdata::script::{Script, Builder}; use bitcoin::blockdata::transaction::Transaction; + use bitcoin::blockdata::opcodes; use hex; use ln::channelmanager::HTLCSource; use ln::channel::{Channel,ChannelKeys,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,TxCreationKeys}; @@ -3273,7 +3270,12 @@ mod tests { } impl KeysInterface for Keys { fn get_node_secret(&self) -> SecretKey { panic!(); } - fn get_destination_script(&self) -> Script { panic!(); } + fn get_destination_script(&self) -> Script { + let secp_ctx = Secp256k1::signing_only(); + let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); + let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); + Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script() + } fn get_shutdown_pubkey(&self) -> PublicKey { let secp_ctx = Secp256k1::signing_only(); @@ -3299,7 +3301,6 @@ mod tests { // These aren't set in the test vectors: revocation_base_key: SecretKey::from_slice(&secp_ctx, &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(), - channel_monitor_claim_key: SecretKey::from_slice(&secp_ctx, &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(), commitment_seed: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], }; assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan_keys.funding_key).serialize()[..], From e397cb99601e9d2849bbc3aad2b0df8bc8b7f522 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Oct 2018 16:25:32 -0400 Subject: [PATCH 07/15] Split Event, move MessageSendEvent push() inside channel_state lock --- fuzz/fuzz_targets/full_stack_target.rs | 5 +- src/ln/channelmanager.rs | 620 ++++++++++++------------- src/ln/msgs.rs | 2 +- src/ln/peer_handler.rs | 69 +-- src/util/events.rs | 37 +- src/util/test_utils.rs | 6 +- 6 files changed, 326 insertions(+), 413 deletions(-) diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index ed5001a3e08..bf6de14aeed 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -460,7 +460,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { _ => return, } loss_detector.handler.process_events(); - for event in loss_detector.handler.get_and_clear_pending_events() { + for event in loss_detector.manager.get_and_clear_pending_events() { match event { Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, output_script, .. } => { pending_funding_generation.push((temporary_channel_id, channel_value_satoshis, output_script)); @@ -473,11 +473,10 @@ pub fn do_test(data: &[u8], logger: &Arc) { }, Event::PaymentSent {..} => {}, Event::PaymentFailed {..} => {}, - Event::PendingHTLCsForwardable {..} => { should_forward = true; }, - _ => panic!("Unknown event"), + Event::SpendableOutputs {..} => {}, } } } diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index c71013f950d..bd663c92412 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -257,6 +257,9 @@ struct ChannelHolder { /// guarantees are made about the channels given here actually existing anymore by the time you /// go to read them! claimable_htlcs: HashMap<[u8; 32], Vec>, + /// Messages to send to peers - pushed to in the same lock that they are generated in (except + /// for broadcast messages, where ordering isn't as strict). + pending_msg_events: Vec, } struct MutChannelHolder<'a> { by_id: &'a mut HashMap<[u8; 32], Channel>, @@ -264,6 +267,7 @@ struct MutChannelHolder<'a> { next_forward: &'a mut Instant, forward_htlcs: &'a mut HashMap>, claimable_htlcs: &'a mut HashMap<[u8; 32], Vec>, + pending_msg_events: &'a mut Vec, } impl ChannelHolder { fn borrow_parts(&mut self) -> MutChannelHolder { @@ -273,6 +277,7 @@ impl ChannelHolder { next_forward: &mut self.next_forward, forward_htlcs: &mut self.forward_htlcs, claimable_htlcs: &mut self.claimable_htlcs, + pending_msg_events: &mut self.pending_msg_events, } } } @@ -397,6 +402,7 @@ impl ChannelManager { next_forward: Instant::now(), forward_htlcs: HashMap::new(), claimable_htlcs: HashMap::new(), + pending_msg_events: Vec::new(), }), our_network_key: keys_manager.get_node_secret(), @@ -418,7 +424,7 @@ impl ChannelManager { /// 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 + /// If successful, will generate a SendOpenChannel message 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 @@ -436,9 +442,7 @@ impl ChannelManager { }, hash_map::Entry::Vacant(entry) => { entry.insert(channel); } } - - let mut events = self.pending_events.lock().unwrap(); - events.push(events::Event::SendOpenChannel { + channel_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel { node_id: their_network_key, msg: res, }); @@ -488,25 +492,29 @@ impl ChannelManager { /// 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. + /// May generate a SendShutdown message event on success, which should be relayed. pub fn close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError> { - let (mut res, node_id, chan_option) = { + let (mut failed_htlcs, chan_option) = { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = channel_state_lock.borrow_parts(); match channel_state.by_id.entry(channel_id.clone()) { hash_map::Entry::Occupied(mut chan_entry) => { - let res = chan_entry.get_mut().get_shutdown()?; + let (shutdown_msg, failed_htlcs) = chan_entry.get_mut().get_shutdown()?; + channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown { + node_id: chan_entry.get().get_their_node_id(), + msg: shutdown_msg + }); if chan_entry.get().is_shutdown() { if let Some(short_id) = chan_entry.get().get_short_channel_id() { channel_state.short_to_id.remove(&short_id); } - (res, chan_entry.get().get_their_node_id(), Some(chan_entry.remove_entry().1)) - } else { (res, chan_entry.get().get_their_node_id(), None) } + (failed_htlcs, Some(chan_entry.remove_entry().1)) + } else { (failed_htlcs, None) } }, hash_map::Entry::Vacant(_) => return Err(APIError::ChannelUnavailable{err: "No such channel"}) } }; - for htlc_source in res.1.drain(..) { + for htlc_source in failed_htlcs.drain(..) { // unknown_next_peer...I dunno who that is anymore.... self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() }); } @@ -516,16 +524,12 @@ impl ChannelManager { } else { None } } else { None }; - let mut events = self.pending_events.lock().unwrap(); if let Some(update) = chan_update { - events.push(events::Event::BroadcastChannelUpdate { + let mut channel_state = self.channel_state.lock().unwrap(); + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } - events.push(events::Event::SendShutdown { - node_id, - msg: res.0 - }); Ok(()) } @@ -565,9 +569,9 @@ impl ChannelManager { } }; self.finish_force_close_channel(chan.force_shutdown()); - let mut events = self.pending_events.lock().unwrap(); if let Ok(update) = self.get_channel_update(&chan) { - events.push(events::Event::BroadcastChannelUpdate { + let mut channel_state = self.channel_state.lock().unwrap(); + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } @@ -594,9 +598,9 @@ impl ChannelManager { }; mem::drop(channel_state_lock); self.finish_force_close_channel(chan.force_shutdown()); - let mut events = self.pending_events.lock().unwrap(); if let Ok(update) = self.get_channel_update(&chan) { - events.push(events::Event::BroadcastChannelUpdate { + let mut channel_state = self.channel_state.lock().unwrap(); + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } @@ -1096,7 +1100,7 @@ impl ChannelManager { /// payment_preimage tracking (which you should already be doing as they represent "proof of /// payment") and prevent double-sends yourself. /// - /// May generate a SendHTLCs event on success, which should be relayed. + /// May generate a SendHTLCs message event on success, which should be relayed. /// /// Raises APIError::RoutError when invalid route or forward parameter /// (cltv_delta, fee, node public key) is specified @@ -1124,66 +1128,52 @@ impl ChannelManager { let (onion_payloads, htlc_msat, htlc_cltv) = ChannelManager::build_onion_payloads(&route, cur_height)?; let onion_packet = ChannelManager::construct_onion_packet(onion_payloads, onion_keys, &payment_hash); - let (first_hop_node_id, update_add, commitment_signed) = { - let mut channel_state = self.channel_state.lock().unwrap(); - - let id = match channel_state.short_to_id.get(&route.hops.first().unwrap().short_channel_id) { - None => return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!"}), - Some(id) => id.clone(), - }; - - let res = { - let res = { - let chan = channel_state.by_id.get_mut(&id).unwrap(); - if chan.get_their_node_id() != route.hops.first().unwrap().pubkey { - return Err(APIError::RouteError{err: "Node ID mismatch on first hop!"}); - } - if chan.is_awaiting_monitor_update() { - return Err(APIError::MonitorUpdateFailed); - } - if !chan.is_live() { - return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected!"}); - } - chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute { - route: route.clone(), - session_priv: session_priv.clone(), - first_hop_htlc_msat: htlc_msat, - }, onion_packet).map_err(|he| APIError::ChannelUnavailable{err: he.err})? - }; - match res { - Some((update_add, commitment_signed, chan_monitor)) => { - if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { - self.handle_monitor_update_fail(channel_state, &id, e, RAACommitmentOrder::CommitmentFirst); - return Err(APIError::MonitorUpdateFailed); - } - Some((update_add, commitment_signed)) - }, - None => None, - } - }; + let mut channel_state = self.channel_state.lock().unwrap(); - let first_hop_node_id = route.hops.first().unwrap().pubkey; + let id = match channel_state.short_to_id.get(&route.hops.first().unwrap().short_channel_id) { + None => return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!"}), + Some(id) => id.clone(), + }; - match res { - Some((update_add, commitment_signed)) => { - (first_hop_node_id, update_add, commitment_signed) - }, - None => return Ok(()), + let res = { + let chan = channel_state.by_id.get_mut(&id).unwrap(); + if chan.get_their_node_id() != route.hops.first().unwrap().pubkey { + return Err(APIError::RouteError{err: "Node ID mismatch on first hop!"}); } + if chan.is_awaiting_monitor_update() { + return Err(APIError::MonitorUpdateFailed); + } + if !chan.is_live() { + return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected!"}); + } + chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute { + route: route.clone(), + session_priv: session_priv.clone(), + first_hop_htlc_msat: htlc_msat, + }, onion_packet).map_err(|he| APIError::ChannelUnavailable{err: he.err})? }; + match res { + Some((update_add, commitment_signed, chan_monitor)) => { + if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { + self.handle_monitor_update_fail(channel_state, &id, e, RAACommitmentOrder::CommitmentFirst); + return Err(APIError::MonitorUpdateFailed); + } - let mut events = self.pending_events.lock().unwrap(); - events.push(events::Event::UpdateHTLCs { - node_id: first_hop_node_id, - updates: msgs::CommitmentUpdate { - update_add_htlcs: vec![update_add], - update_fulfill_htlcs: Vec::new(), - update_fail_htlcs: Vec::new(), - update_fail_malformed_htlcs: Vec::new(), - update_fee: None, - commitment_signed, + channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { + node_id: route.hops.first().unwrap().pubkey, + updates: msgs::CommitmentUpdate { + update_add_htlcs: vec![update_add], + update_fulfill_htlcs: Vec::new(), + update_fail_htlcs: Vec::new(), + update_fail_malformed_htlcs: Vec::new(), + update_fee: None, + commitment_signed, + }, + }); }, - }); + None => {}, + } + Ok(()) } @@ -1194,15 +1184,6 @@ impl ChannelManager { /// 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) { - macro_rules! add_pending_event { - ($event: expr) => { - { - let mut pending_events = self.pending_events.lock().unwrap(); - pending_events.push($event); - } - } - } - let (chan, msg, chan_monitor) = { let mut channel_state = self.channel_state.lock().unwrap(); match channel_state.by_id.remove(temporary_channel_id) { @@ -1213,8 +1194,7 @@ impl ChannelManager { }, Err(e) => { log_error!(self, "Got bad signatures: {}!", e.err); - mem::drop(channel_state); - add_pending_event!(events::Event::HandleError { + channel_state.pending_msg_events.push(events::MessageSendEvent::HandleError { node_id: chan.get_their_node_id(), action: e.action, }); @@ -1230,12 +1210,12 @@ impl ChannelManager { if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { unimplemented!(); } - add_pending_event!(events::Event::SendFundingCreated { + + let mut channel_state = self.channel_state.lock().unwrap(); + channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated { node_id: chan.get_their_node_id(), msg: msg, }); - - let mut channel_state = self.channel_state.lock().unwrap(); match channel_state.by_id.entry(chan.channel_id()) { hash_map::Entry::Occupied(_) => { panic!("Generated duplicate funding txid?"); @@ -1344,7 +1324,7 @@ impl ChannelManager { if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) { unimplemented!();// but def dont push the event... } - new_events.push(events::Event::UpdateHTLCs { + channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { node_id: forward_chan.get_their_node_id(), updates: msgs::CommitmentUpdate { update_add_htlcs: add_htlc_msgs, @@ -1407,19 +1387,20 @@ impl ChannelManager { /// to fail and take the channel_state lock for each iteration (as we take ownership and may /// drop it). In other words, no assumptions are made that entries in claimable_htlcs point to /// still-available channels. - fn fail_htlc_backwards_internal(&self, mut channel_state: MutexGuard, source: HTLCSource, payment_hash: &[u8; 32], onion_error: HTLCFailReason) { + fn fail_htlc_backwards_internal(&self, mut channel_state_lock: MutexGuard, source: HTLCSource, payment_hash: &[u8; 32], onion_error: HTLCFailReason) { match source { HTLCSource::OutboundRoute { .. } => { - mem::drop(channel_state); + mem::drop(channel_state_lock); if let &HTLCFailReason::ErrorPacket { ref err } = &onion_error { let (channel_update, payment_retryable) = self.process_onion_failure(&source, err.data.clone()); - let mut pending_events = self.pending_events.lock().unwrap(); - if let Some(channel_update) = channel_update { - pending_events.push(events::Event::PaymentFailureNetworkUpdate { - update: channel_update, - }); + if let Some(update) = channel_update { + self.channel_state.lock().unwrap().pending_msg_events.push( + events::MessageSendEvent::PaymentFailureNetworkUpdate { + update, + } + ); } - pending_events.push(events::Event::PaymentFailed { + self.pending_events.lock().unwrap().push(events::Event::PaymentFailed { payment_hash: payment_hash.clone(), rejected_by_dest: !payment_retryable, }); @@ -1438,35 +1419,21 @@ impl ChannelManager { } }; - let (node_id, fail_msgs) = { - let chan_id = match channel_state.short_to_id.get(&short_channel_id) { - Some(chan_id) => chan_id.clone(), - None => return - }; + let channel_state = channel_state_lock.borrow_parts(); - let chan = channel_state.by_id.get_mut(&chan_id).unwrap(); - match chan.get_update_fail_htlc_and_commit(htlc_id, err_packet) { - Ok(Some((msg, commitment_msg, chan_monitor))) => { - if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { - unimplemented!(); - } - (chan.get_their_node_id(), Some((msg, commitment_msg))) - }, - Ok(None) => (chan.get_their_node_id(), None), - Err(_e) => { - //TODO: Do something with e? - return; - }, - } + let chan_id = match channel_state.short_to_id.get(&short_channel_id) { + Some(chan_id) => chan_id.clone(), + None => return }; - match fail_msgs { - Some((msg, commitment_msg)) => { - mem::drop(channel_state); - - let mut pending_events = self.pending_events.lock().unwrap(); - pending_events.push(events::Event::UpdateHTLCs { - node_id, + let chan = channel_state.by_id.get_mut(&chan_id).unwrap(); + match chan.get_update_fail_htlc_and_commit(htlc_id, err_packet) { + Ok(Some((msg, commitment_msg, chan_monitor))) => { + if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { + unimplemented!(); + } + channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { + node_id: chan.get_their_node_id(), updates: msgs::CommitmentUpdate { update_add_htlcs: Vec::new(), update_fulfill_htlcs: Vec::new(), @@ -1477,7 +1444,11 @@ impl ChannelManager { }, }); }, - None => {}, + Ok(None) => {}, + Err(_e) => { + //TODO: Do something with e? + return; + }, } }, } @@ -1504,10 +1475,10 @@ impl ChannelManager { true } else { false } } - fn claim_funds_internal(&self, mut channel_state: MutexGuard, source: HTLCSource, payment_preimage: [u8; 32]) { + fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard, source: HTLCSource, payment_preimage: [u8; 32]) { match source { HTLCSource::OutboundRoute { .. } => { - mem::drop(channel_state); + mem::drop(channel_state_lock); let mut pending_events = self.pending_events.lock().unwrap(); pending_events.push(events::Event::PaymentSent { payment_preimage @@ -1515,49 +1486,46 @@ impl ChannelManager { }, HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, .. }) => { //TODO: Delay the claimed_funds relaying just like we do outbound relay! - let (node_id, fulfill_msgs) = { - let chan_id = match channel_state.short_to_id.get(&short_channel_id) { - Some(chan_id) => chan_id.clone(), - None => { - // TODO: There is probably a channel manager somewhere that needs to - // learn the preimage as the channel already hit the chain and that's - // why its missing. - return - } - }; + let channel_state = channel_state_lock.borrow_parts(); + + let chan_id = match channel_state.short_to_id.get(&short_channel_id) { + Some(chan_id) => chan_id.clone(), + None => { + // TODO: There is probably a channel manager somewhere that needs to + // learn the preimage as the channel already hit the chain and that's + // why its missing. + return + } + }; - let chan = channel_state.by_id.get_mut(&chan_id).unwrap(); - match chan.get_update_fulfill_htlc_and_commit(htlc_id, payment_preimage) { - Ok((msgs, Some(chan_monitor))) => { + let chan = channel_state.by_id.get_mut(&chan_id).unwrap(); + match chan.get_update_fulfill_htlc_and_commit(htlc_id, payment_preimage) { + Ok((msgs, monitor_option)) => { + if let Some(chan_monitor) = monitor_option { if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { unimplemented!();// but def dont push the event... } - (chan.get_their_node_id(), msgs) - }, - Ok((msgs, None)) => (chan.get_their_node_id(), msgs), - Err(_e) => { - // TODO: There is probably a channel manager somewhere that needs to - // learn the preimage as the channel may be about to hit the chain. - //TODO: Do something with e? - return - }, - } - }; - - mem::drop(channel_state); - if let Some((msg, commitment_msg)) = fulfill_msgs { - let mut pending_events = self.pending_events.lock().unwrap(); - pending_events.push(events::Event::UpdateHTLCs { - node_id: node_id, - updates: msgs::CommitmentUpdate { - update_add_htlcs: Vec::new(), - update_fulfill_htlcs: vec![msg], - update_fail_htlcs: Vec::new(), - update_fail_malformed_htlcs: Vec::new(), - update_fee: None, - commitment_signed: commitment_msg, } - }); + if let Some((msg, commitment_signed)) = msgs { + channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { + node_id: chan.get_their_node_id(), + updates: msgs::CommitmentUpdate { + update_add_htlcs: Vec::new(), + update_fulfill_htlcs: vec![msg], + update_fail_htlcs: Vec::new(), + update_fail_malformed_htlcs: Vec::new(), + update_fee: None, + commitment_signed, + } + }); + } + }, + Err(_e) => { + // TODO: There is probably a channel manager somewhere that needs to + // learn the preimage as the channel may be about to hit the chain. + //TODO: Do something with e? + return + }, } }, } @@ -1572,7 +1540,6 @@ impl ChannelManager { /// ChannelMonitorUpdateErr::TemporaryFailure was returned from a channel monitor update /// operation. pub fn test_restore_channel_monitor(&self) { - let mut new_events = Vec::new(); let mut close_results = Vec::new(); let mut htlc_forwards = Vec::new(); let mut htlc_failures = Vec::new(); @@ -1581,6 +1548,7 @@ impl ChannelManager { let mut channel_lock = self.channel_state.lock().unwrap(); let channel_state = channel_lock.borrow_parts(); let short_to_id = channel_state.short_to_id; + let pending_msg_events = channel_state.pending_msg_events; channel_state.by_id.retain(|_, channel| { if channel.is_awaiting_monitor_update() { let chan_monitor = channel.channel_monitor(); @@ -1592,7 +1560,7 @@ impl ChannelManager { } close_results.push(channel.force_shutdown()); if let Ok(update) = self.get_channel_update(&channel) { - new_events.push(events::Event::BroadcastChannelUpdate { + pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } @@ -1609,7 +1577,7 @@ impl ChannelManager { macro_rules! handle_cs { () => { if let Some(update) = commitment_update { - new_events.push(events::Event::UpdateHTLCs { + pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { node_id: channel.get_their_node_id(), updates: update, }); @@ -1617,7 +1585,7 @@ impl ChannelManager { } } macro_rules! handle_raa { () => { if let Some(revoke_and_ack) = raa { - new_events.push(events::Event::SendRevokeAndACK { + pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK { node_id: channel.get_their_node_id(), msg: revoke_and_ack, }); @@ -1647,8 +1615,6 @@ impl ChannelManager { for res in close_results.drain(..) { self.finish_force_close_channel(res); } - - self.pending_events.lock().unwrap().append(&mut new_events); } fn internal_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result { @@ -1802,8 +1768,8 @@ impl ChannelManager { } if let Some(chan) = chan_option { if let Ok(update) = self.get_channel_update(&chan) { - let mut events = self.pending_events.lock().unwrap(); - events.push(events::Event::BroadcastChannelUpdate { + let mut channel_state = self.channel_state.lock().unwrap(); + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } @@ -1842,8 +1808,8 @@ impl ChannelManager { } if let Some(chan) = chan_option { if let Ok(update) = self.get_channel_update(&chan) { - let mut events = self.pending_events.lock().unwrap(); - events.push(events::Event::BroadcastChannelUpdate { + let mut channel_state = self.channel_state.lock().unwrap(); + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } @@ -2223,42 +2189,43 @@ impl ChannelManager { } fn internal_announcement_signatures(&self, their_node_id: &PublicKey, msg: &msgs::AnnouncementSignatures) -> Result<(), MsgHandleErrInternal> { - let (chan_announcement, chan_update) = { - 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)); - } - if !chan.is_usable() { - return Err(MsgHandleErrInternal::from_no_close(HandleError{err: "Got an announcement_signatures before we were ready for it", action: Some(msgs::ErrorAction::IgnoreError)})); - } + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); - let our_node_id = self.get_our_node_id(); - let (announcement, our_bitcoin_sig) = chan.get_channel_announcement(our_node_id.clone(), self.genesis_hash.clone()) - .map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))?; + 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)); + } + if !chan.is_usable() { + return Err(MsgHandleErrInternal::from_no_close(HandleError{err: "Got an announcement_signatures before we were ready for it", action: Some(msgs::ErrorAction::IgnoreError)})); + } - let were_node_one = announcement.node_id_1 == our_node_id; - let msghash = Message::from_slice(&Sha256dHash::from_data(&announcement.encode()[..])[..]).unwrap(); - let bad_sig_action = MsgHandleErrInternal::send_err_msg_close_chan("Bad announcement_signatures node_signature", msg.channel_id); - secp_call!(self.secp_ctx.verify(&msghash, &msg.node_signature, if were_node_one { &announcement.node_id_2 } else { &announcement.node_id_1 }), bad_sig_action); - secp_call!(self.secp_ctx.verify(&msghash, &msg.bitcoin_signature, if were_node_one { &announcement.bitcoin_key_2 } else { &announcement.bitcoin_key_1 }), bad_sig_action); + let our_node_id = self.get_our_node_id(); + let (announcement, our_bitcoin_sig) = chan.get_channel_announcement(our_node_id.clone(), self.genesis_hash.clone()) + .map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))?; - let our_node_sig = self.secp_ctx.sign(&msghash, &self.our_network_key); + let were_node_one = announcement.node_id_1 == our_node_id; + let msghash = Message::from_slice(&Sha256dHash::from_data(&announcement.encode()[..])[..]).unwrap(); + let bad_sig_action = MsgHandleErrInternal::send_err_msg_close_chan("Bad announcement_signatures node_signature", msg.channel_id); + secp_call!(self.secp_ctx.verify(&msghash, &msg.node_signature, if were_node_one { &announcement.node_id_2 } else { &announcement.node_id_1 }), bad_sig_action); + secp_call!(self.secp_ctx.verify(&msghash, &msg.bitcoin_signature, if were_node_one { &announcement.bitcoin_key_2 } else { &announcement.bitcoin_key_1 }), bad_sig_action); - (msgs::ChannelAnnouncement { + let our_node_sig = self.secp_ctx.sign(&msghash, &self.our_network_key); + + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement { + msg: msgs::ChannelAnnouncement { node_signature_1: if were_node_one { our_node_sig } else { msg.node_signature }, node_signature_2: if were_node_one { msg.node_signature } else { our_node_sig }, bitcoin_signature_1: if were_node_one { our_bitcoin_sig } else { msg.bitcoin_signature }, bitcoin_signature_2: if were_node_one { msg.bitcoin_signature } else { our_bitcoin_sig }, contents: announcement, - }, self.get_channel_update(chan).unwrap()) // can only fail if we're not in a ready state - }, - None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) - } - }; - let mut pending_events = self.pending_events.lock().unwrap(); - pending_events.push(events::Event::BroadcastChannelAnnouncement { msg: chan_announcement, update_msg: chan_update }); + }, + update_msg: self.get_channel_update(chan).unwrap(), // can only fail if we're not in a ready state + }); + }, + None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } Ok(()) } @@ -2292,7 +2259,9 @@ impl ChannelManager { /// 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(); + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); + match channel_state.by_id.get_mut(&channel_id) { None => return Err(APIError::APIMisuseError{err: "Failed to find corresponding channel"}), Some(chan) => { @@ -2309,8 +2278,7 @@ impl ChannelManager { 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 { + channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { node_id: chan.get_their_node_id(), updates: msgs::CommitmentUpdate { update_add_htlcs: Vec::new(), @@ -2328,10 +2296,19 @@ impl ChannelManager { } } +impl events::MessageSendEventsProvider for ChannelManager { + fn get_and_clear_pending_msg_events(&self) -> Vec { + let mut ret = Vec::new(); + let mut channel_state = self.channel_state.lock().unwrap(); + mem::swap(&mut ret, &mut channel_state.pending_msg_events); + ret + } +} + impl events::EventsProvider for ChannelManager { fn get_and_clear_pending_events(&self) -> Vec { - let mut pending_events = self.pending_events.lock().unwrap(); let mut ret = Vec::new(); + let mut pending_events = self.pending_events.lock().unwrap(); mem::swap(&mut ret, &mut *pending_events); ret } @@ -2339,24 +2316,24 @@ impl events::EventsProvider for ChannelManager { impl ChainListener for ChannelManager { fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) { - let mut new_events = Vec::new(); let mut failed_channels = Vec::new(); { let mut channel_lock = self.channel_state.lock().unwrap(); let channel_state = channel_lock.borrow_parts(); let short_to_id = channel_state.short_to_id; + let pending_msg_events = channel_state.pending_msg_events; channel_state.by_id.retain(|_, channel| { let chan_res = channel.block_connected(header, height, txn_matched, indexes_of_txn_matched); if let Ok(Some(funding_locked)) = chan_res { let announcement_sigs = self.get_announcement_sigs(channel); - new_events.push(events::Event::SendFundingLocked { + pending_msg_events.push(events::MessageSendEvent::SendFundingLocked { node_id: channel.get_their_node_id(), msg: funding_locked, announcement_sigs: announcement_sigs }); short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id()); } else if let Err(e) = chan_res { - new_events.push(events::Event::HandleError { + pending_msg_events.push(events::MessageSendEvent::HandleError { node_id: channel.get_their_node_id(), action: e.action, }); @@ -2376,7 +2353,7 @@ impl ChainListener for ChannelManager { // some kind of SPV attack, though we expect these to be dropped. failed_channels.push(channel.force_shutdown()); if let Ok(update) = self.get_channel_update(&channel) { - new_events.push(events::Event::BroadcastChannelUpdate { + pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } @@ -2395,7 +2372,7 @@ impl ChainListener for ChannelManager { // hurt anything, but does make tests a bit simpler). failed_channels.last_mut().unwrap().0 = Vec::new(); if let Ok(update) = self.get_channel_update(&channel) { - new_events.push(events::Event::BroadcastChannelUpdate { + pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } @@ -2407,21 +2384,17 @@ impl ChainListener for ChannelManager { for failure in failed_channels.drain(..) { self.finish_force_close_channel(failure); } - let mut pending_events = self.pending_events.lock().unwrap(); - for funding_locked in new_events.drain(..) { - pending_events.push(funding_locked); - } self.latest_block_height.store(height as usize, Ordering::Release); } /// We force-close the channel without letting our counterparty participate in the shutdown fn block_disconnected(&self, header: &BlockHeader) { - let mut new_events = Vec::new(); let mut failed_channels = Vec::new(); { let mut channel_lock = self.channel_state.lock().unwrap(); let channel_state = channel_lock.borrow_parts(); let short_to_id = channel_state.short_to_id; + let pending_msg_events = channel_state.pending_msg_events; channel_state.by_id.retain(|_, v| { if v.block_disconnected(header) { if let Some(short_id) = v.get_short_channel_id() { @@ -2429,7 +2402,7 @@ impl ChainListener for ChannelManager { } failed_channels.push(v.force_shutdown()); if let Ok(update) = self.get_channel_update(&v) { - new_events.push(events::Event::BroadcastChannelUpdate { + pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } @@ -2442,12 +2415,6 @@ impl ChainListener for ChannelManager { for failure in failed_channels.drain(..) { self.finish_force_close_channel(failure); } - if !new_events.is_empty() { - let mut pending_events = self.pending_events.lock().unwrap(); - for funding_locked in new_events.drain(..) { - pending_events.push(funding_locked); - } - } self.latest_block_height.fetch_sub(1, Ordering::AcqRel); } } @@ -2551,13 +2518,13 @@ impl ChannelMessageHandler for ChannelManager { } 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(); let short_to_id = channel_state.short_to_id; + let pending_msg_events = channel_state.pending_msg_events; if no_connection_possible { channel_state.by_id.retain(|_, chan| { if chan.get_their_node_id() == *their_node_id { @@ -2566,7 +2533,7 @@ impl ChannelMessageHandler for ChannelManager { } failed_channels.push(chan.force_shutdown()); if let Ok(update) = self.get_channel_update(&chan) { - new_events.push(events::Event::BroadcastChannelUpdate { + pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { msg: update }); } @@ -2598,12 +2565,6 @@ impl ChannelMessageHandler for ChannelManager { for failure in failed_channels.drain(..) { self.finish_force_close_channel(failure); } - if !new_events.is_empty() { - let mut pending_events = self.pending_events.lock().unwrap(); - for event in new_events.drain(..) { - 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() }); @@ -2658,7 +2619,7 @@ mod tests { use ln::msgs; use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler}; use util::test_utils; - use util::events::{Event, EventsProvider}; + use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider}; use util::errors::APIError; use util::logger::Logger; use util::ser::Writeable; @@ -2863,6 +2824,7 @@ mod tests { fn drop(&mut self) { if !::std::thread::panicking() { // Check that we processed all pending events + assert_eq!(self.node.get_and_clear_pending_msg_events().len(), 0); assert_eq!(self.node.get_and_clear_pending_events().len(), 0); assert_eq!(self.chan_monitor.added_monitors.lock().unwrap().len(), 0); } @@ -2882,10 +2844,10 @@ mod tests { fn create_chan_between_nodes_with_value_init(node_a: &Node, node_b: &Node, channel_value: u64, push_msat: u64) -> Transaction { node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42).unwrap(); - let events_1 = node_a.node.get_and_clear_pending_events(); + let events_1 = node_a.node.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 1); let accept_chan = match events_1[0] { - Event::SendOpenChannel { ref node_id, ref msg } => { + MessageSendEvent::SendOpenChannel { ref node_id, ref msg } => { assert_eq!(*node_id, node_b.node.get_our_node_id()); node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), msg).unwrap() }, @@ -2919,10 +2881,10 @@ mod tests { _ => panic!("Unexpected event"), } - let events_3 = node_a.node.get_and_clear_pending_events(); + let events_3 = node_a.node.get_and_clear_pending_msg_events(); assert_eq!(events_3.len(), 1); let funding_signed = match events_3[0] { - Event::SendFundingCreated { ref node_id, ref msg } => { + MessageSendEvent::SendFundingCreated { ref node_id, ref msg } => { assert_eq!(*node_id, node_b.node.get_our_node_id()); let res = node_b.node.handle_funding_created(&node_a.node.get_our_node_id(), msg).unwrap(); let mut added_monitors = node_b.chan_monitor.added_monitors.lock().unwrap(); @@ -2957,10 +2919,10 @@ mod tests { fn create_chan_between_nodes_with_value_confirm(node_a: &Node, node_b: &Node, tx: &Transaction) -> ((msgs::FundingLocked, msgs::AnnouncementSignatures), [u8; 32]) { confirm_transaction(&node_b.chain_monitor, &tx, tx.version); - let events_5 = node_b.node.get_and_clear_pending_events(); + let events_5 = node_b.node.get_and_clear_pending_msg_events(); assert_eq!(events_5.len(), 1); match events_5[0] { - Event::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { + MessageSendEvent::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { assert_eq!(*node_id, node_a.node.get_our_node_id()); assert!(announcement_sigs.is_none()); node_a.node.handle_funding_locked(&node_b.node.get_our_node_id(), msg).unwrap() @@ -2971,10 +2933,10 @@ mod tests { let channel_id; confirm_transaction(&node_a.chain_monitor, &tx, tx.version); - let events_6 = node_a.node.get_and_clear_pending_events(); + let events_6 = node_a.node.get_and_clear_pending_msg_events(); assert_eq!(events_6.len(), 1); (match events_6[0] { - Event::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { + MessageSendEvent::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { channel_id = msg.channel_id.clone(); assert_eq!(*node_id, node_b.node.get_our_node_id()); (msg.clone(), announcement_sigs.clone().unwrap()) @@ -2996,20 +2958,20 @@ mod tests { bs_announcement_sigs }; - let events_7 = node_b.node.get_and_clear_pending_events(); + let events_7 = node_b.node.get_and_clear_pending_msg_events(); assert_eq!(events_7.len(), 1); let (announcement, bs_update) = match events_7[0] { - Event::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { + MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { (msg, update_msg) }, _ => panic!("Unexpected event"), }; node_a.node.handle_announcement_signatures(&node_b.node.get_our_node_id(), &bs_announcement_sigs).unwrap(); - let events_8 = node_a.node.get_and_clear_pending_events(); + let events_8 = node_a.node.get_and_clear_pending_msg_events(); assert_eq!(events_8.len(), 1); let as_update = match events_8[0] { - Event::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { + MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { assert!(*announcement == *msg); update_msg }, @@ -3052,10 +3014,10 @@ mod tests { let (tx_a, tx_b); node_a.close_channel(channel_id).unwrap(); - let events_1 = node_a.get_and_clear_pending_events(); + let events_1 = node_a.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 1); let shutdown_a = match events_1[0] { - Event::SendShutdown { ref node_id, ref msg } => { + MessageSendEvent::SendShutdown { ref node_id, ref msg } => { assert_eq!(node_id, &node_b.get_our_node_id()); msg.clone() }, @@ -3091,19 +3053,19 @@ mod tests { assert_eq!(tx_a, tx_b); check_spends!(tx_a, funding_tx); - let events_2 = node_a.get_and_clear_pending_events(); + let events_2 = node_a.get_and_clear_pending_msg_events(); assert_eq!(events_2.len(), 1); let as_update = match events_2[0] { - Event::BroadcastChannelUpdate { ref msg } => { + MessageSendEvent::BroadcastChannelUpdate { ref msg } => { msg.clone() }, _ => panic!("Unexpected event"), }; - let events_3 = node_b.get_and_clear_pending_events(); + let events_3 = node_b.get_and_clear_pending_msg_events(); assert_eq!(events_3.len(), 1); let bs_update = match events_3[0] { - Event::BroadcastChannelUpdate { ref msg } => { + MessageSendEvent::BroadcastChannelUpdate { ref msg } => { msg.clone() }, _ => panic!("Unexpected event"), @@ -3126,9 +3088,9 @@ mod tests { SendEvent { node_id: node_id, msgs: updates.update_add_htlcs, commitment_msg: updates.commitment_signed } } - fn from_event(event: Event) -> SendEvent { + fn from_event(event: MessageSendEvent) -> SendEvent { match event { - Event::UpdateHTLCs { node_id, updates } => SendEvent::from_commitment_update(node_id, updates), + MessageSendEvent::UpdateHTLCs { node_id, updates } => SendEvent::from_commitment_update(node_id, updates), _ => panic!("Unexpected event type!"), } } @@ -3158,6 +3120,7 @@ mod tests { check_added_monitors!($node_b, 1); if $fail_backwards { assert!($node_a.node.get_and_clear_pending_events().is_empty()); + assert!($node_a.node.get_and_clear_pending_msg_events().is_empty()); } assert!($node_a.node.handle_revoke_and_ack(&$node_b.node.get_our_node_id(), &bs_revoke_and_ack).unwrap().is_none()); { @@ -3195,7 +3158,7 @@ mod tests { origin_node.node.send_payment(route, our_payment_hash).unwrap(); check_added_monitors!(origin_node, 1); - let mut events = origin_node.node.get_and_clear_pending_events(); + let mut events = origin_node.node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); SendEvent::from_event(events.remove(0)) }; @@ -3218,9 +3181,9 @@ mod tests { node.node.channel_state.lock().unwrap().next_forward = Instant::now(); node.node.process_pending_htlc_forwards(); - let mut events_2 = node.node.get_and_clear_pending_events(); - assert_eq!(events_2.len(), 1); if idx == expected_route.len() - 1 { + let events_2 = node.node.get_and_clear_pending_events(); + assert_eq!(events_2.len(), 1); match events_2[0] { Event::PaymentReceived { ref payment_hash, amt } => { assert_eq!(our_payment_hash, *payment_hash); @@ -3229,6 +3192,8 @@ mod tests { _ => panic!("Unexpected event"), } } else { + let mut events_2 = node.node.get_and_clear_pending_msg_events(); + assert_eq!(events_2.len(), 1); check_added_monitors!(node, 1); payment_event = SendEvent::from_event(events_2.remove(0)); assert_eq!(payment_event.msgs.len(), 1); @@ -3267,11 +3232,11 @@ mod tests { update_fulfill_dance!(node, prev_node, false); } - let events = node.node.get_and_clear_pending_events(); + let events = node.node.get_and_clear_pending_msg_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 } } => { + MessageSendEvent::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()); @@ -3367,11 +3332,11 @@ mod tests { update_fail_dance!(node, prev_node, skip_last && idx == expected_route.len() - 1); } - let events = node.node.get_and_clear_pending_events(); + let events = node.node.get_and_clear_pending_msg_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 } } => { + MessageSendEvent::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); @@ -3477,10 +3442,10 @@ mod tests { 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(); + let events_0 = nodes[0].node.get_and_clear_pending_msg_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, .. }, .. } => { + MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, ref commitment_signed, .. }, .. } => { (update_fee.as_ref(), commitment_signed) }, _ => panic!("Unexpected event"), @@ -3494,7 +3459,7 @@ mod tests { check_added_monitors!(nodes[1], 1); let payment_event = { - let mut events_1 = nodes[1].node.get_and_clear_pending_events(); + let mut events_1 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 1); SendEvent::from_event(events_1.remove(0)) }; @@ -3573,10 +3538,10 @@ mod tests { 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(); + let events_0 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_0.len(), 1); let update_msg = match events_0[0] { // (1) - Event::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, .. }, .. } => { + MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, .. }, .. } => { update_fee.as_ref() }, _ => panic!("Unexpected event"), @@ -3590,7 +3555,7 @@ mod tests { check_added_monitors!(nodes[1], 1); let payment_event = { - let mut events_1 = nodes[1].node.get_and_clear_pending_events(); + let mut events_1 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 1); SendEvent::from_event(events_1.remove(0)) }; @@ -3647,10 +3612,10 @@ mod tests { nodes[0].node.update_fee(channel_id, initial_feerate + 20).unwrap(); check_added_monitors!(nodes[0], 1); - let events_0 = nodes[0].node.get_and_clear_pending_events(); + let events_0 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_0.len(), 1); let (update_msg_1, commitment_signed_1) = match events_0[0] { // (1) - Event::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, ref commitment_signed, .. }, .. } => { + MessageSendEvent::UpdateHTLCs { updates: msgs::CommitmentUpdate { ref update_fee, ref commitment_signed, .. }, .. } => { (update_fee.as_ref().unwrap(), commitment_signed) }, _ => panic!("Unexpected event"), @@ -3665,6 +3630,7 @@ mod tests { // transaction: nodes[0].node.update_fee(channel_id, initial_feerate + 40).unwrap(); assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); // Create the (3) update_fee message that nodes[0] will generate before it does... let mut update_msg_2 = msgs::UpdateFee { @@ -3729,10 +3695,10 @@ mod tests { 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(); + let events_0 = nodes[0].node.get_and_clear_pending_msg_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 } } => { + MessageSendEvent::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"), @@ -3777,10 +3743,10 @@ mod tests { 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(); + let events_0 = nodes[0].node.get_and_clear_pending_msg_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 } } => { + MessageSendEvent::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"), @@ -3802,8 +3768,8 @@ mod tests { assert_eq!(added_monitors.len(), 0); added_monitors.clear(); } - let events = nodes[0].node.get_and_clear_pending_events(); - assert_eq!(events.len(), 0); + assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); // 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(); @@ -3894,10 +3860,10 @@ mod tests { 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(); + let events_0 = nodes[0].node.get_and_clear_pending_msg_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 } } => { + MessageSendEvent::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"), @@ -3917,10 +3883,10 @@ mod tests { // 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(); + let events_0 = nodes[0].node.get_and_clear_pending_msg_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 } } => { + MessageSendEvent::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"), @@ -4191,19 +4157,19 @@ mod tests { } fn get_announce_close_broadcast_events(nodes: &Vec, a: usize, b: usize) { - let events_1 = nodes[a].node.get_and_clear_pending_events(); + let events_1 = nodes[a].node.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 1); let as_update = match events_1[0] { - Event::BroadcastChannelUpdate { ref msg } => { + MessageSendEvent::BroadcastChannelUpdate { ref msg } => { msg.clone() }, _ => panic!("Unexpected event"), }; - let events_2 = nodes[b].node.get_and_clear_pending_events(); + let events_2 = nodes[b].node.get_and_clear_pending_msg_events(); assert_eq!(events_2.len(), 1); let bs_update = match events_2[0] { - Event::BroadcastChannelUpdate { ref msg } => { + MessageSendEvent::BroadcastChannelUpdate { ref msg } => { msg.clone() }, _ => panic!("Unexpected event"), @@ -4262,7 +4228,7 @@ mod tests { macro_rules! expect_forward { ($node: expr) => {{ - let mut events = $node.node.get_and_clear_pending_events(); + let mut events = $node.node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); check_added_monitors!($node, 1); let payment_event = SendEvent::from_event(events.remove(0)); @@ -4345,7 +4311,7 @@ mod tests { nodes[0].node.send_payment(route_1, our_payment_hash_1).unwrap(); check_added_monitors!(nodes[0], 1); - let mut events = nodes[0].node.get_and_clear_pending_events(); + let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); SendEvent::from_event(events.remove(0)) }; @@ -4421,8 +4387,8 @@ mod tests { // this will also stuck in the holding cell nodes[0].node.send_payment(route_22, our_payment_hash_22).unwrap(); check_added_monitors!(nodes[0], 0); - let events = nodes[0].node.get_and_clear_pending_events(); - assert_eq!(events.len(), 0); + assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); // flush the pending htlc let (as_revoke_and_ack, as_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event_1.commitment_msg).unwrap(); @@ -4541,10 +4507,10 @@ mod tests { assert!($node.node.claim_funds($preimage)); check_added_monitors!($node, 1); - let events = $node.node.get_and_clear_pending_events(); + let events = $node.node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); match events[0] { - Event::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, .. } } => { + MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, .. } } => { assert!(update_add_htlcs.is_empty()); assert!(update_fail_htlcs.is_empty()); assert_eq!(*node_id, $prev_node.node.get_our_node_id()); @@ -4835,10 +4801,10 @@ mod tests { route_payment(&nodes[0], &[&nodes[1]], 10000000); nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id); { - let events = nodes[0].node.get_and_clear_pending_events(); + let events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); match events[0] { - Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { + MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { assert_eq!(flags & 0b10, 0b10); }, _ => panic!("Unexpected event"), @@ -4852,10 +4818,10 @@ mod tests { nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0], &node_txn[1]], &[1; 2]); { - let events = nodes[1].node.get_and_clear_pending_events(); + let events = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); match events[0] { - Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { + MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { assert_eq!(flags & 0b10, 0b10); }, _ => panic!("Unexpected event"), @@ -4882,7 +4848,7 @@ mod tests { nodes[0].node.send_payment(route, our_payment_hash).unwrap(); check_added_monitors!(nodes[0], 1); - let mut events = nodes[0].node.get_and_clear_pending_events(); + let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); SendEvent::from_event(events.remove(0)) }; @@ -4900,7 +4866,7 @@ mod tests { nodes[1].node.channel_state.lock().unwrap().next_forward = Instant::now(); nodes[1].node.process_pending_htlc_forwards(); - let mut events_2 = nodes[1].node.get_and_clear_pending_events(); + let mut events_2 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_2.len(), 1); payment_event = SendEvent::from_event(events_2.remove(0)); assert_eq!(payment_event.msgs.len(), 1); @@ -4915,10 +4881,10 @@ mod tests { // transaction and ensure nodes[1] doesn't fail-backwards (this was originally a bug!). nodes[2].node.force_close_channel(&payment_event.commitment_msg.channel_id); - let events_3 = nodes[2].node.get_and_clear_pending_events(); + let events_3 = nodes[2].node.get_and_clear_pending_msg_events(); assert_eq!(events_3.len(), 1); match events_3[0] { - Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { + MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { assert_eq!(flags & 0b10, 0b10); }, _ => panic!("Unexpected event"), @@ -4936,11 +4902,11 @@ mod tests { let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&tx], &[1]); - let events_4 = nodes[1].node.get_and_clear_pending_events(); + let events_4 = nodes[1].node.get_and_clear_pending_msg_events(); // Note no UpdateHTLCs event here from nodes[1] to nodes[0]! assert_eq!(events_4.len(), 1); match events_4[0] { - Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { + MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { assert_eq!(flags & 0b10, 0b10); }, _ => panic!("Unexpected event"), @@ -4985,10 +4951,10 @@ mod tests { nodes[0].node.block_disconnected(&headers.pop().unwrap()); } { - let events = nodes[0].node.get_and_clear_pending_events(); + let events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); match events[0] { - Event::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { + MessageSendEvent::BroadcastChannelUpdate { msg: msgs::ChannelUpdate { contents: msgs::UnsignedChannelUpdate { flags, .. }, .. } } => { assert_eq!(flags & 0b10, 0b10); }, _ => panic!("Unexpected event"), @@ -5196,7 +5162,7 @@ mod tests { nodes[0].node.send_payment(route.clone(), payment_hash_1).unwrap(); check_added_monitors!(nodes[0], 1); - let mut events = nodes[0].node.get_and_clear_pending_events(); + let mut events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 1); SendEvent::from_event(events.remove(0)) }; @@ -5273,10 +5239,10 @@ mod tests { nodes[1].node.claim_funds(payment_preimage_1); check_added_monitors!(nodes[1], 1); - let events_3 = nodes[1].node.get_and_clear_pending_events(); + let events_3 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_3.len(), 1); let (update_fulfill_htlc, commitment_signed) = match events_3[0] { - Event::UpdateHTLCs { ref node_id, ref updates } => { + MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => { assert_eq!(*node_id, nodes[0].node.get_our_node_id()); assert!(updates.update_add_htlcs.is_empty()); assert!(updates.update_fail_htlcs.is_empty()); @@ -5384,10 +5350,10 @@ mod tests { nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); confirm_transaction(&nodes[0].chain_monitor, &tx, tx.version); - let events_1 = nodes[0].node.get_and_clear_pending_events(); + let events_1 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 1); match events_1[0] { - Event::SendFundingLocked { ref node_id, msg: _, ref announcement_sigs } => { + MessageSendEvent::SendFundingLocked { ref node_id, msg: _, ref announcement_sigs } => { assert_eq!(*node_id, nodes[1].node.get_our_node_id()); assert!(announcement_sigs.is_none()); }, @@ -5395,10 +5361,10 @@ mod tests { } confirm_transaction(&nodes[1].chain_monitor, &tx, tx.version); - let events_2 = nodes[1].node.get_and_clear_pending_events(); + let events_2 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_2.len(), 1); match events_2[0] { - Event::SendFundingLocked { ref node_id, msg: _, ref announcement_sigs } => { + MessageSendEvent::SendFundingLocked { ref node_id, msg: _, ref announcement_sigs } => { assert_eq!(*node_id, nodes[0].node.get_our_node_id()); assert!(announcement_sigs.is_none()); }, @@ -5434,20 +5400,20 @@ mod tests { nodes[0].node.send_payment(route.clone(), payment_hash_2).unwrap(); check_added_monitors!(nodes[0], 1); - let events_1 = nodes[0].node.get_and_clear_pending_events(); + let events_1 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 1); match events_1[0] { - Event::UpdateHTLCs { .. } => {}, + MessageSendEvent::UpdateHTLCs { .. } => {}, _ => panic!("Unexpected event"), } assert!(nodes[1].node.claim_funds(payment_preimage_1)); check_added_monitors!(nodes[1], 1); - let events_2 = nodes[1].node.get_and_clear_pending_events(); + let events_2 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_2.len(), 1); match events_2[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 } } => { + MessageSendEvent::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_eq!(*node_id, nodes[0].node.get_our_node_id()); assert!(update_add_htlcs.is_empty()); assert_eq!(update_fulfill_htlcs.len(), 1); @@ -5566,10 +5532,10 @@ mod tests { if let Err(APIError::MonitorUpdateFailed) = nodes[0].node.send_payment(route, payment_hash_1) {} else { panic!(); } check_added_monitors!(nodes[0], 1); - let events_1 = nodes[0].node.get_and_clear_pending_events(); + let events_1 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 1); match events_1[0] { - Event::BroadcastChannelUpdate { .. } => {}, + MessageSendEvent::BroadcastChannelUpdate { .. } => {}, _ => panic!("Unexpected event"), }; @@ -5592,8 +5558,8 @@ mod tests { if let Err(APIError::MonitorUpdateFailed) = nodes[0].node.send_payment(route.clone(), payment_hash_1) {} else { panic!(); } check_added_monitors!(nodes[0], 1); - let events_1 = nodes[0].node.get_and_clear_pending_events(); - assert!(events_1.is_empty()); + assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); assert_eq!(nodes[0].node.list_channels().len(), 1); if disconnect { @@ -5606,7 +5572,7 @@ mod tests { nodes[0].node.test_restore_channel_monitor(); check_added_monitors!(nodes[0], 1); - let mut events_2 = nodes[0].node.get_and_clear_pending_events(); + let mut events_2 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_2.len(), 1); let payment_event = SendEvent::from_event(events_2.pop().unwrap()); assert_eq!(payment_event.node_id, nodes[1].node.get_our_node_id()); @@ -5633,8 +5599,8 @@ mod tests { if let Err(APIError::MonitorUpdateFailed) = nodes[0].node.send_payment(route, payment_hash_2) {} else { panic!(); } check_added_monitors!(nodes[0], 1); - let events_4 = nodes[0].node.get_and_clear_pending_events(); - assert!(events_4.is_empty()); + assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); assert_eq!(nodes[0].node.list_channels().len(), 1); if disconnect { @@ -5648,10 +5614,10 @@ mod tests { nodes[0].node.test_restore_channel_monitor(); check_added_monitors!(nodes[0], 1); - let events_5 = nodes[0].node.get_and_clear_pending_events(); + let events_5 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_5.len(), 1); match events_5[0] { - Event::BroadcastChannelUpdate { .. } => {}, + MessageSendEvent::BroadcastChannelUpdate { .. } => {}, _ => panic!("Unexpected event"), } @@ -5700,18 +5666,18 @@ mod tests { if let Err(APIError::MonitorUpdateFailed) = nodes[0].node.send_payment(route.clone(), payment_hash_2) {} else { panic!(); } check_added_monitors!(nodes[0], 1); - let events_1 = nodes[0].node.get_and_clear_pending_events(); - assert!(events_1.is_empty()); + assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); assert_eq!(nodes[0].node.list_channels().len(), 1); // Claim the previous payment, which will result in a update_fulfill_htlc/CS from nodes[1] // but nodes[0] won't respond since it is frozen. assert!(nodes[1].node.claim_funds(payment_preimage_1)); check_added_monitors!(nodes[1], 1); - let events_2 = nodes[1].node.get_and_clear_pending_events(); + let events_2 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_2.len(), 1); let (bs_initial_fulfill, bs_initial_commitment_signed) = match events_2[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 } } => { + MessageSendEvent::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_eq!(*node_id, nodes[0].node.get_our_node_id()); assert!(update_add_htlcs.is_empty()); assert_eq!(update_fulfill_htlcs.len(), 1); @@ -5769,8 +5735,8 @@ mod tests { } } } let (payment_event, initial_revoke_and_ack) = if disconnect_count & !disconnect_flags > 0 { - let events_4 = nodes[0].node.get_and_clear_pending_events(); - assert!(events_4.is_empty()); + assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); let reestablish_1 = nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id()); assert_eq!(reestablish_1.len(), 1); @@ -5833,10 +5799,10 @@ mod tests { (SendEvent::from_commitment_update(nodes[1].node.get_our_node_id(), as_resp.2.unwrap()), as_resp.1.unwrap()) } else { - let mut events_4 = nodes[0].node.get_and_clear_pending_events(); + let mut events_4 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_4.len(), 2); (SendEvent::from_event(events_4.remove(0)), match events_4[0] { - Event::SendRevokeAndACK { ref node_id, ref msg } => { + MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => { assert_eq!(*node_id, nodes[1].node.get_our_node_id()); msg.clone() }, diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index b5db51cf2bb..29ff1a87605 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -521,7 +521,7 @@ pub enum RAACommitmentOrder { /// /// Messages MAY be called in parallel when they originate from different their_node_ids, however /// they MUST NOT be called in parallel when the two calls have the same their_node_id. -pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync { +pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Sync { //Channel init: /// Handle an incoming open_channel message from the given peer. fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &OpenChannel) -> Result; diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 82784efe5fc..631e48aa1eb 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -12,13 +12,13 @@ use ln::msgs; use util::ser::{Writeable, Writer, Readable}; use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep}; use util::byte_utils; -use util::events::{EventsProvider,Event}; +use util::events::{MessageSendEvent}; use util::logger::Logger; use std::collections::{HashMap,hash_map,LinkedList}; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicUsize, Ordering}; -use std::{cmp,error,mem,hash,fmt}; +use std::{cmp,error,hash,fmt}; /// Provides references to trait impls which handle different types of messages. pub struct MessageHandler { @@ -127,7 +127,6 @@ impl PeerHolder { pub struct PeerManager { message_handler: MessageHandler, peers: Mutex>, - pending_events: Mutex>, our_node_secret: SecretKey, initial_syncs_sent: AtomicUsize, logger: Arc, @@ -164,7 +163,6 @@ impl PeerManager { PeerManager { message_handler: message_handler, peers: Mutex::new(PeerHolder { peers: HashMap::new(), node_id_to_descriptor: HashMap::new() }), - pending_events: Mutex::new(Vec::new()), our_node_secret: our_node_secret, initial_syncs_sent: AtomicUsize::new(0), logger, @@ -757,13 +755,12 @@ impl PeerManager { /// Checks for any events generated by our handlers and processes them. May be needed after eg /// calls to ChannelManager::process_pending_htlc_forward. pub fn process_events(&self) { - let mut upstream_events = Vec::new(); { // TODO: There are some DoS attacks here where you can flood someone's outbound send // buffer by doing things like announcing channels on another node. We should be willing to // drop optional-ish messages when send buffers get full! - let mut events_generated = self.message_handler.chan_handler.get_and_clear_pending_events(); + let mut events_generated = self.message_handler.chan_handler.get_and_clear_pending_msg_events(); let mut peers = self.peers.lock().unwrap(); for event in events_generated.drain(..) { macro_rules! get_peer_for_forwarding { @@ -790,15 +787,7 @@ impl PeerManager { } } match event { - Event::FundingGenerationReady {..} => { /* Hand upstream */ }, - Event::FundingBroadcastSafe {..} => { /* Hand upstream */ }, - Event::PaymentReceived {..} => { /* Hand upstream */ }, - Event::PaymentSent {..} => { /* Hand upstream */ }, - Event::PaymentFailed {..} => { /* Hand upstream */ }, - Event::PendingHTLCsForwardable {..} => { /* Hand upstream */ }, - Event::SpendableOutputs { .. } => { /* Hand upstream */ }, - - Event::SendOpenChannel { ref node_id, ref msg } => { + MessageSendEvent::SendOpenChannel { ref node_id, ref msg } => { log_trace!(self, "Handling SendOpenChannel event in peer_handler for node {} for channel {}", log_pubkey!(node_id), log_bytes!(msg.temporary_channel_id)); @@ -807,9 +796,8 @@ impl PeerManager { }); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 32))); Self::do_attempt_write_data(&mut descriptor, peer); - continue; }, - Event::SendFundingCreated { ref node_id, ref msg } => { + MessageSendEvent::SendFundingCreated { ref node_id, ref msg } => { log_trace!(self, "Handling SendFundingCreated event in peer_handler for node {} for channel {} (which becomes {})", log_pubkey!(node_id), log_bytes!(msg.temporary_channel_id), @@ -820,9 +808,8 @@ impl PeerManager { }); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 34))); Self::do_attempt_write_data(&mut descriptor, peer); - continue; }, - Event::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { + MessageSendEvent::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { log_trace!(self, "Handling SendFundingLocked event in peer_handler for node {}{} for channel {}", log_pubkey!(node_id), if announcement_sigs.is_some() { " with announcement sigs" } else { "" }, @@ -836,9 +823,8 @@ impl PeerManager { &None => {}, } Self::do_attempt_write_data(&mut descriptor, peer); - continue; }, - 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 } } => { + MessageSendEvent::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 } } => { log_trace!(self, "Handling UpdateHTLCs event in peer_handler for node {} with {} adds, {} fulfills, {} fails for channel {}", log_pubkey!(node_id), update_add_htlcs.len(), @@ -865,9 +851,8 @@ impl PeerManager { } peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(commitment_signed, 132))); Self::do_attempt_write_data(&mut descriptor, peer); - continue; }, - Event::SendRevokeAndACK { ref node_id, ref msg } => { + MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => { log_trace!(self, "Handling SendRevokeAndACK event in peer_handler for node {} for channel {}", log_pubkey!(node_id), log_bytes!(msg.channel_id)); @@ -876,9 +861,8 @@ impl PeerManager { }); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 133))); Self::do_attempt_write_data(&mut descriptor, peer); - continue; }, - Event::SendShutdown { ref node_id, ref msg } => { + MessageSendEvent::SendShutdown { ref node_id, ref msg } => { log_trace!(self, "Handling Shutdown event in peer_handler for node {} for channel {}", log_pubkey!(node_id), log_bytes!(msg.channel_id)); @@ -887,9 +871,8 @@ impl PeerManager { }); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 38))); Self::do_attempt_write_data(&mut descriptor, peer); - continue; }, - Event::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { + MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { log_trace!(self, "Handling BroadcastChannelAnnouncement event in peer_handler for short channel id {}", msg.contents.short_channel_id); if self.message_handler.route_handler.handle_channel_announcement(msg).is_ok() && self.message_handler.route_handler.handle_channel_update(update_msg).is_ok() { let encoded_msg = encode_msg!(msg, 256); @@ -912,9 +895,8 @@ impl PeerManager { Self::do_attempt_write_data(&mut (*descriptor).clone(), peer); } } - continue; }, - Event::BroadcastChannelUpdate { ref msg } => { + MessageSendEvent::BroadcastChannelUpdate { ref msg } => { log_trace!(self, "Handling BroadcastChannelUpdate event in peer_handler for short channel id {}", msg.contents.short_channel_id); if self.message_handler.route_handler.handle_channel_update(msg).is_ok() { let encoded_msg = encode_msg!(msg, 258); @@ -927,13 +909,11 @@ impl PeerManager { Self::do_attempt_write_data(&mut (*descriptor).clone(), peer); } } - continue; }, - Event::PaymentFailureNetworkUpdate { ref update } => { + MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => { self.message_handler.route_handler.handle_htlc_fail_channel_update(update); - continue; }, - Event::HandleError { ref node_id, ref action } => { + MessageSendEvent::HandleError { ref node_id, ref action } => { if let Some(ref action) = *action { match *action { msgs::ErrorAction::DisconnectPeer { ref msg } => { @@ -955,9 +935,7 @@ impl PeerManager { self.message_handler.chan_handler.peer_disconnected(&node_id, false); } }, - msgs::ErrorAction::IgnoreError => { - continue; - }, + msgs::ErrorAction::IgnoreError => {}, msgs::ErrorAction::SendErrorMessage { ref msg } => { log_trace!(self, "Handling SendErrorMessage HandleError event in peer_handler for node {} with message {}", log_pubkey!(node_id), @@ -972,18 +950,10 @@ impl PeerManager { } else { log_error!(self, "Got no-action HandleError Event in peer_handler for node {}, no such events should ever be generated!", log_pubkey!(node_id)); } - continue; } } - - upstream_events.push(event); } } - - let mut pending_events = self.pending_events.lock().unwrap(); - for event in upstream_events.drain(..) { - pending_events.push(event); - } } /// Indicates that the given socket descriptor's connection is now closed. @@ -1014,15 +984,6 @@ impl PeerManager { } } -impl EventsProvider for PeerManager { - fn get_and_clear_pending_events(&self) -> Vec { - let mut pending_events = self.pending_events.lock().unwrap(); - let mut ret = Vec::new(); - mem::swap(&mut ret, &mut *pending_events); - ret - } -} - #[cfg(test)] mod tests { use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor}; @@ -1094,7 +1055,7 @@ mod tests { let their_id = PublicKey::from_secret_key(&secp_ctx, &peers[1].our_node_secret); let chan_handler = test_utils::TestChannelMessageHandler::new(); - chan_handler.pending_events.lock().unwrap().push(events::Event::HandleError { + chan_handler.pending_events.lock().unwrap().push(events::MessageSendEvent::HandleError { node_id: their_id, action: Some(msgs::ErrorAction::DisconnectPeer { msg: None }), }); diff --git a/src/util/events.rs b/src/util/events.rs index 3a077a4b5ba..261ee57ccc0 100644 --- a/src/util/events.rs +++ b/src/util/events.rs @@ -24,7 +24,6 @@ use std::time::Instant; /// An Event which you should probably take some action in response to. pub enum Event { - // Events a user will probably have to handle /// Used to indicate that the client should generate a funding transaction with the given /// parameters and then call ChannelManager::funding_transaction_generated. /// Generated in ChannelManager message handling. @@ -97,13 +96,14 @@ pub enum Event { /// The outputs which you should store as spendable by you. outputs: Vec, }, +} - // Events indicating the network loop should send a message to a peer: - // TODO: Move these into a separate struct and make a top-level enum +/// An event generated by ChannelManager which indicates a message should be sent to a peer (or +/// broadcast to most peers). +/// These events are handled by PeerManager::process_events if you are using a PeerManager. +pub enum MessageSendEvent { /// Used to indicate that we've initialted a channel open and should send the open_channel /// message provided to the given peer. - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. SendOpenChannel { /// The node_id of the node which should receive this message node_id: PublicKey, @@ -111,8 +111,6 @@ pub enum Event { msg: msgs::OpenChannel, }, /// Used to indicate that a funding_created message should be sent to the peer with the given node_id. - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. SendFundingCreated { /// The node_id of the node which should receive this message node_id: PublicKey, @@ -120,8 +118,6 @@ pub enum Event { msg: msgs::FundingCreated, }, /// Used to indicate that a funding_locked message should be sent to the peer with the given node_id. - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. SendFundingLocked { /// The node_id of the node which should receive these message(s) node_id: PublicKey, @@ -132,8 +128,6 @@ pub enum Event { }, /// Used to indicate that a series of HTLC update messages, as well as a commitment_signed /// message should be sent to the peer with the given node_id. - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. UpdateHTLCs { /// The node_id of the node which should receive these message(s) node_id: PublicKey, @@ -141,8 +135,6 @@ pub enum Event { updates: msgs::CommitmentUpdate, }, /// Used to indicate that a revoke_and_ack message should be sent to the peer with the given node_id. - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. SendRevokeAndACK { /// The node_id of the node which should receive this message node_id: PublicKey, @@ -150,8 +142,6 @@ pub enum Event { msg: msgs::RevokeAndACK, }, /// Used to indicate that a shutdown message should be sent to the peer with the given node_id. - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. SendShutdown { /// The node_id of the node which should receive this message node_id: PublicKey, @@ -160,8 +150,6 @@ pub enum Event { }, /// Used to indicate that a channel_announcement and channel_update should be broadcast to all /// peers (except the peer with node_id either msg.contents.node_id_1 or msg.contents.node_id_2). - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. BroadcastChannelAnnouncement { /// The channel_announcement which should be sent. msg: msgs::ChannelAnnouncement, @@ -169,17 +157,11 @@ pub enum Event { update_msg: msgs::ChannelUpdate, }, /// Used to indicate that a channel_update should be broadcast to all peers. - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. BroadcastChannelUpdate { /// The channel_update which should be sent. msg: msgs::ChannelUpdate, }, - - //Error handling /// Broadcast an error downstream to be handled - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. HandleError { /// The node_id of the node which should receive this message node_id: PublicKey, @@ -188,14 +170,19 @@ pub enum Event { }, /// When a payment fails we may receive updates back from the hop where it failed. In such /// cases this event is generated so that we can inform the router of this information. - /// - /// This event is handled by PeerManager::process_events if you are using a PeerManager. PaymentFailureNetworkUpdate { /// The channel/node update which should be sent to router update: msgs::HTLCFailChannelUpdate, } } +/// A trait indicating an object may generate message send events +pub trait MessageSendEventsProvider { + /// Gets the list of pending events which were generated by previous actions, clearing the list + /// in the process. + fn get_and_clear_pending_msg_events(&self) -> Vec; +} + /// A trait indicating an object may generate events pub trait EventsProvider { /// Gets the list of pending events which were generated by previous actions, clearing the list diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index 2577bc9f9ba..31a19776a2c 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -74,7 +74,7 @@ impl chaininterface::BroadcasterInterface for TestBroadcaster { } pub struct TestChannelMessageHandler { - pub pending_events: Mutex>, + pub pending_events: Mutex>, } impl TestChannelMessageHandler { @@ -141,8 +141,8 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler { fn handle_error(&self, _their_node_id: &PublicKey, _msg: &msgs::ErrorMessage) {} } -impl events::EventsProvider for TestChannelMessageHandler { - fn get_and_clear_pending_events(&self) -> Vec { +impl events::MessageSendEventsProvider for TestChannelMessageHandler { + fn get_and_clear_pending_msg_events(&self) -> Vec { let mut pending_events = self.pending_events.lock().unwrap(); let mut ret = Vec::new(); mem::swap(&mut ret, &mut *pending_events); From 608d517f9255d22c641fbaaf9dcb56753f214a00 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Oct 2018 16:49:12 -0400 Subject: [PATCH 08/15] Send AcceptChannel responses out-of-band to ensure ordered delivery --- fuzz/fuzz_targets/full_stack_target.rs | 2 +- src/ln/channelmanager.rs | 54 ++++++++++++++++---------- src/ln/msgs.rs | 4 +- src/ln/peer_handler.rs | 13 ++++++- src/util/events.rs | 10 ++++- src/util/test_utils.rs | 2 +- 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index bf6de14aeed..8b900880f87 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -803,7 +803,7 @@ mod tests { super::do_test(&::hex::decode("00000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000000300320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030012000603000000000000000000000000000000030016001000000000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000222ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005030000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d00000000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001030132000300000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003014200030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000300000000000000000000000000000003011200060100000000000000000000000000000003011600100000000001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd00fd00fd0301120110010000000000000000000000000000000301ff00210200000000000000020000000000000002000000000000000200000000000000000000000000001a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500030000000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233f00000000000000000000000000000000000000000000000000000000000000f6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000b03011200430100000000000000000000000000000003015300243f000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843f00000000000000000000000000000000000000000000000000000000000000f700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a00823f000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843f00000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d00000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843f00000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833f00000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843f00000000000000000000000000000000000000000000000000000000000000fd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853f0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000305000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000305000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000002500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d000000000000000000000000000000000000000000000000000000000000000000000000000002000000000003e900ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e0000010000000000000003e800000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d000000000000000000000000000000000000000000000000000000000000006800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013f00000000000000000000000000000000000000000000000000000000000000000000000000000080020001000000000000220020ed000000000000000000000000000000000000000000000000000000000000006cc10000000000001600142b88e0198963bf4c37de498583a3ccdb9d67e9740500002000fd0c005e0200000001ec00000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f60000000000000000000000000000000000000000000000000000000000000000000000").unwrap(), &(Arc::clone(&logger) as Arc)); let log_entries = logger.lines.lock().unwrap(); - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Encoding and sending message of type 33 to 030000000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 1 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendAcceptChannel event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679".to_string())), Some(&1)); // 1 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Encoding and sending message of type 35 to 030000000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 2 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 3 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3f00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index bd663c92412..0b302e60b28 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -1617,20 +1617,26 @@ impl ChannelManager { } } - fn internal_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result { + fn internal_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> { if msg.chain_hash != self.genesis_hash { return Err(MsgHandleErrInternal::send_err_msg_no_close("Unknown genesis block hash", msg.temporary_channel_id.clone())); } - let mut channel_state = self.channel_state.lock().unwrap(); - if channel_state.by_id.contains_key(&msg.temporary_channel_id) { - return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision!", msg.temporary_channel_id.clone())); - } let channel = Channel::new_from_req(&*self.fee_estimator, &self.keys_manager, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger)) .map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.temporary_channel_id))?; - let accept_msg = channel.get_accept_channel(); - channel_state.by_id.insert(channel.channel_id(), channel); - Ok(accept_msg) + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); + match channel_state.by_id.entry(channel.channel_id()) { + hash_map::Entry::Occupied(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision!", msg.temporary_channel_id.clone())), + hash_map::Entry::Vacant(entry) => { + channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel { + node_id: their_node_id.clone(), + msg: channel.get_accept_channel(), + }); + entry.insert(channel); + } + } + Ok(()) } fn internal_accept_channel(&self, their_node_id: &PublicKey, msg: &msgs::AcceptChannel) -> Result<(), MsgHandleErrInternal> { @@ -2453,7 +2459,7 @@ macro_rules! handle_error { impl ChannelMessageHandler for ChannelManager { //TODO: Handle errors and close channel (or so) - fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result { + fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<(), HandleError> { handle_error!(self, self.internal_open_channel(their_node_id, msg), their_node_id) } @@ -2841,20 +2847,26 @@ mod tests { (announcement, as_update, bs_update, channel_id, tx) } + macro_rules! get_event_msg { + ($node: expr, $event_type: path, $node_id: expr) => { + { + let events = $node.node.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + match events[0] { + $event_type { ref node_id, ref msg } => { + assert_eq!(*node_id, $node_id); + (*msg).clone() + }, + _ => panic!("Unexpected event"), + } + } + } + } + fn create_chan_between_nodes_with_value_init(node_a: &Node, node_b: &Node, channel_value: u64, push_msat: u64) -> Transaction { node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42).unwrap(); - - let events_1 = node_a.node.get_and_clear_pending_msg_events(); - assert_eq!(events_1.len(), 1); - let accept_chan = match events_1[0] { - MessageSendEvent::SendOpenChannel { ref node_id, ref msg } => { - assert_eq!(*node_id, node_b.node.get_our_node_id()); - node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), msg).unwrap() - }, - _ => panic!("Unexpected event"), - }; - - node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), &accept_chan).unwrap(); + node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id())).unwrap(); + node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id())).unwrap(); let chan_id = *node_a.network_chan_count.borrow(); let tx; diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index 29ff1a87605..89c95b3b917 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -168,6 +168,7 @@ pub struct Pong { } /// An open_channel message to be sent or received from a peer +#[derive(Clone)] pub struct OpenChannel { pub(crate) chain_hash: Sha256dHash, pub(crate) temporary_channel_id: [u8; 32], @@ -191,6 +192,7 @@ pub struct OpenChannel { } /// An accept_channel message to be sent or received from a peer +#[derive(Clone)] pub struct AcceptChannel { pub(crate) temporary_channel_id: [u8; 32], pub(crate) dust_limit_satoshis: u64, @@ -524,7 +526,7 @@ pub enum RAACommitmentOrder { pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Sync { //Channel init: /// Handle an incoming open_channel message from the given peer. - fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &OpenChannel) -> Result; + fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &OpenChannel) -> Result<(), HandleError>; /// Handle an incoming accept_channel message from the given peer. fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &AcceptChannel) -> Result<(), HandleError>; /// Handle an incoming funding_created message from the given peer. diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 631e48aa1eb..85a353a2e33 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -559,8 +559,7 @@ impl PeerManager { // Channel control: 32 => { let msg = try_potential_decodeerror!(msgs::OpenChannel::read(&mut reader)); - let resp = try_potential_handleerror!(self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), &msg)); - encode_and_send_msg!(resp, 33); + try_potential_handleerror!(self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), &msg)); }, 33 => { let msg = try_potential_decodeerror!(msgs::AcceptChannel::read(&mut reader)); @@ -787,6 +786,16 @@ impl PeerManager { } } match event { + MessageSendEvent::SendAcceptChannel { ref node_id, ref msg } => { + log_trace!(self, "Handling SendAcceptChannel event in peer_handler for node {} for channel {}", + log_pubkey!(node_id), + log_bytes!(msg.temporary_channel_id)); + let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { + //TODO: Drop the pending channel? (or just let it timeout, but that sucks) + }); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 33))); + Self::do_attempt_write_data(&mut descriptor, peer); + }, MessageSendEvent::SendOpenChannel { ref node_id, ref msg } => { log_trace!(self, "Handling SendOpenChannel event in peer_handler for node {} for channel {}", log_pubkey!(node_id), diff --git a/src/util/events.rs b/src/util/events.rs index 261ee57ccc0..ce6e5d99fab 100644 --- a/src/util/events.rs +++ b/src/util/events.rs @@ -102,7 +102,15 @@ pub enum Event { /// broadcast to most peers). /// These events are handled by PeerManager::process_events if you are using a PeerManager. pub enum MessageSendEvent { - /// Used to indicate that we've initialted a channel open and should send the open_channel + /// Used to indicate that we've accepted a channel open and should send the accept_channel + /// message provided to the given peer. + SendAcceptChannel { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::AcceptChannel, + }, + /// Used to indicate that we've initiated a channel open and should send the open_channel /// message provided to the given peer. SendOpenChannel { /// The node_id of the node which should receive this message diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index 31a19776a2c..0795162e228 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -86,7 +86,7 @@ impl TestChannelMessageHandler { } impl msgs::ChannelMessageHandler for TestChannelMessageHandler { - fn handle_open_channel(&self, _their_node_id: &PublicKey, _msg: &msgs::OpenChannel) -> Result { + fn handle_open_channel(&self, _their_node_id: &PublicKey, _msg: &msgs::OpenChannel) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } fn handle_accept_channel(&self, _their_node_id: &PublicKey, _msg: &msgs::AcceptChannel) -> Result<(), HandleError> { From c962a27156c92888f9f3cb0bc6565a73525c8da8 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Oct 2018 17:06:40 -0400 Subject: [PATCH 09/15] Send funding_signed messages out-of-band to ensure ordered delivery --- fuzz/fuzz_targets/full_stack_target.rs | 2 +- src/ln/channelmanager.rs | 36 ++++++++++++-------------- src/ln/msgs.rs | 4 ++- src/ln/peer_handler.rs | 14 ++++++++-- src/util/events.rs | 7 +++++ src/util/test_utils.rs | 2 +- 6 files changed, 41 insertions(+), 24 deletions(-) diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index 8b900880f87..6f18d071b95 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -804,7 +804,7 @@ mod tests { let log_entries = logger.lines.lock().unwrap(); assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendAcceptChannel event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679".to_string())), Some(&1)); // 1 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Encoding and sending message of type 35 to 030000000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 2 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingSigned event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 2 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 3 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3f00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Encoding and sending message of type 133 to 030000000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4)); // 5 diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 0b302e60b28..91bfec9600c 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -1666,7 +1666,7 @@ impl ChannelManager { Ok(()) } - fn internal_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result { + fn internal_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> { let (chan, funding_msg, monitor_update) = { let mut channel_state = self.channel_state.lock().unwrap(); match channel_state.by_id.entry(msg.temporary_channel_id.clone()) { @@ -1692,16 +1692,21 @@ impl ChannelManager { if let Err(_e) = self.monitor.add_update_monitor(monitor_update.get_funding_txo().unwrap(), monitor_update) { unimplemented!(); } - let mut channel_state = self.channel_state.lock().unwrap(); + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); match channel_state.by_id.entry(funding_msg.channel_id) { hash_map::Entry::Occupied(_) => { return Err(MsgHandleErrInternal::send_err_msg_no_close("Already had channel with the new channel_id", funding_msg.channel_id)) }, hash_map::Entry::Vacant(e) => { + channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingSigned { + node_id: their_node_id.clone(), + msg: funding_msg, + }); e.insert(chan); } } - Ok(funding_msg) + Ok(()) } fn internal_funding_signed(&self, their_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), MsgHandleErrInternal> { @@ -2467,7 +2472,7 @@ impl ChannelMessageHandler for ChannelManager { handle_error!(self, self.internal_accept_channel(their_node_id, msg), their_node_id) } - fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result { + fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), HandleError> { handle_error!(self, self.internal_funding_created(their_node_id, msg), their_node_id) } @@ -2893,22 +2898,15 @@ mod tests { _ => panic!("Unexpected event"), } - let events_3 = node_a.node.get_and_clear_pending_msg_events(); - assert_eq!(events_3.len(), 1); - let funding_signed = match events_3[0] { - MessageSendEvent::SendFundingCreated { ref node_id, ref msg } => { - assert_eq!(*node_id, node_b.node.get_our_node_id()); - let res = node_b.node.handle_funding_created(&node_a.node.get_our_node_id(), msg).unwrap(); - let mut added_monitors = node_b.chan_monitor.added_monitors.lock().unwrap(); - assert_eq!(added_monitors.len(), 1); - assert_eq!(added_monitors[0].0, funding_output); - added_monitors.clear(); - res - }, - _ => panic!("Unexpected event"), - }; + node_b.node.handle_funding_created(&node_a.node.get_our_node_id(), &get_event_msg!(node_a, MessageSendEvent::SendFundingCreated, node_b.node.get_our_node_id())).unwrap(); + { + let mut added_monitors = node_b.chan_monitor.added_monitors.lock().unwrap(); + assert_eq!(added_monitors.len(), 1); + assert_eq!(added_monitors[0].0, funding_output); + added_monitors.clear(); + } - node_a.node.handle_funding_signed(&node_b.node.get_our_node_id(), &funding_signed).unwrap(); + node_a.node.handle_funding_signed(&node_b.node.get_our_node_id(), &get_event_msg!(node_b, MessageSendEvent::SendFundingSigned, node_a.node.get_our_node_id())).unwrap(); { let mut added_monitors = node_a.chan_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index 89c95b3b917..3ed0cde1f5d 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -212,6 +212,7 @@ pub struct AcceptChannel { } /// A funding_created message to be sent or received from a peer +#[derive(Clone)] pub struct FundingCreated { pub(crate) temporary_channel_id: [u8; 32], pub(crate) funding_txid: Sha256dHash, @@ -220,6 +221,7 @@ pub struct FundingCreated { } /// A funding_signed message to be sent or received from a peer +#[derive(Clone)] pub struct FundingSigned { pub(crate) channel_id: [u8; 32], pub(crate) signature: Signature, @@ -530,7 +532,7 @@ pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Syn /// Handle an incoming accept_channel message from the given peer. fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &AcceptChannel) -> Result<(), HandleError>; /// Handle an incoming funding_created message from the given peer. - fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &FundingCreated) -> Result; + fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &FundingCreated) -> Result<(), HandleError>; /// Handle an incoming funding_signed message from the given peer. fn handle_funding_signed(&self, their_node_id: &PublicKey, msg: &FundingSigned) -> Result<(), HandleError>; /// Handle an incoming funding_locked message from the given peer. diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 85a353a2e33..15cda534290 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -568,8 +568,7 @@ impl PeerManager { 34 => { let msg = try_potential_decodeerror!(msgs::FundingCreated::read(&mut reader)); - let resp = try_potential_handleerror!(self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg)); - encode_and_send_msg!(resp, 35); + try_potential_handleerror!(self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg)); }, 35 => { let msg = try_potential_decodeerror!(msgs::FundingSigned::read(&mut reader)); @@ -818,6 +817,17 @@ impl PeerManager { peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 34))); Self::do_attempt_write_data(&mut descriptor, peer); }, + MessageSendEvent::SendFundingSigned { ref node_id, ref msg } => { + log_trace!(self, "Handling SendFundingSigned event in peer_handler for node {} for channel {}", + log_pubkey!(node_id), + log_bytes!(msg.channel_id)); + let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { + //TODO: generate a DiscardFunding event indicating to the wallet that + //they should just throw away this funding transaction + }); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 35))); + Self::do_attempt_write_data(&mut descriptor, peer); + }, MessageSendEvent::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { log_trace!(self, "Handling SendFundingLocked event in peer_handler for node {}{} for channel {}", log_pubkey!(node_id), diff --git a/src/util/events.rs b/src/util/events.rs index ce6e5d99fab..1ba3f68d12e 100644 --- a/src/util/events.rs +++ b/src/util/events.rs @@ -125,6 +125,13 @@ pub enum MessageSendEvent { /// The message which should be sent. msg: msgs::FundingCreated, }, + /// Used to indicate that a funding_signed message should be sent to the peer with the given node_id. + SendFundingSigned { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::FundingSigned, + }, /// Used to indicate that a funding_locked message should be sent to the peer with the given node_id. SendFundingLocked { /// The node_id of the node which should receive these message(s) diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index 0795162e228..31aa77be1b4 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -92,7 +92,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler { fn handle_accept_channel(&self, _their_node_id: &PublicKey, _msg: &msgs::AcceptChannel) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } - fn handle_funding_created(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingCreated) -> Result { + fn handle_funding_created(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingCreated) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } fn handle_funding_signed(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingSigned) -> Result<(), HandleError> { From e382a7b4b3e5f3e59a9300b9d8a4d8bff06366fe Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Oct 2018 17:30:52 -0400 Subject: [PATCH 10/15] Send announcement_signatures msgs out-of-band for ordered delivery --- src/ln/channelmanager.rs | 89 +++++++++++++++++++++++----------------- src/ln/msgs.rs | 2 +- src/ln/peer_handler.rs | 26 ++++++------ src/util/events.rs | 9 +++- src/util/test_utils.rs | 2 +- 5 files changed, 75 insertions(+), 53 deletions(-) diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 91bfec9600c..4777a3e810a 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -1735,8 +1735,9 @@ impl ChannelManager { Ok(()) } - fn internal_funding_locked(&self, their_node_id: &PublicKey, msg: &msgs::FundingLocked) -> Result, MsgHandleErrInternal> { - let mut channel_state = self.channel_state.lock().unwrap(); + fn internal_funding_locked(&self, their_node_id: &PublicKey, msg: &msgs::FundingLocked) -> Result<(), MsgHandleErrInternal> { + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); match channel_state.by_id.get_mut(&msg.channel_id) { Some(chan) => { if chan.get_their_node_id() != *their_node_id { @@ -1745,10 +1746,16 @@ impl ChannelManager { } chan.funding_locked(&msg) .map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))?; - return Ok(self.get_announcement_sigs(chan)); + if let Some(announcement_sigs) = self.get_announcement_sigs(chan) { + channel_state.pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures { + node_id: their_node_id.clone(), + msg: announcement_sigs, + }); + } + Ok(()) }, - None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) - }; + None => Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } } fn internal_shutdown(&self, their_node_id: &PublicKey, msg: &msgs::Shutdown) -> Result<(Option, Option), MsgHandleErrInternal> { @@ -2336,12 +2343,16 @@ impl ChainListener for ChannelManager { channel_state.by_id.retain(|_, channel| { let chan_res = channel.block_connected(header, height, txn_matched, indexes_of_txn_matched); if let Ok(Some(funding_locked)) = chan_res { - let announcement_sigs = self.get_announcement_sigs(channel); pending_msg_events.push(events::MessageSendEvent::SendFundingLocked { node_id: channel.get_their_node_id(), msg: funding_locked, - announcement_sigs: announcement_sigs }); + if let Some(announcement_sigs) = self.get_announcement_sigs(channel) { + pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures { + node_id: channel.get_their_node_id(), + msg: announcement_sigs, + }); + } short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id()); } else if let Err(e) = chan_res { pending_msg_events.push(events::MessageSendEvent::HandleError { @@ -2480,7 +2491,7 @@ impl ChannelMessageHandler for ChannelManager { handle_error!(self, self.internal_funding_signed(their_node_id, msg), their_node_id) } - fn handle_funding_locked(&self, their_node_id: &PublicKey, msg: &msgs::FundingLocked) -> Result, HandleError> { + fn handle_funding_locked(&self, their_node_id: &PublicKey, msg: &msgs::FundingLocked) -> Result<(), HandleError> { handle_error!(self, self.internal_funding_locked(their_node_id, msg), their_node_id) } @@ -2929,30 +2940,27 @@ mod tests { fn create_chan_between_nodes_with_value_confirm(node_a: &Node, node_b: &Node, tx: &Transaction) -> ((msgs::FundingLocked, msgs::AnnouncementSignatures), [u8; 32]) { confirm_transaction(&node_b.chain_monitor, &tx, tx.version); - let events_5 = node_b.node.get_and_clear_pending_msg_events(); - assert_eq!(events_5.len(), 1); - match events_5[0] { - MessageSendEvent::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { - assert_eq!(*node_id, node_a.node.get_our_node_id()); - assert!(announcement_sigs.is_none()); - node_a.node.handle_funding_locked(&node_b.node.get_our_node_id(), msg).unwrap() - }, - _ => panic!("Unexpected event"), - }; + node_a.node.handle_funding_locked(&node_b.node.get_our_node_id(), &get_event_msg!(node_b, MessageSendEvent::SendFundingLocked, node_a.node.get_our_node_id())).unwrap(); let channel_id; confirm_transaction(&node_a.chain_monitor, &tx, tx.version); let events_6 = node_a.node.get_and_clear_pending_msg_events(); - assert_eq!(events_6.len(), 1); - (match events_6[0] { - MessageSendEvent::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { + assert_eq!(events_6.len(), 2); + ((match events_6[0] { + MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => { channel_id = msg.channel_id.clone(); assert_eq!(*node_id, node_b.node.get_our_node_id()); - (msg.clone(), announcement_sigs.clone().unwrap()) + msg.clone() + }, + _ => panic!("Unexpected event"), + }, match events_6[1] { + MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => { + assert_eq!(*node_id, node_b.node.get_our_node_id()); + msg.clone() }, _ => panic!("Unexpected event"), - }, channel_id) + }), channel_id) } fn create_chan_between_nodes_with_value_a(node_a: &Node, node_b: &Node, channel_value: u64, push_msat: u64) -> ((msgs::FundingLocked, msgs::AnnouncementSignatures), [u8; 32], Transaction) { @@ -2962,11 +2970,9 @@ mod tests { } fn create_chan_between_nodes_with_value_b(node_a: &Node, node_b: &Node, as_funding_msgs: &(msgs::FundingLocked, msgs::AnnouncementSignatures)) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate) { - let bs_announcement_sigs = { - let bs_announcement_sigs = node_b.node.handle_funding_locked(&node_a.node.get_our_node_id(), &as_funding_msgs.0).unwrap().unwrap(); - node_b.node.handle_announcement_signatures(&node_a.node.get_our_node_id(), &as_funding_msgs.1).unwrap(); - bs_announcement_sigs - }; + node_b.node.handle_funding_locked(&node_a.node.get_our_node_id(), &as_funding_msgs.0).unwrap(); + let bs_announcement_sigs = get_event_msg!(node_b, MessageSendEvent::SendAnnouncementSignatures, node_a.node.get_our_node_id()); + node_b.node.handle_announcement_signatures(&node_a.node.get_our_node_id(), &as_funding_msgs.1).unwrap(); let events_7 = node_b.node.get_and_clear_pending_msg_events(); assert_eq!(events_7.len(), 1); @@ -5007,9 +5013,14 @@ mod tests { for chan_msgs in resp_1.drain(..) { if pre_all_htlcs { - let a = node_a.node.handle_funding_locked(&node_b.node.get_our_node_id(), &chan_msgs.0.unwrap()); - let _announcement_sigs_opt = a.unwrap(); - //TODO: Test announcement_sigs re-sending when we've implemented it + node_a.node.handle_funding_locked(&node_b.node.get_our_node_id(), &chan_msgs.0.unwrap()).unwrap(); + let announcement_event = node_a.node.get_and_clear_pending_msg_events(); + if !announcement_event.is_empty() { + assert_eq!(announcement_event.len(), 1); + if let MessageSendEvent::SendAnnouncementSignatures { .. } = announcement_event[0] { + //TODO: Test announcement_sigs re-sending + } else { panic!("Unexpected event!"); } + } } else { assert!(chan_msgs.0.is_none()); } @@ -5056,8 +5067,14 @@ mod tests { 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 + node_b.node.handle_funding_locked(&node_a.node.get_our_node_id(), &chan_msgs.0.unwrap()).unwrap(); + let announcement_event = node_b.node.get_and_clear_pending_msg_events(); + if !announcement_event.is_empty() { + assert_eq!(announcement_event.len(), 1); + if let MessageSendEvent::SendAnnouncementSignatures { .. } = announcement_event[0] { + //TODO: Test announcement_sigs re-sending + } else { panic!("Unexpected event!"); } + } } else { assert!(chan_msgs.0.is_none()); } @@ -5363,9 +5380,8 @@ mod tests { let events_1 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_1.len(), 1); match events_1[0] { - MessageSendEvent::SendFundingLocked { ref node_id, msg: _, ref announcement_sigs } => { + MessageSendEvent::SendFundingLocked { ref node_id, msg: _ } => { assert_eq!(*node_id, nodes[1].node.get_our_node_id()); - assert!(announcement_sigs.is_none()); }, _ => panic!("Unexpected event"), } @@ -5374,9 +5390,8 @@ mod tests { let events_2 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_2.len(), 1); match events_2[0] { - MessageSendEvent::SendFundingLocked { ref node_id, msg: _, ref announcement_sigs } => { + MessageSendEvent::SendFundingLocked { ref node_id, msg: _ } => { assert_eq!(*node_id, nodes[0].node.get_our_node_id()); - assert!(announcement_sigs.is_none()); }, _ => panic!("Unexpected event"), } diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index 3ed0cde1f5d..d01595b7216 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -536,7 +536,7 @@ pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Syn /// Handle an incoming funding_signed message from the given peer. fn handle_funding_signed(&self, their_node_id: &PublicKey, msg: &FundingSigned) -> Result<(), HandleError>; /// Handle an incoming funding_locked message from the given peer. - fn handle_funding_locked(&self, their_node_id: &PublicKey, msg: &FundingLocked) -> Result, HandleError>; + fn handle_funding_locked(&self, their_node_id: &PublicKey, msg: &FundingLocked) -> Result<(), HandleError>; // Channl close: /// Handle an incoming shutdown message from the given peer. diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 15cda534290..9a2cee9dd49 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -576,11 +576,7 @@ impl PeerManager { }, 36 => { let msg = try_potential_decodeerror!(msgs::FundingLocked::read(&mut reader)); - let resp_option = try_potential_handleerror!(self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg)); - match resp_option { - Some(resp) => encode_and_send_msg!(resp, 259), - None => {}, - } + try_potential_handleerror!(self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg)); }, 38 => { @@ -828,19 +824,25 @@ impl PeerManager { peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 35))); Self::do_attempt_write_data(&mut descriptor, peer); }, - MessageSendEvent::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { - log_trace!(self, "Handling SendFundingLocked event in peer_handler for node {}{} for channel {}", + MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => { + log_trace!(self, "Handling SendFundingLocked event in peer_handler for node {} for channel {}", log_pubkey!(node_id), - if announcement_sigs.is_some() { " with announcement sigs" } else { "" }, log_bytes!(msg.channel_id)); let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { //TODO: Do whatever we're gonna do for handling dropped messages }); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 36))); - match announcement_sigs { - &Some(ref announce_msg) => peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(announce_msg, 259))), - &None => {}, - } + Self::do_attempt_write_data(&mut descriptor, peer); + }, + MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => { + log_trace!(self, "Handling SendAnnouncementSignatures event in peer_handler for node {} for channel {})", + log_pubkey!(node_id), + log_bytes!(msg.channel_id)); + let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { + //TODO: generate a DiscardFunding event indicating to the wallet that + //they should just throw away this funding transaction + }); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 259))); Self::do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::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 } } => { diff --git a/src/util/events.rs b/src/util/events.rs index 1ba3f68d12e..d7312cd9129 100644 --- a/src/util/events.rs +++ b/src/util/events.rs @@ -138,8 +138,13 @@ pub enum MessageSendEvent { node_id: PublicKey, /// The funding_locked message which should be sent. msg: msgs::FundingLocked, - /// An optional additional announcement_signatures message which should be sent. - announcement_sigs: Option, + }, + /// Used to indicate that an announcement_signatures message should be sent to the peer with the given node_id. + SendAnnouncementSignatures { + /// The node_id of the node which should receive these message(s) + node_id: PublicKey, + /// The announcement_signatures message which should be sent. + msg: msgs::AnnouncementSignatures, }, /// Used to indicate that a series of HTLC update messages, as well as a commitment_signed /// message should be sent to the peer with the given node_id. diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index 31aa77be1b4..f8959dcf17b 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -98,7 +98,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler { fn handle_funding_signed(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingSigned) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } - fn handle_funding_locked(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingLocked) -> Result, HandleError> { + fn handle_funding_locked(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingLocked) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } fn handle_shutdown(&self, _their_node_id: &PublicKey, _msg: &msgs::Shutdown) -> Result<(Option, Option), HandleError> { From 812f255d7c53c92656493fe103ad4129d1363a90 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 19 Oct 2018 21:50:16 -0400 Subject: [PATCH 11/15] Send shutdown/closing_signed msgs out-of-band for ordered delivery --- src/ln/channelmanager.rs | 149 +++++++++++++++++++++++++-------------- src/ln/msgs.rs | 6 +- src/ln/peer_handler.rs | 23 +++--- src/util/events.rs | 7 ++ src/util/test_utils.rs | 4 +- 5 files changed, 120 insertions(+), 69 deletions(-) diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 4777a3e810a..ace557528b3 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -1758,8 +1758,8 @@ impl ChannelManager { } } - fn internal_shutdown(&self, their_node_id: &PublicKey, msg: &msgs::Shutdown) -> Result<(Option, Option), MsgHandleErrInternal> { - let (mut res, chan_option) = { + fn internal_shutdown(&self, their_node_id: &PublicKey, msg: &msgs::Shutdown) -> Result<(), MsgHandleErrInternal> { + let (mut dropped_htlcs, chan_option) = { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = channel_state_lock.borrow_parts(); @@ -1769,18 +1769,30 @@ impl ChannelManager { //TODO: here and below MsgHandleErrInternal, #153 case return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); } - let res = chan_entry.get_mut().shutdown(&*self.fee_estimator, &msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?; + let (shutdown, closing_signed, dropped_htlcs) = chan_entry.get_mut().shutdown(&*self.fee_estimator, &msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?; + if let Some(msg) = shutdown { + channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown { + node_id: their_node_id.clone(), + msg, + }); + } + if let Some(msg) = closing_signed { + channel_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned { + node_id: their_node_id.clone(), + msg, + }); + } if chan_entry.get().is_shutdown() { if let Some(short_id) = chan_entry.get().get_short_channel_id() { channel_state.short_to_id.remove(&short_id); } - (res, Some(chan_entry.remove_entry().1)) - } else { (res, None) } + (dropped_htlcs, Some(chan_entry.remove_entry().1)) + } else { (dropped_htlcs, None) } }, hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) } }; - for htlc_source in res.2.drain(..) { + for htlc_source in dropped_htlcs.drain(..) { // unknown_next_peer...I dunno who that is anymore.... self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() }); } @@ -1792,11 +1804,11 @@ impl ChannelManager { }); } } - Ok((res.0, res.1)) + Ok(()) } - fn internal_closing_signed(&self, their_node_id: &PublicKey, msg: &msgs::ClosingSigned) -> Result, MsgHandleErrInternal> { - let (res, chan_option) = { + fn internal_closing_signed(&self, their_node_id: &PublicKey, msg: &msgs::ClosingSigned) -> Result<(), MsgHandleErrInternal> { + let (tx, chan_option) = { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = channel_state_lock.borrow_parts(); match channel_state.by_id.entry(msg.channel_id.clone()) { @@ -1805,8 +1817,14 @@ impl ChannelManager { //TODO: here and below MsgHandleErrInternal, #153 case return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); } - let res = chan_entry.get_mut().closing_signed(&*self.fee_estimator, &msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?; - if res.1.is_some() { + let (closing_signed, tx) = chan_entry.get_mut().closing_signed(&*self.fee_estimator, &msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?; + if let Some(msg) = closing_signed { + channel_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned { + node_id: their_node_id.clone(), + msg, + }); + } + if tx.is_some() { // We're done with this channel, we've got a signed closing transaction and // will send the closing_signed back to the remote peer upon return. This // also implies there are no pending HTLCs left on the channel, so we can @@ -1815,13 +1833,13 @@ impl ChannelManager { if let Some(short_id) = chan_entry.get().get_short_channel_id() { channel_state.short_to_id.remove(&short_id); } - (res, Some(chan_entry.remove_entry().1)) - } else { (res, None) } + (tx, Some(chan_entry.remove_entry().1)) + } else { (tx, None) } }, hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) } }; - if let Some(broadcast_tx) = res.1 { + if let Some(broadcast_tx) = tx { self.tx_broadcaster.broadcast_transaction(&broadcast_tx); } if let Some(chan) = chan_option { @@ -1832,7 +1850,7 @@ impl ChannelManager { }); } } - Ok(res.0) + Ok(()) } fn internal_update_add_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateAddHTLC) -> Result<(), MsgHandleErrInternal> { @@ -2495,11 +2513,11 @@ impl ChannelMessageHandler for ChannelManager { handle_error!(self, self.internal_funding_locked(their_node_id, msg), their_node_id) } - fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &msgs::Shutdown) -> Result<(Option, Option), HandleError> { + fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &msgs::Shutdown) -> Result<(), HandleError> { handle_error!(self, self.internal_shutdown(their_node_id, msg), their_node_id) } - fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &msgs::ClosingSigned) -> Result, HandleError> { + fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &msgs::ClosingSigned) -> Result<(), HandleError> { handle_error!(self, self.internal_closing_signed(their_node_id, msg), their_node_id) } @@ -3025,68 +3043,91 @@ mod tests { } fn close_channel(outbound_node: &Node, inbound_node: &Node, channel_id: &[u8; 32], funding_tx: Transaction, close_inbound_first: bool) -> (msgs::ChannelUpdate, msgs::ChannelUpdate) { - let (node_a, broadcaster_a) = if close_inbound_first { (&inbound_node.node, &inbound_node.tx_broadcaster) } else { (&outbound_node.node, &outbound_node.tx_broadcaster) }; + let (node_a, broadcaster_a, struct_a) = if close_inbound_first { (&inbound_node.node, &inbound_node.tx_broadcaster, inbound_node) } else { (&outbound_node.node, &outbound_node.tx_broadcaster, outbound_node) }; let (node_b, broadcaster_b) = if close_inbound_first { (&outbound_node.node, &outbound_node.tx_broadcaster) } else { (&inbound_node.node, &inbound_node.tx_broadcaster) }; let (tx_a, tx_b); node_a.close_channel(channel_id).unwrap(); - let events_1 = node_a.get_and_clear_pending_msg_events(); - assert_eq!(events_1.len(), 1); - let shutdown_a = match events_1[0] { + node_b.handle_shutdown(&node_a.get_our_node_id(), &get_event_msg!(struct_a, MessageSendEvent::SendShutdown, node_b.get_our_node_id())).unwrap(); + + let events_1 = node_b.get_and_clear_pending_msg_events(); + assert!(events_1.len() >= 1); + let shutdown_b = match events_1[0] { MessageSendEvent::SendShutdown { ref node_id, ref msg } => { - assert_eq!(node_id, &node_b.get_our_node_id()); + assert_eq!(node_id, &node_a.get_our_node_id()); msg.clone() }, _ => panic!("Unexpected event"), }; - let (shutdown_b, mut closing_signed_b) = node_b.handle_shutdown(&node_a.get_our_node_id(), &shutdown_a).unwrap(); - if !close_inbound_first { - assert!(closing_signed_b.is_none()); + let closing_signed_b = if !close_inbound_first { + assert_eq!(events_1.len(), 1); + None + } else { + Some(match events_1[1] { + MessageSendEvent::SendClosingSigned { ref node_id, ref msg } => { + assert_eq!(node_id, &node_a.get_our_node_id()); + msg.clone() + }, + _ => panic!("Unexpected event"), + }) + }; + + macro_rules! get_closing_signed_broadcast { + ($node: expr, $dest_pubkey: expr) => { + { + let events = $node.get_and_clear_pending_msg_events(); + assert!(events.len() == 1 || events.len() == 2); + (match events[events.len() - 1] { + MessageSendEvent::BroadcastChannelUpdate { ref msg } => { + msg.clone() + }, + _ => panic!("Unexpected event"), + }, if events.len() == 2 { + match events[0] { + MessageSendEvent::SendClosingSigned { ref node_id, ref msg } => { + assert_eq!(*node_id, $dest_pubkey); + Some(msg.clone()) + }, + _ => panic!("Unexpected event"), + } + } else { None }) + } + } } - let (empty_a, mut closing_signed_a) = node_a.handle_shutdown(&node_b.get_our_node_id(), &shutdown_b.unwrap()).unwrap(); - assert!(empty_a.is_none()); - if close_inbound_first { - assert!(closing_signed_a.is_none()); - closing_signed_a = node_a.handle_closing_signed(&node_b.get_our_node_id(), &closing_signed_b.unwrap()).unwrap(); + + node_a.handle_shutdown(&node_b.get_our_node_id(), &shutdown_b).unwrap(); + let (as_update, bs_update) = if close_inbound_first { + assert!(node_a.get_and_clear_pending_msg_events().is_empty()); + node_a.handle_closing_signed(&node_b.get_our_node_id(), &closing_signed_b.unwrap()).unwrap(); assert_eq!(broadcaster_a.txn_broadcasted.lock().unwrap().len(), 1); tx_a = broadcaster_a.txn_broadcasted.lock().unwrap().remove(0); + let (as_update, closing_signed_a) = get_closing_signed_broadcast!(node_a, node_b.get_our_node_id()); - let empty_b = node_b.handle_closing_signed(&node_a.get_our_node_id(), &closing_signed_a.unwrap()).unwrap(); - assert!(empty_b.is_none()); + node_b.handle_closing_signed(&node_a.get_our_node_id(), &closing_signed_a.unwrap()).unwrap(); + let (bs_update, none_b) = get_closing_signed_broadcast!(node_b, node_a.get_our_node_id()); + assert!(none_b.is_none()); assert_eq!(broadcaster_b.txn_broadcasted.lock().unwrap().len(), 1); tx_b = broadcaster_b.txn_broadcasted.lock().unwrap().remove(0); + (as_update, bs_update) } else { - closing_signed_b = node_b.handle_closing_signed(&node_a.get_our_node_id(), &closing_signed_a.unwrap()).unwrap(); + let closing_signed_a = get_event_msg!(struct_a, MessageSendEvent::SendClosingSigned, node_b.get_our_node_id()); + + node_b.handle_closing_signed(&node_a.get_our_node_id(), &closing_signed_a).unwrap(); assert_eq!(broadcaster_b.txn_broadcasted.lock().unwrap().len(), 1); tx_b = broadcaster_b.txn_broadcasted.lock().unwrap().remove(0); + let (bs_update, closing_signed_b) = get_closing_signed_broadcast!(node_b, node_a.get_our_node_id()); - let empty_a2 = node_a.handle_closing_signed(&node_b.get_our_node_id(), &closing_signed_b.unwrap()).unwrap(); - assert!(empty_a2.is_none()); + node_a.handle_closing_signed(&node_b.get_our_node_id(), &closing_signed_b.unwrap()).unwrap(); + let (as_update, none_a) = get_closing_signed_broadcast!(node_a, node_b.get_our_node_id()); + assert!(none_a.is_none()); assert_eq!(broadcaster_a.txn_broadcasted.lock().unwrap().len(), 1); tx_a = broadcaster_a.txn_broadcasted.lock().unwrap().remove(0); - } + (as_update, bs_update) + }; assert_eq!(tx_a, tx_b); check_spends!(tx_a, funding_tx); - let events_2 = node_a.get_and_clear_pending_msg_events(); - assert_eq!(events_2.len(), 1); - let as_update = match events_2[0] { - MessageSendEvent::BroadcastChannelUpdate { ref msg } => { - msg.clone() - }, - _ => panic!("Unexpected event"), - }; - - let events_3 = node_b.get_and_clear_pending_msg_events(); - assert_eq!(events_3.len(), 1); - let bs_update = match events_3[0] { - MessageSendEvent::BroadcastChannelUpdate { ref msg } => { - msg.clone() - }, - _ => panic!("Unexpected event"), - }; - (as_update, bs_update) } diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index d01595b7216..b8fdeb12994 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -235,12 +235,14 @@ pub struct FundingLocked { } /// A shutdown message to be sent or received from a peer +#[derive(Clone)] pub struct Shutdown { pub(crate) channel_id: [u8; 32], pub(crate) scriptpubkey: Script, } /// A closing_signed message to be sent or received from a peer +#[derive(Clone)] pub struct ClosingSigned { pub(crate) channel_id: [u8; 32], pub(crate) fee_satoshis: u64, @@ -540,9 +542,9 @@ pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Syn // Channl close: /// Handle an incoming shutdown message from the given peer. - fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &Shutdown) -> Result<(Option, Option), HandleError>; + fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &Shutdown) -> Result<(), HandleError>; /// Handle an incoming closing_signed message from the given peer. - fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &ClosingSigned) -> Result, HandleError>; + fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &ClosingSigned) -> Result<(), HandleError>; // HTLC handling: /// Handle an incoming update_add_htlc message from the given peer. diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 9a2cee9dd49..5f1a8dc4034 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -581,20 +581,11 @@ impl PeerManager { 38 => { let msg = try_potential_decodeerror!(msgs::Shutdown::read(&mut reader)); - let resp_options = try_potential_handleerror!(self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg)); - if let Some(resp) = resp_options.0 { - encode_and_send_msg!(resp, 38); - } - if let Some(resp) = resp_options.1 { - encode_and_send_msg!(resp, 39); - } + try_potential_handleerror!(self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg)); }, 39 => { let msg = try_potential_decodeerror!(msgs::ClosingSigned::read(&mut reader)); - let resp_option = try_potential_handleerror!(self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg)); - if let Some(resp) = resp_option { - encode_and_send_msg!(resp, 39); - } + try_potential_handleerror!(self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg)); }, 128 => { @@ -883,6 +874,16 @@ impl PeerManager { peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 133))); Self::do_attempt_write_data(&mut descriptor, peer); }, + MessageSendEvent::SendClosingSigned { ref node_id, ref msg } => { + log_trace!(self, "Handling SendClosingSigned event in peer_handler for node {} for channel {}", + log_pubkey!(node_id), + log_bytes!(msg.channel_id)); + let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { + //TODO: Do whatever we're gonna do for handling dropped messages + }); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 39))); + Self::do_attempt_write_data(&mut descriptor, peer); + }, MessageSendEvent::SendShutdown { ref node_id, ref msg } => { log_trace!(self, "Handling Shutdown event in peer_handler for node {} for channel {}", log_pubkey!(node_id), diff --git a/src/util/events.rs b/src/util/events.rs index d7312cd9129..cfe16151a22 100644 --- a/src/util/events.rs +++ b/src/util/events.rs @@ -161,6 +161,13 @@ pub enum MessageSendEvent { /// The message which should be sent. msg: msgs::RevokeAndACK, }, + /// Used to indicate that a closing_signed message should be sent to the peer with the given node_id. + SendClosingSigned { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::ClosingSigned, + }, /// Used to indicate that a shutdown message should be sent to the peer with the given node_id. SendShutdown { /// The node_id of the node which should receive this message diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index f8959dcf17b..123ddd06fac 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -101,10 +101,10 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler { fn handle_funding_locked(&self, _their_node_id: &PublicKey, _msg: &msgs::FundingLocked) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } - fn handle_shutdown(&self, _their_node_id: &PublicKey, _msg: &msgs::Shutdown) -> Result<(Option, Option), HandleError> { + fn handle_shutdown(&self, _their_node_id: &PublicKey, _msg: &msgs::Shutdown) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } - fn handle_closing_signed(&self, _their_node_id: &PublicKey, _msg: &msgs::ClosingSigned) -> Result, HandleError> { + fn handle_closing_signed(&self, _their_node_id: &PublicKey, _msg: &msgs::ClosingSigned) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } fn handle_update_add_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateAddHTLC) -> Result<(), HandleError> { From 434211434540ab348d5a6937b5d9157eeb6f11bc Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 20 Oct 2018 12:56:42 -0400 Subject: [PATCH 12/15] Send RAA/CS messages out-of-band to ensure ordered delivery --- fuzz/fuzz_targets/full_stack_target.rs | 4 +- src/ln/channelmanager.rs | 551 ++++++++++++++++--------- src/ln/msgs.rs | 8 +- src/ln/peer_handler.rs | 26 +- src/util/test_utils.rs | 4 +- 5 files changed, 367 insertions(+), 226 deletions(-) diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index 6f18d071b95..7f6cf5e1919 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -807,8 +807,8 @@ mod tests { assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingSigned event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 2 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 3 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3f00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Encoding and sending message of type 133 to 030000000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4)); // 5 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Encoding and sending message of type 132 to 030000000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 6 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendRevokeAndACK event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4)); // 5 + assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 6 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3f00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 7 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 1 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 8 assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 1 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 9 diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index ace557528b3..13fb4e62f46 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -2130,25 +2130,40 @@ impl ChannelManager { } } - fn internal_commitment_signed(&self, their_node_id: &PublicKey, msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Option), MsgHandleErrInternal> { - let (revoke_and_ack, commitment_signed) = { - 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 { - //TODO: here and below MsgHandleErrInternal, #153 case - return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); - } - let (revoke_and_ack, commitment_signed, chan_monitor) = chan.commitment_signed(&msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?; - if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { - unimplemented!(); - } - (revoke_and_ack, commitment_signed) - }, - None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) - } - }; - Ok((revoke_and_ack, commitment_signed)) + fn internal_commitment_signed(&self, their_node_id: &PublicKey, msg: &msgs::CommitmentSigned) -> Result<(), MsgHandleErrInternal> { + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); + match channel_state.by_id.get_mut(&msg.channel_id) { + Some(chan) => { + if chan.get_their_node_id() != *their_node_id { + //TODO: here and below MsgHandleErrInternal, #153 case + return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); + } + let (revoke_and_ack, commitment_signed, chan_monitor) = chan.commitment_signed(&msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?; + if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { + unimplemented!(); + } + channel_state.pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK { + node_id: their_node_id.clone(), + msg: revoke_and_ack, + }); + if let Some(msg) = commitment_signed { + channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { + node_id: their_node_id.clone(), + 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: None, + commitment_signed: msg, + }, + }); + } + Ok(()) + }, + None => Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } } #[inline] @@ -2184,20 +2199,27 @@ impl ChannelManager { } } - fn internal_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &msgs::RevokeAndACK) -> Result, MsgHandleErrInternal> { - let ((res, pending_forwards, mut pending_failures), short_channel_id) = { - let mut channel_state = self.channel_state.lock().unwrap(); + fn internal_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &msgs::RevokeAndACK) -> Result<(), MsgHandleErrInternal> { + let (pending_forwards, mut pending_failures, short_channel_id) = { + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); match channel_state.by_id.get_mut(&msg.channel_id) { Some(chan) => { if chan.get_their_node_id() != *their_node_id { //TODO: here and below MsgHandleErrInternal, #153 case return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); } - let (res, pending_forwards, pending_failures, chan_monitor) = chan.revoke_and_ack(&msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?; + let (commitment_update, pending_forwards, pending_failures, chan_monitor) = chan.revoke_and_ack(&msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))?; if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) { unimplemented!(); } - ((res, pending_forwards, pending_failures), chan.get_short_channel_id().expect("RAA should only work on a short-id-available channel")) + if let Some(updates) = commitment_update { + channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { + node_id: their_node_id.clone(), + updates, + }); + } + (pending_forwards, pending_failures, chan.get_short_channel_id().expect("RAA should only work on a short-id-available channel")) }, None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) } @@ -2207,7 +2229,7 @@ impl ChannelManager { } self.forward_htlcs(&mut [(short_channel_id, pending_forwards)]); - Ok(res) + Ok(()) } fn internal_update_fee(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFee) -> Result<(), MsgHandleErrInternal> { @@ -2537,11 +2559,11 @@ impl ChannelMessageHandler for ChannelManager { handle_error!(self, self.internal_update_fail_malformed_htlc(their_node_id, msg), their_node_id) } - fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Option), HandleError> { + fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &msgs::CommitmentSigned) -> Result<(), HandleError> { handle_error!(self, self.internal_commitment_signed(their_node_id, msg), their_node_id) } - fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &msgs::RevokeAndACK) -> Result, HandleError> { + fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &msgs::RevokeAndACK) -> Result<(), HandleError> { handle_error!(self, self.internal_revoke_and_ack(their_node_id, msg), their_node_id) } @@ -2881,6 +2903,33 @@ mod tests { (announcement, as_update, bs_update, channel_id, tx) } + macro_rules! get_revoke_commit_msgs { + ($node: expr, $node_id: expr) => { + { + let events = $node.node.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 2); + (match events[0] { + MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => { + assert_eq!(*node_id, $node_id); + (*msg).clone() + }, + _ => panic!("Unexpected event"), + }, match events[1] { + MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => { + assert_eq!(*node_id, $node_id); + assert!(updates.update_add_htlcs.is_empty()); + assert!(updates.update_fulfill_htlcs.is_empty()); + assert!(updates.update_fail_htlcs.is_empty()); + assert!(updates.update_fail_malformed_htlcs.is_empty()); + assert!(updates.update_fee.is_none()); + updates.commitment_signed.clone() + }, + _ => panic!("Unexpected event"), + }) + } + } + } + macro_rules! get_event_msg { ($node: expr, $event_type: path, $node_id: expr) => { { @@ -2897,6 +2946,22 @@ mod tests { } } + macro_rules! get_htlc_update_msgs { + ($node: expr, $node_id: expr) => { + { + let events = $node.node.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + match events[0] { + MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => { + assert_eq!(*node_id, $node_id); + (*updates).clone() + }, + _ => panic!("Unexpected event"), + } + } + } + } + fn create_chan_between_nodes_with_value_init(node_a: &Node, node_b: &Node, channel_value: u64, push_msat: u64) -> Transaction { node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42).unwrap(); node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id())).unwrap(); @@ -3167,19 +3232,32 @@ mod tests { ($node_a: expr, $node_b: expr, $commitment_signed: expr, $fail_backwards: expr) => { { 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(); + assert!($node_a.node.get_and_clear_pending_msg_events().is_empty()); + $node_a.node.handle_commitment_signed(&$node_b.node.get_our_node_id(), &$commitment_signed).unwrap(); + let (as_revoke_and_ack, as_commitment_signed) = get_revoke_commit_msgs!($node_a, $node_b.node.get_our_node_id()); 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()); + assert!($node_b.node.get_and_clear_pending_msg_events().is_empty()); + $node_b.node.handle_revoke_and_ack(&$node_a.node.get_our_node_id(), &as_revoke_and_ack).unwrap(); + assert!($node_b.node.get_and_clear_pending_msg_events().is_empty()); 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()); + $node_b.node.handle_commitment_signed(&$node_a.node.get_our_node_id(), &as_commitment_signed).unwrap(); + let bs_revoke_and_ack = get_event_msg!($node_b, MessageSendEvent::SendRevokeAndACK, $node_a.node.get_our_node_id()); check_added_monitors!($node_b, 1); if $fail_backwards { assert!($node_a.node.get_and_clear_pending_events().is_empty()); assert!($node_a.node.get_and_clear_pending_msg_events().is_empty()); } - assert!($node_a.node.handle_revoke_and_ack(&$node_b.node.get_our_node_id(), &bs_revoke_and_ack).unwrap().is_none()); + $node_a.node.handle_revoke_and_ack(&$node_b.node.get_our_node_id(), &bs_revoke_and_ack).unwrap(); + if $fail_backwards { + let channel_state = $node_a.node.channel_state.lock().unwrap(); + assert_eq!(channel_state.pending_msg_events.len(), 1); + if let MessageSendEvent::UpdateHTLCs { ref node_id, .. } = channel_state.pending_msg_events[0] { + assert_ne!(*node_id, $node_b.node.get_our_node_id()); + } else { panic!("Unexpected event"); } + } else { + assert!($node_a.node.get_and_clear_pending_msg_events().is_empty()); + } { let mut added_monitors = $node_a.chan_monitor.added_monitors.lock().unwrap(); if $fail_backwards { @@ -3267,45 +3345,65 @@ mod tests { 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) => { + let mut expected_next_node = expected_route.last().unwrap().node.get_our_node_id(); + macro_rules! get_next_msgs { + ($node: expr) => { + { + let events = $node.node.get_and_clear_pending_msg_events(); + assert_eq!(events.len(), 1); + match events[0] { + MessageSendEvent::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(); + Some((update_fulfill_htlcs[0].clone(), commitment_signed.clone())) + }, + _ => panic!("Unexpected event"), + } + } + } + } + + macro_rules! last_update_fulfill_dance { + ($node: expr, $prev_node: expr) => { { $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0).unwrap(); - if $last_node { - check_added_monitors!($node, 0); + check_added_monitors!($node, 0); + assert!($node.node.get_and_clear_pending_msg_events().is_empty()); + commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false); + } + } + } + macro_rules! mid_update_fulfill_dance { + ($node: expr, $prev_node: expr, $new_msgs: expr) => { + { + $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0).unwrap(); + check_added_monitors!($node, 1); + let new_next_msgs = if $new_msgs { + get_next_msgs!($node) } else { - check_added_monitors!($node, 1); - } + assert!($node.node.get_and_clear_pending_msg_events().is_empty()); + None + }; commitment_signed_dance!($node, $prev_node, next_msgs.as_ref().unwrap().1, false); + next_msgs = new_next_msgs; } } } - let mut expected_next_node = expected_route.last().unwrap().node.get_our_node_id(); let mut prev_node = expected_route.last().unwrap(); for (idx, node) in expected_route.iter().rev().enumerate() { assert_eq!(expected_next_node, node.node.get_our_node_id()); + let update_next_msgs = !skip_last || idx != expected_route.len() - 1; if next_msgs.is_some() { - update_fulfill_dance!(node, prev_node, false); - } - - let events = node.node.get_and_clear_pending_msg_events(); - if !skip_last || idx != expected_route.len() - 1 { - assert_eq!(events.len(), 1); - match events[0] { - MessageSendEvent::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"), - } + mid_update_fulfill_dance!(node, prev_node, update_next_msgs); + } else if update_next_msgs { + next_msgs = get_next_msgs!(node); } else { - assert!(events.is_empty()); + assert!(node.node.get_and_clear_pending_msg_events().is_empty()); } if !skip_last && idx == expected_route.len() - 1 { assert_eq!(expected_next_node, origin_node.node.get_our_node_id()); @@ -3315,7 +3413,7 @@ mod tests { } if !skip_last { - update_fulfill_dance!(origin_node, expected_route.first().unwrap(), true); + last_update_fulfill_dance!(origin_node, expected_route.first().unwrap()); let events = origin_node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { @@ -3525,40 +3623,45 @@ mod tests { // ...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 + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &payment_event.commitment_msg).unwrap(); // (2) + let as_revoke_and_ack = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // nodes[0] is awaiting nodes[1] revoke_and_ack so get_event_msg's assert(len == 1) passes 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 + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); + let bs_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + // nodes[1] is awaiting nodes[0] revoke_and_ack so get_event_msg's assert(len == 1) passes 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) + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap(); // deliver (2) + let bs_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); + assert!(bs_update.update_add_htlcs.is_empty()); // (4) + assert!(bs_update.update_fulfill_htlcs.is_empty()); // (4) + assert!(bs_update.update_fail_htlcs.is_empty()); // (4) + assert!(bs_update.update_fail_malformed_htlcs.is_empty()); // (4) + assert!(bs_update.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) + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap(); // deliver (3) + let as_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + assert!(as_update.update_add_htlcs.is_empty()); // (5) + assert!(as_update.update_fulfill_htlcs.is_empty()); // (5) + assert!(as_update.update_fail_htlcs.is_empty()); // (5) + assert!(as_update.update_fail_malformed_htlcs.is_empty()); // (5) + assert!(as_update.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) + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_update.commitment_signed).unwrap(); // deliver (4) + let as_second_revoke = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // only (6) so get_event_msg's assert(len == 1) passes 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()); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_update.commitment_signed).unwrap(); // deliver (5) + let bs_second_revoke = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); 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()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_revoke).unwrap(); check_added_monitors!(nodes[0], 1); let events_2 = nodes[0].node.get_and_clear_pending_events(); @@ -3568,7 +3671,7 @@ mod tests { _ => 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) + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_revoke).unwrap(); // deliver (6) check_added_monitors!(nodes[1], 1); } @@ -3621,11 +3724,12 @@ mod tests { // ...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 + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &payment_event.commitment_msg).unwrap(); // (2) + let as_revoke_msg = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // nodes[0] is awaiting nodes[1] revoke_and_ack so get_event_msg's assert(len == 1) passes 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) + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_msg).unwrap(); // deliver (2) check_added_monitors!(nodes[1], 1); // We can't continue, sadly, because our (1) now has a bogus signature @@ -3680,7 +3784,8 @@ mod tests { // Deliver first update_fee/commitment_signed pair, generating (1) and (2): nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg_1).unwrap(); - let (bs_revoke_msg, bs_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed_1).unwrap(); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed_1).unwrap(); + let (bs_revoke_msg, bs_commitment_signed) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id()); check_added_monitors!(nodes[1], 1); // nodes[0] is awaiting a revoke from nodes[1] before it will create a new commitment @@ -3702,36 +3807,43 @@ mod tests { nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), &update_msg_2).unwrap(); // Deliver (1), generating (3) and (4) - let as_second_update = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_msg).unwrap(); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_msg).unwrap(); + let as_second_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); check_added_monitors!(nodes[0], 1); - assert!(as_second_update.as_ref().unwrap().update_add_htlcs.is_empty()); - assert!(as_second_update.as_ref().unwrap().update_fulfill_htlcs.is_empty()); - assert!(as_second_update.as_ref().unwrap().update_fail_htlcs.is_empty()); - assert!(as_second_update.as_ref().unwrap().update_fail_malformed_htlcs.is_empty()); + assert!(as_second_update.update_add_htlcs.is_empty()); + assert!(as_second_update.update_fulfill_htlcs.is_empty()); + assert!(as_second_update.update_fail_htlcs.is_empty()); + assert!(as_second_update.update_fail_malformed_htlcs.is_empty()); // Check that the update_fee newly generated matches what we delivered: - assert_eq!(as_second_update.as_ref().unwrap().update_fee.as_ref().unwrap().channel_id, update_msg_2.channel_id); - assert_eq!(as_second_update.as_ref().unwrap().update_fee.as_ref().unwrap().feerate_per_kw, update_msg_2.feerate_per_kw); + assert_eq!(as_second_update.update_fee.as_ref().unwrap().channel_id, update_msg_2.channel_id); + assert_eq!(as_second_update.update_fee.as_ref().unwrap().feerate_per_kw, update_msg_2.feerate_per_kw); // Deliver (2) commitment_signed - let (as_revoke_msg, as_commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), bs_commitment_signed.as_ref().unwrap()).unwrap(); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_commitment_signed).unwrap(); + let as_revoke_msg = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); check_added_monitors!(nodes[0], 1); - assert!(as_commitment_signed.is_none()); + // No commitment_signed so get_event_msg's assert(len == 1) passes - assert!(nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_msg).unwrap().is_none()); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_msg).unwrap(); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 1); // Delever (4) - let (bs_second_revoke, bs_second_commitment) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_second_update.unwrap().commitment_signed).unwrap(); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_second_update.commitment_signed).unwrap(); + let (bs_second_revoke, bs_second_commitment) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id()); 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()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_revoke).unwrap(); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[0], 1); - let (as_second_revoke, as_second_commitment) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_commitment.unwrap()).unwrap(); - assert!(as_second_commitment.is_none()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_commitment).unwrap(); + let as_second_revoke = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[0], 1); - assert!(nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_revoke).unwrap().is_none()); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_second_revoke).unwrap(); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 1); } @@ -3751,6 +3863,7 @@ mod tests { let feerate = get_feerate!(nodes[0]); nodes[0].node.update_fee(channel_id, feerate+20).unwrap(); + check_added_monitors!(nodes[0], 1); let events_0 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_0.len(), 1); @@ -3762,21 +3875,21 @@ mod tests { }; 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); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); + let (revoke_msg, commitment_signed) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id()); 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()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); 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()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed).unwrap(); + let revoke_msg = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes 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()); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 1); } @@ -3799,6 +3912,7 @@ mod tests { let feerate = get_feerate!(nodes[0]); nodes[0].node.update_fee(channel_id, feerate+20).unwrap(); + check_added_monitors!(nodes[0], 1); let events_0 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_0.len(), 1); @@ -3809,9 +3923,8 @@ mod tests { _ => 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(); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); + let (revoke_msg, commitment_signed) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id()); 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(); @@ -3829,17 +3942,19 @@ mod tests { assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); // 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()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); 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()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed).unwrap(); + let revoke_msg = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes 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(); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke_msg).unwrap(); + check_added_monitors!(nodes[1], 1); // AwaitingRemoteRevoke ends here - let commitment_update = resp_option.unwrap(); + let commitment_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); 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); @@ -3847,20 +3962,22 @@ mod tests { 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(); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_update.commitment_signed).unwrap(); check_added_monitors!(nodes[0], 1); + let (revoke, commitment_signed) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke).unwrap(); 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()); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); - let (revoke, commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &commitment_signed).unwrap(); + 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(); + let revoke = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes + + 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()); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); let events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); @@ -3916,6 +4033,7 @@ mod tests { // Create and deliver (1)... let feerate = get_feerate!(nodes[0]); nodes[0].node.update_fee(channel_id, feerate+20).unwrap(); + check_added_monitors!(nodes[0], 1); let events_0 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_0.len(), 1); @@ -3928,18 +4046,18 @@ mod tests { 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); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); + let (revoke_msg, commitment_signed_0) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id()); 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()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[0], 1); // Create and deliver (4)... nodes[0].node.update_fee(channel_id, feerate+30).unwrap(); + check_added_monitors!(nodes[0], 1); let events_0 = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events_0.len(), 1); let (update_msg, commitment_signed) = match events_0[0] { @@ -3948,36 +4066,44 @@ mod tests { }, _ => 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); + nodes[1].node.handle_update_fee(&nodes[0].node.get_our_node_id(), update_msg.unwrap()).unwrap(); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), commitment_signed).unwrap(); check_added_monitors!(nodes[1], 1); + // ... creating (5) + let revoke_msg = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes // 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()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed_0).unwrap(); check_added_monitors!(nodes[0], 1); + let revoke_msg_0 = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes // 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()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &revoke_msg).unwrap(); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); 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; + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke_msg_0).unwrap(); + let commitment_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); + assert!(commitment_update.update_add_htlcs.is_empty()); + assert!(commitment_update.update_fulfill_htlcs.is_empty()); + assert!(commitment_update.update_fail_htlcs.is_empty()); + assert!(commitment_update.update_fail_malformed_htlcs.is_empty()); + assert!(commitment_update.update_fee.is_none()); 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()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_update.commitment_signed).unwrap(); 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()); + let revoke_msg = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes + + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &revoke_msg).unwrap(); check_added_monitors!(nodes[1], 1); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); assert_eq!(get_feerate!(nodes[0]), feerate + 30); assert_eq!(get_feerate!(nodes[1]), feerate + 30); @@ -4448,15 +4574,21 @@ mod tests { assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); // flush the pending htlc - let (as_revoke_and_ack, as_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event_1.commitment_msg).unwrap(); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event_1.commitment_msg).unwrap(); + let (as_revoke_and_ack, as_commitment_signed) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id()); check_added_monitors!(nodes[1], 1); - let commitment_update_2 = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &as_revoke_and_ack).unwrap().unwrap(); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &as_revoke_and_ack).unwrap(); check_added_monitors!(nodes[0], 1); - let (bs_revoke_and_ack, bs_none) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &as_commitment_signed.unwrap()).unwrap(); - assert!(bs_none.is_none()); + let commitment_update_2 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); + + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &as_commitment_signed).unwrap(); + let bs_revoke_and_ack = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[0], 1); - assert!(nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &bs_revoke_and_ack).unwrap().is_none()); + + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &bs_revoke_and_ack).unwrap(); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 1); expect_pending_htlcs_forwardable!(nodes[1]); @@ -4932,6 +5064,7 @@ mod tests { 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(); check_added_monitors!(nodes[2], 1); + let (_, _) = get_revoke_commit_msgs!(nodes[2], nodes[1].node.get_our_node_id()); // 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 @@ -5067,7 +5200,8 @@ mod tests { } if pending_raa.0 { assert!(chan_msgs.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst); - assert!(node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap().is_none()); + node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap(); + assert!(node_a.node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(node_a, 1); } else { assert!(chan_msgs.1.is_none()); @@ -5095,10 +5229,12 @@ mod tests { if pending_htlc_adds.0 != -1 { // We use -1 to denote a response commitment_signed commitment_signed_dance!(node_a, node_b, commitment_update.commitment_signed, false); } else { - let (as_revoke_and_ack, as_commitment_signed) = node_a.node.handle_commitment_signed(&node_b.node.get_our_node_id(), &commitment_update.commitment_signed).unwrap(); + node_a.node.handle_commitment_signed(&node_b.node.get_our_node_id(), &commitment_update.commitment_signed).unwrap(); check_added_monitors!(node_a, 1); - assert!(as_commitment_signed.is_none()); - assert!(node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &as_revoke_and_ack).unwrap().is_none()); + let as_revoke_and_ack = get_event_msg!(node_a, MessageSendEvent::SendRevokeAndACK, node_b.node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes + node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &as_revoke_and_ack).unwrap(); + assert!(node_b.node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(node_b, 1); } } else { @@ -5121,7 +5257,8 @@ mod tests { } if pending_raa.1 { assert!(chan_msgs.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst); - assert!(node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap().is_none()); + node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap(); + assert!(node_b.node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(node_b, 1); } else { assert!(chan_msgs.1.is_none()); @@ -5147,10 +5284,12 @@ mod tests { if pending_htlc_adds.1 != -1 { // We use -1 to denote a response commitment_signed commitment_signed_dance!(node_b, node_a, commitment_update.commitment_signed, false); } else { - let (bs_revoke_and_ack, bs_commitment_signed) = node_b.node.handle_commitment_signed(&node_a.node.get_our_node_id(), &commitment_update.commitment_signed).unwrap(); + node_b.node.handle_commitment_signed(&node_a.node.get_our_node_id(), &commitment_update.commitment_signed).unwrap(); check_added_monitors!(node_b, 1); - assert!(bs_commitment_signed.is_none()); - assert!(node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &bs_revoke_and_ack).unwrap().is_none()); + let bs_revoke_and_ack = get_event_msg!(node_b, MessageSendEvent::SendRevokeAndACK, node_a.node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes + node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &bs_revoke_and_ack).unwrap(); + assert!(node_a.node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(node_a, 1); } } else { @@ -5240,20 +5379,24 @@ mod tests { // Drop the payment_event messages, and let them get re-generated in reconnect_nodes! } else { nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]).unwrap(); - let (bs_revoke_and_ack, bs_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg).unwrap(); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg).unwrap(); check_added_monitors!(nodes[1], 1); + let (bs_revoke_and_ack, bs_commitment_signed) = get_revoke_commit_msgs!(nodes[1], nodes[0].node.get_our_node_id()); if messages_delivered >= 3 { - assert!(nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap().is_none()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap(); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[0], 1); if messages_delivered >= 4 { - let (as_revoke_and_ack, as_commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_commitment_signed.unwrap()).unwrap(); - assert!(as_commitment_signed.is_none()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_commitment_signed).unwrap(); + let as_revoke_and_ack = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[0], 1); if messages_delivered >= 5 { - assert!(nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap().is_none()); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap(); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 1); } } @@ -5335,20 +5478,24 @@ mod tests { } if messages_delivered >= 2 { - let (as_revoke_and_ack, as_commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed).unwrap(); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &commitment_signed).unwrap(); check_added_monitors!(nodes[0], 1); + let (as_revoke_and_ack, as_commitment_signed) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id()); if messages_delivered >= 3 { - assert!(nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap().is_none()); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap(); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 1); if messages_delivered >= 4 { - let (bs_revoke_and_ack, bs_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_commitment_signed.unwrap()).unwrap(); - assert!(bs_commitment_signed.is_none()); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_commitment_signed).unwrap(); + let bs_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[1], 1); if messages_delivered >= 5 { - assert!(nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap().is_none()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap(); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[0], 1); } } @@ -5497,8 +5644,9 @@ mod tests { _ => panic!("Unexpected event"), } - let (_, commitment_update) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), commitment_signed).unwrap(); - assert!(commitment_update.is_none()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), commitment_signed).unwrap(); + let _ = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[0], 1); }, _ => panic!("Unexpected event"), @@ -5529,11 +5677,13 @@ mod tests { assert!(as_resp.2.as_ref().unwrap().update_fail_malformed_htlcs.is_empty()); assert!(as_resp.2.as_ref().unwrap().update_fee.is_none()); nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &as_resp.2.as_ref().unwrap().update_add_htlcs[0]).unwrap(); - let (bs_revoke_and_ack, bs_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_resp.2.as_ref().unwrap().commitment_signed).unwrap(); - assert!(bs_commitment_signed.is_none()); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_resp.2.as_ref().unwrap().commitment_signed).unwrap(); + let bs_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[1], 1); - let bs_second_commitment_signed = nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), as_resp.1.as_ref().unwrap()).unwrap().unwrap(); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), as_resp.1.as_ref().unwrap()).unwrap(); + let bs_second_commitment_signed = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); assert!(bs_second_commitment_signed.update_add_htlcs.is_empty()); assert!(bs_second_commitment_signed.update_fulfill_htlcs.is_empty()); assert!(bs_second_commitment_signed.update_fail_htlcs.is_empty()); @@ -5541,7 +5691,8 @@ mod tests { assert!(bs_second_commitment_signed.update_fee.is_none()); check_added_monitors!(nodes[1], 1); - let as_commitment_signed = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap().unwrap(); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap(); + let as_commitment_signed = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); assert!(as_commitment_signed.update_add_htlcs.is_empty()); assert!(as_commitment_signed.update_fulfill_htlcs.is_empty()); assert!(as_commitment_signed.update_fail_htlcs.is_empty()); @@ -5549,15 +5700,18 @@ mod tests { assert!(as_commitment_signed.update_fee.is_none()); check_added_monitors!(nodes[0], 1); - let (as_revoke_and_ack, as_second_commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_commitment_signed.commitment_signed).unwrap(); - assert!(as_second_commitment_signed.is_none()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_commitment_signed.commitment_signed).unwrap(); + let as_revoke_and_ack = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[0], 1); - let (bs_second_revoke_and_ack, bs_third_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_commitment_signed.commitment_signed).unwrap(); - assert!(bs_third_commitment_signed.is_none()); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_commitment_signed.commitment_signed).unwrap(); + let bs_second_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[1], 1); - assert!(nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap().is_none()); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap(); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 1); let events_4 = nodes[1].node.get_and_clear_pending_events(); @@ -5579,7 +5733,8 @@ mod tests { _ => panic!("Unexpected event"), } - assert!(nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_revoke_and_ack).unwrap().is_none()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_revoke_and_ack).unwrap(); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[0], 1); claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2); @@ -5844,8 +5999,9 @@ mod tests { _ => panic!("Unexpected event"), } - let (as_resp_raa, as_resp_cu) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_resp.2.as_ref().unwrap().commitment_signed).unwrap(); - assert!(as_resp_cu.is_none()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_resp.2.as_ref().unwrap().commitment_signed).unwrap(); + let as_resp_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[0], 1); as_resp.1 = Some(as_resp_raa); @@ -5879,8 +6035,9 @@ mod tests { assert_eq!(payment_event.node_id, nodes[1].node.get_our_node_id()); nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]).unwrap(); - let (bs_revoke_and_ack, bs_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg).unwrap(); - assert!(bs_commitment_signed.is_none()); // nodes[1] is awaiting an RAA from nodes[0] still + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &payment_event.commitment_msg).unwrap(); + let bs_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + // nodes[1] is awaiting an RAA from nodes[0] still so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[1], 1); if disconnect_count & !disconnect_flags > 2 { @@ -5897,7 +6054,8 @@ mod tests { let bs_second_commitment_update; macro_rules! handle_bs_raa { () => { - as_commitment_update = nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap().unwrap(); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_revoke_and_ack).unwrap(); + as_commitment_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id()); assert!(as_commitment_update.update_add_htlcs.is_empty()); assert!(as_commitment_update.update_fulfill_htlcs.is_empty()); assert!(as_commitment_update.update_fail_htlcs.is_empty()); @@ -5907,7 +6065,8 @@ mod tests { } } macro_rules! handle_initial_raa { () => { - bs_second_commitment_update = nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &initial_revoke_and_ack).unwrap().unwrap(); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &initial_revoke_and_ack).unwrap(); + bs_second_commitment_update = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); assert!(bs_second_commitment_update.update_add_htlcs.is_empty()); assert!(bs_second_commitment_update.update_fulfill_htlcs.is_empty()); assert!(bs_second_commitment_update.update_fail_htlcs.is_empty()); @@ -5970,18 +6129,22 @@ mod tests { } } - let (as_revoke_and_ack, as_commitment_signed) = nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_commitment_update.commitment_signed).unwrap(); - assert!(as_commitment_signed.is_none()); + nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_second_commitment_update.commitment_signed).unwrap(); + let as_revoke_and_ack = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[0], 1); - let (bs_second_revoke_and_ack, bs_third_commitment_signed) = nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_commitment_update.commitment_signed).unwrap(); - assert!(bs_third_commitment_signed.is_none()); + nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &as_commitment_update.commitment_signed).unwrap(); + let bs_second_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id()); + // No commitment_signed so get_event_msg's assert(len == 1) passes check_added_monitors!(nodes[1], 1); - assert!(nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap().is_none()); + nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &as_revoke_and_ack).unwrap(); + assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[1], 1); - assert!(nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_revoke_and_ack).unwrap().is_none()); + nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_second_revoke_and_ack).unwrap(); + assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(nodes[0], 1); expect_pending_htlcs_forwardable!(nodes[1]); diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index b8fdeb12994..fb0863719ba 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -302,7 +302,7 @@ pub struct RevokeAndACK { } /// An update_fee message to be sent or received from a peer -#[derive(PartialEq)] +#[derive(PartialEq, Clone)] pub struct UpdateFee { pub(crate) channel_id: [u8; 32], pub(crate) feerate_per_kw: u32, @@ -473,7 +473,7 @@ pub struct HandleError { //TODO: rename me /// Struct used to return values from revoke_and_ack messages, containing a bunch of commitment /// transaction updates if they were pending. -#[derive(PartialEq)] +#[derive(PartialEq, Clone)] pub struct CommitmentUpdate { pub(crate) update_add_htlcs: Vec, pub(crate) update_fulfill_htlcs: Vec, @@ -556,9 +556,9 @@ pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Syn /// Handle an incoming update_fail_malformed_htlc message from the given peer. fn handle_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailMalformedHTLC) -> Result<(), HandleError>; /// Handle an incoming commitment_signed message from the given peer. - fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &CommitmentSigned) -> Result<(RevokeAndACK, Option), HandleError>; + fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &CommitmentSigned) -> Result<(), HandleError>; /// Handle an incoming revoke_and_ack message from the given peer. - fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &RevokeAndACK) -> Result, HandleError>; + fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &RevokeAndACK) -> Result<(), HandleError>; /// Handle an incoming update_fee message from the given peer. fn handle_update_fee(&self, their_node_id: &PublicKey, msg: &UpdateFee) -> Result<(), HandleError>; diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 5f1a8dc4034..76533416736 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -607,33 +607,11 @@ impl PeerManager { 132 => { let msg = try_potential_decodeerror!(msgs::CommitmentSigned::read(&mut reader)); - let resps = try_potential_handleerror!(self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg)); - encode_and_send_msg!(resps.0, 133); - if let Some(resp) = resps.1 { - encode_and_send_msg!(resp, 132); - } + try_potential_handleerror!(self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg)); }, 133 => { let msg = try_potential_decodeerror!(msgs::RevokeAndACK::read(&mut reader)); - let resp_option = try_potential_handleerror!(self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg)); - match resp_option { - Some(resps) => { - for resp in resps.update_add_htlcs { - encode_and_send_msg!(resp, 128); - } - for resp in resps.update_fulfill_htlcs { - encode_and_send_msg!(resp, 130); - } - for resp in resps.update_fail_htlcs { - encode_and_send_msg!(resp, 131); - } - if let Some(resp) = resps.update_fee { - encode_and_send_msg!(resp, 134); - } - encode_and_send_msg!(resps.commitment_signed, 132); - }, - None => {}, - } + try_potential_handleerror!(self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg)); }, 134 => { let msg = try_potential_decodeerror!(msgs::UpdateFee::read(&mut reader)); diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index 123ddd06fac..04d6dbeb400 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -119,10 +119,10 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler { fn handle_update_fail_malformed_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFailMalformedHTLC) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } - fn handle_commitment_signed(&self, _their_node_id: &PublicKey, _msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Option), HandleError> { + fn handle_commitment_signed(&self, _their_node_id: &PublicKey, _msg: &msgs::CommitmentSigned) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } - fn handle_revoke_and_ack(&self, _their_node_id: &PublicKey, _msg: &msgs::RevokeAndACK) -> Result, HandleError> { + fn handle_revoke_and_ack(&self, _their_node_id: &PublicKey, _msg: &msgs::RevokeAndACK) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } fn handle_update_fee(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFee) -> Result<(), HandleError> { From e2de49ddc4143da3d87d1a8615bb1b9a33a4c5a3 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 20 Oct 2018 17:18:53 -0400 Subject: [PATCH 13/15] Respond to channel_reestablish out-of-band for ordered delivery --- src/ln/channel.rs | 4 +- src/ln/channelmanager.rs | 179 +++++++++++++++++++++++++++++++-------- src/ln/msgs.rs | 14 +-- src/ln/peer_handler.rs | 40 +-------- src/util/test_utils.rs | 2 +- 5 files changed, 147 insertions(+), 92 deletions(-) diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 6fd6afe8e36..b8a89fe5928 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -13,9 +13,9 @@ use secp256k1; use crypto::digest::Digest; use ln::msgs; -use ln::msgs::{ErrorAction, HandleError, RAACommitmentOrder}; +use ln::msgs::{ErrorAction, HandleError}; use ln::channelmonitor::ChannelMonitor; -use ln::channelmanager::{PendingHTLCStatus, HTLCSource, PendingForwardHTLCInfo, HTLCFailReason, HTLCFailureMsg}; +use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingForwardHTLCInfo, RAACommitmentOrder}; use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT}; use ln::chan_utils; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 13fb4e62f46..7d11fe987f2 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -26,7 +26,7 @@ use ln::channel::{Channel, ChannelError}; use ln::channelmonitor::{ChannelMonitorUpdateErr, ManyChannelMonitor, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS}; use ln::router::{Route,RouteHop}; use ln::msgs; -use ln::msgs::{ChannelMessageHandler, HandleError, RAACommitmentOrder}; +use ln::msgs::{ChannelMessageHandler, HandleError}; use chain::keysinterface::KeysInterface; use util::{byte_utils, events, internal_traits, rng}; use util::sha2::Sha256; @@ -244,6 +244,18 @@ struct HTLCForwardInfo { forward_info: PendingForwardHTLCInfo, } +/// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should +/// be sent in the order they appear in the return value, however sometimes the order needs to be +/// variable at runtime (eg Channel::channel_reestablish needs to re-send messages in the order +/// they were originally sent). In those cases, this enum is also returned. +#[derive(Clone, PartialEq)] +pub(super) enum RAACommitmentOrder { + /// Send the CommitmentUpdate messages first + CommitmentFirst, + /// Send the RevokeAndACK message first + RevokeAndACKFirst, +} + struct ChannelHolder { by_id: HashMap<[u8; 32], Channel>, short_to_id: HashMap, @@ -2287,28 +2299,58 @@ impl ChannelManager { Ok(()) } - fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option, RAACommitmentOrder), MsgHandleErrInternal> { - let res = { - 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)); + fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), MsgHandleErrInternal> { + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); + + 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, order) = chan.channel_reestablish(msg) + .map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))?; + if let Some(monitor) = channel_monitor { + if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) { + unimplemented!(); } - let (funding_locked, revoke_and_ack, commitment_update, channel_monitor, order) = chan.channel_reestablish(msg) - .map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))?; - if let Some(monitor) = channel_monitor { - if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) { - unimplemented!(); - } + } + if let Some(msg) = funding_locked { + channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingLocked { + node_id: their_node_id.clone(), + msg + }); + } + macro_rules! send_raa { () => { + if let Some(msg) = revoke_and_ack { + channel_state.pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK { + node_id: their_node_id.clone(), + msg + }); } - Ok((funding_locked, revoke_and_ack, commitment_update, order)) - }, - None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) - } - }; - - res + } } + macro_rules! send_cu { () => { + if let Some(updates) = commitment_update { + channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { + node_id: their_node_id.clone(), + updates + }); + } + } } + match order { + RAACommitmentOrder::RevokeAndACKFirst => { + send_raa!(); + send_cu!(); + }, + RAACommitmentOrder::CommitmentFirst => { + send_cu!(); + send_raa!(); + }, + } + Ok(()) + }, + None => Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) + } } /// Begin Update fee process. Allowed only on an outbound channel. @@ -2575,7 +2617,7 @@ 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, RAACommitmentOrder), HandleError> { + fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), HandleError> { handle_error!(self, self.internal_channel_reestablish(their_node_id, msg), their_node_id) } @@ -2675,7 +2717,7 @@ mod tests { use chain::chaininterface::ChainListener; use chain::keysinterface::KeysInterface; use chain::keysinterface; - use ln::channelmanager::{ChannelManager,OnionKeys,PaymentFailReason}; + use ln::channelmanager::{ChannelManager,OnionKeys,PaymentFailReason,RAACommitmentOrder}; use ln::channelmonitor::{ChannelMonitorUpdateErr, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS}; use ln::router::{Route, RouteHop, Router}; use ln::msgs; @@ -5155,6 +5197,61 @@ mod tests { assert_eq!(channel_state.short_to_id.len(), 0); } + macro_rules! handle_chan_reestablish_msgs { + ($src_node: expr, $dst_node: expr) => { + { + let msg_events = $src_node.node.get_and_clear_pending_msg_events(); + let mut idx = 0; + let funding_locked = if let Some(&MessageSendEvent::SendFundingLocked { ref node_id, ref msg }) = msg_events.get(0) { + idx += 1; + assert_eq!(*node_id, $dst_node.node.get_our_node_id()); + Some(msg.clone()) + } else { + None + }; + + let mut revoke_and_ack = None; + let mut commitment_update = None; + let order = if let Some(ev) = msg_events.get(idx) { + idx += 1; + match ev { + &MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => { + assert_eq!(*node_id, $dst_node.node.get_our_node_id()); + revoke_and_ack = Some(msg.clone()); + RAACommitmentOrder::RevokeAndACKFirst + }, + &MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => { + assert_eq!(*node_id, $dst_node.node.get_our_node_id()); + commitment_update = Some(updates.clone()); + RAACommitmentOrder::CommitmentFirst + }, + _ => panic!("Unexpected event"), + } + } else { + RAACommitmentOrder::CommitmentFirst + }; + + if let Some(ev) = msg_events.get(idx) { + match ev { + &MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => { + assert_eq!(*node_id, $dst_node.node.get_our_node_id()); + assert!(revoke_and_ack.is_none()); + revoke_and_ack = Some(msg.clone()); + }, + &MessageSendEvent::UpdateHTLCs { ref node_id, ref updates } => { + assert_eq!(*node_id, $dst_node.node.get_our_node_id()); + assert!(commitment_update.is_none()); + commitment_update = Some(updates.clone()); + }, + _ => panic!("Unexpected event"), + } + } + + (funding_locked, revoke_and_ack, commitment_update, order) + } + } + } + /// pending_htlc_adds includes both the holding cell and in-flight update_add_htlcs, whereas /// for claims/fails they are separated out. fn reconnect_nodes(node_a: &Node, node_b: &Node, pre_all_htlcs: bool, pending_htlc_adds: (i64, i64), pending_htlc_claims: (usize, usize), pending_cell_htlc_claims: (usize, usize), pending_cell_htlc_fails: (usize, usize), pending_raa: (bool, bool)) { @@ -5163,7 +5260,8 @@ mod tests { 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()); + node_b.node.handle_channel_reestablish(&node_a.node.get_our_node_id(), &msg).unwrap(); + resp_1.push(handle_chan_reestablish_msgs!(node_b, node_a)); } if pending_cell_htlc_claims.0 != 0 || pending_cell_htlc_fails.0 != 0 { check_added_monitors!(node_b, 1); @@ -5173,7 +5271,8 @@ mod tests { 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()); + node_a.node.handle_channel_reestablish(&node_b.node.get_our_node_id(), &msg).unwrap(); + resp_2.push(handle_chan_reestablish_msgs!(node_a, node_b)); } if pending_cell_htlc_claims.1 != 0 || pending_cell_htlc_fails.1 != 0 { check_added_monitors!(node_a, 1); @@ -5199,7 +5298,7 @@ mod tests { assert!(chan_msgs.0.is_none()); } if pending_raa.0 { - assert!(chan_msgs.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst); + assert!(chan_msgs.3 == RAACommitmentOrder::RevokeAndACKFirst); node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap(); assert!(node_a.node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(node_a, 1); @@ -5256,7 +5355,7 @@ mod tests { assert!(chan_msgs.0.is_none()); } if pending_raa.1 { - assert!(chan_msgs.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst); + assert!(chan_msgs.3 == RAACommitmentOrder::RevokeAndACKFirst); node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &chan_msgs.1.unwrap()).unwrap(); assert!(node_b.node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(node_b, 1); @@ -5660,8 +5759,10 @@ mod tests { let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); assert_eq!(reestablish_2.len(), 1); - let as_resp = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); - let bs_resp = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap(); + nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); + let as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]); + nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap(); + let bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]); assert!(as_resp.0.is_none()); assert!(bs_resp.0.is_none()); @@ -5669,7 +5770,7 @@ mod tests { assert!(bs_resp.1.is_none()); assert!(bs_resp.2.is_none()); - assert!(as_resp.3 == msgs::RAACommitmentOrder::CommitmentFirst); + assert!(as_resp.3 == RAACommitmentOrder::CommitmentFirst); assert_eq!(as_resp.2.as_ref().unwrap().update_add_htlcs.len(), 1); assert!(as_resp.2.as_ref().unwrap().update_fulfill_htlcs.is_empty()); @@ -5946,8 +6047,10 @@ mod tests { let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); assert_eq!(reestablish_2.len(), 1); - let as_resp = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); - let bs_resp = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap(); + nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); + let as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]); + nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap(); + let bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]); assert!(as_resp.0.is_none()); assert!(bs_resp.0.is_none()); @@ -5964,10 +6067,12 @@ mod tests { let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); assert_eq!(reestablish_2.len(), 1); - let mut as_resp = nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); + nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); check_added_monitors!(nodes[0], 0); - let mut bs_resp = nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap(); + let mut as_resp = handle_chan_reestablish_msgs!(nodes[0], nodes[1]); + nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]).unwrap(); check_added_monitors!(nodes[1], 0); + let mut bs_resp = handle_chan_reestablish_msgs!(nodes[1], nodes[0]); assert!(as_resp.0.is_none()); assert!(bs_resp.0.is_none()); @@ -5978,7 +6083,7 @@ mod tests { assert!(as_resp.1.is_some()); assert!(as_resp.2.is_some()); - assert!(as_resp.3 == msgs::RAACommitmentOrder::CommitmentFirst); + assert!(as_resp.3 == RAACommitmentOrder::CommitmentFirst); } else { assert!(bs_resp.2.as_ref().unwrap().update_add_htlcs.is_empty()); assert!(bs_resp.2.as_ref().unwrap().update_fail_htlcs.is_empty()); @@ -6087,7 +6192,7 @@ mod tests { assert!(as_resp.2.unwrap() == as_commitment_update); assert!(bs_resp.2.is_none()); - assert!(as_resp.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst); + assert!(as_resp.3 == RAACommitmentOrder::RevokeAndACKFirst); } handle_initial_raa!(); @@ -6113,7 +6218,7 @@ mod tests { assert!(as_resp.2.is_none()); assert!(bs_resp.2.unwrap() == bs_second_commitment_update); - assert!(bs_resp.3 == msgs::RAACommitmentOrder::RevokeAndACKFirst); + assert!(bs_resp.3 == RAACommitmentOrder::RevokeAndACKFirst); } handle_bs_raa!(); diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index fb0863719ba..6335dc06867 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -511,18 +511,6 @@ pub enum HTLCFailChannelUpdate { } } -/// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should -/// be sent in the order they appear in the return value, however sometimes the order needs to be -/// variable at runtime (eg handle_channel_reestablish needs to re-send messages in the order they -/// were originally sent). In those cases, this enum is also returned. -#[derive(Clone, PartialEq)] -pub enum RAACommitmentOrder { - /// Send the CommitmentUpdate messages first - CommitmentFirst, - /// Send the RevokeAndACK message first - RevokeAndACKFirst, -} - /// A trait to describe an object which can receive channel messages. /// /// Messages MAY be called in parallel when they originate from different their_node_ids, however @@ -577,7 +565,7 @@ pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Syn /// Handle a peer reconnecting, possibly generating channel_reestablish message(s). fn peer_connected(&self, their_node_id: &PublicKey) -> Vec; /// Handle an incoming channel_reestablish message from the given peer. - fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &ChannelReestablish) -> Result<(Option, Option, Option, RAACommitmentOrder), HandleError>; + fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &ChannelReestablish) -> Result<(), HandleError>; // Error: /// Handle an incoming error message from the given peer. diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 76533416736..5c7e23c6bea 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -619,45 +619,7 @@ impl PeerManager { }, 136 => { let msg = try_potential_decodeerror!(msgs::ChannelReestablish::read(&mut reader)); - let (funding_locked, revoke_and_ack, commitment_update, order) = try_potential_handleerror!(self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg)); - if let Some(lock_msg) = funding_locked { - encode_and_send_msg!(lock_msg, 36); - } - macro_rules! handle_raa { () => { - if let Some(revoke_msg) = revoke_and_ack { - encode_and_send_msg!(revoke_msg, 133); - } - } } - macro_rules! handle_cu { () => { - match commitment_update { - Some(resps) => { - for resp in resps.update_add_htlcs { - encode_and_send_msg!(resp, 128); - } - for resp in resps.update_fulfill_htlcs { - encode_and_send_msg!(resp, 130); - } - for resp in resps.update_fail_htlcs { - encode_and_send_msg!(resp, 131); - } - if let Some(resp) = resps.update_fee { - encode_and_send_msg!(resp, 134); - } - encode_and_send_msg!(resps.commitment_signed, 132); - }, - None => {}, - } - } } - match order { - msgs::RAACommitmentOrder::RevokeAndACKFirst => { - handle_raa!(); - handle_cu!(); - }, - msgs::RAACommitmentOrder::CommitmentFirst => { - handle_cu!(); - handle_raa!(); - }, - } + try_potential_handleerror!(self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg)); }, // Routing control: diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index 04d6dbeb400..d20908a3808 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -131,7 +131,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler { fn handle_announcement_signatures(&self, _their_node_id: &PublicKey, _msg: &msgs::AnnouncementSignatures) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } - fn handle_channel_reestablish(&self, _their_node_id: &PublicKey, _msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option, msgs::RAACommitmentOrder), HandleError> { + fn handle_channel_reestablish(&self, _their_node_id: &PublicKey, _msg: &msgs::ChannelReestablish) -> Result<(), HandleError> { Err(HandleError { err: "", action: None }) } fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {} From 249aa7755038172279781caf47f681c01843dc73 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 20 Oct 2018 17:50:34 -0400 Subject: [PATCH 14/15] Send channel_reestablish out-of-band to ensure ordered deliver --- src/ln/channelmanager.rs | 54 ++++++++++++++++++++++++++++++---------- src/ln/msgs.rs | 6 ++--- src/ln/peer_handler.rs | 14 ++++++++--- src/util/events.rs | 7 ++++++ src/util/test_utils.rs | 4 +-- 5 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 7d11fe987f2..c5356e29178 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -2676,9 +2676,10 @@ impl ChannelMessageHandler for ChannelManager { } } - fn peer_connected(&self, their_node_id: &PublicKey) -> Vec { - let mut res = Vec::new(); - let mut channel_state = self.channel_state.lock().unwrap(); + fn peer_connected(&self, their_node_id: &PublicKey) { + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); + let pending_msg_events = channel_state.pending_msg_events; channel_state.by_id.retain(|_, chan| { if chan.get_their_node_id() == *their_node_id { if !chan.have_received_message() { @@ -2688,13 +2689,15 @@ impl ChannelMessageHandler for ChannelManager { // drop it. false } else { - res.push(chan.get_channel_reestablish()); + pending_msg_events.push(events::MessageSendEvent::SendChannelReestablish { + node_id: chan.get_their_node_id(), + msg: 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) { @@ -5197,6 +5200,23 @@ mod tests { assert_eq!(channel_state.short_to_id.len(), 0); } + macro_rules! get_chan_reestablish_msgs { + ($src_node: expr, $dst_node: expr) => { + { + let mut res = Vec::with_capacity(1); + for msg in $src_node.node.get_and_clear_pending_msg_events() { + if let MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } = msg { + assert_eq!(*node_id, $dst_node.node.get_our_node_id()); + res.push(msg.clone()); + } else { + panic!("Unexpected event") + } + } + res + } + } + } + macro_rules! handle_chan_reestablish_msgs { ($src_node: expr, $dst_node: expr) => { { @@ -5255,8 +5275,10 @@ mod tests { /// pending_htlc_adds includes both the holding cell and in-flight update_add_htlcs, whereas /// for claims/fails they are separated out. fn reconnect_nodes(node_a: &Node, node_b: &Node, pre_all_htlcs: bool, pending_htlc_adds: (i64, i64), pending_htlc_claims: (usize, usize), pending_cell_htlc_claims: (usize, usize), pending_cell_htlc_fails: (usize, usize), pending_raa: (bool, bool)) { - 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()); + node_a.node.peer_connected(&node_b.node.get_our_node_id()); + let reestablish_1 = get_chan_reestablish_msgs!(node_a, node_b); + node_b.node.peer_connected(&node_a.node.get_our_node_id()); + let reestablish_2 = get_chan_reestablish_msgs!(node_b, node_a); let mut resp_1 = Vec::new(); for msg in reestablish_1 { @@ -5754,9 +5776,11 @@ mod tests { 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); - let reestablish_1 = nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id()); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id()); + let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); assert_eq!(reestablish_1.len(), 1); - let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); + let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); assert_eq!(reestablish_2.len(), 1); nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); @@ -6042,9 +6066,11 @@ mod tests { 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); - let reestablish_1 = nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id()); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id()); + let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); assert_eq!(reestablish_1.len(), 1); - let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); + let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); assert_eq!(reestablish_2.len(), 1); nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); @@ -6062,9 +6088,11 @@ mod tests { assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - let reestablish_1 = nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id()); + nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id()); + let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]); assert_eq!(reestablish_1.len(), 1); - let reestablish_2 = nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); + nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id()); + let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]); assert_eq!(reestablish_2.len(), 1); nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]).unwrap(); diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index 6335dc06867..110e2f336ad 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -308,14 +308,14 @@ pub struct UpdateFee { pub(crate) feerate_per_kw: u32, } -#[derive(PartialEq)] +#[derive(PartialEq, Clone)] pub(crate) struct DataLossProtect { pub(crate) your_last_per_commitment_secret: [u8; 32], pub(crate) my_current_per_commitment_point: PublicKey, } /// A channel_reestablish message to be sent or received from a peer -#[derive(PartialEq)] +#[derive(PartialEq, Clone)] pub struct ChannelReestablish { pub(crate) channel_id: [u8; 32], pub(crate) next_local_commitment_number: u64, @@ -563,7 +563,7 @@ pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Syn fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool); /// Handle a peer reconnecting, possibly generating channel_reestablish message(s). - fn peer_connected(&self, their_node_id: &PublicKey) -> Vec; + fn peer_connected(&self, their_node_id: &PublicKey); /// Handle an incoming channel_reestablish message from the given peer. fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &ChannelReestablish) -> Result<(), HandleError>; diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 5c7e23c6bea..4471ea00258 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -520,9 +520,7 @@ impl PeerManager { }, 16); } - for msg in self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap()) { - encode_and_send_msg!(msg, 136); - } + self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap()); }, 17 => { let msg = try_potential_decodeerror!(msgs::ErrorMessage::read(&mut reader)); @@ -834,6 +832,16 @@ impl PeerManager { peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 38))); Self::do_attempt_write_data(&mut descriptor, peer); }, + MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } => { + log_trace!(self, "Handling SendChannelReestablish event in peer_handler for node {} for channel {}", + log_pubkey!(node_id), + log_bytes!(msg.channel_id)); + let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { + //TODO: Do whatever we're gonna do for handling dropped messages + }); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 136))); + Self::do_attempt_write_data(&mut descriptor, peer); + }, MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { log_trace!(self, "Handling BroadcastChannelAnnouncement event in peer_handler for short channel id {}", msg.contents.short_channel_id); if self.message_handler.route_handler.handle_channel_announcement(msg).is_ok() && self.message_handler.route_handler.handle_channel_update(update_msg).is_ok() { diff --git a/src/util/events.rs b/src/util/events.rs index cfe16151a22..37cee2eded4 100644 --- a/src/util/events.rs +++ b/src/util/events.rs @@ -175,6 +175,13 @@ pub enum MessageSendEvent { /// The message which should be sent. msg: msgs::Shutdown, }, + /// Used to indicate that a channel_reestablish message should be sent to the peer with the given node_id. + SendChannelReestablish { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::ChannelReestablish, + }, /// Used to indicate that a channel_announcement and channel_update should be broadcast to all /// peers (except the peer with node_id either msg.contents.node_id_1 or msg.contents.node_id_2). BroadcastChannelAnnouncement { diff --git a/src/util/test_utils.rs b/src/util/test_utils.rs index d20908a3808..4fa29fd8e95 100644 --- a/src/util/test_utils.rs +++ b/src/util/test_utils.rs @@ -135,9 +135,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler { Err(HandleError { err: "", action: None }) } fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {} - fn peer_connected(&self, _their_node_id: &PublicKey) -> Vec { - Vec::new() - } + fn peer_connected(&self, _their_node_id: &PublicKey) {} fn handle_error(&self, _their_node_id: &PublicKey, _msg: &msgs::ErrorMessage) {} } From 294ad325233557c2f2faf8e631737e7d7a696cab Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 20 Oct 2018 18:17:19 -0400 Subject: [PATCH 15/15] Avoid reentrancy of send_data from PeerHandler::read_bytes. This greatly simplifies clients of PeerHandler, and because almost all response messages have already been moved to process_events this doesn't change much effeciency-wise. --- src/ln/peer_handler.rs | 47 ++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 4471ea00258..d868b0758bd 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -15,7 +15,7 @@ use util::byte_utils; use util::events::{MessageSendEvent}; use util::logger::Logger; -use std::collections::{HashMap,hash_map,LinkedList}; +use std::collections::{HashMap,hash_map,HashSet,LinkedList}; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::{cmp,error,hash,fmt}; @@ -106,17 +106,22 @@ struct Peer { struct PeerHolder { peers: HashMap, + /// Added to by do_read_event for cases where we pushed a message onto the send buffer but + /// didn't call do_attempt_write_data to avoid reentrancy. Cleared in process_events() + peers_needing_send: HashSet, /// Only add to this set when noise completes: node_id_to_descriptor: HashMap, } struct MutPeerHolder<'a, Descriptor: SocketDescriptor + 'a> { peers: &'a mut HashMap, + peers_needing_send: &'a mut HashSet, node_id_to_descriptor: &'a mut HashMap, } impl PeerHolder { fn borrow_parts(&mut self) -> MutPeerHolder { MutPeerHolder { peers: &mut self.peers, + peers_needing_send: &mut self.peers_needing_send, node_id_to_descriptor: &mut self.node_id_to_descriptor, } } @@ -162,7 +167,11 @@ impl PeerManager { pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, logger: Arc) -> PeerManager { PeerManager { message_handler: message_handler, - peers: Mutex::new(PeerHolder { peers: HashMap::new(), node_id_to_descriptor: HashMap::new() }), + peers: Mutex::new(PeerHolder { + peers: HashMap::new(), + peers_needing_send: HashSet::new(), + node_id_to_descriptor: HashMap::new() + }), our_node_secret: our_node_secret, initial_syncs_sent: AtomicUsize::new(0), logger, @@ -188,7 +197,7 @@ impl PeerManager { /// Note that if an Err is returned here you MUST NOT call disconnect_event for the new /// descriptor but must disconnect the connection immediately. /// - /// Returns some bytes to send to the remote node. + /// Returns a small number of bytes to send to the remote node (currently always 50). /// /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. @@ -298,16 +307,12 @@ impl PeerManager { /// /// May return an Err to indicate that the connection should be closed. /// - /// Will very likely call send_data on the descriptor passed in (or a descriptor handed into - /// new_*_connection) before returning. Thus, be very careful with reentrancy issues! The - /// invariants around calling write_event in case a write did not fully complete must still - /// hold. Note that this function will often call send_data on many peers before returning, not - /// just this peer! + /// Will *not* call back into send_data on any descriptors to avoid reentrancy complexity. + /// Thus, however, you almost certainly want to call process_events() after any read_event to + /// generate send_data calls to handle responses. /// /// If Ok(true) is returned, further read_events should not be triggered until a write_event on - /// this file descriptor has resume_read set (preventing DoS issues in the send buffer). Note - /// that this must be true even if a send_data call with resume_read=true was made during the - /// course of this function! + /// this file descriptor has resume_read set (preventing DoS issues in the send buffer). /// /// Panics if the descriptor was not previously registered in a new_*_connection event. pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec) -> Result { @@ -347,6 +352,7 @@ impl PeerManager { { log_trace!(self, "Encoding and sending message of type {} to {}", $msg_code, log_pubkey!(peer.their_node_id.unwrap())); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!($msg, $msg_code)[..])); + peers.peers_needing_send.insert(peer_descriptor.clone()); } } } @@ -670,13 +676,12 @@ impl PeerManager { pause_read }; - self.process_events(); - Ok(pause_read) } - /// Checks for any events generated by our handlers and processes them. May be needed after eg - /// calls to ChannelManager::process_pending_htlc_forward. + /// Checks for any events generated by our handlers and processes them. Includes sending most + /// response messages as well as messages generated by calls to handler functions directly (eg + /// functions like ChannelManager::process_pending_htlc_forward or send_payment). pub fn process_events(&self) { { // TODO: There are some DoS attacks here where you can flood someone's outbound send @@ -684,7 +689,8 @@ impl PeerManager { // drop optional-ish messages when send buffers get full! let mut events_generated = self.message_handler.chan_handler.get_and_clear_pending_msg_events(); - let mut peers = self.peers.lock().unwrap(); + let mut peers_lock = self.peers.lock().unwrap(); + let peers = peers_lock.borrow_parts(); for event in events_generated.drain(..) { macro_rules! get_peer_for_forwarding { ($node_id: expr, $handle_no_such_peer: block) => { @@ -888,6 +894,7 @@ impl PeerManager { match *action { msgs::ErrorAction::DisconnectPeer { ref msg } => { if let Some(mut descriptor) = peers.node_id_to_descriptor.remove(node_id) { + peers.peers_needing_send.remove(&descriptor); if let Some(mut peer) = peers.peers.remove(&descriptor) { if let Some(ref msg) = *msg { log_trace!(self, "Handling DisconnectPeer HandleError event in peer_handler for node {} with message {}", @@ -923,6 +930,13 @@ impl PeerManager { } } } + + for mut descriptor in peers.peers_needing_send.drain() { + match peers.peers.get_mut(&descriptor) { + Some(peer) => Self::do_attempt_write_data(&mut descriptor, peer), + None => panic!("Inconsistent peers set state!"), + } + } } } @@ -938,6 +952,7 @@ impl PeerManager { fn disconnect_event_internal(&self, descriptor: &Descriptor, no_connection_possible: bool) { let mut peers = self.peers.lock().unwrap(); + peers.peers_needing_send.remove(descriptor); let peer_option = peers.peers.remove(descriptor); match peer_option { None => panic!("Descriptor for disconnect_event is not already known to PeerManager"),