Make accounts explicit in unrecognized jsonParsed instructions (#11351)

This commit is contained in:
Tyera Eulberg
2020-08-03 14:27:15 -06:00
committed by GitHub
parent eefcf484cb
commit 3f6f1adb5b
2 changed files with 40 additions and 11 deletions

View File

@ -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(),

View File

@ -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);
} }