Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node-data: Improve network encoding footprint #1248

Merged
merged 4 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions node-data/src/bls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ pub struct PublicKey {
as_bytes: PublicKeyBytes,
}

impl TryFrom<[u8; 96]> for PublicKey {
type Error = dusk_bls12_381_sign::Error;
fn try_from(bytes: [u8; 96]) -> Result<Self, Self::Error> {
let inner = dusk_bls12_381_sign::PublicKey::from_slice(&bytes)?;
let as_bytes = PublicKeyBytes(bytes);
Ok(Self { as_bytes, inner })
}
}

impl PublicKey {
pub fn new(inner: dusk_bls12_381_sign::PublicKey) -> Self {
let b = inner.to_bytes();
Expand Down
165 changes: 55 additions & 110 deletions node-data/src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ impl Serializable for Block {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
self.header().write(w)?;

Self::write_varint(w, self.txs().len() as u64)?;
let txs_len = self.txs().len() as u32;
w.write_all(&txs_len.to_le_bytes())?;

for t in self.txs().iter() {
t.write(w)?;
Expand All @@ -29,9 +30,9 @@ impl Serializable for Block {
let header = Header::read(r)?;

// Read transactions count
let txlen = Self::read_varint(r)?;
let tx_len = Self::read_u32_le(r)?;

let txs = (0..txlen)
let txs = (0..tx_len)
.map(|_| Transaction::read(r))
.collect::<Result<Vec<_>, _>>()?;

Expand All @@ -42,17 +43,15 @@ impl Serializable for Block {
impl Serializable for Transaction {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
//Write version
w.write_all(&1u32.to_le_bytes())?;
w.write_all(&self.version.to_le_bytes())?;

//Write TxType
w.write_all(&1u32.to_le_bytes())?;
w.write_all(&self.r#type.to_le_bytes())?;

let data = self.inner.to_var_bytes();

// Write inner transaction
let len = data.len() as u32;
w.write_all(&len.to_le_bytes())?;
w.write_all(&data)?;
Self::write_var_le_bytes32(w, &data)?;

Ok(())
}
Expand All @@ -61,13 +60,8 @@ impl Serializable for Transaction {
where
Self: Sized,
{
let mut buf = [0u8; 4];
r.read_exact(&mut buf)?;
let version = u32::from_le_bytes(buf);

let mut buf = [0u8; 4];
r.read_exact(&mut buf)?;
let tx_type = u32::from_le_bytes(buf);
let version = Self::read_u32_le(r)?;
let tx_type = Self::read_u32_le(r)?;

let tx_payload = Self::read_var_le_bytes32(r)?;
let inner = phoenix_core::Transaction::from_slice(&tx_payload[..])
Expand All @@ -90,7 +84,7 @@ impl Serializable for SpentTransaction {
match &self.err {
Some(e) => {
let b = e.as_bytes();
w.write_all(&(b.len() as u64).to_le_bytes())?;
w.write_all(&(b.len() as u32).to_le_bytes())?;
w.write_all(b)?;
}
None => {
Expand All @@ -107,18 +101,9 @@ impl Serializable for SpentTransaction {
{
let inner = Transaction::read(r)?;

let mut buf = [0u8; 8];
r.read_exact(&mut buf)?;
let block_height = u64::from_le_bytes(buf);

let mut buf = [0u8; 8];
r.read_exact(&mut buf)?;
let gas_spent = u64::from_le_bytes(buf);

let mut buf = [0u8; 8];
r.read_exact(&mut buf)?;

let error_len = u64::from_le_bytes(buf);
let block_height = Self::read_u64_le(r)?;
let gas_spent = Self::read_u64_le(r)?;
let error_len = Self::read_u32_le(r)?;

let err = if error_len > 0 {
let mut buf = vec![0u8; error_len as usize];
Expand All @@ -140,9 +125,9 @@ impl Serializable for SpentTransaction {

impl Serializable for Header {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
self.marshal_hashable(w, false)?;
self.marshal_hashable(w)?;
self.cert.write(w)?;
w.write_all(&self.hash[..])?;
w.write_all(&self.hash)?;

Ok(())
}
Expand All @@ -153,26 +138,15 @@ impl Serializable for Header {
{
let mut header = Self::unmarshal_hashable(r)?;
header.cert = Certificate::read(r)?;
r.read_exact(&mut header.hash[..])?;
header.hash = Self::read_bytes(r)?;
Ok(header)
}
}

impl Serializable for Certificate {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
// In order to be aligned with golang impl,
// we cannot use here StepVotes::write for now.
Self::write_var_bytes(
w,
&self.validation.aggregate_signature.inner()[..],
)?;
Self::write_var_bytes(
w,
&self.ratification.aggregate_signature.inner()[..],
)?;

w.write_all(&self.validation.bitset.to_le_bytes())?;
w.write_all(&self.ratification.bitset.to_le_bytes())?;
self.validation.write(w)?;
self.ratification.write(w)?;

Ok(())
}
Expand All @@ -181,39 +155,20 @@ impl Serializable for Certificate {
where
Self: Sized,
{
let validation_signature: [u8; 48] = Self::read_var_bytes(r)?
.try_into()
.map_err(|_| io::Error::from(io::ErrorKind::InvalidData))?;

let ratification_signature: [u8; 48] = Self::read_var_bytes(r)?
.try_into()
.map_err(|_| io::Error::from(io::ErrorKind::InvalidData))?;

let mut buf = [0u8; 8];
r.read_exact(&mut buf)?;
let validation_bitset = u64::from_le_bytes(buf);

let mut buf = [0u8; 8];
r.read_exact(&mut buf)?;
let ratification_bitset = u64::from_le_bytes(buf);
let validation = StepVotes::read(r)?;
let ratification = StepVotes::read(r)?;

Ok(Certificate {
validation: StepVotes {
bitset: validation_bitset,
aggregate_signature: Signature(validation_signature),
},
ratification: StepVotes {
bitset: ratification_bitset,
aggregate_signature: Signature(ratification_signature),
},
validation,
ratification,
})
}
}

impl Serializable for StepVotes {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
w.write_all(&self.bitset.to_le_bytes())?;
Self::write_var_bytes(w, &self.aggregate_signature.inner()[..])?;
w.write_all(&self.aggregate_signature.inner())?;

Ok(())
}
Expand All @@ -222,14 +177,11 @@ impl Serializable for StepVotes {
where
Self: Sized,
{
let mut buf = [0u8; 8];
r.read_exact(&mut buf[..])?;
let aggregate_signature: [u8; 48] = Self::read_var_bytes(r)?
.try_into()
.map_err(|_| io::Error::from(io::ErrorKind::InvalidData))?;
let bitset = Self::read_u64_le(r)?;
let aggregate_signature = Self::read_bytes(r)?;

Ok(StepVotes {
bitset: u64::from_le_bytes(buf),
bitset,
aggregate_signature: Signature(aggregate_signature),
})
}
Expand Down Expand Up @@ -259,15 +211,12 @@ impl Serializable for IterationsInfo {
{
let mut cert_list = vec![];

let mut buf = [0u8; 1];
r.read_exact(&mut buf[..])?;
let count = buf[0];
let count = Self::read_u8(r)?;

for _ in 0..count {
let mut opt = [0u8; 1];
r.read_exact(&mut opt[..])?;
let opt = Self::read_u8(r)?;

let cert = match opt[0] {
let cert = match opt {
0 => None,
1 => Some(Certificate::read(r)?),
_ => {
Expand Down Expand Up @@ -307,16 +256,14 @@ impl Serializable for Label {
where
Self: Sized,
{
let mut buf = [0u8; 1];
r.read_exact(&mut buf[..])?;

Ok(buf[0].into())
let label = Self::read_u8(r)?;
Ok(label.into())
}
}

impl Serializable for Ratification {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
Self::write_var_bytes(w, &self.signature[..])?;
w.write_all(&self.signature)?;
self.validation_result.write(w)?;

Ok(())
Expand All @@ -326,9 +273,7 @@ impl Serializable for Ratification {
where
Self: Sized,
{
let signature: [u8; 48] = Self::read_var_bytes(r)?
.try_into()
.map_err(|_| io::Error::from(io::ErrorKind::InvalidData))?;
let signature = Self::read_bytes(r)?;

let validation_result = ValidationResult::read(r)?;

Expand All @@ -342,7 +287,7 @@ impl Serializable for Ratification {
impl Serializable for ValidationResult {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
self.sv.write(w)?;
w.write_all(&self.hash[..])?;
w.write_all(&self.hash)?;
self.quorum.write(w)?;

Ok(())
Expand All @@ -353,10 +298,7 @@ impl Serializable for ValidationResult {
Self: Sized,
{
let sv = StepVotes::read(r)?;

let mut hash = [0u8; 32];
r.read_exact(&mut hash)?;

let hash = Self::read_bytes(r)?;
let quorum = QuorumType::read(r)?;

Ok(ValidationResult { sv, hash, quorum })
Expand All @@ -365,34 +307,22 @@ impl Serializable for ValidationResult {

impl Serializable for QuorumType {
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
match self {
QuorumType::ValidQuorum => w.write_all(&0u8.to_le_bytes())?,
QuorumType::InvalidQuorum => w.write_all(&1u8.to_le_bytes())?,
QuorumType::NilQuorum => w.write_all(&2u8.to_le_bytes())?,
_ => w.write_all(&255u8.to_le_bytes())?,
}

Ok(())
let val: u8 = *self as u8;
w.write_all(&val.to_le_bytes())
}

fn read<R: Read>(r: &mut R) -> io::Result<Self>
where
Self: Sized,
{
let mut buf = [0u8; 1];
r.read_exact(&mut buf)?;

Ok(match buf[0] {
0 => QuorumType::ValidQuorum,
1 => QuorumType::InvalidQuorum,
2 => QuorumType::NilQuorum,
_ => QuorumType::NoQuorum,
})
Ok(Self::read_u8(r)?.into())
}
}

#[cfg(test)]
mod tests {
use crate::message::payload::{Candidate, Validation};

use super::*;
use fake::{Dummy, Fake, Faker};

Expand All @@ -411,6 +341,21 @@ mod tests {
assert_serializable::<IterationsInfo>();
}

#[test]
fn test_encoding_ratification() {
assert_serializable::<Ratification>();
}

#[test]
fn test_encoding_validation() {
assert_serializable::<Validation>();
}

#[test]
fn test_encoding_candidate() {
assert_serializable::<Candidate>();
}

#[test]
fn test_encoding_cert() {
assert_serializable::<Certificate>();
Expand Down
Loading