From 509b00983d217c0f04c2bd5038af5ecb352e44e8 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Tue, 6 Sep 2022 10:40:39 -0500 Subject: [PATCH] RPC: include resolved keys from table lookups in parsed message response (#27552) * RPC: include resolved keys from table lookups in parsed message response * Add source to ParsedAccount * Ensure that rpc client can parse account meta from old api versions (cherry picked from commit c620b7b34f90172f240a6ca9fb6c16d850b1f775) --- transaction-status/src/lib.rs | 6 +-- transaction-status/src/parse_accounts.rs | 55 ++++++++++++++++++++---- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/transaction-status/src/lib.rs b/transaction-status/src/lib.rs index 4a677606fcad51..9409308d3c5938 100644 --- a/transaction-status/src/lib.rs +++ b/transaction-status/src/lib.rs @@ -3,7 +3,7 @@ pub use {crate::extract_memos::extract_and_fmt_memos, solana_sdk::reward_type::RewardType}; use { crate::{ - parse_accounts::{parse_accounts, parse_static_accounts, ParsedAccount}, + parse_accounts::{parse_legacy_message_accounts, parse_v0_message_accounts, ParsedAccount}, parse_instruction::{parse, ParsedInstruction}, }, solana_account_decoder::parse_token::UiTokenAmount, @@ -903,7 +903,7 @@ impl Encodable for Message { if encoding == UiTransactionEncoding::JsonParsed { let account_keys = AccountKeys::new(&self.account_keys, None); UiMessage::Parsed(UiParsedMessage { - account_keys: parse_accounts(self), + account_keys: parse_legacy_message_accounts(self), recent_blockhash: self.recent_blockhash.to_string(), instructions: self .instructions @@ -935,7 +935,7 @@ impl EncodableWithMeta for v0::Message { let account_keys = AccountKeys::new(&self.account_keys, Some(&meta.loaded_addresses)); let loaded_message = LoadedMessage::new_borrowed(self, &meta.loaded_addresses); UiMessage::Parsed(UiParsedMessage { - account_keys: parse_static_accounts(&loaded_message), + account_keys: parse_v0_message_accounts(&loaded_message), recent_blockhash: self.recent_blockhash.to_string(), instructions: self .instructions diff --git a/transaction-status/src/parse_accounts.rs b/transaction-status/src/parse_accounts.rs index a84fd06bf92ca1..6ad0ec82a6fdad 100644 --- a/transaction-status/src/parse_accounts.rs +++ b/transaction-status/src/parse_accounts.rs @@ -6,27 +6,42 @@ pub struct ParsedAccount { pub pubkey: String, pub writable: bool, pub signer: bool, + pub source: Option, } -pub fn parse_accounts(message: &Message) -> Vec { +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub enum ParsedAccountSource { + Transaction, + LookupTable, +} + +pub fn parse_legacy_message_accounts(message: &Message) -> Vec { let mut accounts: Vec = vec![]; for (i, account_key) in message.account_keys.iter().enumerate() { accounts.push(ParsedAccount { pubkey: account_key.to_string(), writable: message.is_writable(i), signer: message.is_signer(i), + source: Some(ParsedAccountSource::Transaction), }); } accounts } -pub fn parse_static_accounts(message: &LoadedMessage) -> Vec { +pub fn parse_v0_message_accounts(message: &LoadedMessage) -> Vec { let mut accounts: Vec = vec![]; - for (i, account_key) in message.static_account_keys().iter().enumerate() { + for (i, account_key) in message.account_keys().iter().enumerate() { + let source = if i < message.static_account_keys().len() { + ParsedAccountSource::Transaction + } else { + ParsedAccountSource::LookupTable + }; accounts.push(ParsedAccount { pubkey: account_key.to_string(), writable: message.is_writable(i), signer: message.is_signer(i), + source: Some(source), }); } accounts @@ -43,7 +58,7 @@ mod test { }; #[test] - fn test_parse_accounts() { + fn test_parse_legacy_message_accounts() { let pubkey0 = Pubkey::new_unique(); let pubkey1 = Pubkey::new_unique(); let pubkey2 = Pubkey::new_unique(); @@ -59,38 +74,44 @@ mod test { }; assert_eq!( - parse_accounts(&message), + parse_legacy_message_accounts(&message), vec![ ParsedAccount { pubkey: pubkey0.to_string(), writable: true, signer: true, + source: Some(ParsedAccountSource::Transaction), }, ParsedAccount { pubkey: pubkey1.to_string(), writable: false, signer: true, + source: Some(ParsedAccountSource::Transaction), }, ParsedAccount { pubkey: pubkey2.to_string(), writable: true, signer: false, + source: Some(ParsedAccountSource::Transaction), }, ParsedAccount { pubkey: pubkey3.to_string(), writable: false, signer: false, + source: Some(ParsedAccountSource::Transaction), }, ] ); } #[test] - fn test_parse_static_accounts() { + fn test_parse_v0_message_accounts() { let pubkey0 = Pubkey::new_unique(); let pubkey1 = Pubkey::new_unique(); let pubkey2 = Pubkey::new_unique(); let pubkey3 = Pubkey::new_unique(); + let pubkey4 = Pubkey::new_unique(); + let pubkey5 = Pubkey::new_unique(); let message = LoadedMessage::new( v0::Message { header: MessageHeader { @@ -102,33 +123,49 @@ mod test { ..v0::Message::default() }, LoadedAddresses { - writable: vec![Pubkey::new_unique()], - readonly: vec![Pubkey::new_unique()], + writable: vec![pubkey4], + readonly: vec![pubkey5], }, ); assert_eq!( - parse_static_accounts(&message), + parse_v0_message_accounts(&message), vec![ ParsedAccount { pubkey: pubkey0.to_string(), writable: true, signer: true, + source: Some(ParsedAccountSource::Transaction), }, ParsedAccount { pubkey: pubkey1.to_string(), writable: false, signer: true, + source: Some(ParsedAccountSource::Transaction), }, ParsedAccount { pubkey: pubkey2.to_string(), writable: true, signer: false, + source: Some(ParsedAccountSource::Transaction), }, ParsedAccount { pubkey: pubkey3.to_string(), writable: false, signer: false, + source: Some(ParsedAccountSource::Transaction), + }, + ParsedAccount { + pubkey: pubkey4.to_string(), + writable: true, + signer: false, + source: Some(ParsedAccountSource::LookupTable), + }, + ParsedAccount { + pubkey: pubkey5.to_string(), + writable: false, + signer: false, + source: Some(ParsedAccountSource::LookupTable), }, ] );