Add test with transaction with no signatures

Add checks for no signature
This commit is contained in:
Stephen Akridge
2019-03-02 14:01:53 -08:00
committed by sakridge
parent 9ce2bc94bf
commit 97274030b9
2 changed files with 48 additions and 6 deletions

View File

@ -312,17 +312,23 @@ impl Bank {
let mut status_cache = self.status_cache.write().unwrap();
for (i, tx) in txs.iter().enumerate() {
match &res[i] {
Ok(_) => status_cache.add(&tx.signatures[0]),
Ok(_) => {
if !tx.signatures.is_empty() {
status_cache.add(&tx.signatures[0]);
}
}
Err(BankError::BlockhashNotFound) => (),
Err(BankError::DuplicateSignature) => (),
Err(BankError::AccountNotFound) => (),
Err(e) => {
if !tx.signatures.is_empty() {
status_cache.add(&tx.signatures[0]);
status_cache.save_failure_status(&tx.signatures[0], e.clone());
}
}
}
}
}
/// Looks through a list of tick heights and stakes, and finds the latest
/// tick that has achieved confirmation
@ -447,6 +453,9 @@ impl Bank {
txs.iter()
.zip(lock_results.into_iter())
.map(|(tx, lock_res)| {
if tx.signatures.is_empty() {
return lock_res;
}
if lock_res.is_ok() && StatusCache::has_signature_all(&caches, &tx.signatures[0]) {
error_counters.duplicate_signature += 1;
Err(BankError::DuplicateSignature)
@ -1517,4 +1526,35 @@ mod tests {
assert!(child.epoch_vote_accounts(i).is_some());
}
#[test]
fn test_zero_signatures() {
solana_logger::setup();
let (genesis_block, mint_keypair) = GenesisBlock::new(500);
let bank = Arc::new(Bank::new(&genesis_block));
let key = Keypair::new();
let move_tokens = SystemInstruction::Move { tokens: 1 };
let mut tx = Transaction::new_unsigned(
&mint_keypair.pubkey(),
&[key.pubkey()],
system_program::id(),
&move_tokens,
bank.last_blockhash(),
2,
);
assert_eq!(
bank.process_transaction(&tx),
Err(BankError::MissingSignatureForFee)
);
// Set the fee to 0, this should give a ProgramError
// but since no signature we cannot look up the error.
tx.fee = 0;
assert_eq!(bank.process_transaction(&tx), Ok(()));
assert_eq!(bank.get_balance(&key.pubkey()), 0);
}
}

View File

@ -256,9 +256,11 @@ impl Transaction {
// a hash of a slice of transactions only needs to hash the signatures
pub fn hash(transactions: &[Transaction]) -> Hash {
let mut hasher = Hasher::default();
transactions
.iter()
.for_each(|tx| hasher.hash(&tx.signatures[0].as_ref()));
transactions.iter().for_each(|tx| {
if !tx.signatures.is_empty() {
hasher.hash(&tx.signatures[0].as_ref());
}
});
hasher.result()
}