solana_transaction_status_wasm/
parse_accounts.rs

1use agave_reserved_account_keys::ReservedAccountKeys;
2use solana_message::Message;
3use solana_message::v0::LoadedMessage;
4pub use solana_transaction_status_client_types_wasm::ParsedAccount;
5pub use solana_transaction_status_client_types_wasm::ParsedAccountSource;
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,
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,
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 agave_reserved_account_keys::ReservedAccountKeys;
42	use solana_message::MessageHeader;
43	use solana_message::v0;
44	use solana_message::v0::LoadedAddresses;
45	use solana_pubkey::Pubkey;
46
47	use super::*;
48
49	#[test]
50	fn test_parse_legacy_message_accounts() {
51		let pubkey0 = Pubkey::new_unique();
52		let pubkey1 = Pubkey::new_unique();
53		let pubkey2 = Pubkey::new_unique();
54		let pubkey3 = Pubkey::new_unique();
55		let message = Message {
56			header: MessageHeader {
57				num_required_signatures: 2,
58				num_readonly_signed_accounts: 1,
59				num_readonly_unsigned_accounts: 1,
60			},
61			account_keys: vec![pubkey0, pubkey1, pubkey2, pubkey3],
62			..Message::default()
63		};
64
65		assert_eq!(
66			parse_legacy_message_accounts(&message),
67			vec![
68				ParsedAccount {
69					pubkey: pubkey0,
70					writable: true,
71					signer: true,
72					source: Some(ParsedAccountSource::Transaction),
73				},
74				ParsedAccount {
75					pubkey: pubkey1,
76					writable: false,
77					signer: true,
78					source: Some(ParsedAccountSource::Transaction),
79				},
80				ParsedAccount {
81					pubkey: pubkey2,
82					writable: true,
83					signer: false,
84					source: Some(ParsedAccountSource::Transaction),
85				},
86				ParsedAccount {
87					pubkey: pubkey3,
88					writable: false,
89					signer: false,
90					source: Some(ParsedAccountSource::Transaction),
91				},
92			]
93		);
94	}
95
96	#[test]
97	fn test_parse_v0_message_accounts() {
98		let pubkey0 = Pubkey::new_unique();
99		let pubkey1 = Pubkey::new_unique();
100		let pubkey2 = Pubkey::new_unique();
101		let pubkey3 = Pubkey::new_unique();
102		let pubkey4 = Pubkey::new_unique();
103		let pubkey5 = Pubkey::new_unique();
104		let message = LoadedMessage::new(
105			v0::Message {
106				header: MessageHeader {
107					num_required_signatures: 2,
108					num_readonly_signed_accounts: 1,
109					num_readonly_unsigned_accounts: 1,
110				},
111				account_keys: vec![pubkey0, pubkey1, pubkey2, pubkey3],
112				..v0::Message::default()
113			},
114			LoadedAddresses {
115				writable: vec![pubkey4],
116				readonly: vec![pubkey5],
117			},
118			&ReservedAccountKeys::empty_key_set(),
119		);
120
121		assert_eq!(
122			parse_v0_message_accounts(&message),
123			vec![
124				ParsedAccount {
125					pubkey: pubkey0,
126					writable: true,
127					signer: true,
128					source: Some(ParsedAccountSource::Transaction),
129				},
130				ParsedAccount {
131					pubkey: pubkey1,
132					writable: false,
133					signer: true,
134					source: Some(ParsedAccountSource::Transaction),
135				},
136				ParsedAccount {
137					pubkey: pubkey2,
138					writable: true,
139					signer: false,
140					source: Some(ParsedAccountSource::Transaction),
141				},
142				ParsedAccount {
143					pubkey: pubkey3,
144					writable: false,
145					signer: false,
146					source: Some(ParsedAccountSource::Transaction),
147				},
148				ParsedAccount {
149					pubkey: pubkey4,
150					writable: true,
151					signer: false,
152					source: Some(ParsedAccountSource::LookupTable),
153				},
154				ParsedAccount {
155					pubkey: pubkey5,
156					writable: false,
157					signer: false,
158					source: Some(ParsedAccountSource::LookupTable),
159				},
160			]
161		);
162	}
163}