diff --git a/runtime/src/account_info.rs b/runtime/src/account_info.rs index bc3b3099ae..3a745f854a 100644 --- a/runtime/src/account_info.rs +++ b/runtime/src/account_info.rs @@ -1,3 +1,7 @@ +//! AccountInfo represents a reference to AccountSharedData in either an AppendVec or the write cache. +//! AccountInfo is not persisted anywhere between program runs. +//! AccountInfo is purely runtime state. +//! Note that AccountInfo is saved to disk buckets during runtime, but disk buckets are recreated at startup. use crate::{ accounts_db::{AppendVecId, CACHE_VIRTUAL_OFFSET, CACHE_VIRTUAL_STORAGE_ID}, accounts_index::{IsCached, ZeroLamport}, @@ -22,16 +26,16 @@ pub struct AccountInfo { /// needed to track shrink candidacy in bytes. Used to update the number /// of alive bytes in an AppendVec as newer slots purge outdated entries + /// Note that highest bit is used for ZERO_LAMPORT_BIT stored_size: usize, - - /// lamports in the account used when squashing kept for optimization - /// purposes to remove accounts with zero balance. - lamports: u64, } +/// presence of this bit in stored_size indicates this account info references an account with zero lamports +const ZERO_LAMPORT_BIT: usize = 1 << (usize::BITS - 1); + impl ZeroLamport for AccountInfo { fn is_zero_lamport(&self) -> bool { - self.lamports == 0 + self.stored_size & ZERO_LAMPORT_BIT == ZERO_LAMPORT_BIT } } @@ -42,16 +46,19 @@ impl IsCached for AccountInfo { } impl AccountInfo { - pub fn new(storage_location: StorageLocation, stored_size: usize, lamports: u64) -> Self { + pub fn new(storage_location: StorageLocation, mut stored_size: usize, lamports: u64) -> Self { let (store_id, offset) = match storage_location { StorageLocation::AppendVec(store_id, offset) => (store_id, offset), StorageLocation::Cached => (CACHE_VIRTUAL_STORAGE_ID, CACHE_VIRTUAL_OFFSET), }; + assert!(stored_size < ZERO_LAMPORT_BIT); + if lamports == 0 { + stored_size |= ZERO_LAMPORT_BIT; + } Self { store_id, offset, stored_size, - lamports, } } @@ -64,6 +71,7 @@ impl AccountInfo { } pub fn stored_size(&self) -> usize { - self.stored_size + // elminate the special bit that indicates the info references an account with zero lamports + self.stored_size & !ZERO_LAMPORT_BIT } }