Send AcceptChannel responses out-of-band to ensure ordered delivery
[rust-lightning] / src / ln / msgs.rs
index 5dd3165bfc0977728f8c80b03ba9cfeff3ecdb9f..89c95b3b917e895d81194a283c1f88f1aa9a1235 100644 (file)
@@ -1,9 +1,11 @@
 //! 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 mssage, however this does allow you to significantly reduce bandwidth
@@ -30,16 +32,14 @@ use util::ser::{Readable, Writeable, Writer};
 /// An error in decoding a message or struct.
 #[derive(Debug)]
 pub enum DecodeError {
-       /// Unknown realm byte in an OnionHopData packet
-       UnknownRealmByte,
+       /// 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,
-       /// 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,
+       /// 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!
@@ -49,8 +49,6 @@ pub enum DecodeError {
        BadLengthDescriptor,
        /// Error from std::io
        Io(::std::io::Error),
-       /// 1 or 0 is not found for boolean value
-       InvalidValue,
 }
 
 /// Tracks localfeatures which are only in init messages
@@ -170,6 +168,7 @@ pub struct Pong {
 }
 
 /// An open_channel message to be sent or received from a peer
+#[derive(Clone)]
 pub struct OpenChannel {
        pub(crate) chain_hash: Sha256dHash,
        pub(crate) temporary_channel_id: [u8; 32],
@@ -193,6 +192,7 @@ pub struct OpenChannel {
 }
 
 /// An accept_channel message to be sent or received from a peer
+#[derive(Clone)]
 pub struct AcceptChannel {
        pub(crate) temporary_channel_id: [u8; 32],
        pub(crate) dust_limit_satoshis: u64,
@@ -226,6 +226,7 @@ pub struct FundingSigned {
 }
 
 /// A funding_locked message to be sent or received from a peer
+#[derive(Clone, PartialEq)]
 pub struct FundingLocked {
        pub(crate) channel_id: [u8; 32],
        pub(crate) next_per_commitment_point: PublicKey,
@@ -245,7 +246,7 @@ pub struct ClosingSigned {
 }
 
 /// An update_add_htlc message to be sent or received from a peer
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct UpdateAddHTLC {
        pub(crate) channel_id: [u8; 32],
        pub(crate) htlc_id: u64,
@@ -256,7 +257,7 @@ pub struct UpdateAddHTLC {
 }
 
 /// An update_fulfill_htlc message to be sent or received from a peer
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct UpdateFulfillHTLC {
        pub(crate) channel_id: [u8; 32],
        pub(crate) htlc_id: u64,
@@ -264,7 +265,7 @@ pub struct UpdateFulfillHTLC {
 }
 
 /// An update_fail_htlc message to be sent or received from a peer
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct UpdateFailHTLC {
        pub(crate) channel_id: [u8; 32],
        pub(crate) htlc_id: u64,
@@ -272,7 +273,7 @@ pub struct UpdateFailHTLC {
 }
 
 /// An update_fail_malformed_htlc message to be sent or received from a peer
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct UpdateFailMalformedHTLC {
        pub(crate) channel_id: [u8; 32],
        pub(crate) htlc_id: u64,
@@ -281,7 +282,7 @@ pub struct UpdateFailMalformedHTLC {
 }
 
 /// A commitment_signed message to be sent or received from a peer
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct CommitmentSigned {
        pub(crate) channel_id: [u8; 32],
        pub(crate) signature: Signature,
@@ -289,6 +290,7 @@ pub struct CommitmentSigned {
 }
 
 /// A revoke_and_ack message to be sent or received from a peer
+#[derive(Clone, PartialEq)]
 pub struct RevokeAndACK {
        pub(crate) channel_id: [u8; 32],
        pub(crate) per_commitment_secret: [u8; 32],
@@ -296,17 +298,20 @@ pub struct RevokeAndACK {
 }
 
 /// An update_fee message to be sent or received from a peer
+#[derive(PartialEq)]
 pub struct UpdateFee {
        pub(crate) channel_id: [u8; 32],
        pub(crate) feerate_per_kw: u32,
 }
 
+#[derive(PartialEq)]
 pub(crate) struct DataLossProtect {
        pub(crate) your_last_per_commitment_secret: [u8; 32],
        pub(crate) my_current_per_commitment_point: PublicKey,
 }
 
 /// A channel_reestablish message to be sent or received from a peer
+#[derive(PartialEq)]
 pub struct ChannelReestablish {
        pub(crate) channel_id: [u8; 32],
        pub(crate) next_local_commitment_number: u64,
@@ -464,11 +469,13 @@ pub struct HandleError { //TODO: rename me
 
 /// Struct used to return values from revoke_and_ack messages, containing a bunch of commitment
 /// transaction updates if they were pending.
+#[derive(PartialEq)]
 pub struct CommitmentUpdate {
        pub(crate) update_add_htlcs: Vec<UpdateAddHTLC>,
        pub(crate) update_fulfill_htlcs: Vec<UpdateFulfillHTLC>,
        pub(crate) update_fail_htlcs: Vec<UpdateFailHTLC>,
        pub(crate) update_fail_malformed_htlcs: Vec<UpdateFailMalformedHTLC>,
+       pub(crate) update_fee: Option<UpdateFee>,
        pub(crate) commitment_signed: CommitmentSigned,
 }
 
@@ -485,16 +492,41 @@ pub enum HTLCFailChannelUpdate {
        ChannelClosed {
                /// The short_channel_id which has now closed.
                short_channel_id: u64,
+               /// when this true, this channel should be permanently removed from the
+               /// consideration. Otherwise, this channel can be restored as new channel_update is received
+               is_permanent: bool,
        },
+       /// We received an error which indicated only that a node has failed
+       NodeFailure {
+               /// The node_id that has failed.
+               node_id: PublicKey,
+               /// when this true, node should be permanently removed from the
+               /// consideration. Otherwise, the channels connected to this node can be
+               /// restored as new channel_update is received
+               is_permanent: bool,
+       }
 }
 
-/// A trait to describe an object which can receive channel messages. Messages MAY be called in
-/// parallel when they originate from different their_node_ids, however they MUST NOT be called in
-/// parallel when the two calls have the same their_node_id.
-pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync {
+/// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should
+/// be sent in the order they appear in the return value, however sometimes the order needs to be
+/// variable at runtime (eg handle_channel_reestablish needs to re-send messages in the order they
+/// were originally sent). In those cases, this enum is also returned.
+#[derive(Clone, PartialEq)]
+pub enum RAACommitmentOrder {
+       /// Send the CommitmentUpdate messages first
+       CommitmentFirst,
+       /// Send the RevokeAndACK message first
+       RevokeAndACKFirst,
+}
+
+/// A trait to describe an object which can receive channel messages.
+///
+/// Messages MAY be called in parallel when they originate from different their_node_ids, however
+/// they MUST NOT be called in parallel when the two calls have the same their_node_id.
+pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Sync {
        //Channel init:
        /// Handle an incoming open_channel message from the given peer.
-       fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &OpenChannel) -> Result<AcceptChannel, HandleError>;
+       fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &OpenChannel) -> Result<(), HandleError>;
        /// Handle an incoming accept_channel message from the given peer.
        fn handle_accept_channel(&self, their_node_id: &PublicKey, msg: &AcceptChannel) -> Result<(), HandleError>;
        /// Handle an incoming funding_created message from the given peer.
@@ -516,7 +548,7 @@ pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync {
        /// Handle an incoming update_fulfill_htlc message from the given peer.
        fn handle_update_fulfill_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFulfillHTLC) -> Result<(), HandleError>;
        /// Handle an incoming update_fail_htlc message from the given peer.
-       fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailHTLC) -> Result<Option<HTLCFailChannelUpdate>, HandleError>;
+       fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailHTLC) -> Result<(), HandleError>;
        /// Handle an incoming update_fail_malformed_htlc message from the given peer.
        fn handle_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailMalformedHTLC) -> Result<(), HandleError>;
        /// Handle an incoming commitment_signed message from the given peer.
@@ -541,7 +573,7 @@ pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync {
        /// Handle a peer reconnecting, possibly generating channel_reestablish message(s).
        fn peer_connected(&self, their_node_id: &PublicKey) -> Vec<ChannelReestablish>;
        /// Handle an incoming channel_reestablish message from the given peer.
-       fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &ChannelReestablish) -> Result<(Option<FundingLocked>, Option<RevokeAndACK>, Option<CommitmentUpdate>), HandleError>;
+       fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &ChannelReestablish) -> Result<(Option<FundingLocked>, Option<RevokeAndACK>, Option<CommitmentUpdate>, RAACommitmentOrder), HandleError>;
 
        // Error:
        /// Handle an incoming error message from the given peer.
@@ -604,7 +636,18 @@ pub(crate) struct OnionPacket {
        pub(crate) hmac: [u8; 32],
 }
 
-#[derive(Clone)]
+impl PartialEq for OnionPacket {
+       fn eq(&self, other: &OnionPacket) -> bool {
+               for (i, j) in self.hop_data.iter().zip(other.hop_data.iter()) {
+                       if i != j { return false; }
+               }
+               self.version == other.version &&
+                       self.public_key == other.public_key &&
+                       self.hmac == other.hmac
+       }
+}
+
+#[derive(Clone, PartialEq)]
 pub(crate) 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...
@@ -614,16 +657,13 @@ pub(crate) struct OnionErrorPacket {
 impl Error for DecodeError {
        fn description(&self) -> &str {
                match *self {
-                       DecodeError::UnknownRealmByte => "Unknown realm byte in Onion packet",
+                       DecodeError::UnknownVersion => "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::BadText => "Invalid text in packet",
+                       DecodeError::InvalidValue => "Nonsense bytes didn't map to the type they were interpreted as",
                        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",
                }
        }
 }
@@ -919,7 +959,7 @@ impl<R: Read> Readable<R> for OnionHopData {
                        realm: {
                                let r: u8 = Readable::read(r)?;
                                if r != 0 {
-                                       return Err(DecodeError::UnknownRealmByte);
+                                       return Err(DecodeError::UnknownVersion);
                                }
                                r
                        },
@@ -1087,7 +1127,7 @@ impl<R: Read> Readable<R> for ErrorMessage {
                                sz = cmp::min(data_len, sz);
                                match String::from_utf8(data[..sz as usize].to_vec()) {
                                        Ok(s) => s,
-                                       Err(_) => return Err(DecodeError::BadText),
+                                       Err(_) => return Err(DecodeError::InvalidValue),
                                }
                        }
                })