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