1use crate::{errors::Result, ids, packer::Packer, txs::raw};
3
4#[derive(Debug, Clone, Eq, PartialEq)]
8pub struct Vertex {
9 pub codec_version: u16,
10 pub chain_id: ids::Id,
11 pub height: u64,
12 pub epoch: u32,
13 pub parent_ids: Vec<ids::Id>,
14 pub txs: Vec<Vec<u8>>,
15}
16
17impl Packer {
18 pub fn pack_vertex(&self, vtx: &mut Vertex) -> Result<()> {
22 vtx.parent_ids.sort();
25
26 vtx.txs.sort_by(|a, b| {
29 (raw::Data::from_slice(a.as_ref())).cmp(&raw::Data::from_slice(b.as_ref()))
30 });
31
32 self.pack_u16(vtx.codec_version)?;
33 self.pack_bytes(vtx.chain_id.as_ref())?;
34 self.pack_u64(vtx.height)?;
35 self.pack_u32(vtx.epoch)?;
36
37 self.pack_u32(vtx.parent_ids.len() as u32)?;
38 for id in vtx.parent_ids.iter() {
39 self.pack_bytes(id.as_ref())?;
40 }
41
42 self.pack_u32(vtx.txs.len() as u32)?;
43 for tx in vtx.txs.iter() {
44 self.pack_bytes_with_header(tx.as_ref())?;
45 }
46
47 Ok(())
48 }
49
50 pub fn unpack_vertex(&self) -> Result<Vertex> {
54 let codec_version = self.unpack_u16()?;
55
56 let chain_id = self.unpack_bytes(ids::LEN)?;
57 let chain_id = ids::Id::from_slice(chain_id.as_ref());
58
59 let height = self.unpack_u64()?;
60 let epoch = self.unpack_u32()?;
61
62 let parent_ids_size = self.unpack_u32()?;
63 let mut parent_ids: Vec<ids::Id> = Vec::new();
64 for _ in 0..parent_ids_size {
65 let parent_id = self.unpack_bytes(ids::LEN)?;
66 let parent_id = ids::Id::from_slice(parent_id.as_ref());
67 parent_ids.push(parent_id);
68 }
69
70 let txs_size = self.unpack_u32()?;
71 let mut txs: Vec<Vec<u8>> = Vec::new();
72 for _ in 0..txs_size {
73 let tx_size = self.unpack_u32()?;
74 let tx = self.unpack_bytes(tx_size as usize)?;
75 txs.push(tx);
76 }
77
78 Ok(Vertex {
79 codec_version,
80 chain_id,
81 height,
82 epoch,
83 parent_ids,
84 txs,
85 })
86 }
87}
88
89#[test]
91fn test_pack_and_unpack() {
92 use bytes::BytesMut;
93
94 let mut vtx = Vertex {
95 codec_version: 0_u16,
96 chain_id: ids::Id::from_slice(&<Vec<u8>>::from([
97 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,
101 ])),
102 height: 1234567_u64,
103 epoch: 0,
104
105 parent_ids: vec![
107 ids::Id::from_slice(&<Vec<u8>>::from([
108 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,
112 ])),
113 ids::Id::from_slice(&<Vec<u8>>::from([
114 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,
118 ])),
119 ids::Id::from_slice(&<Vec<u8>>::from([
120 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,
124 ])),
125 ],
126
127 txs: vec![
129 <Vec<u8>>::from([0x01]),
130 <Vec<u8>>::from([0x02]),
131 <Vec<u8>>::from([0x03]),
132 ],
133 };
134
135 let packer = Packer::new(1024, 0);
136 packer.pack_vertex(&mut vtx).unwrap();
137
138 let vtx_sorted = Vertex {
139 codec_version: 0_u16,
140 chain_id: ids::Id::from_slice(&<Vec<u8>>::from([
141 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,
145 ])),
146 height: 1234567_u64,
147 epoch: 0,
148
149 parent_ids: vec![
151 ids::Id::from_slice(&<Vec<u8>>::from([
152 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,
156 ])),
157 ids::Id::from_slice(&<Vec<u8>>::from([
158 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,
162 ])),
163 ids::Id::from_slice(&<Vec<u8>>::from([
164 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,
168 ])),
169 ],
170
171 txs: vec![
173 <Vec<u8>>::from([0x03]),
174 <Vec<u8>>::from([0x01]),
175 <Vec<u8>>::from([0x02]),
176 ],
177 };
178 assert!(vtx == vtx_sorted);
179
180 let b = packer.take_bytes();
181 let b = BytesMut::from(&b[..]);
182
183 let packer = Packer::new(0, 0);
184 packer.set_bytes(&b);
185
186 let vtx_unpacked = packer.unpack_vertex().unwrap();
187 assert!(vtx == vtx_unpacked);
188}