mithril_common/cardano_block_scanner/
raw_cardano_point.rs

1#[cfg(feature = "fs")]
2use pallas_network::miniprotocols::Point as PallasPoint;
3use std::fmt::{Debug, Formatter};
4
5use crate::cardano_block_scanner::ScannedBlock;
6use crate::entities::{ChainPoint, SlotNumber};
7
8/// Point internal representation in the Cardano chain.
9#[derive(Clone, PartialEq)]
10pub struct RawCardanoPoint {
11    /// The [slot number](https://docs.cardano.org/learn/cardano-node/#slotsandepochs)
12    pub slot_number: SlotNumber,
13
14    /// Hex array of the block hash
15    pub block_hash: Vec<u8>,
16}
17
18impl RawCardanoPoint {
19    /// Instantiate a new `RawCardanoPoint`
20    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    /// Create a new origin `RawCardanoPoint`
28    pub fn origin() -> Self {
29        RawCardanoPoint {
30            slot_number: SlotNumber(0),
31            block_hash: Vec::new(),
32        }
33    }
34
35    /// Check if origin
36    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
66cfg_fs! {
67    impl From<RawCardanoPoint> for PallasPoint {
68        fn from(raw_point: RawCardanoPoint) -> Self {
69            match raw_point.is_origin() {
70                true => Self::Origin,
71                false => Self::Specific(
72                    *raw_point.slot_number,
73                    raw_point.block_hash
74                ),
75            }
76        }
77    }
78
79    impl From<PallasPoint> for RawCardanoPoint {
80        fn from(point: PallasPoint) -> Self {
81            match point {
82                PallasPoint::Specific(slot_number, block_hash) => Self {
83                    slot_number: SlotNumber(slot_number),
84                    block_hash,
85                },
86                PallasPoint::Origin => Self::origin(),
87            }
88        }
89    }
90}
91
92impl From<&ScannedBlock> for RawCardanoPoint {
93    fn from(scanned_block: &ScannedBlock) -> Self {
94        RawCardanoPoint {
95            slot_number: scanned_block.slot_number,
96            block_hash: scanned_block.block_hash.clone(),
97        }
98    }
99}
100
101impl From<ScannedBlock> for RawCardanoPoint {
102    fn from(scanned_block: ScannedBlock) -> Self {
103        Self::from(&scanned_block)
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use crate::entities::BlockNumber;
110
111    use super::*;
112
113    #[test]
114    fn from_chain_point_to_raw_cardano_point_conversions() {
115        let expected_hash = vec![4, 2, 12, 9, 7];
116        let chain_point =
117            ChainPoint::new(SlotNumber(8), BlockNumber(23), hex::encode(&expected_hash));
118
119        assert_eq!(
120            RawCardanoPoint::new(SlotNumber(8), expected_hash.clone()),
121            RawCardanoPoint::from(&chain_point)
122        );
123        assert_eq!(
124            RawCardanoPoint::new(SlotNumber(8), expected_hash.clone()),
125            RawCardanoPoint::from(chain_point)
126        );
127    }
128
129    #[test]
130    fn from_scanned_block_to_raw_cardano_point_conversions() {
131        let expected_hash = vec![7, 1, 13, 7, 8];
132        let scanned_block = ScannedBlock::new(
133            expected_hash.clone(),
134            BlockNumber(31),
135            SlotNumber(4),
136            Vec::<&str>::new(),
137        );
138        assert_eq!(
139            RawCardanoPoint::new(SlotNumber(4), expected_hash.clone()),
140            RawCardanoPoint::from(&scanned_block)
141        );
142        assert_eq!(
143            RawCardanoPoint::new(SlotNumber(4), expected_hash.clone()),
144            RawCardanoPoint::from(scanned_block)
145        );
146    }
147}