mithril_cardano_node_chain/entities/
raw_cardano_point.rs1use pallas_network::miniprotocols::Point as PallasPoint;
2use std::fmt::{Debug, Formatter};
3
4use mithril_common::entities::{ChainPoint, SlotNumber};
5
6use crate::entities::ScannedBlock;
7
8#[derive(Clone, PartialEq)]
10pub struct RawCardanoPoint {
11 pub slot_number: SlotNumber,
13
14 pub block_hash: Vec<u8>,
16}
17
18impl RawCardanoPoint {
19 pub fn new<T: Into<Vec<u8>>>(slot_number: SlotNumber, block_hash: T) -> Self {
21 RawCardanoPoint {
22 slot_number,
23 block_hash: block_hash.into(),
24 }
25 }
26
27 pub fn origin() -> Self {
29 RawCardanoPoint {
30 slot_number: SlotNumber(0),
31 block_hash: Vec::new(),
32 }
33 }
34
35 pub fn is_origin(&self) -> bool {
37 self.slot_number == 0 && self.block_hash.is_empty()
38 }
39}
40
41impl From<&ChainPoint> for RawCardanoPoint {
42 fn from(point: &ChainPoint) -> Self {
43 RawCardanoPoint {
44 slot_number: point.slot_number,
45 block_hash: hex::decode(&point.block_hash).unwrap(),
46 }
47 }
48}
49
50impl From<ChainPoint> for RawCardanoPoint {
51 fn from(point: ChainPoint) -> Self {
52 Self::from(&point)
53 }
54}
55
56impl Debug for RawCardanoPoint {
57 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
58 let mut debug = f.debug_struct("RawCardanoPoint");
59 debug
60 .field("slot_number", &self.slot_number)
61 .field("block_hash", &hex::encode(&self.block_hash))
62 .finish()
63 }
64}
65
66impl From<RawCardanoPoint> for PallasPoint {
67 fn from(raw_point: RawCardanoPoint) -> Self {
68 match raw_point.is_origin() {
69 true => Self::Origin,
70 false => Self::Specific(*raw_point.slot_number, raw_point.block_hash),
71 }
72 }
73}
74
75impl From<PallasPoint> for RawCardanoPoint {
76 fn from(point: PallasPoint) -> Self {
77 match point {
78 PallasPoint::Specific(slot_number, block_hash) => Self {
79 slot_number: SlotNumber(slot_number),
80 block_hash,
81 },
82 PallasPoint::Origin => Self::origin(),
83 }
84 }
85}
86
87impl From<&ScannedBlock> for RawCardanoPoint {
88 fn from(scanned_block: &ScannedBlock) -> Self {
89 RawCardanoPoint {
90 slot_number: scanned_block.slot_number,
91 block_hash: scanned_block.block_hash.clone(),
92 }
93 }
94}
95
96impl From<ScannedBlock> for RawCardanoPoint {
97 fn from(scanned_block: ScannedBlock) -> Self {
98 Self::from(&scanned_block)
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use mithril_common::entities::BlockNumber;
105
106 use super::*;
107
108 #[test]
109 fn from_chain_point_to_raw_cardano_point_conversions() {
110 let expected_hash = vec![4, 2, 12, 9, 7];
111 let chain_point =
112 ChainPoint::new(SlotNumber(8), BlockNumber(23), hex::encode(&expected_hash));
113
114 assert_eq!(
115 RawCardanoPoint::new(SlotNumber(8), expected_hash.clone()),
116 RawCardanoPoint::from(&chain_point)
117 );
118 assert_eq!(
119 RawCardanoPoint::new(SlotNumber(8), expected_hash.clone()),
120 RawCardanoPoint::from(chain_point)
121 );
122 }
123
124 #[test]
125 fn from_scanned_block_to_raw_cardano_point_conversions() {
126 let expected_hash = vec![7, 1, 13, 7, 8];
127 let scanned_block = ScannedBlock::new(
128 expected_hash.clone(),
129 BlockNumber(31),
130 SlotNumber(4),
131 Vec::<&str>::new(),
132 );
133 assert_eq!(
134 RawCardanoPoint::new(SlotNumber(4), expected_hash.clone()),
135 RawCardanoPoint::from(&scanned_block)
136 );
137 assert_eq!(
138 RawCardanoPoint::new(SlotNumber(4), expected_hash.clone()),
139 RawCardanoPoint::from(scanned_block)
140 );
141 }
142}