use { crate::{StoredExtendedRewards, StoredTransactionStatusMeta}, solana_account_decoder::parse_token::{real_number_string_trimmed, UiTokenAmount}, solana_sdk::{ hash::Hash, instruction::CompiledInstruction, instruction::InstructionError, message::{Message, MessageHeader}, pubkey::Pubkey, signature::Signature, transaction::Transaction, transaction::TransactionError, }, solana_transaction_status::{ ConfirmedBlock, InnerInstructions, Reward, RewardType, TransactionByAddrInfo, TransactionStatusMeta, TransactionTokenBalance, TransactionWithStatusMeta, }, std::{ convert::{TryFrom, TryInto}, str::FromStr, }, }; pub mod generated { include!(concat!( env!("OUT_DIR"), "/solana.storage.confirmed_block.rs" )); } pub mod tx_by_addr { include!(concat!( env!("OUT_DIR"), "/solana.storage.transaction_by_addr.rs" )); } impl From> for generated::Rewards { fn from(rewards: Vec) -> Self { Self { rewards: rewards.into_iter().map(|r| r.into()).collect(), } } } impl From for Vec { fn from(rewards: generated::Rewards) -> Self { rewards.rewards.into_iter().map(|r| r.into()).collect() } } impl From for generated::Rewards { fn from(rewards: StoredExtendedRewards) -> Self { Self { rewards: rewards .into_iter() .map(|r| { let r: Reward = r.into(); r.into() }) .collect(), } } } impl From for StoredExtendedRewards { fn from(rewards: generated::Rewards) -> Self { rewards .rewards .into_iter() .map(|r| { let r: Reward = r.into(); r.into() }) .collect() } } impl From for generated::Reward { fn from(reward: Reward) -> Self { Self { pubkey: reward.pubkey, lamports: reward.lamports, post_balance: reward.post_balance, reward_type: match reward.reward_type { None => generated::RewardType::Unspecified, Some(RewardType::Fee) => generated::RewardType::Fee, Some(RewardType::Rent) => generated::RewardType::Rent, Some(RewardType::Staking) => generated::RewardType::Staking, Some(RewardType::Voting) => generated::RewardType::Voting, } as i32, } } } impl From for Reward { fn from(reward: generated::Reward) -> Self { Self { pubkey: reward.pubkey, lamports: reward.lamports, post_balance: reward.post_balance, reward_type: match reward.reward_type { 0 => None, 1 => Some(RewardType::Fee), 2 => Some(RewardType::Rent), 3 => Some(RewardType::Staking), 4 => Some(RewardType::Voting), _ => None, }, } } } impl From for generated::ConfirmedBlock { fn from(confirmed_block: ConfirmedBlock) -> Self { let ConfirmedBlock { previous_blockhash, blockhash, parent_slot, transactions, rewards, block_time, block_height, } = confirmed_block; Self { previous_blockhash, blockhash, parent_slot, transactions: transactions.into_iter().map(|tx| tx.into()).collect(), rewards: rewards.into_iter().map(|r| r.into()).collect(), block_time: block_time.map(|timestamp| generated::UnixTimestamp { timestamp }), block_height: block_height.map(|block_height| generated::BlockHeight { block_height }), } } } impl TryFrom for ConfirmedBlock { type Error = bincode::Error; fn try_from( confirmed_block: generated::ConfirmedBlock, ) -> std::result::Result { let generated::ConfirmedBlock { previous_blockhash, blockhash, parent_slot, transactions, rewards, block_time, block_height, } = confirmed_block; Ok(Self { previous_blockhash, blockhash, parent_slot, transactions: transactions .into_iter() .map(|tx| tx.try_into()) .collect::, Self::Error>>()?, rewards: rewards.into_iter().map(|r| r.into()).collect(), block_time: block_time.map(|generated::UnixTimestamp { timestamp }| timestamp), block_height: block_height.map(|generated::BlockHeight { block_height }| block_height), }) } } impl From for generated::ConfirmedTransaction { fn from(value: TransactionWithStatusMeta) -> Self { let meta = value.meta.map(|meta| meta.into()); Self { transaction: Some(value.transaction.into()), meta, } } } impl TryFrom for TransactionWithStatusMeta { type Error = bincode::Error; fn try_from(value: generated::ConfirmedTransaction) -> std::result::Result { let meta = value.meta.map(|meta| meta.try_into()).transpose()?; Ok(Self { transaction: value.transaction.expect("transaction is required").into(), meta, }) } } impl From for generated::Transaction { fn from(value: Transaction) -> Self { Self { signatures: value .signatures .into_iter() .map(|signature| >::as_ref(&signature).into()) .collect(), message: Some(value.message.into()), } } } impl From for Transaction { fn from(value: generated::Transaction) -> Self { Self { signatures: value .signatures .into_iter() .map(|x| Signature::new(&x)) .collect(), message: value.message.expect("message is required").into(), } } } impl From for generated::Message { fn from(value: Message) -> Self { Self { header: Some(value.header.into()), account_keys: value .account_keys .into_iter() .map(|key| >::as_ref(&key).into()) .collect(), recent_blockhash: value.recent_blockhash.to_bytes().into(), instructions: value.instructions.into_iter().map(|ix| ix.into()).collect(), } } } impl From for Message { fn from(value: generated::Message) -> Self { Self { header: value.header.expect("header is required").into(), account_keys: value .account_keys .into_iter() .map(|key| Pubkey::new(&key)) .collect(), recent_blockhash: Hash::new(&value.recent_blockhash), instructions: value.instructions.into_iter().map(|ix| ix.into()).collect(), } } } impl From for generated::MessageHeader { fn from(value: MessageHeader) -> Self { Self { num_required_signatures: value.num_required_signatures as u32, num_readonly_signed_accounts: value.num_readonly_signed_accounts as u32, num_readonly_unsigned_accounts: value.num_readonly_unsigned_accounts as u32, } } } impl From for MessageHeader { fn from(value: generated::MessageHeader) -> Self { Self { num_required_signatures: value.num_required_signatures as u8, num_readonly_signed_accounts: value.num_readonly_signed_accounts as u8, num_readonly_unsigned_accounts: value.num_readonly_unsigned_accounts as u8, } } } impl From for generated::TransactionStatusMeta { fn from(value: TransactionStatusMeta) -> Self { let TransactionStatusMeta { status, fee, pre_balances, post_balances, inner_instructions, log_messages, pre_token_balances, post_token_balances, rewards, } = value; let err = match status { Ok(()) => None, Err(err) => Some(generated::TransactionError { err: bincode::serialize(&err).expect("transaction error to serialize to bytes"), }), }; let inner_instructions = inner_instructions .unwrap_or_default() .into_iter() .map(|ii| ii.into()) .collect(); let log_messages = log_messages.unwrap_or_default(); let pre_token_balances = pre_token_balances .unwrap_or_default() .into_iter() .map(|balance| balance.into()) .collect(); let post_token_balances = post_token_balances .unwrap_or_default() .into_iter() .map(|balance| balance.into()) .collect(); let rewards = rewards .unwrap_or_default() .into_iter() .map(|reward| reward.into()) .collect(); Self { err, fee, pre_balances, post_balances, inner_instructions, log_messages, pre_token_balances, post_token_balances, rewards, } } } impl From for generated::TransactionStatusMeta { fn from(meta: StoredTransactionStatusMeta) -> Self { let meta: TransactionStatusMeta = meta.into(); meta.into() } } impl TryFrom for TransactionStatusMeta { type Error = bincode::Error; fn try_from(value: generated::TransactionStatusMeta) -> std::result::Result { let generated::TransactionStatusMeta { err, fee, pre_balances, post_balances, inner_instructions, log_messages, pre_token_balances, post_token_balances, rewards, } = value; let status = match &err { None => Ok(()), Some(tx_error) => Err(bincode::deserialize(&tx_error.err)?), }; let inner_instructions = Some( inner_instructions .into_iter() .map(|inner| inner.into()) .collect(), ); let log_messages = Some(log_messages); let pre_token_balances = Some( pre_token_balances .into_iter() .map(|balance| balance.into()) .collect(), ); let post_token_balances = Some( post_token_balances .into_iter() .map(|balance| balance.into()) .collect(), ); let rewards = Some(rewards.into_iter().map(|reward| reward.into()).collect()); Ok(Self { status, fee, pre_balances, post_balances, inner_instructions, log_messages, pre_token_balances, post_token_balances, rewards, }) } } impl From for generated::InnerInstructions { fn from(value: InnerInstructions) -> Self { Self { index: value.index as u32, instructions: value.instructions.into_iter().map(|i| i.into()).collect(), } } } impl From for InnerInstructions { fn from(value: generated::InnerInstructions) -> Self { Self { index: value.index as u8, instructions: value.instructions.into_iter().map(|i| i.into()).collect(), } } } impl From for generated::TokenBalance { fn from(value: TransactionTokenBalance) -> Self { Self { account_index: value.account_index as u32, mint: value.mint, ui_token_amount: Some(generated::UiTokenAmount { ui_amount: value.ui_token_amount.ui_amount.unwrap_or_default(), decimals: value.ui_token_amount.decimals as u32, amount: value.ui_token_amount.amount, ui_amount_string: value.ui_token_amount.ui_amount_string, }), } } } impl From for TransactionTokenBalance { fn from(value: generated::TokenBalance) -> Self { let ui_token_amount = value.ui_token_amount.unwrap_or_default(); Self { account_index: value.account_index as u8, mint: value.mint, ui_token_amount: UiTokenAmount { ui_amount: if (ui_token_amount.ui_amount - f64::default()).abs() > f64::EPSILON { Some(ui_token_amount.ui_amount) } else { None }, decimals: ui_token_amount.decimals as u8, amount: ui_token_amount.amount.clone(), ui_amount_string: if !ui_token_amount.ui_amount_string.is_empty() { ui_token_amount.ui_amount_string } else { real_number_string_trimmed( u64::from_str(&ui_token_amount.amount).unwrap_or_default(), ui_token_amount.decimals as u8, ) }, }, } } } impl From for generated::CompiledInstruction { fn from(value: CompiledInstruction) -> Self { Self { program_id_index: value.program_id_index as u32, accounts: value.accounts, data: value.data, } } } impl From for CompiledInstruction { fn from(value: generated::CompiledInstruction) -> Self { Self { program_id_index: value.program_id_index as u8, accounts: value.accounts, data: value.data, } } } impl TryFrom for TransactionError { type Error = &'static str; fn try_from(transaction_error: tx_by_addr::TransactionError) -> Result { if transaction_error.transaction_error == 8 { if let Some(instruction_error) = transaction_error.instruction_error { if let Some(custom) = instruction_error.custom { return Ok(TransactionError::InstructionError( instruction_error.index as u8, InstructionError::Custom(custom.custom), )); } let ie = match instruction_error.error { 0 => InstructionError::GenericError, 1 => InstructionError::InvalidArgument, 2 => InstructionError::InvalidInstructionData, 3 => InstructionError::InvalidAccountData, 4 => InstructionError::AccountDataTooSmall, 5 => InstructionError::InsufficientFunds, 6 => InstructionError::IncorrectProgramId, 7 => InstructionError::MissingRequiredSignature, 8 => InstructionError::AccountAlreadyInitialized, 9 => InstructionError::UninitializedAccount, 10 => InstructionError::UnbalancedInstruction, 11 => InstructionError::ModifiedProgramId, 12 => InstructionError::ExternalAccountLamportSpend, 13 => InstructionError::ExternalAccountDataModified, 14 => InstructionError::ReadonlyLamportChange, 15 => InstructionError::ReadonlyDataModified, 16 => InstructionError::DuplicateAccountIndex, 17 => InstructionError::ExecutableModified, 18 => InstructionError::RentEpochModified, 19 => InstructionError::NotEnoughAccountKeys, 20 => InstructionError::AccountDataSizeChanged, 21 => InstructionError::AccountNotExecutable, 22 => InstructionError::AccountBorrowFailed, 23 => InstructionError::AccountBorrowOutstanding, 24 => InstructionError::DuplicateAccountOutOfSync, 26 => InstructionError::InvalidError, 27 => InstructionError::ExecutableDataModified, 28 => InstructionError::ExecutableLamportChange, 29 => InstructionError::ExecutableAccountNotRentExempt, 30 => InstructionError::UnsupportedProgramId, 31 => InstructionError::CallDepth, 32 => InstructionError::MissingAccount, 33 => InstructionError::ReentrancyNotAllowed, 34 => InstructionError::MaxSeedLengthExceeded, 35 => InstructionError::InvalidSeeds, 36 => InstructionError::InvalidRealloc, 37 => InstructionError::ComputationalBudgetExceeded, 38 => InstructionError::PrivilegeEscalation, 39 => InstructionError::ProgramEnvironmentSetupFailure, 40 => InstructionError::ProgramFailedToComplete, 41 => InstructionError::ProgramFailedToCompile, 42 => InstructionError::Immutable, 43 => InstructionError::IncorrectAuthority, 44 => InstructionError::BorshIoError(String::new()), 45 => InstructionError::AccountNotRentExempt, 46 => InstructionError::InvalidAccountOwner, 47 => InstructionError::ArithmeticOverflow, 48 => InstructionError::UnsupportedSysvar, _ => return Err("Invalid InstructionError"), }; return Ok(TransactionError::InstructionError( instruction_error.index as u8, ie, )); } } Ok(match transaction_error.transaction_error { 0 => TransactionError::AccountInUse, 1 => TransactionError::AccountLoadedTwice, 2 => TransactionError::AccountNotFound, 3 => TransactionError::ProgramAccountNotFound, 4 => TransactionError::InsufficientFundsForFee, 5 => TransactionError::InvalidAccountForFee, 6 => TransactionError::AlreadyProcessed, 7 => TransactionError::BlockhashNotFound, 9 => TransactionError::CallChainTooDeep, 10 => TransactionError::MissingSignatureForFee, 11 => TransactionError::InvalidAccountIndex, 12 => TransactionError::SignatureFailure, 13 => TransactionError::InvalidProgramForExecution, 14 => TransactionError::SanitizeFailure, 15 => TransactionError::ClusterMaintenance, 16 => TransactionError::AccountBorrowOutstanding, _ => return Err("Invalid TransactionError"), }) } } impl From for tx_by_addr::TransactionError { fn from(transaction_error: TransactionError) -> Self { Self { transaction_error: match transaction_error { TransactionError::AccountInUse => tx_by_addr::TransactionErrorType::AccountInUse, TransactionError::AccountLoadedTwice => { tx_by_addr::TransactionErrorType::AccountLoadedTwice } TransactionError::AccountNotFound => { tx_by_addr::TransactionErrorType::AccountNotFound } TransactionError::ProgramAccountNotFound => { tx_by_addr::TransactionErrorType::ProgramAccountNotFound } TransactionError::InsufficientFundsForFee => { tx_by_addr::TransactionErrorType::InsufficientFundsForFee } TransactionError::InvalidAccountForFee => { tx_by_addr::TransactionErrorType::InvalidAccountForFee } TransactionError::AlreadyProcessed => { tx_by_addr::TransactionErrorType::AlreadyProcessed } TransactionError::BlockhashNotFound => { tx_by_addr::TransactionErrorType::BlockhashNotFound } TransactionError::CallChainTooDeep => { tx_by_addr::TransactionErrorType::CallChainTooDeep } TransactionError::MissingSignatureForFee => { tx_by_addr::TransactionErrorType::MissingSignatureForFee } TransactionError::InvalidAccountIndex => { tx_by_addr::TransactionErrorType::InvalidAccountIndex } TransactionError::SignatureFailure => { tx_by_addr::TransactionErrorType::SignatureFailure } TransactionError::InvalidProgramForExecution => { tx_by_addr::TransactionErrorType::InvalidProgramForExecution } TransactionError::SanitizeFailure => { tx_by_addr::TransactionErrorType::SanitizeFailure } TransactionError::ClusterMaintenance => { tx_by_addr::TransactionErrorType::ClusterMaintenance } TransactionError::InstructionError(_, _) => { tx_by_addr::TransactionErrorType::InstructionError } TransactionError::AccountBorrowOutstanding => { tx_by_addr::TransactionErrorType::AccountBorrowOutstandingTx } } as i32, instruction_error: match transaction_error { TransactionError::InstructionError(index, ref instruction_error) => { Some(tx_by_addr::InstructionError { index: index as u32, error: match instruction_error { InstructionError::GenericError => { tx_by_addr::InstructionErrorType::GenericError } InstructionError::InvalidArgument => { tx_by_addr::InstructionErrorType::InvalidArgument } InstructionError::InvalidInstructionData => { tx_by_addr::InstructionErrorType::InvalidInstructionData } InstructionError::InvalidAccountData => { tx_by_addr::InstructionErrorType::InvalidAccountData } InstructionError::AccountDataTooSmall => { tx_by_addr::InstructionErrorType::AccountDataTooSmall } InstructionError::InsufficientFunds => { tx_by_addr::InstructionErrorType::InsufficientFunds } InstructionError::IncorrectProgramId => { tx_by_addr::InstructionErrorType::IncorrectProgramId } InstructionError::MissingRequiredSignature => { tx_by_addr::InstructionErrorType::MissingRequiredSignature } InstructionError::AccountAlreadyInitialized => { tx_by_addr::InstructionErrorType::AccountAlreadyInitialized } InstructionError::UninitializedAccount => { tx_by_addr::InstructionErrorType::UninitializedAccount } InstructionError::UnbalancedInstruction => { tx_by_addr::InstructionErrorType::UnbalancedInstruction } InstructionError::ModifiedProgramId => { tx_by_addr::InstructionErrorType::ModifiedProgramId } InstructionError::ExternalAccountLamportSpend => { tx_by_addr::InstructionErrorType::ExternalAccountLamportSpend } InstructionError::ExternalAccountDataModified => { tx_by_addr::InstructionErrorType::ExternalAccountDataModified } InstructionError::ReadonlyLamportChange => { tx_by_addr::InstructionErrorType::ReadonlyLamportChange } InstructionError::ReadonlyDataModified => { tx_by_addr::InstructionErrorType::ReadonlyDataModified } InstructionError::DuplicateAccountIndex => { tx_by_addr::InstructionErrorType::DuplicateAccountIndex } InstructionError::ExecutableModified => { tx_by_addr::InstructionErrorType::ExecutableModified } InstructionError::RentEpochModified => { tx_by_addr::InstructionErrorType::RentEpochModified } InstructionError::NotEnoughAccountKeys => { tx_by_addr::InstructionErrorType::NotEnoughAccountKeys } InstructionError::AccountDataSizeChanged => { tx_by_addr::InstructionErrorType::AccountDataSizeChanged } InstructionError::AccountNotExecutable => { tx_by_addr::InstructionErrorType::AccountNotExecutable } InstructionError::AccountBorrowFailed => { tx_by_addr::InstructionErrorType::AccountBorrowFailed } InstructionError::AccountBorrowOutstanding => { tx_by_addr::InstructionErrorType::AccountBorrowOutstanding } InstructionError::DuplicateAccountOutOfSync => { tx_by_addr::InstructionErrorType::DuplicateAccountOutOfSync } InstructionError::Custom(_) => tx_by_addr::InstructionErrorType::Custom, InstructionError::InvalidError => { tx_by_addr::InstructionErrorType::InvalidError } InstructionError::ExecutableDataModified => { tx_by_addr::InstructionErrorType::ExecutableDataModified } InstructionError::ExecutableLamportChange => { tx_by_addr::InstructionErrorType::ExecutableLamportChange } InstructionError::ExecutableAccountNotRentExempt => { tx_by_addr::InstructionErrorType::ExecutableAccountNotRentExempt } InstructionError::UnsupportedProgramId => { tx_by_addr::InstructionErrorType::UnsupportedProgramId } InstructionError::CallDepth => { tx_by_addr::InstructionErrorType::CallDepth } InstructionError::MissingAccount => { tx_by_addr::InstructionErrorType::MissingAccount } InstructionError::ReentrancyNotAllowed => { tx_by_addr::InstructionErrorType::ReentrancyNotAllowed } InstructionError::MaxSeedLengthExceeded => { tx_by_addr::InstructionErrorType::MaxSeedLengthExceeded } InstructionError::InvalidSeeds => { tx_by_addr::InstructionErrorType::InvalidSeeds } InstructionError::InvalidRealloc => { tx_by_addr::InstructionErrorType::InvalidRealloc } InstructionError::ComputationalBudgetExceeded => { tx_by_addr::InstructionErrorType::ComputationalBudgetExceeded } InstructionError::PrivilegeEscalation => { tx_by_addr::InstructionErrorType::PrivilegeEscalation } InstructionError::ProgramEnvironmentSetupFailure => { tx_by_addr::InstructionErrorType::ProgramEnvironmentSetupFailure } InstructionError::ProgramFailedToComplete => { tx_by_addr::InstructionErrorType::ProgramFailedToComplete } InstructionError::ProgramFailedToCompile => { tx_by_addr::InstructionErrorType::ProgramFailedToCompile } InstructionError::Immutable => { tx_by_addr::InstructionErrorType::Immutable } InstructionError::IncorrectAuthority => { tx_by_addr::InstructionErrorType::IncorrectAuthority } InstructionError::BorshIoError(_) => { tx_by_addr::InstructionErrorType::BorshIoError } InstructionError::AccountNotRentExempt => { tx_by_addr::InstructionErrorType::AccountNotRentExempt } InstructionError::InvalidAccountOwner => { tx_by_addr::InstructionErrorType::InvalidAccountOwner } InstructionError::ArithmeticOverflow => { tx_by_addr::InstructionErrorType::ArithmeticOverflow } InstructionError::UnsupportedSysvar => { tx_by_addr::InstructionErrorType::UnsupportedSysvar } InstructionError::IllegalOwner => { tx_by_addr::InstructionErrorType::IllegalOwner } } as i32, custom: match instruction_error { InstructionError::Custom(custom) => { Some(tx_by_addr::CustomError { custom: *custom }) } _ => None, }, }) } _ => None, }, } } } impl From for tx_by_addr::TransactionByAddrInfo { fn from(by_addr: TransactionByAddrInfo) -> Self { let TransactionByAddrInfo { signature, err, index, memo, block_time, } = by_addr; Self { signature: >::as_ref(&signature).into(), err: err.map(|e| e.into()), index, memo: memo.map(|memo| tx_by_addr::Memo { memo }), block_time: block_time.map(|timestamp| tx_by_addr::UnixTimestamp { timestamp }), } } } impl TryFrom for TransactionByAddrInfo { type Error = &'static str; fn try_from( transaction_by_addr: tx_by_addr::TransactionByAddrInfo, ) -> Result { let err = transaction_by_addr .err .map(|err| err.try_into()) .transpose()?; Ok(Self { signature: Signature::new(&transaction_by_addr.signature), err, index: transaction_by_addr.index, memo: transaction_by_addr .memo .map(|tx_by_addr::Memo { memo }| memo), block_time: transaction_by_addr .block_time .map(|tx_by_addr::UnixTimestamp { timestamp }| timestamp), }) } } impl TryFrom for Vec { type Error = &'static str; fn try_from(collection: tx_by_addr::TransactionByAddr) -> Result { collection .tx_by_addrs .into_iter() .map(|tx_by_addr| tx_by_addr.try_into()) .collect::, Self::Error>>() } } #[cfg(test)] mod test { use super::*; #[test] fn test_reward_type_encode() { let mut reward = Reward { pubkey: "invalid".to_string(), lamports: 123, post_balance: 321, reward_type: None, }; let gen_reward: generated::Reward = reward.clone().into(); assert_eq!(reward, gen_reward.into()); reward.reward_type = Some(RewardType::Fee); let gen_reward: generated::Reward = reward.clone().into(); assert_eq!(reward, gen_reward.into()); reward.reward_type = Some(RewardType::Rent); let gen_reward: generated::Reward = reward.clone().into(); assert_eq!(reward, gen_reward.into()); reward.reward_type = Some(RewardType::Voting); let gen_reward: generated::Reward = reward.clone().into(); assert_eq!(reward, gen_reward.into()); reward.reward_type = Some(RewardType::Staking); let gen_reward: generated::Reward = reward.clone().into(); assert_eq!(reward, gen_reward.into()); } #[test] fn test_transaction_by_addr_encode() { let info = TransactionByAddrInfo { signature: Signature::new(&bs58::decode("Nfo6rgemG1KLbk1xuNwfrQTsdxaGfLuWURHNRy9LYnDrubG7LFQZaA5obPNas9LQ6DdorJqxh2LxA3PsnWdkSrL").into_vec().unwrap()), err: None, index: 5, memo: Some("string".to_string()), block_time: Some(1610674861) }; let tx_by_addr_transaction_info: tx_by_addr::TransactionByAddrInfo = info.clone().into(); assert_eq!(info, tx_by_addr_transaction_info.try_into().unwrap()); } #[test] fn test_transaction_error_encode() { let transaction_error = TransactionError::AccountInUse; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::AccountLoadedTwice; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::AccountNotFound; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::BlockhashNotFound; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::CallChainTooDeep; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::ClusterMaintenance; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::AlreadyProcessed; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InsufficientFundsForFee; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InvalidAccountForFee; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InvalidAccountIndex; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InvalidProgramForExecution; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::MissingSignatureForFee; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::ProgramAccountNotFound; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::SanitizeFailure; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::SignatureFailure; let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::AccountAlreadyInitialized); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::AccountBorrowFailed); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::AccountBorrowOutstanding); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::AccountDataSizeChanged); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::AccountDataTooSmall); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::AccountNotExecutable); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::CallDepth); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ComputationalBudgetExceeded); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::DuplicateAccountIndex); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::DuplicateAccountOutOfSync); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError( 10, InstructionError::ExecutableAccountNotRentExempt, ); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ExecutableDataModified); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ExecutableLamportChange); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ExecutableModified); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ExternalAccountDataModified); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ExternalAccountLamportSpend); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::GenericError); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::Immutable); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::IncorrectAuthority); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::IncorrectProgramId); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::InsufficientFunds); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::InvalidAccountData); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::InvalidArgument); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::InvalidError); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::InvalidInstructionData); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::InvalidRealloc); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::InvalidSeeds); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::MaxSeedLengthExceeded); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::MissingAccount); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::MissingRequiredSignature); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ModifiedProgramId); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::NotEnoughAccountKeys); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::PrivilegeEscalation); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError( 10, InstructionError::ProgramEnvironmentSetupFailure, ); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ProgramFailedToCompile); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ProgramFailedToComplete); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ReadonlyDataModified); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ReadonlyLamportChange); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::ReentrancyNotAllowed); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::RentEpochModified); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::UnbalancedInstruction); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::UninitializedAccount); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::UnsupportedProgramId); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); let transaction_error = TransactionError::InstructionError(10, InstructionError::Custom(10)); let tx_by_addr_transaction_error: tx_by_addr::TransactionError = transaction_error.clone().into(); assert_eq!( transaction_error, tx_by_addr_transaction_error.try_into().unwrap() ); } }