Remove hash field from account (#9915)

This commit is contained in:
Justin Starry 2020-05-12 23:39:46 +08:00 committed by GitHub
parent a75086287c
commit 5cc252d471
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 54 deletions

View File

@ -93,7 +93,6 @@ impl RpcAccount {
})?,
executable: self.executable,
rent_epoch: self.rent_epoch,
..Account::default()
})
}
}

View File

@ -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;

View File

@ -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)
);
}

View File

@ -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,
}
}

View File

@ -550,16 +550,7 @@ impl Bank {
F: Fn(&Option<Account>) -> 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(&current_account.hash);
assert_eq!(
expected_next_slot,
Clock::from_account(&current_account).unwrap().slot

View File

@ -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,
)
}
}

View File

@ -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(),
}
}