Refactor: Add AccountKeys struct for static and dynamic message keys (#22960)

This commit is contained in:
Justin Starry
2022-02-05 20:00:31 +08:00
committed by GitHub
parent e05cf4bf97
commit ba215e94f6
26 changed files with 917 additions and 442 deletions

View File

@@ -2,7 +2,7 @@ use {
crate::{parse_instruction::parse_memo_data, VersionedTransactionWithStatusMeta},
solana_sdk::{
instruction::CompiledInstruction,
message::{Message, SanitizedMessage},
message::{AccountKeys, Message, SanitizedMessage},
pubkey::Pubkey,
},
};
@@ -45,20 +45,23 @@ pub trait ExtractMemos {
impl ExtractMemos for Message {
fn extract_memos(&self) -> Vec<String> {
extract_memos_inner(self.account_keys.iter(), &self.instructions)
extract_memos_inner(
&AccountKeys::new(&self.account_keys, None),
&self.instructions,
)
}
}
impl ExtractMemos for SanitizedMessage {
fn extract_memos(&self) -> Vec<String> {
extract_memos_inner(self.account_keys_iter(), self.instructions())
extract_memos_inner(&self.account_keys(), self.instructions())
}
}
impl ExtractMemos for VersionedTransactionWithStatusMeta {
fn extract_memos(&self) -> Vec<String> {
extract_memos_inner(
self.account_keys_iter(),
&self.account_keys(),
self.transaction.message.instructions(),
)
}
@@ -70,11 +73,11 @@ enum KeyType<'a> {
Unknown(&'a Pubkey),
}
fn extract_memos_inner<'a>(
account_keys: impl Iterator<Item = &'a Pubkey>,
fn extract_memos_inner(
account_keys: &AccountKeys,
instructions: &[CompiledInstruction],
) -> Vec<String> {
let mut account_keys: Vec<KeyType> = account_keys.map(KeyType::Unknown).collect();
let mut account_keys: Vec<KeyType> = account_keys.iter().map(KeyType::Unknown).collect();
instructions
.iter()
.filter_map(|ix| {
@@ -129,15 +132,16 @@ mod test {
data: memo1.as_bytes().to_vec(),
},
];
let account_keys = vec![
let static_keys = vec![
fee_payer,
spl_memo_id_v1(),
another_program_id,
spl_memo_id_v3(),
];
let account_keys = AccountKeys::new(&static_keys, None);
assert_eq!(
extract_memos_inner(account_keys.iter(), &memo_instructions),
extract_memos_inner(&account_keys, &memo_instructions),
expected_memos
);
}

View File

@@ -26,8 +26,7 @@ use {
clock::{Slot, UnixTimestamp},
commitment_config::CommitmentConfig,
instruction::CompiledInstruction,
message::{v0::LoadedAddresses, Message, MessageHeader},
pubkey::Pubkey,
message::{v0::LoadedAddresses, AccountKeys, Message, MessageHeader},
sanitize::Sanitize,
signature::Signature,
transaction::{Result, Transaction, TransactionError, VersionedTransaction},
@@ -82,8 +81,8 @@ pub enum UiInstruction {
}
impl UiInstruction {
fn parse(instruction: &CompiledInstruction, account_keys: &[Pubkey]) -> Self {
let program_id = instruction.program_id(account_keys);
fn parse(instruction: &CompiledInstruction, account_keys: &AccountKeys) -> Self {
let program_id = &account_keys[instruction.program_id_index as usize];
if let Ok(parsed_instruction) = parse(program_id, instruction, account_keys) {
UiInstruction::Parsed(UiParsedInstruction::Parsed(parsed_instruction))
} else {
@@ -130,7 +129,7 @@ pub struct UiPartiallyDecodedInstruction {
}
impl UiPartiallyDecodedInstruction {
fn from(instruction: &CompiledInstruction, account_keys: &[Pubkey]) -> Self {
fn from(instruction: &CompiledInstruction, account_keys: &AccountKeys) -> Self {
Self {
program_id: account_keys[instruction.program_id_index as usize].to_string(),
accounts: instruction
@@ -162,12 +161,13 @@ pub struct UiInnerInstructions {
impl UiInnerInstructions {
fn parse(inner_instructions: InnerInstructions, message: &Message) -> Self {
let account_keys = AccountKeys::new(&message.account_keys, None);
Self {
index: inner_instructions.index,
instructions: inner_instructions
.instructions
.iter()
.map(|ix| UiInstruction::parse(ix, &message.account_keys))
.map(|ix| UiInstruction::parse(ix, &account_keys))
.collect(),
}
}
@@ -572,14 +572,11 @@ pub struct VersionedTransactionWithStatusMeta {
}
impl VersionedTransactionWithStatusMeta {
pub fn account_keys_iter(&self) -> impl Iterator<Item = &Pubkey> {
let static_keys_iter = self.transaction.message.static_account_keys().iter();
let dynamic_keys_iter = self
.meta
.iter()
.flat_map(|meta| meta.loaded_addresses.ordered_iter());
static_keys_iter.chain(dynamic_keys_iter)
pub fn account_keys(&self) -> AccountKeys {
AccountKeys::new(
self.transaction.message.static_account_keys(),
self.meta.as_ref().map(|meta| &meta.loaded_addresses),
)
}
pub fn into_legacy_transaction_with_meta(self) -> Option<TransactionWithStatusMeta> {
@@ -753,13 +750,14 @@ impl Encodable for &Message {
type Encoded = UiMessage;
fn encode(self, encoding: UiTransactionEncoding) -> Self::Encoded {
if encoding == UiTransactionEncoding::JsonParsed {
let account_keys = AccountKeys::new(&self.account_keys, None);
UiMessage::Parsed(UiParsedMessage {
account_keys: parse_accounts(self),
recent_blockhash: self.recent_blockhash.to_string(),
instructions: self
.instructions
.iter()
.map(|instruction| UiInstruction::parse(instruction, &self.account_keys))
.map(|instruction| UiInstruction::parse(instruction, &account_keys))
.collect(),
})
} else {

View File

@@ -3,7 +3,7 @@ use {
check_num_accounts, ParsableProgram, ParseInstructionError, ParsedInstructionEnum,
},
serde_json::json,
solana_sdk::{instruction::CompiledInstruction, pubkey::Pubkey},
solana_sdk::{instruction::CompiledInstruction, message::AccountKeys, pubkey::Pubkey},
};
// A helper function to convert spl_associated_token_account::id() as spl_sdk::pubkey::Pubkey
@@ -14,7 +14,7 @@ pub fn spl_associated_token_id() -> Pubkey {
pub fn parse_associated_token(
instruction: &CompiledInstruction,
account_keys: &[Pubkey],
account_keys: &AccountKeys,
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
match instruction.accounts.iter().max() {
Some(index) if (*index as usize) < account_keys.len() => {}
@@ -88,8 +88,9 @@ mod test {
);
let message = Message::new(&[create_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
let account_keys = AccountKeys::new(&keys, None);
assert_eq!(
parse_associated_token(&compiled_instruction, &keys).unwrap(),
parse_associated_token(&compiled_instruction, &account_keys).unwrap(),
ParsedInstructionEnum {
instruction_type: "create".to_string(),
info: json!({

View File

@@ -6,13 +6,13 @@ use {
serde_json::json,
solana_sdk::{
instruction::CompiledInstruction, loader_instruction::LoaderInstruction,
loader_upgradeable_instruction::UpgradeableLoaderInstruction, pubkey::Pubkey,
loader_upgradeable_instruction::UpgradeableLoaderInstruction, message::AccountKeys,
},
};
pub fn parse_bpf_loader(
instruction: &CompiledInstruction,
account_keys: &[Pubkey],
account_keys: &AccountKeys,
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
let bpf_loader_instruction: LoaderInstruction = deserialize(&instruction.data)
.map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::BpfLoader))?;
@@ -41,7 +41,7 @@ pub fn parse_bpf_loader(
pub fn parse_bpf_upgradeable_loader(
instruction: &CompiledInstruction,
account_keys: &[Pubkey],
account_keys: &AccountKeys,
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
let bpf_upgradeable_loader_instruction: UpgradeableLoaderInstruction =
deserialize(&instruction.data).map_err(|_| {
@@ -159,7 +159,10 @@ mod test {
use {
super::*,
serde_json::Value,
solana_sdk::{message::Message, pubkey},
solana_sdk::{
message::Message,
pubkey::{self, Pubkey},
},
};
#[test]
@@ -180,7 +183,11 @@ mod test {
);
let message = Message::new(&[instruction], Some(&fee_payer));
assert_eq!(
parse_bpf_loader(&message.instructions[0], &account_keys).unwrap(),
parse_bpf_loader(
&message.instructions[0],
&AccountKeys::new(&account_keys, None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "write".to_string(),
info: json!({
@@ -190,12 +197,20 @@ mod test {
}),
}
);
assert!(parse_bpf_loader(&message.instructions[0], &missing_account_keys).is_err());
assert!(parse_bpf_loader(
&message.instructions[0],
&AccountKeys::new(&missing_account_keys, None)
)
.is_err());
let instruction = solana_sdk::loader_instruction::finalize(&account_pubkey, &program_id);
let message = Message::new(&[instruction], Some(&fee_payer));
assert_eq!(
parse_bpf_loader(&message.instructions[0], &account_keys).unwrap(),
parse_bpf_loader(
&message.instructions[0],
&AccountKeys::new(&account_keys, None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "finalize".to_string(),
info: json!({
@@ -203,21 +218,33 @@ mod test {
}),
}
);
assert!(parse_bpf_loader(&message.instructions[0], &missing_account_keys).is_err());
assert!(parse_bpf_loader(
&message.instructions[0],
&AccountKeys::new(&missing_account_keys, None)
)
.is_err());
let bad_compiled_instruction = CompiledInstruction {
program_id_index: 3,
accounts: vec![1, 2],
data: vec![2, 0, 0, 0], // LoaderInstruction enum only has 2 variants
};
assert!(parse_bpf_loader(&bad_compiled_instruction, &account_keys).is_err());
assert!(parse_bpf_loader(
&bad_compiled_instruction,
&AccountKeys::new(&account_keys, None)
)
.is_err());
let bad_compiled_instruction = CompiledInstruction {
program_id_index: 3,
accounts: vec![],
data: vec![1, 0, 0, 0],
};
assert!(parse_bpf_loader(&bad_compiled_instruction, &account_keys).is_err());
assert!(parse_bpf_loader(
&bad_compiled_instruction,
&AccountKeys::new(&account_keys, None)
)
.is_err());
}
#[test]
@@ -240,7 +267,11 @@ mod test {
.unwrap();
let message = Message::new(&instructions, None);
assert_eq!(
parse_bpf_upgradeable_loader(&message.instructions[1], &keys[0..3]).unwrap(),
parse_bpf_upgradeable_loader(
&message.instructions[1],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "initializeBuffer".to_string(),
info: json!({
@@ -249,13 +280,21 @@ mod test {
}),
}
);
assert!(parse_bpf_upgradeable_loader(&message.instructions[1], &keys[0..2]).is_err());
assert!(parse_bpf_upgradeable_loader(
&message.instructions[1],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instruction =
solana_sdk::bpf_loader_upgradeable::write(&keys[1], &keys[0], offset, bytes.clone());
let message = Message::new(&[instruction], None);
assert_eq!(
parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..2]).unwrap(),
parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "write".to_string(),
info: json!({
@@ -266,7 +305,11 @@ mod test {
}),
}
);
assert!(parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let instructions = solana_sdk::bpf_loader_upgradeable::deploy_with_max_program_len(
&keys[0],
@@ -279,7 +322,11 @@ mod test {
.unwrap();
let message = Message::new(&instructions, None);
assert_eq!(
parse_bpf_upgradeable_loader(&message.instructions[1], &keys[0..8]).unwrap(),
parse_bpf_upgradeable_loader(
&message.instructions[1],
&AccountKeys::new(&keys[0..8], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "deployWithMaxDataLen".to_string(),
info: json!({
@@ -295,13 +342,21 @@ mod test {
}),
}
);
assert!(parse_bpf_upgradeable_loader(&message.instructions[1], &keys[0..7]).is_err());
assert!(parse_bpf_upgradeable_loader(
&message.instructions[1],
&AccountKeys::new(&keys[0..7], None)
)
.is_err());
let instruction =
solana_sdk::bpf_loader_upgradeable::upgrade(&keys[2], &keys[3], &keys[0], &keys[4]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..7]).unwrap(),
parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..7], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "upgrade".to_string(),
info: json!({
@@ -315,13 +370,21 @@ mod test {
}),
}
);
assert!(parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..6]).is_err());
assert!(parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..6], None)
)
.is_err());
let instruction =
solana_sdk::bpf_loader_upgradeable::set_buffer_authority(&keys[1], &keys[0], &keys[2]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..3]).unwrap(),
parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "setAuthority".to_string(),
info: json!({
@@ -331,7 +394,11 @@ mod test {
}),
}
);
assert!(parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let instruction = solana_sdk::bpf_loader_upgradeable::set_upgrade_authority(
&keys[1],
@@ -340,7 +407,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..3]).unwrap(),
parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "setAuthority".to_string(),
info: json!({
@@ -350,13 +421,21 @@ mod test {
}),
}
);
assert!(parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let instruction =
solana_sdk::bpf_loader_upgradeable::set_upgrade_authority(&keys[1], &keys[0], None);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..2]).unwrap(),
parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "setAuthority".to_string(),
info: json!({
@@ -366,12 +445,20 @@ mod test {
}),
}
);
assert!(parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let instruction = solana_sdk::bpf_loader_upgradeable::close(&keys[0], &keys[1], &keys[2]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_bpf_upgradeable_loader(&message.instructions[0], &keys[..3]).unwrap(),
parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "close".to_string(),
info: json!({
@@ -381,6 +468,10 @@ mod test {
}),
}
);
assert!(parse_bpf_upgradeable_loader(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_bpf_upgradeable_loader(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
}
}

View File

@@ -11,7 +11,10 @@ use {
inflector::Inflector,
serde_json::Value,
solana_account_decoder::parse_token::spl_token_id,
solana_sdk::{instruction::CompiledInstruction, pubkey::Pubkey, stake, system_program},
solana_sdk::{
instruction::CompiledInstruction, message::AccountKeys, pubkey::Pubkey, stake,
system_program,
},
std::{
collections::HashMap,
str::{from_utf8, Utf8Error},
@@ -98,7 +101,7 @@ pub enum ParsableProgram {
pub fn parse(
program_id: &Pubkey,
instruction: &CompiledInstruction,
account_keys: &[Pubkey],
account_keys: &AccountKeys,
) -> Result<ParsedInstruction, ParseInstructionError> {
let program_name = PARSABLE_PROGRAM_IDS
.get(program_id)
@@ -156,13 +159,14 @@ mod test {
#[test]
fn test_parse() {
let no_keys = AccountKeys::new(&[], None);
let memo_instruction = CompiledInstruction {
program_id_index: 0,
accounts: vec![],
data: vec![240, 159, 166, 150],
};
assert_eq!(
parse(&MEMO_V1_PROGRAM_ID, &memo_instruction, &[]).unwrap(),
parse(&MEMO_V1_PROGRAM_ID, &memo_instruction, &no_keys).unwrap(),
ParsedInstruction {
program: "spl-memo".to_string(),
program_id: MEMO_V1_PROGRAM_ID.to_string(),
@@ -170,7 +174,7 @@ mod test {
}
);
assert_eq!(
parse(&MEMO_V3_PROGRAM_ID, &memo_instruction, &[]).unwrap(),
parse(&MEMO_V3_PROGRAM_ID, &memo_instruction, &no_keys).unwrap(),
ParsedInstruction {
program: "spl-memo".to_string(),
program_id: MEMO_V3_PROGRAM_ID.to_string(),
@@ -179,7 +183,7 @@ mod test {
);
let non_parsable_program_id = Pubkey::new(&[1; 32]);
assert!(parse(&non_parsable_program_id, &memo_instruction, &[]).is_err());
assert!(parse(&non_parsable_program_id, &memo_instruction, &no_keys).is_err());
}
#[test]

View File

@@ -5,13 +5,14 @@ use {
bincode::deserialize,
serde_json::{json, Map},
solana_sdk::{
instruction::CompiledInstruction, pubkey::Pubkey, stake::instruction::StakeInstruction,
instruction::CompiledInstruction, message::AccountKeys,
stake::instruction::StakeInstruction,
},
};
pub fn parse_stake(
instruction: &CompiledInstruction,
account_keys: &[Pubkey],
account_keys: &AccountKeys,
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
let stake_instruction: StakeInstruction = deserialize(&instruction.data)
.map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::Stake))?;
@@ -312,7 +313,11 @@ mod test {
instruction::create_account(&keys[0], &keys[1], &authorized, &lockup, lamports);
let message = Message::new(&instructions, None);
assert_eq!(
parse_stake(&message.instructions[1], &keys[0..3]).unwrap(),
parse_stake(
&message.instructions[1],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "initialize".to_string(),
info: json!({
@@ -330,13 +335,21 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[1], &keys[0..2]).is_err());
assert!(parse_stake(
&message.instructions[1],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instruction =
instruction::authorize(&keys[1], &keys[0], &keys[3], StakeAuthorize::Staker, None);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..3]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorize".to_string(),
info: json!({
@@ -348,7 +361,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instruction = instruction::authorize(
&keys[2],
@@ -359,7 +376,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..4]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorize".to_string(),
info: json!({
@@ -372,12 +393,20 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instruction = instruction::delegate_stake(&keys[1], &keys[0], &keys[2]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..6]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..6], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "delegate".to_string(),
info: json!({
@@ -390,7 +419,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..5]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..5], None)
)
.is_err());
// This looks wrong, but in an actual compiled instruction, the order is:
// * split account (signer, allocate + assign first)
@@ -399,7 +432,11 @@ mod test {
let instructions = instruction::split(&keys[2], &keys[1], lamports, &keys[0]);
let message = Message::new(&instructions, None);
assert_eq!(
parse_stake(&message.instructions[2], &keys[0..3]).unwrap(),
parse_stake(
&message.instructions[2],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "split".to_string(),
info: json!({
@@ -410,12 +447,20 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[2], &keys[0..2]).is_err());
assert!(parse_stake(
&message.instructions[2],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instruction = instruction::withdraw(&keys[1], &keys[0], &keys[2], lamports, None);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..5]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..5], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "withdraw".to_string(),
info: json!({
@@ -432,7 +477,11 @@ mod test {
instruction::withdraw(&keys[2], &keys[0], &keys[3], lamports, Some(&keys[1]));
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..6]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..6], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "withdraw".to_string(),
info: json!({
@@ -446,12 +495,20 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..4]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.is_err());
let instruction = instruction::deactivate_stake(&keys[1], &keys[0]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..3]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "deactivate".to_string(),
info: json!({
@@ -461,12 +518,20 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instructions = instruction::merge(&keys[1], &keys[0], &keys[2]);
let message = Message::new(&instructions, None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..5]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..5], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "merge".to_string(),
info: json!({
@@ -478,7 +543,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..4]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.is_err());
let seed = "test_seed";
let instruction = instruction::authorize_with_seed(
@@ -492,7 +561,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..3]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorizeWithSeed".to_string(),
info: json!({
@@ -506,7 +579,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instruction = instruction::authorize_with_seed(
&keys[2],
@@ -519,7 +596,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..4]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorizeWithSeed".to_string(),
info: json!({
@@ -534,7 +615,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..3]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.is_err());
}
#[test]
@@ -556,7 +641,11 @@ mod test {
let instruction = instruction::set_lockup(&keys[1], &lockup, &keys[0]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..2]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "setLockup".to_string(),
info: json!({
@@ -577,7 +666,11 @@ mod test {
let instruction = instruction::set_lockup(&keys[1], &lockup, &keys[0]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..2]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "setLockup".to_string(),
info: json!({
@@ -599,7 +692,11 @@ mod test {
let instruction = instruction::set_lockup(&keys[1], &lockup, &keys[0]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..2]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "setLockup".to_string(),
info: json!({
@@ -614,7 +711,11 @@ mod test {
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let lockup = LockupArgs {
unix_timestamp: Some(unix_timestamp),
@@ -624,7 +725,11 @@ mod test {
let instruction = instruction::set_lockup_checked(&keys[1], &lockup, &keys[0]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..2]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "setLockupChecked".to_string(),
info: json!({
@@ -645,7 +750,11 @@ mod test {
let instruction = instruction::set_lockup_checked(&keys[1], &lockup, &keys[0]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..2]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "setLockupChecked".to_string(),
info: json!({
@@ -658,7 +767,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let lockup = LockupArgs {
unix_timestamp: Some(unix_timestamp),
@@ -668,7 +781,11 @@ mod test {
let instruction = instruction::set_lockup_checked(&keys[2], &lockup, &keys[0]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..3]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "setLockupChecked".to_string(),
info: json!({
@@ -682,7 +799,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
}
#[test]
@@ -703,7 +824,11 @@ mod test {
instruction::create_account_checked(&keys[0], &keys[1], &authorized, lamports);
let message = Message::new(&instructions, None);
assert_eq!(
parse_stake(&message.instructions[1], &keys[0..4]).unwrap(),
parse_stake(
&message.instructions[1],
&AccountKeys::new(&keys[0..4], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "initializeChecked".to_string(),
info: json!({
@@ -714,7 +839,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[1], &keys[0..3]).is_err());
assert!(parse_stake(
&message.instructions[1],
&AccountKeys::new(&keys[0..3], None)
)
.is_err());
let instruction = instruction::authorize_checked(
&keys[2],
@@ -725,7 +854,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..4]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorizeChecked".to_string(),
info: json!({
@@ -737,7 +870,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..3]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.is_err());
let instruction = instruction::authorize_checked(
&keys[3],
@@ -748,7 +885,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..5]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..5], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorizeChecked".to_string(),
info: json!({
@@ -761,7 +902,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..4]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.is_err());
let seed = "test_seed";
let instruction = instruction::authorize_checked_with_seed(
@@ -775,7 +920,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..4]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorizeCheckedWithSeed".to_string(),
info: json!({
@@ -789,7 +938,11 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..3]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.is_err());
let instruction = instruction::authorize_checked_with_seed(
&keys[3],
@@ -802,7 +955,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_stake(&message.instructions[0], &keys[0..5]).unwrap(),
parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..5], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorizeCheckedWithSeed".to_string(),
info: json!({
@@ -817,6 +974,10 @@ mod test {
}),
}
);
assert!(parse_stake(&message.instructions[0], &keys[0..4]).is_err());
assert!(parse_stake(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.is_err());
}
}

View File

@@ -5,13 +5,14 @@ use {
bincode::deserialize,
serde_json::json,
solana_sdk::{
instruction::CompiledInstruction, pubkey::Pubkey, system_instruction::SystemInstruction,
instruction::CompiledInstruction, message::AccountKeys,
system_instruction::SystemInstruction,
},
};
pub fn parse_system(
instruction: &CompiledInstruction,
account_keys: &[Pubkey],
account_keys: &AccountKeys,
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
let system_instruction: SystemInstruction = deserialize(&instruction.data)
.map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::System))?;
@@ -219,7 +220,11 @@ mod test {
system_instruction::create_account(&keys[0], &keys[1], lamports, space, &keys[2]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..2]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "createAccount".to_string(),
info: json!({
@@ -231,12 +236,20 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let instruction = system_instruction::assign(&keys[0], &keys[1]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..1]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "assign".to_string(),
info: json!({
@@ -245,12 +258,16 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &[]).is_err());
assert!(parse_system(&message.instructions[0], &AccountKeys::new(&[], None)).is_err());
let instruction = system_instruction::transfer(&keys[0], &keys[1], lamports);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..2]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "transfer".to_string(),
info: json!({
@@ -260,7 +277,11 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let seed = "test_seed";
let instruction = system_instruction::create_account_with_seed(
@@ -268,7 +289,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..3]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "createAccountWithSeed".to_string(),
info: json!({
@@ -289,7 +314,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..2]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "createAccountWithSeed".to_string(),
info: json!({
@@ -303,12 +332,20 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let instruction = system_instruction::allocate(&keys[0], space);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..1]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "allocate".to_string(),
info: json!({
@@ -317,13 +354,17 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &[]).is_err());
assert!(parse_system(&message.instructions[0], &AccountKeys::new(&[], None)).is_err());
let instruction =
system_instruction::allocate_with_seed(&keys[1], &keys[0], seed, space, &keys[2]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..2]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "allocateWithSeed".to_string(),
info: json!({
@@ -335,12 +376,20 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let instruction = system_instruction::assign_with_seed(&keys[1], &keys[0], seed, &keys[2]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..2]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "assignWithSeed".to_string(),
info: json!({
@@ -351,7 +400,11 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let instruction = system_instruction::transfer_with_seed(
&keys[1],
@@ -363,7 +416,11 @@ mod test {
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..3]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "transferWithSeed".to_string(),
info: json!({
@@ -376,7 +433,11 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
}
#[test]
@@ -390,7 +451,11 @@ mod test {
let instruction = system_instruction::advance_nonce_account(&keys[1], &keys[0]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..3]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "advanceNonce".to_string(),
info: json!({
@@ -400,14 +465,22 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let lamports = 55;
let instruction =
system_instruction::withdraw_nonce_account(&keys[1], &keys[0], &keys[2], lamports);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..5]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..5], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "withdrawFromNonce".to_string(),
info: json!({
@@ -420,13 +493,21 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..4]).is_err());
assert!(parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.is_err());
let instructions =
system_instruction::create_nonce_account(&keys[0], &keys[1], &keys[4], lamports);
let message = Message::new(&instructions, None);
assert_eq!(
parse_system(&message.instructions[1], &keys[0..4]).unwrap(),
parse_system(
&message.instructions[1],
&AccountKeys::new(&keys[0..4], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "initializeNonce".to_string(),
info: json!({
@@ -437,12 +518,20 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[1], &keys[0..3]).is_err());
assert!(parse_system(
&message.instructions[1],
&AccountKeys::new(&keys[0..3], None)
)
.is_err());
let instruction = system_instruction::authorize_nonce_account(&keys[1], &keys[0], &keys[2]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..2]).unwrap(),
parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorizeNonce".to_string(),
info: json!({
@@ -452,6 +541,10 @@ mod test {
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_system(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
}
}

View File

@@ -6,7 +6,7 @@ use {
solana_account_decoder::parse_token::{pubkey_from_spl_token, token_amount_to_ui_amount},
solana_sdk::{
instruction::{AccountMeta, CompiledInstruction, Instruction},
pubkey::Pubkey,
message::AccountKeys,
},
spl_token::{
instruction::{AuthorityType, TokenInstruction},
@@ -18,7 +18,7 @@ use {
pub fn parse_token(
instruction: &CompiledInstruction,
account_keys: &[Pubkey],
account_keys: &AccountKeys,
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
let token_instruction = TokenInstruction::unpack(&instruction.data)
.map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::SplToken))?;
@@ -411,7 +411,7 @@ impl From<AuthorityType> for UiAuthorityType {
fn parse_signers(
map: &mut Map<String, Value>,
last_nonsigner_index: usize,
account_keys: &[Pubkey],
account_keys: &AccountKeys,
accounts: &[u8],
owner_field_name: &str,
multisig_field_name: &str,
@@ -458,7 +458,7 @@ pub fn spl_token_instruction(instruction: SplTokenInstruction) -> Instruction {
mod test {
use {
super::*,
solana_sdk::instruction::CompiledInstruction,
solana_sdk::{instruction::CompiledInstruction, pubkey::Pubkey},
spl_token::{
instruction::*,
solana_program::{
@@ -503,7 +503,7 @@ mod test {
let message = Message::new(&[initialize_mint_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "initializeMint".to_string(),
info: json!({
@@ -527,7 +527,7 @@ mod test {
let message = Message::new(&[initialize_mint_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "initializeMint".to_string(),
info: json!({
@@ -550,7 +550,7 @@ mod test {
let message = Message::new(&[initialize_account_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "initializeAccount".to_string(),
info: json!({
@@ -577,7 +577,7 @@ mod test {
let message = Message::new(&[initialize_multisig_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "initializeMultisig".to_string(),
info: json!({
@@ -602,7 +602,7 @@ mod test {
let message = Message::new(&[transfer_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "transfer".to_string(),
info: json!({
@@ -626,7 +626,7 @@ mod test {
let message = Message::new(&[transfer_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "transfer".to_string(),
info: json!({
@@ -652,7 +652,7 @@ mod test {
let message = Message::new(&[approve_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "approve".to_string(),
info: json!({
@@ -676,7 +676,7 @@ mod test {
let message = Message::new(&[approve_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "approve".to_string(),
info: json!({
@@ -700,7 +700,7 @@ mod test {
let message = Message::new(&[revoke_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "revoke".to_string(),
info: json!({
@@ -723,7 +723,7 @@ mod test {
let message = Message::new(&[set_authority_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "setAuthority".to_string(),
info: json!({
@@ -748,7 +748,7 @@ mod test {
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
let new_authority: Option<String> = None;
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "setAuthority".to_string(),
info: json!({
@@ -773,7 +773,7 @@ mod test {
let message = Message::new(&[mint_to_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "mintTo".to_string(),
info: json!({
@@ -798,7 +798,7 @@ mod test {
let message = Message::new(&[burn_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "burn".to_string(),
info: json!({
@@ -822,7 +822,7 @@ mod test {
let message = Message::new(&[close_account_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "closeAccount".to_string(),
info: json!({
@@ -845,7 +845,7 @@ mod test {
let message = Message::new(&[freeze_account_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "freezeAccount".to_string(),
info: json!({
@@ -868,7 +868,7 @@ mod test {
let message = Message::new(&[thaw_account_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "thawAccount".to_string(),
info: json!({
@@ -894,7 +894,7 @@ mod test {
let message = Message::new(&[transfer_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "transferChecked".to_string(),
info: json!({
@@ -926,7 +926,7 @@ mod test {
let message = Message::new(&[transfer_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "transferChecked".to_string(),
info: json!({
@@ -960,7 +960,7 @@ mod test {
let message = Message::new(&[approve_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "approveChecked".to_string(),
info: json!({
@@ -992,7 +992,7 @@ mod test {
let message = Message::new(&[approve_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "approveChecked".to_string(),
info: json!({
@@ -1025,7 +1025,7 @@ mod test {
let message = Message::new(&[mint_to_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "mintToChecked".to_string(),
info: json!({
@@ -1056,7 +1056,7 @@ mod test {
let message = Message::new(&[burn_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "burnChecked".to_string(),
info: json!({
@@ -1078,7 +1078,7 @@ mod test {
let message = Message::new(&[sync_native_ix], None);
let compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert_eq!(
parse_token(&compiled_instruction, &keys).unwrap(),
parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).unwrap(),
ParsedInstructionEnum {
instruction_type: "syncNative".to_string(),
info: json!({
@@ -1107,10 +1107,10 @@ mod test {
.unwrap();
let message = Message::new(&[initialize_mint_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..1]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..1], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
let initialize_mint_ix = initialize_mint(
&spl_token::id(),
@@ -1122,10 +1122,10 @@ mod test {
.unwrap();
let message = Message::new(&[initialize_mint_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..1]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..1], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test InitializeAccount
let initialize_account_ix = initialize_account(
@@ -1137,10 +1137,10 @@ mod test {
.unwrap();
let message = Message::new(&[initialize_account_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..3]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..3], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test InitializeMultisig
let initialize_multisig_ix = initialize_multisig(
@@ -1156,10 +1156,10 @@ mod test {
.unwrap();
let message = Message::new(&[initialize_multisig_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..4]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..4], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 3].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test Transfer, incl multisig
let transfer_ix = transfer(
@@ -1173,10 +1173,10 @@ mod test {
.unwrap();
let message = Message::new(&[transfer_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..2]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
let transfer_ix = transfer(
&spl_token::id(),
@@ -1189,10 +1189,10 @@ mod test {
.unwrap();
let message = Message::new(&[transfer_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..4]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..4], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 3].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test Approve, incl multisig
let approve_ix = approve(
@@ -1206,10 +1206,10 @@ mod test {
.unwrap();
let message = Message::new(&[approve_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..2]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
let approve_ix = approve(
&spl_token::id(),
@@ -1222,10 +1222,10 @@ mod test {
.unwrap();
let message = Message::new(&[approve_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..4]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..4], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 3].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test Revoke
let revoke_ix = revoke(
@@ -1237,10 +1237,10 @@ mod test {
.unwrap();
let message = Message::new(&[revoke_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..1]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..1], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test SetAuthority
let set_authority_ix = set_authority(
@@ -1254,10 +1254,10 @@ mod test {
.unwrap();
let message = Message::new(&[set_authority_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..1]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..1], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test MintTo
let mint_to_ix = mint_to(
@@ -1271,10 +1271,10 @@ mod test {
.unwrap();
let message = Message::new(&[mint_to_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..2]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test Burn
let burn_ix = burn(
@@ -1288,10 +1288,10 @@ mod test {
.unwrap();
let message = Message::new(&[burn_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..2]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test CloseAccount
let close_account_ix = close_account(
@@ -1304,10 +1304,10 @@ mod test {
.unwrap();
let message = Message::new(&[close_account_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..2]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test FreezeAccount
let freeze_account_ix = freeze_account(
@@ -1320,10 +1320,10 @@ mod test {
.unwrap();
let message = Message::new(&[freeze_account_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..2]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test ThawAccount
let thaw_account_ix = thaw_account(
@@ -1336,10 +1336,10 @@ mod test {
.unwrap();
let message = Message::new(&[thaw_account_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..2]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test TransferChecked, incl multisig
let transfer_ix = transfer_checked(
@@ -1355,10 +1355,10 @@ mod test {
.unwrap();
let message = Message::new(&[transfer_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..3]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..3], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
let transfer_ix = transfer_checked(
&spl_token::id(),
@@ -1373,10 +1373,10 @@ mod test {
.unwrap();
let message = Message::new(&[transfer_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..5]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..5], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 3].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test ApproveChecked, incl multisig
let approve_ix = approve_checked(
@@ -1392,10 +1392,10 @@ mod test {
.unwrap();
let message = Message::new(&[approve_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..3]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..3], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
let approve_ix = approve_checked(
&spl_token::id(),
@@ -1410,10 +1410,10 @@ mod test {
.unwrap();
let message = Message::new(&[approve_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..5]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..5], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 3].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test MintToChecked
let mint_to_ix = mint_to_checked(
@@ -1428,10 +1428,10 @@ mod test {
.unwrap();
let message = Message::new(&[mint_to_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..2]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test BurnChecked
let burn_ix = burn_checked(
@@ -1446,18 +1446,18 @@ mod test {
.unwrap();
let message = Message::new(&[burn_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &keys[0..2]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys[0..2], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
// Test SyncNative
let sync_native_ix = sync_native(&spl_token::id(), &convert_pubkey(keys[0])).unwrap();
let message = Message::new(&[sync_native_ix], None);
let mut compiled_instruction = convert_compiled_instruction(&message.instructions[0]);
assert!(parse_token(&compiled_instruction, &[]).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&[], None)).is_err());
compiled_instruction.accounts =
compiled_instruction.accounts[0..compiled_instruction.accounts.len() - 1].to_vec();
assert!(parse_token(&compiled_instruction, &keys).is_err());
assert!(parse_token(&compiled_instruction, &AccountKeys::new(&keys, None)).is_err());
}
}

View File

@@ -4,13 +4,13 @@ use {
},
bincode::deserialize,
serde_json::json,
solana_sdk::{instruction::CompiledInstruction, pubkey::Pubkey},
solana_sdk::{instruction::CompiledInstruction, message::AccountKeys},
solana_vote_program::vote_instruction::VoteInstruction,
};
pub fn parse_vote(
instruction: &CompiledInstruction,
account_keys: &[Pubkey],
account_keys: &AccountKeys,
) -> Result<ParsedInstructionEnum, ParseInstructionError> {
let vote_instruction: VoteInstruction = deserialize(&instruction.data)
.map_err(|_| ParseInstructionError::InstructionNotParsable(ParsableProgram::Vote))?;
@@ -227,7 +227,11 @@ mod test {
);
let message = Message::new(&instructions, None);
assert_eq!(
parse_vote(&message.instructions[1], &keys[0..5]).unwrap(),
parse_vote(
&message.instructions[1],
&AccountKeys::new(&keys[0..5], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "initialize".to_string(),
info: json!({
@@ -241,13 +245,21 @@ mod test {
}),
}
);
assert!(parse_vote(&message.instructions[1], &keys[0..3]).is_err());
assert!(parse_vote(
&message.instructions[1],
&AccountKeys::new(&keys[0..3], None)
)
.is_err());
let authority_type = VoteAuthorize::Voter;
let instruction = vote_instruction::authorize(&keys[1], &keys[0], &keys[3], authority_type);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_vote(&message.instructions[0], &keys[0..3]).unwrap(),
parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorize".to_string(),
info: json!({
@@ -259,12 +271,20 @@ mod test {
}),
}
);
assert!(parse_vote(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instruction = vote_instruction::vote(&keys[1], &keys[0], vote.clone());
let message = Message::new(&[instruction], None);
assert_eq!(
parse_vote(&message.instructions[0], &keys[0..4]).unwrap(),
parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "vote".to_string(),
info: json!({
@@ -280,12 +300,20 @@ mod test {
}),
}
);
assert!(parse_vote(&message.instructions[0], &keys[0..3]).is_err());
assert!(parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.is_err());
let instruction = vote_instruction::withdraw(&keys[1], &keys[0], lamports, &keys[2]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_vote(&message.instructions[0], &keys[0..3]).unwrap(),
parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "withdraw".to_string(),
info: json!({
@@ -296,12 +324,20 @@ mod test {
}),
}
);
assert!(parse_vote(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instruction = vote_instruction::update_validator_identity(&keys[2], &keys[1], &keys[0]);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_vote(&message.instructions[0], &keys[0..3]).unwrap(),
parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "updateValidatorIdentity".to_string(),
info: json!({
@@ -311,12 +347,20 @@ mod test {
}),
}
);
assert!(parse_vote(&message.instructions[0], &keys[0..2]).is_err());
assert!(parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.is_err());
let instruction = vote_instruction::update_commission(&keys[1], &keys[0], commission);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_vote(&message.instructions[0], &keys[0..2]).unwrap(),
parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..2], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "updateCommission".to_string(),
info: json!({
@@ -326,13 +370,21 @@ mod test {
}),
}
);
assert!(parse_vote(&message.instructions[0], &keys[0..1]).is_err());
assert!(parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..1], None)
)
.is_err());
let proof_hash = Hash::new_from_array([2; 32]);
let instruction = vote_instruction::vote_switch(&keys[1], &keys[0], vote, proof_hash);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_vote(&message.instructions[0], &keys[0..4]).unwrap(),
parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "voteSwitch".to_string(),
info: json!({
@@ -349,14 +401,22 @@ mod test {
}),
}
);
assert!(parse_vote(&message.instructions[0], &keys[0..3]).is_err());
assert!(parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.is_err());
let authority_type = VoteAuthorize::Voter;
let instruction =
vote_instruction::authorize_checked(&keys[1], &keys[0], &keys[3], authority_type);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_vote(&message.instructions[0], &keys[0..4]).unwrap(),
parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..4], None)
)
.unwrap(),
ParsedInstructionEnum {
instruction_type: "authorizeChecked".to_string(),
info: json!({
@@ -368,6 +428,10 @@ mod test {
}),
}
);
assert!(parse_vote(&message.instructions[0], &keys[0..3]).is_err());
assert!(parse_vote(
&message.instructions[0],
&AccountKeys::new(&keys[0..3], None)
)
.is_err());
}
}

View File

@@ -62,14 +62,12 @@ pub fn collect_token_balances(
let mut collect_time = Measure::start("collect_token_balances");
for transaction in batch.sanitized_transactions() {
let has_token_program = transaction
.message()
.account_keys_iter()
.any(is_token_program);
let account_keys = transaction.message().account_keys();
let has_token_program = account_keys.iter().any(is_token_program);
let mut transaction_balances: Vec<TransactionTokenBalance> = vec![];
if has_token_program {
for (index, account_id) in transaction.message().account_keys_iter().enumerate() {
for (index, account_id) in account_keys.iter().enumerate() {
if transaction.message().is_invoked(index) || is_token_program(account_id) {
continue;
}