Remove SystemError from ProgramError
This commit is contained in:
parent
6a89c68a1d
commit
1de5ae1ef0
|
@ -1,4 +1,5 @@
|
||||||
use crate::native_loader;
|
use crate::native_loader;
|
||||||
|
use crate::system_program::SystemError;
|
||||||
use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount};
|
use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount};
|
||||||
use solana_sdk::native_program::ProgramError;
|
use solana_sdk::native_program::ProgramError;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
|
@ -26,7 +27,9 @@ pub enum InstructionError {
|
||||||
|
|
||||||
impl InstructionError {
|
impl InstructionError {
|
||||||
pub fn new_result_with_negative_lamports() -> Self {
|
pub fn new_result_with_negative_lamports() -> Self {
|
||||||
InstructionError::ProgramError(ProgramError::ResultWithNegativeLamports)
|
let serialized_error =
|
||||||
|
bincode::serialize(&SystemError::ResultWithNegativeLamports).unwrap();
|
||||||
|
InstructionError::ProgramError(ProgramError::CustomError(serialized_error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ const FROM_ACCOUNT_INDEX: usize = 0;
|
||||||
const TO_ACCOUNT_INDEX: usize = 1;
|
const TO_ACCOUNT_INDEX: usize = 1;
|
||||||
|
|
||||||
#[derive(Serialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Debug, Clone, PartialEq)]
|
||||||
enum SystemError {
|
pub enum SystemError {
|
||||||
AccountAlreadyInUse,
|
AccountAlreadyInUse,
|
||||||
ResultWithNegativeLamports,
|
ResultWithNegativeLamports,
|
||||||
SourceNotSystemAccount,
|
SourceNotSystemAccount,
|
||||||
|
@ -55,20 +55,17 @@ fn create_system_account(
|
||||||
fn assign_account_to_program(
|
fn assign_account_to_program(
|
||||||
keyed_accounts: &mut [KeyedAccount],
|
keyed_accounts: &mut [KeyedAccount],
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
) -> Result<(), ProgramError> {
|
) -> Result<(), SystemError> {
|
||||||
if !system_program::check_id(&keyed_accounts[FROM_ACCOUNT_INDEX].account.owner) {
|
|
||||||
Err(ProgramError::AssignOfUnownedAccount)?;
|
|
||||||
}
|
|
||||||
keyed_accounts[FROM_ACCOUNT_INDEX].account.owner = *program_id;
|
keyed_accounts[FROM_ACCOUNT_INDEX].account.owner = *program_id;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn move_lamports(keyed_accounts: &mut [KeyedAccount], lamports: u64) -> Result<(), ProgramError> {
|
fn move_lamports(keyed_accounts: &mut [KeyedAccount], lamports: u64) -> Result<(), SystemError> {
|
||||||
if lamports > keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports {
|
if lamports > keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports {
|
||||||
info!(
|
info!(
|
||||||
"Move: insufficient lamports ({}, need {})",
|
"Move: insufficient lamports ({}, need {})",
|
||||||
keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports, lamports
|
keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports, lamports
|
||||||
);
|
);
|
||||||
Err(ProgramError::ResultWithNegativeLamports)?;
|
Err(SystemError::ResultWithNegativeLamports)?;
|
||||||
}
|
}
|
||||||
keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports -= lamports;
|
keyed_accounts[FROM_ACCOUNT_INDEX].account.lamports -= lamports;
|
||||||
keyed_accounts[TO_ACCOUNT_INDEX].account.lamports += lamports;
|
keyed_accounts[TO_ACCOUNT_INDEX].account.lamports += lamports;
|
||||||
|
@ -81,8 +78,8 @@ pub fn entrypoint(
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
_tick_height: u64,
|
_tick_height: u64,
|
||||||
) -> Result<(), ProgramError> {
|
) -> Result<(), ProgramError> {
|
||||||
if let Ok(syscall) = bincode::deserialize(data) {
|
if let Ok(instruction) = bincode::deserialize(data) {
|
||||||
trace!("process_instruction: {:?}", syscall);
|
trace!("process_instruction: {:?}", instruction);
|
||||||
trace!("keyed_accounts: {:?}", keyed_accounts);
|
trace!("keyed_accounts: {:?}", keyed_accounts);
|
||||||
|
|
||||||
// All system instructions require that accounts_keys[0] be a signer
|
// All system instructions require that accounts_keys[0] be a signer
|
||||||
|
@ -91,24 +88,21 @@ pub fn entrypoint(
|
||||||
Err(ProgramError::InvalidArgument)?;
|
Err(ProgramError::InvalidArgument)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
match syscall {
|
match instruction {
|
||||||
SystemInstruction::CreateAccount {
|
SystemInstruction::CreateAccount {
|
||||||
lamports,
|
lamports,
|
||||||
space,
|
space,
|
||||||
program_id,
|
program_id,
|
||||||
} => create_system_account(keyed_accounts, lamports, space, &program_id).map_err(|e| {
|
} => create_system_account(keyed_accounts, lamports, space, &program_id),
|
||||||
match e {
|
|
||||||
SystemError::ResultWithNegativeLamports => {
|
|
||||||
ProgramError::ResultWithNegativeLamports
|
|
||||||
}
|
|
||||||
e => ProgramError::CustomError(serialize(&e).unwrap()),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
SystemInstruction::Assign { program_id } => {
|
SystemInstruction::Assign { program_id } => {
|
||||||
|
if !system_program::check_id(&keyed_accounts[FROM_ACCOUNT_INDEX].account.owner) {
|
||||||
|
Err(ProgramError::AssignOfUnownedAccount)?;
|
||||||
|
}
|
||||||
assign_account_to_program(keyed_accounts, &program_id)
|
assign_account_to_program(keyed_accounts, &program_id)
|
||||||
}
|
}
|
||||||
SystemInstruction::Move { lamports } => move_lamports(keyed_accounts, lamports),
|
SystemInstruction::Move { lamports } => move_lamports(keyed_accounts, lamports),
|
||||||
}
|
}
|
||||||
|
.map_err(|e| ProgramError::CustomError(serialize(&e).unwrap()))
|
||||||
} else {
|
} else {
|
||||||
info!("Invalid transaction instruction userdata: {:?}", data);
|
info!("Invalid transaction instruction userdata: {:?}", data);
|
||||||
Err(ProgramError::InvalidUserdata)
|
Err(ProgramError::InvalidUserdata)
|
||||||
|
@ -246,7 +240,11 @@ mod tests {
|
||||||
// Attempt to assign account not owned by system program
|
// Attempt to assign account not owned by system program
|
||||||
let another_program_owner = Pubkey::new(&[8; 32]);
|
let another_program_owner = Pubkey::new(&[8; 32]);
|
||||||
keyed_accounts = [KeyedAccount::new(&from, true, &mut from_account)];
|
keyed_accounts = [KeyedAccount::new(&from, true, &mut from_account)];
|
||||||
let result = assign_account_to_program(&mut keyed_accounts, &another_program_owner);
|
let instruction = SystemInstruction::Assign {
|
||||||
|
program_id: another_program_owner,
|
||||||
|
};
|
||||||
|
let data = serialize(&instruction).unwrap();
|
||||||
|
let result = entrypoint(&system_program::id(), &mut keyed_accounts, &data, 0);
|
||||||
assert_eq!(result, Err(ProgramError::AssignOfUnownedAccount));
|
assert_eq!(result, Err(ProgramError::AssignOfUnownedAccount));
|
||||||
assert_eq!(from_account.owner, new_program_owner);
|
assert_eq!(from_account.owner, new_program_owner);
|
||||||
}
|
}
|
||||||
|
@ -273,7 +271,7 @@ mod tests {
|
||||||
KeyedAccount::new(&to, false, &mut to_account),
|
KeyedAccount::new(&to, false, &mut to_account),
|
||||||
];
|
];
|
||||||
let result = move_lamports(&mut keyed_accounts, 100);
|
let result = move_lamports(&mut keyed_accounts, 100);
|
||||||
assert_eq!(result, Err(ProgramError::ResultWithNegativeLamports));
|
assert_eq!(result, Err(SystemError::ResultWithNegativeLamports));
|
||||||
assert_eq!(from_account.lamports, 50);
|
assert_eq!(from_account.lamports, 50);
|
||||||
assert_eq!(to_account.lamports, 51);
|
assert_eq!(to_account.lamports, 51);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,6 @@ pub enum ProgramError {
|
||||||
/// The arguments provided to a program instruction where invalid
|
/// The arguments provided to a program instruction where invalid
|
||||||
InvalidArgument,
|
InvalidArgument,
|
||||||
|
|
||||||
/// An instruction resulted in an account with a negative balance
|
|
||||||
/// The difference from InsufficientFundsForFee is that the transaction was executed by the
|
|
||||||
/// contract
|
|
||||||
ResultWithNegativeLamports,
|
|
||||||
|
|
||||||
/// An account's userdata contents was invalid
|
/// An account's userdata contents was invalid
|
||||||
InvalidUserdata,
|
InvalidUserdata,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue