Make accounts explicit in unrecognized jsonParsed instructions (#11351)
This commit is contained in:
		| @@ -8,12 +8,13 @@ pub mod parse_instruction; | |||||||
| pub mod parse_token; | pub mod parse_token; | ||||||
|  |  | ||||||
| use crate::{parse_accounts::parse_accounts, parse_instruction::parse}; | use crate::{parse_accounts::parse_accounts, parse_instruction::parse}; | ||||||
| use serde_json::Value; | use serde_json::{json, Value}; | ||||||
| use solana_sdk::{ | use solana_sdk::{ | ||||||
|     clock::{Slot, UnixTimestamp}, |     clock::{Slot, UnixTimestamp}, | ||||||
|     commitment_config::CommitmentConfig, |     commitment_config::CommitmentConfig, | ||||||
|     instruction::CompiledInstruction, |     instruction::CompiledInstruction, | ||||||
|     message::MessageHeader, |     message::MessageHeader, | ||||||
|  |     pubkey::Pubkey, | ||||||
|     transaction::{Result, Transaction, TransactionError}, |     transaction::{Result, Transaction, TransactionError}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -44,6 +45,29 @@ impl From<&CompiledInstruction> for UiCompiledInstruction { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// A partially decoded CompiledInstruction that includes explicit account addresses | ||||||
|  | #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] | ||||||
|  | #[serde(rename_all = "camelCase")] | ||||||
|  | pub struct UiPartiallyDecodedInstruction { | ||||||
|  |     pub program_id: String, | ||||||
|  |     pub accounts: Vec<String>, | ||||||
|  |     pub data: String, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl UiPartiallyDecodedInstruction { | ||||||
|  |     fn from(instruction: &CompiledInstruction, account_keys: &[Pubkey]) -> Self { | ||||||
|  |         Self { | ||||||
|  |             program_id: account_keys[instruction.program_id_index as usize].to_string(), | ||||||
|  |             accounts: instruction | ||||||
|  |                 .accounts | ||||||
|  |                 .iter() | ||||||
|  |                 .map(|&i| account_keys[i as usize].to_string()) | ||||||
|  |                 .collect(), | ||||||
|  |             data: bs58::encode(instruction.data.clone()).into_string(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] | #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] | ||||||
| #[serde(rename_all = "camelCase")] | #[serde(rename_all = "camelCase")] | ||||||
| pub struct TransactionStatusMeta { | pub struct TransactionStatusMeta { | ||||||
| @@ -228,7 +252,12 @@ impl EncodedTransaction { | |||||||
|                                 ) { |                                 ) { | ||||||
|                                     UiInstruction::Parsed(parsed_instruction) |                                     UiInstruction::Parsed(parsed_instruction) | ||||||
|                                 } else { |                                 } else { | ||||||
|                                     UiInstruction::Compiled(instruction.into()) |                                     UiInstruction::Parsed(json!( | ||||||
|  |                                         UiPartiallyDecodedInstruction::from( | ||||||
|  |                                             instruction, | ||||||
|  |                                             &transaction.message.account_keys | ||||||
|  |                                         ) | ||||||
|  |                                     )) | ||||||
|                                 } |                                 } | ||||||
|                             }) |                             }) | ||||||
|                             .collect(), |                             .collect(), | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| use serde_json::{json, Value}; | use serde_json::{json, Map, Value}; | ||||||
| use solana_sdk::message::Message; | use solana_sdk::message::Message; | ||||||
|  |  | ||||||
| type AccountAttributes = Vec<AccountAttribute>; | type AccountAttributes = Vec<AccountAttribute>; | ||||||
| @@ -11,7 +11,7 @@ enum AccountAttribute { | |||||||
| } | } | ||||||
|  |  | ||||||
| pub fn parse_accounts(message: &Message) -> Value { | pub fn parse_accounts(message: &Message) -> Value { | ||||||
|     let mut accounts: Vec<Value> = vec![]; |     let mut accounts: Map<String, Value> = Map::new(); | ||||||
|     for (i, account_key) in message.account_keys.iter().enumerate() { |     for (i, account_key) in message.account_keys.iter().enumerate() { | ||||||
|         let mut attributes: AccountAttributes = vec![]; |         let mut attributes: AccountAttributes = vec![]; | ||||||
|         if message.is_writable(i) { |         if message.is_writable(i) { | ||||||
| @@ -20,7 +20,7 @@ pub fn parse_accounts(message: &Message) -> Value { | |||||||
|         if message.is_signer(i) { |         if message.is_signer(i) { | ||||||
|             attributes.push(AccountAttribute::Signer); |             attributes.push(AccountAttribute::Signer); | ||||||
|         } |         } | ||||||
|         accounts.push(json!({ account_key.to_string(): attributes })); |         accounts.insert(account_key.to_string(), json!(attributes)); | ||||||
|     } |     } | ||||||
|     json!(accounts) |     json!(accounts) | ||||||
| } | } | ||||||
| @@ -44,12 +44,12 @@ mod test { | |||||||
|         }; |         }; | ||||||
|         message.account_keys = vec![pubkey0, pubkey1, pubkey2, pubkey3]; |         message.account_keys = vec![pubkey0, pubkey1, pubkey2, pubkey3]; | ||||||
|  |  | ||||||
|         let expected_json = json!([ |         let expected_json = json!({ | ||||||
|             {pubkey0.to_string(): ["writable", "signer"]}, |             pubkey0.to_string(): ["writable", "signer"], | ||||||
|             {pubkey1.to_string(): ["signer"]}, |             pubkey1.to_string(): ["signer"], | ||||||
|             {pubkey2.to_string(): ["writable"]}, |             pubkey2.to_string(): ["writable"], | ||||||
|             {pubkey3.to_string(): []}, |             pubkey3.to_string(): [], | ||||||
|         ]); |         }); | ||||||
|  |  | ||||||
|         assert_eq!(parse_accounts(&message), expected_json); |         assert_eq!(parse_accounts(&message), expected_json); | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user