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:
@ -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)>| {
|
||||
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]
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
let accounts_delta_hash = self.rc.accounts.hash_internal_state(self.slot());
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/// 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]
|
||||
|
Reference in New Issue
Block a user