diff --git a/src/bank.rs b/src/bank.rs index 05e8739606..be44b23e71 100644 --- a/src/bank.rs +++ b/src/bank.rs @@ -803,37 +803,17 @@ impl Bank { // Call the contract method // It's up to the contract to implement its own rules on moving funds if system_program::check_id(&program_id) { - if let Err(err) = - system_program::process_instruction(&tx, instruction_index, program_accounts) - { - let err = match err { - system_program::Error::ResultWithNegativeTokens => { - ProgramError::ResultWithNegativeTokens - } - _ => ProgramError::RuntimeError, - }; - return Err(BankError::ProgramError(instruction_index as u8, err)); - } + system_program::process(&tx, instruction_index, program_accounts) + .map_err(|err| BankError::ProgramError(instruction_index as u8, err))?; } else if budget_program::check_id(&program_id) { - if budget_program::process_instruction(&tx, instruction_index, program_accounts) - .is_err() - { - let err = ProgramError::RuntimeError; - return Err(BankError::ProgramError(instruction_index as u8, err)); - } + budget_program::process(&tx, instruction_index, program_accounts) + .map_err(|err| BankError::ProgramError(instruction_index as u8, err))?; } else if storage_program::check_id(&program_id) { - if storage_program::process_instruction(&tx, instruction_index, program_accounts) - .is_err() - { - let err = ProgramError::RuntimeError; - return Err(BankError::ProgramError(instruction_index as u8, err)); - } + storage_program::process(&tx, instruction_index, program_accounts) + .map_err(|err| BankError::ProgramError(instruction_index as u8, err))?; } else if vote_program::check_id(&program_id) { - if vote_program::process_instruction(&tx, instruction_index, program_accounts).is_err() - { - let err = ProgramError::RuntimeError; - return Err(BankError::ProgramError(instruction_index as u8, err)); - } + vote_program::process(&tx, instruction_index, program_accounts) + .map_err(|err| BankError::ProgramError(instruction_index as u8, err))?; } else { let mut accounts = self.load_executable_accounts(tx.program_ids[instruction_index])?; let mut keyed_accounts = create_keyed_accounts(&mut accounts); diff --git a/src/budget_program.rs b/src/budget_program.rs index 3e1c94a943..d7a0a55eef 100644 --- a/src/budget_program.rs +++ b/src/budget_program.rs @@ -4,6 +4,7 @@ use budget_expr::BudgetExpr; use budget_instruction::Instruction; use chrono::prelude::{DateTime, Utc}; use payment_plan::Witness; +use program::ProgramError; use solana_sdk::account::Account; use solana_sdk::pubkey::Pubkey; use std::io; @@ -133,6 +134,14 @@ pub fn process_instruction( } } +pub fn process( + tx: &Transaction, + instruction_index: usize, + accounts: &mut [&mut Account], +) -> std::result::Result<(), ProgramError> { + process_instruction(&tx, instruction_index, accounts).map_err(|_| ProgramError::RuntimeError) +} + //TODO the contract needs to provide a "get_balance" introspection call of the userdata pub fn get_balance(account: &Account) -> u64 { if let Ok(program) = deserialize(&account.userdata) { diff --git a/src/storage_program.rs b/src/storage_program.rs index 991bd04747..9af5c7c48d 100644 --- a/src/storage_program.rs +++ b/src/storage_program.rs @@ -3,6 +3,7 @@ //! and give reward for good proofs. use bincode::deserialize; +use program::ProgramError; use solana_sdk::account::Account; use solana_sdk::hash::Hash; use solana_sdk::pubkey::Pubkey; @@ -51,6 +52,14 @@ pub fn process_instruction( } } +pub fn process( + tx: &Transaction, + instruction_index: usize, + accounts: &mut [&mut Account], +) -> std::result::Result<(), ProgramError> { + process_instruction(&tx, instruction_index, accounts).map_err(|_| ProgramError::RuntimeError) +} + #[cfg(test)] mod test { use super::*; diff --git a/src/system_program.rs b/src/system_program.rs index 5d70e33f9b..bcdd93651b 100644 --- a/src/system_program.rs +++ b/src/system_program.rs @@ -1,6 +1,7 @@ //! system program use bincode::deserialize; +use program::ProgramError; use solana_sdk::account::Account; use solana_sdk::pubkey::Pubkey; use solana_sdk::system_instruction::SystemInstruction; @@ -99,6 +100,17 @@ pub fn process_instruction( } } +pub fn process( + tx: &Transaction, + instruction_index: usize, + accounts: &mut [&mut Account], +) -> std::result::Result<(), ProgramError> { + process_instruction(&tx, instruction_index, accounts).map_err(|err| match err { + Error::ResultWithNegativeTokens => ProgramError::ResultWithNegativeTokens, + _ => ProgramError::RuntimeError, + }) +} + #[cfg(test)] mod test { use super::*; diff --git a/src/vote_program.rs b/src/vote_program.rs index d5a2b25214..d02c0839a6 100644 --- a/src/vote_program.rs +++ b/src/vote_program.rs @@ -3,6 +3,7 @@ use bincode::{deserialize, serialize}; use byteorder::{ByteOrder, LittleEndian}; +use program::ProgramError; use solana_sdk::account::Account; use solana_sdk::pubkey::Pubkey; use std; @@ -116,6 +117,14 @@ pub fn process_instruction( } } +pub fn process( + tx: &Transaction, + instruction_index: usize, + accounts: &mut [&mut Account], +) -> std::result::Result<(), ProgramError> { + process_instruction(&tx, instruction_index, accounts).map_err(|_| ProgramError::RuntimeError) +} + pub fn get_max_size() -> usize { // Upper limit on the size of the Vote State. Equal to // sizeof(VoteProgram) + MAX_VOTE_HISTORY * sizeof(Vote) +