From 6d5c6c17c57d1e0a5afd2cc010f575b2056a7b88 Mon Sep 17 00:00:00 2001 From: Ryo Onodera Date: Thu, 25 Mar 2021 15:23:20 +0900 Subject: [PATCH] Simplify account.rent_epoch handling for sysvar rent (#16049) * Add some code for special local testing * Add comment to store_account_and_update_capitalization * Simplify account.rent_epoch handling for sysvar rent * Introduce *_for_test functions * Add deprecation messages to existing api --- account-decoder/src/parse_sysvar.rs | 20 +++--- programs/bpf_loader/src/lib.rs | 17 +++--- programs/stake/src/stake_instruction.rs | 29 +++++---- programs/vote/src/vote_instruction.rs | 6 +- runtime/src/accounts.rs | 4 +- runtime/src/accounts_db.rs | 8 +-- runtime/src/bank.rs | 67 +++++++++++++-------- runtime/src/message_processor.rs | 8 +-- runtime/src/system_instruction_processor.rs | 24 ++++---- sdk/benches/slot_hashes.rs | 4 +- sdk/benches/slot_history.rs | 4 +- sdk/program/src/clock.rs | 2 + sdk/src/account.rs | 47 ++++++++++++++- sdk/src/keyed_account.rs | 4 +- sdk/src/native_loader.rs | 22 ++++++- sdk/src/recent_blockhashes_account.rs | 44 +++++++++++--- 16 files changed, 206 insertions(+), 104 deletions(-) diff --git a/account-decoder/src/parse_sysvar.rs b/account-decoder/src/parse_sysvar.rs index af4a39536e..b5bef681f7 100644 --- a/account-decoder/src/parse_sysvar.rs +++ b/account-decoder/src/parse_sysvar.rs @@ -214,13 +214,13 @@ pub struct UiStakeHistoryEntry { mod test { use super::*; use solana_sdk::{ - account::create_account, fee_calculator::FeeCalculator, hash::Hash, + account::create_account_for_test, fee_calculator::FeeCalculator, hash::Hash, sysvar::recent_blockhashes::IterItem, }; #[test] fn test_parse_sysvars() { - let clock_sysvar = create_account(&Clock::default(), 1); + let clock_sysvar = create_account_for_test(&Clock::default()); assert_eq!( parse_sysvar(&clock_sysvar.data, &sysvar::clock::id()).unwrap(), SysvarAccountType::Clock(UiClock::default()), @@ -233,13 +233,13 @@ mod test { first_normal_epoch: 1, first_normal_slot: 12, }; - let epoch_schedule_sysvar = create_account(&epoch_schedule, 1); + let epoch_schedule_sysvar = create_account_for_test(&epoch_schedule); assert_eq!( parse_sysvar(&epoch_schedule_sysvar.data, &sysvar::epoch_schedule::id()).unwrap(), SysvarAccountType::EpochSchedule(epoch_schedule), ); - let fees_sysvar = create_account(&Fees::default(), 1); + let fees_sysvar = create_account_for_test(&Fees::default()); assert_eq!( parse_sysvar(&fees_sysvar.data, &sysvar::fees::id()).unwrap(), SysvarAccountType::Fees(UiFees::default()), @@ -252,7 +252,7 @@ mod test { let recent_blockhashes: RecentBlockhashes = vec![IterItem(0, &hash, &fee_calculator)] .into_iter() .collect(); - let recent_blockhashes_sysvar = create_account(&recent_blockhashes, 1); + let recent_blockhashes_sysvar = create_account_for_test(&recent_blockhashes); assert_eq!( parse_sysvar( &recent_blockhashes_sysvar.data, @@ -270,13 +270,13 @@ mod test { exemption_threshold: 2.0, burn_percent: 5, }; - let rent_sysvar = create_account(&rent, 1); + let rent_sysvar = create_account_for_test(&rent); assert_eq!( parse_sysvar(&rent_sysvar.data, &sysvar::rent::id()).unwrap(), SysvarAccountType::Rent(rent.into()), ); - let rewards_sysvar = create_account(&Rewards::default(), 1); + let rewards_sysvar = create_account_for_test(&Rewards::default()); assert_eq!( parse_sysvar(&rewards_sysvar.data, &sysvar::rewards::id()).unwrap(), SysvarAccountType::Rewards(UiRewards::default()), @@ -284,7 +284,7 @@ mod test { let mut slot_hashes = SlotHashes::default(); slot_hashes.add(1, hash); - let slot_hashes_sysvar = create_account(&slot_hashes, 1); + let slot_hashes_sysvar = create_account_for_test(&slot_hashes); assert_eq!( parse_sysvar(&slot_hashes_sysvar.data, &sysvar::slot_hashes::id()).unwrap(), SysvarAccountType::SlotHashes(vec![UiSlotHashEntry { @@ -295,7 +295,7 @@ mod test { let mut slot_history = SlotHistory::default(); slot_history.add(42); - let slot_history_sysvar = create_account(&slot_history, 1); + let slot_history_sysvar = create_account_for_test(&slot_history); assert_eq!( parse_sysvar(&slot_history_sysvar.data, &sysvar::slot_history::id()).unwrap(), SysvarAccountType::SlotHistory(UiSlotHistory { @@ -311,7 +311,7 @@ mod test { deactivating: 3, }; stake_history.add(1, stake_history_entry.clone()); - let stake_history_sysvar = create_account(&stake_history, 1); + let stake_history_sysvar = create_account_for_test(&stake_history); assert_eq!( parse_sysvar(&stake_history_sysvar.data, &sysvar::stake_history::id()).unwrap(), SysvarAccountType::StakeHistory(vec![UiStakeHistoryEntry { diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index c9aa96bfd1..1245f80033 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -884,7 +884,9 @@ mod tests { message_processor::{Executors, ThisInvokeContext}, }; use solana_sdk::{ - account::{create_account_shared_data as create_account, AccountSharedData}, + account::{ + create_account_shared_data_for_test as create_account_for_test, AccountSharedData, + }, account_utils::StateMut, client::SyncClient, clock::Clock, @@ -2215,15 +2217,12 @@ mod tests { file.read_to_end(&mut elf_new).unwrap(); assert_ne!(elf_orig.len(), elf_new.len()); let rent = Rent::default(); - let rent_account = RefCell::new(create_account(&Rent::default(), 1)); + let rent_account = RefCell::new(create_account_for_test(&Rent::default())); let slot = 42; - let clock_account = RefCell::new(create_account( - &Clock { - slot, - ..Clock::default() - }, - 1, - )); + let clock_account = RefCell::new(create_account_for_test(&Clock { + slot, + ..Clock::default() + })); let min_program_balance = 1.max(rent.minimum_balance(UpgradeableLoaderState::program_len().unwrap())); let min_programdata_balance = 1.max(rent.minimum_balance( diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index e44205c201..722994ddb2 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -663,15 +663,17 @@ mod tests { .iter() .map(|meta| { RefCell::new(if sysvar::clock::check_id(&meta.pubkey) { - account::create_account_shared_data(&sysvar::clock::Clock::default(), 1) + account::create_account_shared_data_for_test(&sysvar::clock::Clock::default()) } else if sysvar::rewards::check_id(&meta.pubkey) { - account::create_account_shared_data(&sysvar::rewards::Rewards::new(0.0), 1) + account::create_account_shared_data_for_test(&sysvar::rewards::Rewards::new( + 0.0, + )) } else if sysvar::stake_history::check_id(&meta.pubkey) { - account::create_account_shared_data(&StakeHistory::default(), 1) + account::create_account_shared_data_for_test(&StakeHistory::default()) } else if config::check_id(&meta.pubkey) { config::create_account(0, &config::Config::default()) } else if sysvar::rent::check_id(&meta.pubkey) { - account::create_account_shared_data(&Rent::default(), 1) + account::create_account_shared_data_for_test(&Rent::default()) } else if meta.pubkey == invalid_stake_state_pubkey() { AccountSharedData::from(Account { owner: id(), @@ -973,7 +975,9 @@ mod tests { KeyedAccount::new( &sysvar::rent::id(), false, - &RefCell::new(account::create_account_shared_data(&Rent::default(), 0)) + &RefCell::new(account::create_account_shared_data_for_test( + &Rent::default() + )) ) ], &serialize(&StakeInstruction::Initialize( @@ -1028,17 +1032,15 @@ mod tests { KeyedAccount::new( &sysvar::clock::id(), false, - &RefCell::new(account::create_account_shared_data( + &RefCell::new(account::create_account_shared_data_for_test( &sysvar::clock::Clock::default(), - 1 )) ), KeyedAccount::new( &sysvar::stake_history::id(), false, - &RefCell::new(account::create_account_shared_data( + &RefCell::new(account::create_account_shared_data_for_test( &sysvar::stake_history::StakeHistory::default(), - 1 )) ), KeyedAccount::new( @@ -1063,17 +1065,15 @@ mod tests { KeyedAccount::new( &sysvar::rewards::id(), false, - &RefCell::new(account::create_account_shared_data( + &RefCell::new(account::create_account_shared_data_for_test( &sysvar::rewards::Rewards::new(0.0), - 1 )) ), KeyedAccount::new( &sysvar::stake_history::id(), false, - &RefCell::new(account::create_account_shared_data( + &RefCell::new(account::create_account_shared_data_for_test( &StakeHistory::default(), - 1, )) ), ], @@ -1107,9 +1107,8 @@ mod tests { KeyedAccount::new( &sysvar::rewards::id(), false, - &RefCell::new(account::create_account_shared_data( + &RefCell::new(account::create_account_shared_data_for_test( &sysvar::rewards::Rewards::new(0.0), - 1 )) ), ], diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index eb5701becd..402a19c067 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -370,11 +370,11 @@ mod tests { .iter() .map(|meta| { RefCell::new(if sysvar::clock::check_id(&meta.pubkey) { - account::create_account_shared_data(&Clock::default(), 1) + account::create_account_shared_data_for_test(&Clock::default()) } else if sysvar::slot_hashes::check_id(&meta.pubkey) { - account::create_account_shared_data(&SlotHashes::default(), 1) + account::create_account_shared_data_for_test(&SlotHashes::default()) } else if sysvar::rent::check_id(&meta.pubkey) { - account::create_account_shared_data(&Rent::free(), 1) + account::create_account_shared_data_for_test(&Rent::free()) } else if meta.pubkey == invalid_vote_state_pubkey() { AccountSharedData::from(Account { owner: invalid_vote_state_pubkey(), diff --git a/runtime/src/accounts.rs b/runtime/src/accounts.rs index 9fe735f550..963b198a12 100644 --- a/runtime/src/accounts.rs +++ b/runtime/src/accounts.rs @@ -19,7 +19,7 @@ use solana_sdk::{ account::{Account, AccountSharedData}, account_utils::StateMut, bpf_loader_upgradeable::{self, UpgradeableLoaderState}, - clock::Slot, + clock::{Slot, INITIAL_RENT_EPOCH}, feature_set::{self, FeatureSet}, fee_calculator::{FeeCalculator, FeeConfig}, genesis_config::ClusterType, @@ -944,7 +944,7 @@ impl Accounts { _ => panic!("unexpected nonce_rollback condition"), } } - if account.rent_epoch == 0 { + if account.rent_epoch == INITIAL_RENT_EPOCH { loaded_transaction.rent += rent_collector.collect_from_created_account(&key, account); } diff --git a/runtime/src/accounts_db.rs b/runtime/src/accounts_db.rs index abde4df9f6..30650d524f 100644 --- a/runtime/src/accounts_db.rs +++ b/runtime/src/accounts_db.rs @@ -7204,7 +7204,7 @@ pub mod tests { some_slot, &[( &native_account_pubkey, - &solana_sdk::native_loader::create_loadable_account("foo", 1), + &solana_sdk::native_loader::create_loadable_account_for_test("foo"), )], ); db.update_accounts_hash_test(some_slot, &ancestors); @@ -8104,9 +8104,8 @@ pub mod tests { #[test] fn test_account_balance_for_capitalization_sysvar() { - let normal_sysvar = solana_sdk::account::create_account( + let normal_sysvar = solana_sdk::account::create_account_for_test( &solana_sdk::slot_history::SlotHistory::default(), - 1, ); assert_eq!( AccountsDb::account_balance_for_capitalization( @@ -8126,7 +8125,8 @@ pub mod tests { #[test] fn test_account_balance_for_capitalization_native_program() { - let normal_native_program = solana_sdk::native_loader::create_loadable_account("foo", 1); + let normal_native_program = + solana_sdk::native_loader::create_loadable_account_for_test("foo"); assert_eq!( AccountsDb::account_balance_for_capitalization( normal_native_program.lamports, diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index fc4d6c0913..b72cc23d32 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -32,13 +32,13 @@ use solana_measure::measure::Measure; use solana_metrics::{datapoint_debug, inc_new_counter_debug, inc_new_counter_info}; use solana_sdk::{ account::{ - create_account_shared_data as create_account, from_account, Account, AccountSharedData, - ReadableAccount, + create_account_shared_data_with_fields as create_account, from_account, Account, + AccountSharedData, InheritableAccountFields, ReadableAccount, }, clock::{ Epoch, Slot, SlotCount, SlotIndex, UnixTimestamp, DEFAULT_TICKS_PER_SECOND, - MAX_PROCESSING_AGE, MAX_RECENT_BLOCKHASHES, MAX_TRANSACTION_FORWARDING_DELAY, - SECONDS_PER_DAY, + INITIAL_RENT_EPOCH, MAX_PROCESSING_AGE, MAX_RECENT_BLOCKHASHES, + MAX_TRANSACTION_FORWARDING_DELAY, SECONDS_PER_DAY, }, epoch_info::EpochInfo, epoch_schedule::EpochSchedule, @@ -1156,7 +1156,7 @@ impl Bank { new.update_sysvar_account(&sysvar::clock::id(), |account| { create_account( &clock, - new.inherit_specially_retained_account_balance(account), + new.inherit_specially_retained_account_fields(account), ) }); @@ -1370,11 +1370,14 @@ impl Bank { self.store_account_and_update_capitalization(pubkey, &new_account); } - fn inherit_specially_retained_account_balance( + fn inherit_specially_retained_account_fields( &self, old_account: &Option, - ) -> u64 { - old_account.as_ref().map(|a| a.lamports).unwrap_or(1) + ) -> InheritableAccountFields { + ( + old_account.as_ref().map(|a| a.lamports).unwrap_or(1), + INITIAL_RENT_EPOCH, + ) } /// Unused conversion @@ -1455,7 +1458,7 @@ impl Bank { self.update_sysvar_account(&sysvar::clock::id(), |account| { create_account( &clock, - self.inherit_specially_retained_account_balance(account), + self.inherit_specially_retained_account_fields(account), ) }); } @@ -1469,7 +1472,7 @@ impl Bank { slot_history.add(self.slot()); create_account( &slot_history, - self.inherit_specially_retained_account_balance(account), + self.inherit_specially_retained_account_fields(account), ) }); } @@ -1483,7 +1486,7 @@ impl Bank { slot_hashes.add(self.parent_slot, self.parent_hash); create_account( &slot_hashes, - self.inherit_specially_retained_account_balance(account), + self.inherit_specially_retained_account_fields(account), ) }); } @@ -1528,7 +1531,7 @@ impl Bank { self.update_sysvar_account(&sysvar::fees::id(), |account| { create_account( &sysvar::fees::Fees::new(&self.fee_calculator), - self.inherit_specially_retained_account_balance(account), + self.inherit_specially_retained_account_fields(account), ) }); } @@ -1537,7 +1540,7 @@ impl Bank { self.update_sysvar_account(&sysvar::rent::id(), |account| { create_account( &self.rent_collector.rent, - self.inherit_specially_retained_account_balance(account), + self.inherit_specially_retained_account_fields(account), ) }); } @@ -1546,7 +1549,7 @@ impl Bank { self.update_sysvar_account(&sysvar::epoch_schedule::id(), |account| { create_account( &self.epoch_schedule, - self.inherit_specially_retained_account_balance(account), + self.inherit_specially_retained_account_fields(account), ) }); } @@ -1559,7 +1562,7 @@ impl Bank { self.update_sysvar_account(&sysvar::stake_history::id(), |account| { create_account::( &self.stakes.read().unwrap().history(), - self.inherit_specially_retained_account_balance(account), + self.inherit_specially_retained_account_fields(account), ) }); } @@ -1687,7 +1690,7 @@ impl Bank { self.update_sysvar_account(&sysvar::rewards::id(), |account| { create_account( &sysvar::rewards::Rewards::new(validator_point_value), - self.inherit_specially_retained_account_balance(account), + self.inherit_specially_retained_account_fields(account), ) }); } @@ -1914,9 +1917,9 @@ impl Bank { fn update_recent_blockhashes_locked(&self, locked_blockhash_queue: &BlockhashQueue) { self.update_sysvar_account(&sysvar::recent_blockhashes::id(), |account| { let recent_blockhash_iter = locked_blockhash_queue.get_recent_blockhashes(); - recent_blockhashes_account::create_account_with_data( - self.inherit_specially_retained_account_balance(account), + recent_blockhashes_account::create_account_with_data_and_fields( recent_blockhash_iter, + self.inherit_specially_retained_account_fields(account), ) }); } @@ -2255,9 +2258,9 @@ impl Bank { ); // Add a bogus executable native account, which will be loaded and ignored. - let account = native_loader::create_loadable_account( + let account = native_loader::create_loadable_account_with_fields( name, - self.inherit_specially_retained_account_balance(&existing_genuine_program), + self.inherit_specially_retained_account_fields(&existing_genuine_program), ); self.store_account_and_update_capitalization(&program_id, &account); @@ -3739,11 +3742,25 @@ impl Bank { // for development/performance purpose. // Absolutely not under ClusterType::MainnetBeta!!!! fn use_multi_epoch_collection_cycle(&self, epoch: Epoch) -> bool { + // Force normal behavior, disabling multi epoch collection cycle for manual local testing + #[cfg(not(test))] + if self.slot_count_per_normal_epoch() == solana_sdk::epoch_schedule::MINIMUM_SLOTS_PER_EPOCH + { + return false; + } + epoch >= self.first_normal_epoch() && self.slot_count_per_normal_epoch() < self.slot_count_in_two_day() } fn use_fixed_collection_cycle(&self) -> bool { + // Force normal behavior, disabling fixed collection cycle for manual local testing + #[cfg(not(test))] + if self.slot_count_per_normal_epoch() == solana_sdk::epoch_schedule::MINIMUM_SLOTS_PER_EPOCH + { + return false; + } + self.cluster_type() != ClusterType::MainnetBeta && self.slot_count_per_normal_epoch() < self.slot_count_in_two_day() } @@ -3912,6 +3929,8 @@ impl Bank { self.rc.accounts.accounts_db.expire_old_recycle_stores() } + /// Technically this issues (or even burns!) new lamports, + /// so be extra careful for its usage fn store_account_and_update_capitalization( &self, pubkey: &Pubkey, @@ -8237,7 +8256,7 @@ pub(crate) mod tests { slot: expected_previous_slot, ..Clock::default() }, - bank1.inherit_specially_retained_account_balance(optional_account), + bank1.inherit_specially_retained_account_fields(optional_account), ) }); let current_account = bank1.get_account(&dummy_clock_id).unwrap(); @@ -8262,7 +8281,7 @@ pub(crate) mod tests { slot: expected_previous_slot, ..Clock::default() }, - bank1.inherit_specially_retained_account_balance(optional_account), + bank1.inherit_specially_retained_account_fields(optional_account), ) }) }, @@ -8288,7 +8307,7 @@ pub(crate) mod tests { slot, ..Clock::default() }, - bank2.inherit_specially_retained_account_balance(optional_account), + bank2.inherit_specially_retained_account_fields(optional_account), ) }); let current_account = bank2.get_account(&dummy_clock_id).unwrap(); @@ -8319,7 +8338,7 @@ pub(crate) mod tests { slot, ..Clock::default() }, - bank2.inherit_specially_retained_account_balance(optional_account), + bank2.inherit_specially_retained_account_fields(optional_account), ) }); let current_account = bank2.get_account(&dummy_clock_id).unwrap(); diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 9474f58652..ead89b43db 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -1124,7 +1124,7 @@ mod tests { account::Account, instruction::{AccountMeta, Instruction, InstructionError}, message::Message, - native_loader::create_loadable_account, + native_loader::create_loadable_account_for_test, }; #[test] @@ -1706,9 +1706,8 @@ mod tests { accounts.push(account); let mut loaders: Vec>)>> = Vec::new(); - let account = Rc::new(RefCell::new(create_loadable_account( + let account = Rc::new(RefCell::new(create_loadable_account_for_test( "mock_system_program", - 1, ))); loaders.push(vec![(mock_system_program_id, account)]); @@ -1876,9 +1875,8 @@ mod tests { accounts.push(account); let mut loaders: Vec>)>> = Vec::new(); - let account = Rc::new(RefCell::new(create_loadable_account( + let account = Rc::new(RefCell::new(create_loadable_account_for_test( "mock_system_program", - 1, ))); loaders.push(vec![(mock_program_id, account)]); diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index 570040d6f9..d336dfe836 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -490,17 +490,18 @@ mod tests { RefCell::new(AccountSharedData::default()) } fn create_default_recent_blockhashes_account() -> RefCell { - RefCell::new(recent_blockhashes_account::create_account_with_data( - 1, - vec![ - IterItem(0u64, &Hash::default(), &FeeCalculator::default()); - sysvar::recent_blockhashes::MAX_ENTRIES - ] - .into_iter(), - )) + RefCell::new( + recent_blockhashes_account::create_account_with_data_for_test( + vec![ + IterItem(0u64, &Hash::default(), &FeeCalculator::default()); + sysvar::recent_blockhashes::MAX_ENTRIES + ] + .into_iter(), + ), + ) } fn create_default_rent_account() -> RefCell { - RefCell::new(account::create_account_shared_data(&Rent::free(), 1)) + RefCell::new(account::create_account_shared_data_for_test(&Rent::free())) } #[test] @@ -1376,7 +1377,7 @@ mod tests { RefCell::new(if sysvar::recent_blockhashes::check_id(&meta.pubkey) { create_default_recent_blockhashes_account().into_inner() } else if sysvar::rent::check_id(&meta.pubkey) { - account::create_account_shared_data(&Rent::free(), 1) + account::create_account_shared_data_for_test(&Rent::free()) } else { AccountSharedData::default() }) @@ -1470,8 +1471,7 @@ mod tests { ) .unwrap(); let new_recent_blockhashes_account = RefCell::new( - solana_sdk::recent_blockhashes_account::create_account_with_data( - 1, + solana_sdk::recent_blockhashes_account::create_account_with_data_for_test( vec![ IterItem( 0u64, diff --git a/sdk/benches/slot_hashes.rs b/sdk/benches/slot_hashes.rs index b58a9e64f7..0167d8d777 100644 --- a/sdk/benches/slot_hashes.rs +++ b/sdk/benches/slot_hashes.rs @@ -2,7 +2,7 @@ extern crate test; use solana_sdk::{ - account::{create_account, from_account}, + account::{create_account_for_test, from_account}, hash::Hash, slot_hashes::{Slot, SlotHashes, MAX_ENTRIES}, }; @@ -15,7 +15,7 @@ fn bench_to_from_account(b: &mut Bencher) { slot_hashes.add(i as Slot, Hash::default()); } b.iter(|| { - let account = create_account(&slot_hashes, 0); + let account = create_account_for_test(&slot_hashes); slot_hashes = from_account::(&account).unwrap(); }); } diff --git a/sdk/benches/slot_history.rs b/sdk/benches/slot_history.rs index e1785c9336..9da3cf69d0 100644 --- a/sdk/benches/slot_history.rs +++ b/sdk/benches/slot_history.rs @@ -2,7 +2,7 @@ extern crate test; use solana_sdk::{ - account::{create_account, from_account}, + account::{create_account_for_test, from_account}, slot_history::SlotHistory, }; use test::Bencher; @@ -12,7 +12,7 @@ fn bench_to_from_account(b: &mut Bencher) { let mut slot_history = SlotHistory::default(); b.iter(|| { - let account = create_account(&slot_history, 0); + let account = create_account_for_test(&slot_history); slot_history = from_account::(&account).unwrap(); }); } diff --git a/sdk/program/src/clock.rs b/sdk/program/src/clock.rs index 4f2bc36912..eff1459cdb 100644 --- a/sdk/program/src/clock.rs +++ b/sdk/program/src/clock.rs @@ -63,6 +63,8 @@ pub type Slot = u64; pub type Epoch = u64; pub const GENESIS_EPOCH: Epoch = 0; +// must be sync with Account::rent_epoch::default() +pub const INITIAL_RENT_EPOCH: Epoch = 0; /// SlotIndex is an index to the slots of a epoch pub type SlotIndex = u64; diff --git a/sdk/src/account.rs b/sdk/src/account.rs index 8a3fcad8ea..854b852523 100644 --- a/sdk/src/account.rs +++ b/sdk/src/account.rs @@ -1,4 +1,7 @@ -use crate::{clock::Epoch, pubkey::Pubkey}; +use crate::{ + clock::{Epoch, INITIAL_RENT_EPOCH}, + pubkey::Pubkey, +}; use solana_program::{account_info::AccountInfo, sysvar::Sysvar}; use std::{cell::Ref, cell::RefCell, cmp, fmt, rc::Rc, sync::Arc}; @@ -449,17 +452,57 @@ impl AccountSharedData { } } +pub type InheritableAccountFields = (u64, Epoch); +pub const DUMMY_INHERITABLE_ACCOUNT_FIELDS: InheritableAccountFields = (1, INITIAL_RENT_EPOCH); + /// Create an `Account` from a `Sysvar`. +#[deprecated( + since = "1.5.17", + note = "Please use `create_account_for_test` instead" +)] pub fn create_account(sysvar: &S, lamports: u64) -> Account { + create_account_with_fields(sysvar, (lamports, INITIAL_RENT_EPOCH)) +} + +pub fn create_account_with_fields( + sysvar: &S, + (lamports, rent_epoch): InheritableAccountFields, +) -> Account { let data_len = S::size_of().max(bincode::serialized_size(sysvar).unwrap() as usize); let mut account = Account::new(lamports, data_len, &solana_program::sysvar::id()); to_account::(sysvar, &mut account).unwrap(); + account.rent_epoch = rent_epoch; account } +pub fn create_account_for_test(sysvar: &S) -> Account { + create_account_with_fields(sysvar, DUMMY_INHERITABLE_ACCOUNT_FIELDS) +} + /// Create an `Account` from a `Sysvar`. +#[deprecated( + since = "1.5.17", + note = "Please use `create_account_shared_data_for_test` instead" +)] pub fn create_account_shared_data(sysvar: &S, lamports: u64) -> AccountSharedData { - AccountSharedData::from(create_account(sysvar, lamports)) + AccountSharedData::from(create_account_with_fields( + sysvar, + (lamports, INITIAL_RENT_EPOCH), + )) +} + +pub fn create_account_shared_data_with_fields( + sysvar: &S, + fields: InheritableAccountFields, +) -> AccountSharedData { + AccountSharedData::from(create_account_with_fields(sysvar, fields)) +} + +pub fn create_account_shared_data_for_test(sysvar: &S) -> AccountSharedData { + AccountSharedData::from(create_account_with_fields( + sysvar, + DUMMY_INHERITABLE_ACCOUNT_FIELDS, + )) } /// Create a `Sysvar` from an `Account`'s data. diff --git a/sdk/src/keyed_account.rs b/sdk/src/keyed_account.rs index bd00c5745c..3f60387a3b 100644 --- a/sdk/src/keyed_account.rs +++ b/sdk/src/keyed_account.rs @@ -225,7 +225,7 @@ pub fn from_keyed_account( mod tests { use super::*; use crate::{ - account::{create_account, to_account}, + account::{create_account_for_test, to_account}, pubkey::Pubkey, }; use std::cell::RefCell; @@ -249,7 +249,7 @@ mod tests { let key = crate::keyed_account::tests::id(); let wrong_key = Pubkey::new_unique(); - let account = create_account(&test_sysvar, 42); + let account = create_account_for_test(&test_sysvar); let test_sysvar = from_account::(&account).unwrap(); assert_eq!(test_sysvar, TestSysvar::default()); diff --git a/sdk/src/native_loader.rs b/sdk/src/native_loader.rs index d6e974c3c5..eaed82bade 100644 --- a/sdk/src/native_loader.rs +++ b/sdk/src/native_loader.rs @@ -1,14 +1,32 @@ -use crate::account::{Account, AccountSharedData}; +use crate::account::{ + Account, AccountSharedData, InheritableAccountFields, DUMMY_INHERITABLE_ACCOUNT_FIELDS, +}; +use crate::clock::INITIAL_RENT_EPOCH; crate::declare_id!("NativeLoader1111111111111111111111111111111"); /// Create an executable account with the given shared object name. +#[deprecated( + since = "1.5.17", + note = "Please use `create_loadable_account_for_test` instead" +)] pub fn create_loadable_account(name: &str, lamports: u64) -> AccountSharedData { + create_loadable_account_with_fields(name, (lamports, INITIAL_RENT_EPOCH)) +} + +pub fn create_loadable_account_with_fields( + name: &str, + (lamports, rent_epoch): InheritableAccountFields, +) -> AccountSharedData { AccountSharedData::from(Account { lamports, owner: id(), data: name.as_bytes().to_vec(), executable: true, - rent_epoch: 0, + rent_epoch, }) } + +pub fn create_loadable_account_for_test(name: &str) -> AccountSharedData { + create_loadable_account_with_fields(name, DUMMY_INHERITABLE_ACCOUNT_FIELDS) +} diff --git a/sdk/src/recent_blockhashes_account.rs b/sdk/src/recent_blockhashes_account.rs index 30e6bea27f..58a0694b47 100644 --- a/sdk/src/recent_blockhashes_account.rs +++ b/sdk/src/recent_blockhashes_account.rs @@ -1,4 +1,8 @@ -use crate::account::{create_account_shared_data, to_account, AccountSharedData}; +use crate::account::{ + create_account_shared_data_with_fields, to_account, AccountSharedData, + InheritableAccountFields, DUMMY_INHERITABLE_ACCOUNT_FIELDS, +}; +use crate::clock::INITIAL_RENT_EPOCH; use solana_program::sysvar::recent_blockhashes::{ IntoIterSorted, IterItem, RecentBlockhashes, MAX_ENTRIES, }; @@ -18,16 +22,39 @@ where to_account(&recent_blockhashes, account) } +#[deprecated( + since = "1.5.17", + note = "Please use `create_account_with_data_for_test` instead" +)] pub fn create_account_with_data<'a, I>(lamports: u64, recent_blockhash_iter: I) -> AccountSharedData where I: IntoIterator>, { - let mut account = - create_account_shared_data::(&RecentBlockhashes::default(), lamports); + create_account_with_data_and_fields(recent_blockhash_iter, (lamports, INITIAL_RENT_EPOCH)) +} + +pub fn create_account_with_data_and_fields<'a, I>( + recent_blockhash_iter: I, + fields: InheritableAccountFields, +) -> AccountSharedData +where + I: IntoIterator>, +{ + let mut account = create_account_shared_data_with_fields::( + &RecentBlockhashes::default(), + fields, + ); update_account(&mut account, recent_blockhash_iter).unwrap(); account } +pub fn create_account_with_data_for_test<'a, I>(recent_blockhash_iter: I) -> AccountSharedData +where + I: IntoIterator>, +{ + create_account_with_data_and_fields(recent_blockhash_iter, DUMMY_INHERITABLE_ACCOUNT_FIELDS) +} + #[cfg(test)] mod tests { use super::*; @@ -41,7 +68,7 @@ mod tests { #[test] fn test_create_account_empty() { - let account = create_account_with_data(42, vec![].into_iter()); + let account = create_account_with_data_for_test(vec![].into_iter()); let recent_blockhashes = from_account::(&account).unwrap(); assert_eq!(recent_blockhashes, RecentBlockhashes::default()); } @@ -50,8 +77,7 @@ mod tests { fn test_create_account_full() { let def_hash = Hash::default(); let def_fees = FeeCalculator::default(); - let account = create_account_with_data( - 42, + let account = create_account_with_data_for_test( vec![IterItem(0u64, &def_hash, &def_fees); MAX_ENTRIES].into_iter(), ); let recent_blockhashes = from_account::(&account).unwrap(); @@ -62,8 +88,7 @@ mod tests { fn test_create_account_truncate() { let def_hash = Hash::default(); let def_fees = FeeCalculator::default(); - let account = create_account_with_data( - 42, + let account = create_account_with_data_for_test( vec![IterItem(0u64, &def_hash, &def_fees); MAX_ENTRIES + 1].into_iter(), ); let recent_blockhashes = from_account::(&account).unwrap(); @@ -85,8 +110,7 @@ mod tests { .collect(); unsorted_blocks.shuffle(&mut thread_rng()); - let account = create_account_with_data( - 42, + let account = create_account_with_data_for_test( unsorted_blocks .iter() .map(|(i, hash)| IterItem(*i, hash, &def_fees)),