Lint Monero serialization

This commit is contained in:
Luke Parker 2022-08-21 04:41:55 -04:00
parent 76db682a25
commit 00d61286b1
No known key found for this signature in database
GPG key ID: F9F1386DB1E119B6
5 changed files with 28 additions and 67 deletions

View file

@ -23,16 +23,8 @@ impl BlockHeader {
major_version: read_varint(r)?, major_version: read_varint(r)?,
minor_version: read_varint(r)?, minor_version: read_varint(r)?,
timestamp: read_varint(r)?, timestamp: read_varint(r)?,
previous: { previous: read_bytes(r)?,
let mut previous = [0; 32]; nonce: read_bytes(r).map(u32::from_le_bytes)?,
r.read_exact(&mut previous)?;
previous
},
nonce: {
let mut nonce = [0; 4];
r.read_exact(&mut nonce)?;
u32::from_le_bytes(nonce)
},
}) })
} }
} }
@ -59,12 +51,7 @@ impl Block {
Ok(Block { Ok(Block {
header: BlockHeader::deserialize(r)?, header: BlockHeader::deserialize(r)?,
miner_tx: Transaction::deserialize(r)?, miner_tx: Transaction::deserialize(r)?,
txs: (0 .. read_varint(r)?) txs: (0 .. read_varint(r)?).map(|_| read_bytes(r)).collect::<Result<_, _>>()?,
.map(|_| {
let mut tx = [0; 32];
r.read_exact(&mut tx).map(|_| tx)
})
.collect::<Result<_, _>>()?,
}) })
} }
} }

View file

@ -50,24 +50,18 @@ impl RctBase {
outputs: usize, outputs: usize,
r: &mut R, r: &mut R,
) -> std::io::Result<(RctBase, u8)> { ) -> std::io::Result<(RctBase, u8)> {
let mut rct_type = [0]; let rct_type = read_byte(r)?;
r.read_exact(&mut rct_type)?;
Ok(( Ok((
if rct_type[0] == 0 { if rct_type == 0 {
RctBase { fee: 0, ecdh_info: vec![], commitments: vec![] } RctBase { fee: 0, ecdh_info: vec![], commitments: vec![] }
} else { } else {
RctBase { RctBase {
fee: read_varint(r)?, fee: read_varint(r)?,
ecdh_info: (0 .. outputs) ecdh_info: (0 .. outputs).map(|_| read_bytes(r)).collect::<Result<_, _>>()?,
.map(|_| {
let mut ecdh = [0; 8];
r.read_exact(&mut ecdh).map(|_| ecdh)
})
.collect::<Result<_, _>>()?,
commitments: read_raw_vec(read_point, outputs, r)?, commitments: read_raw_vec(read_point, outputs, r)?,
} }
}, },
rct_type[0], rct_type,
)) ))
} }
} }

View file

@ -53,10 +53,18 @@ pub fn write_vec<T, W: io::Write, F: Fn(&T, &mut W) -> io::Result<()>>(
write_raw_vec(f, values, w) write_raw_vec(f, values, w)
} }
pub fn read_byte<R: io::Read>(r: &mut R) -> io::Result<u8> { pub fn read_bytes<R: io::Read, const N: usize>(r: &mut R) -> io::Result<[u8; N]> {
let mut res = [0; 1]; let mut res = [0; N];
r.read_exact(&mut res)?; r.read_exact(&mut res)?;
Ok(res[0]) Ok(res)
}
pub fn read_byte<R: io::Read>(r: &mut R) -> io::Result<u8> {
Ok(read_bytes::<_, 1>(r)?[0])
}
pub fn read_u64<R: io::Read>(r: &mut R) -> io::Result<u64> {
read_bytes(r).map(u64::from_le_bytes)
} }
pub fn read_varint<R: io::Read>(r: &mut R) -> io::Result<u64> { pub fn read_varint<R: io::Read>(r: &mut R) -> io::Result<u64> {
@ -72,20 +80,14 @@ pub fn read_varint<R: io::Read>(r: &mut R) -> io::Result<u64> {
Ok(res) Ok(res)
} }
pub fn read_32<R: io::Read>(r: &mut R) -> io::Result<[u8; 32]> {
let mut res = [0; 32];
r.read_exact(&mut res)?;
Ok(res)
}
// TODO: https://github.com/serai-dex/serai/issues/25 // TODO: https://github.com/serai-dex/serai/issues/25
pub fn read_scalar<R: io::Read>(r: &mut R) -> io::Result<Scalar> { pub fn read_scalar<R: io::Read>(r: &mut R) -> io::Result<Scalar> {
Scalar::from_canonical_bytes(read_32(r)?) Scalar::from_canonical_bytes(read_bytes(r)?)
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "unreduced scalar")) .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "unreduced scalar"))
} }
pub fn read_point<R: io::Read>(r: &mut R) -> io::Result<EdwardsPoint> { pub fn read_point<R: io::Read>(r: &mut R) -> io::Result<EdwardsPoint> {
let bytes = read_32(r)?; let bytes = read_bytes(r)?;
CompressedEdwardsY(bytes) CompressedEdwardsY(bytes)
.decompress() .decompress()
// Ban torsioned points, and points which are either unreduced or -0 // Ban torsioned points, and points which are either unreduced or -0

View file

@ -41,9 +41,7 @@ impl Input {
} }
pub fn deserialize<R: std::io::Read>(r: &mut R) -> std::io::Result<Input> { pub fn deserialize<R: std::io::Read>(r: &mut R) -> std::io::Result<Input> {
let mut variant = [0]; Ok(match read_byte(r)? {
r.read_exact(&mut variant)?;
Ok(match variant[0] {
255 => Input::Gen(read_varint(r)?), 255 => Input::Gen(read_varint(r)?),
2 => Input::ToKey { 2 => Input::ToKey {
amount: read_varint(r)?, amount: read_varint(r)?,
@ -83,9 +81,7 @@ impl Output {
pub fn deserialize<R: std::io::Read>(r: &mut R) -> std::io::Result<Output> { pub fn deserialize<R: std::io::Read>(r: &mut R) -> std::io::Result<Output> {
let amount = read_varint(r)?; let amount = read_varint(r)?;
let mut output_type = [0]; let view_tag = match read_byte(r)? {
r.read_exact(&mut output_type)?;
let view_tag = match output_type[0] {
2 => false, 2 => false,
3 => true, 3 => true,
_ => Err(std::io::Error::new( _ => Err(std::io::Error::new(
@ -97,13 +93,7 @@ impl Output {
Ok(Output { Ok(Output {
amount, amount,
key: read_point(r)?, key: read_point(r)?,
view_tag: if view_tag { view_tag: if view_tag { Some(read_byte(r)?) } else { None },
let mut view_tag = [0];
r.read_exact(&mut view_tag)?;
Some(view_tag[0])
} else {
None
},
}) })
} }
} }
@ -191,11 +181,7 @@ impl TransactionPrefix {
outputs: read_vec(Output::deserialize, r)?, outputs: read_vec(Output::deserialize, r)?,
extra: vec![], extra: vec![],
}; };
prefix.extra = read_vec(read_byte, r)?;
let len = read_varint(r)?;
prefix.extra.resize(len.try_into().unwrap(), 0);
r.read_exact(&mut prefix.extra)?;
Ok(prefix) Ok(prefix)
} }
} }

View file

@ -8,7 +8,7 @@ use monero::{consensus::deserialize, blockdata::transaction::ExtraField};
use crate::{ use crate::{
Commitment, Commitment,
serialize::{write_varint, read_32, read_scalar, read_point}, serialize::{write_varint, read_byte, read_bytes, read_u64, read_scalar, read_point},
transaction::{Timelock, Transaction}, transaction::{Timelock, Transaction},
wallet::{ViewPair, uniqueness, shared_key, amount_decryption, commitment_mask}, wallet::{ViewPair, uniqueness, shared_key, amount_decryption, commitment_mask},
}; };
@ -61,19 +61,11 @@ impl SpendableOutput {
pub fn deserialize<R: std::io::Read>(r: &mut R) -> std::io::Result<SpendableOutput> { pub fn deserialize<R: std::io::Read>(r: &mut R) -> std::io::Result<SpendableOutput> {
Ok(SpendableOutput { Ok(SpendableOutput {
tx: read_32(r)?, tx: read_bytes(r)?,
o: { o: read_byte(r)?,
let mut o = [0; 1];
r.read_exact(&mut o)?;
o[0]
},
key: read_point(r)?, key: read_point(r)?,
key_offset: read_scalar(r)?, key_offset: read_scalar(r)?,
commitment: Commitment::new(read_scalar(r)?, { commitment: Commitment::new(read_scalar(r)?, read_u64(r)?),
let mut amount = [0; 8];
r.read_exact(&mut amount)?;
u64::from_le_bytes(amount)
}),
}) })
} }
} }