Resurrect the tests

This commit is contained in:
Greg Fitzgerald
2019-03-07 13:34:13 -07:00
parent a277f3e816
commit 17dcd1f62a
4 changed files with 43 additions and 74 deletions

View File

@ -6,6 +6,7 @@ use solana_budget_api::budget_instruction::BudgetInstruction;
use solana_budget_api::budget_state::{BudgetError, BudgetState}; use solana_budget_api::budget_state::{BudgetError, BudgetState};
use solana_budget_api::payment_plan::Witness; use solana_budget_api::payment_plan::Witness;
use solana_sdk::account::KeyedAccount; use solana_sdk::account::KeyedAccount;
use solana_sdk::pubkey::Pubkey;
/// Process a Witness Signature. Any payment plans waiting on this signature /// Process a Witness Signature. Any payment plans waiting on this signature
/// will progress one step. /// will progress one step.
@ -78,10 +79,6 @@ fn apply_debits(
keyed_accounts: &mut [KeyedAccount], keyed_accounts: &mut [KeyedAccount],
instruction: &BudgetInstruction, instruction: &BudgetInstruction,
) -> Result<(), BudgetError> { ) -> Result<(), BudgetError> {
if !keyed_accounts[0].account.userdata.is_empty() {
trace!("source is pending");
return Err(BudgetError::SourceIsPendingContract);
}
match instruction { match instruction {
BudgetInstruction::InitializeAccount(expr) => { BudgetInstruction::InitializeAccount(expr) => {
let expr = expr.clone(); let expr = expr.clone();
@ -143,21 +140,18 @@ fn apply_debits(
} }
} }
/// Budget DSL contract interface
/// * accounts[0] - The source of the lamports
/// * accounts[1] - The contract context. Once the contract has been completed, the lamports can
/// be spent from this account .
pub fn process_instruction( pub fn process_instruction(
_program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount], keyed_accounts: &mut [KeyedAccount],
data: &[u8], data: &[u8],
) -> Result<(), BudgetError> { ) -> Result<(), BudgetError> {
if let Ok(instruction) = deserialize(data) { let instruction = deserialize(data).map_err(|err| {
info!("Invalid transaction userdata: {:?} {:?}", data, err);
BudgetError::UserdataDeserializeFailure
})?;
trace!("process_instruction: {:?}", instruction); trace!("process_instruction: {:?}", instruction);
apply_debits(keyed_accounts, &instruction) apply_debits(keyed_accounts, &instruction)
} else {
info!("Invalid transaction userdata: {:?}", data);
Err(BudgetError::UserdataDeserializeFailure)
}
} }
#[cfg(test)] #[cfg(test)]
@ -169,9 +163,9 @@ mod test {
use solana_sdk::account::Account; use solana_sdk::account::Account;
use solana_sdk::hash::Hash; use solana_sdk::hash::Hash;
use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_program;
use solana_sdk::transaction::Transaction; use solana_sdk::transaction::Transaction;
// TODO: This is wrong and will only work with single-instruction transactions.
fn process_transaction( fn process_transaction(
tx: &Transaction, tx: &Transaction,
tx_accounts: &mut [Account], tx_accounts: &mut [Account],
@ -199,10 +193,10 @@ mod test {
#[test] #[test]
fn test_unsigned_witness_key() { fn test_unsigned_witness_key() {
let mut accounts = vec![ let mut accounts = vec![
Account::new(1, 0, id()), Account::new(1, 0, system_program::id()),
Account::new(0, 512, id()), Account::new(0, 0, system_program::id()),
Account::new(0, 0, id()), Account::new(0, 0, system_program::id()),
Account::new(0, 0, id()), Account::new(0, 0, system_program::id()),
]; ];
// Initialize BudgetState // Initialize BudgetState
@ -239,10 +233,10 @@ mod test {
#[test] #[test]
fn test_unsigned_timestamp() { fn test_unsigned_timestamp() {
let mut accounts = vec![ let mut accounts = vec![
Account::new(1, 0, id()), Account::new(1, 0, system_program::id()),
Account::new(0, 512, id()), Account::new(0, 0, system_program::id()),
Account::new(0, 0, id()), Account::new(0, 0, system_program::id()),
Account::new(0, 0, id()), Account::new(0, 0, system_program::id()),
]; ];
// Initialize BudgetState // Initialize BudgetState
@ -280,9 +274,9 @@ mod test {
#[test] #[test]
fn test_transfer_on_date() { fn test_transfer_on_date() {
let mut accounts = vec![ let mut accounts = vec![
Account::new(1, 0, id()), Account::new(1, 0, system_program::id()),
Account::new(0, 512, id()), Account::new(0, 0, system_program::id()),
Account::new(0, 0, id()), Account::new(0, 0, system_program::id()),
]; ];
let from_account = 0; let from_account = 0;
let contract_account = 1; let contract_account = 1;
@ -356,9 +350,9 @@ mod test {
#[test] #[test]
fn test_cancel_transfer() { fn test_cancel_transfer() {
let mut accounts = vec![ let mut accounts = vec![
Account::new(1, 0, id()), Account::new(1, 0, system_program::id()),
Account::new(0, 512, id()), Account::new(0, 0, system_program::id()),
Account::new(0, 0, id()), Account::new(0, 0, system_program::id()),
]; ];
let from_account = 0; let from_account = 0;
let contract_account = 1; let contract_account = 1;
@ -422,41 +416,4 @@ mod test {
assert_eq!(accounts[contract_account].lamports, 0); assert_eq!(accounts[contract_account].lamports, 0);
assert_eq!(accounts[pay_account].lamports, 0); assert_eq!(accounts[pay_account].lamports, 0);
} }
#[test]
fn test_userdata_too_small() {
let mut accounts = vec![
Account::new(1, 0, id()),
Account::new(1, 0, id()), // <== userdata is 0, which is not enough
Account::new(1, 0, id()),
];
let from = Keypair::new();
let contract = Keypair::new();
let to = Keypair::new();
let tx = BudgetTransaction::new_on_date(
&from,
to.pubkey(),
contract.pubkey(),
Utc::now(),
from.pubkey(),
None,
1,
Hash::default(),
);
assert!(process_transaction(&tx, &mut accounts).is_err());
assert!(BudgetState::deserialize(&accounts[1].userdata).is_err());
let tx = BudgetTransaction::new_timestamp(
&from,
contract.pubkey(),
to.pubkey(),
Utc::now(),
Hash::default(),
);
assert!(process_transaction(&tx, &mut accounts).is_err());
assert!(BudgetState::deserialize(&accounts[1].userdata).is_err());
// Success if there was no panic...
}
} }

View File

@ -9,7 +9,7 @@ use solana_sdk::solana_entrypoint;
solana_entrypoint!(entrypoint); solana_entrypoint!(entrypoint);
fn entrypoint( fn entrypoint(
_program_id: &Pubkey, program_id: &Pubkey,
keyed_accounts: &mut [KeyedAccount], keyed_accounts: &mut [KeyedAccount],
data: &[u8], data: &[u8],
_tick_height: u64, _tick_height: u64,
@ -18,5 +18,5 @@ fn entrypoint(
trace!("process_instruction: {:?}", data); trace!("process_instruction: {:?}", data);
trace!("keyed_accounts: {:?}", keyed_accounts); trace!("keyed_accounts: {:?}", keyed_accounts);
process_instruction(keyed_accounts, data).map_err(|_| ProgramError::GenericError) process_instruction(program_id, keyed_accounts, data).map_err(|_| ProgramError::GenericError)
} }

View File

@ -43,12 +43,18 @@ impl BudgetInstruction {
to: Pubkey, to: Pubkey,
dt: DateTime<Utc>, dt: DateTime<Utc>,
) -> BuilderInstruction { ) -> BuilderInstruction {
let keys = vec![(from, true), (contract, false), (to, false)]; let mut keys = vec![(from, true), (contract, false)];
if from != to {
keys.push((to, false));
}
BuilderInstruction::new(id(), &BudgetInstruction::ApplyTimestamp(dt), keys) BuilderInstruction::new(id(), &BudgetInstruction::ApplyTimestamp(dt), keys)
} }
pub fn new_apply_signature(from: Pubkey, contract: Pubkey, to: Pubkey) -> BuilderInstruction { pub fn new_apply_signature(from: Pubkey, contract: Pubkey, to: Pubkey) -> BuilderInstruction {
let keys = vec![(from, true), (contract, false), (to, false)]; let mut keys = vec![(from, true), (contract, false)];
if from != to {
keys.push((to, false));
}
BuilderInstruction::new(id(), &BudgetInstruction::ApplySignature, keys) BuilderInstruction::new(id(), &BudgetInstruction::ApplySignature, keys)
} }
} }

View File

@ -196,9 +196,9 @@ pub fn process_transaction<F, E>(
process_instruction: F, process_instruction: F,
) -> Result<(), E> ) -> Result<(), E>
where where
F: Fn(&mut [KeyedAccount], &[u8]) -> Result<(), E>, F: Fn(&Pubkey, &mut [KeyedAccount], &[u8]) -> Result<(), E>,
{ {
for ix in &tx.instructions { for (i, ix) in tx.instructions.iter().enumerate() {
let mut ix_accounts = get_subset_unchecked_mut(tx_accounts, &ix.accounts); let mut ix_accounts = get_subset_unchecked_mut(tx_accounts, &ix.accounts);
let mut keyed_accounts: Vec<_> = ix let mut keyed_accounts: Vec<_> = ix
.accounts .accounts
@ -212,7 +212,13 @@ where
.map(|((key, is_signer), account)| KeyedAccount::new(key, is_signer, account)) .map(|((key, is_signer), account)| KeyedAccount::new(key, is_signer, account))
.collect(); .collect();
process_instruction(&mut keyed_accounts, &ix.userdata)?; let program_id = tx.program_id(i);
if system_program::check_id(&program_id) {
solana_system_program::entrypoint(&program_id, &mut keyed_accounts, &ix.userdata, 0)
.unwrap();
} else {
process_instruction(&program_id, &mut keyed_accounts, &ix.userdata)?;
}
} }
Ok(()) Ok(())
} }