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

View file

@ -50,24 +50,18 @@ impl RctBase {
outputs: usize,
r: &mut R,
) -> std::io::Result<(RctBase, u8)> {
let mut rct_type = [0];
r.read_exact(&mut rct_type)?;
let rct_type = read_byte(r)?;
Ok((
if rct_type[0] == 0 {
if rct_type == 0 {
RctBase { fee: 0, ecdh_info: vec![], commitments: vec![] }
} else {
RctBase {
fee: read_varint(r)?,
ecdh_info: (0 .. outputs)
.map(|_| {
let mut ecdh = [0; 8];
r.read_exact(&mut ecdh).map(|_| ecdh)
})
.collect::<Result<_, _>>()?,
ecdh_info: (0 .. outputs).map(|_| read_bytes(r)).collect::<Result<_, _>>()?,
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)
}
pub fn read_byte<R: io::Read>(r: &mut R) -> io::Result<u8> {
let mut res = [0; 1];
pub fn read_bytes<R: io::Read, const N: usize>(r: &mut R) -> io::Result<[u8; N]> {
let mut res = [0; N];
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> {
@ -72,20 +80,14 @@ pub fn read_varint<R: io::Read>(r: &mut R) -> io::Result<u64> {
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
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"))
}
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)
.decompress()
// 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> {
let mut variant = [0];
r.read_exact(&mut variant)?;
Ok(match variant[0] {
Ok(match read_byte(r)? {
255 => Input::Gen(read_varint(r)?),
2 => Input::ToKey {
amount: read_varint(r)?,
@ -83,9 +81,7 @@ impl Output {
pub fn deserialize<R: std::io::Read>(r: &mut R) -> std::io::Result<Output> {
let amount = read_varint(r)?;
let mut output_type = [0];
r.read_exact(&mut output_type)?;
let view_tag = match output_type[0] {
let view_tag = match read_byte(r)? {
2 => false,
3 => true,
_ => Err(std::io::Error::new(
@ -97,13 +93,7 @@ impl Output {
Ok(Output {
amount,
key: read_point(r)?,
view_tag: if view_tag {
let mut view_tag = [0];
r.read_exact(&mut view_tag)?;
Some(view_tag[0])
} else {
None
},
view_tag: if view_tag { Some(read_byte(r)?) } else { None },
})
}
}
@ -191,11 +181,7 @@ impl TransactionPrefix {
outputs: read_vec(Output::deserialize, r)?,
extra: vec![],
};
let len = read_varint(r)?;
prefix.extra.resize(len.try_into().unwrap(), 0);
r.read_exact(&mut prefix.extra)?;
prefix.extra = read_vec(read_byte, r)?;
Ok(prefix)
}
}

View file

@ -8,7 +8,7 @@ use monero::{consensus::deserialize, blockdata::transaction::ExtraField};
use crate::{
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},
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> {
Ok(SpendableOutput {
tx: read_32(r)?,
o: {
let mut o = [0; 1];
r.read_exact(&mut o)?;
o[0]
},
tx: read_bytes(r)?,
o: read_byte(r)?,
key: read_point(r)?,
key_offset: read_scalar(r)?,
commitment: Commitment::new(read_scalar(r)?, {
let mut amount = [0; 8];
r.read_exact(&mut amount)?;
u64::from_le_bytes(amount)
}),
commitment: Commitment::new(read_scalar(r)?, read_u64(r)?),
})
}
}