solana_block_decoder/transaction/
transaction.rs

1use {
2    crate::{
3        errors::{
4            decode_error::DecodeError,
5        },
6        block::{
7            encoded_block::EncodedTransaction,
8        },
9        message::{
10            message::Message,
11        },
12        decodable::{
13            Decodable,
14        },
15    },
16    serde_derive::{Deserialize, Serialize},
17    solana_program::short_vec,
18    solana_sdk::{
19        signature::ParseSignatureError,
20        signature::Signature,
21    },
22    solana_transaction_status::TransactionBinaryEncoding,
23    std::{
24        str::FromStr,
25    },
26};
27
28#[derive(Debug, PartialEq, Default, Eq, Clone, Serialize, Deserialize)]
29pub struct Transaction {
30    /// A set of signatures of a serialized [`Message`], signed by the first
31    /// keys of the `Message`'s [`account_keys`], where the number of signatures
32    /// is equal to [`num_required_signatures`] of the `Message`'s
33    /// [`MessageHeader`].
34    ///
35    /// [`account_keys`]: Message::account_keys
36    /// [`MessageHeader`]: crate::message::MessageHeader
37    /// [`num_required_signatures`]: crate::message::MessageHeader::num_required_signatures
38    // NOTE: Serialization-related changes must be paired with the direct read at sigverify.
39    #[serde(with = "short_vec")]
40    pub signatures: Vec<Signature>,
41
42    /// The message to sign.
43    pub message: Message,
44}
45
46impl Decodable for Transaction {
47    type Encoded = EncodedTransaction;
48    type Decoded = Transaction;
49
50    fn decode(encoded: &Self::Encoded) -> Result<Self::Decoded, DecodeError> {
51        match encoded {
52            EncodedTransaction::LegacyBinary(s) | EncodedTransaction::Binary(s, TransactionBinaryEncoding::Base58) => {
53                let data = bs58::decode(s)
54                    .into_vec()
55                    .map_err(|_| DecodeError::DeserializeFailed)?;
56                let transaction: Transaction = bincode::deserialize(&data)
57                    .map_err(|_| DecodeError::DeserializeFailed)?;
58                Ok(transaction)
59            }
60            EncodedTransaction::Binary(s, TransactionBinaryEncoding::Base64) => {
61                let data = base64::decode(s)
62                    .map_err(|_| DecodeError::DeserializeFailed)?;
63                let transaction: Transaction = bincode::deserialize(&data)
64                    .map_err(|_| DecodeError::DeserializeFailed)?;
65                Ok(transaction)
66            }
67            EncodedTransaction::Json(ui_transaction) => {
68                let message = Message::decode(&ui_transaction.message)?;
69                let signatures: Result<Vec<Signature>, ParseSignatureError> = ui_transaction.signatures.iter()
70                    .map(|s| Signature::from_str(s))
71                    .collect();
72                let signatures = match signatures {
73                    Ok(signatures) => signatures,
74                    Err(error) => return Err(DecodeError::ParseSignatureFailed(error)),
75                };
76                Ok(Transaction {
77                    signatures,
78                    message,
79                })
80            }
81            EncodedTransaction::Accounts(_) => {
82                Err(DecodeError::UnsupportedEncoding)
83            }
84        }
85    }
86}