@ -1023,25 +1023,34 @@ impl AccountsDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_stored_account(slot: Slot, account: &StoredAccount) -> Hash {
|
pub fn hash_stored_account(slot: Slot, account: &StoredAccount, include_owner: bool) -> Hash {
|
||||||
Self::hash_account_data(
|
Self::hash_account_data(
|
||||||
slot,
|
slot,
|
||||||
account.account_meta.lamports,
|
account.account_meta.lamports,
|
||||||
|
&account.account_meta.owner,
|
||||||
account.account_meta.executable,
|
account.account_meta.executable,
|
||||||
account.account_meta.rent_epoch,
|
account.account_meta.rent_epoch,
|
||||||
account.data,
|
account.data,
|
||||||
&account.meta.pubkey,
|
&account.meta.pubkey,
|
||||||
|
include_owner,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_account(slot: Slot, account: &Account, pubkey: &Pubkey) -> Hash {
|
pub fn hash_account(
|
||||||
|
slot: Slot,
|
||||||
|
account: &Account,
|
||||||
|
pubkey: &Pubkey,
|
||||||
|
include_owner: bool,
|
||||||
|
) -> Hash {
|
||||||
Self::hash_account_data(
|
Self::hash_account_data(
|
||||||
slot,
|
slot,
|
||||||
account.lamports,
|
account.lamports,
|
||||||
|
&account.owner,
|
||||||
account.executable,
|
account.executable,
|
||||||
account.rent_epoch,
|
account.rent_epoch,
|
||||||
&account.data,
|
&account.data,
|
||||||
pubkey,
|
pubkey,
|
||||||
|
include_owner,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,13 +1069,20 @@ impl AccountsDB {
|
|||||||
hasher.result()
|
hasher.result()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn include_owner_in_hash(slot: Slot) -> bool {
|
||||||
|
// Account hashing updated to include owner activates at this slot on the mainnet-beta
|
||||||
|
slot >= 11_000_000
|
||||||
|
}
|
||||||
|
|
||||||
pub fn hash_account_data(
|
pub fn hash_account_data(
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
lamports: u64,
|
lamports: u64,
|
||||||
|
owner: &Pubkey,
|
||||||
executable: bool,
|
executable: bool,
|
||||||
rent_epoch: Epoch,
|
rent_epoch: Epoch,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
|
include_owner: bool,
|
||||||
) -> Hash {
|
) -> Hash {
|
||||||
if lamports == 0 {
|
if lamports == 0 {
|
||||||
return Hash::default();
|
return Hash::default();
|
||||||
@ -1092,6 +1108,10 @@ impl AccountsDB {
|
|||||||
hasher.hash(&[0u8; 1]);
|
hasher.hash(&[0u8; 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if include_owner {
|
||||||
|
hasher.hash(&owner.as_ref());
|
||||||
|
}
|
||||||
|
|
||||||
hasher.hash(&pubkey.as_ref());
|
hasher.hash(&pubkey.as_ref());
|
||||||
|
|
||||||
hasher.result()
|
hasher.result()
|
||||||
@ -1258,7 +1278,11 @@ impl AccountsDB {
|
|||||||
let account = store.accounts.get_account(account_info.offset)?.0;
|
let account = store.accounts.get_account(account_info.offset)?.0;
|
||||||
|
|
||||||
if check_hash {
|
if check_hash {
|
||||||
let hash = Self::hash_stored_account(*slot, &account);
|
let hash = Self::hash_stored_account(
|
||||||
|
*slot,
|
||||||
|
&account,
|
||||||
|
Self::include_owner_in_hash(*slot),
|
||||||
|
);
|
||||||
if hash != *account.hash {
|
if hash != *account.hash {
|
||||||
mismatch_found.store(true, Ordering::Relaxed);
|
mismatch_found.store(true, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
@ -1460,7 +1484,12 @@ impl AccountsDB {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(pubkey, account)| {
|
.map(|(pubkey, account)| {
|
||||||
stats.update(account);
|
stats.update(account);
|
||||||
Self::hash_account(slot_id, account, pubkey)
|
Self::hash_account(
|
||||||
|
slot_id,
|
||||||
|
account,
|
||||||
|
pubkey,
|
||||||
|
Self::include_owner_in_hash(slot_id),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -3022,19 +3051,33 @@ pub mod tests {
|
|||||||
hash: &hash,
|
hash: &hash,
|
||||||
};
|
};
|
||||||
let account = stored_account.clone_account();
|
let account = stored_account.clone_account();
|
||||||
let expected_account_hash =
|
let expected_account_hash_without_owner =
|
||||||
Hash::from_str("GGTsxvxwnMsNfN6yYbBVQaRgvbVLfxeWnGXNyB8iXDyE").unwrap();
|
Hash::from_str("GGTsxvxwnMsNfN6yYbBVQaRgvbVLfxeWnGXNyB8iXDyE").unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
AccountsDB::hash_stored_account(slot, &stored_account),
|
AccountsDB::hash_stored_account(slot, &stored_account, false),
|
||||||
expected_account_hash,
|
expected_account_hash_without_owner,
|
||||||
"StoredAccount's data layout might be changed; update hashing if needed."
|
"StoredAccount's data layout might be changed; update hashing if needed."
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
AccountsDB::hash_account(slot, &account, &stored_account.meta.pubkey),
|
AccountsDB::hash_account(slot, &account, &stored_account.meta.pubkey, false),
|
||||||
expected_account_hash,
|
expected_account_hash_without_owner,
|
||||||
"Account-based hashing must be consistent with StoredAccount-based one."
|
"Account-based hashing must be consistent with StoredAccount-based one."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let expected_account_hash_with_owner =
|
||||||
|
Hash::from_str("5iRNZVcAnq9JLYjSF2ibFhGEeq48r9Eq9HXxwm3BxywN").unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
AccountsDB::hash_stored_account(slot, &stored_account, true),
|
||||||
|
expected_account_hash_with_owner,
|
||||||
|
"StoredAccount's data layout might be changed; update hashing if needed (with owner)."
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
AccountsDB::hash_account(slot, &account, &stored_account.meta.pubkey, true),
|
||||||
|
expected_account_hash_with_owner,
|
||||||
|
"Account-based hashing must be consistent with StoredAccount-based one (with owner)."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -3175,7 +3218,7 @@ pub mod tests {
|
|||||||
let loaded_account = db.load_slow(&ancestors, key).unwrap().0;
|
let loaded_account = db.load_slow(&ancestors, key).unwrap().0;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
loaded_account.hash,
|
loaded_account.hash,
|
||||||
AccountsDB::hash_account(some_slot, &account, &key)
|
AccountsDB::hash_account(some_slot, &account, &key, false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user