//! as ChannelsManagers and ChannelMonitors.
use crate::prelude::*;
-use crate::io::{self, Read, Write};
+use crate::io::{self, Read, Seek, Write};
use crate::io_extras::{copy, sink};
use core::hash::Hash;
use crate::sync::Mutex;
use core::ops::Deref;
use bitcoin::secp256k1::{PublicKey, SecretKey};
-use bitcoin::secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE, COMPACT_SIGNATURE_SIZE};
-use bitcoin::secp256k1::ecdsa::Signature;
+use bitcoin::secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE, COMPACT_SIGNATURE_SIZE, SCHNORR_SIGNATURE_SIZE};
+use bitcoin::secp256k1::ecdsa;
+use bitcoin::secp256k1::schnorr;
+use bitcoin::blockdata::constants::ChainHash;
use bitcoin::blockdata::script::Script;
use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
use bitcoin::consensus;
fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError>;
}
+/// A trait that various rust-lightning types implement allowing them to be read in from a
+/// `Read + Seek`.
+pub(crate) trait SeekReadable where Self: Sized {
+ /// Reads a Self in from the given Read
+ fn read<R: Read + Seek>(reader: &mut R) -> Result<Self, DecodeError>;
+}
+
/// A trait that various higher-level rust-lightning types implement allowing them to be read in
/// from a Read given some additional set of arguments which is required to deserialize.
///
/// In TLV we occasionally send fields which only consist of, or potentially end with, a
/// variable-length integer which is simply truncated by skipping high zero bytes. This type
/// encapsulates such integers implementing Readable/Writeable for them.
-#[cfg_attr(test, derive(PartialEq, Eq))]
-#[derive(Clone, Debug)]
+#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
pub(crate) struct HighZeroBytesDroppedBigSize<T>(pub T);
macro_rules! impl_writeable_primitive {
}
}
+impl_writeable_primitive!(u128, 16);
impl_writeable_primitive!(u64, 8);
impl_writeable_primitive!(u32, 4);
impl_writeable_primitive!(u16, 2);
);
}
-impl_array!(3); // for rgb
+impl_array!(3); // for rgb, ISO 4712 code
impl_array!(4); // for IPv4
impl_array!(12); // for OnionV2
impl_array!(16); // for IPv6
impl_array!(32); // for channel id & hmac
impl_array!(PUBLIC_KEY_SIZE); // for PublicKey
-impl_array!(COMPACT_SIGNATURE_SIZE); // for Signature
+impl_array!(64); // for ecdsa::Signature and schnorr::Signature
impl_array!(1300); // for OnionPacket.hop_data
impl Writeable for [u16; 8] {
Ok(ret)
}
}
-impl Writeable for Vec<Signature> {
+impl Writeable for Vec<ecdsa::Signature> {
#[inline]
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
(self.len() as u16).write(w)?;
}
}
-impl Readable for Vec<Signature> {
+impl Readable for Vec<ecdsa::Signature> {
#[inline]
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let len: u16 = Readable::read(r)?;
}
}
-impl Writeable for Signature {
+impl Writeable for ecdsa::Signature {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
self.serialize_compact().write(w)
}
- #[inline]
- fn serialized_length(&self) -> usize {
- COMPACT_SIGNATURE_SIZE
- }
}
-impl Readable for Signature {
+impl Readable for ecdsa::Signature {
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let buf: [u8; COMPACT_SIGNATURE_SIZE] = Readable::read(r)?;
- match Signature::from_compact(&buf) {
+ match ecdsa::Signature::from_compact(&buf) {
+ Ok(sig) => Ok(sig),
+ Err(_) => return Err(DecodeError::InvalidValue),
+ }
+ }
+}
+
+impl Writeable for schnorr::Signature {
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+ self.as_ref().write(w)
+ }
+}
+
+impl Readable for schnorr::Signature {
+ fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+ let buf: [u8; SCHNORR_SIGNATURE_SIZE] = Readable::read(r)?;
+ match schnorr::Signature::from_slice(&buf) {
Ok(sig) => Ok(sig),
Err(_) => return Err(DecodeError::InvalidValue),
}
}
}
+impl Writeable for ChainHash {
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+ w.write_all(self.as_bytes())
+ }
+}
+
+impl Readable for ChainHash {
+ fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+ let buf: [u8; 32] = Readable::read(r)?;
+ Ok(ChainHash::from(&buf[..]))
+ }
+}
+
impl Writeable for OutPoint {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
self.txid.write(w)?;