BDR: Linearizing secp256k1 deps
[rust-lightning] / lightning / src / util / events.rs
index eda6fc7ee4eab89068a0b7f7a5848c5a3d2e2810..76ec20209412a8ddc4865aa931c3265a5275f60e 100644 (file)
@@ -4,26 +4,24 @@
 //! Because we don't have a built-in runtime, it's up to the client to call events at a time in the
 //! future, as well as generate and broadcast funding transactions handle payment preimages and a
 //! few other things.
-//!
-//! Note that many events are handled for you by PeerHandler, so in the common design of having a
-//! PeerManager which marshalls messages to ChannelManager and Router you only need to call
-//! process_events on the PeerHandler and then get_and_clear_pending_events and handle the events
-//! that bubble up to the surface. If, however, you do not have a PeerHandler managing a
-//! ChannelManager you need to handle all of the events which may be generated.
-//TODO: We need better separation of event types ^
 
 use ln::msgs;
-use ln::channelmanager::{PaymentPreimage, PaymentHash};
+use ln::channelmanager::{PaymentPreimage, PaymentHash, PaymentSecret};
 use chain::transaction::OutPoint;
 use chain::keysinterface::SpendableOutputDescriptor;
+use util::ser::{Writeable, Writer, MaybeReadable, Readable};
 
 use bitcoin::blockdata::script::Script;
 
-use secp256k1::key::PublicKey;
+use bitcoin::secp256k1::key::PublicKey;
 
 use std::time::Duration;
 
 /// An Event which you should probably take some action in response to.
+///
+/// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use
+/// them directly as they don't round-trip exactly (for example FundingGenerationReady is never
+/// written as it makes no sense to respond to it after reconnecting to peers).
 pub enum Event {
        /// Used to indicate that the client should generate a funding transaction with the given
        /// parameters and then call ChannelManager::funding_transaction_generated.
@@ -53,13 +51,27 @@ pub enum Event {
        },
        /// Indicates we've received money! Just gotta dig out that payment preimage and feed it to
        /// ChannelManager::claim_funds to get it....
-       /// Note that if the preimage is not known or the amount paid is incorrect, you must call
-       /// ChannelManager::fail_htlc_backwards to free up resources for this HTLC.
+       /// Note that if the preimage is not known or the amount paid is incorrect, you should call
+       /// ChannelManager::fail_htlc_backwards to free up resources for this HTLC and avoid
+       /// network congestion.
        /// The amount paid should be considered 'incorrect' when it is less than or more than twice
        /// the amount expected.
+       /// If you fail to call either ChannelManager::claim_funds or
+       /// ChannelManager::fail_htlc_backwards within the HTLC's timeout, the HTLC will be
+       /// automatically failed.
        PaymentReceived {
                /// The hash for which the preimage should be handed to the ChannelManager.
                payment_hash: PaymentHash,
+               /// The "payment secret". This authenticates the sender to the recipient, preventing a
+               /// number of deanonymization attacks during the routing process.
+               /// As nodes upgrade, the invoices you provide should likely migrate to setting the
+               /// payment_secret feature to required, at which point you should fail_backwards any HTLCs
+               /// which have a None here.
+               /// Until then, however, values of None should be ignored, and only incorrect Some values
+               /// should result in an HTLC fail_backwards.
+               /// Note that, in any case, this value must be passed as-is to any fail or claim calls as
+               /// the HTLC index includes this value.
+               payment_secret: Option<PaymentSecret>,
                /// The value, in thousandths of a satoshi, that this payment is for. Note that you must
                /// compare this to the expected value before accepting the payment (as otherwise you are
                /// providing proof-of-payment for less than the value you expected!).
@@ -88,6 +100,8 @@ pub enum Event {
                rejected_by_dest: bool,
 #[cfg(test)]
                error_code: Option<u16>,
+#[cfg(test)]
+               error_data: Option<Vec<u8>>,
        },
        /// Used to indicate that ChannelManager::process_pending_htlc_forwards should be called at a
        /// time in the future.
@@ -108,6 +122,99 @@ pub enum Event {
        },
 }
 
+impl Writeable for Event {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+               match self {
+                       &Event::FundingGenerationReady { .. } => {
+                               0u8.write(writer)?;
+                               // We never write out FundingGenerationReady events as, upon disconnection, peers
+                               // drop any channels which have not yet exchanged funding_signed.
+                       },
+                       &Event::FundingBroadcastSafe { ref funding_txo, ref user_channel_id } => {
+                               1u8.write(writer)?;
+                               funding_txo.write(writer)?;
+                               user_channel_id.write(writer)?;
+                       },
+                       &Event::PaymentReceived { ref payment_hash, ref payment_secret, ref amt } => {
+                               2u8.write(writer)?;
+                               payment_hash.write(writer)?;
+                               payment_secret.write(writer)?;
+                               amt.write(writer)?;
+                       },
+                       &Event::PaymentSent { ref payment_preimage } => {
+                               3u8.write(writer)?;
+                               payment_preimage.write(writer)?;
+                       },
+                       &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest,
+                               #[cfg(test)]
+                               ref error_code,
+                               #[cfg(test)]
+                               ref error_data,
+                       } => {
+                               4u8.write(writer)?;
+                               payment_hash.write(writer)?;
+                               rejected_by_dest.write(writer)?;
+                               #[cfg(test)]
+                               error_code.write(writer)?;
+                               #[cfg(test)]
+                               error_data.write(writer)?;
+                       },
+                       &Event::PendingHTLCsForwardable { time_forwardable: _ } => {
+                               5u8.write(writer)?;
+                               // We don't write the time_fordwardable out at all, as we presume when the user
+                               // deserializes us at least that much time has elapsed.
+                       },
+                       &Event::SpendableOutputs { ref outputs } => {
+                               6u8.write(writer)?;
+                               (outputs.len() as u64).write(writer)?;
+                               for output in outputs.iter() {
+                                       output.write(writer)?;
+                               }
+                       },
+               }
+               Ok(())
+       }
+}
+impl MaybeReadable for Event {
+       fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Option<Self>, msgs::DecodeError> {
+               match Readable::read(reader)? {
+                       0u8 => Ok(None),
+                       1u8 => Ok(Some(Event::FundingBroadcastSafe {
+                                       funding_txo: Readable::read(reader)?,
+                                       user_channel_id: Readable::read(reader)?,
+                               })),
+                       2u8 => Ok(Some(Event::PaymentReceived {
+                                       payment_hash: Readable::read(reader)?,
+                                       payment_secret: Readable::read(reader)?,
+                                       amt: Readable::read(reader)?,
+                               })),
+                       3u8 => Ok(Some(Event::PaymentSent {
+                                       payment_preimage: Readable::read(reader)?,
+                               })),
+                       4u8 => Ok(Some(Event::PaymentFailed {
+                                       payment_hash: Readable::read(reader)?,
+                                       rejected_by_dest: Readable::read(reader)?,
+                                       #[cfg(test)]
+                                       error_code: Readable::read(reader)?,
+                                       #[cfg(test)]
+                                       error_data: Readable::read(reader)?,
+                               })),
+                       5u8 => Ok(Some(Event::PendingHTLCsForwardable {
+                                       time_forwardable: Duration::from_secs(0)
+                               })),
+                       6u8 => {
+                               let outputs_len: u64 = Readable::read(reader)?;
+                               let mut outputs = Vec::new();
+                               for _ in 0..outputs_len {
+                                       outputs.push(Readable::read(reader)?);
+                               }
+                               Ok(Some(Event::SpendableOutputs { outputs }))
+                       },
+                       _ => Err(msgs::DecodeError::InvalidValue)
+               }
+       }
+}
+
 /// An event generated by ChannelManager which indicates a message should be sent to a peer (or
 /// broadcast to most peers).
 /// These events are handled by PeerManager::process_events if you are using a PeerManager.
@@ -195,12 +302,23 @@ pub enum MessageSendEvent {
        },
        /// Used to indicate that a channel_announcement and channel_update should be broadcast to all
        /// peers (except the peer with node_id either msg.contents.node_id_1 or msg.contents.node_id_2).
+       ///
+       /// Note that after doing so, you very likely (unless you did so very recently) want to call
+       /// ChannelManager::broadcast_node_announcement to trigger a BroadcastNodeAnnouncement event.
+       /// This ensures that any nodes which see our channel_announcement also have a relevant
+       /// node_announcement, including relevant feature flags which may be important for routing
+       /// through or to us.
        BroadcastChannelAnnouncement {
                /// The channel_announcement which should be sent.
                msg: msgs::ChannelAnnouncement,
                /// The followup channel_update which should be sent.
                update_msg: msgs::ChannelUpdate,
        },
+       /// Used to indicate that a node_announcement should be broadcast to all peers.
+       BroadcastNodeAnnouncement {
+               /// The node_announcement which should be sent.
+               msg: msgs::NodeAnnouncement,
+       },
        /// Used to indicate that a channel_update should be broadcast to all peers.
        BroadcastChannelUpdate {
                /// The channel_update which should be sent.