Implement Readable/Writeable for Events
[rust-lightning] / lightning / src / util / events.rs
index eda6fc7ee4eab89068a0b7f7a5848c5a3d2e2810..a41b7a3bbb95243b21d271359b66c1f58d88a60f 100644 (file)
@@ -16,6 +16,7 @@ use ln::msgs;
 use ln::channelmanager::{PaymentPreimage, PaymentHash};
 use chain::transaction::OutPoint;
 use chain::keysinterface::SpendableOutputDescriptor;
+use util::ser::{Writeable, Writer, MaybeReadable, Readable};
 
 use bitcoin::blockdata::script::Script;
 
@@ -24,6 +25,10 @@ use 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.
@@ -108,6 +113,91 @@ 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 amt } => {
+                               2u8.write(writer)?;
+                               payment_hash.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,
+                       } => {
+                               4u8.write(writer)?;
+                               payment_hash.write(writer)?;
+                               rejected_by_dest.write(writer)?;
+                               #[cfg(test)]
+                               error_code.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<R: ::std::io::Read> MaybeReadable<R> for Event {
+       fn 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)?,
+                                       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)?,
+                               })),
+                       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.