solana_block_decoder/address/
address_table_lookup.rs1
2use {
3 crate::{
4 errors::{
5 decode_error::DecodeError,
6 }
7 },
8 solana_short_vec as short_vec,
9 solana_pubkey::{Pubkey, ParsePubkeyError},
10 solana_transaction_status_client_types::{
11 UiAddressTableLookup,
12 },
13 serde::{
14 Deserialize, Serialize,
15 },
16 std::{
17 str::FromStr,
18 },
19};
20
21#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
22#[serde(rename_all = "camelCase")]
23pub struct MessageAddressTableLookup {
24 pub account_key: Pubkey,
26 #[serde(with = "short_vec")]
28 pub writable_indexes: Vec<u8>,
29 #[serde(with = "short_vec")]
31 pub readonly_indexes: Vec<u8>,
32}
33
34impl TryFrom<&UiAddressTableLookup> for MessageAddressTableLookup {
35 type Error = DecodeError;
36
37 fn try_from(lookup: &UiAddressTableLookup) -> Result<Self, Self::Error> {
38 let account_key = Pubkey::from_str(&lookup.account_key)
39 .map_err(|_| DecodeError::ParsePubkeyFailed(ParsePubkeyError::Invalid))?;
40 Ok(Self {
41 account_key,
42 writable_indexes: lookup.writable_indexes.clone(),
43 readonly_indexes: lookup.readonly_indexes.clone(),
44 })
45 }
46}
47
48impl From<MessageAddressTableLookup> for solana_message::v0::MessageAddressTableLookup {
49 fn from(lookup: MessageAddressTableLookup) -> Self {
50 Self {
51 account_key: lookup.account_key,
52 writable_indexes: lookup.writable_indexes,
53 readonly_indexes: lookup.readonly_indexes,
54 }
55 }
56}
57
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use std::str::FromStr;
63 use solana_message::v0::MessageAddressTableLookup as SolanaMessageAddressTableLookup;
64 use solana_transaction_status_client_types::UiAddressTableLookup;
65 use serde_json::{self, Value};
66
67 #[test]
68 fn test_try_from_ui_address_table_lookup_success() {
69 let ui_lookup = UiAddressTableLookup {
70 account_key: "11111111111111111111111111111111".to_string(),
71 writable_indexes: vec![1, 2, 3],
72 readonly_indexes: vec![4, 5, 6],
73 };
74
75 let lookup = MessageAddressTableLookup::try_from(&ui_lookup).unwrap();
76 assert_eq!(
77 lookup.account_key,
78 Pubkey::from_str("11111111111111111111111111111111").unwrap()
79 );
80 assert_eq!(lookup.writable_indexes, vec![1, 2, 3]);
81 assert_eq!(lookup.readonly_indexes, vec![4, 5, 6]);
82 }
83
84 #[test]
85 fn test_try_from_ui_address_table_lookup_invalid_pubkey() {
86 let ui_lookup = UiAddressTableLookup {
87 account_key: "invalid_pubkey".to_string(),
88 writable_indexes: vec![1, 2, 3],
89 readonly_indexes: vec![4, 5, 6],
90 };
91
92 let result = MessageAddressTableLookup::try_from(&ui_lookup);
93 assert!(result.is_err());
94 }
95
96 #[test]
97 fn test_from_message_address_table_lookup_to_solana_message() {
98 let lookup = MessageAddressTableLookup {
99 account_key: Pubkey::from_str("11111111111111111111111111111111").unwrap(),
100 writable_indexes: vec![1, 2, 3],
101 readonly_indexes: vec![4, 5, 6],
102 };
103
104 let solana_lookup: SolanaMessageAddressTableLookup = lookup.clone().into();
105 assert_eq!(solana_lookup.account_key, lookup.account_key);
106 assert_eq!(solana_lookup.writable_indexes, lookup.writable_indexes);
107 assert_eq!(solana_lookup.readonly_indexes, lookup.readonly_indexes);
108 }
109
110 #[test]
111 fn test_serde_serialization() {
112 let lookup = MessageAddressTableLookup {
113 account_key: Pubkey::from_str("11111111111111111111111111111111").unwrap(),
115 writable_indexes: vec![1, 2, 3],
116 readonly_indexes: vec![4, 5, 6],
117 };
118
119 let serialized = serde_json::to_string(&lookup).unwrap();
120 let zeros = vec![0u8; 32];
124 let expected_value = serde_json::json!({
125 "accountKey": zeros, "writableIndexes": [[3], 1, 2, 3], "readonlyIndexes": [[3], 4, 5, 6]
128 });
129
130 let serialized_value: serde_json::Value = serde_json::from_str(&serialized).unwrap();
131 assert_eq!(serialized_value, expected_value);
132 }
133
134 #[test]
135 fn test_serde_deserialization() {
136 let zeros = vec![0u8; 32];
138 let json_str = serde_json::json!({
139 "accountKey": zeros,
140 "writableIndexes": [[3], 1, 2, 3],
141 "readonlyIndexes": [[3], 4, 5, 6]
142 }).to_string();
143
144 let deserialized: MessageAddressTableLookup = serde_json::from_str(&json_str).unwrap();
145
146 assert_eq!(deserialized.account_key.to_string(), "11111111111111111111111111111111");
148 assert_eq!(deserialized.writable_indexes, vec![1, 2, 3]);
149 assert_eq!(deserialized.readonly_indexes, vec![4, 5, 6]);
150 }
151}