SystemProgram transactions now fail on invalid arguments
This commit is contained in:
parent
785c619198
commit
262f26cf76
|
@ -536,12 +536,15 @@ impl Bank {
|
|||
// Call the contract method
|
||||
// It's up to the contract to implement its own rules on moving funds
|
||||
if SystemProgram::check_id(&tx_program_id) {
|
||||
SystemProgram::process_transaction(
|
||||
if SystemProgram::process_transaction(
|
||||
&tx,
|
||||
instruction_index,
|
||||
program_accounts,
|
||||
&self.loaded_contracts,
|
||||
)
|
||||
).is_err()
|
||||
{
|
||||
return Err(BankError::ProgramRuntimeError(instruction_index as u8));
|
||||
}
|
||||
} else if BudgetState::check_id(&tx_program_id) {
|
||||
if BudgetState::process_transaction(&tx, instruction_index, program_accounts).is_err() {
|
||||
return Err(BankError::ProgramRuntimeError(instruction_index as u8));
|
||||
|
|
|
@ -4,10 +4,24 @@ use bincode::deserialize;
|
|||
use dynamic_program::DynamicProgram;
|
||||
use solana_program_interface::account::Account;
|
||||
use solana_program_interface::pubkey::Pubkey;
|
||||
use std;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::RwLock;
|
||||
use transaction::Transaction;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
InvalidArgument,
|
||||
}
|
||||
impl std::fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "error")
|
||||
}
|
||||
}
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub enum SystemProgram {
|
||||
/// Create a new account
|
||||
|
@ -52,7 +66,7 @@ impl SystemProgram {
|
|||
pix: usize,
|
||||
accounts: &mut [&mut Account],
|
||||
loaded_programs: &RwLock<HashMap<Pubkey, DynamicProgram>>,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
if let Ok(syscall) = deserialize(tx.userdata(pix)) {
|
||||
trace!("process_transaction: {:?}", syscall);
|
||||
match syscall {
|
||||
|
@ -62,13 +76,13 @@ impl SystemProgram {
|
|||
program_id,
|
||||
} => {
|
||||
if !Self::check_id(&accounts[0].program_id) {
|
||||
return;
|
||||
Err(Error::InvalidArgument)?;
|
||||
}
|
||||
if space > 0
|
||||
&& (!accounts[1].userdata.is_empty()
|
||||
|| !Self::check_id(&accounts[1].program_id))
|
||||
{
|
||||
return;
|
||||
Err(Error::InvalidArgument)?;
|
||||
}
|
||||
accounts[0].tokens -= tokens;
|
||||
accounts[1].tokens += tokens;
|
||||
|
@ -77,7 +91,7 @@ impl SystemProgram {
|
|||
}
|
||||
SystemProgram::Assign { program_id } => {
|
||||
if !Self::check_id(&accounts[0].program_id) {
|
||||
return;
|
||||
Err(Error::InvalidArgument)?;
|
||||
}
|
||||
accounts[0].program_id = program_id;
|
||||
}
|
||||
|
@ -91,8 +105,10 @@ impl SystemProgram {
|
|||
hashmap.insert(program_id, DynamicProgram::new_native(name));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
info!("Invalid transaction userdata: {:?}", tx.userdata(pix));
|
||||
Err(Error::InvalidArgument)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,10 +129,11 @@ mod test {
|
|||
tx: &Transaction,
|
||||
accounts: &mut [Account],
|
||||
loaded_programs: &RwLock<HashMap<Pubkey, DynamicProgram>>,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
let mut refs: Vec<&mut Account> = accounts.iter_mut().collect();
|
||||
SystemProgram::process_transaction(&tx, 0, &mut refs[..], loaded_programs)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_noop() {
|
||||
let from = Keypair::new();
|
||||
|
@ -124,7 +141,7 @@ mod test {
|
|||
let mut accounts = vec![Account::default(), Account::default()];
|
||||
let tx = Transaction::system_new(&from, to.pubkey(), 0, Hash::default());
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
process_transaction(&tx, &mut accounts, &hash);
|
||||
process_transaction(&tx, &mut accounts, &hash).unwrap();
|
||||
assert_eq!(accounts[0].tokens, 0);
|
||||
assert_eq!(accounts[1].tokens, 0);
|
||||
}
|
||||
|
@ -136,7 +153,7 @@ mod test {
|
|||
accounts[0].tokens = 1;
|
||||
let tx = Transaction::system_new(&from, to.pubkey(), 1, Hash::default());
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
process_transaction(&tx, &mut accounts, &hash);
|
||||
process_transaction(&tx, &mut accounts, &hash).unwrap();
|
||||
assert_eq!(accounts[0].tokens, 0);
|
||||
assert_eq!(accounts[1].tokens, 1);
|
||||
}
|
||||
|
@ -149,7 +166,7 @@ mod test {
|
|||
accounts[0].program_id = from.pubkey();
|
||||
let tx = Transaction::system_new(&from, to.pubkey(), 1, Hash::default());
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
process_transaction(&tx, &mut accounts, &hash);
|
||||
assert!(process_transaction(&tx, &mut accounts, &hash).is_err());
|
||||
assert_eq!(accounts[0].tokens, 1);
|
||||
assert_eq!(accounts[1].tokens, 0);
|
||||
}
|
||||
|
@ -161,7 +178,7 @@ mod test {
|
|||
let tx =
|
||||
Transaction::system_create(&from, to.pubkey(), Hash::default(), 0, 1, to.pubkey(), 0);
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
process_transaction(&tx, &mut accounts, &hash);
|
||||
process_transaction(&tx, &mut accounts, &hash).unwrap();
|
||||
assert!(accounts[0].userdata.is_empty());
|
||||
assert_eq!(accounts[1].userdata.len(), 1);
|
||||
assert_eq!(accounts[1].program_id, to.pubkey());
|
||||
|
@ -182,7 +199,7 @@ mod test {
|
|||
0,
|
||||
);
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
process_transaction(&tx, &mut accounts, &hash);
|
||||
assert!(process_transaction(&tx, &mut accounts, &hash).is_err());
|
||||
assert!(accounts[1].userdata.is_empty());
|
||||
}
|
||||
#[test]
|
||||
|
@ -201,7 +218,7 @@ mod test {
|
|||
0,
|
||||
);
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
process_transaction(&tx, &mut accounts, &hash);
|
||||
assert!(process_transaction(&tx, &mut accounts, &hash).is_err());
|
||||
assert!(accounts[1].userdata.is_empty());
|
||||
}
|
||||
#[test]
|
||||
|
@ -220,7 +237,7 @@ mod test {
|
|||
0,
|
||||
);
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
process_transaction(&tx, &mut accounts, &hash);
|
||||
assert!(process_transaction(&tx, &mut accounts, &hash).is_err());
|
||||
assert_eq!(accounts[1].userdata.len(), 3);
|
||||
}
|
||||
#[test]
|
||||
|
@ -230,7 +247,7 @@ mod test {
|
|||
let mut accounts = vec![Account::default()];
|
||||
let tx = Transaction::system_assign(&from, Hash::default(), program.pubkey(), 0);
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
process_transaction(&tx, &mut accounts, &hash);
|
||||
process_transaction(&tx, &mut accounts, &hash).unwrap();
|
||||
assert_eq!(accounts[0].program_id, program.pubkey());
|
||||
}
|
||||
#[test]
|
||||
|
@ -241,7 +258,7 @@ mod test {
|
|||
accounts[0].tokens = 1;
|
||||
let tx = Transaction::system_new(&from, to.pubkey(), 1, Hash::default());
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
process_transaction(&tx, &mut accounts, &hash);
|
||||
process_transaction(&tx, &mut accounts, &hash).unwrap();
|
||||
assert_eq!(accounts[0].tokens, 0);
|
||||
assert_eq!(accounts[1].tokens, 1);
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ fn process_transaction(
|
|||
loaded_programs: &RwLock<HashMap<Pubkey, DynamicProgram>>,
|
||||
) {
|
||||
let mut refs: Vec<&mut Account> = accounts.iter_mut().collect();
|
||||
SystemProgram::process_transaction(&tx, 0, &mut refs[..], loaded_programs)
|
||||
SystemProgram::process_transaction(&tx, 0, &mut refs[..], loaded_programs).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue