skip syscall_id in hash and delta (#4500)

* skip syscall_id in hash and delta

* add more tests, skip syscalls
This commit is contained in:
Rob Walker
2019-05-31 12:26:45 -07:00
committed by GitHub
parent 028e111fbc
commit 1c1d83bd56
2 changed files with 37 additions and 10 deletions

View File

@ -15,6 +15,7 @@ use solana_sdk::hash::{Hash, Hasher};
use solana_sdk::native_loader;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::syscall;
use solana_sdk::system_program;
use solana_sdk::transaction::Result;
use solana_sdk::transaction::{Transaction, TransactionError};
@ -450,11 +451,13 @@ impl Accounts {
|stored_account: &StoredAccount,
_id: AppendVecId,
accum: &mut Vec<(Pubkey, u64, Hash)>| {
accum.push((
stored_account.meta.pubkey,
stored_account.meta.write_version,
Self::hash_account(stored_account),
));
if !syscall::check_id(&stored_account.balance.owner) {
accum.push((
stored_account.meta.pubkey,
stored_account.meta.write_version,
Self::hash_account(stored_account),
));
}
},
);
let mut account_hashes: Vec<_> = accumulator.into_iter().flat_map(|x| x).collect();
@ -600,6 +603,7 @@ mod tests {
use solana_sdk::hash::Hash;
use solana_sdk::instruction::CompiledInstruction;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::syscall;
use solana_sdk::transaction::Transaction;
use std::io::Cursor;
use std::thread::{sleep, Builder};
@ -1087,6 +1091,8 @@ mod tests {
fn test_accounts_empty_hash_internal_state() {
let accounts = Accounts::new(None);
assert_eq!(accounts.hash_internal_state(0), None);
accounts.store_slow(0, &Pubkey::default(), &Account::new(1, 0, &syscall::id()));
assert_eq!(accounts.hash_internal_state(0), None);
}
#[test]

View File

@ -1068,12 +1068,11 @@ impl Bank {
fn hash_internal_state(&self) -> Hash {
// If there are no accounts, return the same hash as we did before
// checkpointing.
if !self.rc.accounts.has_accounts(self.slot()) {
return self.parent_hash;
if let Some(accounts_delta_hash) = self.rc.accounts.hash_internal_state(self.slot()) {
extend_and_hash(&self.parent_hash, &serialize(&accounts_delta_hash).unwrap())
} else {
self.parent_hash
}
let accounts_delta_hash = self.rc.accounts.hash_internal_state(self.slot());
extend_and_hash(&self.parent_hash, &serialize(&accounts_delta_hash).unwrap())
}
/// Return the number of ticks per slot
@ -2009,10 +2008,19 @@ mod tests {
system_transaction::transfer(&mint_keypair, &key1.pubkey(), 1, genesis_block.hash());
assert_eq!(bank.process_transaction(&tx_transfer_mint_to_1), Ok(()));
assert_eq!(bank.is_delta.load(Ordering::Relaxed), true);
let bank1 = new_from_parent(&bank);
assert_eq!(bank1.is_delta.load(Ordering::Relaxed), false);
assert_eq!(bank1.hash_internal_state(), bank.hash());
// ticks don't make a bank into a delta
bank.register_tick(&Hash::default());
assert_eq!(bank1.is_delta.load(Ordering::Relaxed), false);
assert_eq!(bank1.hash_internal_state(), bank.hash());
}
#[test]
fn test_is_votable() {
// test normal case
let (genesis_block, mint_keypair) = create_genesis_block(500);
let bank = Arc::new(Bank::new(&genesis_block));
let key1 = Keypair::new();
@ -2030,6 +2038,19 @@ mod tests {
}
assert_eq!(bank.is_votable(), true);
// test empty bank with ticks
let (genesis_block, _mint_keypair) = create_genesis_block(500);
// make an empty bank at slot 1
let bank = new_from_parent(&Arc::new(Bank::new(&genesis_block)));
assert_eq!(bank.is_votable(), false);
// Register enough ticks to hit max tick height
for i in 0..genesis_block.ticks_per_slot - 1 {
bank.register_tick(&hash::hash(format!("hello world {}", i).as_bytes()));
}
// empty banks aren't votable even at max tick height
assert_eq!(bank.is_votable(), false);
}
#[test]