Return program error from process_transaction()
Our unit-test helper `process_transaction()` wasn't returning program errors, which made testing programs tedious and counter-intuitive.
This commit is contained in:
parent
db825b6e26
commit
49b7e67585
|
@ -1,8 +1,8 @@
|
||||||
//use solana_runtime::bank::BankError;
|
use solana_runtime::bank::BankError;
|
||||||
use solana_runtime::bank::{Bank, Result};
|
use solana_runtime::bank::{Bank, Result};
|
||||||
use solana_sdk::genesis_block::GenesisBlock;
|
use solana_sdk::genesis_block::GenesisBlock;
|
||||||
use solana_sdk::hash::hash;
|
use solana_sdk::hash::hash;
|
||||||
//use solana_sdk::native_program::ProgramError;
|
use solana_sdk::native_program::ProgramError;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
use solana_sdk::system_instruction::SystemInstruction;
|
use solana_sdk::system_instruction::SystemInstruction;
|
||||||
|
@ -86,15 +86,15 @@ fn test_vote_via_bank_with_no_signature() {
|
||||||
.push(vote_ix)
|
.push(vote_ix)
|
||||||
.sign(&[&mallory_keypair], last_id);
|
.sign(&[&mallory_keypair], last_id);
|
||||||
|
|
||||||
let _result = bank.process_transaction(&tx);
|
let result = bank.process_transaction(&tx);
|
||||||
|
|
||||||
// And ensure there's no vote.
|
// And ensure there's no vote.
|
||||||
let vote_account = bank.get_account(&vote_id).unwrap();
|
let vote_account = bank.get_account(&vote_id).unwrap();
|
||||||
let vote_state = VoteState::deserialize(&vote_account.userdata).unwrap();
|
let vote_state = VoteState::deserialize(&vote_account.userdata).unwrap();
|
||||||
assert_eq!(vote_state.votes.len(), 0);
|
assert_eq!(vote_state.votes.len(), 0);
|
||||||
|
|
||||||
//assert_eq!(
|
assert_eq!(
|
||||||
// result,
|
result,
|
||||||
// Err(BankError::ProgramError(1, ProgramError::InvalidArgument))
|
Err(BankError::ProgramError(1, ProgramError::InvalidArgument))
|
||||||
//);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,9 @@ fn test_program_native_failure() {
|
||||||
|
|
||||||
// Call user program
|
// Call user program
|
||||||
let tx = Transaction::new(&mint_keypair, &[], program_id, &1u8, bank.last_id(), 0);
|
let tx = Transaction::new(&mint_keypair, &[], program_id, &1u8, bank.last_id(), 0);
|
||||||
bank.process_transaction(&tx).unwrap();
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bank.get_signature_status(&tx.signatures[0]),
|
bank.process_transaction(&tx),
|
||||||
Some(Err(BankError::ProgramError(0, ProgramError::GenericError)))
|
Err(BankError::ProgramError(0, ProgramError::GenericError))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -358,13 +358,10 @@ impl Bank {
|
||||||
/// Process a Transaction. This is used for unit tests and simply calls the vector Bank::process_transactions method.
|
/// Process a Transaction. This is used for unit tests and simply calls the vector Bank::process_transactions method.
|
||||||
pub fn process_transaction(&self, tx: &Transaction) -> Result<()> {
|
pub fn process_transaction(&self, tx: &Transaction) -> Result<()> {
|
||||||
let txs = vec![tx.clone()];
|
let txs = vec![tx.clone()];
|
||||||
match self.process_transactions(&txs)[0] {
|
self.process_transactions(&txs)[0].clone()?;
|
||||||
Err(ref e) => {
|
tx.signatures
|
||||||
info!("process_transaction error: {:?}", e);
|
.get(0)
|
||||||
Err((*e).clone())
|
.map_or(Ok(()), |sig| self.get_signature_status(sig).unwrap())
|
||||||
}
|
|
||||||
Ok(_) => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lock_accounts(&self, txs: &[Transaction]) -> Vec<Result<()>> {
|
pub fn lock_accounts(&self, txs: &[Transaction]) -> Vec<Result<()>> {
|
||||||
|
@ -951,7 +948,7 @@ mod tests {
|
||||||
|
|
||||||
// This test demonstrates that fees are paid even when a program fails.
|
// This test demonstrates that fees are paid even when a program fails.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_detect_failed_duplicate_transactions_issue_1157() {
|
fn test_detect_failed_duplicate_transactions() {
|
||||||
let (genesis_block, mint_keypair) = GenesisBlock::new(2);
|
let (genesis_block, mint_keypair) = GenesisBlock::new(2);
|
||||||
let bank = Bank::new(&genesis_block);
|
let bank = Bank::new(&genesis_block);
|
||||||
let dest = Keypair::new();
|
let dest = Keypair::new();
|
||||||
|
@ -967,16 +964,12 @@ mod tests {
|
||||||
let signature = tx.signatures[0];
|
let signature = tx.signatures[0];
|
||||||
assert!(!bank.has_signature(&signature));
|
assert!(!bank.has_signature(&signature));
|
||||||
|
|
||||||
// Assert that process_transaction has filtered out Program Errors
|
|
||||||
assert_eq!(bank.process_transaction(&tx), Ok(()));
|
|
||||||
|
|
||||||
assert!(bank.has_signature(&signature));
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bank.get_signature_status(&signature),
|
bank.process_transaction(&tx),
|
||||||
Some(Err(BankError::ProgramError(
|
Err(BankError::ProgramError(
|
||||||
0,
|
0,
|
||||||
ProgramError::ResultWithNegativeTokens
|
ProgramError::ResultWithNegativeTokens
|
||||||
)))
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
// The tokens didn't move, but the from address paid the transaction fee.
|
// The tokens didn't move, but the from address paid the transaction fee.
|
||||||
|
@ -1007,18 +1000,14 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(bank.transaction_count(), 1);
|
assert_eq!(bank.transaction_count(), 1);
|
||||||
assert_eq!(bank.get_balance(&pubkey), 1_000);
|
assert_eq!(bank.get_balance(&pubkey), 1_000);
|
||||||
let signature = bank
|
|
||||||
.transfer(10_001, &mint_keypair, pubkey, genesis_block.hash())
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(bank.transaction_count(), 1);
|
|
||||||
assert!(bank.has_signature(&signature));
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bank.get_signature_status(&signature),
|
bank.transfer(10_001, &mint_keypair, pubkey, genesis_block.hash()),
|
||||||
Some(Err(BankError::ProgramError(
|
Err(BankError::ProgramError(
|
||||||
0,
|
0,
|
||||||
ProgramError::ResultWithNegativeTokens
|
ProgramError::ResultWithNegativeTokens
|
||||||
)))
|
))
|
||||||
);
|
);
|
||||||
|
assert_eq!(bank.transaction_count(), 1);
|
||||||
|
|
||||||
let mint_pubkey = mint_keypair.pubkey();
|
let mint_pubkey = mint_keypair.pubkey();
|
||||||
assert_eq!(bank.get_balance(&mint_pubkey), 10_000);
|
assert_eq!(bank.get_balance(&mint_pubkey), 10_000);
|
||||||
|
|
Loading…
Reference in New Issue