don't return zero lamport accounts from 'load' with feature (#27793)
* don't return zero lamport accounts from 'load' * add feature * rename
This commit is contained in:
parent
bac6ebcd88
commit
138d5ed5b0
|
@ -4,7 +4,7 @@ use {
|
|||
account_rent_state::{check_rent_state_with_account, RentState},
|
||||
accounts_db::{
|
||||
AccountShrinkThreshold, AccountsAddRootTiming, AccountsDb, AccountsDbConfig,
|
||||
BankHashInfo, LoadHint, LoadedAccount, ScanStorageResult,
|
||||
BankHashInfo, LoadHint, LoadZeroLamports, LoadedAccount, ScanStorageResult,
|
||||
ACCOUNTS_DB_CONFIG_FOR_BENCHMARKS, ACCOUNTS_DB_CONFIG_FOR_TESTING,
|
||||
},
|
||||
accounts_index::{
|
||||
|
@ -35,8 +35,8 @@ use {
|
|||
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
||||
clock::{BankId, Slot, INITIAL_RENT_EPOCH},
|
||||
feature_set::{
|
||||
self, remove_deprecated_request_unit_ix, use_default_units_in_fee_calculation,
|
||||
FeatureSet,
|
||||
self, remove_deprecated_request_unit_ix, return_none_for_zero_lamport_accounts,
|
||||
use_default_units_in_fee_calculation, FeatureSet,
|
||||
},
|
||||
fee::FeeStructure,
|
||||
genesis_config::ClusterType,
|
||||
|
@ -258,6 +258,13 @@ impl Accounts {
|
|||
feature_set: &FeatureSet,
|
||||
account_overrides: Option<&AccountOverrides>,
|
||||
) -> Result<LoadedTransaction> {
|
||||
let load_zero_lamports =
|
||||
if feature_set.is_active(&return_none_for_zero_lamport_accounts::id()) {
|
||||
LoadZeroLamports::None
|
||||
} else {
|
||||
LoadZeroLamports::SomeWithZeroLamportAccount
|
||||
};
|
||||
|
||||
// Copy all the accounts
|
||||
let message = tx.message();
|
||||
// NOTE: this check will never fail because `tx` is sanitized
|
||||
|
@ -293,7 +300,7 @@ impl Accounts {
|
|||
(account_override.clone(), 0)
|
||||
} else {
|
||||
self.accounts_db
|
||||
.load_with_fixed_root(ancestors, key)
|
||||
.load_with_fixed_root(ancestors, key, load_zero_lamports)
|
||||
.map(|(mut account, _)| {
|
||||
if message.is_writable(i) {
|
||||
let rent_due = rent_collector
|
||||
|
@ -342,9 +349,12 @@ impl Accounts {
|
|||
programdata_address,
|
||||
}) = account.state()
|
||||
{
|
||||
if let Some((programdata_account, _)) = self
|
||||
.accounts_db
|
||||
.load_with_fixed_root(ancestors, &programdata_address)
|
||||
if let Some((programdata_account, _)) =
|
||||
self.accounts_db.load_with_fixed_root(
|
||||
ancestors,
|
||||
&programdata_address,
|
||||
load_zero_lamports,
|
||||
)
|
||||
{
|
||||
account_deps
|
||||
.push((programdata_address, programdata_account));
|
||||
|
@ -388,6 +398,7 @@ impl Accounts {
|
|||
&mut accounts,
|
||||
instruction.program_id_index as IndexOfAccount,
|
||||
error_counters,
|
||||
load_zero_lamports,
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<Vec<IndexOfAccount>>>>()?;
|
||||
|
@ -459,6 +470,7 @@ impl Accounts {
|
|||
accounts: &mut Vec<TransactionAccount>,
|
||||
mut program_account_index: IndexOfAccount,
|
||||
error_counters: &mut TransactionErrorMetrics,
|
||||
load_zero_lamports: LoadZeroLamports,
|
||||
) -> Result<Vec<IndexOfAccount>> {
|
||||
let mut account_indices = Vec::new();
|
||||
let mut program_id = match accounts.get(program_account_index as usize) {
|
||||
|
@ -476,10 +488,11 @@ impl Accounts {
|
|||
}
|
||||
depth += 1;
|
||||
|
||||
program_account_index = match self
|
||||
.accounts_db
|
||||
.load_with_fixed_root(ancestors, &program_id)
|
||||
{
|
||||
program_account_index = match self.accounts_db.load_with_fixed_root(
|
||||
ancestors,
|
||||
&program_id,
|
||||
load_zero_lamports,
|
||||
) {
|
||||
Some((program_account, _)) => {
|
||||
let account_index = accounts.len() as IndexOfAccount;
|
||||
accounts.push((program_id, program_account));
|
||||
|
@ -505,10 +518,11 @@ impl Accounts {
|
|||
programdata_address,
|
||||
}) = program.state()
|
||||
{
|
||||
let programdata_account_index = match self
|
||||
.accounts_db
|
||||
.load_with_fixed_root(ancestors, &programdata_address)
|
||||
{
|
||||
let programdata_account_index = match self.accounts_db.load_with_fixed_root(
|
||||
ancestors,
|
||||
&programdata_address,
|
||||
load_zero_lamports,
|
||||
) {
|
||||
Some((programdata_account, _)) => {
|
||||
let account_index = accounts.len() as IndexOfAccount;
|
||||
accounts.push((programdata_address, programdata_account));
|
||||
|
@ -606,10 +620,15 @@ impl Accounts {
|
|||
ancestors: &Ancestors,
|
||||
address_table_lookup: &MessageAddressTableLookup,
|
||||
slot_hashes: &SlotHashes,
|
||||
load_zero_lamports: LoadZeroLamports,
|
||||
) -> std::result::Result<LoadedAddresses, AddressLookupError> {
|
||||
let table_account = self
|
||||
.accounts_db
|
||||
.load_with_fixed_root(ancestors, &address_table_lookup.account_key)
|
||||
.load_with_fixed_root(
|
||||
ancestors,
|
||||
&address_table_lookup.account_key,
|
||||
load_zero_lamports,
|
||||
)
|
||||
.map(|(account, _rent)| account)
|
||||
.ok_or(AddressLookupError::LookupTableAccountNotFound)?;
|
||||
|
||||
|
@ -2077,6 +2096,7 @@ mod tests {
|
|||
&ancestors,
|
||||
&address_table_lookup,
|
||||
&SlotHashes::default(),
|
||||
LoadZeroLamports::SomeWithZeroLamportAccount,
|
||||
),
|
||||
Err(AddressLookupError::LookupTableAccountNotFound),
|
||||
);
|
||||
|
@ -2094,7 +2114,8 @@ mod tests {
|
|||
);
|
||||
|
||||
let invalid_table_key = Pubkey::new_unique();
|
||||
let invalid_table_account = AccountSharedData::default();
|
||||
let mut invalid_table_account = AccountSharedData::default();
|
||||
invalid_table_account.set_lamports(1);
|
||||
accounts.store_slow_uncached(0, &invalid_table_key, &invalid_table_account);
|
||||
|
||||
let address_table_lookup = MessageAddressTableLookup {
|
||||
|
@ -2108,6 +2129,7 @@ mod tests {
|
|||
&ancestors,
|
||||
&address_table_lookup,
|
||||
&SlotHashes::default(),
|
||||
LoadZeroLamports::SomeWithZeroLamportAccount,
|
||||
),
|
||||
Err(AddressLookupError::InvalidAccountOwner),
|
||||
);
|
||||
|
@ -2140,6 +2162,7 @@ mod tests {
|
|||
&ancestors,
|
||||
&address_table_lookup,
|
||||
&SlotHashes::default(),
|
||||
LoadZeroLamports::SomeWithZeroLamportAccount,
|
||||
),
|
||||
Err(AddressLookupError::InvalidAccountData),
|
||||
);
|
||||
|
@ -2184,6 +2207,7 @@ mod tests {
|
|||
&ancestors,
|
||||
&address_table_lookup,
|
||||
&SlotHashes::default(),
|
||||
LoadZeroLamports::SomeWithZeroLamportAccount,
|
||||
),
|
||||
Ok(LoadedAddresses {
|
||||
writable: vec![table_addresses[0]],
|
||||
|
@ -2498,6 +2522,7 @@ mod tests {
|
|||
&mut vec![(keypair.pubkey(), account)],
|
||||
0,
|
||||
&mut error_counters,
|
||||
LoadZeroLamports::SomeWithZeroLamportAccount,
|
||||
),
|
||||
Err(TransactionError::ProgramAccountNotFound)
|
||||
);
|
||||
|
|
|
@ -145,6 +145,17 @@ pub enum StoreReclaims {
|
|||
Ignore,
|
||||
}
|
||||
|
||||
/// specifies how to return zero lamport accounts
|
||||
/// This will only be useful until a feature activation occurs.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum LoadZeroLamports {
|
||||
/// return None if loaded account has zero lamports
|
||||
None,
|
||||
/// return Some(account with zero lamports) if loaded account has zero lamports
|
||||
/// Today this is the default. With feature activation, this will no longer be possible.
|
||||
SomeWithZeroLamportAccount,
|
||||
}
|
||||
|
||||
// the current best way to add filler accounts is gradually.
|
||||
// In other scenarios, such as monitoring catchup with large # of accounts, it may be useful to be able to
|
||||
// add filler accounts at the beginning, so that code path remains but won't execute at the moment.
|
||||
|
@ -4586,8 +4597,15 @@ impl AccountsDb {
|
|||
&self,
|
||||
ancestors: &Ancestors,
|
||||
pubkey: &Pubkey,
|
||||
load_zero_lamports: LoadZeroLamports,
|
||||
) -> Option<(AccountSharedData, Slot)> {
|
||||
self.load(ancestors, pubkey, LoadHint::FixedMaxRoot)
|
||||
.filter(|(account, _)| {
|
||||
matches!(
|
||||
load_zero_lamports,
|
||||
LoadZeroLamports::SomeWithZeroLamportAccount
|
||||
) || !account.is_zero_lamport()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn load_without_fixed_root(
|
||||
|
@ -13859,13 +13877,13 @@ pub mod tests {
|
|||
|
||||
assert_eq!(db.read_only_accounts_cache.cache_len(), 0);
|
||||
let account = db
|
||||
.load_with_fixed_root(&Ancestors::default(), &account_key)
|
||||
.load_with_fixed_root(&Ancestors::default(), &account_key, LoadZeroLamports::None)
|
||||
.map(|(account, _)| account)
|
||||
.unwrap();
|
||||
assert_eq!(account.lamports(), 1);
|
||||
assert_eq!(db.read_only_accounts_cache.cache_len(), 1);
|
||||
let account = db
|
||||
.load_with_fixed_root(&Ancestors::default(), &account_key)
|
||||
.load_with_fixed_root(&Ancestors::default(), &account_key, LoadZeroLamports::None)
|
||||
.map(|(account, _)| account)
|
||||
.unwrap();
|
||||
assert_eq!(account.lamports(), 1);
|
||||
|
@ -13873,10 +13891,9 @@ pub mod tests {
|
|||
db.store_cached((2, &[(&account_key, &zero_lamport_account)][..]), None);
|
||||
assert_eq!(db.read_only_accounts_cache.cache_len(), 1);
|
||||
let account = db
|
||||
.load_with_fixed_root(&Ancestors::default(), &account_key)
|
||||
.map(|(account, _)| account)
|
||||
.unwrap();
|
||||
assert_eq!(account.lamports(), 0);
|
||||
.load_with_fixed_root(&Ancestors::default(), &account_key, LoadZeroLamports::None)
|
||||
.map(|(account, _)| account);
|
||||
assert!(account.is_none());
|
||||
assert_eq!(db.read_only_accounts_cache.cache_len(), 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use {
|
||||
super::Bank,
|
||||
crate::accounts_db::LoadZeroLamports,
|
||||
solana_address_lookup_table_program::error::AddressLookupError,
|
||||
solana_sdk::{
|
||||
feature_set::return_none_for_zero_lamport_accounts,
|
||||
message::v0::{LoadedAddresses, MessageAddressTableLookup},
|
||||
transaction::{AddressLoader, Result as TransactionResult, TransactionError},
|
||||
},
|
||||
|
@ -16,6 +18,15 @@ impl AddressLoader for &Bank {
|
|||
return Err(TransactionError::UnsupportedVersion);
|
||||
}
|
||||
|
||||
let load_zero_lamports = if self
|
||||
.feature_set
|
||||
.is_active(&return_none_for_zero_lamport_accounts::id())
|
||||
{
|
||||
LoadZeroLamports::None
|
||||
} else {
|
||||
LoadZeroLamports::SomeWithZeroLamportAccount
|
||||
};
|
||||
|
||||
let slot_hashes = self
|
||||
.sysvar_cache
|
||||
.read()
|
||||
|
@ -30,6 +41,7 @@ impl AddressLoader for &Bank {
|
|||
&self.ancestors,
|
||||
address_table_lookup,
|
||||
&slot_hashes,
|
||||
load_zero_lamports,
|
||||
)
|
||||
})
|
||||
.collect::<Result<_, AddressLookupError>>()?)
|
||||
|
|
|
@ -514,6 +514,10 @@ pub mod cap_accounts_data_allocations_per_transaction {
|
|||
solana_sdk::declare_id!("9gxu85LYRAcZL38We8MYJ4A9AwgBBPtVBAqebMcT1241");
|
||||
}
|
||||
|
||||
pub mod return_none_for_zero_lamport_accounts {
|
||||
solana_sdk::declare_id!("7K5HFrS1WAq6ND7RQbShXZXbtAookyTfaDQPTJNuZpze");
|
||||
}
|
||||
|
||||
pub mod epoch_accounts_hash {
|
||||
solana_sdk::declare_id!("5GpmAKxaGsWWbPp4bNXFLJxZVvG92ctxf7jQnzTQjF3n");
|
||||
}
|
||||
|
@ -645,6 +649,7 @@ lazy_static! {
|
|||
(stop_sibling_instruction_search_at_parent::id(), "stop the search in get_processed_sibling_instruction when the parent instruction is reached #27289"),
|
||||
(vote_state_update_root_fix::id(), "fix root in vote state updates #27361"),
|
||||
(cap_accounts_data_allocations_per_transaction::id(), "cap accounts data allocations per transaction #27375"),
|
||||
(return_none_for_zero_lamport_accounts::id(), "return none for zero lamport accounts #27800"),
|
||||
(epoch_accounts_hash::id(), "enable epoch accounts hash calculation #27539"),
|
||||
(remove_deprecated_request_unit_ix::id(), "remove support for RequestUnitsDeprecated instruction #27500"),
|
||||
/*************** ADD NEW FEATURES HERE ***************/
|
||||
|
|
Loading…
Reference in New Issue