mithril_cardano_node_chain/entities/
scanned_block.rs1use pallas_traverse::MultiEraBlock;
2use std::fmt::{Debug, Formatter};
3
4use mithril_common::entities::{
5 BlockHash, BlockNumber, CardanoBlockWithTransactions, CardanoTransaction, ChainPoint,
6 SlotNumber, TransactionHash,
7};
8
9#[derive(Clone, PartialEq)]
11pub struct ScannedBlock {
12 pub block_hash: Vec<u8>,
14 pub block_number: BlockNumber,
16 pub slot_number: SlotNumber,
18 pub transactions_hashes: Vec<TransactionHash>,
20}
21
22impl ScannedBlock {
23 pub fn new<B: Into<Vec<u8>>, T: Into<TransactionHash>>(
25 block_hash: B,
26 block_number: BlockNumber,
27 slot_number: SlotNumber,
28 transaction_hashes: Vec<T>,
29 ) -> Self {
30 Self {
31 block_hash: block_hash.into(),
32 block_number,
33 slot_number,
34 transactions_hashes: transaction_hashes.into_iter().map(|h| h.into()).collect(),
35 }
36 }
37
38 pub(crate) fn convert(multi_era_block: MultiEraBlock) -> Self {
39 let mut transactions = Vec::new();
40 for tx in &multi_era_block.txs() {
41 transactions.push(tx.hash().to_string());
42 }
43
44 Self::new(
45 *multi_era_block.hash(),
46 BlockNumber(multi_era_block.number()),
47 SlotNumber(multi_era_block.slot()),
48 transactions,
49 )
50 }
51
52 pub fn transactions_len(&self) -> usize {
54 self.transactions_hashes.len()
55 }
56
57 pub fn block_hash_hex(&self) -> BlockHash {
59 hex::encode(&self.block_hash)
60 }
61
62 pub fn into_transactions(self) -> Vec<CardanoTransaction> {
66 let block_hash = self.block_hash_hex();
67 self.transactions_hashes
68 .into_iter()
69 .map(|transaction_hash| {
70 CardanoTransaction::new(
71 transaction_hash,
72 self.block_number,
73 self.slot_number,
74 block_hash.clone(),
75 )
76 })
77 .collect::<Vec<_>>()
78 }
79}
80
81impl Debug for ScannedBlock {
82 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
83 let mut debug = f.debug_struct("ScannedBlock");
84 debug
85 .field("block_hash", &self.block_hash_hex())
86 .field("block_number", &self.block_number)
87 .field("slot_number", &self.slot_number)
88 .field("transactions_hashes", &self.transactions_hashes)
89 .finish()
90 }
91}
92
93impl From<&ScannedBlock> for ChainPoint {
94 fn from(scanned_block: &ScannedBlock) -> Self {
95 ChainPoint::new(
96 scanned_block.slot_number,
97 scanned_block.block_number,
98 scanned_block.block_hash_hex(),
99 )
100 }
101}
102
103impl From<ScannedBlock> for CardanoBlockWithTransactions {
104 fn from(value: ScannedBlock) -> Self {
105 CardanoBlockWithTransactions::new(
106 value.block_hash_hex(),
107 value.block_number,
108 value.slot_number,
109 value.transactions_hashes,
110 )
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn block_hash_hex() {
120 let block = ScannedBlock::new(
121 vec![1, 2, 3],
122 BlockNumber(10),
123 SlotNumber(50),
124 vec!["tx_hash"],
125 );
126 assert_eq!("010203", block.block_hash_hex());
127 }
128}