node serialization

This commit is contained in:
NikVolf 2019-09-03 17:22:21 +03:00
parent f432983f09
commit d8c04e8143
4 changed files with 73 additions and 12 deletions

View File

@ -9,4 +9,6 @@ assert_matches = "1.3.0"
quickcheck = "0.8"
[dependencies]
derive_more = "0.15"
derive_more = "0.15"
bigint = "4"
byteorder = "1"

View File

@ -5,6 +5,8 @@
#[cfg(test)] #[macro_use] extern crate assert_matches;
#[cfg(test)] #[macro_use] extern crate quickcheck;
extern crate derive_more;
extern crate bigint;
extern crate byteorder;
mod tree;
mod node_data;
@ -53,7 +55,7 @@ impl Entry {
leaves & (leaves - 1) == 0
}
pub fn leaf_count(&self) -> u32 {
pub fn leaf_count(&self) -> u64 {
self.data.end_height - self.data.start_height + 1
}

View File

@ -1,3 +1,7 @@
use byteorder::{LittleEndian, WriteBytesExt};
use bigint::U256;
/// Node metadata.
#[repr(C)]
#[derive(Debug)]
@ -9,13 +13,15 @@ pub struct NodeData {
pub end_target: u32,
pub start_sapling_root: [u8; 32],
pub end_sapling_root: [u8; 32],
pub subtree_total_work: u64,
pub start_height: u32,
pub end_height: u32,
pub subtree_total_work: U256,
pub start_height: u64,
pub end_height: u64,
pub shielded_tx: u64,
}
impl NodeData {
pub const MAX_SERIALIZED_SIZE: usize = 32 + 4 + 4 + 4 + 4 + 32 + 32 + 32 + 9 + 9 + 9; // =171;
pub fn combine(left: &NodeData, right: &NodeData) -> NodeData {
NodeData {
// TODO: hash children
@ -28,10 +34,61 @@ impl NodeData {
end_sapling_root: right.end_sapling_root,
// TODO: sum work?
subtree_total_work: 0,
subtree_total_work: left.subtree_total_work + right.subtree_total_work,
start_height: left.start_height,
end_height: right.end_height,
shielded_tx: left.shielded_tx + right.shielded_tx,
}
}
fn write_compact<W: std::io::Write>(w: &mut W, compact: u64) -> std::io::Result<()> {
match compact {
0..=0xfc => {
w.write_all(&[compact as u8])?
},
0xfd..=0xffff => {
w.write_all(&[0xfd])?;
w.write_u16::<LittleEndian>(compact as u16)?;
},
0x10000..=0xffff_ffff => {
w.write_all(&[0xfe])?;
w.write_u32::<LittleEndian>(compact as u32)?;
},
_ => {
w.write_all(&[0xff])?;
w.write_u64::<LittleEndian>(compact)?;
}
}
Ok(())
}
pub fn write<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
w.write_all(&self.subtree_commitment)?;
w.write_u32::<LittleEndian>(self.start_time)?;
w.write_u32::<LittleEndian>(self.end_time)?;
w.write_u32::<LittleEndian>(self.start_target)?;
w.write_u32::<LittleEndian>(self.end_target)?;
w.write_all(&self.start_sapling_root)?;
w.write_all(&self.end_sapling_root)?;
let mut work_buf = [0u8; 32];
self.subtree_total_work.to_little_endian(&mut work_buf[..]);
w.write_all(&work_buf)?;
Self::write_compact(w, self.start_height)?;
Self::write_compact(w, self.end_height)?;
Self::write_compact(w, self.shielded_tx)?;
Ok(())
}
pub fn to_bytes(&self) -> Vec<u8> {
let mut buf = [0u8; Self::MAX_SERIALIZED_SIZE];
let pos = {
let mut cursor = std::io::Cursor::new(&mut buf[..]);
self.write(&mut cursor).expect("Cursor cannot fail");
cursor.position() as usize
};
buf[0..pos].to_vec()
}
}

View File

@ -292,14 +292,14 @@ mod tests {
end_target: 0,
start_sapling_root: [0u8; 32],
end_sapling_root: [0u8; 32],
subtree_total_work: 0,
start_height: height,
end_height: height,
subtree_total_work: 0.into(),
start_height: height as u64,
end_height: height as u64,
shielded_tx: 7,
}
}
fn node(start_height: u32, end_height: u32) -> NodeData {
fn node(start_height: u64, end_height: u64) -> NodeData {
NodeData {
subtree_commitment: [0u8; 32],
start_time: 0,
@ -308,7 +308,7 @@ mod tests {
end_target: 0,
start_sapling_root: [0u8; 32],
end_sapling_root: [0u8; 32],
subtree_total_work: 0,
subtree_total_work: 0.into(),
start_height: start_height,
end_height: end_height,
shielded_tx: 7,
@ -679,7 +679,7 @@ mod tests {
.node
.leaf_count()
==
number
number as u64
)
}
}