solana_block_decoder/block/
encoded_block.rs

1
2use {
3    solana_sdk::{
4        clock::{Slot, UnixTimestamp},
5        transaction::{
6            TransactionVersion,
7            VersionedTransaction,
8        },
9    },
10    solana_transaction_status::{
11        TransactionBinaryEncoding,
12        Rewards,
13        UiTransaction,
14        UiAccountsList,
15        UiTransactionStatusMeta,
16    },
17    serde_derive::{Serialize,Deserialize},
18};
19
20#[derive(Debug, PartialEq, Serialize, Deserialize)]
21#[serde(rename_all = "camelCase")]
22pub struct EncodedConfirmedBlock {
23    pub previous_blockhash: String,
24    pub blockhash: String,
25    pub parent_slot: Slot,
26    pub transactions: Vec<EncodedTransactionWithStatusMeta>,
27    pub rewards: Rewards,
28    pub num_partitions: Option<u64>,
29    pub block_time: Option<UnixTimestamp>,
30    pub block_height: Option<u64>,
31}
32
33#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
34#[serde(rename_all = "camelCase")]
35pub struct EncodedTransactionWithStatusMeta {
36    pub transaction: EncodedTransaction,
37    pub meta: Option<UiTransactionStatusMeta>,
38    #[serde(default, skip_serializing_if = "Option::is_none")]
39    pub version: Option<TransactionVersion>,
40}
41
42#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
43#[serde(rename_all = "camelCase", untagged)]
44pub enum EncodedTransaction {
45    LegacyBinary(String), // Old way of expressing base-58, retained for RPC backwards compatibility
46    Binary(String, TransactionBinaryEncoding),
47    Json(UiTransaction),
48    Accounts(UiAccountsList),
49}
50
51impl EncodedTransaction {
52    pub fn decode(&self) -> Option<VersionedTransaction> {
53        let (blob, encoding) = match self {
54            Self::Json(_) | Self::Accounts(_) => return None,
55            Self::LegacyBinary(blob) => (blob, TransactionBinaryEncoding::Base58),
56            Self::Binary(blob, encoding) => (blob, *encoding),
57        };
58
59        let transaction: Option<VersionedTransaction> = match encoding {
60            TransactionBinaryEncoding::Base58 => bs58::decode(blob)
61                .into_vec()
62                .ok()
63                .and_then(|bytes| bincode::deserialize(&bytes).ok()),
64            TransactionBinaryEncoding::Base64 => base64::decode(blob)
65                .ok()
66                .and_then(|bytes| bincode::deserialize(&bytes).ok()),
67        };
68
69        transaction.filter(|transaction| {
70            transaction
71                .sanitize(
72                    // true, // require_static_program_ids
73                )
74                .is_ok()
75        })
76    }
77}