X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fmsgs.rs;h=2c89acf2387686ac8c74a1197109ef07d1daad2f;hb=712051a9fca1b9b2946e9af395036b904b255d32;hp=ed0b3479b78b82060ad85c49f36570f289198840;hpb=eccd527a55307b94a5c5c5df7e3ef056440e79b8;p=rust-lightning diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index ed0b3479..2c89acf2 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -1,15 +1,17 @@ use secp256k1::key::PublicKey; use secp256k1::{Secp256k1, Signature}; -use bitcoin::util::uint::Uint256; +use secp256k1; use bitcoin::util::hash::Sha256dHash; use bitcoin::network::serialize::{deserialize,serialize}; use bitcoin::blockdata::script::Script; use std::error::Error; -use std::fmt; +use std::{cmp, fmt}; +use std::io::Read; use std::result::Result; use util::{byte_utils, internal_traits, events}; +use util::ser::{Readable, Writeable, Writer}; pub trait MsgEncodable { fn encode(&self) -> Vec; @@ -28,14 +30,25 @@ pub trait MsgEncodable { pub enum DecodeError { /// Unknown realm byte in an OnionHopData packet UnknownRealmByte, + /// Unknown feature mandating we fail to parse message + UnknownRequiredFeature, /// Failed to decode a public key (ie it's invalid) BadPublicKey, /// Failed to decode a signature (ie it's invalid) BadSignature, - /// Buffer not of right length (either too short or too long) - WrongLength, + /// Value expected to be text wasn't decodable as text + BadText, + /// Buffer too short + ShortRead, /// node_announcement included more than one address of a given type! ExtraAddressesPerType, + /// A length descriptor in the packet didn't describe the later data correctly + /// (currently only generated in node_announcement) + BadLengthDescriptor, + /// Error from std::io + Io(::std::io::Error), + /// 1 or 0 is not found for boolean value + InvalidValue, } pub trait MsgDecodable: Sized { fn decode(v: &[u8]) -> Result; @@ -61,9 +74,16 @@ impl LocalFeatures { self.flags.len() > 0 && (self.flags[0] & 1) != 0 } - pub fn supports_initial_routing_sync(&self) -> bool { + pub fn initial_routing_sync(&self) -> bool { self.flags.len() > 0 && (self.flags[0] & (1 << 3)) != 0 } + pub fn set_initial_routing_sync(&mut self) { + if self.flags.len() == 0 { + self.flags.resize(1, 1 << 3); + } else { + self.flags[0] |= 1 << 3; + } + } pub fn supports_upfront_shutdown_script(&self) -> bool { self.flags.len() > 0 && (self.flags[0] & (3 << 4)) != 0 @@ -132,9 +152,23 @@ pub struct Init { pub local_features: LocalFeatures, } +pub struct ErrorMessage { + pub channel_id: [u8; 32], + pub data: String, +} + +pub struct Ping { + pub ponglen: u16, + pub byteslen: u16, +} + +pub struct Pong { + pub byteslen: u16, +} + pub struct OpenChannel { pub chain_hash: Sha256dHash, - pub temporary_channel_id: Uint256, + pub temporary_channel_id: [u8; 32], pub funding_satoshis: u64, pub push_msat: u64, pub dust_limit_satoshis: u64, @@ -155,7 +189,7 @@ pub struct OpenChannel { } pub struct AcceptChannel { - pub temporary_channel_id: Uint256, + pub temporary_channel_id: [u8; 32], pub dust_limit_satoshis: u64, pub max_htlc_value_in_flight_msat: u64, pub channel_reserve_satoshis: u64, @@ -173,36 +207,36 @@ pub struct AcceptChannel { } pub struct FundingCreated { - pub temporary_channel_id: Uint256, + pub temporary_channel_id: [u8; 32], pub funding_txid: Sha256dHash, pub funding_output_index: u16, pub signature: Signature, } pub struct FundingSigned { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub signature: Signature, } pub struct FundingLocked { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub next_per_commitment_point: PublicKey, } pub struct Shutdown { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub scriptpubkey: Script, } pub struct ClosingSigned { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub fee_satoshis: u64, pub signature: Signature, } #[derive(Clone)] pub struct UpdateAddHTLC { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub htlc_id: u64, pub amount_msat: u64, pub payment_hash: [u8; 32], @@ -212,21 +246,21 @@ pub struct UpdateAddHTLC { #[derive(Clone)] pub struct UpdateFulfillHTLC { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub htlc_id: u64, pub payment_preimage: [u8; 32], } #[derive(Clone)] pub struct UpdateFailHTLC { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub htlc_id: u64, pub reason: OnionErrorPacket, } #[derive(Clone)] pub struct UpdateFailMalformedHTLC { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub htlc_id: u64, pub sha256_of_onion: [u8; 32], pub failure_code: u16, @@ -234,33 +268,37 @@ pub struct UpdateFailMalformedHTLC { #[derive(Clone)] pub struct CommitmentSigned { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub signature: Signature, pub htlc_signatures: Vec, } pub struct RevokeAndACK { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub per_commitment_secret: [u8; 32], pub next_per_commitment_point: PublicKey, } pub struct UpdateFee { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub feerate_per_kw: u32, } +pub struct DataLossProtect { + pub your_last_per_commitment_secret: [u8; 32], + pub my_current_per_commitment_point: PublicKey, +} + pub struct ChannelReestablish { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub next_local_commitment_number: u64, pub next_remote_commitment_number: u64, - pub your_last_per_commitment_secret: Option<[u8; 32]>, - pub my_current_per_commitment_point: PublicKey, + pub data_loss_protect: Option, } #[derive(Clone)] pub struct AnnouncementSignatures { - pub channel_id: Uint256, + pub channel_id: [u8; 32], pub short_channel_id: u64, pub node_signature: Signature, pub bitcoin_signature: Signature, @@ -307,6 +345,8 @@ pub struct UnsignedNodeAnnouncement { /// List of addresses on which this node is reachable. Note that you may only have up to one /// address of each type, if you have more, they may be silently discarded or we may panic! pub addresses: Vec, + pub excess_address_data: Vec, + pub excess_data: Vec, } pub struct NodeAnnouncement { pub signature: Signature, @@ -322,6 +362,7 @@ pub struct UnsignedChannelAnnouncement { pub node_id_2: PublicKey, pub bitcoin_key_1: PublicKey, pub bitcoin_key_2: PublicKey, + pub excess_data: Vec, } #[derive(PartialEq, Clone)] pub struct ChannelAnnouncement { @@ -342,6 +383,7 @@ pub struct UnsignedChannelUpdate { pub htlc_minimum_msat: u64, pub fee_base_msat: u32, pub fee_proportional_millionths: u32, + pub excess_data: Vec, } #[derive(PartialEq, Clone)] pub struct ChannelUpdate { @@ -351,18 +393,21 @@ pub struct ChannelUpdate { /// Used to put an error message in a HandleError pub enum ErrorAction { - /// Indicates an inbound HTLC add resulted in a failure, and the UpdateFailHTLC provided in msg - /// should be sent back to the sender. - UpdateFailHTLC { - msg: UpdateFailHTLC - }, /// The peer took some action which made us think they were useless. Disconnect them. - DisconnectPeer {}, + DisconnectPeer { + msg: Option + }, + /// The peer did something harmless that we weren't able to process, just log and ignore + IgnoreError, + /// The peer did something incorrect. Tell them. + SendErrorMessage { + msg: ErrorMessage + }, } pub struct HandleError { //TODO: rename me pub err: &'static str, - pub msg: Option, //TODO: Make this required and rename it + pub action: Option, //TODO: Make this required } /// Struct used to return values from revoke_and_ack messages, containing a bunch of commitment @@ -371,6 +416,7 @@ pub struct CommitmentUpdate { pub update_add_htlcs: Vec, pub update_fulfill_htlcs: Vec, pub update_fail_htlcs: Vec, + pub update_fail_malformed_htlcs: Vec, pub commitment_signed: CommitmentSigned, } @@ -386,7 +432,7 @@ pub enum HTLCFailChannelUpdate { /// A trait to describe an object which can receive channel messages. Messages MAY be called in /// paralell when they originate from different their_node_ids, however they MUST NOT be called in /// paralell when the two calls have the same their_node_id. -pub trait ChannelMessageHandler : events::EventsProvider { +pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync { //Channel init: fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &OpenChannel) -> Result; fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &AcceptChannel) -> Result<(), HandleError>; @@ -411,20 +457,26 @@ pub trait ChannelMessageHandler : events::EventsProvider { // Channel-to-announce: fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &AnnouncementSignatures) -> Result<(), HandleError>; - // Informational: + // Connection loss/reestablish: /// Indicates a connection to the peer failed/an existing connection was lost. If no connection /// is believed to be possible in the future (eg they're sending us messages we don't /// understand or indicate they require unknown feature bits), no_connection_possible is set /// and any outstanding channels should be failed. fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool); + + fn peer_connected(&self, their_node_id: &PublicKey) -> Vec; + fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &ChannelReestablish) -> Result<(Option, Option, Option), HandleError>; + + // Error: + fn handle_error(&self, their_node_id: &PublicKey, msg: &ErrorMessage); } -pub trait RoutingMessageHandler { - fn handle_node_announcement(&self, msg: &NodeAnnouncement) -> Result<(), HandleError>; +pub trait RoutingMessageHandler : Send + Sync { + fn handle_node_announcement(&self, msg: &NodeAnnouncement) -> Result; /// Handle a channel_announcement message, returning true if it should be forwarded on, false /// or returning an Err otherwise. fn handle_channel_announcement(&self, msg: &ChannelAnnouncement) -> Result; - fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result<(), HandleError>; + fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result; fn handle_htlc_fail_channel_update(&self, update: &HTLCFailChannelUpdate); } @@ -445,7 +497,10 @@ unsafe impl internal_traits::NoDealloc for OnionHopData{} #[derive(Clone)] pub struct OnionPacket { pub version: u8, - pub public_key: PublicKey, + /// In order to ensure we always return an error on Onion decode in compliance with BOLT 4, we + /// have to deserialize OnionPackets contained in UpdateAddHTLCs even if the ephemeral public + /// key (here) is bogus, so we hold a Result instead of a PublicKey as we'd like. + pub public_key: Result, pub hop_data: [u8; 20*65], pub hmac: [u8; 32], } @@ -467,10 +522,15 @@ impl Error for DecodeError { fn description(&self) -> &str { match *self { DecodeError::UnknownRealmByte => "Unknown realm byte in Onion packet", + DecodeError::UnknownRequiredFeature => "Unknown required feature preventing decode", DecodeError::BadPublicKey => "Invalid public key in packet", DecodeError::BadSignature => "Invalid signature in packet", - DecodeError::WrongLength => "Data was wrong length for packet", + DecodeError::BadText => "Invalid text in packet", + DecodeError::ShortRead => "Packet extended beyond the provided bytes", DecodeError::ExtraAddressesPerType => "More than one address of a single type", + DecodeError::BadLengthDescriptor => "A length descriptor in the packet didn't describe the later data correctly", + DecodeError::Io(ref e) => e.description(), + DecodeError::InvalidValue => "0 or 1 is not found for boolean", } } } @@ -486,6 +546,16 @@ impl fmt::Debug for HandleError { } } +impl From<::std::io::Error> for DecodeError { + fn from(e: ::std::io::Error) -> Self { + if e.kind() == ::std::io::ErrorKind::UnexpectedEof { + DecodeError::ShortRead + } else { + DecodeError::Io(e) + } + } +} + macro_rules! secp_pubkey { ( $ctx: expr, $slice: expr ) => { match PublicKey::from_slice($ctx, $slice) { @@ -506,9 +576,9 @@ macro_rules! secp_signature { impl MsgDecodable for LocalFeatures { fn decode(v: &[u8]) -> Result { - if v.len() < 3 { return Err(DecodeError::WrongLength); } + if v.len() < 2 { return Err(DecodeError::ShortRead); } let len = byte_utils::slice_to_be16(&v[0..2]) as usize; - if v.len() < len + 2 { return Err(DecodeError::WrongLength); } + if v.len() < len + 2 { return Err(DecodeError::ShortRead); } let mut flags = Vec::with_capacity(len); flags.extend_from_slice(&v[2..2 + len]); Ok(Self { @@ -528,9 +598,9 @@ impl MsgEncodable for LocalFeatures { impl MsgDecodable for GlobalFeatures { fn decode(v: &[u8]) -> Result { - if v.len() < 3 { return Err(DecodeError::WrongLength); } + if v.len() < 2 { return Err(DecodeError::ShortRead); } let len = byte_utils::slice_to_be16(&v[0..2]) as usize; - if v.len() < len + 2 { return Err(DecodeError::WrongLength); } + if v.len() < len + 2 { return Err(DecodeError::ShortRead); } let mut flags = Vec::with_capacity(len); flags.extend_from_slice(&v[2..2 + len]); Ok(Self { @@ -552,7 +622,7 @@ impl MsgDecodable for Init { fn decode(v: &[u8]) -> Result { let global_features = GlobalFeatures::decode(v)?; if v.len() < global_features.flags.len() + 4 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let local_features = LocalFeatures::decode(&v[global_features.flags.len() + 2..])?; Ok(Self { @@ -570,10 +640,58 @@ impl MsgEncodable for Init { } } +impl MsgDecodable for Ping { + fn decode(v: &[u8]) -> Result { + if v.len() < 4 { + return Err(DecodeError::ShortRead); + } + let ponglen = byte_utils::slice_to_be16(&v[0..2]); + let byteslen = byte_utils::slice_to_be16(&v[2..4]); + if v.len() < 4 + byteslen as usize { + return Err(DecodeError::ShortRead); + } + Ok(Self { + ponglen, + byteslen, + }) + } +} +impl MsgEncodable for Ping { + fn encode(&self) -> Vec { + let mut res = Vec::with_capacity(self.byteslen as usize + 2); + res.extend_from_slice(&byte_utils::be16_to_array(self.byteslen)); + res.resize(2 + self.byteslen as usize, 0); + res + } +} + +impl MsgDecodable for Pong { + fn decode(v: &[u8]) -> Result { + if v.len() < 2 { + return Err(DecodeError::ShortRead); + } + let byteslen = byte_utils::slice_to_be16(&v[0..2]); + if v.len() < 2 + byteslen as usize { + return Err(DecodeError::ShortRead); + } + Ok(Self { + byteslen + }) + } +} +impl MsgEncodable for Pong { + fn encode(&self) -> Vec { + let mut res = Vec::with_capacity(self.byteslen as usize + 2); + res.extend_from_slice(&byte_utils::be16_to_array(self.byteslen)); + res.resize(2 + self.byteslen as usize, 0); + res + } +} + impl MsgDecodable for OpenChannel { fn decode(v: &[u8]) -> Result { if v.len() < 2*32+6*8+4+2*2+6*33+1 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let ctx = Secp256k1::without_caps(); @@ -581,16 +699,15 @@ impl MsgDecodable for OpenChannel { if v.len() >= 321 { let len = byte_utils::slice_to_be16(&v[319..321]) as usize; if v.len() < 321+len { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } shutdown_scriptpubkey = Some(Script::from(v[321..321+len].to_vec())); - } else if v.len() != 2*32+6*8+4+2*2+6*33+1 { // Message cant have 1 extra byte - return Err(DecodeError::WrongLength); } - + let mut temp_channel_id = [0; 32]; + temp_channel_id[..].copy_from_slice(&v[32..64]); Ok(OpenChannel { chain_hash: deserialize(&v[0..32]).unwrap(), - temporary_channel_id: deserialize(&v[32..64]).unwrap(), + temporary_channel_id: temp_channel_id, funding_satoshis: byte_utils::slice_to_be64(&v[64..72]), push_msat: byte_utils::slice_to_be64(&v[72..80]), dust_limit_satoshis: byte_utils::slice_to_be64(&v[80..88]), @@ -646,7 +763,7 @@ impl MsgEncodable for OpenChannel { impl MsgDecodable for AcceptChannel { fn decode(v: &[u8]) -> Result { if v.len() < 32+4*8+4+2*2+6*33 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let ctx = Secp256k1::without_caps(); @@ -654,15 +771,15 @@ impl MsgDecodable for AcceptChannel { if v.len() >= 272 { let len = byte_utils::slice_to_be16(&v[270..272]) as usize; if v.len() < 272+len { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } shutdown_scriptpubkey = Some(Script::from(v[272..272+len].to_vec())); - } else if v.len() != 32+4*8+4+2*2+6*33 { // Message cant have 1 extra byte - return Err(DecodeError::WrongLength); } + let mut temporary_channel_id = [0; 32]; + temporary_channel_id[..].copy_from_slice(&v[0..32]); Ok(Self { - temporary_channel_id: deserialize(&v[0..32]).unwrap(), + temporary_channel_id, dust_limit_satoshis: byte_utils::slice_to_be64(&v[32..40]), max_htlc_value_in_flight_msat: byte_utils::slice_to_be64(&v[40..48]), channel_reserve_satoshis: byte_utils::slice_to_be64(&v[48..56]), @@ -686,7 +803,7 @@ impl MsgEncodable for AcceptChannel { &Some(ref script) => Vec::with_capacity(270 + 2 + script.len()), &None => Vec::with_capacity(270), }; - res.extend_from_slice(&serialize(&self.temporary_channel_id).unwrap()[..]); + res.extend_from_slice(&self.temporary_channel_id); res.extend_from_slice(&byte_utils::be64_to_array(self.dust_limit_satoshis)); res.extend_from_slice(&byte_utils::be64_to_array(self.max_htlc_value_in_flight_msat)); res.extend_from_slice(&byte_utils::be64_to_array(self.channel_reserve_satoshis)); @@ -711,11 +828,13 @@ impl MsgEncodable for AcceptChannel { impl MsgDecodable for FundingCreated { fn decode(v: &[u8]) -> Result { if v.len() < 32+32+2+64 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let ctx = Secp256k1::without_caps(); + let mut temporary_channel_id = [0; 32]; + temporary_channel_id[..].copy_from_slice(&v[0..32]); Ok(Self { - temporary_channel_id: deserialize(&v[0..32]).unwrap(), + temporary_channel_id, funding_txid: deserialize(&v[32..64]).unwrap(), funding_output_index: byte_utils::slice_to_be16(&v[64..66]), signature: secp_signature!(&ctx, &v[66..130]), @@ -725,7 +844,7 @@ impl MsgDecodable for FundingCreated { impl MsgEncodable for FundingCreated { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+32+2+64); - res.extend_from_slice(&serialize(&self.temporary_channel_id).unwrap()[..]); + res.extend_from_slice(&self.temporary_channel_id); res.extend_from_slice(&serialize(&self.funding_txid).unwrap()[..]); res.extend_from_slice(&byte_utils::be16_to_array(self.funding_output_index)); let secp_ctx = Secp256k1::without_caps(); @@ -737,11 +856,13 @@ impl MsgEncodable for FundingCreated { impl MsgDecodable for FundingSigned { fn decode(v: &[u8]) -> Result { if v.len() < 32+64 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let ctx = Secp256k1::without_caps(); + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); Ok(Self { - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, signature: secp_signature!(&ctx, &v[32..96]), }) } @@ -749,7 +870,7 @@ impl MsgDecodable for FundingSigned { impl MsgEncodable for FundingSigned { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+64); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&self.signature.serialize_compact(&Secp256k1::without_caps())); res } @@ -758,11 +879,13 @@ impl MsgEncodable for FundingSigned { impl MsgDecodable for FundingLocked { fn decode(v: &[u8]) -> Result { if v.len() < 32+33 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let ctx = Secp256k1::without_caps(); + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); Ok(Self { - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, next_per_commitment_point: secp_pubkey!(&ctx, &v[32..65]), }) } @@ -770,7 +893,7 @@ impl MsgDecodable for FundingLocked { impl MsgEncodable for FundingLocked { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+33); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&self.next_per_commitment_point.serialize()); res } @@ -779,14 +902,16 @@ impl MsgEncodable for FundingLocked { impl MsgDecodable for Shutdown { fn decode(v: &[u8]) -> Result { if v.len() < 32 + 2 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let scriptlen = byte_utils::slice_to_be16(&v[32..34]) as usize; if v.len() < 32 + 2 + scriptlen { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); Ok(Self { - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, scriptpubkey: Script::from(v[34..34 + scriptlen].to_vec()), }) } @@ -794,7 +919,7 @@ impl MsgDecodable for Shutdown { impl MsgEncodable for Shutdown { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32 + 2 + self.scriptpubkey.len()); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&byte_utils::be16_to_array(self.scriptpubkey.len() as u16)); res.extend_from_slice(&self.scriptpubkey[..]); res @@ -804,11 +929,13 @@ impl MsgEncodable for Shutdown { impl MsgDecodable for ClosingSigned { fn decode(v: &[u8]) -> Result { if v.len() < 32 + 8 + 64 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let secp_ctx = Secp256k1::without_caps(); + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); Ok(Self { - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, fee_satoshis: byte_utils::slice_to_be64(&v[32..40]), signature: secp_signature!(&secp_ctx, &v[40..104]), }) @@ -817,7 +944,7 @@ impl MsgDecodable for ClosingSigned { impl MsgEncodable for ClosingSigned { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+8+64); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&byte_utils::be64_to_array(self.fee_satoshis)); let secp_ctx = Secp256k1::without_caps(); res.extend_from_slice(&self.signature.serialize_compact(&secp_ctx)); @@ -828,12 +955,14 @@ impl MsgEncodable for ClosingSigned { impl MsgDecodable for UpdateAddHTLC { fn decode(v: &[u8]) -> Result { if v.len() < 32+8+8+32+4+1+33+20*65+32 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); let mut payment_hash = [0; 32]; payment_hash.copy_from_slice(&v[48..80]); Ok(Self{ - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, htlc_id: byte_utils::slice_to_be64(&v[32..40]), amount_msat: byte_utils::slice_to_be64(&v[40..48]), payment_hash, @@ -844,8 +973,8 @@ impl MsgDecodable for UpdateAddHTLC { } impl MsgEncodable for UpdateAddHTLC { fn encode(&self) -> Vec { - let mut res = Vec::with_capacity(32+8+8+32+4+1+1366); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + let mut res = Vec::with_capacity(32+8+8+32+4+1366); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id)); res.extend_from_slice(&byte_utils::be64_to_array(self.amount_msat)); res.extend_from_slice(&self.payment_hash); @@ -858,12 +987,14 @@ impl MsgEncodable for UpdateAddHTLC { impl MsgDecodable for UpdateFulfillHTLC { fn decode(v: &[u8]) -> Result { if v.len() < 32+8+32 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); let mut payment_preimage = [0; 32]; payment_preimage.copy_from_slice(&v[40..72]); Ok(Self{ - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, htlc_id: byte_utils::slice_to_be64(&v[32..40]), payment_preimage, }) @@ -872,7 +1003,7 @@ impl MsgDecodable for UpdateFulfillHTLC { impl MsgEncodable for UpdateFulfillHTLC { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+8+32); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id)); res.extend_from_slice(&self.payment_preimage); res @@ -882,10 +1013,12 @@ impl MsgEncodable for UpdateFulfillHTLC { impl MsgDecodable for UpdateFailHTLC { fn decode(v: &[u8]) -> Result { if v.len() < 32+8 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); Ok(Self{ - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, htlc_id: byte_utils::slice_to_be64(&v[32..40]), reason: OnionErrorPacket::decode(&v[40..])?, }) @@ -895,7 +1028,7 @@ impl MsgEncodable for UpdateFailHTLC { fn encode(&self) -> Vec { let reason = self.reason.encode(); let mut res = Vec::with_capacity(32+8+reason.len()); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id)); res.extend_from_slice(&reason[..]); res @@ -905,12 +1038,14 @@ impl MsgEncodable for UpdateFailHTLC { impl MsgDecodable for UpdateFailMalformedHTLC { fn decode(v: &[u8]) -> Result { if v.len() < 32+8+32+2 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); let mut sha256_of_onion = [0; 32]; sha256_of_onion.copy_from_slice(&v[40..72]); Ok(Self{ - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, htlc_id: byte_utils::slice_to_be64(&v[32..40]), sha256_of_onion, failure_code: byte_utils::slice_to_be16(&v[72..74]), @@ -920,7 +1055,7 @@ impl MsgDecodable for UpdateFailMalformedHTLC { impl MsgEncodable for UpdateFailMalformedHTLC { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+8+32+2); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id)); res.extend_from_slice(&self.sha256_of_onion); res.extend_from_slice(&byte_utils::be16_to_array(self.failure_code)); @@ -931,11 +1066,14 @@ impl MsgEncodable for UpdateFailMalformedHTLC { impl MsgDecodable for CommitmentSigned { fn decode(v: &[u8]) -> Result { if v.len() < 32+64+2 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); + let htlcs = byte_utils::slice_to_be16(&v[96..98]) as usize; if v.len() < 32+64+2+htlcs*64 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let mut htlc_signatures = Vec::with_capacity(htlcs); let secp_ctx = Secp256k1::without_caps(); @@ -943,7 +1081,7 @@ impl MsgDecodable for CommitmentSigned { htlc_signatures.push(secp_signature!(&secp_ctx, &v[98+i*64..98+(i+1)*64])); } Ok(Self { - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, signature: secp_signature!(&secp_ctx, &v[32..96]), htlc_signatures, }) @@ -952,7 +1090,7 @@ impl MsgDecodable for CommitmentSigned { impl MsgEncodable for CommitmentSigned { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+64+2+self.htlc_signatures.len()*64); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); let secp_ctx = Secp256k1::without_caps(); res.extend_from_slice(&self.signature.serialize_compact(&secp_ctx)); res.extend_from_slice(&byte_utils::be16_to_array(self.htlc_signatures.len() as u16)); @@ -966,13 +1104,15 @@ impl MsgEncodable for CommitmentSigned { impl MsgDecodable for RevokeAndACK { fn decode(v: &[u8]) -> Result { if v.len() < 32+32+33 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); let mut per_commitment_secret = [0; 32]; per_commitment_secret.copy_from_slice(&v[32..64]); let secp_ctx = Secp256k1::without_caps(); Ok(Self { - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, per_commitment_secret, next_per_commitment_point: secp_pubkey!(&secp_ctx, &v[64..97]), }) @@ -981,7 +1121,7 @@ impl MsgDecodable for RevokeAndACK { impl MsgEncodable for RevokeAndACK { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+32+33); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&self.per_commitment_secret); res.extend_from_slice(&self.next_per_commitment_point.serialize()); res @@ -991,10 +1131,12 @@ impl MsgEncodable for RevokeAndACK { impl MsgDecodable for UpdateFee { fn decode(v: &[u8]) -> Result { if v.len() < 32+4 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); Ok(Self { - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, feerate_per_kw: byte_utils::slice_to_be32(&v[32..36]), }) } @@ -1002,31 +1144,64 @@ impl MsgDecodable for UpdateFee { impl MsgEncodable for UpdateFee { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+4); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&byte_utils::be32_to_array(self.feerate_per_kw)); res } } impl MsgDecodable for ChannelReestablish { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+2*8 { + return Err(DecodeError::ShortRead); + } + + let data_loss_protect = if v.len() > 32+2*8 { + if v.len() < 32+2*8 + 33+32 { + return Err(DecodeError::ShortRead); + } + let mut inner_array = [0; 32]; + inner_array.copy_from_slice(&v[48..48+32]); + Some(DataLossProtect { + your_last_per_commitment_secret: inner_array, + my_current_per_commitment_point: secp_pubkey!(&Secp256k1::without_caps(), &v[48+32..48+32+33]), + }) + } else { None }; + + Ok(Self { + channel_id: deserialize(&v[0..32]).unwrap(), + next_local_commitment_number: byte_utils::slice_to_be64(&v[32..40]), + next_remote_commitment_number: byte_utils::slice_to_be64(&v[40..48]), + data_loss_protect: data_loss_protect, + }) } } impl MsgEncodable for ChannelReestablish { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(if self.data_loss_protect.is_some() { 32+2*8+33+32 } else { 32+2*8 }); + + res.extend_from_slice(&serialize(&self.channel_id).unwrap()[..]); + res.extend_from_slice(&byte_utils::be64_to_array(self.next_local_commitment_number)); + res.extend_from_slice(&byte_utils::be64_to_array(self.next_remote_commitment_number)); + + if let &Some(ref data_loss_protect) = &self.data_loss_protect { + res.extend_from_slice(&data_loss_protect.your_last_per_commitment_secret[..]); + res.extend_from_slice(&data_loss_protect.my_current_per_commitment_point.serialize()); + } + res } } impl MsgDecodable for AnnouncementSignatures { fn decode(v: &[u8]) -> Result { if v.len() < 32+8+64*2 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let secp_ctx = Secp256k1::without_caps(); + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); Ok(Self { - channel_id: deserialize(&v[0..32]).unwrap(), + channel_id, short_channel_id: byte_utils::slice_to_be64(&v[32..40]), node_signature: secp_signature!(&secp_ctx, &v[40..104]), bitcoin_signature: secp_signature!(&secp_ctx, &v[104..168]), @@ -1036,7 +1211,7 @@ impl MsgDecodable for AnnouncementSignatures { impl MsgEncodable for AnnouncementSignatures { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(32+8+64*2); - res.extend_from_slice(&serialize(&self.channel_id).unwrap()); + res.extend_from_slice(&self.channel_id); res.extend_from_slice(&byte_utils::be64_to_array(self.short_channel_id)); let secp_ctx = Secp256k1::without_caps(); res.extend_from_slice(&self.node_signature.serialize_compact(&secp_ctx)); @@ -1048,8 +1223,12 @@ impl MsgEncodable for AnnouncementSignatures { impl MsgDecodable for UnsignedNodeAnnouncement { fn decode(v: &[u8]) -> Result { let features = GlobalFeatures::decode(&v[..])?; + if features.requires_unknown_bits() { + return Err(DecodeError::UnknownRequiredFeature); + } + if v.len() < features.encoded_len() + 4 + 33 + 3 + 32 + 2 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let start = features.encoded_len(); @@ -1061,22 +1240,22 @@ impl MsgDecodable for UnsignedNodeAnnouncement { let addrlen = byte_utils::slice_to_be16(&v[start + 72..start + 74]) as usize; if v.len() < start + 74 + addrlen { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let addr_read_limit = start + 74 + addrlen; let mut addresses = Vec::with_capacity(4); let mut read_pos = start + 74; loop { - if v.len() <= read_pos { break; } + if addr_read_limit <= read_pos { break; } match v[read_pos] { - 0 => { read_pos += 1; }, 1 => { - if v.len() < read_pos + 1 + 6 { - return Err(DecodeError::WrongLength); - } if addresses.len() > 0 { return Err(DecodeError::ExtraAddressesPerType); } + if addr_read_limit < read_pos + 1 + 6 { + return Err(DecodeError::BadLengthDescriptor); + } let mut addr = [0; 4]; addr.copy_from_slice(&v[read_pos + 1..read_pos + 5]); addresses.push(NetAddress::IPv4 { @@ -1086,12 +1265,12 @@ impl MsgDecodable for UnsignedNodeAnnouncement { read_pos += 1 + 6; }, 2 => { - if v.len() < read_pos + 1 + 18 { - return Err(DecodeError::WrongLength); - } if addresses.len() > 1 || (addresses.len() == 1 && addresses[0].get_id() != 1) { return Err(DecodeError::ExtraAddressesPerType); } + if addr_read_limit < read_pos + 1 + 18 { + return Err(DecodeError::BadLengthDescriptor); + } let mut addr = [0; 16]; addr.copy_from_slice(&v[read_pos + 1..read_pos + 17]); addresses.push(NetAddress::IPv6 { @@ -1101,12 +1280,12 @@ impl MsgDecodable for UnsignedNodeAnnouncement { read_pos += 1 + 18; }, 3 => { - if v.len() < read_pos + 1 + 12 { - return Err(DecodeError::WrongLength); - } if addresses.len() > 2 || (addresses.len() > 0 && addresses.last().unwrap().get_id() > 2) { return Err(DecodeError::ExtraAddressesPerType); } + if addr_read_limit < read_pos + 1 + 12 { + return Err(DecodeError::BadLengthDescriptor); + } let mut addr = [0; 10]; addr.copy_from_slice(&v[read_pos + 1..read_pos + 11]); addresses.push(NetAddress::OnionV2 { @@ -1116,12 +1295,12 @@ impl MsgDecodable for UnsignedNodeAnnouncement { read_pos += 1 + 12; }, 4 => { - if v.len() < read_pos + 1 + 37 { - return Err(DecodeError::WrongLength); - } if addresses.len() > 3 || (addresses.len() > 0 && addresses.last().unwrap().get_id() > 3) { return Err(DecodeError::ExtraAddressesPerType); } + if addr_read_limit < read_pos + 1 + 37 { + return Err(DecodeError::BadLengthDescriptor); + } let mut ed25519_pubkey = [0; 32]; ed25519_pubkey.copy_from_slice(&v[read_pos + 1..read_pos + 33]); addresses.push(NetAddress::OnionV3 { @@ -1136,6 +1315,15 @@ impl MsgDecodable for UnsignedNodeAnnouncement { } } + let excess_address_data = if read_pos < addr_read_limit { + let mut excess_address_data = Vec::with_capacity(addr_read_limit - read_pos); + excess_address_data.extend_from_slice(&v[read_pos..addr_read_limit]); + excess_address_data + } else { Vec::new() }; + + let mut excess_data = Vec::with_capacity(v.len() - addr_read_limit); + excess_data.extend_from_slice(&v[addr_read_limit..]); + let secp_ctx = Secp256k1::without_caps(); Ok(Self { features, @@ -1144,13 +1332,15 @@ impl MsgDecodable for UnsignedNodeAnnouncement { rgb, alias, addresses, + excess_address_data, + excess_data, }) } } impl MsgEncodable for UnsignedNodeAnnouncement { fn encode(&self) -> Vec { let features = self.features.encode(); - let mut res = Vec::with_capacity(74 + features.len() + self.addresses.len()); + let mut res = Vec::with_capacity(74 + features.len() + self.addresses.len()*7 + self.excess_address_data.len() + self.excess_data.len()); res.extend_from_slice(&features[..]); res.extend_from_slice(&byte_utils::be32_to_array(self.timestamp)); res.extend_from_slice(&self.node_id.serialize()); @@ -1186,8 +1376,10 @@ impl MsgEncodable for UnsignedNodeAnnouncement { }, } } - res.extend_from_slice(&byte_utils::be16_to_array(addr_slice.len() as u16)); + res.extend_from_slice(&byte_utils::be16_to_array((addr_slice.len() + self.excess_address_data.len()) as u16)); res.extend_from_slice(&addr_slice[..]); + res.extend_from_slice(&self.excess_address_data[..]); + res.extend_from_slice(&self.excess_data[..]); res } } @@ -1195,7 +1387,7 @@ impl MsgEncodable for UnsignedNodeAnnouncement { impl MsgDecodable for NodeAnnouncement { fn decode(v: &[u8]) -> Result { if v.len() < 64 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let secp_ctx = Secp256k1::without_caps(); Ok(Self { @@ -1218,11 +1410,16 @@ impl MsgEncodable for NodeAnnouncement { impl MsgDecodable for UnsignedChannelAnnouncement { fn decode(v: &[u8]) -> Result { let features = GlobalFeatures::decode(&v[..])?; + if features.requires_unknown_bits() { + return Err(DecodeError::UnknownRequiredFeature); + } if v.len() < features.encoded_len() + 32 + 8 + 33*4 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let start = features.encoded_len(); let secp_ctx = Secp256k1::without_caps(); + let mut excess_data = Vec::with_capacity(v.len() - start - 172); + excess_data.extend_from_slice(&v[start + 172..]); Ok(Self { features, chain_hash: deserialize(&v[start..start + 32]).unwrap(), @@ -1231,13 +1428,14 @@ impl MsgDecodable for UnsignedChannelAnnouncement { node_id_2: secp_pubkey!(&secp_ctx, &v[start + 73..start + 106]), bitcoin_key_1: secp_pubkey!(&secp_ctx, &v[start + 106..start + 139]), bitcoin_key_2: secp_pubkey!(&secp_ctx, &v[start + 139..start + 172]), + excess_data, }) } } impl MsgEncodable for UnsignedChannelAnnouncement { fn encode(&self) -> Vec { let features = self.features.encode(); - let mut res = Vec::with_capacity(172 + features.len()); + let mut res = Vec::with_capacity(172 + features.len() + self.excess_data.len()); res.extend_from_slice(&features[..]); res.extend_from_slice(&self.chain_hash[..]); res.extend_from_slice(&byte_utils::be64_to_array(self.short_channel_id)); @@ -1245,6 +1443,7 @@ impl MsgEncodable for UnsignedChannelAnnouncement { res.extend_from_slice(&self.node_id_2.serialize()); res.extend_from_slice(&self.bitcoin_key_1.serialize()); res.extend_from_slice(&self.bitcoin_key_2.serialize()); + res.extend_from_slice(&self.excess_data[..]); res } } @@ -1252,7 +1451,7 @@ impl MsgEncodable for UnsignedChannelAnnouncement { impl MsgDecodable for ChannelAnnouncement { fn decode(v: &[u8]) -> Result { if v.len() < 64*4 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let secp_ctx = Secp256k1::without_caps(); Ok(Self { @@ -1281,8 +1480,10 @@ impl MsgEncodable for ChannelAnnouncement { impl MsgDecodable for UnsignedChannelUpdate { fn decode(v: &[u8]) -> Result { if v.len() < 32+8+4+2+2+8+4+4 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } + let mut excess_data = Vec::with_capacity(v.len() - 64); + excess_data.extend_from_slice(&v[64..]); Ok(Self { chain_hash: deserialize(&v[0..32]).unwrap(), short_channel_id: byte_utils::slice_to_be64(&v[32..40]), @@ -1292,12 +1493,13 @@ impl MsgDecodable for UnsignedChannelUpdate { htlc_minimum_msat: byte_utils::slice_to_be64(&v[48..56]), fee_base_msat: byte_utils::slice_to_be32(&v[56..60]), fee_proportional_millionths: byte_utils::slice_to_be32(&v[60..64]), + excess_data }) } } impl MsgEncodable for UnsignedChannelUpdate { fn encode(&self) -> Vec { - let mut res = Vec::with_capacity(64); + let mut res = Vec::with_capacity(64 + self.excess_data.len()); res.extend_from_slice(&self.chain_hash[..]); res.extend_from_slice(&byte_utils::be64_to_array(self.short_channel_id)); res.extend_from_slice(&byte_utils::be32_to_array(self.timestamp)); @@ -1306,6 +1508,7 @@ impl MsgEncodable for UnsignedChannelUpdate { res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_minimum_msat)); res.extend_from_slice(&byte_utils::be32_to_array(self.fee_base_msat)); res.extend_from_slice(&byte_utils::be32_to_array(self.fee_proportional_millionths)); + res.extend_from_slice(&self.excess_data[..]); res } } @@ -1313,7 +1516,7 @@ impl MsgEncodable for UnsignedChannelUpdate { impl MsgDecodable for ChannelUpdate { fn decode(v: &[u8]) -> Result { if v.len() < 128 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let secp_ctx = Secp256k1::without_caps(); Ok(Self { @@ -1334,7 +1537,7 @@ impl MsgEncodable for ChannelUpdate { impl MsgDecodable for OnionRealm0HopData { fn decode(v: &[u8]) -> Result { if v.len() < 32 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } Ok(OnionRealm0HopData { short_channel_id: byte_utils::slice_to_be64(&v[0..8]), @@ -1357,7 +1560,7 @@ impl MsgEncodable for OnionRealm0HopData { impl MsgDecodable for OnionHopData { fn decode(v: &[u8]) -> Result { if v.len() < 65 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let realm = v[0]; if realm != 0 { @@ -1385,7 +1588,7 @@ impl MsgEncodable for OnionHopData { impl MsgDecodable for OnionPacket { fn decode(v: &[u8]) -> Result { if v.len() < 1+33+20*65+32 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let mut hop_data = [0; 20*65]; hop_data.copy_from_slice(&v[34..1334]); @@ -1394,7 +1597,7 @@ impl MsgDecodable for OnionPacket { let secp_ctx = Secp256k1::without_caps(); Ok(Self { version: v[0], - public_key: secp_pubkey!(&secp_ctx, &v[1..34]), + public_key: PublicKey::from_slice(&secp_ctx, &v[1..34]), hop_data, hmac, }) @@ -1404,7 +1607,10 @@ impl MsgEncodable for OnionPacket { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(1 + 33 + 20*65 + 32); res.push(self.version); - res.extend_from_slice(&self.public_key.serialize()); + match self.public_key { + Ok(pubkey) => res.extend_from_slice(&pubkey.serialize()), + Err(_) => res.extend_from_slice(&[0; 33]), + } res.extend_from_slice(&self.hop_data); res.extend_from_slice(&self.hmac); res @@ -1414,15 +1620,15 @@ impl MsgEncodable for OnionPacket { impl MsgDecodable for DecodedOnionErrorPacket { fn decode(v: &[u8]) -> Result { if v.len() < 32 + 4 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let failuremsg_len = byte_utils::slice_to_be16(&v[32..34]) as usize; if v.len() < 32 + 4 + failuremsg_len { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let padding_len = byte_utils::slice_to_be16(&v[34 + failuremsg_len..]) as usize; if v.len() < 32 + 4 + failuremsg_len + padding_len { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let mut hmac = [0; 32]; @@ -1449,11 +1655,11 @@ impl MsgEncodable for DecodedOnionErrorPacket { impl MsgDecodable for OnionErrorPacket { fn decode(v: &[u8]) -> Result { if v.len() < 2 { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } let len = byte_utils::slice_to_be16(&v[0..2]) as usize; if v.len() < 2 + len { - return Err(DecodeError::WrongLength); + return Err(DecodeError::ShortRead); } Ok(Self { data: v[2..len+2].to_vec(), @@ -1468,3 +1674,700 @@ impl MsgEncodable for OnionErrorPacket { res } } + +impl MsgEncodable for ErrorMessage { + fn encode(&self) -> Vec { + let mut res = Vec::with_capacity(34 + self.data.len()); + res.extend_from_slice(&self.channel_id); + res.extend_from_slice(&byte_utils::be16_to_array(self.data.len() as u16)); + res.extend_from_slice(&self.data.as_bytes()); + res + } +} +impl MsgDecodable for ErrorMessage { + fn decode(v: &[u8]) -> Result { + if v.len() < 34 { + return Err(DecodeError::ShortRead); + } + // Unlike most messages, BOLT 1 requires we truncate our read if the value is out of range + let len = cmp::min(byte_utils::slice_to_be16(&v[32..34]) as usize, v.len() - 34); + let data = match String::from_utf8(v[34..34 + len].to_vec()) { + Ok(s) => s, + Err(_) => return Err(DecodeError::BadText), + }; + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); + Ok(Self { + channel_id, + data, + }) + } +} + +impl_writeable_len_match!(AcceptChannel, { + {AcceptChannel{ shutdown_scriptpubkey: Some(ref script), ..}, 270 + 2 + script.len()}, + {_, 270} + }, { + temporary_channel_id, + dust_limit_satoshis, + max_htlc_value_in_flight_msat, + channel_reserve_satoshis, + htlc_minimum_msat, + minimum_depth, + to_self_delay, + max_accepted_htlcs, + funding_pubkey, + revocation_basepoint, + payment_basepoint, + delayed_payment_basepoint, + htlc_basepoint, + first_per_commitment_point, + shutdown_scriptpubkey +}); + +impl_writeable!(AnnouncementSignatures, 32+8+64*2, { + channel_id, + short_channel_id, + node_signature, + bitcoin_signature +}); + +impl Writeable for ChannelReestablish { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(if self.data_loss_protect.is_some() { 32+2*8+33+32 } else { 32+2*8 }); + self.channel_id.write(w)?; + self.next_local_commitment_number.write(w)?; + self.next_remote_commitment_number.write(w)?; + if let Some(ref data_loss_protect) = self.data_loss_protect { + data_loss_protect.your_last_per_commitment_secret.write(w)?; + data_loss_protect.my_current_per_commitment_point.write(w)?; + } + Ok(()) + } +} + +impl Readable for ChannelReestablish{ + fn read(r: &mut R) -> Result { + Ok(Self { + channel_id: Readable::read(r)?, + next_local_commitment_number: Readable::read(r)?, + next_remote_commitment_number: Readable::read(r)?, + data_loss_protect: { + match <[u8; 32] as Readable>::read(r) { + Ok(your_last_per_commitment_secret) => + Some(DataLossProtect { + your_last_per_commitment_secret, + my_current_per_commitment_point: Readable::read(r)?, + }), + Err(DecodeError::ShortRead) => None, + Err(e) => return Err(e) + } + } + }) + } +} + +impl_writeable!(ClosingSigned, 32+8+64, { + channel_id, + fee_satoshis, + signature +}); + +impl_writeable_len_match!(CommitmentSigned, { + { CommitmentSigned { ref htlc_signatures, .. }, 32+64+2+htlc_signatures.len()*64 } + }, { + channel_id, + signature, + htlc_signatures +}); + +impl_writeable_len_match!(DecodedOnionErrorPacket, { + { DecodedOnionErrorPacket { ref failuremsg, ref pad, .. }, 32 + 4 + failuremsg.len() + pad.len() } + }, { + hmac, + failuremsg, + pad +}); + +impl_writeable!(FundingCreated, 32+32+2+64, { + temporary_channel_id, + funding_txid, + funding_output_index, + signature +}); + +impl_writeable!(FundingSigned, 32+64, { + channel_id, + signature +}); + +impl_writeable!(FundingLocked, 32+33, { + channel_id, + next_per_commitment_point +}); + +impl_writeable_len_match!(GlobalFeatures, { + { GlobalFeatures { ref flags }, flags.len() + 2 } + }, { + flags +}); + +impl_writeable_len_match!(LocalFeatures, { + { LocalFeatures { ref flags }, flags.len() + 2 } + }, { + flags +}); + +impl_writeable_len_match!(Init, { + { Init { ref global_features, ref local_features }, global_features.flags.len() + local_features.flags.len() + 4 } + }, { + global_features, + local_features +}); + +impl_writeable_len_match!(OpenChannel, { + { OpenChannel { shutdown_scriptpubkey: Some(ref script), .. }, 319 + 2 + script.len() }, + { OpenChannel { shutdown_scriptpubkey: None, .. }, 319 } + }, { + chain_hash, + temporary_channel_id, + funding_satoshis, + push_msat, + dust_limit_satoshis, + max_htlc_value_in_flight_msat, + channel_reserve_satoshis, + htlc_minimum_msat, + feerate_per_kw, + to_self_delay, + max_accepted_htlcs, + funding_pubkey, + revocation_basepoint, + payment_basepoint, + delayed_payment_basepoint, + htlc_basepoint, + first_per_commitment_point, + channel_flags, + shutdown_scriptpubkey +}); + +impl_writeable!(RevokeAndACK, 32+32+33, { + channel_id, + per_commitment_secret, + next_per_commitment_point +}); + +impl_writeable_len_match!(Shutdown, { + { Shutdown { ref scriptpubkey, .. }, 32 + 2 + scriptpubkey.len() } + }, { + channel_id, + scriptpubkey +}); + +impl_writeable_len_match!(UpdateFailHTLC, { + { UpdateFailHTLC { ref reason, .. }, 32 + 10 + reason.data.len() } + }, { + channel_id, + htlc_id, + reason +}); + +impl_writeable!(UpdateFailMalformedHTLC, 32+8+32+2, { + channel_id, + htlc_id, + sha256_of_onion, + failure_code +}); + +impl_writeable!(UpdateFee, 32+4, { + channel_id, + feerate_per_kw +}); + +impl_writeable!(UpdateFulfillHTLC, 32+8+32, { + channel_id, + htlc_id, + payment_preimage +}); + +impl_writeable_len_match!(OnionErrorPacket, { + { OnionErrorPacket { ref data, .. }, 2 + data.len() } + }, { + data +}); + +impl Writeable for OnionPacket { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(1 + 33 + 20*65 + 32); + self.version.write(w)?; + match self.public_key { + Ok(pubkey) => pubkey.write(w)?, + Err(_) => [0u8;33].write(w)?, + } + w.write_all(&self.hop_data)?; + self.hmac.write(w)?; + Ok(()) + } +} + +impl Readable for OnionPacket { + fn read(r: &mut R) -> Result { + Ok(OnionPacket { + version: Readable::read(r)?, + public_key: { + let mut buf = [0u8;33]; + r.read_exact(&mut buf)?; + PublicKey::from_slice(&Secp256k1::without_caps(), &buf) + }, + hop_data: Readable::read(r)?, + hmac: Readable::read(r)?, + }) + } +} + +impl_writeable!(UpdateAddHTLC, 32+8+8+32+4+1366, { + channel_id, + htlc_id, + amount_msat, + payment_hash, + cltv_expiry, + onion_routing_packet +}); + +impl Writeable for OnionRealm0HopData { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(32); + self.short_channel_id.write(w)?; + self.amt_to_forward.write(w)?; + self.outgoing_cltv_value.write(w)?; + w.write_all(&[0;12])?; + Ok(()) + } +} + +impl Readable for OnionRealm0HopData { + fn read(r: &mut R) -> Result { + Ok(OnionRealm0HopData { + short_channel_id: Readable::read(r)?, + amt_to_forward: Readable::read(r)?, + outgoing_cltv_value: { + let v: u32 = Readable::read(r)?; + r.read_exact(&mut [0; 12])?; + v + } + }) + } +} + +impl Writeable for OnionHopData { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(65); + self.realm.write(w)?; + self.data.write(w)?; + self.hmac.write(w)?; + Ok(()) + } +} + +impl Readable for OnionHopData { + fn read(r: &mut R) -> Result { + Ok(OnionHopData { + realm: { + let r: u8 = Readable::read(r)?; + if r != 0 { + return Err(DecodeError::UnknownRealmByte); + } + r + }, + data: Readable::read(r)?, + hmac: Readable::read(r)?, + }) + } +} + +impl Writeable for Ping { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(self.byteslen as usize + 4); + self.ponglen.write(w)?; + vec![0u8; self.byteslen as usize].write(w)?; // size-unchecked write + Ok(()) + } +} + +impl Readable for Ping { + fn read(r: &mut R) -> Result { + Ok(Ping { + ponglen: Readable::read(r)?, + byteslen: { + let byteslen = Readable::read(r)?; + r.read_exact(&mut vec![0u8; byteslen as usize][..])?; + byteslen + } + }) + } +} + +impl Writeable for Pong { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(self.byteslen as usize + 2); + vec![0u8; self.byteslen as usize].write(w)?; // size-unchecked write + Ok(()) + } +} + +impl Readable for Pong { + fn read(r: &mut R) -> Result { + Ok(Pong { + byteslen: { + let byteslen = Readable::read(r)?; + r.read_exact(&mut vec![0u8; byteslen as usize][..])?; + byteslen + } + }) + } +} + +impl Writeable for UnsignedChannelAnnouncement { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(2 + 2*32 + 4*33 + self.features.flags.len() + self.excess_data.len()); + self.features.write(w)?; + self.chain_hash.write(w)?; + self.short_channel_id.write(w)?; + self.node_id_1.write(w)?; + self.node_id_2.write(w)?; + self.bitcoin_key_1.write(w)?; + self.bitcoin_key_2.write(w)?; + w.write_all(&self.excess_data[..])?; + Ok(()) + } +} + +impl Readable for UnsignedChannelAnnouncement { + fn read(r: &mut R) -> Result { + Ok(Self { + features: { + let f: GlobalFeatures = Readable::read(r)?; + if f.requires_unknown_bits() { + return Err(DecodeError::UnknownRequiredFeature); + } + f + }, + chain_hash: Readable::read(r)?, + short_channel_id: Readable::read(r)?, + node_id_1: Readable::read(r)?, + node_id_2: Readable::read(r)?, + bitcoin_key_1: Readable::read(r)?, + bitcoin_key_2: Readable::read(r)?, + excess_data: { + let mut excess_data = vec![]; + r.read_to_end(&mut excess_data)?; + excess_data + }, + }) + } +} + +impl_writeable_len_match!(ChannelAnnouncement, { + { ChannelAnnouncement { contents: UnsignedChannelAnnouncement {ref features, ref excess_data, ..}, .. }, + 2 + 2*32 + 4*33 + features.flags.len() + excess_data.len() + 4*64 } + }, { + node_signature_1, + node_signature_2, + bitcoin_signature_1, + bitcoin_signature_2, + contents +}); + +impl Writeable for UnsignedChannelUpdate { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(64 + self.excess_data.len()); + self.chain_hash.write(w)?; + self.short_channel_id.write(w)?; + self.timestamp.write(w)?; + self.flags.write(w)?; + self.cltv_expiry_delta.write(w)?; + self.htlc_minimum_msat.write(w)?; + self.fee_base_msat.write(w)?; + self.fee_proportional_millionths.write(w)?; + w.write_all(&self.excess_data[..])?; + Ok(()) + } +} + +impl Readable for UnsignedChannelUpdate { + fn read(r: &mut R) -> Result { + Ok(Self { + chain_hash: Readable::read(r)?, + short_channel_id: Readable::read(r)?, + timestamp: Readable::read(r)?, + flags: Readable::read(r)?, + cltv_expiry_delta: Readable::read(r)?, + htlc_minimum_msat: Readable::read(r)?, + fee_base_msat: Readable::read(r)?, + fee_proportional_millionths: Readable::read(r)?, + excess_data: { + let mut excess_data = vec![]; + r.read_to_end(&mut excess_data)?; + excess_data + }, + }) + } +} + +impl_writeable_len_match!(ChannelUpdate, { + { ChannelUpdate { contents: UnsignedChannelUpdate {ref excess_data, ..}, .. }, + 64 + excess_data.len() + 64 } + }, { + signature, + contents +}); + +impl Writeable for ErrorMessage { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(32 + 2 + self.data.len()); + self.channel_id.write(w)?; + (self.data.len() as u16).write(w)?; + w.write_all(self.data.as_bytes())?; + Ok(()) + } +} + +impl Readable for ErrorMessage { + fn read(r: &mut R) -> Result { + Ok(Self { + channel_id: Readable::read(r)?, + data: { + let mut sz: usize = >::read(r)? as usize; + let mut data = vec![]; + let data_len = r.read_to_end(&mut data)?; + sz = cmp::min(data_len, sz); + match String::from_utf8(data[..sz as usize].to_vec()) { + Ok(s) => s, + Err(_) => return Err(DecodeError::BadText), + } + } + }) + } +} + +impl Writeable for UnsignedNodeAnnouncement { + fn write(&self, w: &mut W) -> Result<(), DecodeError> { + w.size_hint(64 + 76 + self.features.flags.len() + self.addresses.len()*38 + self.excess_address_data.len() + self.excess_data.len()); + self.features.write(w)?; + self.timestamp.write(w)?; + self.node_id.write(w)?; + w.write_all(&self.rgb)?; + self.alias.write(w)?; + + let mut addr_slice = Vec::with_capacity(self.addresses.len() * 18); + let mut addrs_to_encode = self.addresses.clone(); + addrs_to_encode.sort_unstable_by(|a, b| { a.get_id().cmp(&b.get_id()) }); + addrs_to_encode.dedup_by(|a, b| { a.get_id() == b.get_id() }); + for addr in addrs_to_encode.iter() { + match addr { + &NetAddress::IPv4{addr, port} => { + addr_slice.push(1); + addr_slice.extend_from_slice(&addr); + addr_slice.extend_from_slice(&byte_utils::be16_to_array(port)); + }, + &NetAddress::IPv6{addr, port} => { + addr_slice.push(2); + addr_slice.extend_from_slice(&addr); + addr_slice.extend_from_slice(&byte_utils::be16_to_array(port)); + }, + &NetAddress::OnionV2{addr, port} => { + addr_slice.push(3); + addr_slice.extend_from_slice(&addr); + addr_slice.extend_from_slice(&byte_utils::be16_to_array(port)); + }, + &NetAddress::OnionV3{ed25519_pubkey, checksum, version, port} => { + addr_slice.push(4); + addr_slice.extend_from_slice(&ed25519_pubkey); + addr_slice.extend_from_slice(&byte_utils::be16_to_array(checksum)); + addr_slice.push(version); + addr_slice.extend_from_slice(&byte_utils::be16_to_array(port)); + }, + } + } + ((addr_slice.len() + self.excess_address_data.len()) as u16).write(w)?; + w.write_all(&addr_slice[..])?; + w.write_all(&self.excess_address_data[..])?; + w.write_all(&self.excess_data[..])?; + Ok(()) + } +} + +impl Readable for UnsignedNodeAnnouncement { + fn read(r: &mut R) -> Result { + let features: GlobalFeatures = Readable::read(r)?; + if features.requires_unknown_bits() { + return Err(DecodeError::UnknownRequiredFeature); + } + let timestamp: u32 = Readable::read(r)?; + let node_id: PublicKey = Readable::read(r)?; + let mut rgb = [0; 3]; + r.read_exact(&mut rgb)?; + let alias: [u8; 32] = Readable::read(r)?; + + let addrlen: u16 = Readable::read(r)?; + let mut addr_readpos = 0; + let mut addresses = Vec::with_capacity(4); + let mut f: u8 = 0; + let mut excess = 0; + loop { + if addrlen <= addr_readpos { break; } + f = Readable::read(r)?; + match f { + 1 => { + if addresses.len() > 0 { + return Err(DecodeError::ExtraAddressesPerType); + } + if addrlen < addr_readpos + 1 + 6 { + return Err(DecodeError::BadLengthDescriptor); + } + addresses.push(NetAddress::IPv4 { + addr: { + let mut addr = [0; 4]; + r.read_exact(&mut addr)?; + addr + }, + port: Readable::read(r)?, + }); + addr_readpos += 1 + 6 + }, + 2 => { + if addresses.len() > 1 || (addresses.len() == 1 && addresses[0].get_id() != 1) { + return Err(DecodeError::ExtraAddressesPerType); + } + if addrlen < addr_readpos + 1 + 18 { + return Err(DecodeError::BadLengthDescriptor); + } + addresses.push(NetAddress::IPv6 { + addr: { + let mut addr = [0; 16]; + r.read_exact(&mut addr)?; + addr + }, + port: Readable::read(r)?, + }); + addr_readpos += 1 + 18 + }, + 3 => { + if addresses.len() > 2 || (addresses.len() > 0 && addresses.last().unwrap().get_id() > 2) { + return Err(DecodeError::ExtraAddressesPerType); + } + if addrlen < addr_readpos + 1 + 12 { + return Err(DecodeError::BadLengthDescriptor); + } + addresses.push(NetAddress::OnionV2 { + addr: { + let mut addr = [0; 10]; + r.read_exact(&mut addr)?; + addr + }, + port: Readable::read(r)?, + }); + addr_readpos += 1 + 12 + }, + 4 => { + if addresses.len() > 3 || (addresses.len() > 0 && addresses.last().unwrap().get_id() > 3) { + return Err(DecodeError::ExtraAddressesPerType); + } + if addrlen < addr_readpos + 1 + 37 { + return Err(DecodeError::BadLengthDescriptor); + } + addresses.push(NetAddress::OnionV3 { + ed25519_pubkey: Readable::read(r)?, + checksum: Readable::read(r)?, + version: Readable::read(r)?, + port: Readable::read(r)?, + }); + addr_readpos += 1 + 37 + }, + _ => { excess = 1; break; } + } + } + + let mut excess_data = vec![]; + let excess_address_data = if addr_readpos < addrlen { + let mut excess_address_data = vec![0; (addrlen - addr_readpos) as usize]; + r.read_exact(&mut excess_address_data[excess..])?; + if excess == 1 { + excess_address_data[0] = f; + } + excess_address_data + } else { + if excess == 1 { + excess_data.push(f); + } + Vec::new() + }; + + Ok(UnsignedNodeAnnouncement { + features: features, + timestamp: timestamp, + node_id: node_id, + rgb: rgb, + alias: alias, + addresses: addresses, + excess_address_data: excess_address_data, + excess_data: { + r.read_to_end(&mut excess_data)?; + excess_data + }, + }) + } +} + +impl_writeable_len_match!(NodeAnnouncement, { + { NodeAnnouncement { contents: UnsignedNodeAnnouncement { ref features, ref addresses, ref excess_address_data, ref excess_data, ..}, .. }, + 64 + 76 + features.flags.len() + addresses.len()*38 + excess_address_data.len() + excess_data.len() } + }, { + signature, + contents +}); + +#[cfg(test)] +mod tests { + use hex; + use ln::msgs::MsgEncodable; + use ln::msgs; + use secp256k1::key::{PublicKey,SecretKey}; + use secp256k1::Secp256k1; + + #[test] + fn encoding_channel_reestablish_no_secret() { + let cr = msgs::ChannelReestablish { + channel_id: [4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0], + next_local_commitment_number: 3, + next_remote_commitment_number: 4, + data_loss_protect: None, + }; + + let encoded_value = cr.encode(); + assert_eq!( + encoded_value, + vec![4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4] + ); + } + + #[test] + fn encoding_channel_reestablish_with_secret() { + let public_key = { + let secp_ctx = Secp256k1::new(); + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap()) + }; + + let cr = msgs::ChannelReestablish { + channel_id: [4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0], + next_local_commitment_number: 3, + next_remote_commitment_number: 4, + data_loss_protect: Some(msgs::DataLossProtect { your_last_per_commitment_secret: [9;32], my_current_per_commitment_point: public_key}), + }; + + let encoded_value = cr.encode(); + assert_eq!( + encoded_value, + vec![4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 27, 132, 197, 86, 123, 18, 100, 64, 153, 93, 62, 213, 170, 186, 5, 101, 215, 30, 24, 52, 96, 72, 25, 255, 156, 23, 245, 233, 213, 221, 7, 143] + ); + } +}