Avoid panicking invalid instructions
This commit is contained in:
@@ -246,7 +246,7 @@ impl BudgetContract {
|
|||||||
/// * accounts[1] - The contract context. Once the contract has been completed, the tokens can
|
/// * accounts[1] - The contract context. Once the contract has been completed, the tokens can
|
||||||
/// be spent from this account .
|
/// be spent from this account .
|
||||||
pub fn process_transaction(tx: &Transaction, accounts: &mut [Account]) -> () {
|
pub fn process_transaction(tx: &Transaction, accounts: &mut [Account]) -> () {
|
||||||
let instruction = deserialize(&tx.userdata).unwrap();
|
if let Ok(instruction) = deserialize(&tx.userdata) {
|
||||||
trace!("process_transaction: {:?}", instruction);
|
trace!("process_transaction: {:?}", instruction);
|
||||||
let _ = Self::apply_debits_to_budget_state(tx, accounts, &instruction)
|
let _ = Self::apply_debits_to_budget_state(tx, accounts, &instruction)
|
||||||
.and_then(|_| Self::apply_credits_to_budget_state(tx, accounts, &instruction))
|
.and_then(|_| Self::apply_credits_to_budget_state(tx, accounts, &instruction))
|
||||||
@@ -254,6 +254,9 @@ impl BudgetContract {
|
|||||||
trace!("saving error {:?}", e);
|
trace!("saving error {:?}", e);
|
||||||
Self::save_error_to_budget_state(e, accounts);
|
Self::save_error_to_budget_state(e, accounts);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
info!("Invalid transaction userdata: {:?}", tx.userdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO the contract needs to provide a "get_balance" introspection call of the userdata
|
//TODO the contract needs to provide a "get_balance" introspection call of the userdata
|
||||||
@@ -299,6 +302,27 @@ mod test {
|
|||||||
Err(BudgetError::UserdataTooSmall)
|
Err(BudgetError::UserdataTooSmall)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_invalid_instruction() {
|
||||||
|
let mut accounts = vec![
|
||||||
|
Account::new(1, 0, BudgetContract::id()),
|
||||||
|
Account::new(0, 512, BudgetContract::id()),
|
||||||
|
];
|
||||||
|
let from = Keypair::new();
|
||||||
|
let contract = Keypair::new();
|
||||||
|
|
||||||
|
let tx = Transaction::new_with_userdata(
|
||||||
|
&from,
|
||||||
|
&[contract.pubkey()],
|
||||||
|
BudgetContract::id(),
|
||||||
|
vec![1, 2, 3], // <== garbage instruction
|
||||||
|
Hash::default(),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
BudgetContract::process_transaction(&tx, &mut accounts);
|
||||||
|
|
||||||
|
// Success if there was no panic...
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transfer_on_date() {
|
fn test_transfer_on_date() {
|
||||||
|
@@ -41,7 +41,7 @@ impl SystemContract {
|
|||||||
account.tokens
|
account.tokens
|
||||||
}
|
}
|
||||||
pub fn process_transaction(tx: &Transaction, accounts: &mut [Account]) {
|
pub fn process_transaction(tx: &Transaction, accounts: &mut [Account]) {
|
||||||
let syscall: SystemContract = deserialize(&tx.userdata).unwrap();
|
if let Ok(syscall) = deserialize(&tx.userdata) {
|
||||||
trace!("process_transaction: {:?}", syscall);
|
trace!("process_transaction: {:?}", syscall);
|
||||||
match syscall {
|
match syscall {
|
||||||
SystemContract::CreateAccount {
|
SystemContract::CreateAccount {
|
||||||
@@ -75,6 +75,9 @@ impl SystemContract {
|
|||||||
accounts[1].tokens += tokens;
|
accounts[1].tokens += tokens;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
info!("Invalid transaction userdata: {:?}", tx.userdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@@ -49,7 +49,7 @@ impl Transaction {
|
|||||||
/// * `userdata` - The input data that the contract will execute with
|
/// * `userdata` - The input data that the contract will execute with
|
||||||
/// * `last_id` - The PoH hash.
|
/// * `last_id` - The PoH hash.
|
||||||
/// * `fee` - The transaction fee.
|
/// * `fee` - The transaction fee.
|
||||||
fn new_with_userdata(
|
pub fn new_with_userdata(
|
||||||
from_keypair: &Keypair,
|
from_keypair: &Keypair,
|
||||||
transaction_keys: &[Pubkey],
|
transaction_keys: &[Pubkey],
|
||||||
contract_id: Pubkey,
|
contract_id: Pubkey,
|
||||||
|
Reference in New Issue
Block a user