X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fmsgs.rs;h=5d4767721dbb08a550b919c94cb6196c20390e41;hb=11e5975523147ae7024b03f05445c78c9b695752;hp=3ff80b1f91cf4c2a105b0426f3c4b0682f332957;hpb=4f4c0a81794dc570a3b275561e8e528e542c1fd5;p=rust-lightning diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index 3ff80b1f..5d476772 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -1,8 +1,7 @@ use secp256k1::key::PublicKey; use secp256k1::{Secp256k1, Signature}; -use bitcoin::util::uint::Uint256; use bitcoin::util::hash::Sha256dHash; -use bitcoin::network::serialize::deserialize; +use bitcoin::network::serialize::{deserialize,serialize}; use bitcoin::blockdata::script::Script; use std::error::Error; @@ -13,6 +12,16 @@ use util::{byte_utils, internal_traits, events}; pub trait MsgEncodable { fn encode(&self) -> Vec; + #[inline] + fn encoded_len(&self) -> usize { self.encode().len() } + #[inline] + fn encode_with_len(&self) -> Vec { + let enc = self.encode(); + let mut res = Vec::with_capacity(enc.len() + 2); + res.extend_from_slice(&byte_utils::be16_to_array(enc.len() as u16)); + res.extend_from_slice(&enc); + res + } } #[derive(Debug)] pub enum DecodeError { @@ -22,8 +31,15 @@ pub enum DecodeError { 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, } pub trait MsgDecodable: Sized { fn decode(v: &[u8]) -> Result; @@ -49,9 +65,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 @@ -120,9 +143,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, @@ -143,7 +180,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, @@ -161,36 +198,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], @@ -200,19 +237,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, @@ -220,24 +259,24 @@ 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 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]>, @@ -246,7 +285,7 @@ pub struct ChannelReestablish { #[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, @@ -254,7 +293,6 @@ pub struct AnnouncementSignatures { #[derive(Clone)] pub enum NetAddress { - Dummy, IPv4 { addr: [u8; 4], port: u16, @@ -271,9 +309,19 @@ pub enum NetAddress { ed25519_pubkey: [u8; 32], checksum: u16, version: u8, - //TODO: Do we need a port number here??? + port: u16, }, } +impl NetAddress { + fn get_id(&self) -> u8 { + match self { + &NetAddress::IPv4 {..} => { 1 }, + &NetAddress::IPv6 {..} => { 2 }, + &NetAddress::OnionV2 {..} => { 3 }, + &NetAddress::OnionV3 {..} => { 4 }, + } + } +} pub struct UnsignedNodeAnnouncement { pub features: GlobalFeatures, @@ -281,6 +329,8 @@ pub struct UnsignedNodeAnnouncement { pub node_id: PublicKey, pub rgb: [u8; 3], pub alias: [u8; 32], + /// 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 struct NodeAnnouncement { @@ -325,19 +375,51 @@ pub struct ChannelUpdate { } /// Used to put an error message in a HandleError -pub enum ErrorMessage { +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 }, - DisconnectPeer {}, + /// The peer took some action which made us think they were useless. Disconnect them. + 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: Move into an Action enum and require it! + pub action: Option, //TODO: Make this required +} + +/// Struct used to return values from revoke_and_ack messages, containing a bunch of commitment +/// transaction updates if they were pending. +pub struct CommitmentUpdate { + pub update_add_htlcs: Vec, + pub update_fulfill_htlcs: Vec, + pub update_fail_htlcs: Vec, + pub commitment_signed: CommitmentSigned, +} + +pub enum HTLCFailChannelUpdate { + ChannelUpdateMessage { + msg: ChannelUpdate, + }, + ChannelClosed { + short_channel_id: u64, + }, } -pub trait ChannelMessageHandler : events::EventsProvider { +/// 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 + 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>; @@ -346,29 +428,37 @@ pub trait ChannelMessageHandler : events::EventsProvider { fn handle_funding_locked(&self, their_node_id: &PublicKey, msg: &FundingLocked) -> Result, HandleError>; // Channl close: - fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &Shutdown) -> Result<(), HandleError>; - fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &ClosingSigned) -> Result<(), HandleError>; + fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &Shutdown) -> Result<(Option, Option), HandleError>; + fn handle_closing_signed(&self, their_node_id: &PublicKey, msg: &ClosingSigned) -> Result, HandleError>; // HTLC handling: fn handle_update_add_htlc(&self, their_node_id: &PublicKey, msg: &UpdateAddHTLC) -> Result<(), HandleError>; - fn handle_update_fulfill_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFulfillHTLC) -> Result, CommitmentSigned)>, HandleError>; - fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailHTLC) -> Result, CommitmentSigned)>, HandleError>; - fn handle_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailMalformedHTLC) -> Result, CommitmentSigned)>, HandleError>; - fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &CommitmentSigned) -> Result; - fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &RevokeAndACK) -> Result<(), HandleError>; + fn handle_update_fulfill_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFulfillHTLC) -> Result<(), HandleError>; + fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailHTLC) -> Result, HandleError>; + fn handle_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailMalformedHTLC) -> Result<(), HandleError>; + fn handle_commitment_signed(&self, their_node_id: &PublicKey, msg: &CommitmentSigned) -> Result<(RevokeAndACK, Option), HandleError>; + fn handle_revoke_and_ack(&self, their_node_id: &PublicKey, msg: &RevokeAndACK) -> Result, HandleError>; fn handle_update_fee(&self, their_node_id: &PublicKey, msg: &UpdateFee) -> Result<(), HandleError>; // Channel-to-announce: fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &AnnouncementSignatures) -> Result<(), HandleError>; + + // Informational: + /// 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); } -pub trait RoutingMessageHandler { +pub trait RoutingMessageHandler : Send + Sync { fn handle_node_announcement(&self, msg: &NodeAnnouncement) -> Result<(), HandleError>; /// 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_htlc_fail_channel_update(&self, update: &HTLCFailChannelUpdate); } pub struct OnionRealm0HopData { @@ -399,6 +489,7 @@ pub struct DecodedOnionErrorPacket { pub pad: Vec, } +#[derive(Clone)] pub struct OnionErrorPacket { // This really should be a constant size slice, but the spec lets these things be up to 128KB? // (TODO) We limit it in decode to much lower... @@ -411,7 +502,10 @@ impl Error for DecodeError { DecodeError::UnknownRealmByte => "Unknown realm byte in Onion packet", 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", } } } @@ -447,11 +541,11 @@ 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..]); + flags.extend_from_slice(&v[2..2 + len]); Ok(Self { flags: flags }) @@ -464,15 +558,16 @@ impl MsgEncodable for LocalFeatures { res.extend_from_slice(&self.flags[..]); res } + fn encoded_len(&self) -> usize { self.flags.len() + 2 } } 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..]); + flags.extend_from_slice(&v[2..2 + len]); Ok(Self { flags: flags }) @@ -485,18 +580,16 @@ impl MsgEncodable for GlobalFeatures { res.extend_from_slice(&self.flags[..]); res } + fn encoded_len(&self) -> usize { self.flags.len() + 2 } } impl MsgDecodable for Init { fn decode(v: &[u8]) -> Result { let global_features = GlobalFeatures::decode(v)?; - if global_features.flags.len() + 4 <= v.len() { - return Err(DecodeError::WrongLength); + if v.len() < global_features.flags.len() + 4 { + return Err(DecodeError::ShortRead); } let local_features = LocalFeatures::decode(&v[global_features.flags.len() + 2..])?; - if global_features.flags.len() + local_features.flags.len() + 4 != v.len() { - return Err(DecodeError::WrongLength); - } Ok(Self { global_features: global_features, local_features: local_features, @@ -512,22 +605,68 @@ 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(); let mut shutdown_scriptpubkey = None; 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); + if v.len() < 321+len { + 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 { - return Err(DecodeError::WrongLength); } Ok(OpenChannel { @@ -555,30 +694,56 @@ impl MsgDecodable for OpenChannel { } impl MsgEncodable for OpenChannel { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = match &self.shutdown_scriptpubkey { + &Some(ref script) => Vec::with_capacity(319 + 2 + script.len()), + &None => Vec::with_capacity(319), + }; + res.extend_from_slice(&serialize(&self.chain_hash).unwrap()); + res.extend_from_slice(&serialize(&self.temporary_channel_id).unwrap()); + res.extend_from_slice(&byte_utils::be64_to_array(self.funding_satoshis)); + res.extend_from_slice(&byte_utils::be64_to_array(self.push_msat)); + 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)); + res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_minimum_msat)); + res.extend_from_slice(&byte_utils::be32_to_array(self.feerate_per_kw)); + res.extend_from_slice(&byte_utils::be16_to_array(self.to_self_delay)); + res.extend_from_slice(&byte_utils::be16_to_array(self.max_accepted_htlcs)); + res.extend_from_slice(&self.funding_pubkey.serialize()); + res.extend_from_slice(&self.revocation_basepoint.serialize()); + res.extend_from_slice(&self.payment_basepoint.serialize()); + res.extend_from_slice(&self.delayed_payment_basepoint.serialize()); + res.extend_from_slice(&self.htlc_basepoint.serialize()); + res.extend_from_slice(&self.first_per_commitment_point.serialize()); + res.push(self.channel_flags); + if let &Some(ref script) = &self.shutdown_scriptpubkey { + res.extend_from_slice(&byte_utils::be16_to_array(script.len() as u16)); + res.extend_from_slice(&script[..]); + } + res } } 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(); let mut shutdown_scriptpubkey = None; 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); + if v.len() < 272+len { + 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 { - 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]), @@ -598,18 +763,42 @@ impl MsgDecodable for AcceptChannel { } impl MsgEncodable for AcceptChannel { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = match &self.shutdown_scriptpubkey { + &Some(ref script) => Vec::with_capacity(270 + 2 + script.len()), + &None => Vec::with_capacity(270), + }; + 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)); + res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_minimum_msat)); + res.extend_from_slice(&byte_utils::be32_to_array(self.minimum_depth)); + res.extend_from_slice(&byte_utils::be16_to_array(self.to_self_delay)); + res.extend_from_slice(&byte_utils::be16_to_array(self.max_accepted_htlcs)); + res.extend_from_slice(&self.funding_pubkey.serialize()); + res.extend_from_slice(&self.revocation_basepoint.serialize()); + res.extend_from_slice(&self.payment_basepoint.serialize()); + res.extend_from_slice(&self.delayed_payment_basepoint.serialize()); + res.extend_from_slice(&self.htlc_basepoint.serialize()); + res.extend_from_slice(&self.first_per_commitment_point.serialize()); + if let &Some(ref script) = &self.shutdown_scriptpubkey { + res.extend_from_slice(&byte_utils::be16_to_array(script.len() as u16)); + res.extend_from_slice(&script[..]); + } + res } } impl MsgDecodable for FundingCreated { fn decode(v: &[u8]) -> Result { - if v.len() != 32+32+2+64 { - return Err(DecodeError::WrongLength); + if v.len() < 32+32+2+64 { + 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]), @@ -618,170 +807,490 @@ impl MsgDecodable for FundingCreated { } impl MsgEncodable for FundingCreated { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+32+2+64); + 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(); + res.extend_from_slice(&self.signature.serialize_compact(&secp_ctx)); + res } } impl MsgDecodable for FundingSigned { fn decode(v: &[u8]) -> Result { - if v.len() != 32+64 { - return Err(DecodeError::WrongLength); + if v.len() < 32+64 { + 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]), }) } } impl MsgEncodable for FundingSigned { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+64); + res.extend_from_slice(&self.channel_id); + res.extend_from_slice(&self.signature.serialize_compact(&Secp256k1::without_caps())); + res } } impl MsgDecodable for FundingLocked { fn decode(v: &[u8]) -> Result { - if v.len() != 32+33 { - return Err(DecodeError::WrongLength); + if v.len() < 32+33 { + 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]), }) } } impl MsgEncodable for FundingLocked { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+33); + res.extend_from_slice(&self.channel_id); + res.extend_from_slice(&self.next_per_commitment_point.serialize()); + res } } impl MsgDecodable for Shutdown { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32 + 2 { + 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::ShortRead); + } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); + Ok(Self { + channel_id, + scriptpubkey: Script::from(v[34..34 + scriptlen].to_vec()), + }) } } impl MsgEncodable for Shutdown { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32 + 2 + self.scriptpubkey.len()); + 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 } } impl MsgDecodable for ClosingSigned { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32 + 8 + 64 { + 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, + fee_satoshis: byte_utils::slice_to_be64(&v[32..40]), + signature: secp_signature!(&secp_ctx, &v[40..104]), + }) } } impl MsgEncodable for ClosingSigned { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+8+64); + 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)); + res } } impl MsgDecodable for UpdateAddHTLC { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+8+8+32+4+1+33+20*65+32 { + 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, + htlc_id: byte_utils::slice_to_be64(&v[32..40]), + amount_msat: byte_utils::slice_to_be64(&v[40..48]), + payment_hash, + cltv_expiry: byte_utils::slice_to_be32(&v[80..84]), + onion_routing_packet: OnionPacket::decode(&v[84..84+1366])?, + }) } } impl MsgEncodable for UpdateAddHTLC { fn encode(&self) -> Vec { - unimplemented!(); + 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); + res.extend_from_slice(&byte_utils::be32_to_array(self.cltv_expiry)); + res.extend_from_slice(&self.onion_routing_packet.encode()[..]); + res } } impl MsgDecodable for UpdateFulfillHTLC { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+8+32 { + 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, + htlc_id: byte_utils::slice_to_be64(&v[32..40]), + payment_preimage, + }) } } impl MsgEncodable for UpdateFulfillHTLC { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+8+32); + 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 } } impl MsgDecodable for UpdateFailHTLC { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+8 { + return Err(DecodeError::ShortRead); + } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); + Ok(Self{ + channel_id, + htlc_id: byte_utils::slice_to_be64(&v[32..40]), + reason: OnionErrorPacket::decode(&v[40..])?, + }) } } impl MsgEncodable for UpdateFailHTLC { fn encode(&self) -> Vec { - unimplemented!(); + let reason = self.reason.encode(); + let mut res = Vec::with_capacity(32+8+reason.len()); + 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 } } impl MsgDecodable for UpdateFailMalformedHTLC { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+8+32+2 { + 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, + htlc_id: byte_utils::slice_to_be64(&v[32..40]), + sha256_of_onion, + failure_code: byte_utils::slice_to_be16(&v[72..74]), + }) } } impl MsgEncodable for UpdateFailMalformedHTLC { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+8+32+2); + 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)); + res } } impl MsgDecodable for CommitmentSigned { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+64+2 { + 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::ShortRead); + } + let mut htlc_signatures = Vec::with_capacity(htlcs); + let secp_ctx = Secp256k1::without_caps(); + for i in 0..htlcs { + htlc_signatures.push(secp_signature!(&secp_ctx, &v[98+i*64..98+(i+1)*64])); + } + Ok(Self { + channel_id, + signature: secp_signature!(&secp_ctx, &v[32..96]), + htlc_signatures, + }) } } impl MsgEncodable for CommitmentSigned { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+64+2+self.htlc_signatures.len()*64); + 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)); + for i in 0..self.htlc_signatures.len() { + res.extend_from_slice(&self.htlc_signatures[i].serialize_compact(&secp_ctx)); + } + res } } impl MsgDecodable for RevokeAndACK { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+32+33 { + 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, + per_commitment_secret, + next_per_commitment_point: secp_pubkey!(&secp_ctx, &v[64..97]), + }) } } impl MsgEncodable for RevokeAndACK { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+32+33); + 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 } } impl MsgDecodable for UpdateFee { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+4 { + return Err(DecodeError::ShortRead); + } + let mut channel_id = [0; 32]; + channel_id[..].copy_from_slice(&v[0..32]); + Ok(Self { + channel_id, + feerate_per_kw: byte_utils::slice_to_be32(&v[32..36]), + }) } } impl MsgEncodable for UpdateFee { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+4); + 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+33 { + return Err(DecodeError::ShortRead); + } + + let your_last_per_commitment_secret = if v.len() > 32+2*8+33 { + 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(inner_array) + } else { None }; + + let option_size = match &your_last_per_commitment_secret { + &Some(ref _ary) => 32, + &None => 0, + }; + 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]), + your_last_per_commitment_secret: your_last_per_commitment_secret, + my_current_per_commitment_point: { + let ctx = Secp256k1::without_caps(); + secp_pubkey!(&ctx, &v[48+option_size..48+option_size+33]) + } + }) } } impl MsgEncodable for ChannelReestablish { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(if self.your_last_per_commitment_secret.is_some() { 32+2*3+33 + 32 } else { 32+2*8+33 }); + + 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 ary) = &self.your_last_per_commitment_secret { + res.extend_from_slice(&ary[..]); + } + + res.extend_from_slice(&self.my_current_per_commitment_point.serialize()); + res } } impl MsgDecodable for AnnouncementSignatures { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+8+64*2 { + 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, + 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]), + }) } } impl MsgEncodable for AnnouncementSignatures { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(32+8+64*2); + 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)); + res.extend_from_slice(&self.bitcoin_signature.serialize_compact(&secp_ctx)); + res } } impl MsgDecodable for UnsignedNodeAnnouncement { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + let features = GlobalFeatures::decode(&v[..])?; + if v.len() < features.encoded_len() + 4 + 33 + 3 + 32 + 2 { + return Err(DecodeError::ShortRead); + } + let start = features.encoded_len(); + + let mut rgb = [0; 3]; + rgb.copy_from_slice(&v[start + 37..start + 40]); + + let mut alias = [0; 32]; + alias.copy_from_slice(&v[start + 40..start + 72]); + + let addrlen = byte_utils::slice_to_be16(&v[start + 72..start + 74]) as usize; + if v.len() < start + 74 + addrlen { + 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 addr_read_limit <= read_pos { break; } + match v[read_pos] { + 0 => { read_pos += 1; }, + 1 => { + 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 { + addr, + port: byte_utils::slice_to_be16(&v[read_pos + 5..read_pos + 7]), + }); + read_pos += 1 + 6; + }, + 2 => { + 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 { + addr, + port: byte_utils::slice_to_be16(&v[read_pos + 17..read_pos + 19]), + }); + read_pos += 1 + 18; + }, + 3 => { + 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 { + addr, + port: byte_utils::slice_to_be16(&v[read_pos + 11..read_pos + 13]), + }); + read_pos += 1 + 12; + }, + 4 => { + 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 { + ed25519_pubkey, + checksum: byte_utils::slice_to_be16(&v[read_pos + 33..read_pos + 35]), + version: v[read_pos + 35], + port: byte_utils::slice_to_be16(&v[read_pos + 36..read_pos + 38]), + }); + read_pos += 1 + 37; + }, + _ => { break; } // We've read all we can, we dont understand anything higher (and they're sorted) + } + } + + let secp_ctx = Secp256k1::without_caps(); + Ok(Self { + features, + timestamp: byte_utils::slice_to_be32(&v[start..start + 4]), + node_id: secp_pubkey!(&secp_ctx, &v[start + 4..start + 37]), + rgb, + alias, + addresses, + }) } } impl MsgEncodable for UnsignedNodeAnnouncement { @@ -794,25 +1303,32 @@ impl MsgEncodable for UnsignedNodeAnnouncement { res.extend_from_slice(&self.rgb); res.extend_from_slice(&self.alias); let mut addr_slice = Vec::with_capacity(self.addresses.len() * 18); - for addr in self.addresses.iter() { + 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::Dummy => {}, &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} => { + &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)); }, } } @@ -823,19 +1339,45 @@ impl MsgEncodable for UnsignedNodeAnnouncement { } impl MsgDecodable for NodeAnnouncement { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 64 { + return Err(DecodeError::ShortRead); + } + let secp_ctx = Secp256k1::without_caps(); + Ok(Self { + signature: secp_signature!(&secp_ctx, &v[0..64]), + contents: UnsignedNodeAnnouncement::decode(&v[64..])?, + }) } } impl MsgEncodable for NodeAnnouncement { fn encode(&self) -> Vec { - unimplemented!(); + let contents = self.contents.encode(); + let mut res = Vec::with_capacity(64 + contents.len()); + let secp_ctx = Secp256k1::without_caps(); + res.extend_from_slice(&self.signature.serialize_compact(&secp_ctx)); + res.extend_from_slice(&contents); + res } } impl MsgDecodable for UnsignedChannelAnnouncement { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + let features = GlobalFeatures::decode(&v[..])?; + if v.len() < features.encoded_len() + 32 + 8 + 33*4 { + return Err(DecodeError::ShortRead); + } + let start = features.encoded_len(); + let secp_ctx = Secp256k1::without_caps(); + Ok(Self { + features, + chain_hash: deserialize(&v[start..start + 32]).unwrap(), + short_channel_id: byte_utils::slice_to_be64(&v[start + 32..start + 40]), + node_id_1: secp_pubkey!(&secp_ctx, &v[start + 40..start + 73]), + 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]), + }) } } impl MsgEncodable for UnsignedChannelAnnouncement { @@ -854,19 +1396,49 @@ impl MsgEncodable for UnsignedChannelAnnouncement { } impl MsgDecodable for ChannelAnnouncement { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 64*4 { + return Err(DecodeError::ShortRead); + } + let secp_ctx = Secp256k1::without_caps(); + Ok(Self { + node_signature_1: secp_signature!(&secp_ctx, &v[0..64]), + node_signature_2: secp_signature!(&secp_ctx, &v[64..128]), + bitcoin_signature_1: secp_signature!(&secp_ctx, &v[128..192]), + bitcoin_signature_2: secp_signature!(&secp_ctx, &v[192..256]), + contents: UnsignedChannelAnnouncement::decode(&v[256..])?, + }) } } impl MsgEncodable for ChannelAnnouncement { fn encode(&self) -> Vec { - unimplemented!(); + let secp_ctx = Secp256k1::without_caps(); + let contents = self.contents.encode(); + let mut res = Vec::with_capacity(64 + contents.len()); + res.extend_from_slice(&self.node_signature_1.serialize_compact(&secp_ctx)); + res.extend_from_slice(&self.node_signature_2.serialize_compact(&secp_ctx)); + res.extend_from_slice(&self.bitcoin_signature_1.serialize_compact(&secp_ctx)); + res.extend_from_slice(&self.bitcoin_signature_2.serialize_compact(&secp_ctx)); + res.extend_from_slice(&contents); + res } } impl MsgDecodable for UnsignedChannelUpdate { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32+8+4+2+2+8+4+4 { + return Err(DecodeError::ShortRead); + } + Ok(Self { + chain_hash: deserialize(&v[0..32]).unwrap(), + short_channel_id: byte_utils::slice_to_be64(&v[32..40]), + timestamp: byte_utils::slice_to_be32(&v[40..44]), + flags: byte_utils::slice_to_be16(&v[44..46]), + cltv_expiry_delta: byte_utils::slice_to_be16(&v[46..48]), + 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]), + }) } } impl MsgEncodable for UnsignedChannelUpdate { @@ -885,15 +1457,21 @@ impl MsgEncodable for UnsignedChannelUpdate { } impl MsgDecodable for ChannelUpdate { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 128 { + return Err(DecodeError::ShortRead); + } + let secp_ctx = Secp256k1::without_caps(); + Ok(Self { + signature: secp_signature!(&secp_ctx, &v[0..64]), + contents: UnsignedChannelUpdate::decode(&v[64..])?, + }) } } impl MsgEncodable for ChannelUpdate { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(128); - //TODO: Should avoid creating a new secp ctx just for a serialize call :( - res.extend_from_slice(&self.signature.serialize_der(&Secp256k1::new())[..]); //TODO: Need in non-der form! (probably elsewhere too) + res.extend_from_slice(&self.signature.serialize_compact(&Secp256k1::without_caps())[..]); res.extend_from_slice(&self.contents.encode()[..]); res } @@ -901,8 +1479,8 @@ impl MsgEncodable for ChannelUpdate { impl MsgDecodable for OnionRealm0HopData { fn decode(v: &[u8]) -> Result { - if v.len() != 32 { - return Err(DecodeError::WrongLength); + if v.len() < 32 { + return Err(DecodeError::ShortRead); } Ok(OnionRealm0HopData { short_channel_id: byte_utils::slice_to_be64(&v[0..8]), @@ -924,8 +1502,8 @@ impl MsgEncodable for OnionRealm0HopData { impl MsgDecodable for OnionHopData { fn decode(v: &[u8]) -> Result { - if v.len() != 65 { - return Err(DecodeError::WrongLength); + if v.len() < 65 { + return Err(DecodeError::ShortRead); } let realm = v[0]; if realm != 0 { @@ -951,8 +1529,21 @@ impl MsgEncodable for OnionHopData { } impl MsgDecodable for OnionPacket { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 1+33+20*65+32 { + return Err(DecodeError::ShortRead); + } + let mut hop_data = [0; 20*65]; + hop_data.copy_from_slice(&v[34..1334]); + let mut hmac = [0; 32]; + hmac.copy_from_slice(&v[1334..1366]); + let secp_ctx = Secp256k1::without_caps(); + Ok(Self { + version: v[0], + public_key: secp_pubkey!(&secp_ctx, &v[1..34]), + hop_data, + hmac, + }) } } impl MsgEncodable for OnionPacket { @@ -967,8 +1558,26 @@ impl MsgEncodable for OnionPacket { } impl MsgDecodable for DecodedOnionErrorPacket { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 32 + 4 { + 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::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::ShortRead); + } + + let mut hmac = [0; 32]; + hmac.copy_from_slice(&v[0..32]); + Ok(Self { + hmac, + failuremsg: v[34..34 + failuremsg_len].to_vec(), + pad: v[36 + failuremsg_len..36 + failuremsg_len + padding_len].to_vec(), + }) } } impl MsgEncodable for DecodedOnionErrorPacket { @@ -984,13 +1593,108 @@ impl MsgEncodable for DecodedOnionErrorPacket { } impl MsgDecodable for OnionErrorPacket { - fn decode(_v: &[u8]) -> Result { - unimplemented!(); + fn decode(v: &[u8]) -> Result { + if v.len() < 2 { + return Err(DecodeError::ShortRead); + } + let len = byte_utils::slice_to_be16(&v[0..2]) as usize; + if v.len() < 2 + len { + return Err(DecodeError::ShortRead); + } + Ok(Self { + data: v[2..len+2].to_vec(), + }) } } impl MsgEncodable for OnionErrorPacket { fn encode(&self) -> Vec { - unimplemented!(); + let mut res = Vec::with_capacity(2 + self.data.len()); + res.extend_from_slice(&byte_utils::be16_to_array(self.data.len() as u16)); + res.extend_from_slice(&self.data); + 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); + } + let len = byte_utils::slice_to_be16(&v[32..34]); + if v.len() < 34 + len as usize { + return Err(DecodeError::ShortRead); + } + let data = match String::from_utf8(v[34..34 + len as usize].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, + }) } } +#[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 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, + your_last_per_commitment_secret: None, + 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, 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] + ); + } + + #[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, + your_last_per_commitment_secret: Some([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] + ); + } +}