From 1c1d83bd5604ff2109e176f452a7d127132903b7 Mon Sep 17 00:00:00 2001 From: Rob Walker Date: Fri, 31 May 2019 12:26:45 -0700 Subject: [PATCH] skip syscall_id in hash and delta (#4500) * skip syscall_id in hash and delta * add more tests, skip syscalls --- runtime/src/accounts.rs | 16 +++++++++++----- runtime/src/bank.rs | 31 ++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/runtime/src/accounts.rs b/runtime/src/accounts.rs index 9d6d0d873f..5a90c3224b 100644 --- a/runtime/src/accounts.rs +++ b/runtime/src/accounts.rs @@ -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] diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 6cfa40f135..f231ea1cc6 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -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]