From eb6a37144a2bf79d0db3793a428fc04454d4b75b Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Tue, 11 Feb 2020 20:36:34 -0800 Subject: [PATCH 01/27] build scaffold for handshake module substitution support --- lightning/src/ln/mod.rs | 4 +- lightning/src/ln/peers/chacha.rs | 34 ++ lightning/src/ln/peers/conduit.rs | 173 +++++++++ lightning/src/ln/peers/handshake/acts.rs | 33 ++ lightning/src/ln/peers/handshake/hash.rs | 25 ++ lightning/src/ln/peers/handshake/mod.rs | 398 +++++++++++++++++++++ lightning/src/ln/peers/handshake/states.rs | 30 ++ lightning/src/ln/peers/handshake/tests.rs | 26 ++ lightning/src/ln/peers/hkdf.rs | 18 + lightning/src/ln/peers/mod.rs | 4 + 10 files changed, 744 insertions(+), 1 deletion(-) create mode 100644 lightning/src/ln/peers/chacha.rs create mode 100644 lightning/src/ln/peers/conduit.rs create mode 100644 lightning/src/ln/peers/handshake/acts.rs create mode 100644 lightning/src/ln/peers/handshake/hash.rs create mode 100644 lightning/src/ln/peers/handshake/mod.rs create mode 100644 lightning/src/ln/peers/handshake/states.rs create mode 100644 lightning/src/ln/peers/handshake/tests.rs create mode 100644 lightning/src/ln/peers/hkdf.rs create mode 100644 lightning/src/ln/peers/mod.rs diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index 9a2a90fd4fd..8ff78e02077 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -13,6 +13,7 @@ pub mod channelmanager; pub mod channelmonitor; pub mod msgs; pub mod router; +pub mod peers; pub mod peer_handler; pub mod chan_utils; pub mod features; @@ -27,7 +28,8 @@ mod onion_utils; mod wire; #[cfg(test)] -#[macro_use] mod functional_test_utils; +#[macro_use] +mod functional_test_utils; #[cfg(test)] mod functional_tests; #[cfg(test)] diff --git a/lightning/src/ln/peers/chacha.rs b/lightning/src/ln/peers/chacha.rs new file mode 100644 index 00000000000..4b29b924388 --- /dev/null +++ b/lightning/src/ln/peers/chacha.rs @@ -0,0 +1,34 @@ +use util::chacha20poly1305rfc::ChaCha20Poly1305RFC; + +pub fn encrypt(key: &[u8], nonce: u64, associated_data: &[u8], plaintext: &[u8]) -> Vec { + let mut nonce_bytes = [0; 12]; + nonce_bytes[4..].copy_from_slice(&nonce.to_le_bytes()); + + let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce_bytes, associated_data); + let mut ciphertext = vec![0u8; plaintext.len()]; + let mut authentication_tag = [0u8; 16]; + chacha.encrypt(plaintext, &mut ciphertext, &mut authentication_tag); + + let mut tagged_ciphertext = ciphertext; + tagged_ciphertext.extend_from_slice(&authentication_tag); + tagged_ciphertext +} + + +pub fn decrypt(key: &[u8], nonce: u64, associated_data: &[u8], tagged_ciphertext: &[u8]) -> Result, String> { + let mut nonce_bytes = [0; 12]; + nonce_bytes[4..].copy_from_slice(&nonce.to_le_bytes()); + + let length = tagged_ciphertext.len(); + let ciphertext = &tagged_ciphertext[0..length - 16]; + let authentication_tag = &tagged_ciphertext[length - 16..length]; + + let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce_bytes, associated_data); + let mut plaintext = vec![0u8; length - 16]; + let success = chacha.decrypt(ciphertext, &mut plaintext, authentication_tag); + if success { + Ok(plaintext.to_vec()) + } else { + Err("invalid hmac".to_string()) + } +} diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs new file mode 100644 index 00000000000..fe1c5adcb90 --- /dev/null +++ b/lightning/src/ln/peers/conduit.rs @@ -0,0 +1,173 @@ +use ln::peers::{chacha, hkdf}; + +/// Returned after a successful handshake to encrypt and decrypt communication with peer nodes +pub struct Conduit { + pub(crate) sending_key: [u8; 32], + pub(crate) receiving_key: [u8; 32], + + pub(crate) sending_chaining_key: [u8; 32], + pub(crate) receiving_chaining_key: [u8; 32], + + pub(crate) receiving_nonce: u32, + pub(crate) sending_nonce: u32, + + pub(super) read_buffer: Option>, +} + +impl Conduit { + pub fn encrypt(&mut self, buffer: &[u8]) -> Vec { + let length = buffer.len() as u16; + let length_bytes = length.to_be_bytes(); + + let encrypted_length = chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes); + self.increment_sending_nonce(); + + let encrypted_message = chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], buffer); + self.increment_sending_nonce(); + + let mut ciphertext = encrypted_length; + ciphertext.extend_from_slice(&encrypted_message); + ciphertext + } + + pub(super) fn read(&mut self, data: &[u8]) { + let mut read_buffer = if let Some(buffer) = self.read_buffer.take() { + buffer + } else { + Vec::new() + }; + + read_buffer.extend_from_slice(data); + self.read_buffer = Some(read_buffer); + } + + /// Add newly received data from the peer node to the buffer and decrypt all possible messages + pub fn decrypt_message_stream(&mut self, new_data: Option<&[u8]>) -> Vec> { + let mut read_buffer = if let Some(buffer) = self.read_buffer.take() { + buffer + } else { + Vec::new() + }; + + if let Some(data) = new_data { + read_buffer.extend_from_slice(data); + } + + let mut messages = Vec::new(); + + loop { + // todo: find way that won't require cloning the entire buffer + let (current_message, offset) = self.decrypt(&read_buffer[..]); + if offset == 0 { + break; + } + + read_buffer.drain(0..offset); + + if let Some(message) = current_message { + messages.push(message); + } else { + break; + } + } + + self.read_buffer = Some(read_buffer); + + messages + } + + /// Decrypt a single message. Buffer is an undelimited amount of bytes + fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { // the response slice should have the same lifetime as the argument. It's the slice data is read from + if buffer.len() < 18 { + return (None, 0); + } + + let encrypted_length = &buffer[0..18]; // todo: abort if too short + let length_vec = chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap(); + let mut length_bytes = [0u8; 2]; + length_bytes.copy_from_slice(length_vec.as_slice()); + let message_length = u16::from_be_bytes(length_bytes) as usize; + + let message_end_index = message_length + 18; // todo: abort if too short + if buffer.len() < message_end_index { + return (None, 0); + } + + let encrypted_message = &buffer[18..message_end_index]; + + self.increment_receiving_nonce(); + + let message = chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_message).unwrap(); + + self.increment_receiving_nonce(); + + (Some(message), message_end_index) + } + + fn increment_sending_nonce(&mut self) { + Self::increment_nonce(&mut self.sending_nonce, &mut self.sending_chaining_key, &mut self.sending_key); + } + + fn increment_receiving_nonce(&mut self) { + Self::increment_nonce(&mut self.receiving_nonce, &mut self.receiving_chaining_key, &mut self.receiving_key); + } + + fn increment_nonce(nonce: &mut u32, chaining_key: &mut [u8; 32], key: &mut [u8; 32]) { + *nonce += 1; + if *nonce == 1000 { + Self::rotate_key(chaining_key, key); + *nonce = 0; + } + } + + fn rotate_key(chaining_key: &mut [u8; 32], key: &mut [u8; 32]) { + let (new_chaining_key, new_key) = hkdf::derive(chaining_key, key); + chaining_key.copy_from_slice(&new_chaining_key); + key.copy_from_slice(&new_key); + } +} + +#[cfg(test)] +mod tests { + use ln::peers::conduit::Conduit; + + #[test] + fn test_chaining() { + let chaining_key_vec = hex::decode("919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01").unwrap(); + let mut chaining_key = [0u8; 32]; + chaining_key.copy_from_slice(&chaining_key_vec); + + let sending_key_vec = hex::decode("969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9").unwrap(); + let mut sending_key = [0u8; 32]; + sending_key.copy_from_slice(&sending_key_vec); + + let receiving_key_vec = hex::decode("bb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442").unwrap(); + let mut receiving_key = [0u8; 32]; + receiving_key.copy_from_slice(&receiving_key_vec); + + let mut connected_peer = Conduit { + sending_key, + receiving_key, + sending_chaining_key: chaining_key, + receiving_chaining_key: chaining_key, + sending_nonce: 0, + receiving_nonce: 0, + read_buffer: None, + }; + + let message = hex::decode("68656c6c6f").unwrap(); + let mut encrypted_messages: Vec> = Vec::new(); + + for _ in 0..1002 { + let encrypted_message = connected_peer.encrypt(&message); + encrypted_messages.push(encrypted_message); + } + + assert_eq!(encrypted_messages[0], hex::decode("cf2b30ddf0cf3f80e7c35a6e6730b59fe802473180f396d88a8fb0db8cbcf25d2f214cf9ea1d95").unwrap()); + assert_eq!(encrypted_messages[1], hex::decode("72887022101f0b6753e0c7de21657d35a4cb2a1f5cde2650528bbc8f837d0f0d7ad833b1a256a1").unwrap()); + assert_eq!(encrypted_messages[500], hex::decode("178cb9d7387190fa34db9c2d50027d21793c9bc2d40b1e14dcf30ebeeeb220f48364f7a4c68bf8").unwrap()); + assert_eq!(encrypted_messages[501], hex::decode("1b186c57d44eb6de4c057c49940d79bb838a145cb528d6e8fd26dbe50a60ca2c104b56b60e45bd").unwrap()); + assert_eq!(encrypted_messages[1000], hex::decode("4a2f3cc3b5e78ddb83dcb426d9863d9d9a723b0337c89dd0b005d89f8d3c05c52b76b29b740f09").unwrap()); + assert_eq!(encrypted_messages[1001], hex::decode("2ecd8c8a5629d0d02ab457a0fdd0f7b90a192cd46be5ecb6ca570bfc5e268338b1a16cf4ef2d36").unwrap()); + } +} \ No newline at end of file diff --git a/lightning/src/ln/peers/handshake/acts.rs b/lightning/src/ln/peers/handshake/acts.rs new file mode 100644 index 00000000000..1a42e5dd430 --- /dev/null +++ b/lightning/src/ln/peers/handshake/acts.rs @@ -0,0 +1,33 @@ +pub struct ActOne( + pub(super) [u8; 50] +); + +pub struct ActTwo( + pub(super) [u8; 50] +); + +pub struct ActThree( + pub(super) [u8; 66] +); + +pub enum Act { + One(ActOne), + Two(ActTwo), + Three(ActThree), +} + +impl Act { + pub fn serialize(&self) -> Vec { + match self { + Act::One(act) => { + act.0.to_vec() + } + Act::Two(act) => { + act.0.to_vec() + } + Act::Three(act) => { + act.0.to_vec() + } + } + } +} \ No newline at end of file diff --git a/lightning/src/ln/peers/handshake/hash.rs b/lightning/src/ln/peers/handshake/hash.rs new file mode 100644 index 00000000000..0beef40fd93 --- /dev/null +++ b/lightning/src/ln/peers/handshake/hash.rs @@ -0,0 +1,25 @@ +use bitcoin_hashes::{Hash, HashEngine}; +use bitcoin_hashes::sha256::Hash as Sha256; + +pub(crate) struct HandshakeHash { + pub(super) value: [u8; 32] +} + +impl HandshakeHash { + pub(super) fn new(first_input: &[u8]) -> Self { + let mut hash = Self { + value: [0; 32] + }; + let mut sha = Sha256::engine(); + sha.input(first_input); + hash.value = Sha256::from_engine(sha).into_inner(); + hash + } + + pub(super) fn update(&mut self, input: &[u8]) { + let mut sha = Sha256::engine(); + sha.input(self.value.as_ref()); + sha.input(input); + self.value = Sha256::from_engine(sha).into_inner(); + } +} \ No newline at end of file diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs new file mode 100644 index 00000000000..087f7ecfa73 --- /dev/null +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -0,0 +1,398 @@ +use bitcoin_hashes::{Hash, HashEngine}; +use bitcoin_hashes::sha256::Hash as Sha256; +use rand::{Rng, thread_rng}; +use secp256k1::{PublicKey, SecretKey}; + +use ln::peers::{chacha, hkdf}; +use ln::peers::conduit::Conduit; +use ln::peers::handshake::acts::{ActOne, ActThree, ActTwo}; +use ln::peers::handshake::hash::HandshakeHash; +use ln::peers::handshake::states::{ActOneExpectation, ActThreeExpectation, ActTwoExpectation, HandshakeState}; + +mod acts; +mod hash; +mod states; +mod tests; + +pub struct PeerHandshake { + state: Option, + private_key: SecretKey, + + preset_ephemeral_private_key: Option, + read_buffer: Vec, +} + +impl PeerHandshake { + pub fn new(private_key: &SecretKey, ephemeral_private_key: Option<&SecretKey>) -> Self { + let preset_ephemeral_private_key = if let Some(key) = ephemeral_private_key { + // deref and clone + Some((*key).clone()) + } else { + None + }; + + let handshake = PeerHandshake { + state: Some(HandshakeState::Blank), + private_key: (*private_key).clone(), + preset_ephemeral_private_key, + read_buffer: Vec::new(), + }; + handshake + } + + pub fn make_inbound(&mut self) { + let public_key = Self::private_key_to_public_key(&self.private_key); + let (hash, chaining_key) = Self::initialize_state(&public_key); + self.state = Some(HandshakeState::AwaitingActOne(ActOneExpectation { + hash, + chaining_key, + })) + } + + fn initialize_state(public_key: &PublicKey) -> (HandshakeHash, [u8; 32]) { + // do the proper initialization + let protocol_name = b"Noise_XK_secp256k1_ChaChaPoly_SHA256"; + let prologue = b"lightning"; + + let mut sha = Sha256::engine(); + sha.input(protocol_name); + let chaining_key = Sha256::from_engine(sha).into_inner(); + + let mut initial_hash_preimage = chaining_key.to_vec(); + initial_hash_preimage.extend_from_slice(prologue.as_ref()); + + let mut hash = HandshakeHash::new(initial_hash_preimage.as_slice()); + hash.update(&public_key.serialize()); + + (hash, chaining_key) // hash, chaining_key + } + + /// Process act dynamically + /// The role must be set before this method can be called + pub fn process_act(&mut self, input: &[u8], remote_public_key: Option<&PublicKey>) -> Result<(Vec, Option, Option), String> { + let mut response: Vec = Vec::new(); + let mut connected_peer = None; + let mut remote_pubkey = None; + + self.read_buffer.extend_from_slice(input); + let read_buffer_length = self.read_buffer.len(); + + match &self.state { + Some(HandshakeState::Blank) => { + let remote_public_key = remote_public_key.ok_or("Call make_initiator() first")?; + let ephemeral_private_key = self.obtain_ephemeral_private_key(); + + let act_one = self.initiate(&ephemeral_private_key, &remote_public_key)?; + response = act_one.0.to_vec(); + } + Some(HandshakeState::AwaitingActOne(_)) => { + let act_length = 50; + if read_buffer_length < act_length { + return Err("need at least 50 bytes".to_string()); + } + + let mut act_one_buffer = [0u8; 50]; + act_one_buffer.copy_from_slice(&self.read_buffer[..act_length]); + self.read_buffer.drain(..act_length); + + let ephemeral_private_key = self.obtain_ephemeral_private_key(); + + let act_two = self.process_act_one(ActOne(act_one_buffer), &ephemeral_private_key)?; + response = act_two.0.to_vec(); + } + Some(HandshakeState::AwaitingActTwo(_)) => { + let act_length = 50; + if read_buffer_length < act_length { + return Err("need at least 50 bytes".to_string()); + } + + let mut act_two_buffer = [0u8; 50]; + act_two_buffer.copy_from_slice(&self.read_buffer[..act_length]); + self.read_buffer.drain(..act_length); + + let (act_three, mut conduit) = self.process_act_two(ActTwo(act_two_buffer))?; + + if self.read_buffer.len() > 0 { // have we received more data still? + conduit.read(&self.read_buffer[..]); + self.read_buffer.drain(..); + } + + response = act_three.0.to_vec(); + connected_peer = Some(conduit); + } + Some(HandshakeState::AwaitingActThree(_)) => { + let act_length = 66; + if read_buffer_length < act_length { + return Err("need at least 50 bytes".to_string()); + } + + let mut act_three_buffer = [0u8; 66]; + act_three_buffer.copy_from_slice(&self.read_buffer[..act_length]); + self.read_buffer.drain(..act_length); + + let (public_key, mut conduit) = self.process_act_three(ActThree(act_three_buffer))?; + + if self.read_buffer.len() > 0 { // have we received more data still? + conduit.read(&self.read_buffer[..]); + self.read_buffer.drain(..); + } + + connected_peer = Some(conduit); + remote_pubkey = Some(public_key); + } + _ => { + return Err("no acts left to process".to_string()); + } + }; + Ok((response, connected_peer, remote_pubkey)) + } + + pub fn initiate(&mut self, ephemeral_private_key: &SecretKey, remote_public_key: &PublicKey) -> Result { + if let Some(HandshakeState::Blank) = &self.state {} else { + return Err("incorrect state".to_string()); + } + + let (mut hash, chaining_key) = Self::initialize_state(&remote_public_key); + + // serialize act one + let (act_one, chaining_key, temporary_key) = self.calculate_act_message( + ephemeral_private_key, + remote_public_key, + chaining_key, + &mut hash, + ); + + self.state = Some(HandshakeState::AwaitingActTwo(ActTwoExpectation { + hash, + chaining_key, + temporary_key, + ephemeral_private_key: (*ephemeral_private_key).clone(), + })); + + Ok(ActOne(act_one)) + } + + pub(crate) fn process_act_one(&mut self, act: ActOne, ephemeral_private_key: &SecretKey) -> Result { + let state = self.state.take(); + let act_one_expectation = match state { + Some(HandshakeState::AwaitingActOne(act_state)) => act_state, + Some(HandshakeState::Blank) => { + // this can also be initiated from a blank state + // public key + let public_key = Self::private_key_to_public_key(&self.private_key); + let (hash, chaining_key) = Self::initialize_state(&public_key); + ActOneExpectation { + hash, + chaining_key, + } + } + _ => { + self.state = state; + return Err("unexpected state".to_string()); + } + }; + + let mut hash = act_one_expectation.hash; + let (remote_ephemeral_public_key, chaining_key, _) = self.process_act_message( + act.0, + &self.private_key, + act_one_expectation.chaining_key, + &mut hash, + )?; + + let (act_two, chaining_key, temporary_key) = self.calculate_act_message( + ephemeral_private_key, + &remote_ephemeral_public_key, + chaining_key, + &mut hash, + ); + + self.state = Some(HandshakeState::AwaitingActThree(ActThreeExpectation { + hash, + chaining_key, + temporary_key, + ephemeral_private_key: (*ephemeral_private_key).clone(), + remote_ephemeral_public_key, + })); + + Ok(ActTwo(act_two)) + } + + pub(crate) fn process_act_two(&mut self, act: ActTwo) -> Result<(ActThree, Conduit), String> { + let state = self.state.take(); + let act_two_expectation = match state { + Some(HandshakeState::AwaitingActTwo(act_state)) => act_state, + _ => { + self.state = state; + return Err("unexpected state".to_string()); + } + }; + + let mut hash = act_two_expectation.hash; + let (remote_ephemeral_public_key, chaining_key, temporary_key) = self.process_act_message( + act.0, + &act_two_expectation.ephemeral_private_key, + act_two_expectation.chaining_key, + &mut hash, + )?; + + self.state = Some(HandshakeState::Complete); + + // start serializing act three + + let static_public_key = Self::private_key_to_public_key(&self.private_key); + let tagged_encrypted_pubkey = chacha::encrypt(&temporary_key, 1, &hash.value, &static_public_key.serialize()); + hash.update(&tagged_encrypted_pubkey); + + let ecdh = Self::ecdh(&self.private_key, &remote_ephemeral_public_key); + let (chaining_key, temporary_key) = hkdf::derive(&chaining_key, &ecdh); + let authentication_tag = chacha::encrypt(&temporary_key, 0, &hash.value, &[0; 0]); + let (sending_key, receiving_key) = hkdf::derive(&chaining_key, &[0; 0]); + + let mut act_three_vec = [0u8].to_vec(); + act_three_vec.extend_from_slice(&tagged_encrypted_pubkey); + act_three_vec.extend_from_slice(authentication_tag.as_slice()); + let mut act_three = [0u8; 66]; + act_three.copy_from_slice(act_three_vec.as_slice()); + + let connected_peer = Conduit { + sending_key, + receiving_key, + sending_chaining_key: chaining_key, + receiving_chaining_key: chaining_key, + sending_nonce: 0, + receiving_nonce: 0, + read_buffer: None, + }; + Ok((ActThree(act_three), connected_peer)) + } + + pub(crate) fn process_act_three(&mut self, act: ActThree) -> Result<(PublicKey, Conduit), String> { + let state = self.state.take(); + let act_three_expectation = match state { + Some(HandshakeState::AwaitingActThree(act_state)) => act_state, + _ => { + self.state = state; + return Err("unexpected state".to_string()); + } + }; + + let version = act.0[0]; + if version != 0 { + return Err("unexpected version".to_string()); + } + + let mut tagged_encrypted_pubkey = [0u8; 49]; + tagged_encrypted_pubkey.copy_from_slice(&act.0[1..50]); + + let mut chacha_tag = [0u8; 16]; + chacha_tag.copy_from_slice(&act.0[50..66]); + + let mut hash = act_three_expectation.hash; + + let remote_pubkey_vec = chacha::decrypt(&act_three_expectation.temporary_key, 1, &hash.value, &tagged_encrypted_pubkey)?; + let mut remote_pubkey_bytes = [0u8; 33]; + remote_pubkey_bytes.copy_from_slice(remote_pubkey_vec.as_slice()); + // todo: replace unwrap with handleable error type + let remote_pubkey = PublicKey::from_slice(&remote_pubkey_bytes).unwrap(); + + hash.update(&tagged_encrypted_pubkey); + + let ecdh = Self::ecdh(&act_three_expectation.ephemeral_private_key, &remote_pubkey); + let (chaining_key, temporary_key) = hkdf::derive(&act_three_expectation.chaining_key, &ecdh); + let _tag_check = chacha::decrypt(&temporary_key, 0, &hash.value, &chacha_tag)?; + let (receiving_key, sending_key) = hkdf::derive(&chaining_key, &[0; 0]); + + let connected_peer = Conduit { + sending_key, + receiving_key, + sending_chaining_key: chaining_key, + receiving_chaining_key: chaining_key, + sending_nonce: 0, + receiving_nonce: 0, + read_buffer: None, + }; + Ok((remote_pubkey, connected_peer)) + } + + fn obtain_ephemeral_private_key(&mut self) -> SecretKey { + if let Some(key) = self.preset_ephemeral_private_key.take() { + key + } else { + // generate a random ephemeral private key right here + let mut rng = thread_rng(); + let mut ephemeral_bytes = [0; 32]; + rng.fill_bytes(&mut ephemeral_bytes); + SecretKey::from_slice(&ephemeral_bytes).expect("You broke elliptic curve cryptography") + } + } + + fn calculate_act_message(&self, local_private_key: &SecretKey, remote_public_key: &PublicKey, chaining_key: [u8; 32], hash: &mut HandshakeHash) -> ([u8; 50], [u8; 32], [u8; 32]) { + let local_public_key = Self::private_key_to_public_key(local_private_key); + + hash.update(&local_public_key.serialize()); + + let ecdh = Self::ecdh(local_private_key, &remote_public_key); + let (chaining_key, temporary_key) = hkdf::derive(&chaining_key, &ecdh); + let tagged_ciphertext = chacha::encrypt(&temporary_key, 0, &hash.value, &[0; 0]); + + hash.update(&tagged_ciphertext); + + let mut act_vec = [0u8].to_vec(); + act_vec.extend_from_slice(&local_public_key.serialize()); + act_vec.extend_from_slice(tagged_ciphertext.as_slice()); + let mut act = [0u8; 50]; + act.copy_from_slice(act_vec.as_slice()); + (act, chaining_key, temporary_key) + } + + fn process_act_message(&self, act_bytes: [u8; 50], local_private_key: &SecretKey, chaining_key: [u8; 32], hash: &mut HandshakeHash) -> Result<(PublicKey, [u8; 32], [u8; 32]), String> { + let version = act_bytes[0]; + if version != 0 { + return Err("unexpected version".to_string()); + } + + let mut ephemeral_public_key_bytes = [0u8; 33]; + ephemeral_public_key_bytes.copy_from_slice(&act_bytes[1..34]); + // todo: replace unwrap with handleable error type + let ephemeral_public_key = PublicKey::from_slice(&ephemeral_public_key_bytes).unwrap(); + + let mut chacha_tag = [0u8; 16]; + chacha_tag.copy_from_slice(&act_bytes[34..50]); + + // process the act message + + // update hash with partner's pubkey + hash.update(&ephemeral_public_key.serialize()); + + // calculate ECDH with partner's pubkey and local privkey + let ecdh = Self::ecdh(local_private_key, &ephemeral_public_key); + + // HKDF(chaining key, ECDH) -> chaining key' + next temporary key + let (chaining_key, temporary_key) = hkdf::derive(&chaining_key, &ecdh); + + // Validate chacha tag (temporary key, 0, self.hash, chacha_tag) + let _tag_check = chacha::decrypt(&temporary_key, 0, &hash.value, &chacha_tag)?; + + hash.update(&chacha_tag); + + Ok((ephemeral_public_key, chaining_key, temporary_key)) + } + + fn private_key_to_public_key(private_key: &SecretKey) -> PublicKey { + let curve = secp256k1::Secp256k1::new(); + let pk_object = PublicKey::from_secret_key(&curve, &private_key); + pk_object + } + + fn ecdh(private_key: &SecretKey, public_key: &PublicKey) -> [u8; 32] { + let curve = secp256k1::Secp256k1::new(); + let mut pk_object = public_key.clone(); + pk_object.mul_assign(&curve, &private_key[..]).expect("invalid multiplication"); + + let preimage = pk_object.serialize(); + let mut sha = Sha256::engine(); + sha.input(preimage.as_ref()); + Sha256::from_engine(sha).into_inner() + } +} \ No newline at end of file diff --git a/lightning/src/ln/peers/handshake/states.rs b/lightning/src/ln/peers/handshake/states.rs new file mode 100644 index 00000000000..836be023a0d --- /dev/null +++ b/lightning/src/ln/peers/handshake/states.rs @@ -0,0 +1,30 @@ +use ln::peers::handshake::hash::HandshakeHash; +use secp256k1::{SecretKey, PublicKey}; + +pub enum HandshakeState { + Blank, + AwaitingActOne(ActOneExpectation), + AwaitingActTwo(ActTwoExpectation), + AwaitingActThree(ActThreeExpectation), + Complete, +} + +pub struct ActOneExpectation { + pub(super) hash: HandshakeHash, + pub(super) chaining_key: [u8; 32], +} + +pub struct ActTwoExpectation { + pub(super) hash: HandshakeHash, + pub(super) chaining_key: [u8; 32], + pub(super) temporary_key: [u8; 32], + pub(super) ephemeral_private_key: SecretKey, +} + +pub struct ActThreeExpectation { + pub(super) hash: HandshakeHash, + pub(super) chaining_key: [u8; 32], + pub(super) temporary_key: [u8; 32], + pub(super) ephemeral_private_key: SecretKey, + pub(super) remote_ephemeral_public_key: PublicKey, +} \ No newline at end of file diff --git a/lightning/src/ln/peers/handshake/tests.rs b/lightning/src/ln/peers/handshake/tests.rs new file mode 100644 index 00000000000..48d89a9fde6 --- /dev/null +++ b/lightning/src/ln/peers/handshake/tests.rs @@ -0,0 +1,26 @@ +#![cfg(test)] + +use secp256k1::key::{PublicKey, SecretKey}; + +use ln::peers::handshake::PeerHandshake; + +#[test] +fn test_exchange() { + let curve = secp256k1::Secp256k1::new(); + + let local_private_key = SecretKey::from_slice(&[0x_11_u8; 32]).unwrap(); + let remote_private_key = SecretKey::from_slice(&[0x_21_u8; 32]).unwrap(); + + let local_ephemeral_private_key = SecretKey::from_slice(&[0x_12_u8; 32]).unwrap(); + let remote_ephemeral_private_key = SecretKey::from_slice(&[0x_22_u8; 32]).unwrap(); + + let mut local_handshake = PeerHandshake::new(&local_private_key, Some(&local_ephemeral_private_key)); + let mut remote_handshake = PeerHandshake::new(&remote_private_key, Some(&remote_ephemeral_private_key)); + + let remote_public_key = PublicKey::from_secret_key(&curve, &remote_private_key); + + let act_1_message = local_handshake.initiate(&local_ephemeral_private_key, &remote_public_key); + let act_2_message = remote_handshake.process_act_one(act_1_message.unwrap(), &remote_ephemeral_private_key); + let act_3_message = local_handshake.process_act_two(act_2_message.unwrap()); + remote_handshake.process_act_three(act_3_message.unwrap().0).unwrap(); +} \ No newline at end of file diff --git a/lightning/src/ln/peers/hkdf.rs b/lightning/src/ln/peers/hkdf.rs new file mode 100644 index 00000000000..396515a4bf2 --- /dev/null +++ b/lightning/src/ln/peers/hkdf.rs @@ -0,0 +1,18 @@ +use bitcoin_hashes::{Hash, HashEngine, Hmac, HmacEngine}; +use bitcoin_hashes::sha256::Hash as Sha256; + +pub fn derive(salt: &[u8], master: &[u8]) -> ([u8; 32], [u8; 32]) { + let mut hmac = HmacEngine::::new(salt); + hmac.input(master); + let prk = Hmac::from_engine(hmac).into_inner(); // prk = sha256(master) + + let mut hmac = HmacEngine::::new(&prk[..]); + hmac.input(&[1; 1]); + let t1 = Hmac::from_engine(hmac).into_inner(); // t1 = sha256(prk | 1) + + let mut hmac = HmacEngine::::new(&prk[..]); + hmac.input(&t1); + hmac.input(&[2; 1]); + // sha256(prk | t1 | 2) = sha256(sha256(master) | sha256(sha256(sha256(master) | 1) | 2) + (t1, Hmac::from_engine(hmac).into_inner()) +} \ No newline at end of file diff --git a/lightning/src/ln/peers/mod.rs b/lightning/src/ln/peers/mod.rs new file mode 100644 index 00000000000..748356a8f12 --- /dev/null +++ b/lightning/src/ln/peers/mod.rs @@ -0,0 +1,4 @@ +mod chacha; +pub mod conduit; +pub mod handshake; +mod hkdf; From b71b7ea4b27b1c1a7a68e2ca59e5819923462f70 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Tue, 11 Feb 2020 22:41:35 -0800 Subject: [PATCH 02/27] change peer_handler.rs to use modular handshake and encryption handler, and only expose old peer_channel_encryptor.rs to fuzz tests --- lightning/src/ln/mod.rs | 2 - lightning/src/ln/peer_handler.rs | 660 ++++++++++++------------ lightning/src/ln/peers/handshake/mod.rs | 2 +- 3 files changed, 337 insertions(+), 327 deletions(-) diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index 8ff78e02077..16bf959be87 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -20,8 +20,6 @@ pub mod features; #[cfg(feature = "fuzztarget")] pub mod peer_channel_encryptor; -#[cfg(not(feature = "fuzztarget"))] -pub(crate) mod peer_channel_encryptor; mod channel; mod onion_utils; diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 44d08030062..44f0214b0fc 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -13,7 +13,6 @@ use ln::msgs; use ln::msgs::ChannelMessageHandler; use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager}; use util::ser::VecWriter; -use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep}; use ln::wire; use ln::wire::Encode; use util::byte_utils; @@ -29,6 +28,9 @@ use std::ops::Deref; use bitcoin_hashes::sha256::Hash as Sha256; use bitcoin_hashes::sha256::HashEngine as Sha256Engine; use bitcoin_hashes::{HashEngine, Hash}; +use ln::peers::handshake::PeerHandshake; +use ln::peers::conduit::Conduit; +use ln::peers::handshake::acts::Act; /// Provides references to trait impls which handle different types of messages. pub struct MessageHandler where CM::Target: msgs::ChannelMessageHandler { @@ -105,8 +107,23 @@ enum InitSyncTracker{ NodesSyncing(PublicKey), } +enum PeerState { + Handshake(PeerHandshake), + Connected(Conduit), +} + +impl PeerState { + fn is_ready_for_encryption(&self) -> bool { + if let PeerState::Connected(_) = self { + true + } else { + false + } + } +} + struct Peer { - channel_encryptor: PeerChannelEncryptor, + encryptor: PeerState, outbound: bool, their_node_id: Option, their_features: Option, @@ -116,8 +133,6 @@ struct Peer { awaiting_write_event: bool, pending_read_buffer: Vec, - pending_read_buffer_pos: usize, - pending_read_is_header: bool, sync_status: InitSyncTracker, @@ -233,7 +248,7 @@ impl PeerManager where pub fn get_peer_node_ids(&self) -> Vec { let peers = self.peers.lock().unwrap(); peers.peers.values().filter_map(|p| { - if !p.channel_encryptor.is_ready_for_encryption() || p.their_features.is_none() { + if !p.encryptor.is_ready_for_encryption() || p.their_features.is_none() { return None; } p.their_node_id @@ -262,13 +277,13 @@ impl PeerManager where /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result, PeerHandleError> { - let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key()); - let res = peer_encryptor.get_act_one().to_vec(); - let pending_read_buffer = [0; 50].to_vec(); // Noise act two is 50 bytes + let mut handshake = PeerHandshake::new(&self.our_node_secret, None); + let act_one = handshake.initiate(&self.get_ephemeral_key(), &their_node_id).unwrap(); + let res = Act::One(act_one).serialize(); let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { - channel_encryptor: peer_encryptor, + encryptor: PeerState::Handshake(handshake), outbound: true, their_node_id: None, their_features: None, @@ -277,9 +292,7 @@ impl PeerManager where pending_outbound_buffer_first_msg_offset: 0, awaiting_write_event: false, - pending_read_buffer: pending_read_buffer, - pending_read_buffer_pos: 0, - pending_read_is_header: false, + pending_read_buffer: Vec::new(), sync_status: InitSyncTracker::NoSyncRequested, @@ -300,12 +313,11 @@ impl PeerManager where /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> { - let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret); - let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes + let handshake = PeerHandshake::new(&self.our_node_secret, None); let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { - channel_encryptor: peer_encryptor, + encryptor: PeerState::Handshake(handshake), outbound: false, their_node_id: None, their_features: None, @@ -314,9 +326,7 @@ impl PeerManager where pending_outbound_buffer_first_msg_offset: 0, awaiting_write_event: false, - pending_read_buffer: pending_read_buffer, - pending_read_buffer_pos: 0, - pending_read_is_header: false, + pending_read_buffer: Vec::new(), sync_status: InitSyncTracker::NoSyncRequested, @@ -332,7 +342,9 @@ impl PeerManager where ($msg: expr) => { { log_trace!(self, "Encoding and sending sync update message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!($msg)[..])); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!($msg)[..])); + } } } } @@ -450,317 +462,277 @@ impl PeerManager where let pause_read = match peers.peers.get_mut(peer_descriptor) { None => panic!("Descriptor for read_event is not already known to PeerManager"), Some(peer) => { - assert!(peer.pending_read_buffer.len() > 0); - assert!(peer.pending_read_buffer.len() > peer.pending_read_buffer_pos); + peer.pending_read_buffer.extend_from_slice(&data); + while peer.pending_read_buffer.len() > 0 { + + macro_rules! encode_and_send_msg { + ($msg: expr) => { + { + log_trace!(self, "Encoding and sending message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(&$msg)[..])); + } + peers.peers_needing_send.insert(peer_descriptor.clone()); + } + } + } - let mut read_pos = 0; - while read_pos < data.len() { - { - let data_to_copy = cmp::min(peer.pending_read_buffer.len() - peer.pending_read_buffer_pos, data.len() - read_pos); - peer.pending_read_buffer[peer.pending_read_buffer_pos..peer.pending_read_buffer_pos + data_to_copy].copy_from_slice(&data[read_pos..read_pos + data_to_copy]); - read_pos += data_to_copy; - peer.pending_read_buffer_pos += data_to_copy; + macro_rules! try_potential_handleerror { + ($thing: expr) => { + match $thing { + Ok(x) => x, + Err(e) => { + match e.action { + msgs::ErrorAction::DisconnectPeer { msg: _ } => { + //TODO: Try to push msg + log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err); + return Err(PeerHandleError{ no_connection_possible: false }); + }, + msgs::ErrorAction::IgnoreError => { + log_trace!(self, "Got Err handling message, ignoring because {}", e.err); + continue; + }, + msgs::ErrorAction::SendErrorMessage { msg } => { + log_trace!(self, "Got Err handling message, sending Error message because {}", e.err); + encode_and_send_msg!(msg); + continue; + }, + } + } + }; + } + } + + macro_rules! insert_node_id { + () => { + match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) { + hash_map::Entry::Occupied(_) => { + log_trace!(self, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); + peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event + return Err(PeerHandleError{ no_connection_possible: false }) + }, + hash_map::Entry::Vacant(entry) => { + log_trace!(self, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); + entry.insert(peer_descriptor.clone()) + }, + }; + } } - if peer.pending_read_buffer_pos == peer.pending_read_buffer.len() { - peer.pending_read_buffer_pos = 0; + if let PeerState::Handshake(ref mut handshake) = &mut peer.encryptor { + let (response, conduit, remote_pubkey) = handshake.process_act(&peer.pending_read_buffer, None).unwrap(); + peer.pending_read_buffer.drain(..); // we read it all - macro_rules! encode_and_send_msg { - ($msg: expr) => { - { - log_trace!(self, "Encoding and sending message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(&$msg)[..])); - peers.peers_needing_send.insert(peer_descriptor.clone()); - } - } + peer.pending_outbound_buffer.push_back(response); + if let Some(conduit) = conduit { + peer.encryptor = PeerState::Connected(conduit); } + } - macro_rules! try_potential_handleerror { - ($thing: expr) => { - match $thing { - Ok(x) => x, - Err(e) => { - match e.action { - msgs::ErrorAction::DisconnectPeer { msg: _ } => { - //TODO: Try to push msg - log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err); - return Err(PeerHandleError{ no_connection_possible: false }); - }, - msgs::ErrorAction::IgnoreError => { - log_trace!(self, "Got Err handling message, ignoring because {}", e.err); - continue; - }, - msgs::ErrorAction::SendErrorMessage { msg } => { - log_trace!(self, "Got Err handling message, sending Error message because {}", e.err); - encode_and_send_msg!(msg); - continue; - }, - } - } - }; - } + if let PeerState::Connected(ref mut conduit) = &mut peer.encryptor { + let mut messages = conduit.decrypt_message_stream(Some(&peer.pending_read_buffer)); + + if messages.len() != 1 { + break; // the length should initially be one, though there will be a possibility of decrypting multiple messages at once in the future } - macro_rules! insert_node_id { - () => { - match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) { - hash_map::Entry::Occupied(_) => { - log_trace!(self, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); - peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event - return Err(PeerHandleError{ no_connection_possible: false }) - }, - hash_map::Entry::Vacant(entry) => { - log_trace!(self, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); - entry.insert(peer_descriptor.clone()) - }, - }; + let msg_data = messages.remove(1); + + let mut reader = ::std::io::Cursor::new(&msg_data[..]); + let message_result = wire::read(&mut reader); + let message = match message_result { + Ok(x) => x, + Err(e) => { + match e { + msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }), + msgs::DecodeError::UnknownRequiredFeature => { + log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to update!"); + continue; + } + msgs::DecodeError::InvalidValue => { + log_debug!(self, "Got an invalid value while deserializing message"); + return Err(PeerHandleError { no_connection_possible: false }); + } + msgs::DecodeError::ShortRead => { + log_debug!(self, "Deserialization failed due to shortness of message"); + return Err(PeerHandleError { no_connection_possible: false }); + } + msgs::DecodeError::ExtraAddressesPerType => { + log_debug!(self, "Error decoding message, ignoring due to lnd spec incompatibility. See https://github.com/lightningnetwork/lnd/issues/1407"); + continue; + } + msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }), + msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }), + } } + }; + + log_trace!(self, "Received message of type {} from {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap())); + + // Need an Init as first message + if let wire::Message::Init(_) = message { + } else if peer.their_features.is_none() { + log_trace!(self, "Peer {} sent non-Init first message", log_pubkey!(peer.their_node_id.unwrap())); + return Err(PeerHandleError{ no_connection_possible: false }); } - let next_step = peer.channel_encryptor.get_noise_step(); - match next_step { - NextNoiseStep::ActOne => { - let act_two = try_potential_handleerror!(peer.channel_encryptor.process_act_one_with_keys(&peer.pending_read_buffer[..], &self.our_node_secret, self.get_ephemeral_key())).to_vec(); - peer.pending_outbound_buffer.push_back(act_two); - peer.pending_read_buffer = [0; 66].to_vec(); // act three is 66 bytes long - }, - NextNoiseStep::ActTwo => { - let (act_three, their_node_id) = try_potential_handleerror!(peer.channel_encryptor.process_act_two(&peer.pending_read_buffer[..], &self.our_node_secret)); - peer.pending_outbound_buffer.push_back(act_three.to_vec()); - peer.pending_read_buffer = [0; 18].to_vec(); // Message length header is 18 bytes - peer.pending_read_is_header = true; - - peer.their_node_id = Some(their_node_id); - insert_node_id!(); - let mut features = InitFeatures::supported(); - if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { - features.set_initial_routing_sync(); + match message { + // Setup and Control messages: + wire::Message::Init(msg) => { + if msg.features.requires_unknown_bits() { + log_info!(self, "Peer global features required unknown version bits"); + return Err(PeerHandleError{ no_connection_possible: true }); + } + if msg.features.requires_unknown_bits() { + log_info!(self, "Peer local features required unknown version bits"); + return Err(PeerHandleError{ no_connection_possible: true }); + } + if peer.their_features.is_some() { + return Err(PeerHandleError{ no_connection_possible: false }); } - let resp = msgs::Init { features }; - encode_and_send_msg!(resp); - }, - NextNoiseStep::ActThree => { - let their_node_id = try_potential_handleerror!(peer.channel_encryptor.process_act_three(&peer.pending_read_buffer[..])); - peer.pending_read_buffer = [0; 18].to_vec(); // Message length header is 18 bytes - peer.pending_read_is_header = true; - peer.their_node_id = Some(their_node_id); - insert_node_id!(); - }, - NextNoiseStep::NoiseComplete => { - if peer.pending_read_is_header { - let msg_len = try_potential_handleerror!(peer.channel_encryptor.decrypt_length_header(&peer.pending_read_buffer[..])); - peer.pending_read_buffer = Vec::with_capacity(msg_len as usize + 16); - peer.pending_read_buffer.resize(msg_len as usize + 16, 0); - if msg_len < 2 { // Need at least the message type tag - return Err(PeerHandleError{ no_connection_possible: false }); - } - peer.pending_read_is_header = false; - } else { - let msg_data = try_potential_handleerror!(peer.channel_encryptor.decrypt_message(&peer.pending_read_buffer[..])); - assert!(msg_data.len() >= 2); - - // Reset read buffer - peer.pending_read_buffer = [0; 18].to_vec(); - peer.pending_read_is_header = true; - - let mut reader = ::std::io::Cursor::new(&msg_data[..]); - let message_result = wire::read(&mut reader); - let message = match message_result { - Ok(x) => x, - Err(e) => { - match e { - msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }), - msgs::DecodeError::UnknownRequiredFeature => { - log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to update!"); - continue; - } - msgs::DecodeError::InvalidValue => { - log_debug!(self, "Got an invalid value while deserializing message"); - return Err(PeerHandleError { no_connection_possible: false }); - } - msgs::DecodeError::ShortRead => { - log_debug!(self, "Deserialization failed due to shortness of message"); - return Err(PeerHandleError { no_connection_possible: false }); - } - msgs::DecodeError::ExtraAddressesPerType => { - log_debug!(self, "Error decoding message, ignoring due to lnd spec incompatibility. See https://github.com/lightningnetwork/lnd/issues/1407"); - continue; - } - msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }), - msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }), - } - } - }; + log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", + if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, + if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, + if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, + if msg.features.supports_unknown_bits() { "present" } else { "none" }, + if msg.features.supports_unknown_bits() { "present" } else { "none" }); - log_trace!(self, "Received message of type {} from {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap())); + if msg.features.initial_routing_sync() { + peer.sync_status = InitSyncTracker::ChannelsSyncing(0); + peers.peers_needing_send.insert(peer_descriptor.clone()); + } - // Need an Init as first message - if let wire::Message::Init(_) = message { - } else if peer.their_features.is_none() { - log_trace!(self, "Peer {} sent non-Init first message", log_pubkey!(peer.their_node_id.unwrap())); - return Err(PeerHandleError{ no_connection_possible: false }); + if !peer.outbound { + let mut features = InitFeatures::supported(); + if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { + features.set_initial_routing_sync(); } - match message { - // Setup and Control messages: - wire::Message::Init(msg) => { - if msg.features.requires_unknown_bits() { - log_info!(self, "Peer global features required unknown version bits"); - return Err(PeerHandleError{ no_connection_possible: true }); - } - if msg.features.requires_unknown_bits() { - log_info!(self, "Peer local features required unknown version bits"); - return Err(PeerHandleError{ no_connection_possible: true }); - } - if peer.their_features.is_some() { - return Err(PeerHandleError{ no_connection_possible: false }); - } - - log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", - if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, - if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, - if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, - if msg.features.supports_unknown_bits() { "present" } else { "none" }, - if msg.features.supports_unknown_bits() { "present" } else { "none" }); - - if msg.features.initial_routing_sync() { - peer.sync_status = InitSyncTracker::ChannelsSyncing(0); - peers.peers_needing_send.insert(peer_descriptor.clone()); - } - - if !peer.outbound { - let mut features = InitFeatures::supported(); - if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { - features.set_initial_routing_sync(); - } - - let resp = msgs::Init { features }; - encode_and_send_msg!(resp); - } - - self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); - peer.their_features = Some(msg.features); - }, - wire::Message::Error(msg) => { - let mut data_is_printable = true; - for b in msg.data.bytes() { - if b < 32 || b > 126 { - data_is_printable = false; - break; - } - } - - if data_is_printable { - log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data); - } else { - log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap())); - } - self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); - if msg.channel_id == [0; 32] { - return Err(PeerHandleError{ no_connection_possible: true }); - } - }, + let resp = msgs::Init { features }; + encode_and_send_msg!(resp); + } - wire::Message::Ping(msg) => { - if msg.ponglen < 65532 { - let resp = msgs::Pong { byteslen: msg.ponglen }; - encode_and_send_msg!(resp); - } - }, - wire::Message::Pong(_msg) => { - peer.awaiting_pong = false; - }, + self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); + peer.their_features = Some(msg.features); + }, + wire::Message::Error(msg) => { + let mut data_is_printable = true; + for b in msg.data.bytes() { + if b < 32 || b > 126 { + data_is_printable = false; + break; + } + } - // Channel messages: - wire::Message::OpenChannel(msg) => { - self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - }, - wire::Message::AcceptChannel(msg) => { - self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - }, + if data_is_printable { + log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data); + } else { + log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap())); + } + self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); + if msg.channel_id == [0; 32] { + return Err(PeerHandleError{ no_connection_possible: true }); + } + }, - wire::Message::FundingCreated(msg) => { - self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::FundingSigned(msg) => { - self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::FundingLocked(msg) => { - self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); - }, + wire::Message::Ping(msg) => { + if msg.ponglen < 65532 { + let resp = msgs::Pong { byteslen: msg.ponglen }; + encode_and_send_msg!(resp); + } + }, + wire::Message::Pong(_msg) => { + peer.awaiting_pong = false; + }, - wire::Message::Shutdown(msg) => { - self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::ClosingSigned(msg) => { - self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); - }, + // Channel messages: + wire::Message::OpenChannel(msg) => { + self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); + }, + wire::Message::AcceptChannel(msg) => { + self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); + }, - // Commitment messages: - wire::Message::UpdateAddHTLC(msg) => { - self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::UpdateFulfillHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::UpdateFailHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::UpdateFailMalformedHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); - }, + wire::Message::FundingCreated(msg) => { + self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::FundingSigned(msg) => { + self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::FundingLocked(msg) => { + self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); + }, - wire::Message::CommitmentSigned(msg) => { - self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::RevokeAndACK(msg) => { - self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::UpdateFee(msg) => { - self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::ChannelReestablish(msg) => { - self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); - }, + wire::Message::Shutdown(msg) => { + self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::ClosingSigned(msg) => { + self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); + }, - // Routing messages: - wire::Message::AnnouncementSignatures(msg) => { - self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::ChannelAnnouncement(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_announcement(&msg)); + // Commitment messages: + wire::Message::UpdateAddHTLC(msg) => { + self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::UpdateFulfillHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::UpdateFailHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::UpdateFailMalformedHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); + }, - if should_forward { - // TODO: forward msg along to all our other peers! - } - }, - wire::Message::NodeAnnouncement(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); + wire::Message::CommitmentSigned(msg) => { + self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::RevokeAndACK(msg) => { + self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::UpdateFee(msg) => { + self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::ChannelReestablish(msg) => { + self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); + }, - if should_forward { - // TODO: forward msg along to all our other peers! - } - }, - wire::Message::ChannelUpdate(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg)); + // Routing messages: + wire::Message::AnnouncementSignatures(msg) => { + self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::ChannelAnnouncement(msg) => { + let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_announcement(&msg)); - if should_forward { - // TODO: forward msg along to all our other peers! - } - }, + if should_forward { + // TODO: forward msg along to all our other peers! + } + }, + wire::Message::NodeAnnouncement(msg) => { + let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); - // Unknown messages: - wire::Message::Unknown(msg_type) if msg_type.is_even() => { - // Fail the channel if message is an even, unknown type as per BOLT #1. - return Err(PeerHandleError{ no_connection_possible: true }); - }, - wire::Message::Unknown(_) => {}, - } + if should_forward { + // TODO: forward msg along to all our other peers! } - } + }, + wire::Message::ChannelUpdate(msg) => { + let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg)); + + if should_forward { + // TODO: forward msg along to all our other peers! + } + }, + + // Unknown messages: + wire::Message::Unknown(msg_type) if msg_type.is_even() => { + // Fail the channel if message is an even, unknown type as per BOLT #1. + return Err(PeerHandleError{ no_connection_possible: true }); + }, + wire::Message::Unknown(_) => {}, } } + } self.do_attempt_write_data(peer_descriptor, peer); @@ -819,7 +791,9 @@ impl PeerManager where 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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::SendOpenChannel { ref node_id, ref msg } => { @@ -829,7 +803,9 @@ impl PeerManager where 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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::SendFundingCreated { ref node_id, ref msg } => { @@ -841,7 +817,9 @@ impl PeerManager where //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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::SendFundingSigned { ref node_id, ref msg } => { @@ -852,7 +830,9 @@ impl PeerManager where //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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => { @@ -862,7 +842,9 @@ impl PeerManager where 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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => { @@ -873,7 +855,9 @@ impl PeerManager where //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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } 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 } } => { @@ -887,21 +871,33 @@ impl PeerManager where //TODO: Do whatever we're gonna do for handling dropped messages }); for msg in update_add_htlcs { - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } } for msg in update_fulfill_htlcs { - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } } for msg in update_fail_htlcs { - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } } for msg in update_fail_malformed_htlcs { - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } } if let &Some(ref msg) = update_fee { - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } + } + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(commitment_signed))); } - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(commitment_signed))); self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => { @@ -911,7 +907,9 @@ impl PeerManager where 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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::SendClosingSigned { ref node_id, ref msg } => { @@ -921,7 +919,9 @@ impl PeerManager where 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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::SendShutdown { ref node_id, ref msg } => { @@ -931,7 +931,9 @@ impl PeerManager where 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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } => { @@ -941,7 +943,9 @@ impl PeerManager where 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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { @@ -951,8 +955,8 @@ impl PeerManager where let encoded_update_msg = encode_msg!(update_msg); for (ref descriptor, ref mut peer) in peers.peers.iter_mut() { - if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_features.is_none() || - !peer.should_forward_channel(msg.contents.short_channel_id) { + if !peer.encryptor.is_ready_for_encryption() || peer.their_features.is_none() || + !peer.should_forward_channel(msg.contents.short_channel_id) { continue } match peer.their_node_id { @@ -963,8 +967,10 @@ impl PeerManager where } } } - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..])); - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_update_msg[..])); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encoded_msg[..])); + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encoded_update_msg[..])); + } self.do_attempt_write_data(&mut (*descriptor).clone(), peer); } } @@ -975,11 +981,13 @@ impl PeerManager where let encoded_msg = encode_msg!(msg); for (ref descriptor, ref mut peer) in peers.peers.iter_mut() { - if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_features.is_none() || - !peer.should_forward_channel(msg.contents.short_channel_id) { + if !peer.encryptor.is_ready_for_encryption() || peer.their_features.is_none() || + !peer.should_forward_channel(msg.contents.short_channel_id) { continue } - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..])); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encoded_msg[..])); + } self.do_attempt_write_data(&mut (*descriptor).clone(), peer); } } @@ -997,7 +1005,9 @@ impl PeerManager where log_trace!(self, "Handling DisconnectPeer HandleError event in peer_handler for node {} with message {}", log_pubkey!(node_id), msg.data); - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } // This isn't guaranteed to work, but if there is enough free // room in the send buffer, put the error message there... self.do_attempt_write_data(&mut descriptor, &mut peer); @@ -1017,7 +1027,9 @@ impl PeerManager where 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))); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); + } self.do_attempt_write_data(&mut descriptor, peer); }, } diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index 087f7ecfa73..0bbd8aa189e 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -9,7 +9,7 @@ use ln::peers::handshake::acts::{ActOne, ActThree, ActTwo}; use ln::peers::handshake::hash::HandshakeHash; use ln::peers::handshake::states::{ActOneExpectation, ActThreeExpectation, ActTwoExpectation, HandshakeState}; -mod acts; +pub(crate) mod acts; mod hash; mod states; mod tests; From 92eac9b6c9359aa34b02fd9b94140fc43925428c Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Wed, 12 Feb 2020 11:48:11 -0800 Subject: [PATCH 03/27] make ephemeral private key explicit for handshake (todo: remove it from the state machine) --- lightning/src/ln/peer_handler.rs | 6 +-- lightning/src/ln/peers/conduit.rs | 10 +---- lightning/src/ln/peers/handshake/mod.rs | 46 +++++++---------------- lightning/src/ln/peers/handshake/tests.rs | 8 ++-- 4 files changed, 21 insertions(+), 49 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 44f0214b0fc..09e1d5b7657 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -277,8 +277,8 @@ impl PeerManager where /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result, PeerHandleError> { - let mut handshake = PeerHandshake::new(&self.our_node_secret, None); - let act_one = handshake.initiate(&self.get_ephemeral_key(), &their_node_id).unwrap(); + let mut handshake = PeerHandshake::new(&self.our_node_secret, &self.get_ephemeral_key()); + let act_one = handshake.initiate(&their_node_id).unwrap(); let res = Act::One(act_one).serialize(); let mut peers = self.peers.lock().unwrap(); @@ -313,7 +313,7 @@ impl PeerManager where /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> { - let handshake = PeerHandshake::new(&self.our_node_secret, None); + let handshake = PeerHandshake::new(&self.our_node_secret, &self.get_ephemeral_key()); let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs index fe1c5adcb90..28c83f3c772 100644 --- a/lightning/src/ln/peers/conduit.rs +++ b/lightning/src/ln/peers/conduit.rs @@ -31,14 +31,8 @@ impl Conduit { } pub(super) fn read(&mut self, data: &[u8]) { - let mut read_buffer = if let Some(buffer) = self.read_buffer.take() { - buffer - } else { - Vec::new() - }; - + let mut read_buffer = self.read_buffer.get_or_insert(Vec::new()); read_buffer.extend_from_slice(data); - self.read_buffer = Some(read_buffer); } /// Add newly received data from the peer node to the buffer and decrypt all possible messages @@ -71,8 +65,6 @@ impl Conduit { } } - self.read_buffer = Some(read_buffer); - messages } diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index 0bbd8aa189e..70d2082269f 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -17,24 +17,18 @@ mod tests; pub struct PeerHandshake { state: Option, private_key: SecretKey, + ephemeral_private_key: SecretKey, - preset_ephemeral_private_key: Option, read_buffer: Vec, } impl PeerHandshake { - pub fn new(private_key: &SecretKey, ephemeral_private_key: Option<&SecretKey>) -> Self { - let preset_ephemeral_private_key = if let Some(key) = ephemeral_private_key { - // deref and clone - Some((*key).clone()) - } else { - None - }; + pub fn new(private_key: &SecretKey, ephemeral_private_key: &SecretKey) -> Self { let handshake = PeerHandshake { state: Some(HandshakeState::Blank), private_key: (*private_key).clone(), - preset_ephemeral_private_key, + ephemeral_private_key: (*ephemeral_private_key).clone(), read_buffer: Vec::new(), }; handshake @@ -80,9 +74,7 @@ impl PeerHandshake { match &self.state { Some(HandshakeState::Blank) => { let remote_public_key = remote_public_key.ok_or("Call make_initiator() first")?; - let ephemeral_private_key = self.obtain_ephemeral_private_key(); - - let act_one = self.initiate(&ephemeral_private_key, &remote_public_key)?; + let act_one = self.initiate(&remote_public_key)?; response = act_one.0.to_vec(); } Some(HandshakeState::AwaitingActOne(_)) => { @@ -95,9 +87,7 @@ impl PeerHandshake { act_one_buffer.copy_from_slice(&self.read_buffer[..act_length]); self.read_buffer.drain(..act_length); - let ephemeral_private_key = self.obtain_ephemeral_private_key(); - - let act_two = self.process_act_one(ActOne(act_one_buffer), &ephemeral_private_key)?; + let act_two = self.process_act_one(ActOne(act_one_buffer))?; response = act_two.0.to_vec(); } Some(HandshakeState::AwaitingActTwo(_)) => { @@ -147,7 +137,7 @@ impl PeerHandshake { Ok((response, connected_peer, remote_pubkey)) } - pub fn initiate(&mut self, ephemeral_private_key: &SecretKey, remote_public_key: &PublicKey) -> Result { + pub fn initiate(&mut self, remote_public_key: &PublicKey) -> Result { if let Some(HandshakeState::Blank) = &self.state {} else { return Err("incorrect state".to_string()); } @@ -156,7 +146,7 @@ impl PeerHandshake { // serialize act one let (act_one, chaining_key, temporary_key) = self.calculate_act_message( - ephemeral_private_key, + &self.ephemeral_private_key, remote_public_key, chaining_key, &mut hash, @@ -166,13 +156,13 @@ impl PeerHandshake { hash, chaining_key, temporary_key, - ephemeral_private_key: (*ephemeral_private_key).clone(), + ephemeral_private_key: (*&self.ephemeral_private_key).clone(), })); Ok(ActOne(act_one)) } - pub(crate) fn process_act_one(&mut self, act: ActOne, ephemeral_private_key: &SecretKey) -> Result { + pub(crate) fn process_act_one(&mut self, act: ActOne) -> Result { let state = self.state.take(); let act_one_expectation = match state { Some(HandshakeState::AwaitingActOne(act_state)) => act_state, @@ -200,8 +190,10 @@ impl PeerHandshake { &mut hash, )?; + let ephemeral_private_key = (*&self.ephemeral_private_key).clone(); + let (act_two, chaining_key, temporary_key) = self.calculate_act_message( - ephemeral_private_key, + &ephemeral_private_key, &remote_ephemeral_public_key, chaining_key, &mut hash, @@ -211,7 +203,7 @@ impl PeerHandshake { hash, chaining_key, temporary_key, - ephemeral_private_key: (*ephemeral_private_key).clone(), + ephemeral_private_key, remote_ephemeral_public_key, })); @@ -315,18 +307,6 @@ impl PeerHandshake { Ok((remote_pubkey, connected_peer)) } - fn obtain_ephemeral_private_key(&mut self) -> SecretKey { - if let Some(key) = self.preset_ephemeral_private_key.take() { - key - } else { - // generate a random ephemeral private key right here - let mut rng = thread_rng(); - let mut ephemeral_bytes = [0; 32]; - rng.fill_bytes(&mut ephemeral_bytes); - SecretKey::from_slice(&ephemeral_bytes).expect("You broke elliptic curve cryptography") - } - } - fn calculate_act_message(&self, local_private_key: &SecretKey, remote_public_key: &PublicKey, chaining_key: [u8; 32], hash: &mut HandshakeHash) -> ([u8; 50], [u8; 32], [u8; 32]) { let local_public_key = Self::private_key_to_public_key(local_private_key); diff --git a/lightning/src/ln/peers/handshake/tests.rs b/lightning/src/ln/peers/handshake/tests.rs index 48d89a9fde6..b749f9ab13c 100644 --- a/lightning/src/ln/peers/handshake/tests.rs +++ b/lightning/src/ln/peers/handshake/tests.rs @@ -14,13 +14,13 @@ fn test_exchange() { let local_ephemeral_private_key = SecretKey::from_slice(&[0x_12_u8; 32]).unwrap(); let remote_ephemeral_private_key = SecretKey::from_slice(&[0x_22_u8; 32]).unwrap(); - let mut local_handshake = PeerHandshake::new(&local_private_key, Some(&local_ephemeral_private_key)); - let mut remote_handshake = PeerHandshake::new(&remote_private_key, Some(&remote_ephemeral_private_key)); + let mut local_handshake = PeerHandshake::new(&local_private_key, &local_ephemeral_private_key); + let mut remote_handshake = PeerHandshake::new(&remote_private_key, &remote_ephemeral_private_key); let remote_public_key = PublicKey::from_secret_key(&curve, &remote_private_key); - let act_1_message = local_handshake.initiate(&local_ephemeral_private_key, &remote_public_key); - let act_2_message = remote_handshake.process_act_one(act_1_message.unwrap(), &remote_ephemeral_private_key); + let act_1_message = local_handshake.initiate(&remote_public_key); + let act_2_message = remote_handshake.process_act_one(act_1_message.unwrap()); let act_3_message = local_handshake.process_act_two(act_2_message.unwrap()); remote_handshake.process_act_three(act_3_message.unwrap().0).unwrap(); } \ No newline at end of file From 986f25f5b7e7fb5ed1743f8112d068732bfaf1bb Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Wed, 12 Feb 2020 12:11:00 -0800 Subject: [PATCH 04/27] remove import of rand --- lightning/src/ln/peers/handshake/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index 70d2082269f..213ed2bbfa0 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -1,6 +1,5 @@ use bitcoin_hashes::{Hash, HashEngine}; use bitcoin_hashes::sha256::Hash as Sha256; -use rand::{Rng, thread_rng}; use secp256k1::{PublicKey, SecretKey}; use ln::peers::{chacha, hkdf}; From ffbf5ec5d3501e26a77a109dc0155ab9d4f84bba Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Wed, 12 Feb 2020 12:28:38 -0800 Subject: [PATCH 05/27] make linter complain less about docs fix last lint doc issue? make the &Some matches explicit for Rust 1.22 appease Rust 1.22 some more with ampersandery appease Rust 1.22 by using byte_utils for endianness functionality appease Rust 1.22 by using byte_utils and ref in match arms experimenting some more with ref matching for Rust 1.22 might Rust 1.22 finally work? Rearranged a lot of borrowing locations and macro behavior and definition locations fix bug that was kindly caught by fuzz tests fix fuzz test improve error messaging the different rust versions are a balancing act, and I can't juggle --- lightning/src/ln/peer_handler.rs | 130 +++++++++++----------- lightning/src/ln/peers/chacha.rs | 13 ++- lightning/src/ln/peers/conduit.rs | 33 +++++- lightning/src/ln/peers/handshake/acts.rs | 11 +- lightning/src/ln/peers/handshake/mod.rs | 27 +++-- lightning/src/ln/peers/handshake/tests.rs | 21 +++- lightning/src/ln/peers/mod.rs | 5 + 7 files changed, 156 insertions(+), 84 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 09e1d5b7657..0aebdf1dc4e 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -114,7 +114,7 @@ enum PeerState { impl PeerState { fn is_ready_for_encryption(&self) -> bool { - if let PeerState::Connected(_) = self { + if let &PeerState::Connected(_) = self { true } else { false @@ -285,7 +285,7 @@ impl PeerManager where if peers.peers.insert(descriptor, Peer { encryptor: PeerState::Handshake(handshake), outbound: true, - their_node_id: None, + their_node_id: Some(their_node_id.clone()), their_features: None, pending_outbound_buffer: LinkedList::new(), @@ -313,7 +313,8 @@ impl PeerManager where /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> { - let handshake = PeerHandshake::new(&self.our_node_secret, &self.get_ephemeral_key()); + let mut handshake = PeerHandshake::new(&self.our_node_secret, &self.get_ephemeral_key()); + handshake.make_inbound(); let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { @@ -465,78 +466,83 @@ impl PeerManager where peer.pending_read_buffer.extend_from_slice(&data); while peer.pending_read_buffer.len() > 0 { - macro_rules! encode_and_send_msg { - ($msg: expr) => { - { - log_trace!(self, "Encoding and sending message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - if let PeerState::Connected(ref mut conduit) = peer.encryptor { - peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(&$msg)[..])); - } - peers.peers_needing_send.insert(peer_descriptor.clone()); - } + let mut conduit_option = None; + let mut remote_pubkey_option = None; + + if let &mut PeerState::Handshake(ref mut handshake) = &mut peer.encryptor { + let (response, conduit, remote_pubkey) = handshake.process_act(&peer.pending_read_buffer, None).unwrap(); + peer.pending_read_buffer.drain(..); // we read it all + + if let Some(key) = remote_pubkey { + remote_pubkey_option = Some(key); } - } - macro_rules! try_potential_handleerror { - ($thing: expr) => { - match $thing { - Ok(x) => x, - Err(e) => { - match e.action { - msgs::ErrorAction::DisconnectPeer { msg: _ } => { - //TODO: Try to push msg - log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err); - return Err(PeerHandleError{ no_connection_possible: false }); - }, - msgs::ErrorAction::IgnoreError => { - log_trace!(self, "Got Err handling message, ignoring because {}", e.err); - continue; - }, - msgs::ErrorAction::SendErrorMessage { msg } => { - log_trace!(self, "Got Err handling message, sending Error message because {}", e.err); - encode_and_send_msg!(msg); - continue; - }, - } - } - }; + peer.pending_outbound_buffer.push_back(response); + if let Some(conduit) = conduit { + conduit_option = Some(conduit); } } - macro_rules! insert_node_id { - () => { - match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) { - hash_map::Entry::Occupied(_) => { - log_trace!(self, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); - peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event - return Err(PeerHandleError{ no_connection_possible: false }) - }, - hash_map::Entry::Vacant(entry) => { - log_trace!(self, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); - entry.insert(peer_descriptor.clone()) - }, - }; - } + if let Some(key) = remote_pubkey_option { + peer.their_node_id = Some(key); } - if let PeerState::Handshake(ref mut handshake) = &mut peer.encryptor { - let (response, conduit, remote_pubkey) = handshake.process_act(&peer.pending_read_buffer, None).unwrap(); - peer.pending_read_buffer.drain(..); // we read it all + if let Some(conduit) = conduit_option { + // Rust 1.22 does not allow assignment in a borrowed context, even if mutable + peer.encryptor = PeerState::Connected(conduit); + } - peer.pending_outbound_buffer.push_back(response); - if let Some(conduit) = conduit { - peer.encryptor = PeerState::Connected(conduit); + if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { + + macro_rules! encode_and_send_msg { + ($msg: expr) => { + { + log_trace!(self, "Encoding and sending message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); + // we are in a context where conduit is known + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(&$msg)[..])); + peers.peers_needing_send.insert(peer_descriptor.clone()); + } + } + } + + macro_rules! try_potential_handleerror { + ($thing: expr) => { + match $thing { + Ok(x) => x, + Err(e) => { + match e.action { + msgs::ErrorAction::DisconnectPeer { msg: _ } => { + //TODO: Try to push msg + log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err); + return Err(PeerHandleError{ no_connection_possible: false }); + }, + msgs::ErrorAction::IgnoreError => { + log_trace!(self, "Got Err handling message, ignoring because {}", e.err); + continue; + }, + msgs::ErrorAction::SendErrorMessage { msg } => { + log_trace!(self, "Got Err handling message, sending Error message because {}", e.err); + encode_and_send_msg!(msg); + continue; + }, + } + } + }; + } } - } - if let PeerState::Connected(ref mut conduit) = &mut peer.encryptor { - let mut messages = conduit.decrypt_message_stream(Some(&peer.pending_read_buffer)); + let mut next_message_result = conduit.decrypt(&peer.pending_read_buffer); - if messages.len() != 1 { - break; // the length should initially be one, though there will be a possibility of decrypting multiple messages at once in the future + let offset = next_message_result.1; + if offset == 0 { + // nothing got read + break; + }else{ + peer.pending_read_buffer.drain(0..offset); } - let msg_data = messages.remove(1); + // something got read, so we definitely have a message + let msg_data = next_message_result.0.unwrap(); let mut reader = ::std::io::Cursor::new(&msg_data[..]); let message_result = wire::read(&mut reader); diff --git a/lightning/src/ln/peers/chacha.rs b/lightning/src/ln/peers/chacha.rs index 4b29b924388..e82e55a91c6 100644 --- a/lightning/src/ln/peers/chacha.rs +++ b/lightning/src/ln/peers/chacha.rs @@ -1,8 +1,9 @@ +use util::byte_utils; use util::chacha20poly1305rfc::ChaCha20Poly1305RFC; pub fn encrypt(key: &[u8], nonce: u64, associated_data: &[u8], plaintext: &[u8]) -> Vec { let mut nonce_bytes = [0; 12]; - nonce_bytes[4..].copy_from_slice(&nonce.to_le_bytes()); + nonce_bytes[4..].copy_from_slice(&byte_utils::le64_to_array(nonce)); let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce_bytes, associated_data); let mut ciphertext = vec![0u8; plaintext.len()]; @@ -17,11 +18,15 @@ pub fn encrypt(key: &[u8], nonce: u64, associated_data: &[u8], plaintext: &[u8]) pub fn decrypt(key: &[u8], nonce: u64, associated_data: &[u8], tagged_ciphertext: &[u8]) -> Result, String> { let mut nonce_bytes = [0; 12]; - nonce_bytes[4..].copy_from_slice(&nonce.to_le_bytes()); + nonce_bytes[4..].copy_from_slice(&byte_utils::le64_to_array(nonce)); let length = tagged_ciphertext.len(); - let ciphertext = &tagged_ciphertext[0..length - 16]; - let authentication_tag = &tagged_ciphertext[length - 16..length]; + if length < 16 { + return Err("ciphertext cannot be shorter than tag length of 16 bytes".to_string()); + } + let end_index = length - 16; + let ciphertext = &tagged_ciphertext[0..end_index]; + let authentication_tag = &tagged_ciphertext[end_index..length]; let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce_bytes, associated_data); let mut plaintext = vec![0u8; length - 16]; diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs index 28c83f3c772..019d3c11d63 100644 --- a/lightning/src/ln/peers/conduit.rs +++ b/lightning/src/ln/peers/conduit.rs @@ -1,6 +1,11 @@ +//! Handles all over the wire message encryption and decryption upon handshake completion. + use ln::peers::{chacha, hkdf}; +use util::byte_utils; /// Returned after a successful handshake to encrypt and decrypt communication with peer nodes +/// Automatically handles key rotation. +/// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering. pub struct Conduit { pub(crate) sending_key: [u8; 32], pub(crate) receiving_key: [u8; 32], @@ -15,9 +20,10 @@ pub struct Conduit { } impl Conduit { + /// Encrypt data to be sent to peer pub fn encrypt(&mut self, buffer: &[u8]) -> Vec { let length = buffer.len() as u16; - let length_bytes = length.to_be_bytes(); + let length_bytes = byte_utils::be16_to_array(length); let encrypted_length = chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes); self.increment_sending_nonce(); @@ -69,7 +75,7 @@ impl Conduit { } /// Decrypt a single message. Buffer is an undelimited amount of bytes - fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { // the response slice should have the same lifetime as the argument. It's the slice data is read from + pub(crate) fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { // the response slice should have the same lifetime as the argument. It's the slice data is read from if buffer.len() < 18 { return (None, 0); } @@ -78,9 +84,9 @@ impl Conduit { let length_vec = chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap(); let mut length_bytes = [0u8; 2]; length_bytes.copy_from_slice(length_vec.as_slice()); - let message_length = u16::from_be_bytes(length_bytes) as usize; + let message_length = byte_utils::slice_to_be16(&length_bytes) as usize; - let message_end_index = message_length + 18; // todo: abort if too short + let message_end_index = message_length + 18 + 16; // todo: abort if too short if buffer.len() < message_end_index { return (None, 0); } @@ -121,6 +127,7 @@ impl Conduit { #[cfg(test)] mod tests { + use hex; use ln::peers::conduit::Conduit; #[test] @@ -147,6 +154,16 @@ mod tests { read_buffer: None, }; + let mut remote_peer = Conduit { + sending_key: receiving_key, + receiving_key: sending_key, + sending_chaining_key: chaining_key, + receiving_chaining_key: chaining_key, + sending_nonce: 0, + receiving_nonce: 0, + read_buffer: None, + }; + let message = hex::decode("68656c6c6f").unwrap(); let mut encrypted_messages: Vec> = Vec::new(); @@ -161,5 +178,13 @@ mod tests { assert_eq!(encrypted_messages[501], hex::decode("1b186c57d44eb6de4c057c49940d79bb838a145cb528d6e8fd26dbe50a60ca2c104b56b60e45bd").unwrap()); assert_eq!(encrypted_messages[1000], hex::decode("4a2f3cc3b5e78ddb83dcb426d9863d9d9a723b0337c89dd0b005d89f8d3c05c52b76b29b740f09").unwrap()); assert_eq!(encrypted_messages[1001], hex::decode("2ecd8c8a5629d0d02ab457a0fdd0f7b90a192cd46be5ecb6ca570bfc5e268338b1a16cf4ef2d36").unwrap()); + + for _ in 0..1002 { + let encrypted_message = encrypted_messages.remove(0); + let mut decrypted_messages = remote_peer.decrypt_message_stream(Some(&encrypted_message)); + assert_eq!(decrypted_messages.len(), 1); + let decrypted_message = decrypted_messages.remove(0); + assert_eq!(decrypted_message, hex::decode("68656c6c6f").unwrap()); + } } } \ No newline at end of file diff --git a/lightning/src/ln/peers/handshake/acts.rs b/lightning/src/ln/peers/handshake/acts.rs index 1a42e5dd430..93e582908a7 100644 --- a/lightning/src/ln/peers/handshake/acts.rs +++ b/lightning/src/ln/peers/handshake/acts.rs @@ -1,15 +1,19 @@ +/// Wrapper for the first act message pub struct ActOne( pub(super) [u8; 50] ); +/// Wrapper for the second act message pub struct ActTwo( pub(super) [u8; 50] ); +/// Wrapper for the third act message pub struct ActThree( pub(super) [u8; 66] ); +/// Wrapper for any act message pub enum Act { One(ActOne), Two(ActTwo), @@ -17,15 +21,16 @@ pub enum Act { } impl Act { + /// Convert any act into a byte vector pub fn serialize(&self) -> Vec { match self { - Act::One(act) => { + &Act::One(ref act) => { act.0.to_vec() } - Act::Two(act) => { + &Act::Two(ref act) => { act.0.to_vec() } - Act::Three(act) => { + &Act::Three(ref act) => { act.0.to_vec() } } diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index 213ed2bbfa0..482b497149e 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -1,3 +1,9 @@ +//! Execute handshakes for peer-to-peer connection establishment. +//! Handshake states can be advanced automatically, or by manually calling the appropriate step. +//! Once complete, returns an instance of Conduit. + +use secp256k1; + use bitcoin_hashes::{Hash, HashEngine}; use bitcoin_hashes::sha256::Hash as Sha256; use secp256k1::{PublicKey, SecretKey}; @@ -13,6 +19,8 @@ mod hash; mod states; mod tests; +/// Object for managing handshakes. +/// Currently requires explicit ephemeral private key specification. pub struct PeerHandshake { state: Option, private_key: SecretKey, @@ -22,8 +30,8 @@ pub struct PeerHandshake { } impl PeerHandshake { + /// Instantiate a new handshake with a node identity secret key and an ephemeral private key pub fn new(private_key: &SecretKey, ephemeral_private_key: &SecretKey) -> Self { - let handshake = PeerHandshake { state: Some(HandshakeState::Blank), private_key: (*private_key).clone(), @@ -33,6 +41,7 @@ impl PeerHandshake { handshake } + /// Make the handshake object inbound in anticipation of a peer's first handshake act pub fn make_inbound(&mut self) { let public_key = Self::private_key_to_public_key(&self.private_key); let (hash, chaining_key) = Self::initialize_state(&public_key); @@ -71,12 +80,12 @@ impl PeerHandshake { let read_buffer_length = self.read_buffer.len(); match &self.state { - Some(HandshakeState::Blank) => { - let remote_public_key = remote_public_key.ok_or("Call make_initiator() first")?; + &Some(HandshakeState::Blank) => { + let remote_public_key = remote_public_key.ok_or("remote_public_key must be Some for outbound connections")?; let act_one = self.initiate(&remote_public_key)?; response = act_one.0.to_vec(); } - Some(HandshakeState::AwaitingActOne(_)) => { + &Some(HandshakeState::AwaitingActOne(_)) => { let act_length = 50; if read_buffer_length < act_length { return Err("need at least 50 bytes".to_string()); @@ -89,7 +98,7 @@ impl PeerHandshake { let act_two = self.process_act_one(ActOne(act_one_buffer))?; response = act_two.0.to_vec(); } - Some(HandshakeState::AwaitingActTwo(_)) => { + &Some(HandshakeState::AwaitingActTwo(_)) => { let act_length = 50; if read_buffer_length < act_length { return Err("need at least 50 bytes".to_string()); @@ -109,7 +118,7 @@ impl PeerHandshake { response = act_three.0.to_vec(); connected_peer = Some(conduit); } - Some(HandshakeState::AwaitingActThree(_)) => { + &Some(HandshakeState::AwaitingActThree(_)) => { let act_length = 66; if read_buffer_length < act_length { return Err("need at least 50 bytes".to_string()); @@ -136,8 +145,9 @@ impl PeerHandshake { Ok((response, connected_peer, remote_pubkey)) } + /// Initiate the handshake with a peer and return the first act pub fn initiate(&mut self, remote_public_key: &PublicKey) -> Result { - if let Some(HandshakeState::Blank) = &self.state {} else { + if let &Some(HandshakeState::Blank) = &self.state {} else { return Err("incorrect state".to_string()); } @@ -161,6 +171,7 @@ impl PeerHandshake { Ok(ActOne(act_one)) } + /// Process a peer's incoming first act and return the second act pub(crate) fn process_act_one(&mut self, act: ActOne) -> Result { let state = self.state.take(); let act_one_expectation = match state { @@ -209,6 +220,7 @@ impl PeerHandshake { Ok(ActTwo(act_two)) } + /// Process a peer's incoming second act and return the third act alongside a Conduit instance pub(crate) fn process_act_two(&mut self, act: ActTwo) -> Result<(ActThree, Conduit), String> { let state = self.state.take(); let act_two_expectation = match state { @@ -258,6 +270,7 @@ impl PeerHandshake { Ok((ActThree(act_three), connected_peer)) } + /// Process a peer's incoming third act and return a Conduit instance pub(crate) fn process_act_three(&mut self, act: ActThree) -> Result<(PublicKey, Conduit), String> { let state = self.state.take(); let act_three_expectation = match state { diff --git a/lightning/src/ln/peers/handshake/tests.rs b/lightning/src/ln/peers/handshake/tests.rs index b749f9ab13c..f0dcff6d993 100644 --- a/lightning/src/ln/peers/handshake/tests.rs +++ b/lightning/src/ln/peers/handshake/tests.rs @@ -1,5 +1,8 @@ #![cfg(test)] +use hex; +use secp256k1; + use secp256k1::key::{PublicKey, SecretKey}; use ln::peers::handshake::PeerHandshake; @@ -19,8 +22,18 @@ fn test_exchange() { let remote_public_key = PublicKey::from_secret_key(&curve, &remote_private_key); - let act_1_message = local_handshake.initiate(&remote_public_key); - let act_2_message = remote_handshake.process_act_one(act_1_message.unwrap()); - let act_3_message = local_handshake.process_act_two(act_2_message.unwrap()); - remote_handshake.process_act_three(act_3_message.unwrap().0).unwrap(); + let act_1 = local_handshake.initiate(&remote_public_key).unwrap(); + let act_1_hex = hex::encode(&act_1.0.to_vec()); + assert_eq!(act_1_hex, "00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a"); + + let act_2 = remote_handshake.process_act_one(act_1).unwrap(); + let act_2_hex = hex::encode(&act_2.0.to_vec()); + assert_eq!(act_2_hex, "0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae"); + + let act_2_result = local_handshake.process_act_two(act_2).unwrap(); + let act_3 = act_2_result.0; + let act_3_hex = hex::encode(&act_3.0.to_vec()); + assert_eq!(act_3_hex, "00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba"); + + remote_handshake.process_act_three(act_3).unwrap(); } \ No newline at end of file diff --git a/lightning/src/ln/peers/mod.rs b/lightning/src/ln/peers/mod.rs index 748356a8f12..23807e840d3 100644 --- a/lightning/src/ln/peers/mod.rs +++ b/lightning/src/ln/peers/mod.rs @@ -1,3 +1,8 @@ +//! Everything that has to do with over-the-wire peer communication. +//! The handshake module exposes mechanisms to conduct inbound and outbound handshakes. +//! When a handshake completes, it returns an instance of Conduit. +//! Conduit enables message encryption and decryption, and automatically handles key rotation. + mod chacha; pub mod conduit; pub mod handshake; From 19b7700e86b3de2889b11e80e2a554a1f55c4bb6 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Wed, 12 Feb 2020 17:22:12 -0800 Subject: [PATCH 06/27] allocate act messages without vector prevarication --- lightning/src/ln/peers/handshake/mod.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index 482b497149e..a53625891bf 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -252,11 +252,9 @@ impl PeerHandshake { let authentication_tag = chacha::encrypt(&temporary_key, 0, &hash.value, &[0; 0]); let (sending_key, receiving_key) = hkdf::derive(&chaining_key, &[0; 0]); - let mut act_three_vec = [0u8].to_vec(); - act_three_vec.extend_from_slice(&tagged_encrypted_pubkey); - act_three_vec.extend_from_slice(authentication_tag.as_slice()); let mut act_three = [0u8; 66]; - act_three.copy_from_slice(act_three_vec.as_slice()); + act_three[1..50].copy_from_slice(&tagged_encrypted_pubkey); + act_three[50..].copy_from_slice(authentication_tag.as_slice()); let connected_peer = Conduit { sending_key, @@ -330,11 +328,10 @@ impl PeerHandshake { hash.update(&tagged_ciphertext); - let mut act_vec = [0u8].to_vec(); - act_vec.extend_from_slice(&local_public_key.serialize()); - act_vec.extend_from_slice(tagged_ciphertext.as_slice()); let mut act = [0u8; 50]; - act.copy_from_slice(act_vec.as_slice()); + act[1..34].copy_from_slice(&local_public_key.serialize()); + act[34..].copy_from_slice(tagged_ciphertext.as_slice()); + (act, chaining_key, temporary_key) } From 17fda756e529a02fcc3317162232e16b362db750 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Wed, 12 Feb 2020 17:29:43 -0800 Subject: [PATCH 07/27] reduce vector allocations for message encryption --- lightning/src/ln/peers/conduit.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs index 019d3c11d63..bf51d3ecbc3 100644 --- a/lightning/src/ln/peers/conduit.rs +++ b/lightning/src/ln/peers/conduit.rs @@ -3,7 +3,8 @@ use ln::peers::{chacha, hkdf}; use util::byte_utils; -/// Returned after a successful handshake to encrypt and decrypt communication with peer nodes +/// Returned after a successful handshake to encrypt and decrypt communication with peer nodes. +/// It should not normally be manually instantiated. /// Automatically handles key rotation. /// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering. pub struct Conduit { @@ -25,14 +26,14 @@ impl Conduit { let length = buffer.len() as u16; let length_bytes = byte_utils::be16_to_array(length); - let encrypted_length = chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes); + let mut ciphertext = vec![0u8; 18 + length as usize + 16]; + + ciphertext[0..18].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes)); self.increment_sending_nonce(); - let encrypted_message = chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], buffer); + ciphertext[18..].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], buffer)); self.increment_sending_nonce(); - let mut ciphertext = encrypted_length; - ciphertext.extend_from_slice(&encrypted_message); ciphertext } From 8169b3158db72fbdeed6ad87586ce04014b6ac5a Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Wed, 19 Feb 2020 11:14:47 -0800 Subject: [PATCH 08/27] address some of Jeff's comments pertaining to message decryption, constants, and type definitions respond to Jeff's comments and add node pubkeys to map simplify review by means of 3 scopes adjust scope indentation resolve merge conflicts respond to more of Jeff's comments constantify key rotation index for conduit --- lightning/src/ln/peer_handler.rs | 403 +++++++++++---------- lightning/src/ln/peers/chacha.rs | 3 +- lightning/src/ln/peers/conduit.rs | 87 +++-- lightning/src/ln/peers/handshake/acts.rs | 10 +- lightning/src/ln/peers/handshake/mod.rs | 73 ++-- lightning/src/ln/peers/handshake/states.rs | 2 +- 6 files changed, 302 insertions(+), 276 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 0aebdf1dc4e..f0c6dc6603f 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -108,16 +108,15 @@ enum InitSyncTracker{ } enum PeerState { - Handshake(PeerHandshake), + Authenticating(PeerHandshake), Connected(Conduit), } impl PeerState { fn is_ready_for_encryption(&self) -> bool { - if let &PeerState::Connected(_) = self { - true - } else { - false + match self { + &PeerState::Connected(_) => true, + _ => false } } } @@ -283,7 +282,7 @@ impl PeerManager where let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { - encryptor: PeerState::Handshake(handshake), + encryptor: PeerState::Authenticating(handshake), outbound: true, their_node_id: Some(their_node_id.clone()), their_features: None, @@ -318,7 +317,7 @@ impl PeerManager where let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { - encryptor: PeerState::Handshake(handshake), + encryptor: PeerState::Authenticating(handshake), outbound: false, their_node_id: None, their_features: None, @@ -469,9 +468,9 @@ impl PeerManager where let mut conduit_option = None; let mut remote_pubkey_option = None; - if let &mut PeerState::Handshake(ref mut handshake) = &mut peer.encryptor { + if let &mut PeerState::Authenticating(ref mut handshake) = &mut peer.encryptor { let (response, conduit, remote_pubkey) = handshake.process_act(&peer.pending_read_buffer, None).unwrap(); - peer.pending_read_buffer.drain(..); // we read it all + peer.pending_read_buffer = Vec::new(); // empty the pending read buffer if let Some(key) = remote_pubkey { remote_pubkey_option = Some(key); @@ -490,10 +489,22 @@ impl PeerManager where if let Some(conduit) = conduit_option { // Rust 1.22 does not allow assignment in a borrowed context, even if mutable peer.encryptor = PeerState::Connected(conduit); + + // the handshake has finished, so one way or another, we now have their node id + match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) { + hash_map::Entry::Occupied(_) => { + log_trace!(self, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); + peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event + return Err(PeerHandleError{ no_connection_possible: false }) + }, + hash_map::Entry::Vacant(entry) => { + log_trace!(self, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); + entry.insert(peer_descriptor.clone()) + }, + }; } if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { - macro_rules! encode_and_send_msg { ($msg: expr) => { { @@ -531,211 +542,211 @@ impl PeerManager where } } - let mut next_message_result = conduit.decrypt(&peer.pending_read_buffer); - - let offset = next_message_result.1; - if offset == 0 { - // nothing got read + let message_option = conduit.decrypt_single_message(Some(&peer.pending_read_buffer.clone())); + peer.pending_read_buffer = Vec::new(); // empty the pending read buffer + let msg_data = if let Some(message) = message_option { + message + } else { break; - }else{ - peer.pending_read_buffer.drain(0..offset); - } - - // something got read, so we definitely have a message - let msg_data = next_message_result.0.unwrap(); - - let mut reader = ::std::io::Cursor::new(&msg_data[..]); - let message_result = wire::read(&mut reader); - let message = match message_result { - Ok(x) => x, - Err(e) => { - match e { - msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }), - msgs::DecodeError::UnknownRequiredFeature => { - log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to update!"); - continue; - } - msgs::DecodeError::InvalidValue => { - log_debug!(self, "Got an invalid value while deserializing message"); - return Err(PeerHandleError { no_connection_possible: false }); - } - msgs::DecodeError::ShortRead => { - log_debug!(self, "Deserialization failed due to shortness of message"); - return Err(PeerHandleError { no_connection_possible: false }); - } - msgs::DecodeError::ExtraAddressesPerType => { - log_debug!(self, "Error decoding message, ignoring due to lnd spec incompatibility. See https://github.com/lightningnetwork/lnd/issues/1407"); - continue; - } - msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }), - msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }), - } - } }; - log_trace!(self, "Received message of type {} from {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - - // Need an Init as first message - if let wire::Message::Init(_) = message { - } else if peer.their_features.is_none() { - log_trace!(self, "Peer {} sent non-Init first message", log_pubkey!(peer.their_node_id.unwrap())); - return Err(PeerHandleError{ no_connection_possible: false }); - } - - match message { - // Setup and Control messages: - wire::Message::Init(msg) => { - if msg.features.requires_unknown_bits() { - log_info!(self, "Peer global features required unknown version bits"); - return Err(PeerHandleError{ no_connection_possible: true }); - } - if msg.features.requires_unknown_bits() { - log_info!(self, "Peer local features required unknown version bits"); - return Err(PeerHandleError{ no_connection_possible: true }); - } - if peer.their_features.is_some() { - return Err(PeerHandleError{ no_connection_possible: false }); - } - - log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", - if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, - if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, - if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, - if msg.features.supports_unknown_bits() { "present" } else { "none" }, - if msg.features.supports_unknown_bits() { "present" } else { "none" }); + { + { + { + let mut reader = ::std::io::Cursor::new(&msg_data[..]); + let message_result = wire::read(&mut reader); + let message = match message_result { + Ok(x) => x, + Err(e) => { + match e { + msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }), + msgs::DecodeError::UnknownRequiredFeature => { + log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to update!"); + continue; + } + msgs::DecodeError::InvalidValue => { + log_debug!(self, "Got an invalid value while deserializing message"); + return Err(PeerHandleError { no_connection_possible: false }); + } + msgs::DecodeError::ShortRead => { + log_debug!(self, "Deserialization failed due to shortness of message"); + return Err(PeerHandleError { no_connection_possible: false }); + } + msgs::DecodeError::ExtraAddressesPerType => { + log_debug!(self, "Error decoding message, ignoring due to lnd spec incompatibility. See https://github.com/lightningnetwork/lnd/issues/1407"); + continue; + } + msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }), + msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }), + } + } + }; - if msg.features.initial_routing_sync() { - peer.sync_status = InitSyncTracker::ChannelsSyncing(0); - peers.peers_needing_send.insert(peer_descriptor.clone()); - } + log_trace!(self, "Received message of type {} from {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - if !peer.outbound { - let mut features = InitFeatures::supported(); - if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { - features.set_initial_routing_sync(); + // Need an Init as first message + if let wire::Message::Init(_) = message {} else if peer.their_features.is_none() { + log_trace!(self, "Peer {} sent non-Init first message", log_pubkey!(peer.their_node_id.unwrap())); + return Err(PeerHandleError { no_connection_possible: false }); } - let resp = msgs::Init { features }; - encode_and_send_msg!(resp); - } - - self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); - peer.their_features = Some(msg.features); - }, - wire::Message::Error(msg) => { - let mut data_is_printable = true; - for b in msg.data.bytes() { - if b < 32 || b > 126 { - data_is_printable = false; - break; - } - } + match message { + // Setup and Control messages: + wire::Message::Init(msg) => { + if msg.features.requires_unknown_bits() { + log_info!(self, "Peer global features required unknown version bits"); + return Err(PeerHandleError { no_connection_possible: true }); + } + if msg.features.requires_unknown_bits() { + log_info!(self, "Peer local features required unknown version bits"); + return Err(PeerHandleError { no_connection_possible: true }); + } + if peer.their_features.is_some() { + return Err(PeerHandleError { no_connection_possible: false }); + } + + log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", + if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, + if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, + if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, + if msg.features.supports_unknown_bits() { "present" } else { "none" }, + if msg.features.supports_unknown_bits() { "present" } else { "none" }); + + if msg.features.initial_routing_sync() { + peer.sync_status = InitSyncTracker::ChannelsSyncing(0); + peers.peers_needing_send.insert(peer_descriptor.clone()); + } + + if !peer.outbound { + let mut features = InitFeatures::supported(); + if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { + features.set_initial_routing_sync(); + } + + let resp = msgs::Init { features }; + encode_and_send_msg!(resp); + } + + self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); + peer.their_features = Some(msg.features); + } + wire::Message::Error(msg) => { + let mut data_is_printable = true; + for b in msg.data.bytes() { + if b < 32 || b > 126 { + data_is_printable = false; + break; + } + } + + if data_is_printable { + log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data); + } else { + log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap())); + } + self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); + if msg.channel_id == [0; 32] { + return Err(PeerHandleError { no_connection_possible: true }); + } + } - if data_is_printable { - log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data); - } else { - log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap())); - } - self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); - if msg.channel_id == [0; 32] { - return Err(PeerHandleError{ no_connection_possible: true }); - } - }, + wire::Message::Ping(msg) => { + if msg.ponglen < 65532 { + let resp = msgs::Pong { byteslen: msg.ponglen }; + encode_and_send_msg!(resp); + } + } + wire::Message::Pong(_msg) => { + peer.awaiting_pong = false; + } - wire::Message::Ping(msg) => { - if msg.ponglen < 65532 { - let resp = msgs::Pong { byteslen: msg.ponglen }; - encode_and_send_msg!(resp); - } - }, - wire::Message::Pong(_msg) => { - peer.awaiting_pong = false; - }, + // Channel messages: + wire::Message::OpenChannel(msg) => { + self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); + } + wire::Message::AcceptChannel(msg) => { + self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); + } - // Channel messages: - wire::Message::OpenChannel(msg) => { - self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - }, - wire::Message::AcceptChannel(msg) => { - self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - }, + wire::Message::FundingCreated(msg) => { + self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::FundingSigned(msg) => { + self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::FundingLocked(msg) => { + self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); + } - wire::Message::FundingCreated(msg) => { - self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::FundingSigned(msg) => { - self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::FundingLocked(msg) => { - self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); - }, + wire::Message::Shutdown(msg) => { + self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::ClosingSigned(msg) => { + self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); + } - wire::Message::Shutdown(msg) => { - self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::ClosingSigned(msg) => { - self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); - }, + // Commitment messages: + wire::Message::UpdateAddHTLC(msg) => { + self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::UpdateFulfillHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::UpdateFailHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::UpdateFailMalformedHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); + } - // Commitment messages: - wire::Message::UpdateAddHTLC(msg) => { - self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::UpdateFulfillHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::UpdateFailHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::UpdateFailMalformedHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); - }, + wire::Message::CommitmentSigned(msg) => { + self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::RevokeAndACK(msg) => { + self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::UpdateFee(msg) => { + self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::ChannelReestablish(msg) => { + self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); + } - wire::Message::CommitmentSigned(msg) => { - self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::RevokeAndACK(msg) => { - self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::UpdateFee(msg) => { - self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::ChannelReestablish(msg) => { - self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); - }, + // Routing messages: + wire::Message::AnnouncementSignatures(msg) => { + self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::ChannelAnnouncement(msg) => { + let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_announcement(&msg)); - // Routing messages: - wire::Message::AnnouncementSignatures(msg) => { - self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); - }, - wire::Message::ChannelAnnouncement(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_announcement(&msg)); + if should_forward { + // TODO: forward msg along to all our other peers! + } + } + wire::Message::NodeAnnouncement(msg) => { + let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); - if should_forward { - // TODO: forward msg along to all our other peers! - } - }, - wire::Message::NodeAnnouncement(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); + if should_forward { + // TODO: forward msg along to all our other peers! + } + } + wire::Message::ChannelUpdate(msg) => { + let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg)); - if should_forward { - // TODO: forward msg along to all our other peers! - } - }, - wire::Message::ChannelUpdate(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg)); + if should_forward { + // TODO: forward msg along to all our other peers! + } + } - if should_forward { - // TODO: forward msg along to all our other peers! + // Unknown messages: + wire::Message::Unknown(msg_type) if msg_type.is_even() => { + // Fail the channel if message is an even, unknown type as per BOLT #1. + return Err(PeerHandleError { no_connection_possible: true }); + } + wire::Message::Unknown(_) => {} + } } - }, - - // Unknown messages: - wire::Message::Unknown(msg_type) if msg_type.is_even() => { - // Fail the channel if message is an even, unknown type as per BOLT #1. - return Err(PeerHandleError{ no_connection_possible: true }); - }, - wire::Message::Unknown(_) => {}, + } } } diff --git a/lightning/src/ln/peers/chacha.rs b/lightning/src/ln/peers/chacha.rs index e82e55a91c6..4e8d948706f 100644 --- a/lightning/src/ln/peers/chacha.rs +++ b/lightning/src/ln/peers/chacha.rs @@ -1,6 +1,8 @@ use util::byte_utils; use util::chacha20poly1305rfc::ChaCha20Poly1305RFC; +pub const TAG_SIZE: usize = 16; + pub fn encrypt(key: &[u8], nonce: u64, associated_data: &[u8], plaintext: &[u8]) -> Vec { let mut nonce_bytes = [0; 12]; nonce_bytes[4..].copy_from_slice(&byte_utils::le64_to_array(nonce)); @@ -15,7 +17,6 @@ pub fn encrypt(key: &[u8], nonce: u64, associated_data: &[u8], plaintext: &[u8]) tagged_ciphertext } - pub fn decrypt(key: &[u8], nonce: u64, associated_data: &[u8], tagged_ciphertext: &[u8]) -> Result, String> { let mut nonce_bytes = [0; 12]; nonce_bytes[4..].copy_from_slice(&byte_utils::le64_to_array(nonce)); diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs index bf51d3ecbc3..2fcec64fc05 100644 --- a/lightning/src/ln/peers/conduit.rs +++ b/lightning/src/ln/peers/conduit.rs @@ -3,16 +3,23 @@ use ln::peers::{chacha, hkdf}; use util::byte_utils; +pub(super) type SymmetricKey = [u8; 32]; + +const MESSAGE_LENGTH_HEADER_SIZE: usize = 2; +const TAGGED_MESSAGE_LENGTH_HEADER_SIZE: usize = MESSAGE_LENGTH_HEADER_SIZE + chacha::TAG_SIZE; + +const KEY_ROTATION_INDEX: u32 = 1000; + /// Returned after a successful handshake to encrypt and decrypt communication with peer nodes. /// It should not normally be manually instantiated. /// Automatically handles key rotation. /// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering. pub struct Conduit { - pub(crate) sending_key: [u8; 32], - pub(crate) receiving_key: [u8; 32], + pub(crate) sending_key: SymmetricKey, + pub(crate) receiving_key: SymmetricKey, - pub(crate) sending_chaining_key: [u8; 32], - pub(crate) receiving_chaining_key: [u8; 32], + pub(crate) sending_chaining_key: SymmetricKey, + pub(crate) receiving_chaining_key: SymmetricKey, pub(crate) receiving_nonce: u32, pub(crate) sending_nonce: u32, @@ -26,24 +33,27 @@ impl Conduit { let length = buffer.len() as u16; let length_bytes = byte_utils::be16_to_array(length); - let mut ciphertext = vec![0u8; 18 + length as usize + 16]; + let mut ciphertext = vec![0u8; TAGGED_MESSAGE_LENGTH_HEADER_SIZE + length as usize + chacha::TAG_SIZE]; - ciphertext[0..18].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes)); + ciphertext[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes)); self.increment_sending_nonce(); - ciphertext[18..].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], buffer)); + ciphertext[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], buffer)); self.increment_sending_nonce(); ciphertext } pub(super) fn read(&mut self, data: &[u8]) { - let mut read_buffer = self.read_buffer.get_or_insert(Vec::new()); + let read_buffer = self.read_buffer.get_or_insert(Vec::new()); read_buffer.extend_from_slice(data); } - /// Add newly received data from the peer node to the buffer and decrypt all possible messages - pub fn decrypt_message_stream(&mut self, new_data: Option<&[u8]>) -> Vec> { + /// Decrypt a single message. If data containing more than one message has been received, + /// only the first message will be returned, and the rest stored in the internal buffer. + /// If a message pending in the buffer still hasn't been decrypted, that message will be + /// returned in lieu of anything new, even if new data is provided. + pub fn decrypt_single_message(&mut self, new_data: Option<&[u8]>) -> Option> { let mut read_buffer = if let Some(buffer) = self.read_buffer.take() { buffer } else { @@ -54,45 +64,34 @@ impl Conduit { read_buffer.extend_from_slice(data); } - let mut messages = Vec::new(); - - loop { - // todo: find way that won't require cloning the entire buffer - let (current_message, offset) = self.decrypt(&read_buffer[..]); - if offset == 0 { - break; - } - - read_buffer.drain(0..offset); + let (current_message, offset) = self.decrypt(&read_buffer[..]); + read_buffer.drain(0..offset); // drain the read buffer + self.read_buffer = Some(read_buffer); // assign the new value to the built-in buffer - if let Some(message) = current_message { - messages.push(message); - } else { - break; - } + if offset == 0 { + return None; } - messages + current_message } - /// Decrypt a single message. Buffer is an undelimited amount of bytes pub(crate) fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { // the response slice should have the same lifetime as the argument. It's the slice data is read from - if buffer.len() < 18 { + if buffer.len() < TAGGED_MESSAGE_LENGTH_HEADER_SIZE { return (None, 0); } - let encrypted_length = &buffer[0..18]; // todo: abort if too short + let encrypted_length = &buffer[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE]; // todo: abort if too short let length_vec = chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap(); - let mut length_bytes = [0u8; 2]; + let mut length_bytes = [0u8; MESSAGE_LENGTH_HEADER_SIZE]; length_bytes.copy_from_slice(length_vec.as_slice()); let message_length = byte_utils::slice_to_be16(&length_bytes) as usize; - let message_end_index = message_length + 18 + 16; // todo: abort if too short + let message_end_index = TAGGED_MESSAGE_LENGTH_HEADER_SIZE + message_length + chacha::TAG_SIZE; // todo: abort if too short if buffer.len() < message_end_index { return (None, 0); } - let encrypted_message = &buffer[18..message_end_index]; + let encrypted_message = &buffer[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..message_end_index]; self.increment_receiving_nonce(); @@ -111,15 +110,15 @@ impl Conduit { Self::increment_nonce(&mut self.receiving_nonce, &mut self.receiving_chaining_key, &mut self.receiving_key); } - fn increment_nonce(nonce: &mut u32, chaining_key: &mut [u8; 32], key: &mut [u8; 32]) { + fn increment_nonce(nonce: &mut u32, chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) { *nonce += 1; - if *nonce == 1000 { + if *nonce == KEY_ROTATION_INDEX { Self::rotate_key(chaining_key, key); *nonce = 0; } } - fn rotate_key(chaining_key: &mut [u8; 32], key: &mut [u8; 32]) { + fn rotate_key(chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) { let (new_chaining_key, new_key) = hkdf::derive(chaining_key, key); chaining_key.copy_from_slice(&new_chaining_key); key.copy_from_slice(&new_key); @@ -132,6 +131,7 @@ mod tests { use ln::peers::conduit::Conduit; #[test] + /// Based on RFC test vectors: https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#message-encryption-tests fn test_chaining() { let chaining_key_vec = hex::decode("919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01").unwrap(); let mut chaining_key = [0u8; 32]; @@ -180,11 +180,18 @@ mod tests { assert_eq!(encrypted_messages[1000], hex::decode("4a2f3cc3b5e78ddb83dcb426d9863d9d9a723b0337c89dd0b005d89f8d3c05c52b76b29b740f09").unwrap()); assert_eq!(encrypted_messages[1001], hex::decode("2ecd8c8a5629d0d02ab457a0fdd0f7b90a192cd46be5ecb6ca570bfc5e268338b1a16cf4ef2d36").unwrap()); - for _ in 0..1002 { - let encrypted_message = encrypted_messages.remove(0); - let mut decrypted_messages = remote_peer.decrypt_message_stream(Some(&encrypted_message)); - assert_eq!(decrypted_messages.len(), 1); - let decrypted_message = decrypted_messages.remove(0); + for _ in 0..501 { + // read two messages at once, filling buffer + let mut current_encrypted_message = encrypted_messages.remove(0); + let mut next_encrypted_message = encrypted_messages.remove(0); + current_encrypted_message.extend_from_slice(&next_encrypted_message); + let decrypted_message = remote_peer.decrypt_single_message(Some(¤t_encrypted_message)).unwrap(); + assert_eq!(decrypted_message, hex::decode("68656c6c6f").unwrap()); + } + + for _ in 0..501 { + // decrypt messages directly from buffer without adding to it + let decrypted_message = remote_peer.decrypt_single_message(None).unwrap(); assert_eq!(decrypted_message, hex::decode("68656c6c6f").unwrap()); } } diff --git a/lightning/src/ln/peers/handshake/acts.rs b/lightning/src/ln/peers/handshake/acts.rs index 93e582908a7..4f29d0e4f8d 100644 --- a/lightning/src/ln/peers/handshake/acts.rs +++ b/lightning/src/ln/peers/handshake/acts.rs @@ -1,16 +1,20 @@ +pub const ACT_ONE_LENGTH: usize = 50; +pub const ACT_TWO_LENGTH: usize = 50; +pub const ACT_THREE_LENGTH: usize = 66; + /// Wrapper for the first act message pub struct ActOne( - pub(super) [u8; 50] + pub(super) [u8; ACT_ONE_LENGTH] ); /// Wrapper for the second act message pub struct ActTwo( - pub(super) [u8; 50] + pub(super) [u8; ACT_TWO_LENGTH] ); /// Wrapper for the third act message pub struct ActThree( - pub(super) [u8; 66] + pub(super) [u8; ACT_THREE_LENGTH] ); /// Wrapper for any act message diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index a53625891bf..fd9380f8fec 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -9,8 +9,8 @@ use bitcoin_hashes::sha256::Hash as Sha256; use secp256k1::{PublicKey, SecretKey}; use ln::peers::{chacha, hkdf}; -use ln::peers::conduit::Conduit; -use ln::peers::handshake::acts::{ActOne, ActThree, ActTwo}; +use ln::peers::conduit::{Conduit, SymmetricKey}; +use ln::peers::handshake::acts::{ActOne, ActThree, ActTwo, ACT_ONE_LENGTH, ACT_TWO_LENGTH, ACT_THREE_LENGTH}; use ln::peers::handshake::hash::HandshakeHash; use ln::peers::handshake::states::{ActOneExpectation, ActThreeExpectation, ActTwoExpectation, HandshakeState}; @@ -32,13 +32,12 @@ pub struct PeerHandshake { impl PeerHandshake { /// Instantiate a new handshake with a node identity secret key and an ephemeral private key pub fn new(private_key: &SecretKey, ephemeral_private_key: &SecretKey) -> Self { - let handshake = PeerHandshake { - state: Some(HandshakeState::Blank), + Self { + state: Some(HandshakeState::Uninitiated), private_key: (*private_key).clone(), ephemeral_private_key: (*ephemeral_private_key).clone(), read_buffer: Vec::new(), - }; - handshake + } } /// Make the handshake object inbound in anticipation of a peer's first handshake act @@ -52,7 +51,6 @@ impl PeerHandshake { } fn initialize_state(public_key: &PublicKey) -> (HandshakeHash, [u8; 32]) { - // do the proper initialization let protocol_name = b"Noise_XK_secp256k1_ChaChaPoly_SHA256"; let prologue = b"lightning"; @@ -66,11 +64,19 @@ impl PeerHandshake { let mut hash = HandshakeHash::new(initial_hash_preimage.as_slice()); hash.update(&public_key.serialize()); - (hash, chaining_key) // hash, chaining_key + (hash, chaining_key) } /// Process act dynamically - /// The role must be set before this method can be called + /// # Arguments + /// `input`: Byte slice received from peer as part of the handshake protocol + /// `remote_public_key`: If outbound, the peer's static identity public key needs is required for the handshake initiation + /// + /// # Return values + /// Returns a tuple with the following components: + /// `.0`: Byte vector containing the next act to send back to the peer per the handshake protocol + /// `.1`: Conduit option if the handshake was just processed to completion and messages can now be encrypted and decrypted + /// `.2`: Public key option if the handshake was inbound and the peer's static identity pubkey was just learned pub fn process_act(&mut self, input: &[u8], remote_public_key: Option<&PublicKey>) -> Result<(Vec, Option, Option), String> { let mut response: Vec = Vec::new(); let mut connected_peer = None; @@ -80,7 +86,7 @@ impl PeerHandshake { let read_buffer_length = self.read_buffer.len(); match &self.state { - &Some(HandshakeState::Blank) => { + &Some(HandshakeState::Uninitiated) => { let remote_public_key = remote_public_key.ok_or("remote_public_key must be Some for outbound connections")?; let act_one = self.initiate(&remote_public_key)?; response = act_one.0.to_vec(); @@ -91,22 +97,21 @@ impl PeerHandshake { return Err("need at least 50 bytes".to_string()); } - let mut act_one_buffer = [0u8; 50]; - act_one_buffer.copy_from_slice(&self.read_buffer[..act_length]); - self.read_buffer.drain(..act_length); + let mut act_one_buffer = [0u8; ACT_ONE_LENGTH]; + act_one_buffer.copy_from_slice(&self.read_buffer[..ACT_ONE_LENGTH]); + self.read_buffer.drain(..ACT_ONE_LENGTH); let act_two = self.process_act_one(ActOne(act_one_buffer))?; response = act_two.0.to_vec(); } &Some(HandshakeState::AwaitingActTwo(_)) => { - let act_length = 50; - if read_buffer_length < act_length { + if read_buffer_length < ACT_TWO_LENGTH { return Err("need at least 50 bytes".to_string()); } - let mut act_two_buffer = [0u8; 50]; - act_two_buffer.copy_from_slice(&self.read_buffer[..act_length]); - self.read_buffer.drain(..act_length); + let mut act_two_buffer = [0u8; ACT_TWO_LENGTH]; + act_two_buffer.copy_from_slice(&self.read_buffer[..ACT_TWO_LENGTH]); + self.read_buffer.drain(..ACT_TWO_LENGTH); let (act_three, mut conduit) = self.process_act_two(ActTwo(act_two_buffer))?; @@ -119,14 +124,13 @@ impl PeerHandshake { connected_peer = Some(conduit); } &Some(HandshakeState::AwaitingActThree(_)) => { - let act_length = 66; - if read_buffer_length < act_length { - return Err("need at least 50 bytes".to_string()); + if read_buffer_length < ACT_THREE_LENGTH { + return Err("need at least 66 bytes".to_string()); } - let mut act_three_buffer = [0u8; 66]; - act_three_buffer.copy_from_slice(&self.read_buffer[..act_length]); - self.read_buffer.drain(..act_length); + let mut act_three_buffer = [0u8; ACT_THREE_LENGTH]; + act_three_buffer.copy_from_slice(&self.read_buffer[..ACT_THREE_LENGTH]); + self.read_buffer.drain(..ACT_THREE_LENGTH); let (public_key, mut conduit) = self.process_act_three(ActThree(act_three_buffer))?; @@ -147,14 +151,14 @@ impl PeerHandshake { /// Initiate the handshake with a peer and return the first act pub fn initiate(&mut self, remote_public_key: &PublicKey) -> Result { - if let &Some(HandshakeState::Blank) = &self.state {} else { + if let &Some(HandshakeState::Uninitiated) = &self.state {} else { return Err("incorrect state".to_string()); } let (mut hash, chaining_key) = Self::initialize_state(&remote_public_key); // serialize act one - let (act_one, chaining_key, temporary_key) = self.calculate_act_message( + let (act_one, chaining_key, temporary_key) = Self::calculate_act_message( &self.ephemeral_private_key, remote_public_key, chaining_key, @@ -176,9 +180,8 @@ impl PeerHandshake { let state = self.state.take(); let act_one_expectation = match state { Some(HandshakeState::AwaitingActOne(act_state)) => act_state, - Some(HandshakeState::Blank) => { + Some(HandshakeState::Uninitiated) => { // this can also be initiated from a blank state - // public key let public_key = Self::private_key_to_public_key(&self.private_key); let (hash, chaining_key) = Self::initialize_state(&public_key); ActOneExpectation { @@ -193,7 +196,7 @@ impl PeerHandshake { }; let mut hash = act_one_expectation.hash; - let (remote_ephemeral_public_key, chaining_key, _) = self.process_act_message( + let (remote_ephemeral_public_key, chaining_key, _) = Self::process_act_message( act.0, &self.private_key, act_one_expectation.chaining_key, @@ -202,7 +205,7 @@ impl PeerHandshake { let ephemeral_private_key = (*&self.ephemeral_private_key).clone(); - let (act_two, chaining_key, temporary_key) = self.calculate_act_message( + let (act_two, chaining_key, temporary_key) = Self::calculate_act_message( &ephemeral_private_key, &remote_ephemeral_public_key, chaining_key, @@ -232,7 +235,7 @@ impl PeerHandshake { }; let mut hash = act_two_expectation.hash; - let (remote_ephemeral_public_key, chaining_key, temporary_key) = self.process_act_message( + let (remote_ephemeral_public_key, chaining_key, temporary_key) = Self::process_act_message( act.0, &act_two_expectation.ephemeral_private_key, act_two_expectation.chaining_key, @@ -317,7 +320,7 @@ impl PeerHandshake { Ok((remote_pubkey, connected_peer)) } - fn calculate_act_message(&self, local_private_key: &SecretKey, remote_public_key: &PublicKey, chaining_key: [u8; 32], hash: &mut HandshakeHash) -> ([u8; 50], [u8; 32], [u8; 32]) { + fn calculate_act_message(local_private_key: &SecretKey, remote_public_key: &PublicKey, chaining_key: [u8; 32], hash: &mut HandshakeHash) -> ([u8; 50], SymmetricKey, SymmetricKey) { let local_public_key = Self::private_key_to_public_key(local_private_key); hash.update(&local_public_key.serialize()); @@ -335,7 +338,7 @@ impl PeerHandshake { (act, chaining_key, temporary_key) } - fn process_act_message(&self, act_bytes: [u8; 50], local_private_key: &SecretKey, chaining_key: [u8; 32], hash: &mut HandshakeHash) -> Result<(PublicKey, [u8; 32], [u8; 32]), String> { + fn process_act_message(act_bytes: [u8; 50], local_private_key: &SecretKey, chaining_key: [u8; 32], hash: &mut HandshakeHash) -> Result<(PublicKey, SymmetricKey, SymmetricKey), String> { let version = act_bytes[0]; if version != 0 { return Err("unexpected version".to_string()); @@ -360,7 +363,7 @@ impl PeerHandshake { // HKDF(chaining key, ECDH) -> chaining key' + next temporary key let (chaining_key, temporary_key) = hkdf::derive(&chaining_key, &ecdh); - // Validate chacha tag (temporary key, 0, self.hash, chacha_tag) + // Validate chacha tag (temporary key, 0, hash, chacha_tag) let _tag_check = chacha::decrypt(&temporary_key, 0, &hash.value, &chacha_tag)?; hash.update(&chacha_tag); @@ -374,7 +377,7 @@ impl PeerHandshake { pk_object } - fn ecdh(private_key: &SecretKey, public_key: &PublicKey) -> [u8; 32] { + fn ecdh(private_key: &SecretKey, public_key: &PublicKey) -> SymmetricKey { let curve = secp256k1::Secp256k1::new(); let mut pk_object = public_key.clone(); pk_object.mul_assign(&curve, &private_key[..]).expect("invalid multiplication"); diff --git a/lightning/src/ln/peers/handshake/states.rs b/lightning/src/ln/peers/handshake/states.rs index 836be023a0d..643d7b16f9a 100644 --- a/lightning/src/ln/peers/handshake/states.rs +++ b/lightning/src/ln/peers/handshake/states.rs @@ -2,7 +2,7 @@ use ln::peers::handshake::hash::HandshakeHash; use secp256k1::{SecretKey, PublicKey}; pub enum HandshakeState { - Blank, + Uninitiated, AwaitingActOne(ActOneExpectation), AwaitingActTwo(ActTwoExpectation), AwaitingActThree(ActThreeExpectation), From f1002c5493b999d51a285e0d753ac451b623d54d Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Wed, 19 Feb 2020 15:47:26 -0800 Subject: [PATCH 09/27] Use type standin for remaining act lengths when parsing. Use the same handshake method `process_act` across both call sites from peer_handler.rs. --- lightning/src/ln/peer_handler.rs | 3 +-- lightning/src/ln/peers/conduit.rs | 6 +++--- lightning/src/ln/peers/handshake/mod.rs | 5 ++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index f0c6dc6603f..8121a7465ef 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -277,8 +277,7 @@ impl PeerManager where /// disconnect_event. pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result, PeerHandleError> { let mut handshake = PeerHandshake::new(&self.our_node_secret, &self.get_ephemeral_key()); - let act_one = handshake.initiate(&their_node_id).unwrap(); - let res = Act::One(act_one).serialize(); + let (res, ..) = handshake.process_act(&[], Some(&their_node_id)).unwrap(); let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs index 2fcec64fc05..e3275dcd447 100644 --- a/lightning/src/ln/peers/conduit.rs +++ b/lightning/src/ln/peers/conduit.rs @@ -75,15 +75,15 @@ impl Conduit { current_message } - pub(crate) fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { // the response slice should have the same lifetime as the argument. It's the slice data is read from + /// Decrypt a message from the beginning of the provided buffer. Returns the consumed number of bytes. + fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { if buffer.len() < TAGGED_MESSAGE_LENGTH_HEADER_SIZE { return (None, 0); } let encrypted_length = &buffer[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE]; // todo: abort if too short - let length_vec = chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap(); let mut length_bytes = [0u8; MESSAGE_LENGTH_HEADER_SIZE]; - length_bytes.copy_from_slice(length_vec.as_slice()); + length_bytes.copy_from_slice(&chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap()); let message_length = byte_utils::slice_to_be16(&length_bytes) as usize; let message_end_index = TAGGED_MESSAGE_LENGTH_HEADER_SIZE + message_length + chacha::TAG_SIZE; // todo: abort if too short diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index fd9380f8fec..a97aacad4bc 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -92,8 +92,7 @@ impl PeerHandshake { response = act_one.0.to_vec(); } &Some(HandshakeState::AwaitingActOne(_)) => { - let act_length = 50; - if read_buffer_length < act_length { + if read_buffer_length < ACT_ONE_LENGTH { return Err("need at least 50 bytes".to_string()); } @@ -152,7 +151,7 @@ impl PeerHandshake { /// Initiate the handshake with a peer and return the first act pub fn initiate(&mut self, remote_public_key: &PublicKey) -> Result { if let &Some(HandshakeState::Uninitiated) = &self.state {} else { - return Err("incorrect state".to_string()); + return Err("Handshakes can only be initiated from the uninitiated state".to_string()); } let (mut hash, chaining_key) = Self::initialize_state(&remote_public_key); From f0fc10b08468793efbd21bfe35acbba89fb42132 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 20 Feb 2020 10:00:03 -0800 Subject: [PATCH 10/27] Improve comments and type aliasing for handshake module. --- lightning/src/ln/peers/handshake/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index a97aacad4bc..1b415ffad34 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -337,7 +337,8 @@ impl PeerHandshake { (act, chaining_key, temporary_key) } - fn process_act_message(act_bytes: [u8; 50], local_private_key: &SecretKey, chaining_key: [u8; 32], hash: &mut HandshakeHash) -> Result<(PublicKey, SymmetricKey, SymmetricKey), String> { + // Due to the very high similarity of acts 1 and 2, this method is used to process both + fn process_act_message(act_bytes: [u8; 50], local_private_key: &SecretKey, chaining_key: SymmetricKey, hash: &mut HandshakeHash) -> Result<(PublicKey, SymmetricKey, SymmetricKey), String> { let version = act_bytes[0]; if version != 0 { return Err("unexpected version".to_string()); From 256b6f578b0ca9ff9ecd1325ea2ac768b221c4d5 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 20 Feb 2020 12:23:43 -0800 Subject: [PATCH 11/27] Reflect new modular encryption mechanism in tock ping message creation. --- lightning/src/ln/peer_handler.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 73008ee7b00..85e5bdb4a81 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -1115,21 +1115,19 @@ impl PeerManager where return false; } - if !peer.channel_encryptor.is_ready_for_encryption() { - // The peer needs to complete its handshake before we can exchange messages - return true; - } + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + let ping = msgs::Ping { + ponglen: 0, + byteslen: 64, + }; + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(&ping))); - let ping = msgs::Ping { - ponglen: 0, - byteslen: 64, - }; - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(&ping))); + let mut descriptor_clone = descriptor.clone(); + self.do_attempt_write_data(&mut descriptor_clone, peer); - let mut descriptor_clone = descriptor.clone(); - self.do_attempt_write_data(&mut descriptor_clone, peer); + peer.awaiting_pong = true; + } - peer.awaiting_pong = true; true }); } From b4921e900a31f4a02c12a00c6a4dd26ab6c8d686 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 20 Feb 2020 19:13:23 -0800 Subject: [PATCH 12/27] Elaborate on lightning codec in conduit's decrypt method. --- lightning/src/ln/peer_handler.rs | 7 +++++-- lightning/src/ln/peers/conduit.rs | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 85e5bdb4a81..9c13f74be59 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -1115,19 +1115,22 @@ impl PeerManager where return false; } + let mut needs_to_write_data = false; if let PeerState::Connected(ref mut conduit) = peer.encryptor { let ping = msgs::Ping { ponglen: 0, byteslen: 64, }; peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(&ping))); + needs_to_write_data = true; + } + if needs_to_write_data { let mut descriptor_clone = descriptor.clone(); self.do_attempt_write_data(&mut descriptor_clone, peer); - - peer.awaiting_pong = true; } + peer.awaiting_pong = true; true }); } diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs index e3275dcd447..b7fd882b2d5 100644 --- a/lightning/src/ln/peers/conduit.rs +++ b/lightning/src/ln/peers/conduit.rs @@ -78,15 +78,17 @@ impl Conduit { /// Decrypt a message from the beginning of the provided buffer. Returns the consumed number of bytes. fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { if buffer.len() < TAGGED_MESSAGE_LENGTH_HEADER_SIZE { + // A message must be at least 18 bytes (2 for encrypted length, 16 for the tag) return (None, 0); } - let encrypted_length = &buffer[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE]; // todo: abort if too short + let encrypted_length = &buffer[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE]; let mut length_bytes = [0u8; MESSAGE_LENGTH_HEADER_SIZE]; length_bytes.copy_from_slice(&chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap()); + // message_length is the length of the encrypted message excluding its trailing 16-byte tag let message_length = byte_utils::slice_to_be16(&length_bytes) as usize; - let message_end_index = TAGGED_MESSAGE_LENGTH_HEADER_SIZE + message_length + chacha::TAG_SIZE; // todo: abort if too short + let message_end_index = TAGGED_MESSAGE_LENGTH_HEADER_SIZE + message_length + chacha::TAG_SIZE; if buffer.len() < message_end_index { return (None, 0); } From 299b6f734e5eedb1827f3dfa04a90d1cd9da9ed8 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Fri, 21 Feb 2020 11:03:02 -0800 Subject: [PATCH 13/27] Split up conduit unit tests by tested functionality. --- lightning/src/ln/peers/conduit.rs | 67 ++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs index b7fd882b2d5..9d848f45b8f 100644 --- a/lightning/src/ln/peers/conduit.rs +++ b/lightning/src/ln/peers/conduit.rs @@ -65,13 +65,8 @@ impl Conduit { } let (current_message, offset) = self.decrypt(&read_buffer[..]); - read_buffer.drain(0..offset); // drain the read buffer + read_buffer.drain(..offset); // drain the read buffer self.read_buffer = Some(read_buffer); // assign the new value to the built-in buffer - - if offset == 0 { - return None; - } - current_message } @@ -132,9 +127,7 @@ mod tests { use hex; use ln::peers::conduit::Conduit; - #[test] - /// Based on RFC test vectors: https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#message-encryption-tests - fn test_chaining() { + fn setup_peers() -> (Conduit, Conduit) { let chaining_key_vec = hex::decode("919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01").unwrap(); let mut chaining_key = [0u8; 32]; chaining_key.copy_from_slice(&chaining_key_vec); @@ -147,7 +140,7 @@ mod tests { let mut receiving_key = [0u8; 32]; receiving_key.copy_from_slice(&receiving_key_vec); - let mut connected_peer = Conduit { + let connected_peer = Conduit { sending_key, receiving_key, sending_chaining_key: chaining_key, @@ -157,7 +150,7 @@ mod tests { read_buffer: None, }; - let mut remote_peer = Conduit { + let remote_peer = Conduit { sending_key: receiving_key, receiving_key: sending_key, sending_chaining_key: chaining_key, @@ -167,6 +160,39 @@ mod tests { read_buffer: None, }; + (connected_peer, remote_peer) + } + + #[test] + fn test_empty_message() { + let (mut connected_peer, mut remote_peer) = setup_peers(); + + let message: Vec = vec![]; + let encrypted_message = connected_peer.encrypt(&message); + assert_eq!(encrypted_message.len(), 2 + 16 + 16); + + let decrypted_message = remote_peer.decrypt_single_message(Some(&encrypted_message)).unwrap(); + assert_eq!(decrypted_message, vec![]); + } + + #[test] + fn test_nonce_chaining() { + let (mut connected_peer, mut remote_peer) = setup_peers(); + let message = hex::decode("68656c6c6f").unwrap(); + + let encrypted_message = connected_peer.encrypt(&message); + assert_eq!(encrypted_message, hex::decode("cf2b30ddf0cf3f80e7c35a6e6730b59fe802473180f396d88a8fb0db8cbcf25d2f214cf9ea1d95").unwrap()); + + // the second time the same message is encrypted, the ciphertext should be different + let encrypted_message = connected_peer.encrypt(&message); + assert_eq!(encrypted_message, hex::decode("72887022101f0b6753e0c7de21657d35a4cb2a1f5cde2650528bbc8f837d0f0d7ad833b1a256a1").unwrap()); + } + + #[test] + /// Based on RFC test vectors: https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#message-encryption-tests + fn test_key_rotation() { + let (mut connected_peer, mut remote_peer) = setup_peers(); + let message = hex::decode("68656c6c6f").unwrap(); let mut encrypted_messages: Vec> = Vec::new(); @@ -175,12 +201,23 @@ mod tests { encrypted_messages.push(encrypted_message); } - assert_eq!(encrypted_messages[0], hex::decode("cf2b30ddf0cf3f80e7c35a6e6730b59fe802473180f396d88a8fb0db8cbcf25d2f214cf9ea1d95").unwrap()); - assert_eq!(encrypted_messages[1], hex::decode("72887022101f0b6753e0c7de21657d35a4cb2a1f5cde2650528bbc8f837d0f0d7ad833b1a256a1").unwrap()); assert_eq!(encrypted_messages[500], hex::decode("178cb9d7387190fa34db9c2d50027d21793c9bc2d40b1e14dcf30ebeeeb220f48364f7a4c68bf8").unwrap()); assert_eq!(encrypted_messages[501], hex::decode("1b186c57d44eb6de4c057c49940d79bb838a145cb528d6e8fd26dbe50a60ca2c104b56b60e45bd").unwrap()); assert_eq!(encrypted_messages[1000], hex::decode("4a2f3cc3b5e78ddb83dcb426d9863d9d9a723b0337c89dd0b005d89f8d3c05c52b76b29b740f09").unwrap()); assert_eq!(encrypted_messages[1001], hex::decode("2ecd8c8a5629d0d02ab457a0fdd0f7b90a192cd46be5ecb6ca570bfc5e268338b1a16cf4ef2d36").unwrap()); + } + + #[test] + fn test_decryption_buffering() { + let (mut connected_peer, mut remote_peer) = setup_peers(); + + let message = hex::decode("68656c6c6f").unwrap(); + let mut encrypted_messages: Vec> = Vec::new(); + + for _ in 0..1002 { + let encrypted_message = connected_peer.encrypt(&message); + encrypted_messages.push(encrypted_message); + } for _ in 0..501 { // read two messages at once, filling buffer @@ -188,13 +225,13 @@ mod tests { let mut next_encrypted_message = encrypted_messages.remove(0); current_encrypted_message.extend_from_slice(&next_encrypted_message); let decrypted_message = remote_peer.decrypt_single_message(Some(¤t_encrypted_message)).unwrap(); - assert_eq!(decrypted_message, hex::decode("68656c6c6f").unwrap()); + assert_eq!(decrypted_message, message); } for _ in 0..501 { // decrypt messages directly from buffer without adding to it let decrypted_message = remote_peer.decrypt_single_message(None).unwrap(); - assert_eq!(decrypted_message, hex::decode("68656c6c6f").unwrap()); + assert_eq!(decrypted_message, message); } } } \ No newline at end of file From 944177a0843e6ad8a605f92323fa582fe7ccf0bb Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Fri, 21 Feb 2020 11:35:54 -0800 Subject: [PATCH 14/27] Make handshake store the remote public key instead of passing an option to the process_act method, which now also returns an enum of the next act instead of a Vec. --- lightning/src/ln/peer_handler.rs | 17 ++++---- lightning/src/ln/peers/handshake/mod.rs | 47 +++++++++++++++-------- lightning/src/ln/peers/handshake/tests.rs | 6 +-- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 9c13f74be59..c20503fed9c 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -276,8 +276,9 @@ impl PeerManager where /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result, PeerHandleError> { - let mut handshake = PeerHandshake::new(&self.our_node_secret, &self.get_ephemeral_key()); - let (res, ..) = handshake.process_act(&[], Some(&their_node_id)).unwrap(); + let mut handshake = PeerHandshake::new_outbound(&self.our_node_secret, &their_node_id, &self.get_ephemeral_key()); + let (act, ..) = handshake.process_act(&[]).unwrap(); + let res = act.unwrap().serialize(); let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { @@ -311,8 +312,7 @@ impl PeerManager where /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> { - let mut handshake = PeerHandshake::new(&self.our_node_secret, &self.get_ephemeral_key()); - handshake.make_inbound(); + let handshake = PeerHandshake::new_inbound(&self.our_node_secret, &self.get_ephemeral_key()); let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { @@ -468,14 +468,17 @@ impl PeerManager where let mut remote_pubkey_option = None; if let &mut PeerState::Authenticating(ref mut handshake) = &mut peer.encryptor { - let (response, conduit, remote_pubkey) = handshake.process_act(&peer.pending_read_buffer, None).unwrap(); + let (next_act, conduit) = handshake.process_act(&peer.pending_read_buffer).unwrap(); peer.pending_read_buffer = Vec::new(); // empty the pending read buffer - if let Some(key) = remote_pubkey { + if let Some(key) = handshake.get_remote_pubkey() { remote_pubkey_option = Some(key); } - peer.pending_outbound_buffer.push_back(response); + if let Some(act) = next_act { + peer.pending_outbound_buffer.push_back(act.serialize()); + } + if let Some(conduit) = conduit { conduit_option = Some(conduit); } diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index 1b415ffad34..d58134b033b 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -10,7 +10,7 @@ use secp256k1::{PublicKey, SecretKey}; use ln::peers::{chacha, hkdf}; use ln::peers::conduit::{Conduit, SymmetricKey}; -use ln::peers::handshake::acts::{ActOne, ActThree, ActTwo, ACT_ONE_LENGTH, ACT_TWO_LENGTH, ACT_THREE_LENGTH}; +use ln::peers::handshake::acts::{ActOne, ActThree, ActTwo, ACT_ONE_LENGTH, ACT_TWO_LENGTH, ACT_THREE_LENGTH, Act}; use ln::peers::handshake::hash::HandshakeHash; use ln::peers::handshake::states::{ActOneExpectation, ActThreeExpectation, ActTwoExpectation, HandshakeState}; @@ -24,6 +24,7 @@ mod tests; pub struct PeerHandshake { state: Option, private_key: SecretKey, + remote_public_key: Option, ephemeral_private_key: SecretKey, read_buffer: Vec, @@ -31,23 +32,38 @@ pub struct PeerHandshake { impl PeerHandshake { /// Instantiate a new handshake with a node identity secret key and an ephemeral private key - pub fn new(private_key: &SecretKey, ephemeral_private_key: &SecretKey) -> Self { + pub fn new_outbound(private_key: &SecretKey, remote_public_key: &PublicKey, ephemeral_private_key: &SecretKey) -> Self { Self { state: Some(HandshakeState::Uninitiated), private_key: (*private_key).clone(), + remote_public_key: Some(remote_public_key.clone()), ephemeral_private_key: (*ephemeral_private_key).clone(), read_buffer: Vec::new(), } } - /// Make the handshake object inbound in anticipation of a peer's first handshake act - pub fn make_inbound(&mut self) { - let public_key = Self::private_key_to_public_key(&self.private_key); + /// Instantiate a new handshake in anticipation of a peer's first handshake act + pub fn new_inbound(private_key: &SecretKey, ephemeral_private_key: &SecretKey) -> Self { + let mut handshake = Self { + state: Some(HandshakeState::Uninitiated), + private_key: (*private_key).clone(), + remote_public_key: None, + ephemeral_private_key: (*ephemeral_private_key).clone(), + read_buffer: Vec::new(), + }; + let public_key = Self::private_key_to_public_key(&private_key); let (hash, chaining_key) = Self::initialize_state(&public_key); - self.state = Some(HandshakeState::AwaitingActOne(ActOneExpectation { + handshake.state = Some(HandshakeState::AwaitingActOne(ActOneExpectation { hash, chaining_key, - })) + })); + handshake + } + + /// Getter accessor for the remote public key. It is useful for inbound connections to obtain + /// the remote peer's public key once it is extracted from the third act message. + pub fn get_remote_pubkey(&self) -> Option { + self.remote_public_key } fn initialize_state(public_key: &PublicKey) -> (HandshakeHash, [u8; 32]) { @@ -77,19 +93,18 @@ impl PeerHandshake { /// `.0`: Byte vector containing the next act to send back to the peer per the handshake protocol /// `.1`: Conduit option if the handshake was just processed to completion and messages can now be encrypted and decrypted /// `.2`: Public key option if the handshake was inbound and the peer's static identity pubkey was just learned - pub fn process_act(&mut self, input: &[u8], remote_public_key: Option<&PublicKey>) -> Result<(Vec, Option, Option), String> { - let mut response: Vec = Vec::new(); + pub fn process_act(&mut self, input: &[u8]) -> Result<(Option, Option), String> { + let mut response = None; let mut connected_peer = None; - let mut remote_pubkey = None; self.read_buffer.extend_from_slice(input); let read_buffer_length = self.read_buffer.len(); match &self.state { &Some(HandshakeState::Uninitiated) => { - let remote_public_key = remote_public_key.ok_or("remote_public_key must be Some for outbound connections")?; + let remote_public_key = &self.remote_public_key.ok_or("outbound connections must be initialized with new_outbound")?; let act_one = self.initiate(&remote_public_key)?; - response = act_one.0.to_vec(); + response = Some(Act::One(act_one)); } &Some(HandshakeState::AwaitingActOne(_)) => { if read_buffer_length < ACT_ONE_LENGTH { @@ -101,7 +116,7 @@ impl PeerHandshake { self.read_buffer.drain(..ACT_ONE_LENGTH); let act_two = self.process_act_one(ActOne(act_one_buffer))?; - response = act_two.0.to_vec(); + response = Some(Act::Two(act_two)); } &Some(HandshakeState::AwaitingActTwo(_)) => { if read_buffer_length < ACT_TWO_LENGTH { @@ -119,7 +134,7 @@ impl PeerHandshake { self.read_buffer.drain(..); } - response = act_three.0.to_vec(); + response = Some(Act::Three(act_three)); connected_peer = Some(conduit); } &Some(HandshakeState::AwaitingActThree(_)) => { @@ -139,13 +154,13 @@ impl PeerHandshake { } connected_peer = Some(conduit); - remote_pubkey = Some(public_key); + self.remote_public_key = Some(public_key); } _ => { return Err("no acts left to process".to_string()); } }; - Ok((response, connected_peer, remote_pubkey)) + Ok((response, connected_peer)) } /// Initiate the handshake with a peer and return the first act diff --git a/lightning/src/ln/peers/handshake/tests.rs b/lightning/src/ln/peers/handshake/tests.rs index f0dcff6d993..4b0d2592777 100644 --- a/lightning/src/ln/peers/handshake/tests.rs +++ b/lightning/src/ln/peers/handshake/tests.rs @@ -17,11 +17,11 @@ fn test_exchange() { let local_ephemeral_private_key = SecretKey::from_slice(&[0x_12_u8; 32]).unwrap(); let remote_ephemeral_private_key = SecretKey::from_slice(&[0x_22_u8; 32]).unwrap(); - let mut local_handshake = PeerHandshake::new(&local_private_key, &local_ephemeral_private_key); - let mut remote_handshake = PeerHandshake::new(&remote_private_key, &remote_ephemeral_private_key); - let remote_public_key = PublicKey::from_secret_key(&curve, &remote_private_key); + let mut local_handshake = PeerHandshake::new_outbound(&local_private_key, &remote_public_key, &local_ephemeral_private_key); + let mut remote_handshake = PeerHandshake::new_inbound(&remote_private_key, &remote_ephemeral_private_key); + let act_1 = local_handshake.initiate(&remote_public_key).unwrap(); let act_1_hex = hex::encode(&act_1.0.to_vec()); assert_eq!(act_1_hex, "00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a"); From 0fbd8953e5b3c17c4d73a2e9b784a5c1ad343588 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 27 Feb 2020 11:39:10 -0800 Subject: [PATCH 15/27] Panic when attempting invalid state transitions. --- lightning/src/ln/peer_handler.rs | 75 +++++++++++++------------ lightning/src/ln/peers/handshake/mod.rs | 19 +++---- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index c20503fed9c..8c2d9559686 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -341,8 +341,9 @@ impl PeerManager where ($msg: expr) => { { log_trace!(self, "Encoding and sending sync update message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - if let PeerState::Connected(ref mut conduit) = peer.encryptor { - peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!($msg)[..])); + match peer.encryptor { + PeerState::Connected(ref mut conduit) => peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!($msg)[..])), + _ => panic!("peer must be connected!") } } } @@ -597,22 +598,22 @@ impl PeerManager where wire::Message::Init(msg) => { if msg.features.requires_unknown_bits() { log_info!(self, "Peer global features required unknown version bits"); - return Err(PeerHandleError { no_connection_possible: true }); + return Err(PeerHandleError{ no_connection_possible: true }); } if msg.features.requires_unknown_bits() { log_info!(self, "Peer local features required unknown version bits"); - return Err(PeerHandleError { no_connection_possible: true }); + return Err(PeerHandleError{ no_connection_possible: true }); } if peer.their_features.is_some() { - return Err(PeerHandleError { no_connection_possible: false }); + return Err(PeerHandleError{ no_connection_possible: false }); } log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", - if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, - if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, - if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, - if msg.features.supports_unknown_bits() { "present" } else { "none" }, - if msg.features.supports_unknown_bits() { "present" } else { "none" }); + if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, + if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, + if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, + if msg.features.supports_unknown_bits() { "present" } else { "none" }, + if msg.features.supports_unknown_bits() { "present" } else { "none" }); if msg.features.initial_routing_sync() { peer.sync_status = InitSyncTracker::ChannelsSyncing(0); @@ -631,7 +632,7 @@ impl PeerManager where self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); peer.their_features = Some(msg.features); - } + }, wire::Message::Error(msg) => { let mut data_is_printable = true; for b in msg.data.bytes() { @@ -648,104 +649,104 @@ impl PeerManager where } self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); if msg.channel_id == [0; 32] { - return Err(PeerHandleError { no_connection_possible: true }); + return Err(PeerHandleError{ no_connection_possible: true }); } - } + }, wire::Message::Ping(msg) => { if msg.ponglen < 65532 { let resp = msgs::Pong { byteslen: msg.ponglen }; encode_and_send_msg!(resp); } - } + }, wire::Message::Pong(_msg) => { peer.awaiting_pong = false; - } + }, // Channel messages: wire::Message::OpenChannel(msg) => { self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - } + }, wire::Message::AcceptChannel(msg) => { self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - } + }, wire::Message::FundingCreated(msg) => { self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::FundingSigned(msg) => { self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::FundingLocked(msg) => { self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::Shutdown(msg) => { self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::ClosingSigned(msg) => { self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); - } + }, // Commitment messages: wire::Message::UpdateAddHTLC(msg) => { self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::UpdateFulfillHTLC(msg) => { self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::UpdateFailHTLC(msg) => { self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::UpdateFailMalformedHTLC(msg) => { self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::CommitmentSigned(msg) => { self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::RevokeAndACK(msg) => { self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::UpdateFee(msg) => { self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::ChannelReestablish(msg) => { self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); - } + }, // Routing messages: wire::Message::AnnouncementSignatures(msg) => { self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); - } + }, wire::Message::ChannelAnnouncement(msg) => { let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_announcement(&msg)); if should_forward { // TODO: forward msg along to all our other peers! } - } + }, wire::Message::NodeAnnouncement(msg) => { let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); if should_forward { // TODO: forward msg along to all our other peers! } - } + }, wire::Message::ChannelUpdate(msg) => { let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg)); if should_forward { // TODO: forward msg along to all our other peers! } - } + }, // Unknown messages: wire::Message::Unknown(msg_type) if msg_type.is_even() => { // Fail the channel if message is an even, unknown type as per BOLT #1. - return Err(PeerHandleError { no_connection_possible: true }); - } - wire::Message::Unknown(_) => {} + return Err(PeerHandleError{ no_connection_possible: true }); + }, + wire::Message::Unknown(_) => {}, } } } diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index d58134b033b..c6d20496c57 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -60,8 +60,8 @@ impl PeerHandshake { handshake } - /// Getter accessor for the remote public key. It is useful for inbound connections to obtain - /// the remote peer's public key once it is extracted from the third act message. + /// Return the remote public key once it has been extracted from the third act. + /// Potentially useful for inbound connections pub fn get_remote_pubkey(&self) -> Option { self.remote_public_key } @@ -86,13 +86,11 @@ impl PeerHandshake { /// Process act dynamically /// # Arguments /// `input`: Byte slice received from peer as part of the handshake protocol - /// `remote_public_key`: If outbound, the peer's static identity public key needs is required for the handshake initiation /// /// # Return values /// Returns a tuple with the following components: /// `.0`: Byte vector containing the next act to send back to the peer per the handshake protocol /// `.1`: Conduit option if the handshake was just processed to completion and messages can now be encrypted and decrypted - /// `.2`: Public key option if the handshake was inbound and the peer's static identity pubkey was just learned pub fn process_act(&mut self, input: &[u8]) -> Result<(Option, Option), String> { let mut response = None; let mut connected_peer = None; @@ -157,7 +155,7 @@ impl PeerHandshake { self.remote_public_key = Some(public_key); } _ => { - return Err("no acts left to process".to_string()); + panic!("no acts left to process"); } }; Ok((response, connected_peer)) @@ -195,7 +193,6 @@ impl PeerHandshake { let act_one_expectation = match state { Some(HandshakeState::AwaitingActOne(act_state)) => act_state, Some(HandshakeState::Uninitiated) => { - // this can also be initiated from a blank state let public_key = Self::private_key_to_public_key(&self.private_key); let (hash, chaining_key) = Self::initialize_state(&public_key); ActOneExpectation { @@ -205,7 +202,7 @@ impl PeerHandshake { } _ => { self.state = state; - return Err("unexpected state".to_string()); + panic!("unexpected state"); } }; @@ -244,7 +241,7 @@ impl PeerHandshake { Some(HandshakeState::AwaitingActTwo(act_state)) => act_state, _ => { self.state = state; - return Err("unexpected state".to_string()); + panic!("unexpected state".to_string()); } }; @@ -269,7 +266,7 @@ impl PeerHandshake { let authentication_tag = chacha::encrypt(&temporary_key, 0, &hash.value, &[0; 0]); let (sending_key, receiving_key) = hkdf::derive(&chaining_key, &[0; 0]); - let mut act_three = [0u8; 66]; + let mut act_three = [0u8; ACT_THREE_LENGTH]; act_three[1..50].copy_from_slice(&tagged_encrypted_pubkey); act_three[50..].copy_from_slice(authentication_tag.as_slice()); @@ -292,12 +289,13 @@ impl PeerHandshake { Some(HandshakeState::AwaitingActThree(act_state)) => act_state, _ => { self.state = state; - return Err("unexpected state".to_string()); + panic!("unexpected state".to_string()); } }; let version = act.0[0]; if version != 0 { + // this should not crash the process, hence no panic return Err("unexpected version".to_string()); } @@ -356,6 +354,7 @@ impl PeerHandshake { fn process_act_message(act_bytes: [u8; 50], local_private_key: &SecretKey, chaining_key: SymmetricKey, hash: &mut HandshakeHash) -> Result<(PublicKey, SymmetricKey, SymmetricKey), String> { let version = act_bytes[0]; if version != 0 { + // this should not crash the process, hence no panic return Err("unexpected version".to_string()); } From 6f4e76a5c98dbcdf2f9ccaf5f458e967bd90c33c Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 12 Mar 2020 15:32:54 -0700 Subject: [PATCH 16/27] Group peer handler's connected state checks instead of repeating them in each iteration. --- lightning/src/ln/peer_handler.rs | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index fbd82eef537..79691942fef 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -901,32 +901,22 @@ impl PeerManager where let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { //TODO: Do whatever we're gonna do for handling dropped messages }); - for msg in update_add_htlcs { - if let PeerState::Connected(ref mut conduit) = peer.encryptor { + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + for msg in update_add_htlcs { peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); } - } - for msg in update_fulfill_htlcs { - if let PeerState::Connected(ref mut conduit) = peer.encryptor { + for msg in update_fulfill_htlcs { peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); } - } - for msg in update_fail_htlcs { - if let PeerState::Connected(ref mut conduit) = peer.encryptor { + for msg in update_fail_htlcs { peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); } - } - for msg in update_fail_malformed_htlcs { - if let PeerState::Connected(ref mut conduit) = peer.encryptor { + for msg in update_fail_malformed_htlcs { peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); } - } - if let &Some(ref msg) = update_fee { - if let PeerState::Connected(ref mut conduit) = peer.encryptor { + if let &Some(ref msg) = update_fee { peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(msg))); } - } - if let PeerState::Connected(ref mut conduit) = peer.encryptor { peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(commitment_signed))); } self.do_attempt_write_data(&mut descriptor, peer); @@ -1012,11 +1002,13 @@ impl PeerManager where let encoded_msg = encode_msg!(msg); for (ref descriptor, ref mut peer) in peers.peers.iter_mut() { - if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_features.is_none() || + if !peer.encryptor.is_ready_for_encryption() || peer.their_features.is_none() || !peer.should_forward_node_announcement(msg.contents.node_id) { continue } - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..])); + if let PeerState::Connected(ref mut conduit) = peer.encryptor { + peer.pending_outbound_buffer.push_back(conduit.encrypt(&encoded_msg[..])); + } self.do_attempt_write_data(&mut (*descriptor).clone(), peer); } } From c2227b640b0bf9f3c37b5fe5d4df2acd237c954e Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Fri, 13 Mar 2020 12:11:37 -0700 Subject: [PATCH 17/27] Fix missing init message send upon connection initiation. --- lightning/src/ln/peer_handler.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 79691942fef..2f256d29f3f 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -480,6 +480,8 @@ impl PeerManager where let mut conduit_option = None; let mut remote_pubkey_option = None; + let mut needs_to_send_init_message = false; + if let &mut PeerState::Authenticating(ref mut handshake) = &mut peer.encryptor { let (next_act, conduit) = handshake.process_act(&peer.pending_read_buffer).unwrap(); peer.pending_read_buffer = Vec::new(); // empty the pending read buffer @@ -488,11 +490,16 @@ impl PeerManager where remote_pubkey_option = Some(key); } + let mut has_remaining_act = false; if let Some(act) = next_act { + has_remaining_act = true; peer.pending_outbound_buffer.push_back(act.serialize()); } if let Some(conduit) = conduit { + if has_remaining_act { + needs_to_send_init_message = true; + } conduit_option = Some(conduit); } } @@ -557,6 +564,16 @@ impl PeerManager where } } + if needs_to_send_init_message { + let mut features = InitFeatures::supported(); + if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { + features.set_initial_routing_sync(); + } + + let resp = msgs::Init { features }; + encode_and_send_msg!(resp); + } + let message_option = conduit.decrypt_single_message(Some(&peer.pending_read_buffer.clone())); peer.pending_read_buffer = Vec::new(); // empty the pending read buffer let msg_data = if let Some(message) = message_option { From 2df93cadbf9b82c6529e627cd4b61741469024af Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 9 Apr 2020 11:48:22 -0700 Subject: [PATCH 18/27] fix some unit tests --- lightning/src/ln/peer_handler.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 936b522c676..2b00b95c4ce 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -474,13 +474,15 @@ impl PeerManager where let pause_read = match peers.peers.get_mut(peer_descriptor) { None => panic!("Descriptor for read_event is not already known to PeerManager"), Some(peer) => { + let mut read_from_conduit_buffer = false; peer.pending_read_buffer.extend_from_slice(&data); - while peer.pending_read_buffer.len() > 0 { + while peer.pending_read_buffer.len() > 0 || read_from_conduit_buffer { let mut conduit_option = None; let mut remote_pubkey_option = None; let mut needs_to_send_init_message = false; + read_from_conduit_buffer = false; if let &mut PeerState::Authenticating(ref mut handshake) = &mut peer.encryptor { let (next_act, conduit) = handshake.process_act(&peer.pending_read_buffer).unwrap(); @@ -577,6 +579,7 @@ impl PeerManager where let message_option = conduit.decrypt_single_message(Some(&peer.pending_read_buffer.clone())); peer.pending_read_buffer = Vec::new(); // empty the pending read buffer let msg_data = if let Some(message) = message_option { + read_from_conduit_buffer = true; message } else { break; From eda13bfc4b8ad97f431fbe6b21de7ee150b7a488 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 9 Apr 2020 13:31:12 -0700 Subject: [PATCH 19/27] Disconnect peer if act message is too short. --- lightning/src/ln/peer_handler.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 2b00b95c4ce..52ee18ed77a 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -485,7 +485,13 @@ impl PeerManager where read_from_conduit_buffer = false; if let &mut PeerState::Authenticating(ref mut handshake) = &mut peer.encryptor { - let (next_act, conduit) = handshake.process_act(&peer.pending_read_buffer).unwrap(); + let (next_act, conduit) = match handshake.process_act(&peer.pending_read_buffer) { + Ok(act_result) => act_result, + Err(e) => { + log_trace!(self, "Invalid act message; disconnecting: {}", e); + return Err(PeerHandleError{ no_connection_possible: false }); + } + }; peer.pending_read_buffer = Vec::new(); // empty the pending read buffer if let Some(key) = handshake.get_remote_pubkey() { From 4e6b25a2e6d85d8d7fbe44b3c00adb0a6c97dfb0 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 9 Apr 2020 14:29:42 -0700 Subject: [PATCH 20/27] Replace unwrapping public keys with handleable errors in handshake module. --- lightning/src/ln/peers/handshake/mod.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index c6d20496c57..8ff3a32d21b 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -310,8 +310,11 @@ impl PeerHandshake { let remote_pubkey_vec = chacha::decrypt(&act_three_expectation.temporary_key, 1, &hash.value, &tagged_encrypted_pubkey)?; let mut remote_pubkey_bytes = [0u8; 33]; remote_pubkey_bytes.copy_from_slice(remote_pubkey_vec.as_slice()); - // todo: replace unwrap with handleable error type - let remote_pubkey = PublicKey::from_slice(&remote_pubkey_bytes).unwrap(); + let remote_pubkey = if let Ok(public_key) = PublicKey::from_slice(&remote_pubkey_bytes) { + public_key + } else { + return Err("invalid remote public key".to_string()); + }; hash.update(&tagged_encrypted_pubkey); @@ -360,8 +363,11 @@ impl PeerHandshake { let mut ephemeral_public_key_bytes = [0u8; 33]; ephemeral_public_key_bytes.copy_from_slice(&act_bytes[1..34]); - // todo: replace unwrap with handleable error type - let ephemeral_public_key = PublicKey::from_slice(&ephemeral_public_key_bytes).unwrap(); + let ephemeral_public_key = if let Ok(public_key) = PublicKey::from_slice(&ephemeral_public_key_bytes) { + public_key + } else { + return Err("invalid remote ephemeral public key".to_string()); + }; let mut chacha_tag = [0u8; 16]; chacha_tag.copy_from_slice(&act_bytes[34..50]); From 4deb2903a562faaf4a3e45a47a11610e674057f5 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 30 Apr 2020 03:26:45 -0700 Subject: [PATCH 21/27] Split conduit into encryptor and decryptor components (to allow for borrow splits). Extract handshake response method in peer handler into separate method. Create iterator pattern for decryptor. --- fuzz/src/full_stack.rs | 20 +- lightning-net-tokio/src/lib.rs | 4 +- lightning/src/ln/mod.rs | 1 - lightning/src/ln/peers/conduit.rs | 182 ++++++++---- .../ln/{peer_handler.rs => peers/handler.rs} | 260 +++++++++--------- lightning/src/ln/peers/handshake/mod.rs | 20 +- lightning/src/ln/peers/mod.rs | 1 + 7 files changed, 272 insertions(+), 216 deletions(-) rename lightning/src/ln/{peer_handler.rs => peers/handler.rs} (93%) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 3ae4e56b5f1..12d1482f514 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -23,7 +23,7 @@ use lightning::chain::transaction::OutPoint; use lightning::chain::keysinterface::{InMemoryChannelKeys, KeysInterface}; use lightning::ln::channelmonitor; use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage}; -use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor}; +use lightning::ln::peers::handler::{MessageHandler,PeerManager,SocketDescriptor}; use lightning::ln::router::Router; use lightning::util::events::{EventsProvider,Event}; use lightning::util::enforcing_trait_impls::EnforcingChannelKeys; @@ -858,15 +858,15 @@ mod tests { super::do_test(&::hex::decode("00000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000000300320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030012000603000000000000000000000000000000030016001000000000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000222ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005030000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d0000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001030132000300000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003014200030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000300000000000000000000000000000003011200060100000000000000000000000000000003011600100000000001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd00fd00fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e02000000000000001a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500030000000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233900000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000b030112004301000000000000000000000000000000030153002439000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a008239000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000000000000000000000000000301120063010000000000000000000000000000000301730085390000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d00000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833900000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000000000000000030112006301000000000000000000000000000000030173008539000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000305000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e0000010000000000000003e800000000010000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d0200000001390000000000000000000000000000000000000000000000000000000000000000000000000000008002000100000000000022002090000000000000000000000000000000000000000000000000000000000000006cc10000000000001600145c000000000000000000000000000000000000000500002000fd00fd0c005e0200000001fd00000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f6000000000000000000000000000000000000000000000000000000000000000000000000fd0c000000fd0c00000c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc)); 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(), "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 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 - 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 3900000000000000000000000000000000000000000000000000000000000000".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(&2)); // 9 + assert_eq!(log_entries.get(&("lightning::ln::peers::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::peers::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::peers::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::peers::handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 + assert_eq!(log_entries.get(&("lightning::ln::peers::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::peers::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::peers::handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 7 + assert_eq!(log_entries.get(&("lightning::ln::peers::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::peers::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(&2)); // 9 assert_eq!(log_entries.get(&("lightning::ln::channelmonitor".to_string(), "Input spending remote commitment tx (00000000000000000000000000000000000000000000000000000000000000fd:0) in 0000000000000000000000000000000000000000000000000000000000000044 resolves outbound HTLC with payment hash ff00000000000000000000000000000000000000000000000000000000000000 with timeout".to_string())), Some(&1)); // 10 } } diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index dd0b861c197..a899aebb0ae 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -66,8 +66,8 @@ use tokio::{io, time}; use tokio::sync::mpsc; use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; -use lightning::ln::peer_handler; -use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait; +use lightning::ln::peers::handler; +use lightning::ln::peers::handler::SocketDescriptor as LnSocketTrait; use lightning::ln::msgs::ChannelMessageHandler; use std::{task, thread}; diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index fb312209d73..a7cc86e9b71 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -14,7 +14,6 @@ pub mod channelmonitor; pub mod msgs; pub mod router; pub mod peers; -pub mod peer_handler; pub mod chan_utils; pub mod features; pub(crate) mod onchaintx; diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs index 9d848f45b8f..dc17a91c15c 100644 --- a/lightning/src/ln/peers/conduit.rs +++ b/lightning/src/ln/peers/conduit.rs @@ -15,35 +15,120 @@ const KEY_ROTATION_INDEX: u32 = 1000; /// Automatically handles key rotation. /// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering. pub struct Conduit { - pub(crate) sending_key: SymmetricKey, - pub(crate) receiving_key: SymmetricKey, + pub(super) encryptor: Encryptor, + pub(super) decryptor: Decryptor - pub(crate) sending_chaining_key: SymmetricKey, - pub(crate) receiving_chaining_key: SymmetricKey, +} + +pub(super) struct Encryptor { + sending_key: SymmetricKey, + sending_chaining_key: SymmetricKey, + sending_nonce: u32, +} - pub(crate) receiving_nonce: u32, - pub(crate) sending_nonce: u32, +pub(super) struct Decryptor { + receiving_key: SymmetricKey, + receiving_chaining_key: SymmetricKey, + receiving_nonce: u32, - pub(super) read_buffer: Option>, + pending_message_length: Option, + read_buffer: Option>, +} + +impl Iterator for Decryptor { + type Item = Vec; + + fn next(&mut self) -> Option { + self.decrypt_single_message(None) + } } impl Conduit { + /// Instantiate a new Conduit with specified sending and receiving keys + pub fn new(sending_key: SymmetricKey, sending_chaining_key: SymmetricKey, receiving_key: SymmetricKey, receiving_chaining_key: SymmetricKey) -> Self { + Conduit { + encryptor: Encryptor { + sending_key, + sending_chaining_key, + sending_nonce: 0 + }, + decryptor: Decryptor { + receiving_key, + receiving_chaining_key, + receiving_nonce: 0, + read_buffer: None, + pending_message_length: None + } + } + } + /// Encrypt data to be sent to peer pub fn encrypt(&mut self, buffer: &[u8]) -> Vec { + self.encryptor.encrypt(buffer) + } + + pub(super) fn read(&mut self, data: &[u8]) { + self.decryptor.read(data) + } + + /// Decrypt a single message. If data containing more than one message has been received, + /// only the first message will be returned, and the rest stored in the internal buffer. + /// If a message pending in the buffer still hasn't been decrypted, that message will be + /// returned in lieu of anything new, even if new data is provided. + pub fn decrypt_single_message(&mut self, new_data: Option<&[u8]>) -> Option> { + self.decryptor.decrypt_single_message(new_data) + } + + /// Decrypt a message from the beginning of the provided buffer. Returns the consumed number of bytes. + fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { + self.decryptor.decrypt(buffer) + } + + fn increment_sending_nonce(&mut self) { + self.encryptor.increment_nonce() + } + + fn increment_receiving_nonce(&mut self) { + self.decryptor.increment_nonce() + } + + fn increment_nonce(nonce: &mut u32, chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) { + *nonce += 1; + if *nonce == KEY_ROTATION_INDEX { + Self::rotate_key(chaining_key, key); + *nonce = 0; + } + } + + fn rotate_key(chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) { + let (new_chaining_key, new_key) = hkdf::derive(chaining_key, key); + chaining_key.copy_from_slice(&new_chaining_key); + key.copy_from_slice(&new_key); + } +} + +impl Encryptor { + pub(super) fn encrypt(&mut self, buffer: &[u8]) -> Vec { let length = buffer.len() as u16; let length_bytes = byte_utils::be16_to_array(length); let mut ciphertext = vec![0u8; TAGGED_MESSAGE_LENGTH_HEADER_SIZE + length as usize + chacha::TAG_SIZE]; ciphertext[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes)); - self.increment_sending_nonce(); + self.increment_nonce(); ciphertext[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], buffer)); - self.increment_sending_nonce(); + self.increment_nonce(); ciphertext } + fn increment_nonce(&mut self) { + Conduit::increment_nonce(&mut self.sending_nonce, &mut self.sending_chaining_key, &mut self.sending_key); + } +} + +impl Decryptor { pub(super) fn read(&mut self, data: &[u8]) { let read_buffer = self.read_buffer.get_or_insert(Vec::new()); read_buffer.extend_from_slice(data); @@ -70,61 +155,53 @@ impl Conduit { current_message } - /// Decrypt a message from the beginning of the provided buffer. Returns the consumed number of bytes. fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { - if buffer.len() < TAGGED_MESSAGE_LENGTH_HEADER_SIZE { - // A message must be at least 18 bytes (2 for encrypted length, 16 for the tag) - return (None, 0); - } + let message_length = if let Some(length) = self.pending_message_length { + // we have already decrypted the header + length + } else { + if buffer.len() < TAGGED_MESSAGE_LENGTH_HEADER_SIZE { + // A message must be at least 18 bytes (2 for encrypted length, 16 for the tag) + return (None, 0); + } + + let encrypted_length = &buffer[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE]; + let mut length_bytes = [0u8; MESSAGE_LENGTH_HEADER_SIZE]; + length_bytes.copy_from_slice(&chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap()); - let encrypted_length = &buffer[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE]; - let mut length_bytes = [0u8; MESSAGE_LENGTH_HEADER_SIZE]; - length_bytes.copy_from_slice(&chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap()); - // message_length is the length of the encrypted message excluding its trailing 16-byte tag - let message_length = byte_utils::slice_to_be16(&length_bytes) as usize; + self.increment_nonce(); + + // the message length + byte_utils::slice_to_be16(&length_bytes) as usize + }; let message_end_index = TAGGED_MESSAGE_LENGTH_HEADER_SIZE + message_length + chacha::TAG_SIZE; + if buffer.len() < message_end_index { + self.pending_message_length = Some(message_length); return (None, 0); } - let encrypted_message = &buffer[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..message_end_index]; + self.pending_message_length = None; - self.increment_receiving_nonce(); + let encrypted_message = &buffer[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..message_end_index]; let message = chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_message).unwrap(); - self.increment_receiving_nonce(); + self.increment_nonce(); (Some(message), message_end_index) } - fn increment_sending_nonce(&mut self) { - Self::increment_nonce(&mut self.sending_nonce, &mut self.sending_chaining_key, &mut self.sending_key); - } - - fn increment_receiving_nonce(&mut self) { - Self::increment_nonce(&mut self.receiving_nonce, &mut self.receiving_chaining_key, &mut self.receiving_key); - } - - fn increment_nonce(nonce: &mut u32, chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) { - *nonce += 1; - if *nonce == KEY_ROTATION_INDEX { - Self::rotate_key(chaining_key, key); - *nonce = 0; - } - } - - fn rotate_key(chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) { - let (new_chaining_key, new_key) = hkdf::derive(chaining_key, key); - chaining_key.copy_from_slice(&new_chaining_key); - key.copy_from_slice(&new_key); + fn increment_nonce(&mut self) { + Conduit::increment_nonce(&mut self.receiving_nonce, &mut self.receiving_chaining_key, &mut self.receiving_key); } } #[cfg(test)] mod tests { use hex; + use ln::peers::conduit::Conduit; fn setup_peers() -> (Conduit, Conduit) { @@ -140,25 +217,8 @@ mod tests { let mut receiving_key = [0u8; 32]; receiving_key.copy_from_slice(&receiving_key_vec); - let connected_peer = Conduit { - sending_key, - receiving_key, - sending_chaining_key: chaining_key, - receiving_chaining_key: chaining_key, - sending_nonce: 0, - receiving_nonce: 0, - read_buffer: None, - }; - - let remote_peer = Conduit { - sending_key: receiving_key, - receiving_key: sending_key, - sending_chaining_key: chaining_key, - receiving_chaining_key: chaining_key, - sending_nonce: 0, - receiving_nonce: 0, - read_buffer: None, - }; + let connected_peer = Conduit::new(sending_key, chaining_key, receiving_key, chaining_key); + let remote_peer = Conduit::new(receiving_key, chaining_key, sending_key, chaining_key); (connected_peer, remote_peer) } diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peers/handler.rs similarity index 93% rename from lightning/src/ln/peer_handler.rs rename to lightning/src/ln/peers/handler.rs index be7ea68aa62..6096fd2f4ca 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peers/handler.rs @@ -114,6 +114,12 @@ enum PeerState { Connected(Conduit), } +enum PeerDataProcessingDecision { + CompleteHandshake(bool, Option), + Continue, + Disconnect(PeerHandleError) +} + impl PeerState { fn is_ready_for_encryption(&self) -> bool { match self { @@ -121,6 +127,35 @@ impl PeerState { _ => false } } + + fn process_peer_data(&mut self, data: &[u8], mutable_response_buffer: &mut LinkedList>) -> PeerDataProcessingDecision { + if let &mut PeerState::Authenticating(ref mut handshake) = self { + let (next_act, conduit) = match handshake.process_act(data) { + Ok(act_result) => act_result, + Err(e) => { + return PeerDataProcessingDecision::Disconnect(PeerHandleError { no_connection_possible: false }); + } + }; + + let requires_response = next_act.is_some(); + if let Some(act) = next_act { + mutable_response_buffer.push_back(act.serialize()); + } + + let remote_pubkey_option = handshake.get_remote_pubkey(); + if let Some(conduit) = conduit { + *self = PeerState::Connected(conduit); + return PeerDataProcessingDecision::CompleteHandshake(requires_response, remote_pubkey_option) + } + + }; + + if let &mut PeerState::Connected(ref mut conduit) = self { + conduit.read(data); + } + + PeerDataProcessingDecision::Continue + } } struct Peer { @@ -478,122 +513,99 @@ impl PeerManager where let pause_read = match peers.peers.get_mut(peer_descriptor) { None => panic!("Descriptor for read_event is not already known to PeerManager"), Some(peer) => { - let mut read_from_conduit_buffer = false; - peer.pending_read_buffer.extend_from_slice(&data); - while peer.pending_read_buffer.len() > 0 || read_from_conduit_buffer { - - let mut conduit_option = None; - let mut remote_pubkey_option = None; - - let mut needs_to_send_init_message = false; - read_from_conduit_buffer = false; - - if let &mut PeerState::Authenticating(ref mut handshake) = &mut peer.encryptor { - let (next_act, conduit) = match handshake.process_act(&peer.pending_read_buffer) { - Ok(act_result) => act_result, - Err(e) => { - log_trace!(self, "Invalid act message; disconnecting: {}", e); - return Err(PeerHandleError{ no_connection_possible: false }); - } - }; - peer.pending_read_buffer = Vec::new(); // empty the pending read buffer + let mut send_init_message = false; + let data_processing_decision = peer.encryptor.process_peer_data(data, &mut peer.pending_outbound_buffer); - if let Some(key) = handshake.get_remote_pubkey() { - remote_pubkey_option = Some(key); - } - - let mut has_remaining_act = false; - if let Some(act) = next_act { - has_remaining_act = true; - peer.pending_outbound_buffer.push_back(act.serialize()); - } - - if let Some(conduit) = conduit { - if has_remaining_act { - needs_to_send_init_message = true; - } - conduit_option = Some(conduit); - } + let conduit_option = match data_processing_decision { + PeerDataProcessingDecision::Disconnect(e) => { + log_trace!(self, "Invalid act message; disconnecting: {}", e); + return Err(e); } - if let Some(key) = remote_pubkey_option { - peer.their_node_id = Some(key); - } + PeerDataProcessingDecision::CompleteHandshake(needs_to_send_init_message, remote_pubkey_option) => { + send_init_message = needs_to_send_init_message; - if let Some(conduit) = conduit_option { - // Rust 1.22 does not allow assignment in a borrowed context, even if mutable - peer.encryptor = PeerState::Connected(conduit); + if let Some(key) = remote_pubkey_option { + peer.their_node_id = Some(key); + } - // the handshake has finished, so one way or another, we now have their node id match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) { hash_map::Entry::Occupied(_) => { log_trace!(self, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event - return Err(PeerHandleError{ no_connection_possible: false }) - }, + return Err(PeerHandleError { no_connection_possible: false }); + } hash_map::Entry::Vacant(entry) => { log_trace!(self, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); entry.insert(peer_descriptor.clone()) - }, + } }; + + None + } + PeerDataProcessingDecision::Continue => { + if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { + Some(conduit) + } else { + None + } } + }; - if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { - macro_rules! encode_and_send_msg { - ($msg: expr) => { - { - log_trace!(self, "Encoding and sending message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - // we are in a context where conduit is known - peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(&$msg)[..])); - peers.peers_needing_send.insert(peer_descriptor.clone()); - } + if let Some(conduit) = conduit_option { + + let encryptor = &mut conduit.encryptor; + let decryptor = &mut conduit.decryptor; + + macro_rules! encode_and_send_msg { + ($msg: expr) => { + { + log_trace!(self, "Encoding and sending message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); + // we are in a context where conduit is known + peer.pending_outbound_buffer.push_back(encryptor.encrypt(&encode_msg!(&$msg)[..])); + peers.peers_needing_send.insert(peer_descriptor.clone()); } } + } - macro_rules! try_potential_handleerror { - ($thing: expr) => { - match $thing { - Ok(x) => x, - Err(e) => { - match e.action { - msgs::ErrorAction::DisconnectPeer { msg: _ } => { - //TODO: Try to push msg - log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err); - return Err(PeerHandleError{ no_connection_possible: false }); - }, - msgs::ErrorAction::IgnoreError => { - log_trace!(self, "Got Err handling message, ignoring because {}", e.err); - continue; - }, - msgs::ErrorAction::SendErrorMessage { msg } => { - log_trace!(self, "Got Err handling message, sending Error message because {}", e.err); - encode_and_send_msg!(msg); - continue; - }, - } + macro_rules! try_potential_handleerror { + ($thing: expr) => { + match $thing { + Ok(x) => x, + Err(e) => { + match e.action { + msgs::ErrorAction::DisconnectPeer { msg: _ } => { + //TODO: Try to push msg + log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err); + return Err(PeerHandleError{ no_connection_possible: false }); + }, + msgs::ErrorAction::IgnoreError => { + log_trace!(self, "Got Err handling message, ignoring because {}", e.err); + continue; + }, + msgs::ErrorAction::SendErrorMessage { msg } => { + log_trace!(self, "Got Err handling message, sending Error message because {}", e.err); + encode_and_send_msg!(msg); + continue; + }, } - }; - } + } + }; } + } - if needs_to_send_init_message { - let mut features = InitFeatures::supported(); - if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { - features.set_initial_routing_sync(); - } - - let resp = msgs::Init { features }; - encode_and_send_msg!(resp); + if send_init_message { + let mut features = InitFeatures::supported(); + if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { + features.set_initial_routing_sync(); } - let message_option = conduit.decrypt_single_message(Some(&peer.pending_read_buffer.clone())); - peer.pending_read_buffer = Vec::new(); // empty the pending read buffer - let msg_data = if let Some(message) = message_option { - read_from_conduit_buffer = true; - message - } else { - break; - }; + let resp = msgs::Init { features }; + encode_and_send_msg!(resp); + send_init_message = false + } + + for msg_data in decryptor { { { @@ -636,14 +648,14 @@ impl PeerManager where wire::Message::Init(msg) => { if msg.features.requires_unknown_bits() { log_info!(self, "Peer global features required unknown version bits"); - return Err(PeerHandleError{ no_connection_possible: true }); + return Err(PeerHandleError { no_connection_possible: true }); } if msg.features.requires_unknown_bits() { log_info!(self, "Peer local features required unknown version bits"); - return Err(PeerHandleError{ no_connection_possible: true }); + return Err(PeerHandleError { no_connection_possible: true }); } if peer.their_features.is_some() { - return Err(PeerHandleError{ no_connection_possible: false }); + return Err(PeerHandleError { no_connection_possible: false }); } log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", @@ -670,7 +682,7 @@ impl PeerManager where self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); peer.their_features = Some(msg.features); - }, + } wire::Message::Error(msg) => { let mut data_is_printable = true; for b in msg.data.bytes() { @@ -687,107 +699,107 @@ impl PeerManager where } self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); if msg.channel_id == [0; 32] { - return Err(PeerHandleError{ no_connection_possible: true }); + return Err(PeerHandleError { no_connection_possible: true }); } - }, + } wire::Message::Ping(msg) => { if msg.ponglen < 65532 { let resp = msgs::Pong { byteslen: msg.ponglen }; encode_and_send_msg!(resp); } - }, + } wire::Message::Pong(_msg) => { peer.awaiting_pong = false; - }, + } // Channel messages: wire::Message::OpenChannel(msg) => { self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - }, + } wire::Message::AcceptChannel(msg) => { self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - }, + } wire::Message::FundingCreated(msg) => { self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::FundingSigned(msg) => { self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::FundingLocked(msg) => { self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::Shutdown(msg) => { self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::ClosingSigned(msg) => { self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); - }, + } // Commitment messages: wire::Message::UpdateAddHTLC(msg) => { self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::UpdateFulfillHTLC(msg) => { self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::UpdateFailHTLC(msg) => { self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::UpdateFailMalformedHTLC(msg) => { self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::CommitmentSigned(msg) => { self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::RevokeAndACK(msg) => { self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::UpdateFee(msg) => { self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::ChannelReestablish(msg) => { self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); - }, + } // Routing messages: wire::Message::AnnouncementSignatures(msg) => { self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); - }, + } wire::Message::ChannelAnnouncement(msg) => { let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_announcement(&msg)); if should_forward { // TODO: forward msg along to all our other peers! } - }, + } wire::Message::NodeAnnouncement(msg) => { let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); if should_forward { // TODO: forward msg along to all our other peers! } - }, + } wire::Message::ChannelUpdate(msg) => { let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg)); if should_forward { // TODO: forward msg along to all our other peers! } - }, + } // Unknown messages: wire::Message::Unknown(msg_type) if msg_type.is_even() => { log_debug!(self, "Received unknown even message of type {}, disconnecting peer!", msg_type); // Fail the channel if message is an even, unknown type as per BOLT #1. - return Err(PeerHandleError{ no_connection_possible: true }); - }, + return Err(PeerHandleError { no_connection_possible: true }); + } wire::Message::Unknown(msg_type) => { log_trace!(self, "Received unknown odd message of type {}, ignoring", msg_type); - }, + } } } } @@ -1208,7 +1220,7 @@ mod tests { use bitcoin::BitcoinHash; use bitcoin::network::constants::Network; use bitcoin::blockdata::constants::genesis_block; - use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor}; + use ln::peers::handler::{PeerManager, MessageHandler, SocketDescriptor}; use ln::msgs; use ln::features::ChannelFeatures; use util::events; diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index 8ff3a32d21b..6f73c266c33 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -270,15 +270,7 @@ impl PeerHandshake { act_three[1..50].copy_from_slice(&tagged_encrypted_pubkey); act_three[50..].copy_from_slice(authentication_tag.as_slice()); - let connected_peer = Conduit { - sending_key, - receiving_key, - sending_chaining_key: chaining_key, - receiving_chaining_key: chaining_key, - sending_nonce: 0, - receiving_nonce: 0, - read_buffer: None, - }; + let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key, chaining_key); Ok((ActThree(act_three), connected_peer)) } @@ -323,15 +315,7 @@ impl PeerHandshake { let _tag_check = chacha::decrypt(&temporary_key, 0, &hash.value, &chacha_tag)?; let (receiving_key, sending_key) = hkdf::derive(&chaining_key, &[0; 0]); - let connected_peer = Conduit { - sending_key, - receiving_key, - sending_chaining_key: chaining_key, - receiving_chaining_key: chaining_key, - sending_nonce: 0, - receiving_nonce: 0, - read_buffer: None, - }; + let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key, chaining_key); Ok((remote_pubkey, connected_peer)) } diff --git a/lightning/src/ln/peers/mod.rs b/lightning/src/ln/peers/mod.rs index 23807e840d3..f8082c50f10 100644 --- a/lightning/src/ln/peers/mod.rs +++ b/lightning/src/ln/peers/mod.rs @@ -6,4 +6,5 @@ mod chacha; pub mod conduit; pub mod handshake; +pub mod handler; mod hkdf; From 5e9c3507f2e569f3ae157aa89fa8debb774d53a9 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 30 Apr 2020 04:02:23 -0700 Subject: [PATCH 22/27] Fix conduit constructor bugs and revert indentation for message processing block. --- lightning/src/ln/peers/conduit.rs | 10 +- lightning/src/ln/peers/handler.rs | 402 ++++++++++++------------ lightning/src/ln/peers/handshake/mod.rs | 4 +- 3 files changed, 206 insertions(+), 210 deletions(-) diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs index dc17a91c15c..74e420b192a 100644 --- a/lightning/src/ln/peers/conduit.rs +++ b/lightning/src/ln/peers/conduit.rs @@ -45,16 +45,16 @@ impl Iterator for Decryptor { impl Conduit { /// Instantiate a new Conduit with specified sending and receiving keys - pub fn new(sending_key: SymmetricKey, sending_chaining_key: SymmetricKey, receiving_key: SymmetricKey, receiving_chaining_key: SymmetricKey) -> Self { + pub fn new(sending_key: SymmetricKey, receiving_key: SymmetricKey, chaining_key: SymmetricKey) -> Self { Conduit { encryptor: Encryptor { sending_key, - sending_chaining_key, + sending_chaining_key: chaining_key, sending_nonce: 0 }, decryptor: Decryptor { receiving_key, - receiving_chaining_key, + receiving_chaining_key: chaining_key, receiving_nonce: 0, read_buffer: None, pending_message_length: None @@ -217,8 +217,8 @@ mod tests { let mut receiving_key = [0u8; 32]; receiving_key.copy_from_slice(&receiving_key_vec); - let connected_peer = Conduit::new(sending_key, chaining_key, receiving_key, chaining_key); - let remote_peer = Conduit::new(receiving_key, chaining_key, sending_key, chaining_key); + let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key); + let remote_peer = Conduit::new(receiving_key, sending_key, chaining_key); (connected_peer, remote_peer) } diff --git a/lightning/src/ln/peers/handler.rs b/lightning/src/ln/peers/handler.rs index 6096fd2f4ca..cdf01c5663b 100644 --- a/lightning/src/ln/peers/handler.rs +++ b/lightning/src/ln/peers/handler.rs @@ -129,31 +129,32 @@ impl PeerState { } fn process_peer_data(&mut self, data: &[u8], mutable_response_buffer: &mut LinkedList>) -> PeerDataProcessingDecision { - if let &mut PeerState::Authenticating(ref mut handshake) = self { - let (next_act, conduit) = match handshake.process_act(data) { - Ok(act_result) => act_result, - Err(e) => { - return PeerDataProcessingDecision::Disconnect(PeerHandleError { no_connection_possible: false }); + match self { + &mut PeerState::Authenticating(ref mut handshake) => { + let (next_act, conduit) = match handshake.process_act(data) { + Ok(act_result) => act_result, + Err(e) => { + return PeerDataProcessingDecision::Disconnect(PeerHandleError { no_connection_possible: false }); + } + }; + + let requires_response = next_act.is_some(); + if let Some(act) = next_act { + mutable_response_buffer.push_back(act.serialize()); } - }; - let requires_response = next_act.is_some(); - if let Some(act) = next_act { - mutable_response_buffer.push_back(act.serialize()); + let remote_pubkey_option = handshake.get_remote_pubkey(); + if let Some(conduit) = conduit { + *self = PeerState::Connected(conduit); + return PeerDataProcessingDecision::CompleteHandshake(requires_response, remote_pubkey_option); + } } - let remote_pubkey_option = handshake.get_remote_pubkey(); - if let Some(conduit) = conduit { - *self = PeerState::Connected(conduit); - return PeerDataProcessingDecision::CompleteHandshake(requires_response, remote_pubkey_option) + &mut PeerState::Connected(ref mut conduit) => { + conduit.read(data); } - }; - if let &mut PeerState::Connected(ref mut conduit) = self { - conduit.read(data); - } - PeerDataProcessingDecision::Continue } } @@ -513,10 +514,12 @@ impl PeerManager where let pause_read = match peers.peers.get_mut(peer_descriptor) { None => panic!("Descriptor for read_event is not already known to PeerManager"), Some(peer) => { + let mut send_init_message = false; - let data_processing_decision = peer.encryptor.process_peer_data(data, &mut peer.pending_outbound_buffer); + let mut conduit_option = None; - let conduit_option = match data_processing_decision { + let data_processing_decision = peer.encryptor.process_peer_data(data, &mut peer.pending_outbound_buffer); + match data_processing_decision { PeerDataProcessingDecision::Disconnect(e) => { log_trace!(self, "Invalid act message; disconnecting: {}", e); return Err(e); @@ -541,13 +544,13 @@ impl PeerManager where } }; - None + if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { + conduit_option = Some(conduit); + } } PeerDataProcessingDecision::Continue => { if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { - Some(conduit) - } else { - None + conduit_option = Some(conduit); } } }; @@ -606,203 +609,196 @@ impl PeerManager where } for msg_data in decryptor { + let mut reader = ::std::io::Cursor::new(&msg_data[..]); + let message_result = wire::read(&mut reader); + let message = match message_result { + Ok(x) => x, + Err(e) => { + match e { + msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }), + msgs::DecodeError::UnknownRequiredFeature => { + log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to update!"); + continue; + } + msgs::DecodeError::InvalidValue => { + log_debug!(self, "Got an invalid value while deserializing message"); + return Err(PeerHandleError { no_connection_possible: false }); + } + msgs::DecodeError::ShortRead => { + log_debug!(self, "Deserialization failed due to shortness of message"); + return Err(PeerHandleError { no_connection_possible: false }); + } + msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }), + msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }), + } + } + }; - { - { - { - let mut reader = ::std::io::Cursor::new(&msg_data[..]); - let message_result = wire::read(&mut reader); - let message = match message_result { - Ok(x) => x, - Err(e) => { - match e { - msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }), - msgs::DecodeError::UnknownRequiredFeature => { - log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to update!"); - continue; - } - msgs::DecodeError::InvalidValue => { - log_debug!(self, "Got an invalid value while deserializing message"); - return Err(PeerHandleError { no_connection_possible: false }); - } - msgs::DecodeError::ShortRead => { - log_debug!(self, "Deserialization failed due to shortness of message"); - return Err(PeerHandleError { no_connection_possible: false }); - } - msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }), - msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }), - } - } - }; + log_trace!(self, "Received message of type {} from {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - log_trace!(self, "Received message of type {} from {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap())); + // Need an Init as first message + if let wire::Message::Init(_) = message {} else if peer.their_features.is_none() { + log_trace!(self, "Peer {} sent non-Init first message", log_pubkey!(peer.their_node_id.unwrap())); + return Err(PeerHandleError { no_connection_possible: false }); + } - // Need an Init as first message - if let wire::Message::Init(_) = message {} else if peer.their_features.is_none() { - log_trace!(self, "Peer {} sent non-Init first message", log_pubkey!(peer.their_node_id.unwrap())); - return Err(PeerHandleError { no_connection_possible: false }); + match message { + // Setup and Control messages: + wire::Message::Init(msg) => { + if msg.features.requires_unknown_bits() { + log_info!(self, "Peer global features required unknown version bits"); + return Err(PeerHandleError { no_connection_possible: true }); + } + if msg.features.requires_unknown_bits() { + log_info!(self, "Peer local features required unknown version bits"); + return Err(PeerHandleError { no_connection_possible: true }); + } + if peer.their_features.is_some() { + return Err(PeerHandleError { no_connection_possible: false }); + } + + log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", + if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, + if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, + if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, + if msg.features.supports_unknown_bits() { "present" } else { "none" }, + if msg.features.supports_unknown_bits() { "present" } else { "none" }); + + if msg.features.initial_routing_sync() { + peer.sync_status = InitSyncTracker::ChannelsSyncing(0); + peers.peers_needing_send.insert(peer_descriptor.clone()); + } + + if !peer.outbound { + let mut features = InitFeatures::supported(); + if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { + features.set_initial_routing_sync(); } - match message { - // Setup and Control messages: - wire::Message::Init(msg) => { - if msg.features.requires_unknown_bits() { - log_info!(self, "Peer global features required unknown version bits"); - return Err(PeerHandleError { no_connection_possible: true }); - } - if msg.features.requires_unknown_bits() { - log_info!(self, "Peer local features required unknown version bits"); - return Err(PeerHandleError { no_connection_possible: true }); - } - if peer.their_features.is_some() { - return Err(PeerHandleError { no_connection_possible: false }); - } - - log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", - if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, - if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, - if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, - if msg.features.supports_unknown_bits() { "present" } else { "none" }, - if msg.features.supports_unknown_bits() { "present" } else { "none" }); - - if msg.features.initial_routing_sync() { - peer.sync_status = InitSyncTracker::ChannelsSyncing(0); - peers.peers_needing_send.insert(peer_descriptor.clone()); - } - - if !peer.outbound { - let mut features = InitFeatures::supported(); - if self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { - features.set_initial_routing_sync(); - } - - let resp = msgs::Init { features }; - encode_and_send_msg!(resp); - } - - self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); - peer.their_features = Some(msg.features); - } - wire::Message::Error(msg) => { - let mut data_is_printable = true; - for b in msg.data.bytes() { - if b < 32 || b > 126 { - data_is_printable = false; - break; - } - } - - if data_is_printable { - log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data); - } else { - log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap())); - } - self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); - if msg.channel_id == [0; 32] { - return Err(PeerHandleError { no_connection_possible: true }); - } - } + let resp = msgs::Init { features }; + encode_and_send_msg!(resp); + } - wire::Message::Ping(msg) => { - if msg.ponglen < 65532 { - let resp = msgs::Pong { byteslen: msg.ponglen }; - encode_and_send_msg!(resp); - } - } - wire::Message::Pong(_msg) => { - peer.awaiting_pong = false; - } + self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); + peer.their_features = Some(msg.features); + } + wire::Message::Error(msg) => { + let mut data_is_printable = true; + for b in msg.data.bytes() { + if b < 32 || b > 126 { + data_is_printable = false; + break; + } + } - // Channel messages: - wire::Message::OpenChannel(msg) => { - self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - } - wire::Message::AcceptChannel(msg) => { - self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - } + if data_is_printable { + log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data); + } else { + log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap())); + } + self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); + if msg.channel_id == [0; 32] { + return Err(PeerHandleError { no_connection_possible: true }); + } + } - wire::Message::FundingCreated(msg) => { - self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::FundingSigned(msg) => { - self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::FundingLocked(msg) => { - self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); - } + wire::Message::Ping(msg) => { + if msg.ponglen < 65532 { + let resp = msgs::Pong { byteslen: msg.ponglen }; + encode_and_send_msg!(resp); + } + } + wire::Message::Pong(_msg) => { + peer.awaiting_pong = false; + } - wire::Message::Shutdown(msg) => { - self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::ClosingSigned(msg) => { - self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); - } + // Channel messages: + wire::Message::OpenChannel(msg) => { + self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); + } + wire::Message::AcceptChannel(msg) => { + self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); + } - // Commitment messages: - wire::Message::UpdateAddHTLC(msg) => { - self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::UpdateFulfillHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::UpdateFailHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::UpdateFailMalformedHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); - } + wire::Message::FundingCreated(msg) => { + self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::FundingSigned(msg) => { + self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::FundingLocked(msg) => { + self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); + } - wire::Message::CommitmentSigned(msg) => { - self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::RevokeAndACK(msg) => { - self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::UpdateFee(msg) => { - self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::ChannelReestablish(msg) => { - self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); - } + wire::Message::Shutdown(msg) => { + self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::ClosingSigned(msg) => { + self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); + } - // Routing messages: - wire::Message::AnnouncementSignatures(msg) => { - self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::ChannelAnnouncement(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_announcement(&msg)); + // Commitment messages: + wire::Message::UpdateAddHTLC(msg) => { + self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::UpdateFulfillHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::UpdateFailHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::UpdateFailMalformedHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); + } - if should_forward { - // TODO: forward msg along to all our other peers! - } - } - wire::Message::NodeAnnouncement(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); + wire::Message::CommitmentSigned(msg) => { + self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::RevokeAndACK(msg) => { + self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::UpdateFee(msg) => { + self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::ChannelReestablish(msg) => { + self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); + } - if should_forward { - // TODO: forward msg along to all our other peers! - } - } - wire::Message::ChannelUpdate(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg)); + // Routing messages: + wire::Message::AnnouncementSignatures(msg) => { + self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); + } + wire::Message::ChannelAnnouncement(msg) => { + let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_announcement(&msg)); - if should_forward { - // TODO: forward msg along to all our other peers! - } - } + if should_forward { + // TODO: forward msg along to all our other peers! + } + } + wire::Message::NodeAnnouncement(msg) => { + let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); - // Unknown messages: - wire::Message::Unknown(msg_type) if msg_type.is_even() => { - log_debug!(self, "Received unknown even message of type {}, disconnecting peer!", msg_type); - // Fail the channel if message is an even, unknown type as per BOLT #1. - return Err(PeerHandleError { no_connection_possible: true }); - } - wire::Message::Unknown(msg_type) => { - log_trace!(self, "Received unknown odd message of type {}, ignoring", msg_type); - } - } + if should_forward { + // TODO: forward msg along to all our other peers! } } + wire::Message::ChannelUpdate(msg) => { + let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg)); + + if should_forward { + // TODO: forward msg along to all our other peers! + } + } + + // Unknown messages: + wire::Message::Unknown(msg_type) if msg_type.is_even() => { + log_debug!(self, "Received unknown even message of type {}, disconnecting peer!", msg_type); + // Fail the channel if message is an even, unknown type as per BOLT #1. + return Err(PeerHandleError { no_connection_possible: true }); + } + wire::Message::Unknown(msg_type) => { + log_trace!(self, "Received unknown odd message of type {}, ignoring", msg_type); + } } } diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index 6f73c266c33..235d75ea4c6 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -270,7 +270,7 @@ impl PeerHandshake { act_three[1..50].copy_from_slice(&tagged_encrypted_pubkey); act_three[50..].copy_from_slice(authentication_tag.as_slice()); - let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key, chaining_key); + let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key); Ok((ActThree(act_three), connected_peer)) } @@ -315,7 +315,7 @@ impl PeerHandshake { let _tag_check = chacha::decrypt(&temporary_key, 0, &hash.value, &chacha_tag)?; let (receiving_key, sending_key) = hkdf::derive(&chaining_key, &[0; 0]); - let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key, chaining_key); + let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key); Ok((remote_pubkey, connected_peer)) } From 029bb66b7f42cc9b34bc59f5e9189c0afab4481c Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 30 Apr 2020 11:14:55 -0700 Subject: [PATCH 23/27] Replace hashing and secp256k1 dependencies with components of the bitcoin crate. --- fuzz/src/full_stack.rs | 18 +++++++++--------- lightning/src/ln/peers/handshake/hash.rs | 6 +++--- lightning/src/ln/peers/handshake/mod.rs | 10 +++++----- lightning/src/ln/peers/handshake/states.rs | 4 ++-- lightning/src/ln/peers/handshake/tests.rs | 6 +++--- lightning/src/ln/peers/hkdf.rs | 6 +++--- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 6679b291001..274ac2829d9 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -881,15 +881,15 @@ mod tests { super::do_test(&::hex::decode("00000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000000300320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030012000603000000000000000000000000000000030016001000000000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000222ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005030000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d0000000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001030132000300000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003014200030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000300000000000000000000000000000003011200060100000000000000000000000000000003011600100000000001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd00fd00fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e02000000000000001a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500030000000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233900000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000b030112004301000000000000000000000000000000030153002439000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e80000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a008239000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000000000000000000000000000301120063010000000000000000000000000000000301730085390000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e80000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d00000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833900000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000000000000000030112006301000000000000000000000000000000030173008539000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000305000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000004f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e0000010000000000000003e8000000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013900000000000000000000000000000000000000000000000000000000000000000000000000000080020001000000000000220020bb000000000000000000000000000000000000000000000000000000000000006cc10000000000001600145c000000000000000000000000000000000000000500002000fd00fd0c005e0200000001d600000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f600000000000000000000000000000000000000000000000000000000000000000000000c00000c000000fd0c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc)); 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(), "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 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 - 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 3900000000000000000000000000000000000000000000000000000000000000".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(&2)); // 9 + assert_eq!(log_entries.get(&("lightning::ln::peers::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::peers::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::peers::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::peers::handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 + assert_eq!(log_entries.get(&("lightning::ln::peers::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::peers::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::peers::handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 7 + assert_eq!(log_entries.get(&("lightning::ln::peers::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::peers::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(&2)); // 9 assert_eq!(log_entries.get(&("lightning::ln::channelmonitor".to_string(), "Input spending remote commitment tx (00000000000000000000000000000000000000000000000000000000000000d6:0) in 000000000000000000000000000000000000000000000000000000000000006f resolves outbound HTLC with payment hash ff00000000000000000000000000000000000000000000000000000000000000 with timeout".to_string())), Some(&1)); // 10 } } diff --git a/lightning/src/ln/peers/handshake/hash.rs b/lightning/src/ln/peers/handshake/hash.rs index 0beef40fd93..e7704b37e34 100644 --- a/lightning/src/ln/peers/handshake/hash.rs +++ b/lightning/src/ln/peers/handshake/hash.rs @@ -1,5 +1,5 @@ -use bitcoin_hashes::{Hash, HashEngine}; -use bitcoin_hashes::sha256::Hash as Sha256; +use bitcoin::hashes::{Hash, HashEngine}; +use bitcoin::hashes::sha256::Hash as Sha256; pub(crate) struct HandshakeHash { pub(super) value: [u8; 32] @@ -22,4 +22,4 @@ impl HandshakeHash { sha.input(input); self.value = Sha256::from_engine(sha).into_inner(); } -} \ No newline at end of file +} diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs index 235d75ea4c6..32efc969a22 100644 --- a/lightning/src/ln/peers/handshake/mod.rs +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -2,11 +2,11 @@ //! Handshake states can be advanced automatically, or by manually calling the appropriate step. //! Once complete, returns an instance of Conduit. -use secp256k1; +use bitcoin::secp256k1; -use bitcoin_hashes::{Hash, HashEngine}; -use bitcoin_hashes::sha256::Hash as Sha256; -use secp256k1::{PublicKey, SecretKey}; +use bitcoin::hashes::{Hash, HashEngine}; +use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::secp256k1::{PublicKey, SecretKey}; use ln::peers::{chacha, hkdf}; use ln::peers::conduit::{Conduit, SymmetricKey}; @@ -391,4 +391,4 @@ impl PeerHandshake { sha.input(preimage.as_ref()); Sha256::from_engine(sha).into_inner() } -} \ No newline at end of file +} diff --git a/lightning/src/ln/peers/handshake/states.rs b/lightning/src/ln/peers/handshake/states.rs index 643d7b16f9a..2a7401f5e9b 100644 --- a/lightning/src/ln/peers/handshake/states.rs +++ b/lightning/src/ln/peers/handshake/states.rs @@ -1,5 +1,5 @@ use ln::peers::handshake::hash::HandshakeHash; -use secp256k1::{SecretKey, PublicKey}; +use bitcoin::secp256k1::{SecretKey, PublicKey}; pub enum HandshakeState { Uninitiated, @@ -27,4 +27,4 @@ pub struct ActThreeExpectation { pub(super) temporary_key: [u8; 32], pub(super) ephemeral_private_key: SecretKey, pub(super) remote_ephemeral_public_key: PublicKey, -} \ No newline at end of file +} diff --git a/lightning/src/ln/peers/handshake/tests.rs b/lightning/src/ln/peers/handshake/tests.rs index 4b0d2592777..e99500d1399 100644 --- a/lightning/src/ln/peers/handshake/tests.rs +++ b/lightning/src/ln/peers/handshake/tests.rs @@ -1,9 +1,9 @@ #![cfg(test)] use hex; -use secp256k1; +use bitcoin::secp256k1; -use secp256k1::key::{PublicKey, SecretKey}; +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; use ln::peers::handshake::PeerHandshake; @@ -36,4 +36,4 @@ fn test_exchange() { assert_eq!(act_3_hex, "00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba"); remote_handshake.process_act_three(act_3).unwrap(); -} \ No newline at end of file +} diff --git a/lightning/src/ln/peers/hkdf.rs b/lightning/src/ln/peers/hkdf.rs index 396515a4bf2..48415594114 100644 --- a/lightning/src/ln/peers/hkdf.rs +++ b/lightning/src/ln/peers/hkdf.rs @@ -1,5 +1,5 @@ -use bitcoin_hashes::{Hash, HashEngine, Hmac, HmacEngine}; -use bitcoin_hashes::sha256::Hash as Sha256; +use bitcoin::hashes::{Hash, HashEngine, Hmac, HmacEngine}; +use bitcoin::hashes::sha256::Hash as Sha256; pub fn derive(salt: &[u8], master: &[u8]) -> ([u8; 32], [u8; 32]) { let mut hmac = HmacEngine::::new(salt); @@ -15,4 +15,4 @@ pub fn derive(salt: &[u8], master: &[u8]) -> ([u8; 32], [u8; 32]) { hmac.input(&[2; 1]); // sha256(prk | t1 | 2) = sha256(sha256(master) | sha256(sha256(sha256(master) | 1) | 2) (t1, Hmac::from_engine(hmac).into_inner()) -} \ No newline at end of file +} From 54b7464024448119447f96d06c7bc667cf2c05d7 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 30 Apr 2020 12:05:14 -0700 Subject: [PATCH 24/27] Restrict conduit borrow scope for compatibility with Rust 1.22.0. --- lightning/src/ln/peers/handler.rs | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/lightning/src/ln/peers/handler.rs b/lightning/src/ln/peers/handler.rs index a6d2d856f45..7059bbd430e 100644 --- a/lightning/src/ln/peers/handler.rs +++ b/lightning/src/ln/peers/handler.rs @@ -129,6 +129,9 @@ impl PeerState { } fn process_peer_data(&mut self, data: &[u8], mutable_response_buffer: &mut LinkedList>) -> PeerDataProcessingDecision { + let mut conduit_option = None; + let mut decision_option = None; + match self { &mut PeerState::Authenticating(ref mut handshake) => { let (next_act, conduit) = match handshake.process_act(data) { @@ -145,8 +148,8 @@ impl PeerState { let remote_pubkey_option = handshake.get_remote_pubkey(); if let Some(conduit) = conduit { - *self = PeerState::Connected(conduit); - return PeerDataProcessingDecision::CompleteHandshake(requires_response, remote_pubkey_option); + conduit_option = Some(conduit); + decision_option = Some(PeerDataProcessingDecision::CompleteHandshake(requires_response, remote_pubkey_option)); } } @@ -155,6 +158,11 @@ impl PeerState { } }; + if let (Some(conduit), Some(decision)) = (conduit_option, decision_option) { + *self = PeerState::Connected(conduit); + return decision; + } + PeerDataProcessingDecision::Continue } } @@ -169,8 +177,6 @@ struct Peer { pending_outbound_buffer_first_msg_offset: usize, awaiting_write_event: bool, - pending_read_buffer: Vec, - sync_status: InitSyncTracker, awaiting_pong: bool, @@ -338,8 +344,6 @@ impl PeerManager where pending_outbound_buffer_first_msg_offset: 0, awaiting_write_event: false, - pending_read_buffer: Vec::new(), - sync_status: InitSyncTracker::NoSyncRequested, awaiting_pong: false, @@ -372,8 +376,6 @@ impl PeerManager where pending_outbound_buffer_first_msg_offset: 0, awaiting_write_event: false, - pending_read_buffer: Vec::new(), - sync_status: InitSyncTracker::NoSyncRequested, awaiting_pong: false, @@ -516,7 +518,6 @@ impl PeerManager where Some(peer) => { let mut send_init_message = false; - let mut conduit_option = None; let data_processing_decision = peer.encryptor.process_peer_data(data, &mut peer.pending_outbound_buffer); match data_processing_decision { @@ -543,19 +544,11 @@ impl PeerManager where entry.insert(peer_descriptor.clone()) } }; - - if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { - conduit_option = Some(conduit); - } - } - PeerDataProcessingDecision::Continue => { - if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { - conduit_option = Some(conduit); - } } + _ => {} }; - if let Some(conduit) = conduit_option { + if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { let encryptor = &mut conduit.encryptor; let decryptor = &mut conduit.decryptor; From fe705a90d04b03560a80b097227e0c7cdbe2ca45 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Thu, 30 Apr 2020 12:17:46 -0700 Subject: [PATCH 25/27] Fix lightning-net-tokio peer handler import. --- lightning-net-tokio/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index 9845f0dd2d2..6a2c78b17d3 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -26,7 +26,7 @@ //! type FeeEstimator = dyn lightning::chain::chaininterface::FeeEstimator; //! type ChannelMonitor = lightning::ln::channelmonitor::SimpleManyChannelMonitor, Arc>; //! type ChannelManager = lightning::ln::channelmanager::SimpleArcChannelManager; -//! type PeerManager = lightning::ln::peer_handler::SimpleArcPeerManager; +//! type PeerManager = lightning::ln::peers::handler::SimpleArcPeerManager; //! //! // Connect to node with pubkey their_node_id at addr: //! async fn connect_to_node(peer_manager: PeerManager, channel_monitor: Arc, channel_manager: ChannelManager, their_node_id: PublicKey, addr: SocketAddr) { @@ -66,7 +66,7 @@ use tokio::{io, time}; use tokio::sync::mpsc; use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; -use lightning::ln::peers::handler; +use lightning::ln::peers::handler as peer_handler; use lightning::ln::peers::handler::SocketDescriptor as LnSocketTrait; use lightning::ln::msgs::ChannelMessageHandler; @@ -479,7 +479,7 @@ impl Hash for SocketDescriptor { mod tests { use lightning::ln::features::*; use lightning::ln::msgs::*; - use lightning::ln::peer_handler::{MessageHandler, PeerManager}; + use lightning::ln::peers::handler::{MessageHandler, PeerManager}; use lightning::util::events::*; use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey}; From be5e2a5b1523ada8c0357e57402d3c528080d2a3 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Fri, 12 Jun 2020 10:52:35 -0700 Subject: [PATCH 26/27] Apply message handling extraction to relocated peer handler. --- lightning/src/ln/peers/handler.rs | 629 ++++++++++++++---------------- 1 file changed, 294 insertions(+), 335 deletions(-) diff --git a/lightning/src/ln/peers/handler.rs b/lightning/src/ln/peers/handler.rs index 7059bbd430e..49c1adbe3e3 100644 --- a/lightning/src/ln/peers/handler.rs +++ b/lightning/src/ln/peers/handler.rs @@ -3,21 +3,23 @@ //! Instead of actually servicing sockets ourselves we require that you implement the //! SocketDescriptor interface and use that to receive actions which you should perform on the //! socket, and call into PeerManager with bytes read from the socket. The PeerManager will then -//! call into the provided message handlers (probably a ChannelManager and Router) with messages +//! call into the provided message handlers (probably a ChannelManager and NetGraphmsgHandler) with messages //! they should handle, and encoding/sending response messages. use bitcoin::secp256k1::key::{SecretKey,PublicKey}; use ln::features::InitFeatures; use ln::msgs; -use ln::msgs::ChannelMessageHandler; +use ln::msgs::{ChannelMessageHandler, LightningError, RoutingMessageHandler}; use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager}; -use util::ser::VecWriter; +use util::ser::{VecWriter, Writeable}; +use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep}; use ln::wire; use ln::wire::Encode; use util::byte_utils; use util::events::{MessageSendEvent, MessageSendEventsProvider}; use util::logger::Logger; +use routing::network_graph::NetGraphMsgHandler; use std::collections::{HashMap,hash_map,HashSet,LinkedList}; use std::sync::{Arc, Mutex}; @@ -33,13 +35,15 @@ use ln::peers::conduit::Conduit; use ln::peers::handshake::acts::Act; /// Provides references to trait impls which handle different types of messages. -pub struct MessageHandler where CM::Target: msgs::ChannelMessageHandler { +pub struct MessageHandler where + CM::Target: ChannelMessageHandler, + RM::Target: RoutingMessageHandler { /// A message handler which handles messages specific to channels. Usually this is just a /// ChannelManager object. pub chan_handler: CM, /// A message handler which handles messages updating our knowledge of the network channel - /// graph. Usually this is just a Router object. - pub route_handler: Arc, + /// graph. Usually this is just a NetGraphMsgHandlerMonitor object. + pub route_handler: RM, } /// Provides an object which can be used to send data to and which uniquely identifies a connection @@ -85,7 +89,7 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone { pub struct PeerHandleError { /// Used to indicate that we probably can't make any future connections to this peer, implying /// we should go ahead and force-close any channels we have with it. - no_connection_possible: bool, + pub no_connection_possible: bool, } impl fmt::Debug for PeerHandleError { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { @@ -227,7 +231,7 @@ fn _check_usize_is_32_or_64() { /// lifetimes). Other times you can afford a reference, which is more efficient, in which case /// SimpleRefPeerManager is the more appropriate type. Defining these type aliases prevents /// issues such as overly long function definitions. -pub type SimpleArcPeerManager = Arc>>; +pub type SimpleArcPeerManager = Arc, Arc, Arc>>, Arc>>; /// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference /// counterpart to the SimpleArcPeerManager type alias. Use this type by default when you don't @@ -235,7 +239,7 @@ pub type SimpleArcPeerManager = Arc = PeerManager>; +pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, SD, M, T, F, C, L> = PeerManager, &'e NetGraphMsgHandler<&'g C, &'f L>, &'f L>; /// A PeerManager manages a set of peers, described by their SocketDescriptor and marshalls socket /// events into messages which it passes on to its MessageHandlers. @@ -245,8 +249,11 @@ pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, SD, M, T, F> = PeerManager where CM::Target: msgs::ChannelMessageHandler { - message_handler: MessageHandler, +pub struct PeerManager where + CM::Target: ChannelMessageHandler, + RM::Target: RoutingMessageHandler, + L::Target: Logger { + message_handler: MessageHandler, peers: Mutex>, our_node_secret: SecretKey, ephemeral_key_midstate: Sha256Engine, @@ -256,7 +263,24 @@ pub struct PeerManager where CM::Target peer_counter_low: AtomicUsize, peer_counter_high: AtomicUsize, - logger: Arc, + logger: L, +} + +enum MessageHandlingError { + PeerHandleError(PeerHandleError), + LightningError(LightningError), +} + +impl From for MessageHandlingError { + fn from(error: PeerHandleError) -> Self { + MessageHandlingError::PeerHandleError(error) + } +} + +impl From for MessageHandlingError { + fn from(error: LightningError) -> Self { + MessageHandlingError::LightningError(error) + } } macro_rules! encode_msg { @@ -269,22 +293,25 @@ macro_rules! encode_msg { /// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds. /// PeerIds may repeat, but only after socket_disconnected() has been called. -impl PeerManager where CM::Target: msgs::ChannelMessageHandler { +impl PeerManager where + CM::Target: ChannelMessageHandler, + RM::Target: RoutingMessageHandler, + L::Target: Logger { /// Constructs a new PeerManager with the given message handlers and node_id secret key /// ephemeral_random_data is used to derive per-connection ephemeral keys and must be /// cryptographically secure random bytes. - pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: Arc) -> PeerManager { + pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: L) -> Self { let mut ephemeral_key_midstate = Sha256::engine(); ephemeral_key_midstate.input(ephemeral_random_data); PeerManager { - message_handler: message_handler, + message_handler, peers: Mutex::new(PeerHolder { peers: HashMap::new(), peers_needing_send: HashSet::new(), node_id_to_descriptor: HashMap::new() }), - our_node_secret: our_node_secret, + our_node_secret, ephemeral_key_midstate, peer_counter_low: AtomicUsize::new(0), peer_counter_high: AtomicUsize::new(0), @@ -389,7 +416,7 @@ impl PeerManager where macro_rules! encode_and_send_msg { ($msg: expr) => { { - log_trace!(self, "Encoding and sending sync update message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); + log_trace!(self.logger, "Encoding and sending sync update message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); match peer.encryptor { PeerState::Connected(ref mut conduit) => peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!($msg)[..])), _ => panic!("peer must be connected!") @@ -509,6 +536,20 @@ impl PeerManager where } } + /// Append a message to a peer's pending outbound/write buffer, and update the map of peers needing sends accordingly. + fn enqueue_message(&self, peers_needing_send: &mut HashSet, peer: &mut Peer, descriptor: Descriptor, message: &M) { + let mut buffer = VecWriter(Vec::new()); + wire::write(message, &mut buffer).unwrap(); // crash if the write failed + let encoded_message = buffer.0; + + log_trace!(self.logger, "Enqueueing message of type {} to {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap())); + match peer.encryptor { + PeerState::Connected(ref mut conduit) => peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!($msg)[..])), + _ => panic!("peer must be connected!") + } + peers_needing_send.insert(descriptor); + } + fn do_read_event(&self, peer_descriptor: &mut Descriptor, data: &[u8]) -> Result { let pause_read = { let mut peers_lock = self.peers.lock().unwrap(); @@ -533,6 +574,7 @@ impl PeerManager where peer.their_node_id = Some(key); } + // insert node id match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) { hash_map::Entry::Occupied(_) => { log_trace!(self, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); @@ -581,7 +623,7 @@ impl PeerManager where }, msgs::ErrorAction::SendErrorMessage { msg } => { log_trace!(self, "Got Err handling message, sending Error message because {}", e.err); - encode_and_send_msg!(msg); + self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &msg); continue; }, } @@ -597,7 +639,7 @@ impl PeerManager where } let resp = msgs::Init { features }; - encode_and_send_msg!(resp); + self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &resp); send_init_message = false } @@ -610,15 +652,15 @@ impl PeerManager where match e { msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }), msgs::DecodeError::UnknownRequiredFeature => { - log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to update!"); + log_debug!(self.logger, "Got a channel/node announcement with an known required feature flag, you may want to update!"); continue; } msgs::DecodeError::InvalidValue => { - log_debug!(self, "Got an invalid value while deserializing message"); + log_debug!(self.logger, "Got an invalid value while deserializing message"); return Err(PeerHandleError { no_connection_possible: false }); } msgs::DecodeError::ShortRead => { - log_debug!(self, "Deserialization failed due to shortness of message"); + log_debug!(self.logger, "Deserialization failed due to shortness of message"); return Err(PeerHandleError { no_connection_possible: false }); } msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }), @@ -627,186 +669,215 @@ impl PeerManager where } }; - log_trace!(self, "Received message of type {} from {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - - // Need an Init as first message - if let wire::Message::Init(_) = message {} else if peer.their_features.is_none() { - log_trace!(self, "Peer {} sent non-Init first message", log_pubkey!(peer.their_node_id.unwrap())); - return Err(PeerHandleError { no_connection_possible: false }); + if let Err(handling_error) = self.handle_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), message){ + match handling_error { + MessageHandlingError::PeerHandleError(e) => { return Err(e) }, + MessageHandlingError::LightningError(e) => { + try_potential_handleerror!(Err(e)); + }, + } } + } - match message { - // Setup and Control messages: - wire::Message::Init(msg) => { - if msg.features.requires_unknown_bits() { - log_info!(self, "Peer global features required unknown version bits"); - return Err(PeerHandleError { no_connection_possible: true }); - } - if msg.features.requires_unknown_bits() { - log_info!(self, "Peer local features required unknown version bits"); - return Err(PeerHandleError { no_connection_possible: true }); - } - if peer.their_features.is_some() { - return Err(PeerHandleError { no_connection_possible: false }); - } - - log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", - if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, - if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, - if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, - if msg.features.supports_unknown_bits() { "present" } else { "none" }, - if msg.features.supports_unknown_bits() { "present" } else { "none" }); - - if msg.features.initial_routing_sync() { - peer.sync_status = InitSyncTracker::ChannelsSyncing(0); - peers.peers_needing_send.insert(peer_descriptor.clone()); - } - - if !peer.outbound { - let mut features = InitFeatures::known(); - if !self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { - features.clear_initial_routing_sync(); - } - - let resp = msgs::Init { features }; - encode_and_send_msg!(resp); - } - - self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); - peer.their_features = Some(msg.features); - } - wire::Message::Error(msg) => { - let mut data_is_printable = true; - for b in msg.data.bytes() { - if b < 32 || b > 126 { - data_is_printable = false; - break; - } - } + } - if data_is_printable { - log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data); - } else { - log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap())); - } - self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); - if msg.channel_id == [0; 32] { - return Err(PeerHandleError { no_connection_possible: true }); - } - } + self.do_attempt_write_data(peer_descriptor, peer); - wire::Message::Ping(msg) => { - if msg.ponglen < 65532 { - let resp = msgs::Pong { byteslen: msg.ponglen }; - encode_and_send_msg!(resp); - } - } - wire::Message::Pong(_msg) => { - peer.awaiting_pong = false; - } + peer.pending_outbound_buffer.len() > 10 // pause_read + } + }; - // Channel messages: - wire::Message::OpenChannel(msg) => { - self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - } - wire::Message::AcceptChannel(msg) => { - self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); - } + pause_read + }; - wire::Message::FundingCreated(msg) => { - self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::FundingSigned(msg) => { - self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::FundingLocked(msg) => { - self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); - } + Ok(pause_read) + } - wire::Message::Shutdown(msg) => { - self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::ClosingSigned(msg) => { - self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); - } + /// Process an incoming message and return a decision (ok, lightning error, peer handling error) regarding the next action with the peer + fn handle_message(&self, peers_needing_send: &mut HashSet, peer: &mut Peer, peer_descriptor: Descriptor, message: wire::Message) -> Result<(), MessageHandlingError> { + log_trace!(self.logger, "Received message of type {} from {}", message.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - // Commitment messages: - wire::Message::UpdateAddHTLC(msg) => { - self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::UpdateFulfillHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::UpdateFailHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::UpdateFailMalformedHTLC(msg) => { - self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); - } + // Need an Init as first message + if let wire::Message::Init(_) = message { + } else if peer.their_features.is_none() { + log_trace!(self.logger, "Peer {} sent non-Init first message", log_pubkey!(peer.their_node_id.unwrap())); + return Err(PeerHandleError{ no_connection_possible: false }.into()); + } - wire::Message::CommitmentSigned(msg) => { - self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::RevokeAndACK(msg) => { - self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::UpdateFee(msg) => { - self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::ChannelReestablish(msg) => { - self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); - } + match message { + // Setup and Control messages: + wire::Message::Init(msg) => { + if msg.features.requires_unknown_bits() { + log_info!(self.logger, "Peer global features required unknown version bits"); + return Err(PeerHandleError{ no_connection_possible: true }.into()); + } + if msg.features.requires_unknown_bits() { + log_info!(self.logger, "Peer local features required unknown version bits"); + return Err(PeerHandleError{ no_connection_possible: true }.into()); + } + if peer.their_features.is_some() { + return Err(PeerHandleError{ no_connection_possible: false }.into()); + } - // Routing messages: - wire::Message::AnnouncementSignatures(msg) => { - self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); - } - wire::Message::ChannelAnnouncement(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_announcement(&msg)); + log_info!( + self.logger, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, static_remote_key: {}, unknown flags (local and global): {}", + if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, + if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, + if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, + if msg.features.supports_static_remote_key() { "supported" } else { "not supported"}, + if msg.features.supports_unknown_bits() { "present" } else { "none" } + ); + + if msg.features.initial_routing_sync() { + peer.sync_status = InitSyncTracker::ChannelsSyncing(0); + peers_needing_send.insert(peer_descriptor.clone()); + } + if !msg.features.supports_static_remote_key() { + log_debug!(self.logger, "Peer {} does not support static remote key, disconnecting with no_connection_possible", log_pubkey!(peer.their_node_id.unwrap())); + return Err(PeerHandleError{ no_connection_possible: true }.into()); + } - if should_forward { - // TODO: forward msg along to all our other peers! - } - } - wire::Message::NodeAnnouncement(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); + if !peer.outbound { + let mut features = InitFeatures::known(); + if !self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { + features.clear_initial_routing_sync(); + } - if should_forward { - // TODO: forward msg along to all our other peers! - } - } - wire::Message::ChannelUpdate(msg) => { - let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg)); + let resp = msgs::Init { features }; + self.enqueue_message(peers_needing_send, peer, peer_descriptor.clone(), &resp); + } - if should_forward { - // TODO: forward msg along to all our other peers! - } - } + self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); + peer.their_features = Some(msg.features); + }, + wire::Message::Error(msg) => { + let mut data_is_printable = true; + for b in msg.data.bytes() { + if b < 32 || b > 126 { + data_is_printable = false; + break; + } + } - // Unknown messages: - wire::Message::Unknown(msg_type) if msg_type.is_even() => { - log_debug!(self, "Received unknown even message of type {}, disconnecting peer!", msg_type); - // Fail the channel if message is an even, unknown type as per BOLT #1. - return Err(PeerHandleError { no_connection_possible: true }); - } - wire::Message::Unknown(msg_type) => { - log_trace!(self, "Received unknown odd message of type {}, ignoring", msg_type); - } - } - } + if data_is_printable { + log_debug!(self.logger, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data); + } else { + log_debug!(self.logger, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap())); + } + self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg); + if msg.channel_id == [0; 32] { + return Err(PeerHandleError{ no_connection_possible: true }.into()); + } + }, - } + wire::Message::Ping(msg) => { + if msg.ponglen < 65532 { + let resp = msgs::Pong { byteslen: msg.ponglen }; + self.enqueue_message(peers_needing_send, peer, peer_descriptor.clone(), &resp); + } + }, + wire::Message::Pong(_msg) => { + peer.awaiting_pong = false; + }, + + // Channel messages: + wire::Message::OpenChannel(msg) => { + self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); + }, + wire::Message::AcceptChannel(msg) => { + self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); + }, + + wire::Message::FundingCreated(msg) => { + self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::FundingSigned(msg) => { + self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::FundingLocked(msg) => { + self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); + }, + + wire::Message::Shutdown(msg) => { + self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::ClosingSigned(msg) => { + self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); + }, + + // Commitment messages: + wire::Message::UpdateAddHTLC(msg) => { + self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::UpdateFulfillHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::UpdateFailHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::UpdateFailMalformedHTLC(msg) => { + self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); + }, + + wire::Message::CommitmentSigned(msg) => { + self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::RevokeAndACK(msg) => { + self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::UpdateFee(msg) => { + self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::ChannelReestablish(msg) => { + self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); + }, + + // Routing messages: + wire::Message::AnnouncementSignatures(msg) => { + self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); + }, + wire::Message::ChannelAnnouncement(msg) => { + let should_forward = match self.message_handler.route_handler.handle_channel_announcement(&msg) { + Ok(v) => v, + Err(e) => { return Err(e.into()); }, + }; - self.do_attempt_write_data(peer_descriptor, peer); + if should_forward { + // TODO: forward msg along to all our other peers! + } + }, + wire::Message::NodeAnnouncement(msg) => { + let should_forward = match self.message_handler.route_handler.handle_node_announcement(&msg) { + Ok(v) => v, + Err(e) => { return Err(e.into()); }, + }; - peer.pending_outbound_buffer.len() > 10 // pause_read + if should_forward { + // TODO: forward msg along to all our other peers! } - }; + }, + wire::Message::ChannelUpdate(msg) => { + let should_forward = match self.message_handler.route_handler.handle_channel_update(&msg) { + Ok(v) => v, + Err(e) => { return Err(e.into()); }, + }; - pause_read + if should_forward { + // TODO: forward msg along to all our other peers! + } + }, + + // Unknown messages: + wire::Message::Unknown(msg_type) if msg_type.is_even() => { + log_debug!(self.logger, "Received unknown even message of type {}, disconnecting peer!", msg_type); + // Fail the channel if message is an even, unknown type as per BOLT #1. + return Err(PeerHandleError{ no_connection_possible: true }.into()); + }, + wire::Message::Unknown(msg_type) => { + log_trace!(self.logger, "Received unknown odd message of type {}, ignoring", msg_type); + } }; - - Ok(pause_read) + Ok(()) } /// Checks for any events generated by our handlers and processes them. Includes sending most @@ -1205,16 +1276,10 @@ impl PeerManager where #[cfg(test)] mod tests { - use bitcoin::secp256k1::Signature; - use bitcoin::BitcoinHash; - use bitcoin::network::constants::Network; - use bitcoin::blockdata::constants::genesis_block; - use ln::peers::handler::{PeerManager, MessageHandler, SocketDescriptor}; + use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor}; use ln::msgs; - use ln::features::ChannelFeatures; use util::events; use util::test_utils; - use util::logger::Logger; use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::key::{SecretKey, PublicKey}; @@ -1222,9 +1287,8 @@ mod tests { use rand::{thread_rng, Rng}; use std; - use std::cmp::min; use std::sync::{Arc, Mutex}; - use std::sync::atomic::{AtomicUsize, Ordering}; + use std::sync::atomic::Ordering; #[derive(Clone)] struct FileDescriptor { @@ -1252,41 +1316,48 @@ mod tests { fn disconnect_socket(&mut self) {} } - fn create_chan_handlers(peer_count: usize) -> Vec { - let mut chan_handlers = Vec::new(); + struct PeerManagerCfg { + chan_handler: test_utils::TestChannelMessageHandler, + routing_handler: test_utils::TestRoutingMessageHandler, + logger: test_utils::TestLogger, + } + + fn create_peermgr_cfgs(peer_count: usize) -> Vec { + let mut cfgs = Vec::new(); for _ in 0..peer_count { - let chan_handler = test_utils::TestChannelMessageHandler::new(); - chan_handlers.push(chan_handler); + cfgs.push( + PeerManagerCfg{ + chan_handler: test_utils::TestChannelMessageHandler::new(), + logger: test_utils::TestLogger::new(), + routing_handler: test_utils::TestRoutingMessageHandler::new(), + } + ); } - chan_handlers + cfgs } - fn create_network<'a>(peer_count: usize, chan_handlers: &'a Vec, routing_handlers: Option<&'a Vec>>) -> Vec> { + fn create_network<'a>(peer_count: usize, cfgs: &'a Vec) -> Vec> { let mut peers = Vec::new(); let mut rng = thread_rng(); - let logger : Arc = Arc::new(test_utils::TestLogger::new()); let mut ephemeral_bytes = [0; 32]; rng.fill_bytes(&mut ephemeral_bytes); for i in 0..peer_count { - let router = if let Some(routers) = routing_handlers { routers[i].clone() } else { - Arc::new(test_utils::TestRoutingMessageHandler::new()) - }; let node_id = { let mut key_slice = [0;32]; rng.fill_bytes(&mut key_slice); SecretKey::from_slice(&key_slice).unwrap() }; - let msg_handler = MessageHandler { chan_handler: &chan_handlers[i], route_handler: router }; - let peer = PeerManager::new(msg_handler, node_id, &ephemeral_bytes, Arc::clone(&logger)); + let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: &cfgs[i].routing_handler }; + let peer = PeerManager::new(msg_handler, node_id, &ephemeral_bytes, &cfgs[i].logger); peers.push(peer); } peers } - fn establish_connection<'a>(peer_a: &PeerManager, peer_b: &PeerManager) -> (FileDescriptor, FileDescriptor) { + fn establish_connection<'a>(peer_a: &PeerManager, peer_b: &PeerManager) -> (FileDescriptor, FileDescriptor) { let secp_ctx = Secp256k1::new(); let a_id = PublicKey::from_secret_key(&secp_ctx, &peer_a.our_node_secret); let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) }; @@ -1299,7 +1370,7 @@ mod tests { (fd_a.clone(), fd_b.clone()) } - fn establish_connection_and_read_events<'a>(peer_a: &PeerManager, peer_b: &PeerManager) -> (FileDescriptor, FileDescriptor) { + fn establish_connection_and_read_events<'a>(peer_a: &PeerManager, peer_b: &PeerManager) -> (FileDescriptor, FileDescriptor) { let (mut fd_a, mut fd_b) = establish_connection(peer_a, peer_b); assert_eq!(peer_b.read_event(&mut fd_b, &fd_a.outbound_data.lock().unwrap().split_off(0)).unwrap(), false); assert_eq!(peer_a.read_event(&mut fd_a, &fd_b.outbound_data.lock().unwrap().split_off(0)).unwrap(), false); @@ -1310,9 +1381,9 @@ mod tests { fn test_disconnect_peer() { // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and // push a DisconnectPeer event to remove the node flagged by id - let chan_handlers = create_chan_handlers(2); + let cfgs = create_peermgr_cfgs(2); let chan_handler = test_utils::TestChannelMessageHandler::new(); - let mut peers = create_network(2, &chan_handlers, None); + let mut peers = create_network(2, &cfgs); establish_connection(&peers[0], &peers[1]); assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1); @@ -1333,8 +1404,8 @@ mod tests { #[test] fn test_timer_tick_occurred() { // Create peers, a vector of two peer managers, perform initial set up and check that peers[0] has one Peer. - let chan_handlers = create_chan_handlers(2); - let peers = create_network(2, &chan_handlers, None); + let cfgs = create_peermgr_cfgs(2); + let peers = create_network(2, &cfgs); establish_connection(&peers[0], &peers[1]); assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1); @@ -1347,119 +1418,13 @@ mod tests { assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 0); } - pub struct TestRoutingMessageHandler { - pub chan_upds_recvd: AtomicUsize, - pub chan_anns_recvd: AtomicUsize, - pub chan_anns_sent: AtomicUsize, - } - - impl TestRoutingMessageHandler { - pub fn new() -> Self { - TestRoutingMessageHandler { - chan_upds_recvd: AtomicUsize::new(0), - chan_anns_recvd: AtomicUsize::new(0), - chan_anns_sent: AtomicUsize::new(0), - } - } - - } - impl msgs::RoutingMessageHandler for TestRoutingMessageHandler { - fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result { - Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError }) - } - fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result { - self.chan_anns_recvd.fetch_add(1, Ordering::AcqRel); - Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError }) - } - fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result { - self.chan_upds_recvd.fetch_add(1, Ordering::AcqRel); - Err(msgs::LightningError { err: "", action: msgs::ErrorAction::IgnoreError }) - } - fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {} - fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option, Option)> { - let mut chan_anns = Vec::new(); - const TOTAL_UPDS: u64 = 100; - let end: u64 = min(starting_point + batch_amount as u64, TOTAL_UPDS - self.chan_anns_sent.load(Ordering::Acquire) as u64); - for i in starting_point..end { - let chan_upd_1 = get_dummy_channel_update(i); - let chan_upd_2 = get_dummy_channel_update(i); - let chan_ann = get_dummy_channel_announcement(i); - - chan_anns.push((chan_ann, Some(chan_upd_1), Some(chan_upd_2))); - } - - self.chan_anns_sent.fetch_add(chan_anns.len(), Ordering::AcqRel); - chan_anns - } - - fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec { - Vec::new() - } - - fn should_request_full_sync(&self, _node_id: &PublicKey) -> bool { - true - } - } - - fn get_dummy_channel_announcement(short_chan_id: u64) -> msgs::ChannelAnnouncement { - use bitcoin::secp256k1::ffi::Signature as FFISignature; - let secp_ctx = Secp256k1::new(); - let network = Network::Testnet; - let node_1_privkey = SecretKey::from_slice(&[42; 32]).unwrap(); - let node_2_privkey = SecretKey::from_slice(&[41; 32]).unwrap(); - let node_1_btckey = SecretKey::from_slice(&[40; 32]).unwrap(); - let node_2_btckey = SecretKey::from_slice(&[39; 32]).unwrap(); - let unsigned_ann = msgs::UnsignedChannelAnnouncement { - features: ChannelFeatures::known(), - chain_hash: genesis_block(network).header.bitcoin_hash(), - short_channel_id: short_chan_id, - node_id_1: PublicKey::from_secret_key(&secp_ctx, &node_1_privkey), - node_id_2: PublicKey::from_secret_key(&secp_ctx, &node_2_privkey), - bitcoin_key_1: PublicKey::from_secret_key(&secp_ctx, &node_1_btckey), - bitcoin_key_2: PublicKey::from_secret_key(&secp_ctx, &node_2_btckey), - excess_data: Vec::new(), - }; - - msgs::ChannelAnnouncement { - node_signature_1: Signature::from(FFISignature::new()), - node_signature_2: Signature::from(FFISignature::new()), - bitcoin_signature_1: Signature::from(FFISignature::new()), - bitcoin_signature_2: Signature::from(FFISignature::new()), - contents: unsigned_ann, - } - } - - fn get_dummy_channel_update(short_chan_id: u64) -> msgs::ChannelUpdate { - use bitcoin::secp256k1::ffi::Signature as FFISignature; - let network = Network::Testnet; - msgs::ChannelUpdate { - signature: Signature::from(FFISignature::new()), - contents: msgs::UnsignedChannelUpdate { - chain_hash: genesis_block(network).header.bitcoin_hash(), - short_channel_id: short_chan_id, - timestamp: 0, - flags: 0, - cltv_expiry_delta: 0, - htlc_minimum_msat: 0, - fee_base_msat: 0, - fee_proportional_millionths: 0, - excess_data: vec![], - } - } - } - #[test] fn test_do_attempt_write_data() { // Create 2 peers with custom TestRoutingMessageHandlers and connect them. - let chan_handlers = create_chan_handlers(2); - let mut routing_handlers: Vec> = Vec::new(); - let mut routing_handlers_concrete: Vec> = Vec::new(); - for _ in 0..2 { - let routing_handler = Arc::new(TestRoutingMessageHandler::new()); - routing_handlers.push(routing_handler.clone()); - routing_handlers_concrete.push(routing_handler.clone()); - } - let peers = create_network(2, &chan_handlers, Some(&routing_handlers)); + let cfgs = create_peermgr_cfgs(2); + cfgs[0].routing_handler.request_full_sync.store(true, Ordering::Release); + cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release); + let peers = create_network(2, &cfgs); // By calling establish_connect, we trigger do_attempt_write_data between // the peers. Previously this function would mistakenly enter an infinite loop @@ -1475,22 +1440,19 @@ mod tests { // Check that each peer has received the expected number of channel updates and channel // announcements. - assert_eq!(routing_handlers_concrete[0].clone().chan_upds_recvd.load(Ordering::Acquire), 100); - assert_eq!(routing_handlers_concrete[0].clone().chan_anns_recvd.load(Ordering::Acquire), 50); - assert_eq!(routing_handlers_concrete[1].clone().chan_upds_recvd.load(Ordering::Acquire), 100); - assert_eq!(routing_handlers_concrete[1].clone().chan_anns_recvd.load(Ordering::Acquire), 50); + assert_eq!(cfgs[0].routing_handler.chan_upds_recvd.load(Ordering::Acquire), 100); + assert_eq!(cfgs[0].routing_handler.chan_anns_recvd.load(Ordering::Acquire), 50); + assert_eq!(cfgs[1].routing_handler.chan_upds_recvd.load(Ordering::Acquire), 100); + assert_eq!(cfgs[1].routing_handler.chan_anns_recvd.load(Ordering::Acquire), 50); } #[test] fn limit_initial_routing_sync_requests() { // Inbound peer 0 requests initial_routing_sync, but outbound peer 1 does not. { - let chan_handlers = create_chan_handlers(2); - let routing_handlers: Vec> = vec![ - Arc::new(test_utils::TestRoutingMessageHandler::new().set_request_full_sync()), - Arc::new(test_utils::TestRoutingMessageHandler::new()), - ]; - let peers = create_network(2, &chan_handlers, Some(&routing_handlers)); + let cfgs = create_peermgr_cfgs(2); + cfgs[0].routing_handler.request_full_sync.store(true, Ordering::Release); + let peers = create_network(2, &cfgs); let (fd_0_to_1, fd_1_to_0) = establish_connection_and_read_events(&peers[0], &peers[1]); let peer_0 = peers[0].peers.lock().unwrap(); @@ -1505,12 +1467,9 @@ mod tests { // Outbound peer 1 requests initial_routing_sync, but inbound peer 0 does not. { - let chan_handlers = create_chan_handlers(2); - let routing_handlers: Vec> = vec![ - Arc::new(test_utils::TestRoutingMessageHandler::new()), - Arc::new(test_utils::TestRoutingMessageHandler::new().set_request_full_sync()), - ]; - let peers = create_network(2, &chan_handlers, Some(&routing_handlers)); + let cfgs = create_peermgr_cfgs(2); + cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release); + let peers = create_network(2, &cfgs); let (fd_0_to_1, fd_1_to_0) = establish_connection_and_read_events(&peers[0], &peers[1]); let peer_0 = peers[0].peers.lock().unwrap(); From a4fff76fd9374f29f0d8daa30e8f6d74182e1c41 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Fri, 12 Jun 2020 19:33:42 -0700 Subject: [PATCH 27/27] Fix unit tests --- fuzz/src/full_stack.rs | 20 +++--- lightning-net-tokio/src/lib.rs | 18 +++--- lightning/src/ln/peers/handler.rs | 103 +++++++++++++++--------------- 3 files changed, 71 insertions(+), 70 deletions(-) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index df3b20b0386..090758b1682 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -22,7 +22,7 @@ use lightning::chain::transaction::OutPoint; use lightning::chain::keysinterface::{InMemoryChannelKeys, KeysInterface}; use lightning::ln::channelmonitor; use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret}; -use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor}; +use lightning::ln::peers::handler::{MessageHandler,PeerManager,SocketDescriptor}; use lightning::routing::router::get_route; use lightning::routing::network_graph::NetGraphMsgHandler; use lightning::util::events::{EventsProvider,Event}; @@ -892,15 +892,15 @@ mod tests { super::do_test(&::hex::decode("00000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000000300320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030012000a0300000000000000000000000000000003001a00100002200000022000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000222ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005030000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d00000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d0000000000000000000000000000000000000000000000000000000000000003010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000010301320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030142000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000030112000a0100000000000000000000000000000003011a0010000220000002200001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd00fd00fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e02000000000000001a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500030000000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233900000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000b030112004301000000000000000000000000000000030153002439000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e80000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a008239000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000000000000000000000000000301120063010000000000000000000000000000000301730085390000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e80000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d00000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833900000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000000000000000030112006301000000000000000000000000000000030173008539000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000305000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e0000010000000000000003e8000000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013900000000000000000000000000000000000000000000000000000000000000000000000000000080020001000000000000220020bb000000000000000000000000000000000000000000000000000000000000006cc10000000000001600142b000000000000000000000000000000000000000500002000fd00fd0c005e0200000001a100000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f600000000000000000000000000000000000000000000000000000000000000000000000c00000c000000fd0c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc)); 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(), "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 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 - 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 3900000000000000000000000000000000000000000000000000000000000000".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(&2)); // 9 + assert_eq!(log_entries.get(&("lightning::ln::peers::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::peers::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::peers::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::peers::handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 + assert_eq!(log_entries.get(&("lightning::ln::peers::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::peers::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::peers::handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 7 + assert_eq!(log_entries.get(&("lightning::ln::peers::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::peers::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(&2)); // 9 assert_eq!(log_entries.get(&("lightning::ln::channelmonitor".to_string(), "Input spending remote commitment tx (00000000000000000000000000000000000000000000000000000000000000a1:0) in 0000000000000000000000000000000000000000000000000000000000000018 resolves outbound HTLC with payment hash ff00000000000000000000000000000000000000000000000000000000000000 with timeout".to_string())), Some(&1)); // 10 } } diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index d2494d270ee..402a6bc7d5e 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -28,7 +28,7 @@ //! type ChainWatchInterface = dyn lightning::chain::chaininterface::ChainWatchInterface; //! type ChannelMonitor = lightning::ln::channelmonitor::SimpleManyChannelMonitor, Arc, Arc, Arc>; //! type ChannelManager = lightning::ln::channelmanager::SimpleArcChannelManager; -//! type PeerManager = lightning::ln::peer_handler::SimpleArcPeerManager; +//! type PeerManager = lightning::ln::peers::handler::SimpleArcPeerManager; //! //! // Connect to node with pubkey their_node_id at addr: //! async fn connect_to_node(peer_manager: PeerManager, channel_monitor: Arc, channel_manager: ChannelManager, their_node_id: PublicKey, addr: SocketAddr) { @@ -68,8 +68,8 @@ use tokio::{io, time}; use tokio::sync::mpsc; use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; -use lightning::ln::peer_handler; -use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait; +use lightning::ln::peers::handler; +use lightning::ln::peers::handler::SocketDescriptor as LnSocketTrait; use lightning::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler}; use lightning::util::logger::Logger; @@ -124,7 +124,7 @@ impl Connection { _ => panic!() } } - async fn schedule_read(peer_manager: Arc, Arc, Arc>>, us: Arc>, mut reader: io::ReadHalf, mut read_wake_receiver: mpsc::Receiver<()>, mut write_avail_receiver: mpsc::Receiver<()>) where + async fn schedule_read(peer_manager: Arc, Arc, Arc>>, us: Arc>, mut reader: io::ReadHalf, mut read_wake_receiver: mpsc::Receiver<()>, mut write_avail_receiver: mpsc::Receiver<()>) where CMH: ChannelMessageHandler + 'static, RMH: RoutingMessageHandler + 'static, L: Logger + 'static + ?Sized { @@ -237,7 +237,7 @@ impl Connection { /// not need to poll the provided future in order to make progress. /// /// See the module-level documentation for how to handle the event_notify mpsc::Sender. -pub fn setup_inbound(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, stream: TcpStream) -> impl std::future::Future where +pub fn setup_inbound(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, stream: TcpStream) -> impl std::future::Future where CMH: ChannelMessageHandler + 'static, RMH: RoutingMessageHandler + 'static, L: Logger + 'static + ?Sized { @@ -279,7 +279,7 @@ pub fn setup_inbound(peer_manager: Arc(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, stream: TcpStream) -> impl std::future::Future where +pub fn setup_outbound(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, stream: TcpStream) -> impl std::future::Future where CMH: ChannelMessageHandler + 'static, RMH: RoutingMessageHandler + 'static, L: Logger + 'static + ?Sized { @@ -351,7 +351,7 @@ pub fn setup_outbound(peer_manager: Arc(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, addr: SocketAddr) -> Option> where +pub async fn connect_outbound(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, addr: SocketAddr) -> Option> where CMH: ChannelMessageHandler + 'static, RMH: RoutingMessageHandler + 'static, L: Logger + 'static + ?Sized { @@ -402,7 +402,7 @@ impl SocketDescriptor { Self { conn, id } } } -impl peer_handler::SocketDescriptor for SocketDescriptor { +impl handler::SocketDescriptor for SocketDescriptor { fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize { // To send data, we take a lock on our Connection to access the WriteHalf of the TcpStream, // writing to it if there's room in the kernel buffer, or otherwise create a new Waker with @@ -494,7 +494,7 @@ impl Hash for SocketDescriptor { mod tests { use lightning::ln::features::*; use lightning::ln::msgs::*; - use lightning::ln::peer_handler::{MessageHandler, PeerManager}; + use lightning::ln::peers::handler::{MessageHandler, PeerManager}; use lightning::util::events::*; use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey}; diff --git a/lightning/src/ln/peers/handler.rs b/lightning/src/ln/peers/handler.rs index 241573045e0..54e996214ce 100644 --- a/lightning/src/ln/peers/handler.rs +++ b/lightning/src/ln/peers/handler.rs @@ -544,7 +544,7 @@ impl PeerManager peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!($msg)[..])), + PeerState::Connected(ref mut conduit) => peer.pending_outbound_buffer.push_back(conduit.encrypt(&encoded_message[..])), _ => panic!("peer must be connected!") } peers_needing_send.insert(descriptor); @@ -563,7 +563,7 @@ impl PeerManager { - log_trace!(self, "Invalid act message; disconnecting: {}", e); + log_trace!(self.logger, "Invalid act message; disconnecting: {}", e); return Err(e); } @@ -577,12 +577,12 @@ impl PeerManager { - log_trace!(self, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); + log_trace!(self.logger, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event return Err(PeerHandleError { no_connection_possible: false }); } hash_map::Entry::Vacant(entry) => { - log_trace!(self, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); + log_trace!(self.logger, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); entry.insert(peer_descriptor.clone()) } }; @@ -590,48 +590,22 @@ impl PeerManager {} }; - if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { + if send_init_message { + let mut features = InitFeatures::known(); + if !self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { + features.clear_initial_routing_sync(); + } + + let resp = msgs::Init { features }; + self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &resp); + send_init_message = false + } + let mut received_messages = vec![]; + if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { let encryptor = &mut conduit.encryptor; let decryptor = &mut conduit.decryptor; - macro_rules! try_potential_handleerror { - ($thing: expr) => { - match $thing { - Ok(x) => x, - Err(e) => { - match e.action { - msgs::ErrorAction::DisconnectPeer { msg: _ } => { - //TODO: Try to push msg - log_trace!(self.logger, "Got Err handling message, disconnecting peer because {}", e.err); - return Err(PeerHandleError{ no_connection_possible: false }); - }, - msgs::ErrorAction::IgnoreError => { - log_trace!(self.logger, "Got Err handling message, ignoring because {}", e.err); - continue; - }, - msgs::ErrorAction::SendErrorMessage { msg } => { - log_trace!(self.logger, "Got Err handling message, sending Error message because {}", e.err); - self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &msg); - continue; - }, - } - } - }; - } - } - - if send_init_message { - let mut features = InitFeatures::known(); - if !self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { - features.clear_initial_routing_sync(); - } - - let resp = msgs::Init { features }; - self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &resp); - send_init_message = false - } - for msg_data in decryptor { let mut reader = ::std::io::Cursor::new(&msg_data[..]); let message_result = wire::read(&mut reader); @@ -658,16 +632,43 @@ impl PeerManager { return Err(e) }, - MessageHandlingError::LightningError(e) => { - try_potential_handleerror!(Err(e)); - }, - } + received_messages.push(message); + } + } + + for message in received_messages { + macro_rules! try_potential_handleerror { + ($thing: expr) => { + match $thing { + Ok(x) => x, + Err(e) => { + match e.action { + msgs::ErrorAction::DisconnectPeer { msg: _ } => { + //TODO: Try to push msg + log_trace!(self.logger, "Got Err handling message, disconnecting peer because {}", e.err); + return Err(PeerHandleError{ no_connection_possible: false }); + }, + msgs::ErrorAction::IgnoreError => { + log_trace!(self.logger, "Got Err handling message, ignoring because {}", e.err); + continue; + }, + msgs::ErrorAction::SendErrorMessage { msg } => { + log_trace!(self.logger, "Got Err handling message, sending Error message because {}", e.err); + self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &msg); + continue; + }, } } - } + }; + } + } + + if let Err(handling_error) = self.handle_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), message){ + match handling_error { + MessageHandlingError::PeerHandleError(e) => { return Err(e) }, + MessageHandlingError::LightningError(e) => { + try_potential_handleerror!(Err(e)); + }, } } } @@ -1267,7 +1268,7 @@ impl PeerManager