solana_block_decoder/block/
versioned_block.rs

1
2use {
3    crate::{
4        block::{
5            confirmed_block::{
6                ConfirmedBlock,
7                TransactionWithStatusMeta
8            },
9        },
10        transaction::{
11            versioned_transaction::VersionedTransactionWithStatusMeta,
12        },
13    },
14    solana_clock::{
15        Slot,
16        UnixTimestamp,
17    },
18    solana_transaction_status_client_types::{
19        Rewards,
20    },
21    thiserror::Error,
22};
23
24
25// Confirmed block with type guarantees that transaction metadata
26// is always present. Used for uploading to HBase.
27#[derive(Clone, Debug, PartialEq)]
28pub struct VersionedConfirmedBlock {
29    pub previous_blockhash: String,
30    pub blockhash: String,
31    pub parent_slot: Slot,
32    pub transactions: Vec<VersionedTransactionWithStatusMeta>,
33    pub rewards: Rewards,
34    pub num_partitions: Option<u64>,
35    pub block_time: Option<UnixTimestamp>,
36    pub block_height: Option<u64>,
37}
38
39
40impl TryFrom<ConfirmedBlock> for VersionedConfirmedBlock {
41    type Error = ConvertBlockError;
42
43    fn try_from(block: ConfirmedBlock) -> Result<Self, Self::Error> {
44        let expected_transaction_count = block.transactions.len();
45
46        let txs: Vec<_> = block
47            .transactions
48            .into_iter()
49            .filter_map(|tx| match tx {
50                TransactionWithStatusMeta::MissingMetadata(_) => None,
51                TransactionWithStatusMeta::Complete(tx) => Some(tx),
52            })
53            .collect();
54
55        if txs.len() != expected_transaction_count {
56            return Err(ConvertBlockError::TransactionsMissing(
57                expected_transaction_count,
58                txs.len(),
59            ));
60        }
61
62        Ok(Self {
63            previous_blockhash: block.previous_blockhash,
64            blockhash: block.blockhash,
65            parent_slot: block.parent_slot,
66            transactions: txs,
67            rewards: block.rewards,
68            num_partitions: block.num_partitions,
69            block_time: block.block_time,
70            block_height: block.block_height,
71        })
72    }
73}
74
75#[derive(Debug, Error)]
76pub enum ConvertBlockError {
77    #[error("transactions missing after converted, before: {0}, after: {1}")]
78    TransactionsMissing(usize, usize),
79}
80
81impl From<VersionedConfirmedBlock> for solana_transaction_status::VersionedConfirmedBlock {
82    fn from(block: VersionedConfirmedBlock) -> Self {
83        Self {
84            previous_blockhash: block.previous_blockhash,
85            blockhash: block.blockhash,
86            parent_slot: block.parent_slot,
87            transactions: block.transactions.into_iter().map(Into::into).collect(),
88            rewards: block.rewards,
89            num_partitions: block.num_partitions,
90            block_time: block.block_time,
91            block_height: block.block_height,
92        }
93    }
94}