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