X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fser.rs;h=5f109e1a93c64529d09e462899fb539abf662c68;hb=c166c2177a5fe325c8eb567da821d67202ea8216;hp=f333fa2bac27f5182e4122a5321e684fc83a08ab;hpb=3c24a137b1088ca75d549b4355dc18980fad1a44;p=rust-lightning diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index f333fa2b..5f109e1a 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -19,7 +19,6 @@ use crate::io_extras::{copy, sink}; use core::hash::Hash; use crate::sync::{Mutex, RwLock}; use core::cmp; -use core::convert::TryFrom; use core::ops::Deref; use alloc::collections::BTreeMap; @@ -28,6 +27,7 @@ use bitcoin::secp256k1::{PublicKey, SecretKey}; 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::amount::Amount; use bitcoin::blockdata::constants::ChainHash; use bitcoin::blockdata::script::{self, ScriptBuf}; use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut}; @@ -35,13 +35,12 @@ use bitcoin::{consensus, Witness}; use bitcoin::consensus::Encodable; use bitcoin::hashes::sha256d::Hash as Sha256dHash; use bitcoin::hash_types::{Txid, BlockHash}; -use core::marker::Sized; use core::time::Duration; use crate::chain::ClaimId; use crate::ln::msgs::DecodeError; #[cfg(taproot)] use crate::ln::msgs::PartialSignatureWithNonce; -use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret}; +use crate::ln::types::{PaymentPreimage, PaymentHash, PaymentSecret}; use crate::util::byte_utils::{be48_to_array, slice_to_be48}; use crate::util::string::UntrustedString; @@ -820,6 +819,49 @@ macro_rules! impl_for_vec { } } +// Alternatives to impl_writeable_for_vec/impl_readable_for_vec that add a length prefix to each +// element in the Vec. Intended to be used when elements have variable lengths. +macro_rules! impl_writeable_for_vec_with_element_length_prefix { + ($ty: ty $(, $name: ident)*) => { + impl<$($name : Writeable),*> Writeable for Vec<$ty> { + #[inline] + fn write(&self, w: &mut W) -> Result<(), io::Error> { + CollectionLength(self.len() as u64).write(w)?; + for elem in self.iter() { + CollectionLength(elem.serialized_length() as u64).write(w)?; + elem.write(w)?; + } + Ok(()) + } + } + } +} +macro_rules! impl_readable_for_vec_with_element_length_prefix { + ($ty: ty $(, $name: ident)*) => { + impl<$($name : Readable),*> Readable for Vec<$ty> { + #[inline] + fn read(r: &mut R) -> Result { + let len: CollectionLength = Readable::read(r)?; + let mut ret = Vec::with_capacity(cmp::min(len.0 as usize, MAX_BUF_SIZE / core::mem::size_of::<$ty>())); + for _ in 0..len.0 { + let elem_len: CollectionLength = Readable::read(r)?; + let mut elem_reader = FixedLengthReader::new(r, elem_len.0); + if let Some(val) = MaybeReadable::read(&mut elem_reader)? { + ret.push(val); + } + } + Ok(ret) + } + } + } +} +macro_rules! impl_for_vec_with_element_length_prefix { + ($ty: ty $(, $name: ident)*) => { + impl_writeable_for_vec_with_element_length_prefix!($ty $(, $name)*); + impl_readable_for_vec_with_element_length_prefix!($ty $(, $name)*); + } +} + impl Writeable for Vec { #[inline] fn write(&self, w: &mut W) -> Result<(), io::Error> { @@ -851,13 +893,15 @@ impl_for_vec!(crate::ln::msgs::SocketAddress); impl_for_vec!((A, B), A, B); impl_writeable_for_vec!(&crate::routing::router::BlindedTail); impl_readable_for_vec!(crate::routing::router::BlindedTail); +impl_for_vec_with_element_length_prefix!(crate::ln::msgs::UpdateAddHTLC); +impl_writeable_for_vec_with_element_length_prefix!(&crate::ln::msgs::UpdateAddHTLC); impl Writeable for Vec { #[inline] fn write(&self, w: &mut W) -> Result<(), io::Error> { (self.len() as u16).write(w)?; for witness in self { - (witness.serialized_len() as u16).write(w)?; + (witness.size() as u16).write(w)?; witness.write(w)?; } Ok(()) @@ -877,7 +921,7 @@ impl Readable for Vec { // of witnesses. We'll just do a sanity check for the lengths and error if there is a mismatch. let witness_len = ::read(r)? as usize; let witness = ::read(r)?; - if witness.serialized_len() != witness_len { + if witness.size() != witness_len { return Err(DecodeError::BadLengthDescriptor); } witnesses.push(witness); @@ -1102,6 +1146,20 @@ impl Readable for Option } } +impl Writeable for Amount { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + self.to_sat().write(w) + } +} + + +impl Readable for Amount { + fn read(r: &mut R) -> Result { + let amount: u64 = Readable::read(r)?; + Ok(Amount::from_sat(amount)) + } +} + impl Writeable for Txid { fn write(&self, w: &mut W) -> Result<(), io::Error> { w.write_all(&self[..]) @@ -1449,10 +1507,10 @@ impl Readable for ClaimId { #[cfg(test)] mod tests { - use core::convert::TryFrom; use bitcoin::hashes::hex::FromHex; use bitcoin::secp256k1::ecdsa; use crate::util::ser::{Readable, Hostname, Writeable}; + use crate::prelude::*; #[test] fn hostname_conversion() {