saito_core/core/msg/
ghost_chain_sync.rs1use crate::core::defs::{PrintForLog, SaitoHash, Timestamp};
2use std::fmt::{Debug, Formatter};
3
4pub struct GhostChainSync {
5 pub start: SaitoHash,
6 pub prehashes: Vec<SaitoHash>,
7 pub previous_block_hashes: Vec<SaitoHash>,
8 pub block_ids: Vec<u64>,
9 pub block_ts: Vec<Timestamp>,
10 pub txs: Vec<bool>,
11 pub gts: Vec<bool>,
12}
13
14impl GhostChainSync {
15 pub fn serialize(&self) -> Vec<u8> {
16 [
17 self.start.as_slice(),
18 (self.prehashes.len() as u32).to_be_bytes().as_slice(),
19 self.prehashes.concat().as_slice(),
20 self.previous_block_hashes.concat().as_slice(),
21 self.block_ids
22 .iter()
23 .map(|id| id.to_be_bytes().to_vec())
24 .collect::<Vec<Vec<u8>>>()
25 .concat()
26 .as_slice(),
27 self.block_ts
28 .iter()
29 .map(|id| id.to_be_bytes().to_vec())
30 .collect::<Vec<Vec<u8>>>()
31 .concat()
32 .as_slice(),
33 self.txs
34 .iter()
35 .map(|id| (*id as u8).to_be_bytes().to_vec())
36 .collect::<Vec<Vec<u8>>>()
37 .concat()
38 .as_slice(),
39 self.gts
40 .iter()
41 .map(|id| (*id as u8).to_be_bytes().to_vec())
42 .collect::<Vec<Vec<u8>>>()
43 .concat()
44 .as_slice(),
45 ]
46 .concat()
47 }
48 pub fn deserialize(buffer: Vec<u8>) -> GhostChainSync {
49 let start: SaitoHash = buffer[0..32].to_vec().try_into().unwrap();
50 let count: usize = u32::from_be_bytes(buffer[32..36].try_into().unwrap()) as usize;
51 let mut prehashes: Vec<SaitoHash> = vec![];
52 let mut previous_block_hashes = vec![];
53 let mut block_ids = vec![];
54 let mut block_ts = vec![];
55 let mut txs = vec![];
56 let mut gts = vec![];
57
58 let buffer = &buffer[36..buffer.len()];
59 let buf = buffer[0..(count * 32)].to_vec();
60 for i in 0..count {
61 prehashes.push(buf[i * 32..(i + 1) * 32].try_into().unwrap());
62 }
63 let buf = buffer[(count * 32)..(count * 64)].to_vec();
64 for i in 0..count {
65 previous_block_hashes.push(buf[i * 32..(i + 1) * 32].try_into().unwrap());
66 }
67 let buf = buffer[(count * 64)..(count * 72)].to_vec();
68 for i in 0..count {
69 block_ids.push(u64::from_be_bytes(
70 buf[i * 8..(i + 1) * 8].try_into().unwrap(),
71 ));
72 }
73 let buf = buffer[(count * 72)..(count * 80)].to_vec();
74 for i in 0..count {
75 block_ts.push(Timestamp::from_be_bytes(
76 buf[i * 8..(i + 1) * 8].try_into().unwrap(),
77 ));
78 }
79 let buf = buffer[(count * 80)..(count * 81)].to_vec();
80 for i in 0..count {
81 txs.push(buf[i] != 0);
82 }
83 let buf = buffer[(count * 81)..(count * 82)].to_vec();
84 for i in 0..count {
85 gts.push(buf[i] != 0);
86 }
87
88 GhostChainSync {
89 start,
90 prehashes,
91 previous_block_hashes,
92 block_ids,
93 block_ts,
94 txs,
95 gts,
96 }
97 }
98}
99
100impl Debug for GhostChainSync {
101 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
102 f.debug_struct("GhostChainSync")
103 .field("start", &self.start.to_hex())
104 .field(
105 "prehashes",
106 &self
107 .prehashes
108 .iter()
109 .map(|h| h.to_hex())
110 .collect::<Vec<String>>(),
111 )
112 .field(
113 "prev_block_hashes",
114 &self
115 .previous_block_hashes
116 .iter()
117 .map(|h| h.to_hex())
118 .collect::<Vec<String>>(),
119 )
120 .field("block_ids", &self.block_ids)
121 .field("block_ts", &self.block_ts)
122 .field("txs", &self.txs)
123 .field("gts", &self.gts)
124 .finish()
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use crate::core::msg::ghost_chain_sync::GhostChainSync;
131
132 #[test]
133 fn serialize_test() {
134 let chain = GhostChainSync {
135 start: [1; 32],
136 prehashes: vec![[2; 32], [3; 32]],
137 previous_block_hashes: vec![[4; 32], [5; 32]],
138 block_ids: vec![10, 20],
139 block_ts: vec![100, 200],
140 txs: vec![false, true],
141 gts: vec![true, false],
142 };
143 let buffer = chain.serialize();
144 let chain2 = GhostChainSync::deserialize(buffer);
145 assert_eq!(chain.start, chain2.start);
146 assert_eq!(chain.prehashes, chain2.prehashes);
147 assert_eq!(chain.previous_block_hashes, chain2.previous_block_hashes);
148 assert_eq!(chain.block_ids, chain2.block_ids);
149 assert_eq!(chain.block_ts, chain2.block_ts);
150 assert_eq!(chain.txs, chain2.txs);
151 assert_eq!(chain.gts, chain2.gts);
152 }
153}