solana_block_decoder/message/
message.rs

1use {
2    crate::{
3        errors::{
4            decode_error::DecodeError,
5        },
6        instruction::{
7            CompiledInstruction,
8        },
9        decodable::{
10            Decodable,
11        },
12    },
13    serde_derive::{Deserialize, Serialize},
14    solana_short_vec as short_vec,
15    solana_hash::{
16        Hash,
17    },
18    solana_message::{
19        Message as SolanaMessage,
20        MessageHeader,
21    },
22    solana_pubkey::Pubkey,
23    solana_transaction_status_client_types::{
24        UiMessage,
25    },
26    std::{
27        str::FromStr,
28    },
29};
30
31#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
32#[serde(rename_all = "camelCase")]
33pub struct Message {
34    /// The message header, identifying signed and read-only `account_keys`.
35    // NOTE: Serialization-related changes must be paired with the direct read at sigverify.
36    pub header: MessageHeader,
37
38    /// All the account keys used by this transaction.
39    #[serde(with = "short_vec")]
40    pub account_keys: Vec<Pubkey>,
41
42    /// The id of a recent ledger entry.
43    pub recent_blockhash: Hash,
44
45    /// Programs that will be executed in sequence and committed in one atomic transaction if all
46    /// succeed.
47    #[serde(with = "short_vec")]
48    pub instructions: Vec<CompiledInstruction>,
49}
50
51impl Decodable for Message {
52    type Encoded = UiMessage;
53    type Decoded = Message;
54
55    fn decode(encoded: &Self::Encoded) -> Result<Self::Decoded, DecodeError> {
56        match encoded {
57            UiMessage::Raw(raw_message) => {
58                let header = raw_message.header;
59                let account_keys: Result<Vec<Pubkey>, _> = raw_message
60                    .account_keys
61                    .iter()
62                    .map(|key_str| key_str.parse())
63                    .collect();
64                let account_keys = account_keys?;
65                let recent_blockhash = Hash::from_str(&raw_message.recent_blockhash)
66                    .map_err(|err| DecodeError::ParseHashFailed(err))?;
67                let instructions: Vec<CompiledInstruction> = raw_message
68                    .instructions
69                    .iter()
70                    // .map(|ui_instruction| (*ui_instruction).into() )
71                    .map(|ui_instruction| ui_instruction.clone().into() )
72                    .collect();
73
74                Ok(Message {
75                    header,
76                    account_keys,
77                    recent_blockhash,
78                    instructions,
79                })
80            }
81            UiMessage::Parsed(_) => {
82                Err(DecodeError::UnsupportedEncoding)
83            }
84        }
85    }
86}
87
88
89impl From<Message> for SolanaMessage {
90    fn from(msg: Message) -> Self {
91        Self {
92            header: msg.header,
93            account_keys: msg.account_keys,
94            recent_blockhash: msg.recent_blockhash,
95            instructions: msg.instructions.into_iter().map(Into::into).collect(),
96        }
97    }
98}