solana_transaction_status/
parse_accounts.rs

1pub use solana_transaction_status_client_types::{ParsedAccount, ParsedAccountSource};
2use {
3    agave_reserved_account_keys::ReservedAccountKeys,
4    solana_message::{v0::LoadedMessage, Message},
5};
6
7pub fn parse_legacy_message_accounts(message: &Message) -> Vec<ParsedAccount> {
8    let reserved_account_keys = ReservedAccountKeys::new_all_activated().active;
9    let mut accounts: Vec<ParsedAccount> = vec![];
10    for (i, account_key) in message.account_keys.iter().enumerate() {
11        accounts.push(ParsedAccount {
12            pubkey: account_key.to_string(),
13            writable: message.is_maybe_writable(i, Some(&reserved_account_keys)),
14            signer: message.is_signer(i),
15            source: Some(ParsedAccountSource::Transaction),
16        });
17    }
18    accounts
19}
20
21pub fn parse_v0_message_accounts(message: &LoadedMessage) -> Vec<ParsedAccount> {
22    let mut accounts: Vec<ParsedAccount> = vec![];
23    for (i, account_key) in message.account_keys().iter().enumerate() {
24        let source = if i < message.static_account_keys().len() {
25            ParsedAccountSource::Transaction
26        } else {
27            ParsedAccountSource::LookupTable
28        };
29        accounts.push(ParsedAccount {
30            pubkey: account_key.to_string(),
31            writable: message.is_writable(i),
32            signer: message.is_signer(i),
33            source: Some(source),
34        });
35    }
36    accounts
37}
38
39#[cfg(test)]
40mod test {
41    use {
42        super::*,
43        agave_reserved_account_keys::ReservedAccountKeys,
44        solana_message::{v0, v0::LoadedAddresses, MessageHeader},
45        solana_pubkey::Pubkey,
46    };
47
48    #[test]
49    fn test_parse_legacy_message_accounts() {
50        let pubkey0 = Pubkey::new_unique();
51        let pubkey1 = Pubkey::new_unique();
52        let pubkey2 = Pubkey::new_unique();
53        let pubkey3 = Pubkey::new_unique();
54        let message = Message {
55            header: MessageHeader {
56                num_required_signatures: 2,
57                num_readonly_signed_accounts: 1,
58                num_readonly_unsigned_accounts: 1,
59            },
60            account_keys: vec![pubkey0, pubkey1, pubkey2, pubkey3],
61            ..Message::default()
62        };
63
64        assert_eq!(
65            parse_legacy_message_accounts(&message),
66            vec![
67                ParsedAccount {
68                    pubkey: pubkey0.to_string(),
69                    writable: true,
70                    signer: true,
71                    source: Some(ParsedAccountSource::Transaction),
72                },
73                ParsedAccount {
74                    pubkey: pubkey1.to_string(),
75                    writable: false,
76                    signer: true,
77                    source: Some(ParsedAccountSource::Transaction),
78                },
79                ParsedAccount {
80                    pubkey: pubkey2.to_string(),
81                    writable: true,
82                    signer: false,
83                    source: Some(ParsedAccountSource::Transaction),
84                },
85                ParsedAccount {
86                    pubkey: pubkey3.to_string(),
87                    writable: false,
88                    signer: false,
89                    source: Some(ParsedAccountSource::Transaction),
90                },
91            ]
92        );
93    }
94
95    #[test]
96    fn test_parse_v0_message_accounts() {
97        let pubkey0 = Pubkey::new_unique();
98        let pubkey1 = Pubkey::new_unique();
99        let pubkey2 = Pubkey::new_unique();
100        let pubkey3 = Pubkey::new_unique();
101        let pubkey4 = Pubkey::new_unique();
102        let pubkey5 = Pubkey::new_unique();
103        let message = LoadedMessage::new(
104            v0::Message {
105                header: MessageHeader {
106                    num_required_signatures: 2,
107                    num_readonly_signed_accounts: 1,
108                    num_readonly_unsigned_accounts: 1,
109                },
110                account_keys: vec![pubkey0, pubkey1, pubkey2, pubkey3],
111                ..v0::Message::default()
112            },
113            LoadedAddresses {
114                writable: vec![pubkey4],
115                readonly: vec![pubkey5],
116            },
117            &ReservedAccountKeys::empty_key_set(),
118        );
119
120        assert_eq!(
121            parse_v0_message_accounts(&message),
122            vec![
123                ParsedAccount {
124                    pubkey: pubkey0.to_string(),
125                    writable: true,
126                    signer: true,
127                    source: Some(ParsedAccountSource::Transaction),
128                },
129                ParsedAccount {
130                    pubkey: pubkey1.to_string(),
131                    writable: false,
132                    signer: true,
133                    source: Some(ParsedAccountSource::Transaction),
134                },
135                ParsedAccount {
136                    pubkey: pubkey2.to_string(),
137                    writable: true,
138                    signer: false,
139                    source: Some(ParsedAccountSource::Transaction),
140                },
141                ParsedAccount {
142                    pubkey: pubkey3.to_string(),
143                    writable: false,
144                    signer: false,
145                    source: Some(ParsedAccountSource::Transaction),
146                },
147                ParsedAccount {
148                    pubkey: pubkey4.to_string(),
149                    writable: true,
150                    signer: false,
151                    source: Some(ParsedAccountSource::LookupTable),
152                },
153                ParsedAccount {
154                    pubkey: pubkey5.to_string(),
155                    writable: false,
156                    signer: false,
157                    source: Some(ParsedAccountSource::LookupTable),
158                },
159            ]
160        );
161    }
162}