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>;
/// Read a i64 from the underlying Read
fn read_i64(&mut self) -> Result<i64, Error>;
/// first before the data bytes.
fn read_vec(&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 u64 len prefix followed by that number of exact bytes.
fn read_bytes_len_prefix(&mut self) -> Result<Vec<u8>, Error>;
/// Read a fixed number of bytes from the underlying reader.
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
@ -281,16 +279,11 @@ impl<'a> Reader for BinReader<'a> {
self.source.read_i64::<BigEndian>().map_err(map_io_err)
}
/// 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()?;
self.read_fixed_bytes(len as usize)
}
/// Read limited variable size vector from the underlying Read. Expects a
/// 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)
}
/// Read a fixed number of bytes.
fn read_fixed_bytes(&mut self, length: usize) -> Result<Vec<u8>, Error> {
// not reading more than 100k in a single read
if length > 100000 {
@ -369,27 +362,30 @@ impl Writeable for RangeProof {
impl Readable for RangeProof {
fn read(reader: &mut Reader) -> Result<RangeProof, Error> {
let p = reader.read_limited_vec(MAX_PROOF_SIZE)?;
let mut a = [0; MAX_PROOF_SIZE];
a[..p.len()].clone_from_slice(&p[..]);
let len = reader.read_u64()?;
let max_len = cmp::min(len as usize, MAX_PROOF_SIZE);
let p = reader.read_fixed_bytes(max_len)?;
let mut proof = [0; MAX_PROOF_SIZE];
proof[..p.len()].clone_from_slice(&p[..]);
Ok(RangeProof {
proof: a,
plen: p.len(),
plen: proof.len(),
proof,
})
}
}
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 Readable for Signature {
fn read(reader: &mut Reader) -> Result<Signature, Error> {
let a = reader.read_fixed_bytes(AGG_SIGNATURE_SIZE)?;
let mut c = [0; AGG_SIGNATURE_SIZE];
c[..AGG_SIGNATURE_SIZE].clone_from_slice(&a[..AGG_SIGNATURE_SIZE]);
let a = reader.read_fixed_bytes(Signature::LEN)?;
let mut c = [0; Signature::LEN];
c[..Signature::LEN].clone_from_slice(&a[..Signature::LEN]);
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
/// to write numbers, byte vectors, hashes, etc.
pub struct BinWriter<'a> {

View file

@ -362,7 +362,7 @@ impl Readable for Hand {
let total_diff = Difficulty::read(reader)?;
let sender_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 genesis = Hash::read(reader)?;
Ok(Hand {
@ -413,7 +413,7 @@ impl Readable for Shake {
let (version, capab) = ser_multiread!(reader, read_u32, read_u32);
let capabilities = Capabilities::from_bits_truncate(capab);
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 genesis = Hash::read(reader)?;
Ok(Shake {
@ -498,7 +498,8 @@ impl Writeable for PeerError {
impl Readable for PeerError {
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)?;
Ok(PeerError {
code: code,

View file

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