diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 2ce883816c..e30cf085e2 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -39,13 +39,13 @@ use solana_sdk::{ bpf_loader, clock::{Epoch, Slot, DEFAULT_TICKS_PER_SECOND}, commitment_config::CommitmentConfig, + decode_error::DecodeError, fee_calculator::FeeCalculator, hash::Hash, instruction::InstructionError, loader_instruction, message::Message, native_token::lamports_to_sol, - program_utils::DecodeError, pubkey::{Pubkey, MAX_SEED_LEN}, signature::{Keypair, Signature, Signer, SignerError}, signers::Signers, diff --git a/programs/bpf/rust/error_handling/src/lib.rs b/programs/bpf/rust/error_handling/src/lib.rs index 6a33ce2a8c..37c2df5017 100644 --- a/programs/bpf/rust/error_handling/src/lib.rs +++ b/programs/bpf/rust/error_handling/src/lib.rs @@ -5,11 +5,11 @@ use num_derive::FromPrimitive; use num_traits::FromPrimitive; use solana_sdk::{ account_info::AccountInfo, + decode_error::DecodeError, entrypoint, entrypoint::ProgramResult, info, program_error::{PrintProgramError, ProgramError}, - program_utils::DecodeError, pubkey::Pubkey, }; use thiserror::Error; diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 61c631edef..ba86ef4eac 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -12,14 +12,14 @@ use solana_rbpf::{ EbpfVm, }; use solana_sdk::{ - account::KeyedAccount, + account::{is_executable, next_keyed_account, KeyedAccount}, bpf_loader, + decode_error::DecodeError, entrypoint::SUCCESS, entrypoint_native::InvokeContext, instruction::InstructionError, loader_instruction::LoaderInstruction, - program_utils::DecodeError, - program_utils::{is_executable, limited_deserialize, next_keyed_account}, + program_utils::limited_deserialize, pubkey::Pubkey, }; use std::{io::prelude::*, mem}; diff --git a/programs/budget/src/budget_instruction.rs b/programs/budget/src/budget_instruction.rs index 3d782b579c..297c0ab9ca 100644 --- a/programs/budget/src/budget_instruction.rs +++ b/programs/budget/src/budget_instruction.rs @@ -4,9 +4,9 @@ use chrono::prelude::{DateTime, Utc}; use num_derive::{FromPrimitive, ToPrimitive}; use serde_derive::{Deserialize, Serialize}; use solana_sdk::{ + decode_error::DecodeError, hash::Hash, instruction::{AccountMeta, Instruction}, - program_utils::DecodeError, pubkey::Pubkey, system_instruction, }; diff --git a/programs/budget/src/budget_processor.rs b/programs/budget/src/budget_processor.rs index c82bebcded..4b4318da5e 100644 --- a/programs/budget/src/budget_processor.rs +++ b/programs/budget/src/budget_processor.rs @@ -7,10 +7,10 @@ use crate::{ use chrono::prelude::{DateTime, Utc}; use log::*; use solana_sdk::{ - account::KeyedAccount, + account::{next_keyed_account, KeyedAccount}, hash::hash, instruction::InstructionError, - program_utils::{limited_deserialize, next_keyed_account}, + program_utils::limited_deserialize, pubkey::Pubkey, }; diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index 73e9388337..95996722c3 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -3,9 +3,9 @@ use crate::ConfigKeys; use bincode::deserialize; use log::*; -use solana_sdk::account::KeyedAccount; +use solana_sdk::account::{next_keyed_account, KeyedAccount}; use solana_sdk::instruction::InstructionError; -use solana_sdk::program_utils::{limited_deserialize, next_keyed_account}; +use solana_sdk::program_utils::limited_deserialize; use solana_sdk::pubkey::Pubkey; pub fn process_instruction( diff --git a/programs/exchange/src/exchange_processor.rs b/programs/exchange/src/exchange_processor.rs index b004aed052..3d29df7e96 100644 --- a/programs/exchange/src/exchange_processor.rs +++ b/programs/exchange/src/exchange_processor.rs @@ -8,8 +8,8 @@ use num_derive::{FromPrimitive, ToPrimitive}; use serde_derive::Serialize; use solana_metrics::inc_new_counter_info; use solana_sdk::{ - account::KeyedAccount, instruction::InstructionError, program_utils::limited_deserialize, - program_utils::DecodeError, pubkey::Pubkey, + account::KeyedAccount, decode_error::DecodeError, instruction::InstructionError, + program_utils::limited_deserialize, pubkey::Pubkey, }; use std::cmp; use thiserror::Error; diff --git a/programs/move_loader/src/processor.rs b/programs/move_loader/src/processor.rs index c4a4a97afb..1a421297db 100644 --- a/programs/move_loader/src/processor.rs +++ b/programs/move_loader/src/processor.rs @@ -6,13 +6,13 @@ use log::*; use num_derive::{FromPrimitive, ToPrimitive}; use serde_derive::{Deserialize, Serialize}; use solana_sdk::{ - account::KeyedAccount, + account::{is_executable, next_keyed_account, KeyedAccount}, account_utils::State, + decode_error::DecodeError, entrypoint_native::InvokeContext, instruction::InstructionError, move_loader::id, - program_utils::DecodeError, - program_utils::{is_executable, limited_deserialize, next_keyed_account}, + program_utils::limited_deserialize, pubkey::Pubkey, }; use thiserror::Error; diff --git a/programs/ownable/src/ownable_instruction.rs b/programs/ownable/src/ownable_instruction.rs index 8a35d2c762..48095e1f06 100644 --- a/programs/ownable/src/ownable_instruction.rs +++ b/programs/ownable/src/ownable_instruction.rs @@ -1,7 +1,7 @@ use num_derive::{FromPrimitive, ToPrimitive}; use solana_sdk::{ + decode_error::DecodeError, instruction::{AccountMeta, Instruction}, - program_utils::DecodeError, pubkey::Pubkey, system_instruction, }; diff --git a/programs/ownable/src/ownable_processor.rs b/programs/ownable/src/ownable_processor.rs index 0d07d54891..ed588acf0d 100644 --- a/programs/ownable/src/ownable_processor.rs +++ b/programs/ownable/src/ownable_processor.rs @@ -3,9 +3,9 @@ use crate::ownable_instruction::OwnableError; use bincode::serialize_into; use solana_sdk::{ - account::KeyedAccount, + account::{next_keyed_account, KeyedAccount}, instruction::InstructionError, - program_utils::{limited_deserialize, next_keyed_account}, + program_utils::limited_deserialize, pubkey::Pubkey, }; diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 083f102d64..f270d27b62 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -6,10 +6,11 @@ use log::*; use num_derive::{FromPrimitive, ToPrimitive}; use serde_derive::{Deserialize, Serialize}; use solana_sdk::{ - account::{get_signers, KeyedAccount}, + account::{get_signers, next_keyed_account, KeyedAccount}, clock::{Epoch, UnixTimestamp}, + decode_error::DecodeError, instruction::{AccountMeta, Instruction, InstructionError}, - program_utils::{limited_deserialize, next_keyed_account, DecodeError}, + program_utils::limited_deserialize, pubkey::Pubkey, system_instruction, sysvar::{self, clock::Clock, rent::Rent, stake_history::StakeHistory, Sysvar}, diff --git a/programs/vest/src/vest_instruction.rs b/programs/vest/src/vest_instruction.rs index bc3a481d5b..ca944750aa 100644 --- a/programs/vest/src/vest_instruction.rs +++ b/programs/vest/src/vest_instruction.rs @@ -4,8 +4,8 @@ use chrono::prelude::{Date, DateTime, Utc}; use num_derive::FromPrimitive; use serde_derive::{Deserialize, Serialize}; use solana_sdk::{ + decode_error::DecodeError, instruction::{AccountMeta, Instruction, InstructionError}, - program_utils::DecodeError, pubkey::Pubkey, system_instruction, }; diff --git a/programs/vest/src/vest_processor.rs b/programs/vest/src/vest_processor.rs index 5fda3f35c9..e60377f578 100644 --- a/programs/vest/src/vest_processor.rs +++ b/programs/vest/src/vest_processor.rs @@ -7,9 +7,9 @@ use chrono::prelude::*; use solana_config_program::date_instruction::DateConfig; use solana_config_program::get_config_data; use solana_sdk::{ - account::{Account, KeyedAccount}, + account::{next_keyed_account, Account, KeyedAccount}, instruction::InstructionError, - program_utils::{limited_deserialize, next_keyed_account}, + program_utils::limited_deserialize, pubkey::Pubkey, }; use std::cell::RefMut; diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index e265a753de..5df237758d 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -10,10 +10,11 @@ use num_derive::{FromPrimitive, ToPrimitive}; use serde_derive::{Deserialize, Serialize}; use solana_metrics::inc_new_counter_info; use solana_sdk::{ - account::{get_signers, KeyedAccount}, + account::{get_signers, next_keyed_account, KeyedAccount}, + decode_error::DecodeError, hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, - program_utils::{limited_deserialize, next_keyed_account, DecodeError}, + program_utils::limited_deserialize, pubkey::Pubkey, system_instruction, sysvar::{self, clock::Clock, slot_hashes::SlotHashes, Sysvar}, diff --git a/programs/vote/src/vote_state/mod.rs b/programs/vote/src/vote_state/mod.rs index 26ed5e1e9d..dc2686d2e9 100644 --- a/programs/vote/src/vote_state/mod.rs +++ b/programs/vote/src/vote_state/mod.rs @@ -738,10 +738,9 @@ mod tests { use super::*; use crate::vote_state; use solana_sdk::{ - account::{get_signers, Account}, + account::{get_signers, next_keyed_account, Account}, account_utils::StateMut, hash::hash, - program_utils::next_keyed_account, }; use std::cell::RefCell; diff --git a/runtime/src/legacy_system_instruction_processor0.rs b/runtime/src/legacy_system_instruction_processor0.rs index 5237a3cd7c..f5f29605fe 100644 --- a/runtime/src/legacy_system_instruction_processor0.rs +++ b/runtime/src/legacy_system_instruction_processor0.rs @@ -1,9 +1,9 @@ use log::*; use solana_sdk::{ - account::{get_signers, Account, KeyedAccount}, + account::{get_signers, next_keyed_account, Account, KeyedAccount}, instruction::InstructionError, nonce::Account as NonceAccount, - program_utils::{limited_deserialize, next_keyed_account}, + program_utils::limited_deserialize, pubkey::Pubkey, system_instruction::{SystemError, SystemInstruction, MAX_PERMITTED_DATA_LENGTH}, system_program, diff --git a/runtime/src/native_loader.rs b/runtime/src/native_loader.rs index 3d0711f265..dc1901a9a4 100644 --- a/runtime/src/native_loader.rs +++ b/runtime/src/native_loader.rs @@ -6,10 +6,10 @@ use libloading::os::windows::*; use log::*; use num_derive::{FromPrimitive, ToPrimitive}; use solana_sdk::{ - account::KeyedAccount, + account::{next_keyed_account, KeyedAccount}, + decode_error::DecodeError, entrypoint_native::{InvokeContext, LoaderEntrypoint, ProgramEntrypoint}, instruction::InstructionError, - program_utils::{next_keyed_account, DecodeError}, pubkey::Pubkey, }; use std::{collections::HashMap, env, path::PathBuf, str, sync::RwLock}; diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index fdc632f2ae..ea2af1a3d7 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -1,10 +1,10 @@ use log::*; use solana_sdk::{ - account::{get_signers, Account, KeyedAccount}, + account::{get_signers, next_keyed_account, Account, KeyedAccount}, account_utils::StateMut, instruction::InstructionError, nonce::{self, Account as NonceAccount}, - program_utils::{limited_deserialize, next_keyed_account}, + program_utils::limited_deserialize, pubkey::Pubkey, system_instruction::{SystemError, SystemInstruction, MAX_PERMITTED_DATA_LENGTH}, system_program, diff --git a/sdk/src/account.rs b/sdk/src/account.rs index df244d05e7..be337f4c30 100644 --- a/sdk/src/account.rs +++ b/sdk/src/account.rs @@ -286,3 +286,16 @@ where .cloned() .collect::() } + +/// Return the next KeyedAccount or a NotEnoughAccountKeys error +pub fn next_keyed_account<'a, 'b, I: Iterator>>( + iter: &mut I, +) -> Result { + iter.next().ok_or(InstructionError::NotEnoughAccountKeys) +} + +/// Return true if the first keyed_account is executable, used to determine if +/// the loader should call a program's 'main' +pub fn is_executable(keyed_accounts: &[KeyedAccount]) -> Result { + Ok(!keyed_accounts.is_empty() && keyed_accounts[0].executable()?) +} diff --git a/sdk/src/account_info.rs b/sdk/src/account_info.rs index f0f355cef1..958e30584c 100644 --- a/sdk/src/account_info.rs +++ b/sdk/src/account_info.rs @@ -216,3 +216,10 @@ pub fn create_is_signer_account_infos<'a>( }) .collect() } + +/// Return the next AccountInfo or a NotEnoughAccountKeys error +pub fn next_account_info<'a, 'b, I: Iterator>>( + iter: &mut I, +) -> Result { + iter.next().ok_or(ProgramError::NotEnoughAccountKeys) +} diff --git a/sdk/src/decode_error.rs b/sdk/src/decode_error.rs new file mode 100644 index 0000000000..f50e5bfd00 --- /dev/null +++ b/sdk/src/decode_error.rs @@ -0,0 +1,38 @@ +use num_traits::FromPrimitive; + +/// Allows customer errors to be decoded back to their original enum +pub trait DecodeError { + fn decode_custom_error_to_enum(custom: u32) -> Option + where + E: FromPrimitive, + { + E::from_u32(custom) + } + fn type_of() -> &'static str; +} + +#[cfg(test)] +mod tests { + use super::*; + use num_derive::FromPrimitive; + + #[test] + fn test_decode_custom_error_to_enum() { + #[derive(Debug, FromPrimitive, PartialEq)] + enum TestEnum { + A, + B, + C, + } + impl DecodeError for TestEnum { + fn type_of() -> &'static str { + "TestEnum" + } + } + assert_eq!(TestEnum::decode_custom_error_to_enum(0), Some(TestEnum::A)); + assert_eq!(TestEnum::decode_custom_error_to_enum(1), Some(TestEnum::B)); + assert_eq!(TestEnum::decode_custom_error_to_enum(2), Some(TestEnum::C)); + let option: Option = TestEnum::decode_custom_error_to_enum(3); + assert_eq!(option, None); + } +} diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index 00e4de11e6..bdb73fc8cb 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -13,6 +13,7 @@ pub mod account_utils; pub mod bpf_loader; pub mod clock; pub mod commitment_config; +pub mod decode_error; pub mod entrypoint_native; pub mod epoch_info; pub mod epoch_schedule; diff --git a/sdk/src/program_error.rs b/sdk/src/program_error.rs index 056486f006..91dac2993f 100644 --- a/sdk/src/program_error.rs +++ b/sdk/src/program_error.rs @@ -1,4 +1,4 @@ -use crate::{instruction::InstructionError, program_utils::DecodeError}; +use crate::{decode_error::DecodeError, instruction::InstructionError}; use num_traits::{FromPrimitive, ToPrimitive}; use std::convert::TryFrom; use thiserror::Error; diff --git a/sdk/src/program_utils.rs b/sdk/src/program_utils.rs index 4c380343c5..979a18beeb 100644 --- a/sdk/src/program_utils.rs +++ b/sdk/src/program_utils.rs @@ -1,28 +1,4 @@ -use crate::{ - account::KeyedAccount, account_info::AccountInfo, instruction::InstructionError, - program_error::ProgramError, -}; -use num_traits::FromPrimitive; - -/// Return the next KeyedAccount or a NotEnoughAccountKeys error -pub fn next_keyed_account<'a, 'b, I: Iterator>>( - iter: &mut I, -) -> Result { - iter.next().ok_or(InstructionError::NotEnoughAccountKeys) -} - -/// Return the next AccountInfo or a NotEnoughAccountKeys error -pub fn next_account_info<'a, 'b, I: Iterator>>( - iter: &mut I, -) -> Result { - iter.next().ok_or(ProgramError::NotEnoughAccountKeys) -} - -/// Return true if the first keyed_account is executable, used to determine if -/// the loader should call a program's 'main' -pub fn is_executable(keyed_accounts: &[KeyedAccount]) -> Result { - Ok(!keyed_accounts.is_empty() && keyed_accounts[0].executable()?) -} +use crate::instruction::InstructionError; /// Deserialize with a limit based the maximum amount of data a program can expect to get. /// This function should be used in place of direct deserialization to help prevent OOM errors @@ -36,40 +12,3 @@ where .deserialize(instruction_data) .map_err(|_| InstructionError::InvalidInstructionData) } - -/// Allows customer errors to be decoded back to their original enum -pub trait DecodeError { - fn decode_custom_error_to_enum(custom: u32) -> Option - where - E: FromPrimitive, - { - E::from_u32(custom) - } - fn type_of() -> &'static str; -} - -#[cfg(test)] -mod tests { - use super::*; - use num_derive::FromPrimitive; - - #[test] - fn test_decode_custom_error_to_enum() { - #[derive(Debug, FromPrimitive, PartialEq)] - enum TestEnum { - A, - B, - C, - } - impl DecodeError for TestEnum { - fn type_of() -> &'static str { - "TestEnum" - } - } - assert_eq!(TestEnum::decode_custom_error_to_enum(0), Some(TestEnum::A)); - assert_eq!(TestEnum::decode_custom_error_to_enum(1), Some(TestEnum::B)); - assert_eq!(TestEnum::decode_custom_error_to_enum(2), Some(TestEnum::C)); - let option: Option = TestEnum::decode_custom_error_to_enum(3); - assert_eq!(option, None); - } -} diff --git a/sdk/src/pubkey.rs b/sdk/src/pubkey.rs index 8a5ac46a6c..6afc15567c 100644 --- a/sdk/src/pubkey.rs +++ b/sdk/src/pubkey.rs @@ -1,6 +1,6 @@ use crate::{ + decode_error::DecodeError, hash::{hash, hashv, Hasher}, - program_utils::DecodeError, }; use num_derive::{FromPrimitive, ToPrimitive}; #[cfg(not(feature = "program"))] diff --git a/sdk/src/system_instruction.rs b/sdk/src/system_instruction.rs index ad70e16bcb..dabc716fdb 100644 --- a/sdk/src/system_instruction.rs +++ b/sdk/src/system_instruction.rs @@ -1,7 +1,7 @@ use crate::{ + decode_error::DecodeError, instruction::{AccountMeta, Instruction}, nonce, - program_utils::DecodeError, pubkey::Pubkey, system_program, sysvar::{recent_blockhashes, rent},