saito_core/core/consensus/
ringitem.rs1use crate::core::defs::SaitoHash;
2
3#[derive(Debug, Default)]
12pub struct RingItem {
13 pub lc_pos: Option<usize>,
14 pub block_hashes: Vec<SaitoHash>,
15 pub block_ids: Vec<u64>,
16}
17
18impl RingItem {
19 pub fn add_block(&mut self, block_id: u64, hash: SaitoHash) {
20 self.block_hashes.push(hash);
21 self.block_ids.push(block_id);
22 }
23
24 pub fn contains_block_hash(&self, hash: SaitoHash) -> bool {
25 self.block_hashes.iter().any(|&i| i == hash)
26 }
27
28 pub fn delete_block(&mut self, block_id: u64, hash: SaitoHash) {
29 let mut new_block_hashes: Vec<SaitoHash> = vec![];
30 let mut new_block_ids: Vec<u64> = vec![];
31 let mut index_loop = 0;
32 let mut new_lc_pos = Some(0);
33
34 for i in 0..self.block_ids.len() {
35 if self.block_ids[i] == block_id && self.block_hashes[i] == hash {
36 } else {
37 new_block_hashes.push(self.block_hashes[i]);
38 new_block_ids.push(self.block_ids[i]);
39 if self.lc_pos == Some(i) {
40 new_lc_pos = Some(index_loop);
41 }
42 index_loop += 1;
43 }
44 }
45
46 self.block_hashes = new_block_hashes;
47 self.block_ids = new_block_ids;
48 self.lc_pos = new_lc_pos;
49 }
50
51 pub fn on_chain_reorganization(&mut self, hash: SaitoHash, lc: bool) {
52 if !lc {
53 self.lc_pos = None;
54 } else {
55 self.lc_pos = self.block_hashes.iter().position(|b_hash| b_hash == &hash);
56 }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62
63 use crate::core::consensus::block::Block;
64 use crate::core::consensus::ringitem::RingItem;
65
66 #[test]
67 fn ringitem_new_test() {
68 let ringitem = RingItem::default();
69 assert_eq!(ringitem.block_hashes.len() as u64, 0);
70 assert_eq!(ringitem.block_ids.len() as u64, 0);
71 assert_eq!(ringitem.lc_pos, None);
72 }
73
74 #[test]
75 fn ringitem_add_and_delete_block() {
76 let mut ringitem = RingItem::default();
77 let mut block = Block::new();
78 block.generate_hash();
79 let block_id = block.id;
80 let block_hash = block.hash;
81
82 assert_eq!(ringitem.contains_block_hash(block_hash), false);
83 assert_eq!(ringitem.block_hashes.len() as u64, 0);
84 assert_eq!(ringitem.block_ids.len() as u64, 0);
85
86 ringitem.add_block(block.id, block.hash);
87
88 assert_eq!(ringitem.contains_block_hash(block_hash), true);
89 assert_eq!(ringitem.block_hashes.len() as u64, 1);
90 assert_eq!(ringitem.block_ids.len() as u64, 1);
91
92 ringitem.delete_block(block_id, block_hash);
93
94 assert_eq!(ringitem.contains_block_hash(block_hash), false);
95 assert_eq!(ringitem.block_hashes.len() as u64, 0);
96 assert_eq!(ringitem.block_ids.len() as u64, 0);
97 }
98}