solana_block_decoder/block/
confirmed_block.rs1
2use {
3 crate::{
4 errors::{
5 decode_error::DecodeError,
6 },
7 decodable::Decodable,
8 transaction::{
9 versioned_transaction::VersionedTransactionWithStatusMeta,
10 },
11 block::{
12 encoded_block::EncodedTransactionWithStatusMeta,
13 ui_block::UiConfirmedBlock,
14 },
15 transaction::{
16 transaction::{Transaction},
17 }
18 },
19 solana_clock::{
20 Slot,
21 UnixTimestamp,
22 },
23 solana_transaction_status::{
24 BlockEncodingOptions,
25 },
26 solana_transaction_status_client_types::{
27 UiTransactionEncoding,
28 TransactionDetails,
29 Rewards,
30 },
31 serde_derive::{Serialize,Deserialize},
32};
33
34#[derive(Clone, Debug, PartialEq)]
35pub struct ConfirmedBlock {
36 pub previous_blockhash: String,
37 pub blockhash: String,
38 pub parent_slot: Slot,
39 pub transactions: Vec<TransactionWithStatusMeta>,
40 pub rewards: Rewards,
41 pub num_partitions: Option<u64>,
42 pub block_time: Option<UnixTimestamp>,
43 pub block_height: Option<u64>,
44}
45
46impl ConfirmedBlock {
47 pub fn decode_with_options(
48 ui_confirmed_block: UiConfirmedBlock,
49 encoding: UiTransactionEncoding,
50 options: BlockEncodingOptions,
51 ) -> Result<Self, DecodeError> {
52 let transactions = match options.transaction_details {
53 TransactionDetails::Full => {
54 let transactions = ui_confirmed_block
55 .transactions
56 .ok_or(DecodeError::InvalidEncoding)?
57 .into_iter()
58 .map(|encoded_tx_with_meta| {
59 TransactionWithStatusMeta::decode(encoded_tx_with_meta, encoding)
60 })
61 .collect::<Result<Vec<_>, _>>()?;
62 transactions
63 }
64 TransactionDetails::Signatures => {
65 let _signatures = ui_confirmed_block
66 .signatures
67 .ok_or(DecodeError::InvalidEncoding)?;
68 return Err(DecodeError::NotImplemented);
70 }
71 TransactionDetails::None => Vec::new(),
72 TransactionDetails::Accounts => {
73 let transactions = ui_confirmed_block
74 .transactions
75 .ok_or(DecodeError::InvalidEncoding)?
76 .into_iter()
77 .map(|encoded_tx_with_meta| {
78 TransactionWithStatusMeta::decode(encoded_tx_with_meta, encoding)
79 })
80 .collect::<Result<Vec<_>, _>>()?;
81 transactions
82 }
83 };
84
85 Ok(ConfirmedBlock {
86 previous_blockhash: ui_confirmed_block.previous_blockhash,
87 blockhash: ui_confirmed_block.blockhash,
88 parent_slot: ui_confirmed_block.parent_slot,
89 transactions,
90 rewards: ui_confirmed_block
91 .rewards
92 .unwrap_or_default(),
93 num_partitions: ui_confirmed_block.num_reward_partitions,
94 block_time: ui_confirmed_block.block_time,
95 block_height: ui_confirmed_block.block_height,
96 })
97 }
98}
99
100
101#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
102#[allow(clippy::large_enum_variant)]
103pub enum TransactionWithStatusMeta {
104 MissingMetadata(Transaction),
106 Complete(VersionedTransactionWithStatusMeta),
108}
109
110impl TransactionWithStatusMeta {
111 pub fn decode(
112 encoded: EncodedTransactionWithStatusMeta,
113 encoding: UiTransactionEncoding,
114 ) -> Result<Self, DecodeError> {
115 match encoded.meta {
116 Some(_) => {
117 let complete = VersionedTransactionWithStatusMeta::decode(encoded, encoding )?;
118 Ok(Self::Complete(complete))
119 },
120 None => {
121 let transaction = Transaction::decode(&encoded.transaction)?;
122 Ok(Self::MissingMetadata(transaction))
123 }
124 }
125 }
126}