cleanup how we deal with flexible rproof size in ser/deser (#1965)

This commit is contained in:
Antioch Peverell 2018-11-13 09:30:40 +00:00 committed by GitHub
parent a3c1c6d603
commit c631b45ab6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 29 deletions

View file

@ -184,10 +184,8 @@ pub trait Reader {
fn read_i32(&mut self) -> Result<i32, Error>; fn read_i32(&mut self) -> Result<i32, Error>;
/// Read a i64 from the underlying Read /// Read a i64 from the underlying Read
fn read_i64(&mut self) -> Result<i64, Error>; fn read_i64(&mut self) -> Result<i64, Error>;
/// first before the data bytes. /// Read a u64 len prefix followed by that number of exact bytes.
fn read_vec(&mut self) -> Result<Vec<u8>, Error>; fn read_bytes_len_prefix(&mut self) -> Result<Vec<u8>, Error>;
/// first before the data bytes limited to max bytes.
fn read_limited_vec(&mut self, max: usize) -> Result<Vec<u8>, Error>;
/// Read a fixed number of bytes from the underlying reader. /// Read a fixed number of bytes from the underlying reader.
fn read_fixed_bytes(&mut self, length: usize) -> Result<Vec<u8>, Error>; fn read_fixed_bytes(&mut self, length: usize) -> Result<Vec<u8>, Error>;
/// Consumes a byte from the reader, producing an error if it doesn't have /// Consumes a byte from the reader, producing an error if it doesn't have
@ -281,16 +279,11 @@ impl<'a> Reader for BinReader<'a> {
self.source.read_i64::<BigEndian>().map_err(map_io_err) self.source.read_i64::<BigEndian>().map_err(map_io_err)
} }
/// Read a variable size vector from the underlying Read. Expects a usize /// Read a variable size vector from the underlying Read. Expects a usize
fn read_vec(&mut self) -> Result<Vec<u8>, Error> { fn read_bytes_len_prefix(&mut self) -> Result<Vec<u8>, Error> {
let len = self.read_u64()?; let len = self.read_u64()?;
self.read_fixed_bytes(len as usize) self.read_fixed_bytes(len as usize)
} }
/// Read limited variable size vector from the underlying Read. Expects a /// Read a fixed number of bytes.
/// usize
fn read_limited_vec(&mut self, max: usize) -> Result<Vec<u8>, Error> {
let len = cmp::min(max, self.read_u64()? as usize);
self.read_fixed_bytes(len as usize)
}
fn read_fixed_bytes(&mut self, length: usize) -> Result<Vec<u8>, Error> { fn read_fixed_bytes(&mut self, length: usize) -> Result<Vec<u8>, Error> {
// not reading more than 100k in a single read // not reading more than 100k in a single read
if length > 100000 { if length > 100000 {
@ -369,27 +362,30 @@ impl Writeable for RangeProof {
impl Readable for RangeProof { impl Readable for RangeProof {
fn read(reader: &mut Reader) -> Result<RangeProof, Error> { fn read(reader: &mut Reader) -> Result<RangeProof, Error> {
let p = reader.read_limited_vec(MAX_PROOF_SIZE)?; let len = reader.read_u64()?;
let mut a = [0; MAX_PROOF_SIZE]; let max_len = cmp::min(len as usize, MAX_PROOF_SIZE);
a[..p.len()].clone_from_slice(&p[..]); let p = reader.read_fixed_bytes(max_len)?;
let mut proof = [0; MAX_PROOF_SIZE];
proof[..p.len()].clone_from_slice(&p[..]);
Ok(RangeProof { Ok(RangeProof {
proof: a, plen: proof.len(),
plen: p.len(), proof,
}) })
} }
} }
impl FixedLength for RangeProof { impl FixedLength for RangeProof {
const LEN: usize = MAX_PROOF_SIZE + 8; const LEN: usize = 8 // length prefix
+ MAX_PROOF_SIZE;
} }
impl PMMRable for RangeProof {} impl PMMRable for RangeProof {}
impl Readable for Signature { impl Readable for Signature {
fn read(reader: &mut Reader) -> Result<Signature, Error> { fn read(reader: &mut Reader) -> Result<Signature, Error> {
let a = reader.read_fixed_bytes(AGG_SIGNATURE_SIZE)?; let a = reader.read_fixed_bytes(Signature::LEN)?;
let mut c = [0; AGG_SIGNATURE_SIZE]; let mut c = [0; Signature::LEN];
c[..AGG_SIGNATURE_SIZE].clone_from_slice(&a[..AGG_SIGNATURE_SIZE]); c[..Signature::LEN].clone_from_slice(&a[..Signature::LEN]);
Ok(Signature::from_raw_data(&c).unwrap()) Ok(Signature::from_raw_data(&c).unwrap())
} }
} }
@ -400,6 +396,10 @@ impl Writeable for Signature {
} }
} }
impl FixedLength for Signature {
const LEN: usize = AGG_SIGNATURE_SIZE;
}
/// Utility wrapper for an underlying byte Writer. Defines higher level methods /// Utility wrapper for an underlying byte Writer. Defines higher level methods
/// to write numbers, byte vectors, hashes, etc. /// to write numbers, byte vectors, hashes, etc.
pub struct BinWriter<'a> { pub struct BinWriter<'a> {

View file

@ -362,7 +362,7 @@ impl Readable for Hand {
let total_diff = Difficulty::read(reader)?; let total_diff = Difficulty::read(reader)?;
let sender_addr = SockAddr::read(reader)?; let sender_addr = SockAddr::read(reader)?;
let receiver_addr = SockAddr::read(reader)?; let receiver_addr = SockAddr::read(reader)?;
let ua = reader.read_vec()?; let ua = reader.read_bytes_len_prefix()?;
let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?; let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?;
let genesis = Hash::read(reader)?; let genesis = Hash::read(reader)?;
Ok(Hand { Ok(Hand {
@ -413,7 +413,7 @@ impl Readable for Shake {
let (version, capab) = ser_multiread!(reader, read_u32, read_u32); let (version, capab) = ser_multiread!(reader, read_u32, read_u32);
let capabilities = Capabilities::from_bits_truncate(capab); let capabilities = Capabilities::from_bits_truncate(capab);
let total_diff = Difficulty::read(reader)?; let total_diff = Difficulty::read(reader)?;
let ua = reader.read_vec()?; let ua = reader.read_bytes_len_prefix()?;
let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?; let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?;
let genesis = Hash::read(reader)?; let genesis = Hash::read(reader)?;
Ok(Shake { Ok(Shake {
@ -498,7 +498,8 @@ impl Writeable for PeerError {
impl Readable for PeerError { impl Readable for PeerError {
fn read(reader: &mut Reader) -> Result<PeerError, ser::Error> { fn read(reader: &mut Reader) -> Result<PeerError, ser::Error> {
let (code, msg) = ser_multiread!(reader, read_u32, read_vec); let code = reader.read_u32()?;
let msg = reader.read_bytes_len_prefix()?;
let message = String::from_utf8(msg).map_err(|_| ser::Error::CorruptedData)?; let message = String::from_utf8(msg).map_err(|_| ser::Error::CorruptedData)?;
Ok(PeerError { Ok(PeerError {
code: code, code: code,

View file

@ -80,8 +80,10 @@ impl Writeable for PeerData {
impl Readable for PeerData { impl Readable for PeerData {
fn read(reader: &mut Reader) -> Result<PeerData, ser::Error> { fn read(reader: &mut Reader) -> Result<PeerData, ser::Error> {
let addr = SockAddr::read(reader)?; let addr = SockAddr::read(reader)?;
let (capab, ua, fl, lb, br) = let capab = reader.read_u32()?;
ser_multiread!(reader, read_u32, read_vec, read_u8, read_i64, read_i32); let ua = reader.read_bytes_len_prefix()?;
let (fl, lb, br) = ser_multiread!(reader, read_u8, read_i64, read_i32);
let lc = reader.read_i64(); let lc = reader.read_i64();
// this only works because each PeerData is read in its own vector and this // this only works because each PeerData is read in its own vector and this
// is the last data element // is the last data element
@ -90,6 +92,7 @@ impl Readable for PeerData {
} else { } else {
lc.unwrap() lc.unwrap()
}; };
let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?; let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?;
let capabilities = Capabilities::from_bits_truncate(capab); let capabilities = Capabilities::from_bits_truncate(capab);
let ban_reason = ReasonForBan::from_i32(br).ok_or(ser::Error::CorruptedData)?; let ban_reason = ReasonForBan::from_i32(br).ok_or(ser::Error::CorruptedData)?;

View file

@ -262,7 +262,7 @@ impl ser::Writeable for OutputData {
impl ser::Readable for OutputData { impl ser::Readable for OutputData {
fn read(reader: &mut ser::Reader) -> Result<OutputData, ser::Error> { fn read(reader: &mut ser::Reader) -> Result<OutputData, ser::Error> {
let data = reader.read_vec()?; let data = reader.read_bytes_len_prefix()?;
serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData) serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData)
} }
} }
@ -431,7 +431,7 @@ impl ser::Writeable for Context {
impl ser::Readable for Context { impl ser::Readable for Context {
fn read(reader: &mut ser::Reader) -> Result<Context, ser::Error> { fn read(reader: &mut ser::Reader) -> Result<Context, ser::Error> {
let data = reader.read_vec()?; let data = reader.read_bytes_len_prefix()?;
serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData) serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData)
} }
} }
@ -615,7 +615,7 @@ impl ser::Writeable for TxLogEntry {
impl ser::Readable for TxLogEntry { impl ser::Readable for TxLogEntry {
fn read(reader: &mut ser::Reader) -> Result<TxLogEntry, ser::Error> { fn read(reader: &mut ser::Reader) -> Result<TxLogEntry, ser::Error> {
let data = reader.read_vec()?; let data = reader.read_bytes_len_prefix()?;
serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData) serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData)
} }
} }
@ -663,7 +663,7 @@ impl ser::Writeable for AcctPathMapping {
impl ser::Readable for AcctPathMapping { impl ser::Readable for AcctPathMapping {
fn read(reader: &mut ser::Reader) -> Result<AcctPathMapping, ser::Error> { fn read(reader: &mut ser::Reader) -> Result<AcctPathMapping, ser::Error> {
let data = reader.read_vec()?; let data = reader.read_bytes_len_prefix()?;
serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData) serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData)
} }
} }