}
}
+impl Writeable for SpendableOutputDescriptor {
+ fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+ match self {
+ &SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => {
+ 0u8.write(writer)?;
+ outpoint.write(writer)?;
+ output.write(writer)?;
+ },
+ &SpendableOutputDescriptor::DynamicOutputP2WSH { ref outpoint, ref key, ref witness_script, ref to_self_delay, ref output } => {
+ 1u8.write(writer)?;
+ outpoint.write(writer)?;
+ key.write(writer)?;
+ witness_script.write(writer)?;
+ to_self_delay.write(writer)?;
+ output.write(writer)?;
+ },
+ &SpendableOutputDescriptor::DynamicOutputP2WPKH { ref outpoint, ref key, ref output } => {
+ 2u8.write(writer)?;
+ outpoint.write(writer)?;
+ key.write(writer)?;
+ output.write(writer)?;
+ },
+ }
+ Ok(())
+ }
+}
+
+impl<R: ::std::io::Read> Readable<R> for SpendableOutputDescriptor {
+ fn read(reader: &mut R) -> Result<Self, DecodeError> {
+ match Readable::read(reader)? {
+ 0u8 => Ok(SpendableOutputDescriptor::StaticOutput {
+ outpoint: Readable::read(reader)?,
+ output: Readable::read(reader)?,
+ }),
+ 1u8 => Ok(SpendableOutputDescriptor::DynamicOutputP2WSH {
+ outpoint: Readable::read(reader)?,
+ key: Readable::read(reader)?,
+ witness_script: Readable::read(reader)?,
+ to_self_delay: Readable::read(reader)?,
+ output: Readable::read(reader)?,
+ }),
+ 2u8 => Ok(SpendableOutputDescriptor::DynamicOutputP2WPKH {
+ outpoint: Readable::read(reader)?,
+ key: Readable::read(reader)?,
+ output: Readable::read(reader)?,
+ }),
+ _ => Err(DecodeError::InvalidValue),
+ }
+ }
+}
+
/// A trait to describe an object which can get user secrets and key material.
pub trait KeysInterface: Send + Sync {
/// A type which implements ChannelKeys which will be returned by get_channel_keys.
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;
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.
},
}
+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.
use secp256k1::Signature;
use secp256k1::key::{PublicKey, SecretKey};
use bitcoin::blockdata::script::Script;
-use bitcoin::blockdata::transaction::{OutPoint, Transaction};
+use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
use bitcoin::consensus;
use bitcoin::consensus::Encodable;
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
fn read(reader: &mut R, params: P) -> Result<Self, DecodeError>;
}
+/// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a Read
+pub trait MaybeReadable<R>
+ where Self: Sized,
+ R: Read
+{
+ /// Reads a Self in from the given Read
+ fn read(reader: &mut R) -> Result<Option<Self>, DecodeError>;
+}
+
pub(crate) struct U48(pub u64);
impl Writeable for U48 {
#[inline]
}
}
-impl Writeable for Transaction {
- fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
- match self.consensus_encode(WriterWriteAdaptor(writer)) {
- Ok(_) => Ok(()),
- Err(consensus::encode::Error::Io(e)) => Err(e),
- Err(_) => panic!("We shouldn't get a consensus::encode::Error unless our Write generated an std::io::Error"),
+macro_rules! impl_consensus_ser {
+ ($bitcoin_type: ty) => {
+ impl Writeable for $bitcoin_type {
+ fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
+ match self.consensus_encode(WriterWriteAdaptor(writer)) {
+ Ok(_) => Ok(()),
+ Err(consensus::encode::Error::Io(e)) => Err(e),
+ Err(_) => panic!("We shouldn't get a consensus::encode::Error unless our Write generated an std::io::Error"),
+ }
+ }
}
- }
-}
-impl<R: Read> Readable<R> for Transaction {
- fn read(r: &mut R) -> Result<Self, DecodeError> {
- match consensus::encode::Decodable::consensus_decode(r) {
- Ok(t) => Ok(t),
- Err(consensus::encode::Error::Io(ref e)) if e.kind() == ::std::io::ErrorKind::UnexpectedEof => Err(DecodeError::ShortRead),
- Err(consensus::encode::Error::Io(e)) => Err(DecodeError::Io(e)),
- Err(_) => Err(DecodeError::InvalidValue),
+ impl<R: Read> Readable<R> for $bitcoin_type {
+ fn read(r: &mut R) -> Result<Self, DecodeError> {
+ match consensus::encode::Decodable::consensus_decode(r) {
+ Ok(t) => Ok(t),
+ Err(consensus::encode::Error::Io(ref e)) if e.kind() == ::std::io::ErrorKind::UnexpectedEof => Err(DecodeError::ShortRead),
+ Err(consensus::encode::Error::Io(e)) => Err(DecodeError::Io(e)),
+ Err(_) => Err(DecodeError::InvalidValue),
+ }
+ }
}
}
}
+impl_consensus_ser!(Transaction);
+impl_consensus_ser!(TxOut);
impl<R: Read, T: Readable<R>> Readable<R> for Mutex<T> {
fn read(r: &mut R) -> Result<Self, DecodeError> {