diff --git a/client/src/rpc_response.rs b/client/src/rpc_response.rs index d339b95fe..e15a74943 100644 --- a/client/src/rpc_response.rs +++ b/client/src/rpc_response.rs @@ -93,7 +93,6 @@ impl RpcAccount { })?, executable: self.executable, rent_epoch: self.rent_epoch, - ..Account::default() }) } } diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 9f4fbe278..467dcc47a 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -13,7 +13,6 @@ use solana_sdk::{ bpf_loader, entrypoint::SUCCESS, entrypoint_native::InvokeContext, - hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, message::Message, program_error::ProgramError, @@ -399,7 +398,6 @@ impl<'a> SyscallProcessInstruction<'a> for SyscallProcessInstructionRust<'a> { executable: account_info.executable, owner: *owner, rent_epoch: account_info.rent_epoch, - hash: Hash::default(), }))); refs.push((lamports_ref, data)); continue 'root; @@ -599,7 +597,6 @@ impl<'a> SyscallProcessInstruction<'a> for SyscallProcessSolInstructionC<'a> { executable: account_info.executable, owner: *owner, rent_epoch: account_info.rent_epoch, - hash: Hash::default(), }))); refs.push((lamports_ref, data)); continue 'root; diff --git a/runtime/src/accounts_db.rs b/runtime/src/accounts_db.rs index 9ebf4cfef..54aa13591 100644 --- a/runtime/src/accounts_db.rs +++ b/runtime/src/accounts_db.rs @@ -396,8 +396,8 @@ impl<'a, 'b> Serialize for AccountsDBSerialize<'a, 'b> { #[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq)] pub struct BankHashStats { + pub num_updated_accounts: u64, pub num_removed_accounts: u64, - pub num_added_accounts: u64, pub num_lamports_stored: u64, pub total_data_len: u64, pub num_executable_accounts: u64, @@ -405,10 +405,10 @@ pub struct BankHashStats { impl BankHashStats { pub fn update(&mut self, account: &Account) { - if Hash::default() == account.hash { - self.num_added_accounts += 1; - } else { + if account.lamports == 0 { self.num_removed_accounts += 1; + } else { + self.num_updated_accounts += 1; } self.total_data_len = self.total_data_len.wrapping_add(account.data.len() as u64); if account.executable { @@ -418,8 +418,8 @@ impl BankHashStats { } pub fn merge(&mut self, other: &BankHashStats) { + self.num_updated_accounts += other.num_updated_accounts; self.num_removed_accounts += other.num_removed_accounts; - self.num_added_accounts += other.num_added_accounts; self.total_data_len = self.total_data_len.wrapping_add(other.total_data_len); self.num_lamports_stored = self .num_lamports_stored @@ -956,6 +956,7 @@ impl AccountsDB { stored_accounts.push(( account.meta.pubkey, account.clone_account(), + *account.hash, next - start, (store.id, account.offset), account.meta.write_version, @@ -980,7 +981,14 @@ impl AccountsDB { stored_accounts .iter() .filter( - |(pubkey, _account, _storage_size, (store_id, offset), _write_version)| { + |( + pubkey, + _account, + _account_hash, + _storage_size, + (store_id, offset), + _write_version, + )| { if let Some((list, _)) = accounts_index.get(pubkey, &no_ancestors) { list.iter() .any(|(_slot, i)| i.store_id == *store_id && i.offset == *offset) @@ -994,7 +1002,11 @@ impl AccountsDB { let alive_total: u64 = alive_accounts .iter() - .map(|(_pubkey, _account, account_size, _location, _write_verion)| *account_size as u64) + .map( + |(_pubkey, _account, _account_hash, account_size, _location, _write_verion)| { + *account_size as u64 + }, + ) .sum(); let aligned_total: u64 = (alive_total + (PAGE_SIZE - 1)) & !(PAGE_SIZE - 1); @@ -1012,9 +1024,9 @@ impl AccountsDB { let mut hashes = Vec::with_capacity(alive_accounts.len()); let mut write_versions = Vec::with_capacity(alive_accounts.len()); - for (pubkey, account, _size, _location, write_version) in alive_accounts { + for (pubkey, account, account_hash, _size, _location, write_version) in alive_accounts { accounts.push((pubkey, account)); - hashes.push(account.hash); + hashes.push(*account_hash); write_versions.push(*write_version); } @@ -1183,6 +1195,19 @@ impl AccountsDB { } } + #[cfg(test)] + fn load_account_hash(&self, ancestors: &Ancestors, pubkey: &Pubkey) -> Hash { + let accounts_index = self.accounts_index.read().unwrap(); + let (lock, index) = accounts_index.get(pubkey, ancestors).unwrap(); + let slot = lock[index].0; + let storage = self.storage.read().unwrap(); + let slot_storage = storage.0.get(&slot).unwrap(); + let info = &lock[index].1; + let entry = slot_storage.get(&info.store_id).unwrap(); + let account = entry.accounts.get_account(info.offset); + *account.as_ref().unwrap().0.hash + } + pub fn load_slow(&self, ancestors: &Ancestors, pubkey: &Pubkey) -> Option<(Account, Slot)> { let accounts_index = self.accounts_index.read().unwrap(); let storage = self.storage.read().unwrap(); @@ -3500,16 +3525,16 @@ pub mod tests { db.store(some_slot, &[(&key, &account)]); let mut account = db.load_slow(&ancestors, &key).unwrap().0; - account.lamports += 1; + account.lamports -= 1; account.executable = true; db.store(some_slot, &[(&key, &account)]); db.add_root(some_slot); let bank_hashes = db.bank_hashes.read().unwrap(); let bank_hash = bank_hashes.get(&some_slot).unwrap(); + assert_eq!(bank_hash.stats.num_updated_accounts, 1); assert_eq!(bank_hash.stats.num_removed_accounts, 1); - assert_eq!(bank_hash.stats.num_added_accounts, 1); - assert_eq!(bank_hash.stats.num_lamports_stored, 3); + assert_eq!(bank_hash.stats.num_lamports_stored, 1); assert_eq!(bank_hash.stats.total_data_len, 2 * some_data_len as u64); assert_eq!(bank_hash.stats.num_executable_accounts, 1); } @@ -3622,9 +3647,8 @@ pub mod tests { db.store(some_slot, &account_refs); for (key, account) in &accounts_keys { - let loaded_account = db.load_slow(&ancestors, key).unwrap().0; assert_eq!( - loaded_account.hash, + db.load_account_hash(&ancestors, key), AccountsDB::hash_account(some_slot, &account, &key) ); } diff --git a/runtime/src/append_vec.rs b/runtime/src/append_vec.rs index 832cea6ff..134fcc844 100644 --- a/runtime/src/append_vec.rs +++ b/runtime/src/append_vec.rs @@ -75,7 +75,6 @@ impl<'a> StoredAccount<'a> { executable: self.account_meta.executable, rent_epoch: self.account_meta.rent_epoch, data: self.data.to_vec(), - hash: *self.hash, } } diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index b2b1b5059..f4a1e58d7 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -550,16 +550,7 @@ impl Bank { F: Fn(&Option) -> Account, { let old_account = self.get_sysvar_account(pubkey); - let mut new_account = updater(&old_account); - - // Normally, just use the hash from parent slot. However, use the - // existing stored hash if any for the sake of bank hash's idempotent. - if let Some((modified_account, _)) = self.get_account_modified_since_parent(pubkey) { - new_account.hash = modified_account.hash; - } else if let Some(old_account) = old_account { - new_account.hash = old_account.hash; - } - + let new_account = updater(&old_account); self.store_account(pubkey, &new_account); } @@ -4518,7 +4509,6 @@ mod tests { .create_account(1) }); let current_account = bank2.get_account(&dummy_clock_id).unwrap(); - //let added_bank_hash = BankHash::from_hash(¤t_account.hash); assert_eq!( expected_next_slot, Clock::from_account(¤t_account).unwrap().slot diff --git a/sdk/src/account.rs b/sdk/src/account.rs index 7d6e8378c..df244d05e 100644 --- a/sdk/src/account.rs +++ b/sdk/src/account.rs @@ -1,4 +1,4 @@ -use crate::{clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey}; +use crate::{clock::Epoch, instruction::InstructionError, pubkey::Pubkey}; use std::{ cell::{Ref, RefCell, RefMut}, cmp, fmt, @@ -8,7 +8,7 @@ use std::{ /// An Account with data that is stored on chain #[repr(C)] -#[derive(Serialize, Deserialize, Clone, Default)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Default)] #[serde(rename_all = "camelCase")] pub struct Account { /// lamports in the account @@ -22,26 +22,8 @@ pub struct Account { pub executable: bool, /// the epoch at which this account will next owe rent pub rent_epoch: Epoch, - /// Hash of this account's state, skip serializing as to not expose to external api - /// Used for keeping the accounts state hash updated. - #[serde(skip)] - pub hash: Hash, } -/// skip comparison of account.hash, since it is only meaningful when the account is loaded in a -/// given fork and some tests do not have that. -impl PartialEq for Account { - fn eq(&self, other: &Self) -> bool { - self.lamports == other.lamports - && self.data == other.data - && self.owner == other.owner - && self.executable == other.executable - && self.rent_epoch == other.rent_epoch - } -} - -impl Eq for Account {} - impl fmt::Debug for Account { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let data_len = cmp::min(64, self.data.len()); @@ -52,14 +34,13 @@ impl fmt::Debug for Account { }; write!( f, - "Account {{ lamports: {} data.len: {} owner: {} executable: {} rent_epoch: {}{} hash: {} }}", + "Account {{ lamports: {} data.len: {} owner: {} executable: {} rent_epoch: {}{} }}", self.lamports, self.data.len(), self.owner, self.executable, self.rent_epoch, data_str, - self.hash, ) } } diff --git a/sdk/src/native_loader.rs b/sdk/src/native_loader.rs index e7bdff6d4..20abc9762 100644 --- a/sdk/src/native_loader.rs +++ b/sdk/src/native_loader.rs @@ -1,4 +1,4 @@ -use crate::{account::Account, hash::Hash}; +use crate::account::Account; crate::declare_id!("NativeLoader1111111111111111111111111111111"); @@ -10,6 +10,5 @@ pub fn create_loadable_account(name: &str) -> Account { data: name.as_bytes().to_vec(), executable: true, rent_epoch: 0, - hash: Hash::default(), } }