X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fmsgs.rs;h=6c910865388d965e69f7c92ba6f91d10d5e9d04a;hb=675cf4ac1d02b2b558a0e041d6cd4bebac0e5108;hp=de6750af57d191dd5ad0b1fd47c8f2cd3f373518;hpb=5d923e2a634351e285292466a8d84d2848c39980;p=rust-lightning diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index de6750af..6c910865 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -1,49 +1,55 @@ +//! Wire messages, traits representing wire message handlers, and a few error types live here. +//! +//! For a normal node you probably don't need to use anything here, however, if you wish to split a +//! node into an internet-facing route/message socket handling daemon and a separate daemon (or +//! server entirely) which handles only channel-related messages you may wish to implement +//! ChannelMessageHandler yourself and use it to re-serialize messages and pass them across +//! daemons/servers. +//! +//! Note that if you go with such an architecture (instead of passing raw socket events to a +//! non-internet-facing system) you trust the frontend internet-facing system to not lie about the +//! source node_id of the message, however this does allow you to significantly reduce bandwidth +//! between the systems as routing messages can represent a significant chunk of bandwidth usage +//! (especially for non-channel-publicly-announcing nodes). As an alternate design which avoids +//! this issue, if you have sufficient bidirectional bandwidth between your systems, you may send +//! raw socket events into your non-internet-facing system and then send routing events back to +//! track the network on the less-secure system. + use secp256k1::key::PublicKey; -use secp256k1::{Secp256k1, Signature}; +use secp256k1::Signature; use secp256k1; -use bitcoin::util::hash::Sha256dHash; -use bitcoin::network::serialize::{deserialize,serialize}; +use bitcoin_hashes::sha256d::Hash as Sha256dHash; use bitcoin::blockdata::script::Script; use std::error::Error; use std::{cmp, fmt}; +use std::io::Read; use std::result::Result; -use util::{byte_utils, internal_traits, events}; +use util::events; +use util::ser::{Readable, Writeable, Writer}; -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 - } -} +use ln::channelmanager::{PaymentPreimage, PaymentHash}; + +/// An error in decoding a message or struct. #[derive(Debug)] pub enum DecodeError { - /// Unknown realm byte in an OnionHopData packet - UnknownRealmByte, - /// Failed to decode a public key (ie it's invalid) - BadPublicKey, - /// Failed to decode a signature (ie it's invalid) - BadSignature, - /// Value expected to be text wasn't decodable as text - BadText, + /// A version byte specified something we don't know how to handle. + /// Includes unknown realm byte in an OnionHopData packet + UnknownVersion, + /// Unknown feature mandating we fail to parse message + UnknownRequiredFeature, + /// Value was invalid, eg a byte which was supposed to be a bool was something other than a 0 + /// or 1, a public key/private key/signature was invalid, text wasn't UTF-8, etc + InvalidValue, /// 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; + /// Error from std::io + Io(::std::io::Error), } /// Tracks localfeatures which are only in init messages @@ -53,23 +59,31 @@ pub struct LocalFeatures { } impl LocalFeatures { + /// Create a blank LocalFeatures flags (visibility extended for fuzz tests) + #[cfg(not(feature = "fuzztarget"))] + pub(crate) fn new() -> LocalFeatures { + LocalFeatures { + flags: vec![1 << 4], + } + } + #[cfg(feature = "fuzztarget")] pub fn new() -> LocalFeatures { LocalFeatures { - flags: Vec::new(), + flags: vec![1 << 4], } } - pub fn supports_data_loss_protect(&self) -> bool { + pub(crate) fn supports_data_loss_protect(&self) -> bool { self.flags.len() > 0 && (self.flags[0] & 3) != 0 } - pub fn requires_data_loss_protect(&self) -> bool { + pub(crate) fn requires_data_loss_protect(&self) -> bool { self.flags.len() > 0 && (self.flags[0] & 1) != 0 } - pub fn initial_routing_sync(&self) -> bool { + pub(crate) fn initial_routing_sync(&self) -> bool { self.flags.len() > 0 && (self.flags[0] & (1 << 3)) != 0 } - pub fn set_initial_routing_sync(&mut self) { + pub(crate) fn set_initial_routing_sync(&mut self) { if self.flags.len() == 0 { self.flags.resize(1, 1 << 3); } else { @@ -77,50 +91,44 @@ impl LocalFeatures { } } - pub fn supports_upfront_shutdown_script(&self) -> bool { + pub(crate) fn supports_upfront_shutdown_script(&self) -> bool { self.flags.len() > 0 && (self.flags[0] & (3 << 4)) != 0 } - pub fn requires_upfront_shutdown_script(&self) -> bool { - self.flags.len() > 0 && (self.flags[0] & (1 << 4)) != 0 + pub(crate) fn unset_upfront_shutdown_script(&mut self) { + self.flags[0] ^= 1 << 4; } - pub fn requires_unknown_bits(&self) -> bool { - for (idx, &byte) in self.flags.iter().enumerate() { - if idx != 0 && (byte & 0x55) != 0 { - return true; - } else if idx == 0 && (byte & 0x14) != 0 { - return true; - } - } - return false; + pub(crate) fn requires_unknown_bits(&self) -> bool { + self.flags.iter().enumerate().any(|(idx, &byte)| { + ( idx != 0 && (byte & 0x55) != 0 ) || ( idx == 0 && (byte & 0x14) != 0 ) + }) } - pub fn supports_unknown_bits(&self) -> bool { - for (idx, &byte) in self.flags.iter().enumerate() { - if idx != 0 && byte != 0 { - return true; - } else if idx == 0 && (byte & 0xc4) != 0 { - return true; - } - } - return false; + pub(crate) fn supports_unknown_bits(&self) -> bool { + self.flags.iter().enumerate().any(|(idx, &byte)| { + ( idx != 0 && byte != 0 ) || ( idx == 0 && (byte & 0xc4) != 0 ) + }) } } /// Tracks globalfeatures which are in init messages and routing announcements -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Debug)] pub struct GlobalFeatures { + #[cfg(not(test))] flags: Vec, + // Used to test encoding of diverse msgs + #[cfg(test)] + pub flags: Vec } impl GlobalFeatures { - pub fn new() -> GlobalFeatures { + pub(crate) fn new() -> GlobalFeatures { GlobalFeatures { flags: Vec::new(), } } - pub fn requires_unknown_bits(&self) -> bool { + pub(crate) fn requires_unknown_bits(&self) -> bool { for &byte in self.flags.iter() { if (byte & 0x55) != 0 { return true; @@ -129,7 +137,7 @@ impl GlobalFeatures { return false; } - pub fn supports_unknown_bits(&self) -> bool { + pub(crate) fn supports_unknown_bits(&self) -> bool { for &byte in self.flags.iter() { if byte != 0 { return true; @@ -139,177 +147,230 @@ impl GlobalFeatures { } } +/// An init message to be sent or received from a peer pub struct Init { - pub global_features: GlobalFeatures, - pub local_features: LocalFeatures, + pub(crate) global_features: GlobalFeatures, + pub(crate) local_features: LocalFeatures, } +/// An error message to be sent or received from a peer +#[derive(Clone)] pub struct ErrorMessage { - pub channel_id: [u8; 32], - pub data: String, + pub(crate) channel_id: [u8; 32], + pub(crate) data: String, } +/// A ping message to be sent or received from a peer pub struct Ping { - pub ponglen: u16, - pub byteslen: u16, + pub(crate) ponglen: u16, + pub(crate) byteslen: u16, } +/// A pong message to be sent or received from a peer pub struct Pong { - pub byteslen: u16, + pub(crate) byteslen: u16, } +/// An open_channel message to be sent or received from a peer +#[derive(Clone)] pub struct OpenChannel { - pub chain_hash: Sha256dHash, - pub temporary_channel_id: [u8; 32], - pub funding_satoshis: u64, - pub push_msat: u64, - pub dust_limit_satoshis: u64, - pub max_htlc_value_in_flight_msat: u64, - pub channel_reserve_satoshis: u64, - pub htlc_minimum_msat: u64, - pub feerate_per_kw: u32, - pub to_self_delay: u16, - pub max_accepted_htlcs: u16, - pub funding_pubkey: PublicKey, - pub revocation_basepoint: PublicKey, - pub payment_basepoint: PublicKey, - pub delayed_payment_basepoint: PublicKey, - pub htlc_basepoint: PublicKey, - pub first_per_commitment_point: PublicKey, - pub channel_flags: u8, - pub shutdown_scriptpubkey: Option