mithril_common/cardano_block_scanner/
scanned_block.rs

1use pallas_traverse::MultiEraBlock;
2use std::fmt::{Debug, Formatter};
3
4use crate::entities::{BlockNumber, CardanoTransaction, ChainPoint, SlotNumber, TransactionHash};
5
6/// A block scanned from a Cardano database
7#[derive(Clone, PartialEq)]
8pub struct ScannedBlock {
9    /// Block hash
10    pub block_hash: Vec<u8>,
11    /// Block number
12    pub block_number: BlockNumber,
13    /// Slot number of the block
14    pub slot_number: SlotNumber,
15    /// Hashes of the transactions in the block
16    pub transactions_hashes: Vec<TransactionHash>,
17}
18
19impl ScannedBlock {
20    /// Scanned block factory
21    pub fn new<B: Into<Vec<u8>>, T: Into<TransactionHash>>(
22        block_hash: B,
23        block_number: BlockNumber,
24        slot_number: SlotNumber,
25        transaction_hashes: Vec<T>,
26    ) -> Self {
27        Self {
28            block_hash: block_hash.into(),
29            block_number,
30            slot_number,
31            transactions_hashes: transaction_hashes.into_iter().map(|h| h.into()).collect(),
32        }
33    }
34
35    pub(crate) fn convert(multi_era_block: MultiEraBlock) -> Self {
36        let mut transactions = Vec::new();
37        for tx in &multi_era_block.txs() {
38            transactions.push(tx.hash().to_string());
39        }
40
41        Self::new(
42            *multi_era_block.hash(),
43            BlockNumber(multi_era_block.number()),
44            SlotNumber(multi_era_block.slot()),
45            transactions,
46        )
47    }
48
49    /// Number of transactions in the block
50    pub fn transactions_len(&self) -> usize {
51        self.transactions_hashes.len()
52    }
53
54    /// Convert the scanned block into a list of Cardano transactions.
55    ///
56    /// Consume the block.
57    pub fn into_transactions(self) -> Vec<CardanoTransaction> {
58        let block_hash = hex::encode(&self.block_hash);
59        self.transactions_hashes
60            .into_iter()
61            .map(|transaction_hash| {
62                CardanoTransaction::new(
63                    transaction_hash,
64                    self.block_number,
65                    self.slot_number,
66                    block_hash.clone(),
67                )
68            })
69            .collect::<Vec<_>>()
70    }
71}
72
73impl Debug for ScannedBlock {
74    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
75        let mut debug = f.debug_struct("ScannedBlock");
76        debug
77            .field("block_hash", &hex::encode(&self.block_hash))
78            .field("block_number", &self.block_number)
79            .field("slot_number", &self.slot_number)
80            .field("transactions_hashes", &self.transactions_hashes)
81            .finish()
82    }
83}
84
85impl From<&ScannedBlock> for ChainPoint {
86    fn from(scanned_block: &ScannedBlock) -> Self {
87        ChainPoint::new(
88            scanned_block.slot_number,
89            scanned_block.block_number,
90            hex::encode(&scanned_block.block_hash),
91        )
92    }
93}