use crate::{errors::Result, ids, packer::Packer, txs::raw};
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Vertex {
pub codec_version: u16,
pub chain_id: ids::Id,
pub height: u64,
pub epoch: u32,
pub parent_ids: Vec<ids::Id>,
pub txs: Vec<Vec<u8>>,
}
impl Packer {
pub fn pack_vertex(&self, vtx: &mut Vertex) -> Result<()> {
vtx.parent_ids.sort();
vtx.txs.sort_by(|a, b| {
(raw::Data::from_slice(a.as_ref())).cmp(&raw::Data::from_slice(b.as_ref()))
});
self.pack_u16(vtx.codec_version)?;
self.pack_bytes(vtx.chain_id.as_ref())?;
self.pack_u64(vtx.height)?;
self.pack_u32(vtx.epoch)?;
self.pack_u32(vtx.parent_ids.len() as u32)?;
for id in vtx.parent_ids.iter() {
self.pack_bytes(id.as_ref())?;
}
self.pack_u32(vtx.txs.len() as u32)?;
for tx in vtx.txs.iter() {
self.pack_bytes_with_header(tx.as_ref())?;
}
Ok(())
}
pub fn unpack_vertex(&self) -> Result<Vertex> {
let codec_version = self.unpack_u16()?;
let chain_id = self.unpack_bytes(ids::LEN)?;
let chain_id = ids::Id::from_slice(chain_id.as_ref());
let height = self.unpack_u64()?;
let epoch = self.unpack_u32()?;
let parent_ids_size = self.unpack_u32()?;
let mut parent_ids: Vec<ids::Id> = Vec::new();
for _ in 0..parent_ids_size {
let parent_id = self.unpack_bytes(ids::LEN)?;
let parent_id = ids::Id::from_slice(parent_id.as_ref());
parent_ids.push(parent_id);
}
let txs_size = self.unpack_u32()?;
let mut txs: Vec<Vec<u8>> = Vec::new();
for _ in 0..txs_size {
let tx_size = self.unpack_u32()?;
let tx = self.unpack_bytes(tx_size as usize)?;
txs.push(tx);
}
Ok(Vertex {
codec_version,
chain_id,
height,
epoch,
parent_ids,
txs,
})
}
}
#[test]
fn test_pack_and_unpack() {
use bytes::BytesMut;
let mut vtx = Vertex {
codec_version: 0_u16,
chain_id: ids::Id::from_slice(&<Vec<u8>>::from([
0x3d, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
])),
height: 1234567_u64,
epoch: 0,
parent_ids: vec![
ids::Id::from_slice(&<Vec<u8>>::from([
0x03, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
])),
ids::Id::from_slice(&<Vec<u8>>::from([
0x02, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
])),
ids::Id::from_slice(&<Vec<u8>>::from([
0x01, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
])),
],
txs: vec![
<Vec<u8>>::from([0x01]),
<Vec<u8>>::from([0x02]),
<Vec<u8>>::from([0x03]),
],
};
let packer = Packer::new(1024, 0);
packer.pack_vertex(&mut vtx).unwrap();
let vtx_sorted = Vertex {
codec_version: 0_u16,
chain_id: ids::Id::from_slice(&<Vec<u8>>::from([
0x3d, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
])),
height: 1234567_u64,
epoch: 0,
parent_ids: vec![
ids::Id::from_slice(&<Vec<u8>>::from([
0x01, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
])),
ids::Id::from_slice(&<Vec<u8>>::from([
0x02, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
])),
ids::Id::from_slice(&<Vec<u8>>::from([
0x03, 0x0a, 0xd1, 0x2b, 0x8e, 0xe8, 0x92, 0x8e, 0xdf, 0x24, 0x8c, 0xa9, 0x1c, 0xa5, 0x56, 0x00, 0xfb, 0x38, 0x3f, 0x07, 0xc3, 0x2b, 0xff, 0x1d, 0x6d, 0xec, 0x47, 0x2b, 0x25, 0xcf, 0x59, 0xa7,
])),
],
txs: vec![
<Vec<u8>>::from([0x03]),
<Vec<u8>>::from([0x01]),
<Vec<u8>>::from([0x02]),
],
};
assert!(vtx == vtx_sorted);
let b = packer.take_bytes();
let b = BytesMut::from(&b[..]);
let packer = Packer::new(0, 0);
packer.set_bytes(&b);
let vtx_unpacked = packer.unpack_vertex().unwrap();
assert!(vtx == vtx_unpacked);
}