solana_block_decoder/message/
message_v0.rs1use {
2 crate::{
3 address::{
4 address_table_lookup::MessageAddressTableLookup,
5 },
6 errors::{
7 decode_error::DecodeError,
8 },
9 instruction::{
10 CompiledInstruction,
11 },
12 decodable::{
13 DecodableWithMeta,
14 },
15 },
16 serde_derive::{Deserialize, Serialize},
17 solana_program::short_vec,
18 solana_sdk::{
19 hash::Hash,
20 message::{
21 v0::Message as SolanaMessageV0,
22 MessageHeader,
23 },
24 pubkey::Pubkey,
25 transaction::TransactionVersion,
26 },
27 solana_transaction_status::{
28 UiMessage,
29 UiTransactionEncoding,
30 },
31};
32
33#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
34#[serde(rename_all = "camelCase")]
35pub struct Message {
36 pub header: MessageHeader,
40
41 #[serde(with = "short_vec")]
43 pub account_keys: Vec<Pubkey>,
44
45 pub recent_blockhash: Hash,
47
48 #[serde(with = "short_vec")]
62 pub instructions: Vec<CompiledInstruction>,
63
64 #[serde(with = "short_vec")]
67 pub address_table_lookups: Vec<MessageAddressTableLookup>,
68}
69
70impl DecodableWithMeta for Message {
71 type Encoded = UiMessage;
72 type Decoded = Message;
73
74 fn decode_with_meta(
75 encoded: Self::Encoded,
76 decoding: UiTransactionEncoding,
77 version: Option<TransactionVersion>
78 ) -> Result<Self::Decoded, DecodeError> {
79 match decoding {
80 UiTransactionEncoding::Json => match encoded {
81 UiMessage::Raw(_) => Self::json_decode(encoded, version),
82 UiMessage::Parsed(_) => Err(DecodeError::UnsupportedEncoding),
83 },
84 _ => Err(DecodeError::UnsupportedEncoding),
85 }
86 }
87
88 fn json_decode(encoded: Self::Encoded, _version: Option<TransactionVersion>) -> Result<Self::Decoded, DecodeError> {
89 if let UiMessage::Raw(raw_msg) = encoded {
90 let header = raw_msg.header;
91 let account_keys = raw_msg.account_keys
92 .iter()
93 .map(|s| s.parse::<Pubkey>())
94 .collect::<Result<Vec<_>, _>>()
95 .map_err(|_| DecodeError::InvalidAccountKey)?;
96 let recent_blockhash = raw_msg.recent_blockhash.parse::<Hash>()
97 .map_err(|_| DecodeError::InvalidBlockhash)?;
98 let instructions = raw_msg.instructions
99 .iter()
100 .map(|i| CompiledInstruction::from(i.clone()))
101 .collect::<Vec<_>>();
102 let address_table_lookups = match raw_msg.address_table_lookups {
103 Some(lookups) => lookups
104 .iter()
105 .map(|lookup| MessageAddressTableLookup::try_from(lookup).unwrap())
106 .collect(),
107 None => vec![],
108 };
109
110 Ok(Self {
111 header,
112 account_keys,
113 recent_blockhash,
114 instructions,
115 address_table_lookups,
116 })
117 } else {
118 Err(DecodeError::UnsupportedEncoding)
119 }
120 }
121}
122
123
124impl From<Message> for SolanaMessageV0 {
125 fn from(msg: Message) -> Self {
126 Self {
127 header: msg.header,
128 account_keys: msg.account_keys,
129 recent_blockhash: msg.recent_blockhash,
130 instructions: msg.instructions.into_iter().map(Into::into).collect(),
131 address_table_lookups: msg.address_table_lookups.into_iter().map(Into::into).collect(),
132 }
133 }
134}