gemachain_runtime/
bank.rs

1//! The `bank` module tracks client accounts and the progress of on-chain
2//! programs.
3//!
4//! A single bank relates to a block produced by a single leader and each bank
5//! except for the genesis bank points back to a parent bank.
6//!
7//! The bank is the main entrypoint for processing verified transactions with the function
8//! `Bank::process_transactions`
9//!
10//! It does this by loading the accounts using the reference it holds on the account store,
11//! and then passing those to the message_processor which handles loading the programs specified
12//! by the Transaction and executing it.
13//!
14//! The bank then stores the results to the accounts store.
15//!
16//! It then has apis for retrieving if a transaction has been processed and it's status.
17//! See `get_signature_status` et al.
18//!
19//! Bank lifecycle:
20//!
21//! A bank is newly created and open to transactions. Transactions are applied
22//! until either the bank reached the tick count when the node is the leader for that slot, or the
23//! node has applied all transactions present in all `Entry`s in the slot.
24//!
25//! Once it is complete, the bank can then be frozen. After frozen, no more transactions can
26//! be applied or state changes made. At the frozen step, rent will be applied and various
27//! sysvar special accounts update to the new state of the system.
28//!
29//! After frozen, and the bank has had the appropriate number of votes on it, then it can become
30//! rooted. At this point, it will not be able to be removed from the chain and the
31//! state is finalized.
32//!
33//! It offers a high-level API that signs transactions
34//! on behalf of the caller, and a low-level API for when they have
35//! already been signed and verified.
36use crate::{
37    accounts::{AccountAddressFilter, Accounts, TransactionAccounts, TransactionLoadResult},
38    accounts_db::{
39        AccountShrinkThreshold, AccountsDbConfig, ErrorCounters, SnapshotStorages,
40        ACCOUNTS_DB_CONFIG_FOR_BENCHMARKS, ACCOUNTS_DB_CONFIG_FOR_TESTING,
41    },
42    accounts_index::{AccountSecondaryIndexes, IndexKey, ScanResult},
43    ancestors::{Ancestors, AncestorsForSerialization},
44    blockhash_queue::BlockhashQueue,
45    builtins::{self, ActivationType, Builtin, Builtins},
46    epoch_stakes::{EpochStakes, NodeVoteAccounts},
47    inline_spl_token_v2_0,
48    instruction_recorder::InstructionRecorder,
49    log_collector::LogCollector,
50    message_processor::MessageProcessor,
51    rent_collector::RentCollector,
52    stake_weighted_timestamp::{
53        calculate_stake_weighted_timestamp, MaxAllowableDrift, MAX_ALLOWABLE_DRIFT_PERCENTAGE,
54        MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST, MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW,
55    },
56    stakes::Stakes,
57    status_cache::{SlotDelta, StatusCache},
58    system_instruction_processor::{get_system_account_kind, SystemAccountKind},
59    transaction_batch::TransactionBatch,
60    vote_account::VoteAccount,
61};
62use byteorder::{ByteOrder, LittleEndian};
63use itertools::Itertools;
64use log::*;
65use rayon::ThreadPool;
66use gemachain_measure::measure::Measure;
67use gemachain_metrics::{datapoint_debug, inc_new_counter_debug, inc_new_counter_info};
68use gemachain_program_runtime::{ExecuteDetailsTimings, Executors};
69#[allow(deprecated)]
70use gemachain_sdk::recent_blockhashes_account;
71use gemachain_sdk::{
72    account::{
73        create_account_shared_data_with_fields as create_account, from_account, Account,
74        AccountSharedData, InheritableAccountFields, ReadableAccount, WritableAccount,
75    },
76    account_utils::StateMut,
77    clock::{
78        BankId, Epoch, Slot, SlotCount, SlotIndex, UnixTimestamp, DEFAULT_TICKS_PER_SECOND,
79        INITIAL_RENT_EPOCH, MAX_PROCESSING_AGE, MAX_RECENT_BLOCKHASHES,
80        MAX_TRANSACTION_FORWARDING_DELAY, SECONDS_PER_DAY,
81    },
82    compute_budget::ComputeBudget,
83    epoch_info::EpochInfo,
84    epoch_schedule::EpochSchedule,
85    feature,
86    feature_set::{self, tx_wide_compute_cap, FeatureSet},
87    fee_calculator::{FeeCalculator, FeeRateGovernor},
88    genesis_config::{ClusterType, GenesisConfig},
89    hard_forks::HardForks,
90    hash::{extend_and_hash, hashv, Hash},
91    incinerator,
92    inflation::Inflation,
93    instruction::{CompiledInstruction, InstructionError},
94    carats::CaratsError,
95    message::SanitizedMessage,
96    native_loader,
97    native_token::gema_to_carats,
98    nonce, nonce_account,
99    packet::PACKET_DATA_SIZE,
100    process_instruction::{ComputeMeter, Executor, ProcessInstructionWithContext},
101    program_utils::limited_deserialize,
102    pubkey::Pubkey,
103    signature::{Keypair, Signature},
104    slot_hashes::SlotHashes,
105    slot_history::SlotHistory,
106    stake::{self, state::Delegation},
107    system_transaction,
108    sysvar::{self},
109    timing::years_as_slots,
110    transaction::{
111        Result, SanitizedTransaction, Transaction, TransactionError, VersionedTransaction,
112    },
113};
114use gemachain_stake_program::stake_state::{self, InflationPointCalculationEvent, PointValue};
115use gemachain_vote_program::{
116    vote_instruction::VoteInstruction,
117    vote_state::{VoteState, VoteStateVersions},
118};
119use std::{
120    borrow::Cow,
121    cell::RefCell,
122    collections::{HashMap, HashSet},
123    convert::{TryFrom, TryInto},
124    fmt, mem,
125    ops::RangeInclusive,
126    path::PathBuf,
127    ptr,
128    rc::Rc,
129    sync::{
130        atomic::{AtomicBool, AtomicU64, Ordering::Relaxed},
131        LockResult, RwLockWriteGuard, {Arc, RwLock, RwLockReadGuard},
132    },
133    time::Duration,
134    time::Instant,
135};
136
137pub const SECONDS_PER_YEAR: f64 = 365.25 * 24.0 * 60.0 * 60.0;
138
139pub const MAX_LEADER_SCHEDULE_STAKES: Epoch = 5;
140
141#[derive(Clone, Debug, Default, PartialEq)]
142pub struct RentDebits(pub Vec<(Pubkey, RewardInfo)>);
143impl RentDebits {
144    pub fn push(&mut self, account: &Pubkey, rent: u64, post_balance: u64) {
145        if rent != 0 {
146            let rent_debit = i64::try_from(rent).ok().and_then(|r| r.checked_neg());
147            if let Some(rent_debit) = rent_debit {
148                let reward_info = RewardInfo {
149                    reward_type: RewardType::Rent,
150                    carats: rent_debit,
151                    post_balance,
152                    commission: None, // Not applicable
153                };
154                self.0.push((*account, reward_info));
155            } else {
156                warn!("out of range rent debit from {}: {}", account, rent);
157            }
158        }
159    }
160}
161
162#[derive(Default, Debug)]
163pub struct ExecuteTimings {
164    pub check_us: u64,
165    pub load_us: u64,
166    pub execute_us: u64,
167    pub store_us: u64,
168    pub total_batches_len: usize,
169    pub num_execute_batches: u64,
170    pub details: ExecuteDetailsTimings,
171}
172impl ExecuteTimings {
173    pub fn accumulate(&mut self, other: &ExecuteTimings) {
174        self.check_us = self.check_us.saturating_add(other.check_us);
175        self.load_us = self.load_us.saturating_add(other.load_us);
176        self.execute_us = self.execute_us.saturating_add(other.execute_us);
177        self.store_us = self.store_us.saturating_add(other.store_us);
178        self.total_batches_len = self
179            .total_batches_len
180            .saturating_add(other.total_batches_len);
181        self.num_execute_batches = self
182            .num_execute_batches
183            .saturating_add(other.num_execute_batches);
184        self.details.accumulate(&other.details);
185    }
186}
187
188type BankStatusCache = StatusCache<Result<()>>;
189#[frozen_abi(digest = "5Br3PNyyX1L7XoS4jYLt5JTeMXowLSsu7v9LhokC8vnq")]
190pub type BankSlotDelta = SlotDelta<Result<()>>;
191type TransactionAccountRefCells = Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>;
192
193// Eager rent collection repeats in cyclic manner.
194// Each cycle is composed of <partition_count> number of tiny pubkey subranges
195// to scan, which is always multiple of the number of slots in epoch.
196type PartitionIndex = u64;
197type PartitionsPerCycle = u64;
198type Partition = (PartitionIndex, PartitionIndex, PartitionsPerCycle);
199type RentCollectionCycleParams = (
200    Epoch,
201    SlotCount,
202    bool,
203    Epoch,
204    EpochCount,
205    PartitionsPerCycle,
206);
207
208type EpochCount = u64;
209
210/// Copy-on-write holder of CachedExecutors
211#[derive(AbiExample, Debug, Default)]
212struct CowCachedExecutors {
213    shared: bool,
214    executors: Arc<RwLock<CachedExecutors>>,
215}
216impl Clone for CowCachedExecutors {
217    fn clone(&self) -> Self {
218        Self {
219            shared: true,
220            executors: self.executors.clone(),
221        }
222    }
223}
224impl CowCachedExecutors {
225    fn clone_with_epoch(&self, epoch: u64) -> Self {
226        let executors_raw = self.read().unwrap();
227        if executors_raw.current_epoch() == epoch {
228            self.clone()
229        } else {
230            Self {
231                shared: false,
232                executors: Arc::new(RwLock::new(executors_raw.clone_with_epoch(epoch))),
233            }
234        }
235    }
236    fn new(executors: Arc<RwLock<CachedExecutors>>) -> Self {
237        Self {
238            shared: true,
239            executors,
240        }
241    }
242    fn read(&self) -> LockResult<RwLockReadGuard<CachedExecutors>> {
243        self.executors.read()
244    }
245    fn write(&mut self) -> LockResult<RwLockWriteGuard<CachedExecutors>> {
246        if self.shared {
247            self.shared = false;
248            let local_cache = (*self.executors.read().unwrap()).clone();
249            self.executors = Arc::new(RwLock::new(local_cache));
250        }
251        self.executors.write()
252    }
253}
254
255const MAX_CACHED_EXECUTORS: usize = 100; // 10 MB assuming programs are around 100k
256#[derive(Debug)]
257struct CachedExecutorsEntry {
258    prev_epoch_count: u64,
259    epoch_count: AtomicU64,
260    executor: Arc<dyn Executor>,
261}
262/// LFU Cache of executors with single-epoch memory of usage counts
263#[derive(Debug)]
264struct CachedExecutors {
265    max: usize,
266    current_epoch: Epoch,
267    executors: HashMap<Pubkey, CachedExecutorsEntry>,
268}
269impl Default for CachedExecutors {
270    fn default() -> Self {
271        Self {
272            max: MAX_CACHED_EXECUTORS,
273            current_epoch: 0,
274            executors: HashMap::new(),
275        }
276    }
277}
278
279#[cfg(RUSTC_WITH_SPECIALIZATION)]
280impl AbiExample for CachedExecutors {
281    fn example() -> Self {
282        // Delegate AbiExample impl to Default before going deep and stuck with
283        // not easily impl-able Arc<dyn Executor> due to rust's coherence issue
284        // This is safe because CachedExecutors isn't serializable by definition.
285        Self::default()
286    }
287}
288
289impl Clone for CachedExecutors {
290    fn clone(&self) -> Self {
291        self.clone_with_epoch(self.current_epoch)
292    }
293}
294impl CachedExecutors {
295    fn current_epoch(&self) -> Epoch {
296        self.current_epoch
297    }
298
299    fn clone_with_epoch(&self, epoch: Epoch) -> Self {
300        let mut executors = HashMap::new();
301        for (key, entry) in self.executors.iter() {
302            // The total_count = prev_epoch_count + epoch_count will be used for LFU eviction.
303            // If the epoch has changed, we store the prev_epoch_count and reset the epoch_count to 0.
304            if epoch > self.current_epoch {
305                executors.insert(
306                    *key,
307                    CachedExecutorsEntry {
308                        prev_epoch_count: entry.epoch_count.load(Relaxed),
309                        epoch_count: AtomicU64::new(0),
310                        executor: entry.executor.clone(),
311                    },
312                );
313            } else {
314                executors.insert(
315                    *key,
316                    CachedExecutorsEntry {
317                        prev_epoch_count: entry.prev_epoch_count,
318                        epoch_count: AtomicU64::new(entry.epoch_count.load(Relaxed)),
319                        executor: entry.executor.clone(),
320                    },
321                );
322            }
323        }
324        Self {
325            max: self.max,
326            current_epoch: epoch,
327            executors,
328        }
329    }
330
331    fn new(max: usize, current_epoch: Epoch) -> Self {
332        Self {
333            max,
334            current_epoch,
335            executors: HashMap::new(),
336        }
337    }
338    fn get(&self, pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
339        self.executors.get(pubkey).map(|entry| {
340            entry.epoch_count.fetch_add(1, Relaxed);
341            entry.executor.clone()
342        })
343    }
344    fn put(&mut self, pubkey: &Pubkey, executor: Arc<dyn Executor>) {
345        if !self.executors.contains_key(pubkey) && self.executors.len() >= self.max {
346            let mut least = u64::MAX;
347            let default_key = Pubkey::default();
348            let mut least_key = &default_key;
349
350            for (key, entry) in self.executors.iter() {
351                let count = entry.prev_epoch_count + entry.epoch_count.load(Relaxed);
352                if count < least {
353                    least = count;
354                    least_key = key;
355                }
356            }
357            let least_key = *least_key;
358            let _ = self.executors.remove(&least_key);
359        }
360        let _ = self.executors.insert(
361            *pubkey,
362            CachedExecutorsEntry {
363                prev_epoch_count: 0,
364                epoch_count: AtomicU64::new(0),
365                executor,
366            },
367        );
368    }
369    fn remove(&mut self, pubkey: &Pubkey) {
370        let _ = self.executors.remove(pubkey);
371    }
372}
373
374pub struct TransactionComputeMeter {
375    remaining: u64,
376}
377impl TransactionComputeMeter {
378    pub fn new(cap: u64) -> Self {
379        Self { remaining: cap }
380    }
381}
382impl ComputeMeter for TransactionComputeMeter {
383    fn consume(&mut self, amount: u64) -> std::result::Result<(), InstructionError> {
384        let exceeded = self.remaining < amount;
385        self.remaining = self.remaining.saturating_sub(amount);
386        if exceeded {
387            return Err(InstructionError::ComputationalBudgetExceeded);
388        }
389        Ok(())
390    }
391    fn get_remaining(&self) -> u64 {
392        self.remaining
393    }
394}
395
396#[derive(Debug)]
397pub struct BankRc {
398    /// where all the Accounts are stored
399    pub accounts: Arc<Accounts>,
400
401    /// Previous checkpoint of this bank
402    pub(crate) parent: RwLock<Option<Arc<Bank>>>,
403
404    /// Current slot
405    pub(crate) slot: Slot,
406
407    pub(crate) bank_id_generator: Arc<AtomicU64>,
408}
409
410#[cfg(RUSTC_WITH_SPECIALIZATION)]
411use gemachain_frozen_abi::abi_example::AbiExample;
412
413#[cfg(RUSTC_WITH_SPECIALIZATION)]
414impl AbiExample for BankRc {
415    fn example() -> Self {
416        BankRc {
417            // Set parent to None to cut the recursion into another Bank
418            parent: RwLock::new(None),
419            // AbiExample for Accounts is specially implemented to contain a storage example
420            accounts: AbiExample::example(),
421            slot: AbiExample::example(),
422            bank_id_generator: Arc::new(AtomicU64::new(0)),
423        }
424    }
425}
426
427impl BankRc {
428    pub(crate) fn new(accounts: Accounts, slot: Slot) -> Self {
429        Self {
430            accounts: Arc::new(accounts),
431            parent: RwLock::new(None),
432            slot,
433            bank_id_generator: Arc::new(AtomicU64::new(0)),
434        }
435    }
436}
437
438#[derive(Default, Debug, AbiExample)]
439pub struct StatusCacheRc {
440    /// where all the Accounts are stored
441    /// A cache of signature statuses
442    pub status_cache: Arc<RwLock<BankStatusCache>>,
443}
444
445impl StatusCacheRc {
446    pub fn slot_deltas(&self, slots: &[Slot]) -> Vec<BankSlotDelta> {
447        let sc = self.status_cache.read().unwrap();
448        sc.slot_deltas(slots)
449    }
450
451    pub fn roots(&self) -> Vec<Slot> {
452        self.status_cache
453            .read()
454            .unwrap()
455            .roots()
456            .iter()
457            .cloned()
458            .sorted()
459            .collect()
460    }
461
462    pub fn append(&self, slot_deltas: &[BankSlotDelta]) {
463        let mut sc = self.status_cache.write().unwrap();
464        sc.append(slot_deltas);
465    }
466}
467
468pub type TransactionCheckResult = (Result<()>, Option<NonceRollbackPartial>);
469pub type TransactionExecutionResult = (Result<()>, Option<NonceRollbackFull>);
470pub struct TransactionResults {
471    pub fee_collection_results: Vec<Result<()>>,
472    pub execution_results: Vec<TransactionExecutionResult>,
473    pub overwritten_vote_accounts: Vec<OverwrittenVoteAccount>,
474    pub rent_debits: Vec<RentDebits>,
475}
476pub struct TransactionSimulationResult {
477    pub result: Result<()>,
478    pub logs: TransactionLogMessages,
479    pub post_simulation_accounts: Vec<(Pubkey, AccountSharedData)>,
480    pub units_consumed: u64,
481}
482pub struct TransactionBalancesSet {
483    pub pre_balances: TransactionBalances,
484    pub post_balances: TransactionBalances,
485}
486pub struct OverwrittenVoteAccount {
487    pub account: VoteAccount,
488    pub transaction_index: usize,
489    pub transaction_result_index: usize,
490}
491
492impl TransactionBalancesSet {
493    pub fn new(pre_balances: TransactionBalances, post_balances: TransactionBalances) -> Self {
494        assert_eq!(pre_balances.len(), post_balances.len());
495        Self {
496            pre_balances,
497            post_balances,
498        }
499    }
500}
501pub type TransactionBalances = Vec<Vec<u64>>;
502
503/// An ordered list of instructions that were invoked during a transaction instruction
504pub type InnerInstructions = Vec<CompiledInstruction>;
505
506/// A list of instructions that were invoked during each instruction of a transaction
507pub type InnerInstructionsList = Vec<InnerInstructions>;
508
509/// A list of log messages emitted during a transaction
510pub type TransactionLogMessages = Vec<String>;
511
512#[derive(Serialize, Deserialize, AbiExample, AbiEnumVisitor, Debug, PartialEq)]
513pub enum TransactionLogCollectorFilter {
514    All,
515    AllWithVotes,
516    None,
517    OnlyMentionedAddresses,
518}
519
520impl Default for TransactionLogCollectorFilter {
521    fn default() -> Self {
522        Self::None
523    }
524}
525
526#[derive(AbiExample, Debug, Default)]
527pub struct TransactionLogCollectorConfig {
528    pub mentioned_addresses: HashSet<Pubkey>,
529    pub filter: TransactionLogCollectorFilter,
530}
531
532#[derive(AbiExample, Clone, Debug)]
533pub struct TransactionLogInfo {
534    pub signature: Signature,
535    pub result: Result<()>,
536    pub is_vote: bool,
537    pub log_messages: TransactionLogMessages,
538}
539
540#[derive(AbiExample, Default, Debug)]
541pub struct TransactionLogCollector {
542    // All the logs collected for from this Bank.  Exact contents depend on the
543    // active `TransactionLogCollectorFilter`
544    pub logs: Vec<TransactionLogInfo>,
545
546    // For each `mentioned_addresses`, maintain a list of indices into `logs` to easily
547    // locate the logs from transactions that included the mentioned addresses.
548    pub mentioned_address_map: HashMap<Pubkey, Vec<usize>>,
549}
550
551pub trait NonceRollbackInfo {
552    fn nonce_address(&self) -> &Pubkey;
553    fn nonce_account(&self) -> &AccountSharedData;
554    fn fee_calculator(&self) -> Option<FeeCalculator>;
555    fn fee_account(&self) -> Option<&AccountSharedData>;
556}
557
558#[derive(Clone, Debug, Default, PartialEq)]
559pub struct NonceRollbackPartial {
560    nonce_address: Pubkey,
561    nonce_account: AccountSharedData,
562}
563
564impl NonceRollbackPartial {
565    pub fn new(nonce_address: Pubkey, nonce_account: AccountSharedData) -> Self {
566        Self {
567            nonce_address,
568            nonce_account,
569        }
570    }
571}
572
573impl NonceRollbackInfo for NonceRollbackPartial {
574    fn nonce_address(&self) -> &Pubkey {
575        &self.nonce_address
576    }
577    fn nonce_account(&self) -> &AccountSharedData {
578        &self.nonce_account
579    }
580    fn fee_calculator(&self) -> Option<FeeCalculator> {
581        nonce_account::fee_calculator_of(&self.nonce_account)
582    }
583    fn fee_account(&self) -> Option<&AccountSharedData> {
584        None
585    }
586}
587
588#[derive(Clone, Debug, Default, PartialEq)]
589pub struct NonceRollbackFull {
590    nonce_address: Pubkey,
591    nonce_account: AccountSharedData,
592    fee_account: Option<AccountSharedData>,
593}
594
595impl NonceRollbackFull {
596    #[cfg(test)]
597    pub fn new(
598        nonce_address: Pubkey,
599        nonce_account: AccountSharedData,
600        fee_account: Option<AccountSharedData>,
601    ) -> Self {
602        Self {
603            nonce_address,
604            nonce_account,
605            fee_account,
606        }
607    }
608    pub fn from_partial(
609        partial: NonceRollbackPartial,
610        message: &SanitizedMessage,
611        accounts: &[(Pubkey, AccountSharedData)],
612    ) -> Result<Self> {
613        let NonceRollbackPartial {
614            nonce_address,
615            nonce_account,
616        } = partial;
617        let fee_payer = (0..message.account_keys_len()).find_map(|i| {
618            if let Some((k, a)) = &accounts.get(i) {
619                if message.is_non_loader_key(i) {
620                    return Some((k, a));
621                }
622            }
623            None
624        });
625        if let Some((fee_pubkey, fee_account)) = fee_payer {
626            if *fee_pubkey == nonce_address {
627                Ok(Self {
628                    nonce_address,
629                    nonce_account: fee_account.clone(),
630                    fee_account: None,
631                })
632            } else {
633                Ok(Self {
634                    nonce_address,
635                    nonce_account,
636                    fee_account: Some(fee_account.clone()),
637                })
638            }
639        } else {
640            Err(TransactionError::AccountNotFound)
641        }
642    }
643}
644
645impl NonceRollbackInfo for NonceRollbackFull {
646    fn nonce_address(&self) -> &Pubkey {
647        &self.nonce_address
648    }
649    fn nonce_account(&self) -> &AccountSharedData {
650        &self.nonce_account
651    }
652    fn fee_calculator(&self) -> Option<FeeCalculator> {
653        nonce_account::fee_calculator_of(&self.nonce_account)
654    }
655    fn fee_account(&self) -> Option<&AccountSharedData> {
656        self.fee_account.as_ref()
657    }
658}
659
660// Bank's common fields shared by all supported snapshot versions for deserialization.
661// Sync fields with BankFieldsToSerialize! This is paired with it.
662// All members are made public to remain Bank's members private and to make versioned deserializer workable on this
663#[derive(Clone, Debug, Default)]
664pub(crate) struct BankFieldsToDeserialize {
665    pub(crate) blockhash_queue: BlockhashQueue,
666    pub(crate) ancestors: AncestorsForSerialization,
667    pub(crate) hash: Hash,
668    pub(crate) parent_hash: Hash,
669    pub(crate) parent_slot: Slot,
670    pub(crate) hard_forks: HardForks,
671    pub(crate) transaction_count: u64,
672    pub(crate) tick_height: u64,
673    pub(crate) signature_count: u64,
674    pub(crate) capitalization: u64,
675    pub(crate) max_tick_height: u64,
676    pub(crate) hashes_per_tick: Option<u64>,
677    pub(crate) ticks_per_slot: u64,
678    pub(crate) ns_per_slot: u128,
679    pub(crate) genesis_creation_time: UnixTimestamp,
680    pub(crate) slots_per_year: f64,
681    pub(crate) unused: u64,
682    pub(crate) slot: Slot,
683    pub(crate) epoch: Epoch,
684    pub(crate) block_height: u64,
685    pub(crate) collector_id: Pubkey,
686    pub(crate) collector_fees: u64,
687    pub(crate) fee_calculator: FeeCalculator,
688    pub(crate) fee_rate_governor: FeeRateGovernor,
689    pub(crate) collected_rent: u64,
690    pub(crate) rent_collector: RentCollector,
691    pub(crate) epoch_schedule: EpochSchedule,
692    pub(crate) inflation: Inflation,
693    pub(crate) stakes: Stakes,
694    pub(crate) epoch_stakes: HashMap<Epoch, EpochStakes>,
695    pub(crate) is_delta: bool,
696}
697
698// Bank's common fields shared by all supported snapshot versions for serialization.
699// This is separated from BankFieldsToDeserialize to avoid cloning by using refs.
700// So, sync fields with BankFieldsToDeserialize!
701// all members are made public to keep Bank private and to make versioned serializer workable on this
702#[derive(Debug)]
703pub(crate) struct BankFieldsToSerialize<'a> {
704    pub(crate) blockhash_queue: &'a RwLock<BlockhashQueue>,
705    pub(crate) ancestors: &'a AncestorsForSerialization,
706    pub(crate) hash: Hash,
707    pub(crate) parent_hash: Hash,
708    pub(crate) parent_slot: Slot,
709    pub(crate) hard_forks: &'a RwLock<HardForks>,
710    pub(crate) transaction_count: u64,
711    pub(crate) tick_height: u64,
712    pub(crate) signature_count: u64,
713    pub(crate) capitalization: u64,
714    pub(crate) max_tick_height: u64,
715    pub(crate) hashes_per_tick: Option<u64>,
716    pub(crate) ticks_per_slot: u64,
717    pub(crate) ns_per_slot: u128,
718    pub(crate) genesis_creation_time: UnixTimestamp,
719    pub(crate) slots_per_year: f64,
720    pub(crate) unused: u64,
721    pub(crate) slot: Slot,
722    pub(crate) epoch: Epoch,
723    pub(crate) block_height: u64,
724    pub(crate) collector_id: Pubkey,
725    pub(crate) collector_fees: u64,
726    pub(crate) fee_calculator: FeeCalculator,
727    pub(crate) fee_rate_governor: FeeRateGovernor,
728    pub(crate) collected_rent: u64,
729    pub(crate) rent_collector: RentCollector,
730    pub(crate) epoch_schedule: EpochSchedule,
731    pub(crate) inflation: Inflation,
732    pub(crate) stakes: &'a RwLock<Stakes>,
733    pub(crate) epoch_stakes: &'a HashMap<Epoch, EpochStakes>,
734    pub(crate) is_delta: bool,
735}
736
737// Can't derive PartialEq because RwLock doesn't implement PartialEq
738impl PartialEq for Bank {
739    fn eq(&self, other: &Self) -> bool {
740        if ptr::eq(self, other) {
741            return true;
742        }
743        *self.blockhash_queue.read().unwrap() == *other.blockhash_queue.read().unwrap()
744            && self.ancestors == other.ancestors
745            && *self.hash.read().unwrap() == *other.hash.read().unwrap()
746            && self.parent_hash == other.parent_hash
747            && self.parent_slot == other.parent_slot
748            && *self.hard_forks.read().unwrap() == *other.hard_forks.read().unwrap()
749            && self.transaction_count.load(Relaxed) == other.transaction_count.load(Relaxed)
750            && self.tick_height.load(Relaxed) == other.tick_height.load(Relaxed)
751            && self.signature_count.load(Relaxed) == other.signature_count.load(Relaxed)
752            && self.capitalization.load(Relaxed) == other.capitalization.load(Relaxed)
753            && self.max_tick_height == other.max_tick_height
754            && self.hashes_per_tick == other.hashes_per_tick
755            && self.ticks_per_slot == other.ticks_per_slot
756            && self.ns_per_slot == other.ns_per_slot
757            && self.genesis_creation_time == other.genesis_creation_time
758            && self.slots_per_year == other.slots_per_year
759            && self.unused == other.unused
760            && self.slot == other.slot
761            && self.epoch == other.epoch
762            && self.block_height == other.block_height
763            && self.collector_id == other.collector_id
764            && self.collector_fees.load(Relaxed) == other.collector_fees.load(Relaxed)
765            && self.fee_calculator == other.fee_calculator
766            && self.fee_rate_governor == other.fee_rate_governor
767            && self.collected_rent.load(Relaxed) == other.collected_rent.load(Relaxed)
768            && self.rent_collector == other.rent_collector
769            && self.epoch_schedule == other.epoch_schedule
770            && *self.inflation.read().unwrap() == *other.inflation.read().unwrap()
771            && *self.stakes.read().unwrap() == *other.stakes.read().unwrap()
772            && self.epoch_stakes == other.epoch_stakes
773            && self.is_delta.load(Relaxed) == other.is_delta.load(Relaxed)
774    }
775}
776
777#[derive(Debug, PartialEq, Serialize, Deserialize, AbiExample, AbiEnumVisitor, Clone, Copy)]
778pub enum RewardType {
779    Fee,
780    Rent,
781    Staking,
782    Voting,
783}
784
785#[derive(Debug)]
786pub enum RewardCalculationEvent<'a, 'b> {
787    Staking(&'a Pubkey, &'b InflationPointCalculationEvent),
788}
789
790fn null_tracer() -> Option<impl FnMut(&RewardCalculationEvent)> {
791    None::<fn(&RewardCalculationEvent)>
792}
793
794impl fmt::Display for RewardType {
795    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
796        write!(
797            f,
798            "{}",
799            match self {
800                RewardType::Fee => "fee",
801                RewardType::Rent => "rent",
802                RewardType::Staking => "staking",
803                RewardType::Voting => "voting",
804            }
805        )
806    }
807}
808
809pub trait DropCallback: fmt::Debug {
810    fn callback(&self, b: &Bank);
811    fn clone_box(&self) -> Box<dyn DropCallback + Send + Sync>;
812}
813
814#[derive(Debug, PartialEq, Serialize, Deserialize, AbiExample, Clone, Copy)]
815pub struct RewardInfo {
816    pub reward_type: RewardType,
817    pub carats: i64,          // Reward amount
818    pub post_balance: u64,      // Account balance in carats after `carats` was applied
819    pub commission: Option<u8>, // Vote account commission when the reward was credited, only present for voting and staking rewards
820}
821
822#[derive(Debug, Default)]
823pub struct OptionalDropCallback(Option<Box<dyn DropCallback + Send + Sync>>);
824
825#[cfg(RUSTC_WITH_SPECIALIZATION)]
826impl AbiExample for OptionalDropCallback {
827    fn example() -> Self {
828        Self(None)
829    }
830}
831
832/// Manager for the state of all accounts and programs after processing its entries.
833/// AbiExample is needed even without Serialize/Deserialize; actual (de-)serialization
834/// are implemented elsewhere for versioning
835#[derive(AbiExample, Debug)]
836pub struct Bank {
837    /// References to accounts, parent and signature status
838    pub rc: BankRc,
839
840    pub src: StatusCacheRc,
841
842    /// FIFO queue of `recent_blockhash` items
843    blockhash_queue: RwLock<BlockhashQueue>,
844
845    /// The set of parents including this bank
846    pub ancestors: Ancestors,
847
848    /// Hash of this Bank's state. Only meaningful after freezing.
849    hash: RwLock<Hash>,
850
851    /// Hash of this Bank's parent's state
852    parent_hash: Hash,
853
854    /// parent's slot
855    parent_slot: Slot,
856
857    /// slots to hard fork at
858    hard_forks: Arc<RwLock<HardForks>>,
859
860    /// The number of transactions processed without error
861    transaction_count: AtomicU64,
862
863    /// The number of transaction errors in this slot
864    transaction_error_count: AtomicU64,
865
866    /// The number of transaction entries in this slot
867    transaction_entries_count: AtomicU64,
868
869    /// The max number of transaction in an entry in this slot
870    transactions_per_entry_max: AtomicU64,
871
872    /// Bank tick height
873    tick_height: AtomicU64,
874
875    /// The number of signatures from valid transactions in this slot
876    signature_count: AtomicU64,
877
878    /// Total capitalization, used to calculate inflation
879    capitalization: AtomicU64,
880
881    // Bank max_tick_height
882    max_tick_height: u64,
883
884    /// The number of hashes in each tick. None value means hashing is disabled.
885    hashes_per_tick: Option<u64>,
886
887    /// The number of ticks in each slot.
888    ticks_per_slot: u64,
889
890    /// length of a slot in ns
891    pub ns_per_slot: u128,
892
893    /// genesis time, used for computed clock
894    genesis_creation_time: UnixTimestamp,
895
896    /// The number of slots per year, used for inflation
897    slots_per_year: f64,
898
899    /// Unused
900    unused: u64,
901
902    /// Bank slot (i.e. block)
903    slot: Slot,
904
905    bank_id: BankId,
906
907    /// Bank epoch
908    epoch: Epoch,
909
910    /// Bank block_height
911    block_height: u64,
912
913    /// The pubkey to send transactions fees to.
914    collector_id: Pubkey,
915
916    /// Fees that have been collected
917    collector_fees: AtomicU64,
918
919    /// Latest transaction fees for transactions processed by this bank
920    fee_calculator: FeeCalculator,
921
922    /// Track cluster signature throughput and adjust fee rate
923    fee_rate_governor: FeeRateGovernor,
924
925    /// Rent that has been collected
926    collected_rent: AtomicU64,
927
928    /// latest rent collector, knows the epoch
929    rent_collector: RentCollector,
930
931    /// initialized from genesis
932    epoch_schedule: EpochSchedule,
933
934    /// inflation specs
935    inflation: Arc<RwLock<Inflation>>,
936
937    /// cache of vote_account and stake_account state for this fork
938    stakes: RwLock<Stakes>,
939
940    /// staked nodes on epoch boundaries, saved off when a bank.slot() is at
941    ///   a leader schedule calculation boundary
942    epoch_stakes: HashMap<Epoch, EpochStakes>,
943
944    /// A boolean reflecting whether any entries were recorded into the PoH
945    /// stream for the slot == self.slot
946    is_delta: AtomicBool,
947
948    /// The Message processor
949    message_processor: MessageProcessor,
950
951    compute_budget: Option<ComputeBudget>,
952
953    /// Builtin programs activated dynamically by feature
954    #[allow(clippy::rc_buffer)]
955    feature_builtins: Arc<Vec<(Builtin, Pubkey, ActivationType)>>,
956
957    /// Last time when the cluster info vote listener has synced with this bank
958    pub last_vote_sync: AtomicU64,
959
960    /// Protocol-level rewards that were distributed by this bank
961    pub rewards: RwLock<Vec<(Pubkey, RewardInfo)>>,
962
963    pub cluster_type: Option<ClusterType>,
964
965    pub lazy_rent_collection: AtomicBool,
966
967    // this is temporary field only to remove rewards_pool entirely
968    pub rewards_pool_pubkeys: Arc<HashSet<Pubkey>>,
969
970    /// Cached executors
971    cached_executors: RwLock<CowCachedExecutors>,
972
973    transaction_debug_keys: Option<Arc<HashSet<Pubkey>>>,
974
975    // Global configuration for how transaction logs should be collected across all banks
976    pub transaction_log_collector_config: Arc<RwLock<TransactionLogCollectorConfig>>,
977
978    // Logs from transactions that this Bank executed collected according to the criteria in
979    // `transaction_log_collector_config`
980    pub transaction_log_collector: Arc<RwLock<TransactionLogCollector>>,
981
982    pub feature_set: Arc<FeatureSet>,
983
984    pub drop_callback: RwLock<OptionalDropCallback>,
985
986    pub freeze_started: AtomicBool,
987
988    vote_only_bank: bool,
989}
990
991impl Default for BlockhashQueue {
992    fn default() -> Self {
993        Self::new(MAX_RECENT_BLOCKHASHES)
994    }
995}
996
997impl Bank {
998    pub fn default_for_tests() -> Self {
999        Self::default_with_accounts(Accounts::default_for_tests())
1000    }
1001
1002    pub fn new_for_benches(genesis_config: &GenesisConfig) -> Self {
1003        // this will diverge
1004        Self::new_for_tests(genesis_config)
1005    }
1006
1007    pub fn new_for_tests(genesis_config: &GenesisConfig) -> Self {
1008        // this will diverge
1009        Self::new_with_paths_for_tests(
1010            genesis_config,
1011            Vec::new(),
1012            &[],
1013            None,
1014            None,
1015            AccountSecondaryIndexes::default(),
1016            false,
1017            AccountShrinkThreshold::default(),
1018            false,
1019        )
1020    }
1021
1022    pub fn new_no_wallclock_throttle_for_tests(genesis_config: &GenesisConfig) -> Self {
1023        let mut bank = Self::new_with_paths_for_tests(
1024            genesis_config,
1025            Vec::new(),
1026            &[],
1027            None,
1028            None,
1029            AccountSecondaryIndexes::default(),
1030            false,
1031            AccountShrinkThreshold::default(),
1032            false,
1033        );
1034
1035        bank.ns_per_slot = std::u128::MAX;
1036        bank
1037    }
1038
1039    #[cfg(test)]
1040    pub(crate) fn new_with_config(
1041        genesis_config: &GenesisConfig,
1042        account_indexes: AccountSecondaryIndexes,
1043        accounts_db_caching_enabled: bool,
1044        shrink_ratio: AccountShrinkThreshold,
1045    ) -> Self {
1046        Self::new_with_paths_for_tests(
1047            genesis_config,
1048            Vec::new(),
1049            &[],
1050            None,
1051            None,
1052            account_indexes,
1053            accounts_db_caching_enabled,
1054            shrink_ratio,
1055            false,
1056        )
1057    }
1058
1059    fn default_with_accounts(accounts: Accounts) -> Self {
1060        Self {
1061            rc: BankRc::new(accounts, Slot::default()),
1062            src: StatusCacheRc::default(),
1063            blockhash_queue: RwLock::<BlockhashQueue>::default(),
1064            ancestors: Ancestors::default(),
1065            hash: RwLock::<Hash>::default(),
1066            parent_hash: Hash::default(),
1067            parent_slot: Slot::default(),
1068            hard_forks: Arc::<RwLock<HardForks>>::default(),
1069            transaction_count: AtomicU64::default(),
1070            transaction_error_count: AtomicU64::default(),
1071            transaction_entries_count: AtomicU64::default(),
1072            transactions_per_entry_max: AtomicU64::default(),
1073            tick_height: AtomicU64::default(),
1074            signature_count: AtomicU64::default(),
1075            capitalization: AtomicU64::default(),
1076            max_tick_height: u64::default(),
1077            hashes_per_tick: Option::<u64>::default(),
1078            ticks_per_slot: u64::default(),
1079            ns_per_slot: u128::default(),
1080            genesis_creation_time: UnixTimestamp::default(),
1081            slots_per_year: f64::default(),
1082            unused: u64::default(),
1083            slot: Slot::default(),
1084            bank_id: BankId::default(),
1085            epoch: Epoch::default(),
1086            block_height: u64::default(),
1087            collector_id: Pubkey::default(),
1088            collector_fees: AtomicU64::default(),
1089            fee_calculator: FeeCalculator::default(),
1090            fee_rate_governor: FeeRateGovernor::default(),
1091            collected_rent: AtomicU64::default(),
1092            rent_collector: RentCollector::default(),
1093            epoch_schedule: EpochSchedule::default(),
1094            inflation: Arc::<RwLock<Inflation>>::default(),
1095            stakes: RwLock::<Stakes>::default(),
1096            epoch_stakes: HashMap::<Epoch, EpochStakes>::default(),
1097            is_delta: AtomicBool::default(),
1098            message_processor: MessageProcessor::default(),
1099            compute_budget: Option::<ComputeBudget>::default(),
1100            feature_builtins: Arc::<Vec<(Builtin, Pubkey, ActivationType)>>::default(),
1101            last_vote_sync: AtomicU64::default(),
1102            rewards: RwLock::<Vec<(Pubkey, RewardInfo)>>::default(),
1103            cluster_type: Option::<ClusterType>::default(),
1104            lazy_rent_collection: AtomicBool::default(),
1105            rewards_pool_pubkeys: Arc::<HashSet<Pubkey>>::default(),
1106            cached_executors: RwLock::<CowCachedExecutors>::default(),
1107            transaction_debug_keys: Option::<Arc<HashSet<Pubkey>>>::default(),
1108            transaction_log_collector_config: Arc::<RwLock<TransactionLogCollectorConfig>>::default(
1109            ),
1110            transaction_log_collector: Arc::<RwLock<TransactionLogCollector>>::default(),
1111            feature_set: Arc::<FeatureSet>::default(),
1112            drop_callback: RwLock::<OptionalDropCallback>::default(),
1113            freeze_started: AtomicBool::default(),
1114            vote_only_bank: false,
1115        }
1116    }
1117
1118    pub fn new_with_paths_for_tests(
1119        genesis_config: &GenesisConfig,
1120        paths: Vec<PathBuf>,
1121        frozen_account_pubkeys: &[Pubkey],
1122        debug_keys: Option<Arc<HashSet<Pubkey>>>,
1123        additional_builtins: Option<&Builtins>,
1124        account_indexes: AccountSecondaryIndexes,
1125        accounts_db_caching_enabled: bool,
1126        shrink_ratio: AccountShrinkThreshold,
1127        debug_do_not_add_builtins: bool,
1128    ) -> Self {
1129        Self::new_with_paths(
1130            genesis_config,
1131            paths,
1132            frozen_account_pubkeys,
1133            debug_keys,
1134            additional_builtins,
1135            account_indexes,
1136            accounts_db_caching_enabled,
1137            shrink_ratio,
1138            debug_do_not_add_builtins,
1139            Some(ACCOUNTS_DB_CONFIG_FOR_TESTING),
1140        )
1141    }
1142
1143    pub fn new_with_paths_for_benches(
1144        genesis_config: &GenesisConfig,
1145        paths: Vec<PathBuf>,
1146        frozen_account_pubkeys: &[Pubkey],
1147        debug_keys: Option<Arc<HashSet<Pubkey>>>,
1148        additional_builtins: Option<&Builtins>,
1149        account_indexes: AccountSecondaryIndexes,
1150        accounts_db_caching_enabled: bool,
1151        shrink_ratio: AccountShrinkThreshold,
1152        debug_do_not_add_builtins: bool,
1153    ) -> Self {
1154        Self::new_with_paths(
1155            genesis_config,
1156            paths,
1157            frozen_account_pubkeys,
1158            debug_keys,
1159            additional_builtins,
1160            account_indexes,
1161            accounts_db_caching_enabled,
1162            shrink_ratio,
1163            debug_do_not_add_builtins,
1164            Some(ACCOUNTS_DB_CONFIG_FOR_BENCHMARKS),
1165        )
1166    }
1167
1168    #[allow(clippy::too_many_arguments)]
1169    pub fn new_with_paths(
1170        genesis_config: &GenesisConfig,
1171        paths: Vec<PathBuf>,
1172        frozen_account_pubkeys: &[Pubkey],
1173        debug_keys: Option<Arc<HashSet<Pubkey>>>,
1174        additional_builtins: Option<&Builtins>,
1175        account_indexes: AccountSecondaryIndexes,
1176        accounts_db_caching_enabled: bool,
1177        shrink_ratio: AccountShrinkThreshold,
1178        debug_do_not_add_builtins: bool,
1179        accounts_db_config: Option<AccountsDbConfig>,
1180    ) -> Self {
1181        let accounts = Accounts::new_with_config(
1182            paths,
1183            &genesis_config.cluster_type,
1184            account_indexes,
1185            accounts_db_caching_enabled,
1186            shrink_ratio,
1187            accounts_db_config,
1188        );
1189        let mut bank = Self::default_with_accounts(accounts);
1190        bank.ancestors = Ancestors::from(vec![bank.slot()]);
1191        bank.transaction_debug_keys = debug_keys;
1192        bank.cluster_type = Some(genesis_config.cluster_type);
1193
1194        bank.process_genesis_config(genesis_config);
1195        bank.finish_init(
1196            genesis_config,
1197            additional_builtins,
1198            debug_do_not_add_builtins,
1199        );
1200
1201        // Freeze accounts after process_genesis_config creates the initial append vecs
1202        Arc::get_mut(&mut Arc::get_mut(&mut bank.rc.accounts).unwrap().accounts_db)
1203            .unwrap()
1204            .freeze_accounts(&bank.ancestors, frozen_account_pubkeys);
1205
1206        // genesis needs stakes for all epochs up to the epoch implied by
1207        //  slot = 0 and genesis configuration
1208        {
1209            let stakes = bank.stakes.read().unwrap();
1210            for epoch in 0..=bank.get_leader_schedule_epoch(bank.slot) {
1211                bank.epoch_stakes
1212                    .insert(epoch, EpochStakes::new(&stakes, epoch));
1213            }
1214            bank.update_stake_history(None);
1215        }
1216        bank.update_clock(None);
1217        bank.update_rent();
1218        bank.update_epoch_schedule();
1219        bank.update_recent_blockhashes();
1220        bank
1221    }
1222
1223    /// Create a new bank that points to an immutable checkpoint of another bank.
1224    pub fn new_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: Slot) -> Self {
1225        Self::_new_from_parent(parent, collector_id, slot, &mut null_tracer(), false)
1226    }
1227
1228    pub fn new_from_parent_with_vote_only(
1229        parent: &Arc<Bank>,
1230        collector_id: &Pubkey,
1231        slot: Slot,
1232        vote_only_bank: bool,
1233    ) -> Self {
1234        Self::_new_from_parent(
1235            parent,
1236            collector_id,
1237            slot,
1238            &mut null_tracer(),
1239            vote_only_bank,
1240        )
1241    }
1242
1243    pub fn new_from_parent_with_tracer(
1244        parent: &Arc<Bank>,
1245        collector_id: &Pubkey,
1246        slot: Slot,
1247        reward_calc_tracer: impl FnMut(&RewardCalculationEvent),
1248    ) -> Self {
1249        Self::_new_from_parent(
1250            parent,
1251            collector_id,
1252            slot,
1253            &mut Some(reward_calc_tracer),
1254            false,
1255        )
1256    }
1257
1258    fn _new_from_parent(
1259        parent: &Arc<Bank>,
1260        collector_id: &Pubkey,
1261        slot: Slot,
1262        reward_calc_tracer: &mut Option<impl FnMut(&RewardCalculationEvent)>,
1263        vote_only_bank: bool,
1264    ) -> Self {
1265        parent.freeze();
1266        assert_ne!(slot, parent.slot());
1267
1268        let epoch_schedule = parent.epoch_schedule;
1269        let epoch = epoch_schedule.get_epoch(slot);
1270
1271        let rc = BankRc {
1272            accounts: Arc::new(Accounts::new_from_parent(
1273                &parent.rc.accounts,
1274                slot,
1275                parent.slot(),
1276            )),
1277            parent: RwLock::new(Some(parent.clone())),
1278            slot,
1279            bank_id_generator: parent.rc.bank_id_generator.clone(),
1280        };
1281        let src = StatusCacheRc {
1282            status_cache: parent.src.status_cache.clone(),
1283        };
1284
1285        let fee_rate_governor =
1286            FeeRateGovernor::new_derived(&parent.fee_rate_governor, parent.signature_count());
1287
1288        let bank_id = rc.bank_id_generator.fetch_add(1, Relaxed) + 1;
1289        let mut new = Bank {
1290            rc,
1291            src,
1292            slot,
1293            bank_id,
1294            epoch,
1295            blockhash_queue: RwLock::new(parent.blockhash_queue.read().unwrap().clone()),
1296
1297            // TODO: clean this up, so much special-case copying...
1298            hashes_per_tick: parent.hashes_per_tick,
1299            ticks_per_slot: parent.ticks_per_slot,
1300            ns_per_slot: parent.ns_per_slot,
1301            genesis_creation_time: parent.genesis_creation_time,
1302            unused: parent.unused,
1303            slots_per_year: parent.slots_per_year,
1304            epoch_schedule,
1305            collected_rent: AtomicU64::new(0),
1306            rent_collector: parent.rent_collector.clone_with_epoch(epoch),
1307            max_tick_height: (slot + 1) * parent.ticks_per_slot,
1308            block_height: parent.block_height + 1,
1309            fee_calculator: fee_rate_governor.create_fee_calculator(),
1310            fee_rate_governor,
1311            capitalization: AtomicU64::new(parent.capitalization()),
1312            vote_only_bank,
1313            inflation: parent.inflation.clone(),
1314            transaction_count: AtomicU64::new(parent.transaction_count()),
1315            transaction_error_count: AtomicU64::new(0),
1316            transaction_entries_count: AtomicU64::new(0),
1317            transactions_per_entry_max: AtomicU64::new(0),
1318            // we will .clone_with_epoch() this soon after stake data update; so just .clone() for now
1319            stakes: RwLock::new(parent.stakes.read().unwrap().clone()),
1320            epoch_stakes: parent.epoch_stakes.clone(),
1321            parent_hash: parent.hash(),
1322            parent_slot: parent.slot(),
1323            collector_id: *collector_id,
1324            collector_fees: AtomicU64::new(0),
1325            ancestors: Ancestors::default(),
1326            hash: RwLock::new(Hash::default()),
1327            is_delta: AtomicBool::new(false),
1328            tick_height: AtomicU64::new(parent.tick_height.load(Relaxed)),
1329            signature_count: AtomicU64::new(0),
1330            message_processor: parent.message_processor.clone(),
1331            compute_budget: parent.compute_budget,
1332            feature_builtins: parent.feature_builtins.clone(),
1333            hard_forks: parent.hard_forks.clone(),
1334            last_vote_sync: AtomicU64::new(parent.last_vote_sync.load(Relaxed)),
1335            rewards: RwLock::new(vec![]),
1336            cluster_type: parent.cluster_type,
1337            lazy_rent_collection: AtomicBool::new(parent.lazy_rent_collection.load(Relaxed)),
1338            rewards_pool_pubkeys: parent.rewards_pool_pubkeys.clone(),
1339            cached_executors: RwLock::new(
1340                (*parent.cached_executors.read().unwrap()).clone_with_epoch(epoch),
1341            ),
1342            transaction_debug_keys: parent.transaction_debug_keys.clone(),
1343            transaction_log_collector_config: parent.transaction_log_collector_config.clone(),
1344            transaction_log_collector: Arc::new(RwLock::new(TransactionLogCollector::default())),
1345            feature_set: parent.feature_set.clone(),
1346            drop_callback: RwLock::new(OptionalDropCallback(
1347                parent
1348                    .drop_callback
1349                    .read()
1350                    .unwrap()
1351                    .0
1352                    .as_ref()
1353                    .map(|drop_callback| drop_callback.clone_box()),
1354            )),
1355            freeze_started: AtomicBool::new(false),
1356        };
1357
1358        datapoint_info!(
1359            "bank-new_from_parent-heights",
1360            ("slot_height", slot, i64),
1361            ("block_height", new.block_height, i64),
1362            ("parent_slot_height", parent.slot(), i64),
1363        );
1364
1365        let mut ancestors = Vec::with_capacity(1 + new.parents().len());
1366        ancestors.push(new.slot());
1367        new.parents().iter().for_each(|p| {
1368            ancestors.push(p.slot());
1369        });
1370        new.ancestors = Ancestors::from(ancestors);
1371
1372        // Following code may touch AccountsDb, requiring proper ancestors
1373        let parent_epoch = parent.epoch();
1374        if parent_epoch < new.epoch() {
1375            new.apply_feature_activations(false, false);
1376        }
1377
1378        let cloned = new.stakes.read().unwrap().clone_with_epoch(epoch);
1379        *new.stakes.write().unwrap() = cloned;
1380
1381        let leader_schedule_epoch = epoch_schedule.get_leader_schedule_epoch(slot);
1382        new.update_epoch_stakes(leader_schedule_epoch);
1383        new.update_slot_hashes();
1384        new.update_rewards(parent_epoch, reward_calc_tracer);
1385        new.update_stake_history(Some(parent_epoch));
1386        new.update_clock(Some(parent_epoch));
1387        new.update_fees();
1388        new
1389    }
1390
1391    /// Returns all ancestors excluding self.slot.
1392    pub(crate) fn proper_ancestors(&self) -> impl Iterator<Item = Slot> + '_ {
1393        self.ancestors
1394            .keys()
1395            .into_iter()
1396            .filter(move |slot| *slot != self.slot)
1397    }
1398
1399    pub fn set_callback(&self, callback: Option<Box<dyn DropCallback + Send + Sync>>) {
1400        *self.drop_callback.write().unwrap() = OptionalDropCallback(callback);
1401    }
1402
1403    pub fn vote_only_bank(&self) -> bool {
1404        self.vote_only_bank
1405    }
1406
1407    /// Like `new_from_parent` but additionally:
1408    /// * Doesn't assume that the parent is anywhere near `slot`, parent could be millions of slots
1409    /// in the past
1410    /// * Adjusts the new bank's tick height to avoid having to run PoH for millions of slots
1411    /// * Freezes the new bank, assuming that the user will `Bank::new_from_parent` from this bank
1412    pub fn warp_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: Slot) -> Self {
1413        let parent_timestamp = parent.clock().unix_timestamp;
1414        let mut new = Bank::new_from_parent(parent, collector_id, slot);
1415        new.apply_feature_activations(true, false);
1416        new.update_epoch_stakes(new.epoch_schedule().get_epoch(slot));
1417        new.tick_height.store(new.max_tick_height(), Relaxed);
1418
1419        let mut clock = new.clock();
1420        clock.epoch_start_timestamp = parent_timestamp;
1421        clock.unix_timestamp = parent_timestamp;
1422        new.update_sysvar_account(&sysvar::clock::id(), |account| {
1423            create_account(
1424                &clock,
1425                new.inherit_specially_retained_account_fields(account),
1426            )
1427        });
1428
1429        new.freeze();
1430        new
1431    }
1432
1433    /// Create a bank from explicit arguments and deserialized fields from snapshot
1434    #[allow(clippy::float_cmp)]
1435    pub(crate) fn new_from_fields(
1436        bank_rc: BankRc,
1437        genesis_config: &GenesisConfig,
1438        fields: BankFieldsToDeserialize,
1439        debug_keys: Option<Arc<HashSet<Pubkey>>>,
1440        additional_builtins: Option<&Builtins>,
1441        debug_do_not_add_builtins: bool,
1442    ) -> Self {
1443        fn new<T: Default>() -> T {
1444            T::default()
1445        }
1446        let mut bank = Self {
1447            rc: bank_rc,
1448            src: new(),
1449            blockhash_queue: RwLock::new(fields.blockhash_queue),
1450            ancestors: Ancestors::from(&fields.ancestors),
1451            hash: RwLock::new(fields.hash),
1452            parent_hash: fields.parent_hash,
1453            parent_slot: fields.parent_slot,
1454            hard_forks: Arc::new(RwLock::new(fields.hard_forks)),
1455            transaction_count: AtomicU64::new(fields.transaction_count),
1456            transaction_error_count: new(),
1457            transaction_entries_count: new(),
1458            transactions_per_entry_max: new(),
1459            tick_height: AtomicU64::new(fields.tick_height),
1460            signature_count: AtomicU64::new(fields.signature_count),
1461            capitalization: AtomicU64::new(fields.capitalization),
1462            max_tick_height: fields.max_tick_height,
1463            hashes_per_tick: fields.hashes_per_tick,
1464            ticks_per_slot: fields.ticks_per_slot,
1465            ns_per_slot: fields.ns_per_slot,
1466            genesis_creation_time: fields.genesis_creation_time,
1467            slots_per_year: fields.slots_per_year,
1468            unused: genesis_config.unused,
1469            slot: fields.slot,
1470            bank_id: 0,
1471            epoch: fields.epoch,
1472            block_height: fields.block_height,
1473            collector_id: fields.collector_id,
1474            collector_fees: AtomicU64::new(fields.collector_fees),
1475            fee_calculator: fields.fee_calculator,
1476            fee_rate_governor: fields.fee_rate_governor,
1477            collected_rent: AtomicU64::new(fields.collected_rent),
1478            // clone()-ing is needed to consider a gated behavior in rent_collector
1479            rent_collector: fields.rent_collector.clone_with_epoch(fields.epoch),
1480            epoch_schedule: fields.epoch_schedule,
1481            inflation: Arc::new(RwLock::new(fields.inflation)),
1482            stakes: RwLock::new(fields.stakes),
1483            epoch_stakes: fields.epoch_stakes,
1484            is_delta: AtomicBool::new(fields.is_delta),
1485            message_processor: new(),
1486            compute_budget: None,
1487            feature_builtins: new(),
1488            last_vote_sync: new(),
1489            rewards: new(),
1490            cluster_type: Some(genesis_config.cluster_type),
1491            lazy_rent_collection: new(),
1492            rewards_pool_pubkeys: new(),
1493            cached_executors: RwLock::new(CowCachedExecutors::new(Arc::new(RwLock::new(
1494                CachedExecutors::new(MAX_CACHED_EXECUTORS, fields.epoch),
1495            )))),
1496            transaction_debug_keys: debug_keys,
1497            transaction_log_collector_config: new(),
1498            transaction_log_collector: new(),
1499            feature_set: new(),
1500            drop_callback: RwLock::new(OptionalDropCallback(None)),
1501            freeze_started: AtomicBool::new(fields.hash != Hash::default()),
1502            vote_only_bank: false,
1503        };
1504        bank.finish_init(
1505            genesis_config,
1506            additional_builtins,
1507            debug_do_not_add_builtins,
1508        );
1509
1510        // Sanity assertions between bank snapshot and genesis config
1511        // Consider removing from serializable bank state
1512        // (BankFieldsToSerialize/BankFieldsToDeserialize) and initializing
1513        // from the passed in genesis_config instead (as new()/new_with_paths() already do)
1514        assert_eq!(
1515            bank.hashes_per_tick,
1516            genesis_config.poh_config.hashes_per_tick
1517        );
1518        assert_eq!(bank.ticks_per_slot, genesis_config.ticks_per_slot);
1519        assert_eq!(
1520            bank.ns_per_slot,
1521            genesis_config.poh_config.target_tick_duration.as_nanos()
1522                * genesis_config.ticks_per_slot as u128
1523        );
1524        assert_eq!(bank.genesis_creation_time, genesis_config.creation_time);
1525        assert_eq!(bank.unused, genesis_config.unused);
1526        assert_eq!(bank.max_tick_height, (bank.slot + 1) * bank.ticks_per_slot);
1527        assert_eq!(
1528            bank.slots_per_year,
1529            years_as_slots(
1530                1.0,
1531                &genesis_config.poh_config.target_tick_duration,
1532                bank.ticks_per_slot,
1533            )
1534        );
1535        assert_eq!(bank.epoch_schedule, genesis_config.epoch_schedule);
1536        assert_eq!(bank.epoch, bank.epoch_schedule.get_epoch(bank.slot));
1537        bank.fee_rate_governor.carats_per_signature = bank.fee_calculator.carats_per_signature;
1538        assert_eq!(
1539            bank.fee_rate_governor.create_fee_calculator(),
1540            bank.fee_calculator
1541        );
1542        bank
1543    }
1544
1545    /// Return subset of bank fields representing serializable state
1546    pub(crate) fn get_fields_to_serialize<'a>(
1547        &'a self,
1548        ancestors: &'a HashMap<Slot, usize>,
1549    ) -> BankFieldsToSerialize<'a> {
1550        BankFieldsToSerialize {
1551            blockhash_queue: &self.blockhash_queue,
1552            ancestors,
1553            hash: *self.hash.read().unwrap(),
1554            parent_hash: self.parent_hash,
1555            parent_slot: self.parent_slot,
1556            hard_forks: &*self.hard_forks,
1557            transaction_count: self.transaction_count.load(Relaxed),
1558            tick_height: self.tick_height.load(Relaxed),
1559            signature_count: self.signature_count.load(Relaxed),
1560            capitalization: self.capitalization.load(Relaxed),
1561            max_tick_height: self.max_tick_height,
1562            hashes_per_tick: self.hashes_per_tick,
1563            ticks_per_slot: self.ticks_per_slot,
1564            ns_per_slot: self.ns_per_slot,
1565            genesis_creation_time: self.genesis_creation_time,
1566            slots_per_year: self.slots_per_year,
1567            unused: self.unused,
1568            slot: self.slot,
1569            epoch: self.epoch,
1570            block_height: self.block_height,
1571            collector_id: self.collector_id,
1572            collector_fees: self.collector_fees.load(Relaxed),
1573            fee_calculator: self.fee_calculator.clone(),
1574            fee_rate_governor: self.fee_rate_governor.clone(),
1575            collected_rent: self.collected_rent.load(Relaxed),
1576            rent_collector: self.rent_collector.clone(),
1577            epoch_schedule: self.epoch_schedule,
1578            inflation: *self.inflation.read().unwrap(),
1579            stakes: &self.stakes,
1580            epoch_stakes: &self.epoch_stakes,
1581            is_delta: self.is_delta.load(Relaxed),
1582        }
1583    }
1584
1585    pub fn collector_id(&self) -> &Pubkey {
1586        &self.collector_id
1587    }
1588
1589    pub fn genesis_creation_time(&self) -> UnixTimestamp {
1590        self.genesis_creation_time
1591    }
1592
1593    pub fn slot(&self) -> Slot {
1594        self.slot
1595    }
1596
1597    pub fn bank_id(&self) -> BankId {
1598        self.bank_id
1599    }
1600
1601    pub fn epoch(&self) -> Epoch {
1602        self.epoch
1603    }
1604
1605    pub fn first_normal_epoch(&self) -> Epoch {
1606        self.epoch_schedule.first_normal_epoch
1607    }
1608
1609    pub fn freeze_lock(&self) -> RwLockReadGuard<Hash> {
1610        self.hash.read().unwrap()
1611    }
1612
1613    pub fn hash(&self) -> Hash {
1614        *self.hash.read().unwrap()
1615    }
1616
1617    pub fn is_frozen(&self) -> bool {
1618        *self.hash.read().unwrap() != Hash::default()
1619    }
1620
1621    pub fn freeze_started(&self) -> bool {
1622        self.freeze_started.load(Relaxed)
1623    }
1624
1625    pub fn status_cache_ancestors(&self) -> Vec<u64> {
1626        let mut roots = self.src.status_cache.read().unwrap().roots().clone();
1627        let min = roots.iter().min().cloned().unwrap_or(0);
1628        for ancestor in self.ancestors.keys() {
1629            if ancestor >= min {
1630                roots.insert(ancestor);
1631            }
1632        }
1633
1634        let mut ancestors: Vec<_> = roots.into_iter().collect();
1635        #[allow(clippy::stable_sort_primitive)]
1636        ancestors.sort();
1637        ancestors
1638    }
1639
1640    /// computed unix_timestamp at this slot height
1641    pub fn unix_timestamp_from_genesis(&self) -> i64 {
1642        self.genesis_creation_time + ((self.slot as u128 * self.ns_per_slot) / 1_000_000_000) as i64
1643    }
1644
1645    fn update_sysvar_account<F>(&self, pubkey: &Pubkey, updater: F)
1646    where
1647        F: Fn(&Option<AccountSharedData>) -> AccountSharedData,
1648    {
1649        let old_account = if !self.rent_for_sysvars() {
1650            // This old behavior is being retired for simpler reasoning for the benefits of all.
1651            // Specifically, get_sysvar_account_with_fixed_root() doesn't work nicely with eager
1652            // rent collection, which becomes significant for sysvars after rent_for_sysvars
1653            // activation. That's because get_sysvar_account_with_fixed_root() invocations by both
1654            // update_slot_history() and update_recent_blockhashes() ignores any updates
1655            // by eager rent collection in this slot.
1656            // Also, it turned out that get_sysvar_account_with_fixed_root()'s special
1657            // behavior (idempotent) isn't needed to begin with, because we're fairly certain that
1658            // we don't call new_from_parent() with same child slot multiple times in the
1659            // production code (except after proper handling of duplicate slot dumping)...
1660            self.get_sysvar_account_with_fixed_root(pubkey)
1661        } else {
1662            self.get_account_with_fixed_root(pubkey)
1663        };
1664        let mut new_account = updater(&old_account);
1665
1666        if self.rent_for_sysvars() {
1667            // When new sysvar comes into existence (with RENT_UNADJUSTED_INITIAL_BALANCE carats),
1668            // this code ensures that the sysvar's balance is adjusted to be rent-exempt.
1669            // Note that all of existing sysvar balances must be adjusted immediately (i.e. reset) upon
1670            // the `rent_for_sysvars` feature activation (ref: reset_all_sysvar_balances).
1671            //
1672            // More generally, this code always re-calculates for possible sysvar data size change,
1673            // although there is no such sysvars currently.
1674            self.adjust_sysvar_balance_for_rent(&mut new_account);
1675        }
1676
1677        self.store_account_and_update_capitalization(pubkey, &new_account);
1678    }
1679
1680    fn inherit_specially_retained_account_fields(
1681        &self,
1682        old_account: &Option<AccountSharedData>,
1683    ) -> InheritableAccountFields {
1684        const RENT_UNADJUSTED_INITIAL_BALANCE: u64 = 1;
1685
1686        (
1687            old_account
1688                .as_ref()
1689                .map(|a| a.carats())
1690                .unwrap_or(RENT_UNADJUSTED_INITIAL_BALANCE),
1691            if !self.rent_for_sysvars() {
1692                INITIAL_RENT_EPOCH
1693            } else {
1694                // start to inherit rent_epoch updated by rent collection to be consistent with
1695                // other normal accounts
1696                old_account
1697                    .as_ref()
1698                    .map(|a| a.rent_epoch())
1699                    .unwrap_or(INITIAL_RENT_EPOCH)
1700            },
1701        )
1702    }
1703
1704    /// Unused conversion
1705    pub fn get_unused_from_slot(rooted_slot: Slot, unused: u64) -> u64 {
1706        (rooted_slot + (unused - 1)) / unused
1707    }
1708
1709    pub fn clock(&self) -> sysvar::clock::Clock {
1710        from_account(&self.get_account(&sysvar::clock::id()).unwrap_or_default())
1711            .unwrap_or_default()
1712    }
1713
1714    fn update_clock(&self, parent_epoch: Option<Epoch>) {
1715        let mut unix_timestamp = self.clock().unix_timestamp;
1716        let warp_timestamp_again = self
1717            .feature_set
1718            .activated_slot(&feature_set::warp_timestamp_again::id());
1719        let epoch_start_timestamp = if warp_timestamp_again == Some(self.slot()) {
1720            None
1721        } else {
1722            let epoch = if let Some(epoch) = parent_epoch {
1723                epoch
1724            } else {
1725                self.epoch()
1726            };
1727            let first_slot_in_epoch = self.epoch_schedule.get_first_slot_in_epoch(epoch);
1728            Some((first_slot_in_epoch, self.clock().epoch_start_timestamp))
1729        };
1730        let max_allowable_drift = if self
1731            .feature_set
1732            .is_active(&feature_set::warp_timestamp_again::id())
1733        {
1734            MaxAllowableDrift {
1735                fast: MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST,
1736                slow: MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW,
1737            }
1738        } else {
1739            MaxAllowableDrift {
1740                fast: MAX_ALLOWABLE_DRIFT_PERCENTAGE,
1741                slow: MAX_ALLOWABLE_DRIFT_PERCENTAGE,
1742            }
1743        };
1744
1745        let ancestor_timestamp = self.clock().unix_timestamp;
1746        if let Some(timestamp_estimate) =
1747            self.get_timestamp_estimate(max_allowable_drift, epoch_start_timestamp)
1748        {
1749            unix_timestamp = timestamp_estimate;
1750            if timestamp_estimate < ancestor_timestamp {
1751                unix_timestamp = ancestor_timestamp;
1752            }
1753        }
1754        datapoint_info!(
1755            "bank-timestamp-correction",
1756            ("slot", self.slot(), i64),
1757            ("from_genesis", self.unix_timestamp_from_genesis(), i64),
1758            ("corrected", unix_timestamp, i64),
1759            ("ancestor_timestamp", ancestor_timestamp, i64),
1760        );
1761        let mut epoch_start_timestamp =
1762            // On epoch boundaries, update epoch_start_timestamp
1763            if parent_epoch.is_some() && parent_epoch.unwrap() != self.epoch() {
1764                unix_timestamp
1765            } else {
1766                self.clock().epoch_start_timestamp
1767            };
1768        if self.slot == 0 {
1769            unix_timestamp = self.unix_timestamp_from_genesis();
1770            epoch_start_timestamp = self.unix_timestamp_from_genesis();
1771        }
1772        let clock = sysvar::clock::Clock {
1773            slot: self.slot,
1774            epoch_start_timestamp,
1775            epoch: self.epoch_schedule.get_epoch(self.slot),
1776            leader_schedule_epoch: self.epoch_schedule.get_leader_schedule_epoch(self.slot),
1777            unix_timestamp,
1778        };
1779        self.update_sysvar_account(&sysvar::clock::id(), |account| {
1780            create_account(
1781                &clock,
1782                self.inherit_specially_retained_account_fields(account),
1783            )
1784        });
1785    }
1786
1787    fn update_slot_history(&self) {
1788        self.update_sysvar_account(&sysvar::slot_history::id(), |account| {
1789            let mut slot_history = account
1790                .as_ref()
1791                .map(|account| from_account::<SlotHistory, _>(account).unwrap())
1792                .unwrap_or_default();
1793            slot_history.add(self.slot());
1794            create_account(
1795                &slot_history,
1796                self.inherit_specially_retained_account_fields(account),
1797            )
1798        });
1799    }
1800
1801    fn update_slot_hashes(&self) {
1802        self.update_sysvar_account(&sysvar::slot_hashes::id(), |account| {
1803            let mut slot_hashes = account
1804                .as_ref()
1805                .map(|account| from_account::<SlotHashes, _>(account).unwrap())
1806                .unwrap_or_default();
1807            slot_hashes.add(self.parent_slot, self.parent_hash);
1808            create_account(
1809                &slot_hashes,
1810                self.inherit_specially_retained_account_fields(account),
1811            )
1812        });
1813    }
1814
1815    pub fn get_slot_history(&self) -> SlotHistory {
1816        from_account(&self.get_account(&sysvar::slot_history::id()).unwrap()).unwrap()
1817    }
1818
1819    fn update_epoch_stakes(&mut self, leader_schedule_epoch: Epoch) {
1820        // update epoch_stakes cache
1821        //  if my parent didn't populate for this staker's epoch, we've
1822        //  crossed a boundary
1823        if self.epoch_stakes.get(&leader_schedule_epoch).is_none() {
1824            self.epoch_stakes.retain(|&epoch, _| {
1825                epoch >= leader_schedule_epoch.saturating_sub(MAX_LEADER_SCHEDULE_STAKES)
1826            });
1827
1828            let new_epoch_stakes =
1829                EpochStakes::new(&self.stakes.read().unwrap(), leader_schedule_epoch);
1830            {
1831                let vote_stakes: HashMap<_, _> = self
1832                    .stakes
1833                    .read()
1834                    .unwrap()
1835                    .vote_accounts()
1836                    .iter()
1837                    .map(|(pubkey, (stake, _))| (*pubkey, *stake))
1838                    .collect();
1839                info!(
1840                    "new epoch stakes, epoch: {}, stakes: {:#?}, total_stake: {}",
1841                    leader_schedule_epoch,
1842                    vote_stakes,
1843                    new_epoch_stakes.total_stake(),
1844                );
1845            }
1846            self.epoch_stakes
1847                .insert(leader_schedule_epoch, new_epoch_stakes);
1848        }
1849    }
1850
1851    #[allow(deprecated)]
1852    fn update_fees(&self) {
1853        if !self
1854            .feature_set
1855            .is_active(&feature_set::disable_fees_sysvar::id())
1856        {
1857            self.update_sysvar_account(&sysvar::fees::id(), |account| {
1858                create_account(
1859                    &sysvar::fees::Fees::new(&self.fee_calculator),
1860                    self.inherit_specially_retained_account_fields(account),
1861                )
1862            });
1863        }
1864    }
1865
1866    fn update_rent(&self) {
1867        self.update_sysvar_account(&sysvar::rent::id(), |account| {
1868            create_account(
1869                &self.rent_collector.rent,
1870                self.inherit_specially_retained_account_fields(account),
1871            )
1872        });
1873    }
1874
1875    fn update_epoch_schedule(&self) {
1876        self.update_sysvar_account(&sysvar::epoch_schedule::id(), |account| {
1877            create_account(
1878                &self.epoch_schedule,
1879                self.inherit_specially_retained_account_fields(account),
1880            )
1881        });
1882    }
1883
1884    fn update_stake_history(&self, epoch: Option<Epoch>) {
1885        if epoch == Some(self.epoch()) {
1886            return;
1887        }
1888        // if I'm the first Bank in an epoch, ensure stake_history is updated
1889        self.update_sysvar_account(&sysvar::stake_history::id(), |account| {
1890            create_account::<sysvar::stake_history::StakeHistory>(
1891                self.stakes.read().unwrap().history(),
1892                self.inherit_specially_retained_account_fields(account),
1893            )
1894        });
1895    }
1896
1897    pub fn epoch_duration_in_years(&self, prev_epoch: Epoch) -> f64 {
1898        // period: time that has passed as a fraction of a year, basically the length of
1899        //  an epoch as a fraction of a year
1900        //  calculated as: slots_elapsed / (slots / year)
1901        self.epoch_schedule.get_slots_in_epoch(prev_epoch) as f64 / self.slots_per_year
1902    }
1903
1904    // Calculates the starting-slot for inflation from the activation slot.
1905    // This method assumes that `pico_inflation` will be enabled before `full_inflation`, giving
1906    // precedence to the latter. However, since `pico_inflation` is fixed-rate Inflation, should
1907    // `pico_inflation` be enabled 2nd, the incorrect start slot provided here should have no
1908    // effect on the inflation calculation.
1909    fn get_inflation_start_slot(&self) -> Slot {
1910        let mut slots = self
1911            .feature_set
1912            .full_inflation_features_enabled()
1913            .iter()
1914            .filter_map(|id| self.feature_set.activated_slot(id))
1915            .collect::<Vec<_>>();
1916        slots.sort_unstable();
1917        slots.get(0).cloned().unwrap_or_else(|| {
1918            self.feature_set
1919                .activated_slot(&feature_set::pico_inflation::id())
1920                .unwrap_or(0)
1921        })
1922    }
1923
1924    fn get_inflation_num_slots(&self) -> u64 {
1925        let inflation_activation_slot = self.get_inflation_start_slot();
1926        // Normalize inflation_start to align with the start of rewards accrual.
1927        let inflation_start_slot = self.epoch_schedule.get_first_slot_in_epoch(
1928            self.epoch_schedule
1929                .get_epoch(inflation_activation_slot)
1930                .saturating_sub(1),
1931        );
1932        self.epoch_schedule.get_first_slot_in_epoch(self.epoch()) - inflation_start_slot
1933    }
1934
1935    pub fn slot_in_year_for_inflation(&self) -> f64 {
1936        let num_slots = self.get_inflation_num_slots();
1937
1938        // calculated as: num_slots / (slots / year)
1939        num_slots as f64 / self.slots_per_year
1940    }
1941
1942    // update rewards based on the previous epoch
1943    fn update_rewards(
1944        &mut self,
1945        prev_epoch: Epoch,
1946        reward_calc_tracer: &mut Option<impl FnMut(&RewardCalculationEvent)>,
1947    ) {
1948        if prev_epoch == self.epoch() {
1949            return;
1950        }
1951        // if I'm the first Bank in an epoch, count, claim, disburse rewards from Inflation
1952
1953        let slot_in_year = self.slot_in_year_for_inflation();
1954        let epoch_duration_in_years = self.epoch_duration_in_years(prev_epoch);
1955
1956        let (validator_rate, foundation_rate) = {
1957            let inflation = self.inflation.read().unwrap();
1958            (
1959                (*inflation).validator(slot_in_year),
1960                (*inflation).foundation(slot_in_year),
1961            )
1962        };
1963
1964        let capitalization = self.capitalization();
1965        let validator_rewards =
1966            (validator_rate * capitalization as f64 * epoch_duration_in_years) as u64;
1967
1968        let old_vote_balance_and_staked = self.stakes.read().unwrap().vote_balance_and_staked();
1969
1970        let validator_point_value = self.pay_validator_rewards(
1971            prev_epoch,
1972            validator_rewards,
1973            reward_calc_tracer,
1974            self.stake_program_advance_activating_credits_observed(),
1975        );
1976
1977        if !self
1978            .feature_set
1979            .is_active(&feature_set::deprecate_rewards_sysvar::id())
1980        {
1981            // this sysvar can be retired once `pico_inflation` is enabled on all clusters
1982            self.update_sysvar_account(&sysvar::rewards::id(), |account| {
1983                create_account(
1984                    &sysvar::rewards::Rewards::new(validator_point_value),
1985                    self.inherit_specially_retained_account_fields(account),
1986                )
1987            });
1988        }
1989
1990        let new_vote_balance_and_staked = self.stakes.read().unwrap().vote_balance_and_staked();
1991        let validator_rewards_paid = new_vote_balance_and_staked - old_vote_balance_and_staked;
1992        assert_eq!(
1993            validator_rewards_paid,
1994            u64::try_from(
1995                self.rewards
1996                    .read()
1997                    .unwrap()
1998                    .iter()
1999                    .map(|(_address, reward_info)| {
2000                        match reward_info.reward_type {
2001                            RewardType::Voting | RewardType::Staking => reward_info.carats,
2002                            _ => 0,
2003                        }
2004                    })
2005                    .sum::<i64>()
2006            )
2007            .unwrap()
2008        );
2009
2010        // verify that we didn't pay any more than we expected to
2011        assert!(validator_rewards >= validator_rewards_paid);
2012
2013        info!(
2014            "distributed inflation: {} (rounded from: {})",
2015            validator_rewards_paid, validator_rewards
2016        );
2017
2018        self.capitalization
2019            .fetch_add(validator_rewards_paid, Relaxed);
2020
2021        let active_stake = if let Some(stake_history_entry) =
2022            self.stakes.read().unwrap().history().get(&prev_epoch)
2023        {
2024            stake_history_entry.effective
2025        } else {
2026            0
2027        };
2028
2029        datapoint_warn!(
2030            "epoch_rewards",
2031            ("slot", self.slot, i64),
2032            ("epoch", prev_epoch, i64),
2033            ("validator_rate", validator_rate, f64),
2034            ("foundation_rate", foundation_rate, f64),
2035            ("epoch_duration_in_years", epoch_duration_in_years, f64),
2036            ("validator_rewards", validator_rewards_paid, i64),
2037            ("active_stake", active_stake, i64),
2038            ("pre_capitalization", capitalization, i64),
2039            ("post_capitalization", self.capitalization(), i64)
2040        );
2041    }
2042
2043    /// map stake delegations into resolved (pubkey, account) pairs
2044    ///  returns a map (has to be copied) of loaded
2045    ///   ( Vec<(staker info)> (voter account) ) keyed by voter pubkey
2046    ///
2047    /// Filters out invalid pairs
2048    fn stake_delegation_accounts(
2049        &self,
2050        reward_calc_tracer: &mut Option<impl FnMut(&RewardCalculationEvent)>,
2051    ) -> HashMap<Pubkey, (Vec<(Pubkey, AccountSharedData)>, AccountSharedData)> {
2052        let mut accounts = HashMap::new();
2053
2054        self.stakes
2055            .read()
2056            .unwrap()
2057            .stake_delegations()
2058            .iter()
2059            .for_each(|(stake_pubkey, delegation)| {
2060                match (
2061                    self.get_account_with_fixed_root(stake_pubkey),
2062                    self.get_account_with_fixed_root(&delegation.voter_pubkey),
2063                ) {
2064                    (Some(stake_account), Some(vote_account)) => {
2065                        // call tracer to catch any illegal data if any
2066                        if let Some(reward_calc_tracer) = reward_calc_tracer {
2067                            reward_calc_tracer(&RewardCalculationEvent::Staking(
2068                                stake_pubkey,
2069                                &InflationPointCalculationEvent::Delegation(
2070                                    *delegation,
2071                                    *vote_account.owner(),
2072                                ),
2073                            ));
2074                        }
2075                        if self
2076                            .feature_set
2077                            .is_active(&feature_set::filter_stake_delegation_accounts::id())
2078                            && (stake_account.owner() != &stake::program::id()
2079                                || vote_account.owner() != &gemachain_vote_program::id())
2080                        {
2081                            datapoint_warn!(
2082                                "bank-stake_delegation_accounts-invalid-account",
2083                                ("slot", self.slot() as i64, i64),
2084                                ("stake-address", format!("{:?}", stake_pubkey), String),
2085                                (
2086                                    "vote-address",
2087                                    format!("{:?}", delegation.voter_pubkey),
2088                                    String
2089                                ),
2090                            );
2091                            return;
2092                        }
2093                        let entry = accounts
2094                            .entry(delegation.voter_pubkey)
2095                            .or_insert((Vec::new(), vote_account));
2096                        entry.0.push((*stake_pubkey, stake_account));
2097                    }
2098                    (_, _) => {}
2099                }
2100            });
2101
2102        accounts
2103    }
2104
2105    /// iterate over all stakes, redeem vote credits for each stake we can
2106    ///   successfully load and parse, return the carat value of one point
2107    fn pay_validator_rewards(
2108        &mut self,
2109        rewarded_epoch: Epoch,
2110        rewards: u64,
2111        reward_calc_tracer: &mut Option<impl FnMut(&RewardCalculationEvent)>,
2112        fix_activating_credits_observed: bool,
2113    ) -> f64 {
2114        let stake_history = self.stakes.read().unwrap().history().clone();
2115
2116        let mut stake_delegation_accounts = self.stake_delegation_accounts(reward_calc_tracer);
2117
2118        let points: u128 = stake_delegation_accounts
2119            .iter()
2120            .flat_map(|(_vote_pubkey, (stake_group, vote_account))| {
2121                stake_group
2122                    .iter()
2123                    .map(move |(_stake_pubkey, stake_account)| (stake_account, vote_account))
2124            })
2125            .map(|(stake_account, vote_account)| {
2126                stake_state::calculate_points(stake_account, vote_account, Some(&stake_history))
2127                    .unwrap_or(0)
2128            })
2129            .sum();
2130
2131        if points == 0 {
2132            return 0.0;
2133        }
2134
2135        let point_value = PointValue { rewards, points };
2136
2137        let mut rewards = vec![];
2138        // pay according to point value
2139        for (vote_pubkey, (stake_group, vote_account)) in stake_delegation_accounts.iter_mut() {
2140            let mut vote_account_changed = false;
2141            let voters_account_pre_balance = vote_account.carats();
2142            let vote_state: VoteState = match StateMut::<VoteStateVersions>::state(vote_account) {
2143                Ok(vote_state) => vote_state.convert_to_current(),
2144                Err(err) => {
2145                    debug!(
2146                        "failed to deserialize vote account {}: {}",
2147                        vote_pubkey, err
2148                    );
2149                    continue;
2150                }
2151            };
2152            let commission = Some(vote_state.commission);
2153
2154            for (stake_pubkey, stake_account) in stake_group.iter_mut() {
2155                // curry closure to add the contextual stake_pubkey
2156                let mut reward_calc_tracer = reward_calc_tracer.as_mut().map(|outer| {
2157                    let stake_pubkey = *stake_pubkey;
2158                    // inner
2159                    move |inner_event: &_| {
2160                        outer(&RewardCalculationEvent::Staking(&stake_pubkey, inner_event))
2161                    }
2162                });
2163                let redeemed = stake_state::redeem_rewards(
2164                    rewarded_epoch,
2165                    stake_account,
2166                    vote_account,
2167                    &vote_state,
2168                    &point_value,
2169                    Some(&stake_history),
2170                    &mut reward_calc_tracer.as_mut(),
2171                    fix_activating_credits_observed,
2172                );
2173                if let Ok((stakers_reward, _voters_reward)) = redeemed {
2174                    self.store_account(stake_pubkey, stake_account);
2175                    vote_account_changed = true;
2176
2177                    if stakers_reward > 0 {
2178                        rewards.push((
2179                            *stake_pubkey,
2180                            RewardInfo {
2181                                reward_type: RewardType::Staking,
2182                                carats: stakers_reward as i64,
2183                                post_balance: stake_account.carats(),
2184                                commission,
2185                            },
2186                        ));
2187                    }
2188                } else {
2189                    debug!(
2190                        "stake_state::redeem_rewards() failed for {}: {:?}",
2191                        stake_pubkey, redeemed
2192                    );
2193                }
2194            }
2195
2196            if vote_account_changed {
2197                let post_balance = vote_account.carats();
2198                let carats = (post_balance - voters_account_pre_balance) as i64;
2199                if carats != 0 {
2200                    rewards.push((
2201                        *vote_pubkey,
2202                        RewardInfo {
2203                            reward_type: RewardType::Voting,
2204                            carats,
2205                            post_balance,
2206                            commission,
2207                        },
2208                    ));
2209                }
2210                self.store_account(vote_pubkey, vote_account);
2211            }
2212        }
2213        self.rewards.write().unwrap().append(&mut rewards);
2214
2215        point_value.rewards as f64 / point_value.points as f64
2216    }
2217
2218    fn update_recent_blockhashes_locked(&self, locked_blockhash_queue: &BlockhashQueue) {
2219        #[allow(deprecated)]
2220        self.update_sysvar_account(&sysvar::recent_blockhashes::id(), |account| {
2221            let recent_blockhash_iter = locked_blockhash_queue.get_recent_blockhashes();
2222            recent_blockhashes_account::create_account_with_data_and_fields(
2223                recent_blockhash_iter,
2224                self.inherit_specially_retained_account_fields(account),
2225            )
2226        });
2227    }
2228
2229    pub fn update_recent_blockhashes(&self) {
2230        let blockhash_queue = self.blockhash_queue.read().unwrap();
2231        self.update_recent_blockhashes_locked(&blockhash_queue);
2232    }
2233
2234    fn get_timestamp_estimate(
2235        &self,
2236        max_allowable_drift: MaxAllowableDrift,
2237        epoch_start_timestamp: Option<(Slot, UnixTimestamp)>,
2238    ) -> Option<UnixTimestamp> {
2239        let mut get_timestamp_estimate_time = Measure::start("get_timestamp_estimate");
2240        let slots_per_epoch = self.epoch_schedule().slots_per_epoch;
2241        let vote_accounts = self.vote_accounts();
2242        let recent_timestamps = vote_accounts.iter().filter_map(|(pubkey, (_, account))| {
2243            let vote_state = account.vote_state();
2244            let vote_state = vote_state.as_ref().ok()?;
2245            let slot_delta = self.slot().checked_sub(vote_state.last_timestamp.slot)?;
2246            (slot_delta <= slots_per_epoch).then(|| {
2247                (
2248                    *pubkey,
2249                    (
2250                        vote_state.last_timestamp.slot,
2251                        vote_state.last_timestamp.timestamp,
2252                    ),
2253                )
2254            })
2255        });
2256        let slot_duration = Duration::from_nanos(self.ns_per_slot as u64);
2257        let epoch = self.epoch_schedule().get_epoch(self.slot());
2258        let stakes = self.epoch_vote_accounts(epoch)?;
2259        let stake_weighted_timestamp = calculate_stake_weighted_timestamp(
2260            recent_timestamps,
2261            stakes,
2262            self.slot(),
2263            slot_duration,
2264            epoch_start_timestamp,
2265            max_allowable_drift,
2266            self.feature_set
2267                .is_active(&feature_set::warp_timestamp_again::id()),
2268        );
2269        get_timestamp_estimate_time.stop();
2270        datapoint_info!(
2271            "bank-timestamp",
2272            (
2273                "get_timestamp_estimate_us",
2274                get_timestamp_estimate_time.as_us(),
2275                i64
2276            ),
2277        );
2278        stake_weighted_timestamp
2279    }
2280
2281    // Distribute collected transaction fees for this slot to collector_id (= current leader).
2282    //
2283    // Each validator is incentivized to process more transactions to earn more transaction fees.
2284    // Transaction fees are rewarded for the computing resource utilization cost, directly
2285    // proportional to their actual processing power.
2286    //
2287    // collector_id is rotated according to stake-weighted leader schedule. So the opportunity of
2288    // earning transaction fees are fairly distributed by stake. And missing the opportunity
2289    // (not producing a block as a leader) earns nothing. So, being online is incentivized as a
2290    // form of transaction fees as well.
2291    //
2292    // On the other hand, rent fees are distributed under slightly different philosophy, while
2293    // still being stake-weighted.
2294    // Ref: distribute_rent_to_validators
2295    fn collect_fees(&self) {
2296        let collector_fees = self.collector_fees.load(Relaxed) as u64;
2297
2298        if collector_fees != 0 {
2299            let (deposit, mut burn) = self.fee_rate_governor.burn(collector_fees);
2300            // burn a portion of fees
2301            debug!(
2302                "distributed fee: {} (rounded from: {}, burned: {})",
2303                deposit, collector_fees, burn
2304            );
2305
2306            match self.deposit(&self.collector_id, deposit) {
2307                Ok(post_balance) => {
2308                    if deposit != 0 {
2309                        self.rewards.write().unwrap().push((
2310                            self.collector_id,
2311                            RewardInfo {
2312                                reward_type: RewardType::Fee,
2313                                carats: deposit as i64,
2314                                post_balance,
2315                                commission: None,
2316                            },
2317                        ));
2318                    }
2319                }
2320                Err(_) => {
2321                    error!(
2322                        "Burning {} fee instead of crediting {}",
2323                        deposit, self.collector_id
2324                    );
2325                    inc_new_counter_error!("bank-burned_fee_carats", deposit as usize);
2326                    burn += deposit;
2327                }
2328            }
2329            self.capitalization.fetch_sub(burn, Relaxed);
2330        }
2331    }
2332
2333    pub fn rehash(&self) {
2334        let mut hash = self.hash.write().unwrap();
2335        let new = self.hash_internal_state();
2336        if new != *hash {
2337            warn!("Updating bank hash to {}", new);
2338            *hash = new;
2339        }
2340    }
2341
2342    pub fn freeze(&self) {
2343        // This lock prevents any new commits from BankingStage
2344        // `process_and_record_transactions_locked()` from coming
2345        // in after the last tick is observed. This is because in
2346        // BankingStage, any transaction successfully recorded in
2347        // `record_transactions()` is recorded after this `hash` lock
2348        // is grabbed. At the time of the successful record,
2349        // this means the PoH has not yet reached the last tick,
2350        // so this means freeze() hasn't been called yet. And because
2351        // BankingStage doesn't release this hash lock until both
2352        // record and commit are finished, those transactions will be
2353        // committed before this write lock can be obtained here.
2354        let mut hash = self.hash.write().unwrap();
2355        if *hash == Hash::default() {
2356            // finish up any deferred changes to account state
2357            self.collect_rent_eagerly();
2358            self.collect_fees();
2359            self.distribute_rent();
2360            self.update_slot_history();
2361            self.run_incinerator();
2362
2363            // freeze is a one-way trip, idempotent
2364            self.freeze_started.store(true, Relaxed);
2365            *hash = self.hash_internal_state();
2366            self.rc.accounts.accounts_db.mark_slot_frozen(self.slot());
2367        }
2368    }
2369
2370    // Should not be called outside of startup, will race with
2371    // concurrent cleaning logic in AccountsBackgroundService
2372    pub fn exhaustively_free_unused_resource(&self, last_full_snapshot_slot: Option<Slot>) {
2373        const IS_STARTUP: bool = true; // this is only called at startup, and we want to use more threads
2374        let mut flush = Measure::start("flush");
2375        // Flush all the rooted accounts. Must be called after `squash()`,
2376        // so that AccountsDb knows what the roots are.
2377        self.force_flush_accounts_cache();
2378        flush.stop();
2379
2380        let mut clean = Measure::start("clean");
2381        // Don't clean the slot we're snapshotting because it may have zero-carat
2382        // accounts that were included in the bank delta hash when the bank was frozen,
2383        // and if we clean them here, any newly created snapshot's hash for this bank
2384        // may not match the frozen hash.
2385        self.clean_accounts(true, IS_STARTUP, last_full_snapshot_slot);
2386        clean.stop();
2387
2388        let mut shrink = Measure::start("shrink");
2389        self.shrink_all_slots(IS_STARTUP, last_full_snapshot_slot);
2390        shrink.stop();
2391
2392        info!(
2393            "exhaustively_free_unused_resource() {} {} {}",
2394            flush, clean, shrink,
2395        );
2396    }
2397
2398    pub fn epoch_schedule(&self) -> &EpochSchedule {
2399        &self.epoch_schedule
2400    }
2401
2402    /// squash the parent's state up into this Bank,
2403    ///   this Bank becomes a root
2404    pub fn squash(&self) {
2405        self.freeze();
2406
2407        //this bank and all its parents are now on the rooted path
2408        let mut roots = vec![self.slot()];
2409        roots.append(&mut self.parents().iter().map(|p| p.slot()).collect());
2410
2411        let mut squash_accounts_time = Measure::start("squash_accounts_time");
2412        for slot in roots.iter().rev() {
2413            // root forks cannot be purged
2414            self.rc.accounts.add_root(*slot);
2415        }
2416        squash_accounts_time.stop();
2417
2418        *self.rc.parent.write().unwrap() = None;
2419
2420        let mut squash_cache_time = Measure::start("squash_cache_time");
2421        roots
2422            .iter()
2423            .for_each(|slot| self.src.status_cache.write().unwrap().add_root(*slot));
2424        squash_cache_time.stop();
2425
2426        datapoint_debug!(
2427            "tower-observed",
2428            ("squash_accounts_ms", squash_accounts_time.as_ms(), i64),
2429            ("squash_cache_ms", squash_cache_time.as_ms(), i64)
2430        );
2431    }
2432
2433    /// Return the more recent checkpoint of this bank instance.
2434    pub fn parent(&self) -> Option<Arc<Bank>> {
2435        self.rc.parent.read().unwrap().clone()
2436    }
2437
2438    pub fn parent_slot(&self) -> Slot {
2439        self.parent_slot
2440    }
2441
2442    pub fn parent_hash(&self) -> Hash {
2443        self.parent_hash
2444    }
2445
2446    fn process_genesis_config(&mut self, genesis_config: &GenesisConfig) {
2447        // Bootstrap validator collects fees until `new_from_parent` is called.
2448        self.fee_rate_governor = genesis_config.fee_rate_governor.clone();
2449        self.fee_calculator = self.fee_rate_governor.create_fee_calculator();
2450
2451        for (pubkey, account) in genesis_config.accounts.iter() {
2452            if self.get_account(pubkey).is_some() {
2453                panic!("{} repeated in genesis config", pubkey);
2454            }
2455            self.store_account(pubkey, &AccountSharedData::from(account.clone()));
2456            self.capitalization.fetch_add(account.carats(), Relaxed);
2457        }
2458        // updating sysvars (the fees sysvar in this case) now depends on feature activations in
2459        // genesis_config.accounts above
2460        self.update_fees();
2461
2462        for (pubkey, account) in genesis_config.rewards_pools.iter() {
2463            if self.get_account(pubkey).is_some() {
2464                panic!("{} repeated in genesis config", pubkey);
2465            }
2466            self.store_account(pubkey, &AccountSharedData::from(account.clone()));
2467        }
2468
2469        // highest staked node is the first collector
2470        self.collector_id = self
2471            .stakes
2472            .read()
2473            .unwrap()
2474            .highest_staked_node()
2475            .unwrap_or_default();
2476
2477        self.blockhash_queue
2478            .write()
2479            .unwrap()
2480            .genesis_hash(&genesis_config.hash(), &self.fee_calculator);
2481
2482        self.hashes_per_tick = genesis_config.hashes_per_tick();
2483        self.ticks_per_slot = genesis_config.ticks_per_slot();
2484        self.ns_per_slot = genesis_config.ns_per_slot();
2485        self.genesis_creation_time = genesis_config.creation_time;
2486        self.unused = genesis_config.unused;
2487        self.max_tick_height = (self.slot + 1) * self.ticks_per_slot;
2488        self.slots_per_year = genesis_config.slots_per_year();
2489
2490        self.epoch_schedule = genesis_config.epoch_schedule;
2491
2492        self.inflation = Arc::new(RwLock::new(genesis_config.inflation));
2493
2494        self.rent_collector = RentCollector::new(
2495            self.epoch,
2496            &self.epoch_schedule,
2497            self.slots_per_year,
2498            &genesis_config.rent,
2499        );
2500
2501        // Add additional native programs specified in the genesis config
2502        for (name, program_id) in &genesis_config.native_instruction_processors {
2503            self.add_native_program(name, program_id, false);
2504        }
2505    }
2506
2507    // NOTE: must hold idempotent for the same set of arguments
2508    pub fn add_native_program(&self, name: &str, program_id: &Pubkey, must_replace: bool) {
2509        let existing_genuine_program =
2510            if let Some(mut account) = self.get_account_with_fixed_root(program_id) {
2511                // it's very unlikely to be squatted at program_id as non-system account because of burden to
2512                // find victim's pubkey/hash. So, when account.owner is indeed native_loader's, it's
2513                // safe to assume it's a genuine program.
2514                if native_loader::check_id(account.owner()) {
2515                    Some(account)
2516                } else {
2517                    // malicious account is pre-occupying at program_id
2518                    // forcibly burn and purge it
2519
2520                    self.capitalization.fetch_sub(account.carats(), Relaxed);
2521
2522                    // Resetting account balance to 0 is needed to really purge from AccountsDb and
2523                    // flush the Stakes cache
2524                    account.set_carats(0);
2525                    self.store_account(program_id, &account);
2526                    None
2527                }
2528            } else {
2529                None
2530            };
2531
2532        if must_replace {
2533            // updating native program
2534
2535            match &existing_genuine_program {
2536                None => panic!(
2537                    "There is no account to replace with native program ({}, {}).",
2538                    name, program_id
2539                ),
2540                Some(account) => {
2541                    if *name == String::from_utf8_lossy(account.data()) {
2542                        // nop; it seems that already AccountsDb is updated.
2543                        return;
2544                    }
2545                    // continue to replace account
2546                }
2547            }
2548        } else {
2549            // introducing native program
2550
2551            match &existing_genuine_program {
2552                None => (), // continue to add account
2553                Some(_account) => {
2554                    // nop; it seems that we already have account
2555
2556                    // before returning here to retain idempotent just make sure
2557                    // the existing native program name is same with what we're
2558                    // supposed to add here (but skipping) But I can't:
2559                    // following assertion already catches several different names for same
2560                    // program_id
2561                    // depending on clusters...
2562                    // assert_eq!(name.to_owned(), String::from_utf8_lossy(&account.data));
2563                    return;
2564                }
2565            }
2566        }
2567
2568        assert!(
2569            !self.freeze_started(),
2570            "Can't change frozen bank by adding not-existing new native program ({}, {}). \
2571            Maybe, inconsistent program activation is detected on snapshot restore?",
2572            name,
2573            program_id
2574        );
2575
2576        // Add a bogus executable native account, which will be loaded and ignored.
2577        let account = native_loader::create_loadable_account_with_fields(
2578            name,
2579            self.inherit_specially_retained_account_fields(&existing_genuine_program),
2580        );
2581        self.store_account_and_update_capitalization(program_id, &account);
2582
2583        debug!("Added native program {} under {:?}", name, program_id);
2584    }
2585
2586    pub fn set_rent_burn_percentage(&mut self, burn_percent: u8) {
2587        self.rent_collector.rent.burn_percent = burn_percent;
2588    }
2589
2590    pub fn set_hashes_per_tick(&mut self, hashes_per_tick: Option<u64>) {
2591        self.hashes_per_tick = hashes_per_tick;
2592    }
2593
2594    /// Return the last block hash registered.
2595    pub fn last_blockhash(&self) -> Hash {
2596        self.blockhash_queue.read().unwrap().last_hash()
2597    }
2598
2599    pub fn is_blockhash_valid(&self, hash: &Hash) -> bool {
2600        let blockhash_queue = self.blockhash_queue.read().unwrap();
2601        blockhash_queue.check_hash(hash)
2602    }
2603
2604    pub fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> u64 {
2605        self.rent_collector.rent.minimum_balance(data_len)
2606    }
2607
2608    #[deprecated(
2609        since = "1.8.0",
2610        note = "Please use `last_blockhash` and `get_fee_for_message` instead"
2611    )]
2612    pub fn last_blockhash_with_fee_calculator(&self) -> (Hash, FeeCalculator) {
2613        let blockhash_queue = self.blockhash_queue.read().unwrap();
2614        let last_hash = blockhash_queue.last_hash();
2615        (
2616            last_hash,
2617            #[allow(deprecated)]
2618            blockhash_queue
2619                .get_fee_calculator(&last_hash)
2620                .unwrap()
2621                .clone(),
2622        )
2623    }
2624
2625    #[deprecated(since = "1.8.0", note = "Please use `get_fee_for_message` instead")]
2626    pub fn get_fee_calculator(&self, hash: &Hash) -> Option<FeeCalculator> {
2627        let blockhash_queue = self.blockhash_queue.read().unwrap();
2628        #[allow(deprecated)]
2629        blockhash_queue.get_fee_calculator(hash).cloned()
2630    }
2631
2632    #[deprecated(since = "1.8.0", note = "Please use `get_fee_for_message` instead")]
2633    pub fn get_fee_rate_governor(&self) -> &FeeRateGovernor {
2634        &self.fee_rate_governor
2635    }
2636
2637    pub fn get_fee_for_message(&self, hash: &Hash, message: &SanitizedMessage) -> Option<u64> {
2638        let blockhash_queue = self.blockhash_queue.read().unwrap();
2639        #[allow(deprecated)]
2640        let fee_calculator = blockhash_queue.get_fee_calculator(hash)?;
2641        Some(message.calculate_fee(fee_calculator))
2642    }
2643
2644    #[deprecated(
2645        since = "1.6.11",
2646        note = "Please use `get_blockhash_last_valid_block_height`"
2647    )]
2648    pub fn get_blockhash_last_valid_slot(&self, blockhash: &Hash) -> Option<Slot> {
2649        let blockhash_queue = self.blockhash_queue.read().unwrap();
2650        // This calculation will need to be updated to consider epoch boundaries if BlockhashQueue
2651        // length is made variable by epoch
2652        blockhash_queue
2653            .get_hash_age(blockhash)
2654            .map(|age| self.slot + blockhash_queue.len() as u64 - age)
2655    }
2656
2657    pub fn get_blockhash_last_valid_block_height(&self, blockhash: &Hash) -> Option<Slot> {
2658        let blockhash_queue = self.blockhash_queue.read().unwrap();
2659        // This calculation will need to be updated to consider epoch boundaries if BlockhashQueue
2660        // length is made variable by epoch
2661        blockhash_queue
2662            .get_hash_age(blockhash)
2663            .map(|age| self.block_height + blockhash_queue.len() as u64 - age)
2664    }
2665
2666    #[deprecated(
2667        since = "1.8.0",
2668        note = "Please use `confirmed_last_blockhash` and `get_fee_for_message` instead"
2669    )]
2670    pub fn confirmed_last_blockhash_with_fee_calculator(&self) -> (Hash, FeeCalculator) {
2671        const NUM_BLOCKHASH_CONFIRMATIONS: usize = 3;
2672
2673        let parents = self.parents();
2674        if parents.is_empty() {
2675            #[allow(deprecated)]
2676            self.last_blockhash_with_fee_calculator()
2677        } else {
2678            let index = NUM_BLOCKHASH_CONFIRMATIONS.min(parents.len() - 1);
2679            #[allow(deprecated)]
2680            parents[index].last_blockhash_with_fee_calculator()
2681        }
2682    }
2683
2684    pub fn confirmed_last_blockhash(&self) -> Hash {
2685        const NUM_BLOCKHASH_CONFIRMATIONS: usize = 3;
2686
2687        let parents = self.parents();
2688        if parents.is_empty() {
2689            self.last_blockhash()
2690        } else {
2691            let index = NUM_BLOCKHASH_CONFIRMATIONS.min(parents.len() - 1);
2692            parents[index].last_blockhash()
2693        }
2694    }
2695
2696    /// Forget all signatures. Useful for benchmarking.
2697    pub fn clear_signatures(&self) {
2698        self.src.status_cache.write().unwrap().clear();
2699    }
2700
2701    pub fn clear_slot_signatures(&self, slot: Slot) {
2702        self.src
2703            .status_cache
2704            .write()
2705            .unwrap()
2706            .clear_slot_entries(slot);
2707    }
2708
2709    pub fn can_commit(result: &Result<()>) -> bool {
2710        match result {
2711            Ok(_) => true,
2712            Err(TransactionError::InstructionError(_, _)) => true,
2713            Err(_) => false,
2714        }
2715    }
2716
2717    fn update_transaction_statuses(
2718        &self,
2719        sanitized_txs: &[SanitizedTransaction],
2720        res: &[TransactionExecutionResult],
2721    ) {
2722        let mut status_cache = self.src.status_cache.write().unwrap();
2723        assert_eq!(sanitized_txs.len(), res.len());
2724        for (tx, (res, _nonce_rollback)) in sanitized_txs.iter().zip(res) {
2725            if Self::can_commit(res) {
2726                // Add the message hash to the status cache to ensure that this message
2727                // won't be processed again with a different signature.
2728                status_cache.insert(
2729                    tx.message().recent_blockhash(),
2730                    tx.message_hash(),
2731                    self.slot(),
2732                    res.clone(),
2733                );
2734                // Add the transaction signature to the status cache so that transaction status
2735                // can be queried by transaction signature over RPC. In the future, this should
2736                // only be added for API nodes because voting validators don't need to do this.
2737                status_cache.insert(
2738                    tx.message().recent_blockhash(),
2739                    tx.signature(),
2740                    self.slot(),
2741                    res.clone(),
2742                );
2743            }
2744        }
2745    }
2746
2747    /// Tell the bank which Entry IDs exist on the ledger. This function
2748    /// assumes subsequent calls correspond to later entries, and will boot
2749    /// the oldest ones once its internal cache is full. Once boot, the
2750    /// bank will reject transactions using that `hash`.
2751    pub fn register_tick(&self, hash: &Hash) {
2752        assert!(
2753            !self.freeze_started(),
2754            "register_tick() working on a bank that is already frozen or is undergoing freezing!"
2755        );
2756
2757        inc_new_counter_debug!("bank-register_tick-registered", 1);
2758        let mut w_blockhash_queue = self.blockhash_queue.write().unwrap();
2759        if self.is_block_boundary(self.tick_height.load(Relaxed) + 1) {
2760            w_blockhash_queue.register_hash(hash, &self.fee_calculator);
2761            self.update_recent_blockhashes_locked(&w_blockhash_queue);
2762        }
2763        // ReplayStage will start computing the accounts delta hash when it
2764        // detects the tick height has reached the boundary, so the system
2765        // needs to guarantee all account updates for the slot have been
2766        // committed before this tick height is incremented (like the blockhash
2767        // sysvar above)
2768        self.tick_height.fetch_add(1, Relaxed);
2769    }
2770
2771    pub fn is_complete(&self) -> bool {
2772        self.tick_height() == self.max_tick_height()
2773    }
2774
2775    pub fn is_block_boundary(&self, tick_height: u64) -> bool {
2776        tick_height % self.ticks_per_slot == 0
2777    }
2778
2779    /// Prepare a transaction batch from a list of legacy transactionsy. Used for tests only.
2780    pub fn prepare_batch(&self, txs: Vec<Transaction>) -> Result<TransactionBatch> {
2781        let sanitized_txs = txs
2782            .into_iter()
2783            .map(SanitizedTransaction::try_from)
2784            .collect::<Result<Vec<_>>>()?;
2785        let lock_results = self
2786            .rc
2787            .accounts
2788            .lock_accounts(sanitized_txs.iter(), self.demote_program_write_locks());
2789        Ok(TransactionBatch::new(
2790            lock_results,
2791            self,
2792            Cow::Owned(sanitized_txs),
2793        ))
2794    }
2795
2796    /// Prepare a transaction batch from a list of versioned transactions from
2797    /// an entry. Used for tests only.
2798    pub fn prepare_entry_batch(&self, txs: Vec<VersionedTransaction>) -> Result<TransactionBatch> {
2799        let sanitized_txs = txs
2800            .into_iter()
2801            .map(|tx| {
2802                let message_hash = tx.message.hash();
2803                SanitizedTransaction::try_create(tx, message_hash, |_| {
2804                    Err(TransactionError::UnsupportedVersion)
2805                })
2806            })
2807            .collect::<Result<Vec<_>>>()?;
2808        let lock_results = self
2809            .rc
2810            .accounts
2811            .lock_accounts(sanitized_txs.iter(), self.demote_program_write_locks());
2812        Ok(TransactionBatch::new(
2813            lock_results,
2814            self,
2815            Cow::Owned(sanitized_txs),
2816        ))
2817    }
2818
2819    /// Prepare a locked transaction batch from a list of sanitized transactions.
2820    pub fn prepare_sanitized_batch<'a, 'b>(
2821        &'a self,
2822        txs: &'b [SanitizedTransaction],
2823    ) -> TransactionBatch<'a, 'b> {
2824        let lock_results = self
2825            .rc
2826            .accounts
2827            .lock_accounts(txs.iter(), self.demote_program_write_locks());
2828        TransactionBatch::new(lock_results, self, Cow::Borrowed(txs))
2829    }
2830
2831    /// Prepare a transaction batch without locking accounts for transaction simulation.
2832    pub(crate) fn prepare_simulation_batch<'a>(
2833        &'a self,
2834        transaction: SanitizedTransaction,
2835    ) -> TransactionBatch<'a, '_> {
2836        let mut batch = TransactionBatch::new(vec![Ok(())], self, Cow::Owned(vec![transaction]));
2837        batch.needs_unlock = false;
2838        batch
2839    }
2840
2841    /// Run transactions against a frozen bank without committing the results
2842    pub fn simulate_transaction(
2843        &self,
2844        transaction: SanitizedTransaction,
2845    ) -> TransactionSimulationResult {
2846        assert!(self.is_frozen(), "simulation bank must be frozen");
2847
2848        let number_of_accounts = transaction.message().account_keys_len();
2849        let batch = self.prepare_simulation_batch(transaction);
2850        let mut timings = ExecuteTimings::default();
2851
2852        let (
2853            loaded_transactions,
2854            executed,
2855            _inner_instructions,
2856            logs,
2857            _retryable_transactions,
2858            _transaction_count,
2859            _signature_count,
2860        ) = self.load_and_execute_transactions(
2861            &batch,
2862            // After simulation, transactions will need to be forwarded to the leader
2863            // for processing. During forwarding, the transaction could expire if the
2864            // delay is not accounted for.
2865            MAX_PROCESSING_AGE - MAX_TRANSACTION_FORWARDING_DELAY,
2866            false,
2867            true,
2868            &mut timings,
2869        );
2870
2871        let result = executed[0].0.clone().map(|_| ());
2872        let logs = logs.get(0).cloned().flatten().unwrap_or_default();
2873        let post_simulation_accounts = loaded_transactions
2874            .into_iter()
2875            .next()
2876            .unwrap()
2877            .0
2878            .ok()
2879            .map(|loaded_transaction| {
2880                loaded_transaction
2881                    .accounts
2882                    .into_iter()
2883                    .take(number_of_accounts)
2884                    .collect::<Vec<_>>()
2885            })
2886            .unwrap_or_default();
2887
2888        let units_consumed = timings
2889            .details
2890            .per_program_timings
2891            .iter()
2892            .fold(0, |acc: u64, (_, program_timing)| {
2893                acc.saturating_add(program_timing.accumulated_units)
2894            });
2895
2896        debug!("simulate_transaction: {:?}", timings);
2897
2898        TransactionSimulationResult {
2899            result,
2900            logs,
2901            post_simulation_accounts,
2902            units_consumed,
2903        }
2904    }
2905
2906    pub fn unlock_accounts(&self, batch: &mut TransactionBatch) {
2907        if batch.needs_unlock {
2908            batch.needs_unlock = false;
2909            self.rc.accounts.unlock_accounts(
2910                batch.sanitized_transactions().iter(),
2911                batch.lock_results(),
2912                self.demote_program_write_locks(),
2913            )
2914        }
2915    }
2916
2917    pub fn remove_unrooted_slots(&self, slots: &[(Slot, BankId)]) {
2918        self.rc.accounts.accounts_db.remove_unrooted_slots(slots)
2919    }
2920
2921    pub fn set_shrink_paths(&self, paths: Vec<PathBuf>) {
2922        self.rc.accounts.accounts_db.set_shrink_paths(paths);
2923    }
2924
2925    fn check_age<'a>(
2926        &self,
2927        txs: impl Iterator<Item = &'a SanitizedTransaction>,
2928        lock_results: &[Result<()>],
2929        max_age: usize,
2930        error_counters: &mut ErrorCounters,
2931    ) -> Vec<TransactionCheckResult> {
2932        let hash_queue = self.blockhash_queue.read().unwrap();
2933        txs.zip(lock_results)
2934            .map(|(tx, lock_res)| match lock_res {
2935                Ok(()) => {
2936                    let recent_blockhash = tx.message().recent_blockhash();
2937                    let hash_age = hash_queue.check_hash_age(recent_blockhash, max_age);
2938                    if hash_age == Some(true) {
2939                        (Ok(()), None)
2940                    } else if let Some((pubkey, acc)) = self.check_tx_durable_nonce(tx) {
2941                        (Ok(()), Some(NonceRollbackPartial::new(pubkey, acc)))
2942                    } else if hash_age == Some(false) {
2943                        error_counters.blockhash_too_old += 1;
2944                        (Err(TransactionError::BlockhashNotFound), None)
2945                    } else {
2946                        error_counters.blockhash_not_found += 1;
2947                        (Err(TransactionError::BlockhashNotFound), None)
2948                    }
2949                }
2950                Err(e) => (Err(e.clone()), None),
2951            })
2952            .collect()
2953    }
2954
2955    fn is_tx_already_processed(
2956        &self,
2957        sanitized_tx: &SanitizedTransaction,
2958        status_cache: &StatusCache<Result<()>>,
2959    ) -> bool {
2960        let key = sanitized_tx.message_hash();
2961        let transaction_blockhash = sanitized_tx.message().recent_blockhash();
2962        status_cache
2963            .get_status(key, transaction_blockhash, &self.ancestors)
2964            .is_some()
2965    }
2966
2967    fn check_status_cache(
2968        &self,
2969        sanitized_txs: &[SanitizedTransaction],
2970        lock_results: Vec<TransactionCheckResult>,
2971        error_counters: &mut ErrorCounters,
2972    ) -> Vec<TransactionCheckResult> {
2973        let rcache = self.src.status_cache.read().unwrap();
2974        sanitized_txs
2975            .iter()
2976            .zip(lock_results)
2977            .map(|(sanitized_tx, (lock_res, nonce_rollback))| {
2978                if lock_res.is_ok() && self.is_tx_already_processed(sanitized_tx, &rcache) {
2979                    error_counters.already_processed += 1;
2980                    return (Err(TransactionError::AlreadyProcessed), None);
2981                }
2982
2983                (lock_res, nonce_rollback)
2984            })
2985            .collect()
2986    }
2987
2988    fn filter_by_vote_transactions<'a>(
2989        &self,
2990        txs: impl Iterator<Item = &'a SanitizedTransaction>,
2991        lock_results: Vec<TransactionCheckResult>,
2992        error_counters: &mut ErrorCounters,
2993    ) -> Vec<TransactionCheckResult> {
2994        txs.zip(lock_results)
2995            .map(|(tx, lock_res)| {
2996                if lock_res.0.is_ok() {
2997                    if is_simple_vote_transaction(tx) {
2998                        return lock_res;
2999                    }
3000
3001                    error_counters.not_allowed_during_cluster_maintenance += 1;
3002                    return (Err(TransactionError::ClusterMaintenance), lock_res.1);
3003                }
3004                lock_res
3005            })
3006            .collect()
3007    }
3008
3009    pub fn check_hash_age(&self, hash: &Hash, max_age: usize) -> Option<bool> {
3010        self.blockhash_queue
3011            .read()
3012            .unwrap()
3013            .check_hash_age(hash, max_age)
3014    }
3015
3016    pub fn check_tx_durable_nonce(
3017        &self,
3018        tx: &SanitizedTransaction,
3019    ) -> Option<(Pubkey, AccountSharedData)> {
3020        tx.get_durable_nonce()
3021            .and_then(|nonce_pubkey| {
3022                self.get_account(nonce_pubkey)
3023                    .map(|acc| (*nonce_pubkey, acc))
3024            })
3025            .filter(|(_pubkey, nonce_account)| {
3026                nonce_account::verify_nonce_account(nonce_account, tx.message().recent_blockhash())
3027            })
3028    }
3029
3030    // Determine if the bank is currently in an upgrade epoch, where only votes are permitted
3031    fn upgrade_epoch(&self) -> bool {
3032        match self.cluster_type() {
3033            #[cfg(test)]
3034            ClusterType::Development => self.epoch == 0xdead, // Value assumed by `test_upgrade_epoch()`
3035            #[cfg(not(test))]
3036            ClusterType::Development => false,
3037            ClusterType::Devnet => false,
3038            ClusterType::Testnet => false,
3039            ClusterType::MainnetBeta => self.epoch == 61,
3040        }
3041    }
3042
3043    pub fn check_transactions(
3044        &self,
3045        sanitized_txs: &[SanitizedTransaction],
3046        lock_results: &[Result<()>],
3047        max_age: usize,
3048        mut error_counters: &mut ErrorCounters,
3049    ) -> Vec<TransactionCheckResult> {
3050        let age_results = self.check_age(
3051            sanitized_txs.iter(),
3052            lock_results,
3053            max_age,
3054            &mut error_counters,
3055        );
3056        let cache_results =
3057            self.check_status_cache(sanitized_txs, age_results, &mut error_counters);
3058        if self.upgrade_epoch() {
3059            // Reject all non-vote transactions
3060            self.filter_by_vote_transactions(
3061                sanitized_txs.iter(),
3062                cache_results,
3063                &mut error_counters,
3064            )
3065        } else {
3066            cache_results
3067        }
3068    }
3069
3070    pub fn collect_balances(&self, batch: &TransactionBatch) -> TransactionBalances {
3071        let mut balances: TransactionBalances = vec![];
3072        for transaction in batch.sanitized_transactions() {
3073            let mut transaction_balances: Vec<u64> = vec![];
3074            for account_key in transaction.message().account_keys_iter() {
3075                transaction_balances.push(self.get_balance(account_key));
3076            }
3077            balances.push(transaction_balances);
3078        }
3079        balances
3080    }
3081
3082    #[allow(clippy::cognitive_complexity)]
3083    fn update_error_counters(error_counters: &ErrorCounters) {
3084        if 0 != error_counters.total {
3085            inc_new_counter_info!(
3086                "bank-process_transactions-error_count",
3087                error_counters.total
3088            );
3089        }
3090        if 0 != error_counters.account_not_found {
3091            inc_new_counter_info!(
3092                "bank-process_transactions-account_not_found",
3093                error_counters.account_not_found
3094            );
3095        }
3096        if 0 != error_counters.account_in_use {
3097            inc_new_counter_info!(
3098                "bank-process_transactions-account_in_use",
3099                error_counters.account_in_use
3100            );
3101        }
3102        if 0 != error_counters.account_loaded_twice {
3103            inc_new_counter_info!(
3104                "bank-process_transactions-account_loaded_twice",
3105                error_counters.account_loaded_twice
3106            );
3107        }
3108        if 0 != error_counters.blockhash_not_found {
3109            inc_new_counter_info!(
3110                "bank-process_transactions-error-blockhash_not_found",
3111                error_counters.blockhash_not_found
3112            );
3113        }
3114        if 0 != error_counters.blockhash_too_old {
3115            inc_new_counter_info!(
3116                "bank-process_transactions-error-blockhash_too_old",
3117                error_counters.blockhash_too_old
3118            );
3119        }
3120        if 0 != error_counters.invalid_account_index {
3121            inc_new_counter_info!(
3122                "bank-process_transactions-error-invalid_account_index",
3123                error_counters.invalid_account_index
3124            );
3125        }
3126        if 0 != error_counters.invalid_account_for_fee {
3127            inc_new_counter_info!(
3128                "bank-process_transactions-error-invalid_account_for_fee",
3129                error_counters.invalid_account_for_fee
3130            );
3131        }
3132        if 0 != error_counters.insufficient_funds {
3133            inc_new_counter_info!(
3134                "bank-process_transactions-error-insufficient_funds",
3135                error_counters.insufficient_funds
3136            );
3137        }
3138        if 0 != error_counters.instruction_error {
3139            inc_new_counter_info!(
3140                "bank-process_transactions-error-instruction_error",
3141                error_counters.instruction_error
3142            );
3143        }
3144        if 0 != error_counters.already_processed {
3145            inc_new_counter_info!(
3146                "bank-process_transactions-error-already_processed",
3147                error_counters.already_processed
3148            );
3149        }
3150        if 0 != error_counters.not_allowed_during_cluster_maintenance {
3151            inc_new_counter_info!(
3152                "bank-process_transactions-error-cluster-maintenance",
3153                error_counters.not_allowed_during_cluster_maintenance
3154            );
3155        }
3156        if 0 != error_counters.invalid_writable_account {
3157            inc_new_counter_info!(
3158                "bank-process_transactions-error-invalid_writable_account",
3159                error_counters.invalid_writable_account
3160            );
3161        }
3162    }
3163
3164    /// Converts Accounts into RefCell<AccountSharedData>, this involves moving
3165    /// ownership by draining the source
3166    fn accounts_to_refcells(accounts: &mut TransactionAccounts) -> TransactionAccountRefCells {
3167        let account_refcells: Vec<_> = accounts
3168            .drain(..)
3169            .map(|(pubkey, account)| (pubkey, Rc::new(RefCell::new(account))))
3170            .collect();
3171        account_refcells
3172    }
3173
3174    /// Converts back from RefCell<AccountSharedData> to AccountSharedData, this involves moving
3175    /// ownership by draining the sources
3176    fn refcells_to_accounts(
3177        accounts: &mut TransactionAccounts,
3178        mut account_refcells: TransactionAccountRefCells,
3179    ) -> std::result::Result<(), TransactionError> {
3180        for (pubkey, account_refcell) in account_refcells.drain(..) {
3181            accounts.push((
3182                pubkey,
3183                Rc::try_unwrap(account_refcell)
3184                    .map_err(|_| TransactionError::AccountBorrowOutstanding)?
3185                    .into_inner(),
3186            ))
3187        }
3188
3189        Ok(())
3190    }
3191
3192    fn collect_log_messages(
3193        log_collector: Option<Rc<LogCollector>>,
3194    ) -> Option<TransactionLogMessages> {
3195        log_collector.and_then(|log_collector| Rc::try_unwrap(log_collector).map(Into::into).ok())
3196    }
3197
3198    fn compile_recorded_instructions(
3199        instruction_recorders: Option<Vec<InstructionRecorder>>,
3200        message: &SanitizedMessage,
3201    ) -> Option<InnerInstructionsList> {
3202        instruction_recorders.and_then(|instruction_recorders| {
3203            instruction_recorders
3204                .into_iter()
3205                .map(|r| r.compile_instructions(message))
3206                .collect()
3207        })
3208    }
3209
3210    /// Get any cached executors needed by the transaction
3211    fn get_executors(
3212        &self,
3213        message: &SanitizedMessage,
3214        accounts: &[(Pubkey, AccountSharedData)],
3215        program_indices: &[Vec<usize>],
3216    ) -> Rc<RefCell<Executors>> {
3217        let mut num_executors = message.account_keys_len();
3218        for program_indices_of_instruction in program_indices.iter() {
3219            num_executors += program_indices_of_instruction.len();
3220        }
3221        let mut executors = HashMap::with_capacity(num_executors);
3222        let cow_cache = self.cached_executors.read().unwrap();
3223        let cache = cow_cache.read().unwrap();
3224
3225        for key in message.account_keys_iter() {
3226            if let Some(executor) = cache.get(key) {
3227                executors.insert(*key, executor);
3228            }
3229        }
3230        for program_indices_of_instruction in program_indices.iter() {
3231            for account_index in program_indices_of_instruction.iter() {
3232                let key = accounts[*account_index].0;
3233                if let Some(executor) = cache.get(&key) {
3234                    executors.insert(key, executor);
3235                }
3236            }
3237        }
3238
3239        Rc::new(RefCell::new(Executors {
3240            executors,
3241            is_dirty: false,
3242        }))
3243    }
3244
3245    /// Add executors back to the bank's cache if modified
3246    fn update_executors(&self, executors: Rc<RefCell<Executors>>) {
3247        let executors = executors.borrow();
3248        if executors.is_dirty {
3249            let mut cow_cache = self.cached_executors.write().unwrap();
3250            let mut cache = cow_cache.write().unwrap();
3251            for (key, executor) in executors.executors.iter() {
3252                cache.put(key, (*executor).clone());
3253            }
3254        }
3255    }
3256
3257    /// Remove an executor from the bank's cache
3258    pub fn remove_executor(&self, pubkey: &Pubkey) {
3259        let mut cow_cache = self.cached_executors.write().unwrap();
3260        let mut cache = cow_cache.write().unwrap();
3261        cache.remove(pubkey);
3262    }
3263
3264    #[allow(clippy::type_complexity)]
3265    pub fn load_and_execute_transactions(
3266        &self,
3267        batch: &TransactionBatch,
3268        max_age: usize,
3269        enable_cpi_recording: bool,
3270        enable_log_recording: bool,
3271        timings: &mut ExecuteTimings,
3272    ) -> (
3273        Vec<TransactionLoadResult>,
3274        Vec<TransactionExecutionResult>,
3275        Vec<Option<InnerInstructionsList>>,
3276        Vec<Option<TransactionLogMessages>>,
3277        Vec<usize>,
3278        u64,
3279        u64,
3280    ) {
3281        let sanitized_txs = batch.sanitized_transactions();
3282        debug!("processing transactions: {}", sanitized_txs.len());
3283        inc_new_counter_info!("bank-process_transactions", sanitized_txs.len());
3284        let mut error_counters = ErrorCounters::default();
3285
3286        let retryable_txs: Vec<_> = batch
3287            .lock_results()
3288            .iter()
3289            .enumerate()
3290            .filter_map(|(index, res)| match res {
3291                Err(TransactionError::AccountInUse) => {
3292                    error_counters.account_in_use += 1;
3293                    Some(index)
3294                }
3295                Err(_) => None,
3296                Ok(_) => None,
3297            })
3298            .collect();
3299
3300        let mut check_time = Measure::start("check_transactions");
3301        let check_results = self.check_transactions(
3302            sanitized_txs,
3303            batch.lock_results(),
3304            max_age,
3305            &mut error_counters,
3306        );
3307        check_time.stop();
3308
3309        let mut load_time = Measure::start("accounts_load");
3310        let mut loaded_txs = self.rc.accounts.load_accounts(
3311            &self.ancestors,
3312            sanitized_txs,
3313            check_results,
3314            &self.blockhash_queue.read().unwrap(),
3315            &mut error_counters,
3316            &self.rent_collector,
3317            &self.feature_set,
3318        );
3319        load_time.stop();
3320
3321        let mut execution_time = Measure::start("execution_time");
3322        let mut signature_count: u64 = 0;
3323        let mut inner_instructions: Vec<Option<InnerInstructionsList>> =
3324            Vec::with_capacity(sanitized_txs.len());
3325        let mut transaction_log_messages: Vec<Option<Vec<String>>> =
3326            Vec::with_capacity(sanitized_txs.len());
3327
3328        let executed: Vec<TransactionExecutionResult> = loaded_txs
3329            .iter_mut()
3330            .zip(sanitized_txs.iter())
3331            .map(|(accs, tx)| match accs {
3332                (Err(e), _nonce_rollback) => {
3333                    transaction_log_messages.push(None);
3334                    inner_instructions.push(None);
3335                    (Err(e.clone()), None)
3336                }
3337                (Ok(loaded_transaction), nonce_rollback) => {
3338                    let feature_set = self.feature_set.clone();
3339                    signature_count += u64::from(tx.message().header().num_required_signatures);
3340
3341                    let mut compute_budget = self.compute_budget.unwrap_or_else(ComputeBudget::new);
3342
3343                    let mut process_result = if feature_set.is_active(&tx_wide_compute_cap::id()) {
3344                        compute_budget.process_transaction(tx)
3345                    } else {
3346                        Ok(())
3347                    };
3348
3349                    if process_result.is_ok() {
3350                        let executors = self.get_executors(
3351                            tx.message(),
3352                            &loaded_transaction.accounts,
3353                            &loaded_transaction.program_indices,
3354                        );
3355
3356                        let account_refcells =
3357                            Self::accounts_to_refcells(&mut loaded_transaction.accounts);
3358
3359                        let instruction_recorders = if enable_cpi_recording {
3360                            let ix_count = tx.message().instructions().len();
3361                            let mut recorders = Vec::with_capacity(ix_count);
3362                            recorders.resize_with(ix_count, InstructionRecorder::default);
3363                            Some(recorders)
3364                        } else {
3365                            None
3366                        };
3367
3368                        let log_collector = if enable_log_recording {
3369                            Some(Rc::new(LogCollector::default()))
3370                        } else {
3371                            None
3372                        };
3373
3374                        let compute_meter = Rc::new(RefCell::new(TransactionComputeMeter::new(
3375                            compute_budget.max_units,
3376                        )));
3377
3378                        let (blockhash, fee_calculator) = {
3379                            let blockhash_queue = self.blockhash_queue.read().unwrap();
3380                            let blockhash = blockhash_queue.last_hash();
3381                            (
3382                                blockhash,
3383                                #[allow(deprecated)]
3384                                blockhash_queue
3385                                    .get_fee_calculator(&blockhash)
3386                                    .cloned()
3387                                    .unwrap_or_else(|| self.fee_calculator.clone()),
3388                            )
3389                        };
3390
3391                        if let Some(legacy_message) = tx.message().legacy_message() {
3392                            process_result = self.message_processor.process_message(
3393                                legacy_message,
3394                                &loaded_transaction.program_indices,
3395                                &account_refcells,
3396                                &self.rent_collector,
3397                                log_collector.clone(),
3398                                executors.clone(),
3399                                instruction_recorders.as_deref(),
3400                                feature_set,
3401                                compute_budget,
3402                                compute_meter,
3403                                &mut timings.details,
3404                                self.rc.accounts.clone(),
3405                                &self.ancestors,
3406                                blockhash,
3407                                fee_calculator,
3408                            );
3409                        } else {
3410                            // TODO: support versioned messages
3411                            process_result = Err(TransactionError::UnsupportedVersion);
3412                        }
3413
3414                        transaction_log_messages.push(Self::collect_log_messages(log_collector));
3415                        inner_instructions.push(Self::compile_recorded_instructions(
3416                            instruction_recorders,
3417                            tx.message(),
3418                        ));
3419
3420                        if let Err(e) = Self::refcells_to_accounts(
3421                            &mut loaded_transaction.accounts,
3422                            account_refcells,
3423                        ) {
3424                            warn!("Account lifetime mismanagement");
3425                            process_result = Err(e);
3426                        }
3427
3428                        if process_result.is_ok() {
3429                            self.update_executors(executors);
3430                        }
3431                    } else {
3432                        transaction_log_messages.push(None);
3433                        inner_instructions.push(None);
3434                    }
3435
3436                    let nonce_rollback =
3437                        if let Err(TransactionError::InstructionError(_, _)) = &process_result {
3438                            error_counters.instruction_error += 1;
3439                            nonce_rollback.clone()
3440                        } else if process_result.is_err() {
3441                            None
3442                        } else {
3443                            nonce_rollback.clone()
3444                        };
3445                    (process_result, nonce_rollback)
3446                }
3447            })
3448            .collect();
3449
3450        execution_time.stop();
3451
3452        debug!(
3453            "check: {}us load: {}us execute: {}us txs_len={}",
3454            check_time.as_us(),
3455            load_time.as_us(),
3456            execution_time.as_us(),
3457            sanitized_txs.len(),
3458        );
3459        timings.check_us = timings.check_us.saturating_add(check_time.as_us());
3460        timings.load_us = timings.load_us.saturating_add(load_time.as_us());
3461        timings.execute_us = timings.execute_us.saturating_add(execution_time.as_us());
3462
3463        let mut tx_count: u64 = 0;
3464        let err_count = &mut error_counters.total;
3465        let transaction_log_collector_config =
3466            self.transaction_log_collector_config.read().unwrap();
3467
3468        for (i, ((r, _nonce_rollback), tx)) in executed.iter().zip(sanitized_txs).enumerate() {
3469            if let Some(debug_keys) = &self.transaction_debug_keys {
3470                for key in tx.message().account_keys_iter() {
3471                    if debug_keys.contains(key) {
3472                        info!("slot: {} result: {:?} tx: {:?}", self.slot, r, tx);
3473                        break;
3474                    }
3475                }
3476            }
3477
3478            if Self::can_commit(r) // Skip log collection for unprocessed transactions
3479                && transaction_log_collector_config.filter != TransactionLogCollectorFilter::None
3480            {
3481                let mut transaction_log_collector = self.transaction_log_collector.write().unwrap();
3482                let transaction_log_index = transaction_log_collector.logs.len();
3483
3484                let mut mentioned_address = false;
3485                if !transaction_log_collector_config
3486                    .mentioned_addresses
3487                    .is_empty()
3488                {
3489                    for key in tx.message().account_keys_iter() {
3490                        if transaction_log_collector_config
3491                            .mentioned_addresses
3492                            .contains(key)
3493                        {
3494                            transaction_log_collector
3495                                .mentioned_address_map
3496                                .entry(*key)
3497                                .or_default()
3498                                .push(transaction_log_index);
3499                            mentioned_address = true;
3500                        }
3501                    }
3502                }
3503
3504                let is_vote = is_simple_vote_transaction(tx);
3505                let store = match transaction_log_collector_config.filter {
3506                    TransactionLogCollectorFilter::All => !is_vote || mentioned_address,
3507                    TransactionLogCollectorFilter::AllWithVotes => true,
3508                    TransactionLogCollectorFilter::None => false,
3509                    TransactionLogCollectorFilter::OnlyMentionedAddresses => mentioned_address,
3510                };
3511
3512                if store {
3513                    if let Some(log_messages) = transaction_log_messages.get(i).cloned().flatten() {
3514                        transaction_log_collector.logs.push(TransactionLogInfo {
3515                            signature: *tx.signature(),
3516                            result: r.clone(),
3517                            is_vote,
3518                            log_messages,
3519                        });
3520                    }
3521                }
3522            }
3523
3524            if r.is_ok() {
3525                tx_count += 1;
3526            } else {
3527                if *err_count == 0 {
3528                    debug!("tx error: {:?} {:?}", r, tx);
3529                }
3530                *err_count += 1;
3531            }
3532        }
3533        if *err_count > 0 {
3534            debug!(
3535                "{} errors of {} txs",
3536                *err_count,
3537                *err_count as u64 + tx_count
3538            );
3539        }
3540        Self::update_error_counters(&error_counters);
3541        (
3542            loaded_txs,
3543            executed,
3544            inner_instructions,
3545            transaction_log_messages,
3546            retryable_txs,
3547            tx_count,
3548            signature_count,
3549        )
3550    }
3551
3552    fn filter_program_errors_and_collect_fee(
3553        &self,
3554        txs: &[SanitizedTransaction],
3555        executed: &[TransactionExecutionResult],
3556    ) -> Vec<Result<()>> {
3557        let hash_queue = self.blockhash_queue.read().unwrap();
3558        let mut fees = 0;
3559
3560        let results = txs
3561            .iter()
3562            .zip(executed)
3563            .map(|(tx, (res, nonce_rollback))| {
3564                let (fee_calculator, is_durable_nonce) = nonce_rollback
3565                    .as_ref()
3566                    .map(|nonce_rollback| nonce_rollback.fee_calculator())
3567                    .map(|maybe_fee_calculator| (maybe_fee_calculator, true))
3568                    .unwrap_or_else(|| {
3569                        (
3570                            #[allow(deprecated)]
3571                            hash_queue
3572                                .get_fee_calculator(tx.message().recent_blockhash())
3573                                .cloned(),
3574                            false,
3575                        )
3576                    });
3577
3578                let fee_calculator = fee_calculator.ok_or(TransactionError::BlockhashNotFound)?;
3579                let fee = tx.message().calculate_fee(&fee_calculator);
3580
3581                match *res {
3582                    Err(TransactionError::InstructionError(_, _)) => {
3583                        // credit the transaction fee even in case of InstructionError
3584                        // necessary to withdraw from account[0] here because previous
3585                        // work of doing so (in accounts.load()) is ignored by store_account()
3586                        //
3587                        // ...except nonce accounts, which will have their post-load,
3588                        // pre-execute account state stored
3589                        if !is_durable_nonce {
3590                            self.withdraw(tx.message().fee_payer(), fee)?;
3591                        }
3592                        fees += fee;
3593                        Ok(())
3594                    }
3595                    Ok(()) => {
3596                        fees += fee;
3597                        Ok(())
3598                    }
3599                    _ => res.clone(),
3600                }
3601            })
3602            .collect();
3603
3604        self.collector_fees.fetch_add(fees, Relaxed);
3605        results
3606    }
3607
3608    pub fn commit_transactions(
3609        &self,
3610        sanitized_txs: &[SanitizedTransaction],
3611        loaded_txs: &mut [TransactionLoadResult],
3612        executed: &[TransactionExecutionResult],
3613        tx_count: u64,
3614        signature_count: u64,
3615        timings: &mut ExecuteTimings,
3616    ) -> TransactionResults {
3617        assert!(
3618            !self.freeze_started(),
3619            "commit_transactions() working on a bank that is already frozen or is undergoing freezing!"
3620        );
3621
3622        self.increment_transaction_count(tx_count);
3623        self.increment_signature_count(signature_count);
3624
3625        inc_new_counter_info!("bank-process_transactions-txs", tx_count as usize);
3626        inc_new_counter_info!("bank-process_transactions-sigs", signature_count as usize);
3627
3628        if !sanitized_txs.is_empty() {
3629            let processed_tx_count = sanitized_txs.len() as u64;
3630            let failed_tx_count = processed_tx_count.saturating_sub(tx_count);
3631            self.transaction_error_count
3632                .fetch_add(failed_tx_count, Relaxed);
3633            self.transaction_entries_count.fetch_add(1, Relaxed);
3634            self.transactions_per_entry_max
3635                .fetch_max(processed_tx_count, Relaxed);
3636        }
3637
3638        if executed
3639            .iter()
3640            .any(|(res, _nonce_rollback)| Self::can_commit(res))
3641        {
3642            self.is_delta.store(true, Relaxed);
3643        }
3644
3645        let mut write_time = Measure::start("write_time");
3646        #[allow(deprecated)]
3647        self.rc.accounts.store_cached(
3648            self.slot(),
3649            sanitized_txs,
3650            executed,
3651            loaded_txs,
3652            &self.rent_collector,
3653            &self.last_blockhash_with_fee_calculator(),
3654            self.rent_for_sysvars(),
3655            self.merge_nonce_error_into_system_error(),
3656            self.demote_program_write_locks(),
3657        );
3658        let rent_debits = self.collect_rent(executed, loaded_txs);
3659
3660        let overwritten_vote_accounts =
3661            self.update_cached_accounts(sanitized_txs, executed, loaded_txs);
3662
3663        // once committed there is no way to unroll
3664        write_time.stop();
3665        debug!(
3666            "store: {}us txs_len={}",
3667            write_time.as_us(),
3668            sanitized_txs.len()
3669        );
3670        timings.store_us = timings.store_us.saturating_add(write_time.as_us());
3671        self.update_transaction_statuses(sanitized_txs, executed);
3672        let fee_collection_results =
3673            self.filter_program_errors_and_collect_fee(sanitized_txs, executed);
3674
3675        TransactionResults {
3676            fee_collection_results,
3677            execution_results: executed.to_vec(),
3678            overwritten_vote_accounts,
3679            rent_debits,
3680        }
3681    }
3682
3683    // Distribute collected rent fees for this slot to staked validators (excluding stakers)
3684    // according to stake.
3685    //
3686    // The nature of rent fee is the cost of doing business, every validator has to hold (or have
3687    // access to) the same list of accounts, so we pay according to stake, which is a rough proxy for
3688    // value to the network.
3689    //
3690    // Currently, rent distribution doesn't consider given validator's uptime at all (this might
3691    // change). That's because rent should be rewarded for the storage resource utilization cost.
3692    // It's treated differently from transaction fees, which is for the computing resource
3693    // utilization cost.
3694    //
3695    // We can't use collector_id (which is rotated according to stake-weighted leader schedule)
3696    // as an approximation to the ideal rent distribution to simplify and avoid this per-slot
3697    // computation for the distribution (time: N log N, space: N acct. stores; N = # of
3698    // validators).
3699    // The reason is that rent fee doesn't need to be incentivized for throughput unlike transaction
3700    // fees
3701    //
3702    // Ref: collect_fees
3703    #[allow(clippy::needless_collect)]
3704    fn distribute_rent_to_validators(
3705        &self,
3706        vote_accounts: &HashMap<Pubkey, (/*stake:*/ u64, VoteAccount)>,
3707        rent_to_be_distributed: u64,
3708    ) {
3709        let mut total_staked = 0;
3710
3711        // Collect the stake associated with each validator.
3712        // Note that a validator may be present in this vector multiple times if it happens to have
3713        // more than one staked vote account somehow
3714        let mut validator_stakes = vote_accounts
3715            .iter()
3716            .filter_map(|(_vote_pubkey, (staked, account))| {
3717                if *staked == 0 {
3718                    None
3719                } else {
3720                    total_staked += *staked;
3721                    let node_pubkey = account.vote_state().as_ref().ok()?.node_pubkey;
3722                    Some((node_pubkey, *staked))
3723                }
3724            })
3725            .collect::<Vec<(Pubkey, u64)>>();
3726
3727        #[cfg(test)]
3728        if validator_stakes.is_empty() {
3729            // some tests bank.freezes() with bad staking state
3730            self.capitalization
3731                .fetch_sub(rent_to_be_distributed, Relaxed);
3732            return;
3733        }
3734        #[cfg(not(test))]
3735        assert!(!validator_stakes.is_empty());
3736
3737        // Sort first by stake and then by validator identity pubkey for determinism
3738        validator_stakes.sort_by(|(pubkey1, staked1), (pubkey2, staked2)| {
3739            match staked2.cmp(staked1) {
3740                std::cmp::Ordering::Equal => pubkey2.cmp(pubkey1),
3741                other => other,
3742            }
3743        });
3744
3745        let enforce_fix = self.no_overflow_rent_distribution_enabled();
3746
3747        let mut rent_distributed_in_initial_round = 0;
3748        let validator_rent_shares = validator_stakes
3749            .into_iter()
3750            .map(|(pubkey, staked)| {
3751                let rent_share = if !enforce_fix {
3752                    (((staked * rent_to_be_distributed) as f64) / (total_staked as f64)) as u64
3753                } else {
3754                    (((staked as u128) * (rent_to_be_distributed as u128)) / (total_staked as u128))
3755                        .try_into()
3756                        .unwrap()
3757                };
3758                rent_distributed_in_initial_round += rent_share;
3759                (pubkey, rent_share)
3760            })
3761            .collect::<Vec<(Pubkey, u64)>>();
3762
3763        // Leftover carats after fraction calculation, will be paid to validators starting from highest stake
3764        // holder
3765        let mut leftover_carats = rent_to_be_distributed - rent_distributed_in_initial_round;
3766
3767        let mut rewards = vec![];
3768        validator_rent_shares
3769            .into_iter()
3770            .for_each(|(pubkey, rent_share)| {
3771                let rent_to_be_paid = if leftover_carats > 0 {
3772                    leftover_carats -= 1;
3773                    rent_share + 1
3774                } else {
3775                    rent_share
3776                };
3777                if !enforce_fix || rent_to_be_paid > 0 {
3778                    let mut account = self
3779                        .get_account_with_fixed_root(&pubkey)
3780                        .unwrap_or_default();
3781                    if account.checked_add_carats(rent_to_be_paid).is_err() {
3782                        // overflow adding carats
3783                        self.capitalization.fetch_sub(rent_to_be_paid, Relaxed);
3784                        error!(
3785                            "Burned {} rent carats instead of sending to {}",
3786                            rent_to_be_paid, pubkey
3787                        );
3788                        inc_new_counter_error!(
3789                            "bank-burned_rent_carats",
3790                            rent_to_be_paid as usize
3791                        );
3792                    } else {
3793                        self.store_account(&pubkey, &account);
3794                        rewards.push((
3795                            pubkey,
3796                            RewardInfo {
3797                                reward_type: RewardType::Rent,
3798                                carats: rent_to_be_paid as i64,
3799                                post_balance: account.carats(),
3800                                commission: None,
3801                            },
3802                        ));
3803                    }
3804                }
3805            });
3806        self.rewards.write().unwrap().append(&mut rewards);
3807
3808        if enforce_fix {
3809            assert_eq!(leftover_carats, 0);
3810        } else if leftover_carats != 0 {
3811            warn!(
3812                "There was leftover from rent distribution: {}",
3813                leftover_carats
3814            );
3815            self.capitalization.fetch_sub(leftover_carats, Relaxed);
3816        }
3817    }
3818
3819    fn distribute_rent(&self) {
3820        let total_rent_collected = self.collected_rent.load(Relaxed);
3821
3822        let (burned_portion, rent_to_be_distributed) = self
3823            .rent_collector
3824            .rent
3825            .calculate_burn(total_rent_collected);
3826
3827        debug!(
3828            "distributed rent: {} (rounded from: {}, burned: {})",
3829            rent_to_be_distributed, total_rent_collected, burned_portion
3830        );
3831        self.capitalization.fetch_sub(burned_portion, Relaxed);
3832
3833        if rent_to_be_distributed == 0 {
3834            return;
3835        }
3836
3837        self.distribute_rent_to_validators(&self.vote_accounts(), rent_to_be_distributed);
3838    }
3839
3840    fn collect_rent(
3841        &self,
3842        res: &[TransactionExecutionResult],
3843        loaded_txs: &mut [TransactionLoadResult],
3844    ) -> Vec<RentDebits> {
3845        let mut collected_rent: u64 = 0;
3846        let mut rent_debits: Vec<RentDebits> = Vec::with_capacity(loaded_txs.len());
3847        for (i, (raccs, _nonce_rollback)) in loaded_txs.iter_mut().enumerate() {
3848            let (res, _nonce_rollback) = &res[i];
3849            if res.is_err() || raccs.is_err() {
3850                rent_debits.push(RentDebits::default());
3851                continue;
3852            }
3853
3854            let loaded_transaction = raccs.as_mut().unwrap();
3855
3856            collected_rent += loaded_transaction.rent;
3857            rent_debits.push(mem::take(&mut loaded_transaction.rent_debits));
3858        }
3859
3860        self.collected_rent.fetch_add(collected_rent, Relaxed);
3861        rent_debits
3862    }
3863
3864    fn run_incinerator(&self) {
3865        if let Some((account, _)) =
3866            self.get_account_modified_since_parent_with_fixed_root(&incinerator::id())
3867        {
3868            self.capitalization.fetch_sub(account.carats(), Relaxed);
3869            self.store_account(&incinerator::id(), &AccountSharedData::default());
3870        }
3871    }
3872
3873    fn collect_rent_eagerly(&self) {
3874        if !self.enable_eager_rent_collection() {
3875            return;
3876        }
3877
3878        let mut measure = Measure::start("collect_rent_eagerly-ms");
3879        let partitions = self.rent_collection_partitions();
3880        let count = partitions.len();
3881        let account_count: usize = partitions
3882            .into_iter()
3883            .map(|partition| self.collect_rent_in_partition(partition))
3884            .sum();
3885        measure.stop();
3886        datapoint_info!(
3887            "collect_rent_eagerly",
3888            ("accounts", account_count, i64),
3889            ("partitions", count, i64)
3890        );
3891        inc_new_counter_info!("collect_rent_eagerly-ms", measure.as_ms() as usize);
3892    }
3893
3894    #[cfg(test)]
3895    fn restore_old_behavior_for_fragile_tests(&self) {
3896        self.lazy_rent_collection.store(true, Relaxed);
3897    }
3898
3899    fn enable_eager_rent_collection(&self) -> bool {
3900        if self.lazy_rent_collection.load(Relaxed) {
3901            return false;
3902        }
3903
3904        true
3905    }
3906
3907    fn rent_collection_partitions(&self) -> Vec<Partition> {
3908        if !self.use_fixed_collection_cycle() {
3909            // This mode is for production/development/testing.
3910            // In this mode, we iterate over the whole pubkey value range for each epochs
3911            // including warm-up epochs.
3912            // The only exception is the situation where normal epochs are relatively short
3913            // (currently less than 2 day). In that case, we arrange a single collection
3914            // cycle to be multiple of epochs so that a cycle could be greater than the 2 day.
3915            self.variable_cycle_partitions()
3916        } else {
3917            // This mode is mainly for benchmarking only.
3918            // In this mode, we always iterate over the whole pubkey value range with
3919            // <slot_count_in_two_day> slots as a collection cycle, regardless warm-up or
3920            // alignment between collection cycles and epochs.
3921            // Thus, we can simulate stable processing load of eager rent collection,
3922            // strictly proportional to the number of pubkeys since genesis.
3923            self.fixed_cycle_partitions()
3924        }
3925    }
3926
3927    fn collect_rent_in_partition(&self, partition: Partition) -> usize {
3928        let subrange = Self::pubkey_range_from_partition(partition);
3929
3930        self.rc.accounts.hold_range_in_memory(&subrange, true);
3931
3932        let accounts = self
3933            .rc
3934            .accounts
3935            .load_to_collect_rent_eagerly(&self.ancestors, subrange.clone());
3936        let account_count = accounts.len();
3937
3938        // parallelize?
3939        let rent_for_sysvars = self.rent_for_sysvars();
3940        let mut total_rent = 0;
3941        let mut rent_debits = RentDebits::default();
3942        for (pubkey, mut account) in accounts {
3943            let rent = self.rent_collector.collect_from_existing_account(
3944                &pubkey,
3945                &mut account,
3946                rent_for_sysvars,
3947            );
3948            total_rent += rent;
3949            // Store all of them unconditionally to purge old AppendVec,
3950            // even if collected rent is 0 (= not updated).
3951            // Also, there's another subtle side-effect from this: this
3952            // ensures we verify the whole on-chain state (= all accounts)
3953            // via the account delta hash slowly once per an epoch.
3954            self.store_account(&pubkey, &account);
3955            rent_debits.push(&pubkey, rent, account.carats());
3956        }
3957        self.collected_rent.fetch_add(total_rent, Relaxed);
3958        self.rewards.write().unwrap().append(&mut rent_debits.0);
3959
3960        self.rc.accounts.hold_range_in_memory(&subrange, false);
3961        account_count
3962    }
3963
3964    // Mostly, the pair (start_index & end_index) is equivalent to this range:
3965    // start_index..=end_index. But it has some exceptional cases, including
3966    // this important and valid one:
3967    //   0..=0: the first partition in the new epoch when crossing epochs
3968    fn pubkey_range_from_partition(
3969        (start_index, end_index, partition_count): Partition,
3970    ) -> RangeInclusive<Pubkey> {
3971        assert!(start_index <= end_index);
3972        assert!(start_index < partition_count);
3973        assert!(end_index < partition_count);
3974        assert!(0 < partition_count);
3975
3976        type Prefix = u64;
3977        const PREFIX_SIZE: usize = mem::size_of::<Prefix>();
3978        const PREFIX_MAX: Prefix = Prefix::max_value();
3979
3980        let mut start_pubkey = [0x00u8; 32];
3981        let mut end_pubkey = [0xffu8; 32];
3982
3983        if partition_count == 1 {
3984            assert_eq!(start_index, 0);
3985            assert_eq!(end_index, 0);
3986            return Pubkey::new_from_array(start_pubkey)..=Pubkey::new_from_array(end_pubkey);
3987        }
3988
3989        // not-overflowing way of `(Prefix::max_value() + 1) / partition_count`
3990        let partition_width = (PREFIX_MAX - partition_count + 1) / partition_count + 1;
3991        let mut start_key_prefix = if start_index == 0 && end_index == 0 {
3992            0
3993        } else if start_index + 1 == partition_count {
3994            PREFIX_MAX
3995        } else {
3996            (start_index + 1) * partition_width
3997        };
3998
3999        let mut end_key_prefix = if end_index + 1 == partition_count {
4000            PREFIX_MAX
4001        } else {
4002            (end_index + 1) * partition_width - 1
4003        };
4004
4005        if start_index != 0 && start_index == end_index {
4006            // n..=n (n != 0): a noop pair across epochs without a gap under
4007            // multi_epoch_cycle, just nullify it.
4008            if end_key_prefix == PREFIX_MAX {
4009                start_key_prefix = end_key_prefix;
4010                start_pubkey = end_pubkey;
4011            } else {
4012                end_key_prefix = start_key_prefix;
4013                end_pubkey = start_pubkey;
4014            }
4015        }
4016
4017        start_pubkey[0..PREFIX_SIZE].copy_from_slice(&start_key_prefix.to_be_bytes());
4018        end_pubkey[0..PREFIX_SIZE].copy_from_slice(&end_key_prefix.to_be_bytes());
4019        trace!(
4020            "pubkey_range_from_partition: ({}-{})/{} [{}]: {}-{}",
4021            start_index,
4022            end_index,
4023            partition_count,
4024            (end_key_prefix - start_key_prefix),
4025            start_pubkey.iter().map(|x| format!("{:02x}", x)).join(""),
4026            end_pubkey.iter().map(|x| format!("{:02x}", x)).join(""),
4027        );
4028        // should be an inclusive range (a closed interval) like this:
4029        // [0xgg00-0xhhff], [0xii00-0xjjff], ... (where 0xii00 == 0xhhff + 1)
4030        Pubkey::new_from_array(start_pubkey)..=Pubkey::new_from_array(end_pubkey)
4031    }
4032
4033    fn fixed_cycle_partitions(&self) -> Vec<Partition> {
4034        let slot_count_in_two_day = self.slot_count_in_two_day();
4035
4036        let parent_cycle = self.parent_slot() / slot_count_in_two_day;
4037        let current_cycle = self.slot() / slot_count_in_two_day;
4038        let mut parent_cycle_index = self.parent_slot() % slot_count_in_two_day;
4039        let current_cycle_index = self.slot() % slot_count_in_two_day;
4040        let mut partitions = vec![];
4041        if parent_cycle < current_cycle {
4042            if current_cycle_index > 0 {
4043                // generate and push gapped partitions because some slots are skipped
4044                let parent_last_cycle_index = slot_count_in_two_day - 1;
4045
4046                // ... for parent cycle
4047                partitions.push((
4048                    parent_cycle_index,
4049                    parent_last_cycle_index,
4050                    slot_count_in_two_day,
4051                ));
4052
4053                // ... for current cycle
4054                partitions.push((0, 0, slot_count_in_two_day));
4055            }
4056            parent_cycle_index = 0;
4057        }
4058
4059        partitions.push((
4060            parent_cycle_index,
4061            current_cycle_index,
4062            slot_count_in_two_day,
4063        ));
4064
4065        partitions
4066    }
4067
4068    fn variable_cycle_partitions(&self) -> Vec<Partition> {
4069        let (current_epoch, current_slot_index) = self.get_epoch_and_slot_index(self.slot());
4070        let (parent_epoch, mut parent_slot_index) =
4071            self.get_epoch_and_slot_index(self.parent_slot());
4072
4073        let mut partitions = vec![];
4074        if parent_epoch < current_epoch {
4075            let slot_skipped = (self.slot() - self.parent_slot()) > 1;
4076            if slot_skipped {
4077                // Generate special partitions because there are skipped slots
4078                // exactly at the epoch transition.
4079
4080                let parent_last_slot_index = self.get_slots_in_epoch(parent_epoch) - 1;
4081
4082                // ... for parent epoch
4083                partitions.push(self.partition_from_slot_indexes_with_gapped_epochs(
4084                    parent_slot_index,
4085                    parent_last_slot_index,
4086                    parent_epoch,
4087                ));
4088
4089                if current_slot_index > 0 {
4090                    // ... for current epoch
4091                    partitions.push(self.partition_from_slot_indexes_with_gapped_epochs(
4092                        0,
4093                        0,
4094                        current_epoch,
4095                    ));
4096                }
4097            }
4098            parent_slot_index = 0;
4099        }
4100
4101        partitions.push(self.partition_from_normal_slot_indexes(
4102            parent_slot_index,
4103            current_slot_index,
4104            current_epoch,
4105        ));
4106
4107        partitions
4108    }
4109
4110    fn do_partition_from_slot_indexes(
4111        &self,
4112        start_slot_index: SlotIndex,
4113        end_slot_index: SlotIndex,
4114        epoch: Epoch,
4115        generated_for_gapped_epochs: bool,
4116    ) -> Partition {
4117        let cycle_params = self.determine_collection_cycle_params(epoch);
4118        let (_, _, in_multi_epoch_cycle, _, _, partition_count) = cycle_params;
4119
4120        // use common codepath for both very likely and very unlikely for the sake of minimized
4121        // risk of any miscalculation instead of negligibly faster computation per slot for the
4122        // likely case.
4123        let mut start_partition_index =
4124            Self::partition_index_from_slot_index(start_slot_index, cycle_params);
4125        let mut end_partition_index =
4126            Self::partition_index_from_slot_index(end_slot_index, cycle_params);
4127
4128        // Adjust partition index for some edge cases
4129        let is_special_new_epoch = start_slot_index == 0 && end_slot_index != 1;
4130        let in_middle_of_cycle = start_partition_index > 0;
4131        if in_multi_epoch_cycle && is_special_new_epoch && in_middle_of_cycle {
4132            // Adjust slot indexes so that the final partition ranges are continuous!
4133            // This is need because the caller gives us off-by-one indexes when
4134            // an epoch boundary is crossed.
4135            // Usually there is no need for this adjustment because cycles are aligned
4136            // with epochs. But for multi-epoch cycles, adjust the indexes if it
4137            // happens in the middle of a cycle for both gapped and not-gapped cases:
4138            //
4139            // epoch (slot range)|slot idx.*1|raw part. idx.|adj. part. idx.|epoch boundary
4140            // ------------------+-----------+--------------+---------------+--------------
4141            // 3 (20..30)        | [7..8]    |   7.. 8      |   7.. 8
4142            //                   | [8..9]    |   8.. 9      |   8.. 9
4143            // 4 (30..40)        | [0..0]    |<10>..10      | <9>..10      <--- not gapped
4144            //                   | [0..1]    |  10..11      |  10..12
4145            //                   | [1..2]    |  11..12      |  11..12
4146            //                   | [2..9   *2|  12..19      |  12..19      <-+
4147            // 5 (40..50)        |  0..0   *2|<20>..<20>    |<19>..<19> *3 <-+- gapped
4148            //                   |  0..4]    |<20>..24      |<19>..24      <-+
4149            //                   | [4..5]    |  24..25      |  24..25
4150            //                   | [5..6]    |  25..26      |  25..26
4151            //
4152            // NOTE: <..> means the adjusted slots
4153            //
4154            // *1: The range of parent_bank.slot() and current_bank.slot() is firstly
4155            //     split by the epoch boundaries and then the split ones are given to us.
4156            //     The original ranges are denoted as [...]
4157            // *2: These are marked with generated_for_gapped_epochs = true.
4158            // *3: This becomes no-op partition
4159            start_partition_index -= 1;
4160            if generated_for_gapped_epochs {
4161                assert_eq!(start_slot_index, end_slot_index);
4162                end_partition_index -= 1;
4163            }
4164        }
4165
4166        (start_partition_index, end_partition_index, partition_count)
4167    }
4168
4169    fn partition_from_normal_slot_indexes(
4170        &self,
4171        start_slot_index: SlotIndex,
4172        end_slot_index: SlotIndex,
4173        epoch: Epoch,
4174    ) -> Partition {
4175        self.do_partition_from_slot_indexes(start_slot_index, end_slot_index, epoch, false)
4176    }
4177
4178    fn partition_from_slot_indexes_with_gapped_epochs(
4179        &self,
4180        start_slot_index: SlotIndex,
4181        end_slot_index: SlotIndex,
4182        epoch: Epoch,
4183    ) -> Partition {
4184        self.do_partition_from_slot_indexes(start_slot_index, end_slot_index, epoch, true)
4185    }
4186
4187    fn determine_collection_cycle_params(&self, epoch: Epoch) -> RentCollectionCycleParams {
4188        let slot_count_per_epoch = self.get_slots_in_epoch(epoch);
4189
4190        if !self.use_multi_epoch_collection_cycle(epoch) {
4191            (
4192                epoch,
4193                slot_count_per_epoch,
4194                false,
4195                0,
4196                1,
4197                slot_count_per_epoch,
4198            )
4199        } else {
4200            let epoch_count_in_cycle = self.slot_count_in_two_day() / slot_count_per_epoch;
4201            let partition_count = slot_count_per_epoch * epoch_count_in_cycle;
4202
4203            (
4204                epoch,
4205                slot_count_per_epoch,
4206                true,
4207                self.first_normal_epoch(),
4208                epoch_count_in_cycle,
4209                partition_count,
4210            )
4211        }
4212    }
4213
4214    fn partition_index_from_slot_index(
4215        slot_index_in_epoch: SlotIndex,
4216        (
4217            epoch,
4218            slot_count_per_epoch,
4219            _,
4220            base_epoch,
4221            epoch_count_per_cycle,
4222            _,
4223        ): RentCollectionCycleParams,
4224    ) -> PartitionIndex {
4225        let epoch_offset = epoch - base_epoch;
4226        let epoch_index_in_cycle = epoch_offset % epoch_count_per_cycle;
4227        slot_index_in_epoch + epoch_index_in_cycle * slot_count_per_epoch
4228    }
4229
4230    // Given short epochs, it's too costly to collect rent eagerly
4231    // within an epoch, so lower the frequency of it.
4232    // These logic isn't strictly eager anymore and should only be used
4233    // for development/performance purpose.
4234    // Absolutely not under ClusterType::MainnetBeta!!!!
4235    fn use_multi_epoch_collection_cycle(&self, epoch: Epoch) -> bool {
4236        // Force normal behavior, disabling multi epoch collection cycle for manual local testing
4237        #[cfg(not(test))]
4238        if self.slot_count_per_normal_epoch() == gemachain_sdk::epoch_schedule::MINIMUM_SLOTS_PER_EPOCH
4239        {
4240            return false;
4241        }
4242
4243        epoch >= self.first_normal_epoch()
4244            && self.slot_count_per_normal_epoch() < self.slot_count_in_two_day()
4245    }
4246
4247    fn use_fixed_collection_cycle(&self) -> bool {
4248        // Force normal behavior, disabling fixed collection cycle for manual local testing
4249        #[cfg(not(test))]
4250        if self.slot_count_per_normal_epoch() == gemachain_sdk::epoch_schedule::MINIMUM_SLOTS_PER_EPOCH
4251        {
4252            return false;
4253        }
4254
4255        self.cluster_type() != ClusterType::MainnetBeta
4256            && self.slot_count_per_normal_epoch() < self.slot_count_in_two_day()
4257    }
4258
4259    // This value is specially chosen to align with slots per epoch in mainnet-beta and testnet
4260    // Also, assume 500GB account data set as the extreme, then for 2 day (=48 hours) to collect
4261    // rent eagerly, we'll consume 5.7 MB/s IO bandwidth, bidirectionally.
4262    fn slot_count_in_two_day(&self) -> SlotCount {
4263        2 * DEFAULT_TICKS_PER_SECOND * SECONDS_PER_DAY / self.ticks_per_slot
4264    }
4265
4266    fn slot_count_per_normal_epoch(&self) -> SlotCount {
4267        self.get_slots_in_epoch(self.first_normal_epoch())
4268    }
4269
4270    pub fn cluster_type(&self) -> ClusterType {
4271        // unwrap is safe; self.cluster_type is ensured to be Some() always...
4272        // we only using Option here for ABI compatibility...
4273        self.cluster_type.unwrap()
4274    }
4275
4276    /// Process a batch of transactions.
4277    #[must_use]
4278    pub fn load_execute_and_commit_transactions(
4279        &self,
4280        batch: &TransactionBatch,
4281        max_age: usize,
4282        collect_balances: bool,
4283        enable_cpi_recording: bool,
4284        enable_log_recording: bool,
4285        timings: &mut ExecuteTimings,
4286    ) -> (
4287        TransactionResults,
4288        TransactionBalancesSet,
4289        Vec<Option<InnerInstructionsList>>,
4290        Vec<Option<TransactionLogMessages>>,
4291    ) {
4292        let pre_balances = if collect_balances {
4293            self.collect_balances(batch)
4294        } else {
4295            vec![]
4296        };
4297
4298        let (
4299            mut loaded_txs,
4300            executed,
4301            inner_instructions,
4302            transaction_logs,
4303            _,
4304            tx_count,
4305            signature_count,
4306        ) = self.load_and_execute_transactions(
4307            batch,
4308            max_age,
4309            enable_cpi_recording,
4310            enable_log_recording,
4311            timings,
4312        );
4313
4314        let results = self.commit_transactions(
4315            batch.sanitized_transactions(),
4316            &mut loaded_txs,
4317            &executed,
4318            tx_count,
4319            signature_count,
4320            timings,
4321        );
4322        let post_balances = if collect_balances {
4323            self.collect_balances(batch)
4324        } else {
4325            vec![]
4326        };
4327        (
4328            results,
4329            TransactionBalancesSet::new(pre_balances, post_balances),
4330            inner_instructions,
4331            transaction_logs,
4332        )
4333    }
4334
4335    /// Process a Transaction. This is used for unit tests and simply calls the vector
4336    /// Bank::process_transactions method.
4337    pub fn process_transaction(&self, tx: &Transaction) -> Result<()> {
4338        self.try_process_transactions(std::iter::once(tx))?[0].clone()?;
4339        tx.signatures
4340            .get(0)
4341            .map_or(Ok(()), |sig| self.get_signature_status(sig).unwrap())
4342    }
4343
4344    /// Process multiple transaction in a single batch. This is used for benches and unit tests.
4345    ///
4346    /// # Panics
4347    ///
4348    /// Panics if any of the transactions do not pass sanitization checks.
4349    #[must_use]
4350    pub fn process_transactions<'a>(
4351        &self,
4352        txs: impl Iterator<Item = &'a Transaction>,
4353    ) -> Vec<Result<()>> {
4354        self.try_process_transactions(txs).unwrap()
4355    }
4356
4357    /// Process multiple transaction in a single batch. This is used for benches and unit tests.
4358    /// Short circuits if any of the transactions do not pass sanitization checks.
4359    pub fn try_process_transactions<'a>(
4360        &self,
4361        txs: impl Iterator<Item = &'a Transaction>,
4362    ) -> Result<Vec<Result<()>>> {
4363        let txs = txs
4364            .map(|tx| VersionedTransaction::from(tx.clone()))
4365            .collect();
4366        self.try_process_entry_transactions(txs)
4367    }
4368
4369    /// Process entry transactions in a single batch. This is used for benches and unit tests.
4370    ///
4371    /// # Panics
4372    ///
4373    /// Panics if any of the transactions do not pass sanitization checks.
4374    #[must_use]
4375    pub fn process_entry_transactions(&self, txs: Vec<VersionedTransaction>) -> Vec<Result<()>> {
4376        self.try_process_entry_transactions(txs).unwrap()
4377    }
4378
4379    /// Process multiple transaction in a single batch. This is used for benches and unit tests.
4380    /// Short circuits if any of the transactions do not pass sanitization checks.
4381    pub fn try_process_entry_transactions(
4382        &self,
4383        txs: Vec<VersionedTransaction>,
4384    ) -> Result<Vec<Result<()>>> {
4385        let batch = self.prepare_entry_batch(txs)?;
4386        Ok(self.process_transaction_batch(&batch))
4387    }
4388
4389    #[must_use]
4390    fn process_transaction_batch(&self, batch: &TransactionBatch) -> Vec<Result<()>> {
4391        self.load_execute_and_commit_transactions(
4392            batch,
4393            MAX_PROCESSING_AGE,
4394            false,
4395            false,
4396            false,
4397            &mut ExecuteTimings::default(),
4398        )
4399        .0
4400        .fee_collection_results
4401    }
4402
4403    /// Create, sign, and process a Transaction from `keypair` to `to` of
4404    /// `n` carats where `blockhash` is the last Entry ID observed by the client.
4405    pub fn transfer(&self, n: u64, keypair: &Keypair, to: &Pubkey) -> Result<Signature> {
4406        let blockhash = self.last_blockhash();
4407        let tx = system_transaction::transfer(keypair, to, n, blockhash);
4408        let signature = tx.signatures[0];
4409        self.process_transaction(&tx).map(|_| signature)
4410    }
4411
4412    pub fn read_balance(account: &AccountSharedData) -> u64 {
4413        account.carats()
4414    }
4415    /// Each program would need to be able to introspect its own state
4416    /// this is hard-coded to the Budget language
4417    pub fn get_balance(&self, pubkey: &Pubkey) -> u64 {
4418        self.get_account(pubkey)
4419            .map(|x| Self::read_balance(&x))
4420            .unwrap_or(0)
4421    }
4422
4423    /// Compute all the parents of the bank in order
4424    pub fn parents(&self) -> Vec<Arc<Bank>> {
4425        let mut parents = vec![];
4426        let mut bank = self.parent();
4427        while let Some(parent) = bank {
4428            parents.push(parent.clone());
4429            bank = parent.parent();
4430        }
4431        parents
4432    }
4433
4434    /// Compute all the parents of the bank including this bank itself
4435    pub fn parents_inclusive(self: Arc<Self>) -> Vec<Arc<Bank>> {
4436        let mut parents = self.parents();
4437        parents.insert(0, self);
4438        parents
4439    }
4440
4441    pub fn store_account(&self, pubkey: &Pubkey, account: &AccountSharedData) {
4442        assert!(!self.freeze_started());
4443        self.rc
4444            .accounts
4445            .store_slow_cached(self.slot(), pubkey, account);
4446
4447        if Stakes::is_stake(account) {
4448            self.stakes.write().unwrap().store(
4449                pubkey,
4450                account,
4451                self.check_init_vote_data_enabled(),
4452                self.stakes_remove_delegation_if_inactive_enabled(),
4453            );
4454        }
4455    }
4456
4457    pub fn force_flush_accounts_cache(&self) {
4458        self.rc
4459            .accounts
4460            .accounts_db
4461            .flush_accounts_cache(true, Some(self.slot()))
4462    }
4463
4464    pub fn flush_accounts_cache_if_needed(&self) {
4465        self.rc
4466            .accounts
4467            .accounts_db
4468            .flush_accounts_cache(false, Some(self.slot()))
4469    }
4470
4471    #[cfg(test)]
4472    pub fn flush_accounts_cache_slot(&self) {
4473        self.rc
4474            .accounts
4475            .accounts_db
4476            .flush_accounts_cache_slot(self.slot())
4477    }
4478
4479    pub fn expire_old_recycle_stores(&self) {
4480        self.rc.accounts.accounts_db.expire_old_recycle_stores()
4481    }
4482
4483    /// Technically this issues (or even burns!) new carats,
4484    /// so be extra careful for its usage
4485    fn store_account_and_update_capitalization(
4486        &self,
4487        pubkey: &Pubkey,
4488        new_account: &AccountSharedData,
4489    ) {
4490        if let Some(old_account) = self.get_account_with_fixed_root(pubkey) {
4491            match new_account.carats().cmp(&old_account.carats()) {
4492                std::cmp::Ordering::Greater => {
4493                    let increased = new_account.carats() - old_account.carats();
4494                    trace!(
4495                        "store_account_and_update_capitalization: increased: {} {}",
4496                        pubkey,
4497                        increased
4498                    );
4499                    self.capitalization.fetch_add(increased, Relaxed);
4500                }
4501                std::cmp::Ordering::Less => {
4502                    let decreased = old_account.carats() - new_account.carats();
4503                    trace!(
4504                        "store_account_and_update_capitalization: decreased: {} {}",
4505                        pubkey,
4506                        decreased
4507                    );
4508                    self.capitalization.fetch_sub(decreased, Relaxed);
4509                }
4510                std::cmp::Ordering::Equal => {}
4511            }
4512        } else {
4513            trace!(
4514                "store_account_and_update_capitalization: created: {} {}",
4515                pubkey,
4516                new_account.carats()
4517            );
4518            self.capitalization
4519                .fetch_add(new_account.carats(), Relaxed);
4520        }
4521
4522        self.store_account(pubkey, new_account);
4523    }
4524
4525    fn withdraw(&self, pubkey: &Pubkey, carats: u64) -> Result<()> {
4526        match self.get_account_with_fixed_root(pubkey) {
4527            Some(mut account) => {
4528                let min_balance = match get_system_account_kind(&account) {
4529                    Some(SystemAccountKind::Nonce) => self
4530                        .rent_collector
4531                        .rent
4532                        .minimum_balance(nonce::State::size()),
4533                    _ => 0,
4534                };
4535
4536                carats
4537                    .checked_add(min_balance)
4538                    .filter(|required_balance| *required_balance <= account.carats())
4539                    .ok_or(TransactionError::InsufficientFundsForFee)?;
4540                account
4541                    .checked_sub_carats(carats)
4542                    .map_err(|_| TransactionError::InsufficientFundsForFee)?;
4543                self.store_account(pubkey, &account);
4544
4545                Ok(())
4546            }
4547            None => Err(TransactionError::AccountNotFound),
4548        }
4549    }
4550
4551    pub fn deposit(
4552        &self,
4553        pubkey: &Pubkey,
4554        carats: u64,
4555    ) -> std::result::Result<u64, CaratsError> {
4556        // This doesn't collect rents intentionally.
4557        // Rents should only be applied to actual TXes
4558        let mut account = self.get_account_with_fixed_root(pubkey).unwrap_or_default();
4559        account.checked_add_carats(carats)?;
4560        self.store_account(pubkey, &account);
4561        Ok(account.carats())
4562    }
4563
4564    pub fn accounts(&self) -> Arc<Accounts> {
4565        self.rc.accounts.clone()
4566    }
4567
4568    fn finish_init(
4569        &mut self,
4570        genesis_config: &GenesisConfig,
4571        additional_builtins: Option<&Builtins>,
4572        debug_do_not_add_builtins: bool,
4573    ) {
4574        self.rewards_pool_pubkeys =
4575            Arc::new(genesis_config.rewards_pools.keys().cloned().collect());
4576
4577        let mut builtins = builtins::get();
4578        if let Some(additional_builtins) = additional_builtins {
4579            builtins
4580                .genesis_builtins
4581                .extend_from_slice(&additional_builtins.genesis_builtins);
4582            builtins
4583                .feature_builtins
4584                .extend_from_slice(&additional_builtins.feature_builtins);
4585        }
4586        if !debug_do_not_add_builtins {
4587            for builtin in builtins.genesis_builtins {
4588                self.add_builtin(
4589                    &builtin.name,
4590                    builtin.id,
4591                    builtin.process_instruction_with_context,
4592                );
4593            }
4594        }
4595        self.feature_builtins = Arc::new(builtins.feature_builtins);
4596
4597        self.apply_feature_activations(true, debug_do_not_add_builtins);
4598    }
4599
4600    pub fn set_inflation(&self, inflation: Inflation) {
4601        *self.inflation.write().unwrap() = inflation;
4602    }
4603
4604    pub fn set_compute_budget(&mut self, compute_budget: Option<ComputeBudget>) {
4605        self.compute_budget = compute_budget;
4606    }
4607
4608    #[allow(deprecated)]
4609    #[deprecated(since = "1.8.0", note = "please use `set_compute_budget` instead")]
4610    pub fn set_bpf_compute_budget(
4611        &mut self,
4612        bpf_compute_budget: Option<gemachain_sdk::process_instruction::BpfComputeBudget>,
4613    ) {
4614        self.compute_budget = bpf_compute_budget.map(|budget| budget.into());
4615    }
4616
4617    pub fn hard_forks(&self) -> Arc<RwLock<HardForks>> {
4618        self.hard_forks.clone()
4619    }
4620
4621    // Hi! leaky abstraction here....
4622    // try to use get_account_with_fixed_root() if it's called ONLY from on-chain runtime account
4623    // processing. That alternative fn provides more safety.
4624    pub fn get_account(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
4625        self.get_account_modified_slot(pubkey)
4626            .map(|(acc, _slot)| acc)
4627    }
4628
4629    // Hi! leaky abstraction here....
4630    // use this over get_account() if it's called ONLY from on-chain runtime account
4631    // processing (i.e. from in-band replay/banking stage; that ensures root is *fixed* while
4632    // running).
4633    // pro: safer assertion can be enabled inside AccountsDb
4634    // con: panics!() if called from off-chain processing
4635    pub fn get_account_with_fixed_root(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
4636        self.load_slow_with_fixed_root(&self.ancestors, pubkey)
4637            .map(|(acc, _slot)| acc)
4638    }
4639
4640    pub fn get_account_modified_slot(&self, pubkey: &Pubkey) -> Option<(AccountSharedData, Slot)> {
4641        self.load_slow(&self.ancestors, pubkey)
4642    }
4643
4644    fn load_slow(
4645        &self,
4646        ancestors: &Ancestors,
4647        pubkey: &Pubkey,
4648    ) -> Option<(AccountSharedData, Slot)> {
4649        // get_account (= primary this fn caller) may be called from on-chain Bank code even if we
4650        // try hard to use get_account_with_fixed_root for that purpose...
4651        // so pass safer LoadHint:Unspecified here as a fallback
4652        self.rc.accounts.load_without_fixed_root(ancestors, pubkey)
4653    }
4654
4655    fn load_slow_with_fixed_root(
4656        &self,
4657        ancestors: &Ancestors,
4658        pubkey: &Pubkey,
4659    ) -> Option<(AccountSharedData, Slot)> {
4660        self.rc.accounts.load_with_fixed_root(ancestors, pubkey)
4661    }
4662
4663    // Exclude self to really fetch the parent Bank's account hash and data.
4664    //
4665    // Being idempotent is needed to make the lazy initialization possible,
4666    // especially for update_slot_hashes at the moment, which can be called
4667    // multiple times with the same parent_slot in the case of forking.
4668    //
4669    // Generally, all of sysvar update granularity should be slot boundaries.
4670    //
4671    // This behavior is deprecated... See comment in update_sysvar_account() for details
4672    fn get_sysvar_account_with_fixed_root(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
4673        let mut ancestors = self.ancestors.clone();
4674        ancestors.remove(&self.slot());
4675        self.rc
4676            .accounts
4677            .load_with_fixed_root(&ancestors, pubkey)
4678            .map(|(acc, _slot)| acc)
4679    }
4680
4681    pub fn get_program_accounts(
4682        &self,
4683        program_id: &Pubkey,
4684    ) -> ScanResult<Vec<(Pubkey, AccountSharedData)>> {
4685        self.rc
4686            .accounts
4687            .load_by_program(&self.ancestors, self.bank_id, program_id)
4688    }
4689
4690    pub fn get_filtered_program_accounts<F: Fn(&AccountSharedData) -> bool>(
4691        &self,
4692        program_id: &Pubkey,
4693        filter: F,
4694    ) -> ScanResult<Vec<(Pubkey, AccountSharedData)>> {
4695        self.rc.accounts.load_by_program_with_filter(
4696            &self.ancestors,
4697            self.bank_id,
4698            program_id,
4699            filter,
4700        )
4701    }
4702
4703    pub fn get_filtered_indexed_accounts<F: Fn(&AccountSharedData) -> bool>(
4704        &self,
4705        index_key: &IndexKey,
4706        filter: F,
4707    ) -> ScanResult<Vec<(Pubkey, AccountSharedData)>> {
4708        self.rc.accounts.load_by_index_key_with_filter(
4709            &self.ancestors,
4710            self.bank_id,
4711            index_key,
4712            filter,
4713        )
4714    }
4715
4716    pub fn account_indexes_include_key(&self, key: &Pubkey) -> bool {
4717        self.rc.accounts.account_indexes_include_key(key)
4718    }
4719
4720    pub fn get_all_accounts_with_modified_slots(
4721        &self,
4722    ) -> ScanResult<Vec<(Pubkey, AccountSharedData, Slot)>> {
4723        self.rc.accounts.load_all(&self.ancestors, self.bank_id)
4724    }
4725
4726    pub fn get_program_accounts_modified_since_parent(
4727        &self,
4728        program_id: &Pubkey,
4729    ) -> Vec<(Pubkey, AccountSharedData)> {
4730        self.rc
4731            .accounts
4732            .load_by_program_slot(self.slot(), Some(program_id))
4733    }
4734
4735    pub fn get_transaction_logs(
4736        &self,
4737        address: Option<&Pubkey>,
4738    ) -> Option<Vec<TransactionLogInfo>> {
4739        let transaction_log_collector = self.transaction_log_collector.read().unwrap();
4740
4741        match address {
4742            None => Some(transaction_log_collector.logs.clone()),
4743            Some(address) => transaction_log_collector
4744                .mentioned_address_map
4745                .get(address)
4746                .map(|log_indices| {
4747                    log_indices
4748                        .iter()
4749                        .map(|i| transaction_log_collector.logs[*i].clone())
4750                        .collect()
4751                }),
4752        }
4753    }
4754
4755    pub fn get_all_accounts_modified_since_parent(&self) -> Vec<(Pubkey, AccountSharedData)> {
4756        self.rc.accounts.load_by_program_slot(self.slot(), None)
4757    }
4758
4759    // if you want get_account_modified_since_parent without fixed_root, please define so...
4760    fn get_account_modified_since_parent_with_fixed_root(
4761        &self,
4762        pubkey: &Pubkey,
4763    ) -> Option<(AccountSharedData, Slot)> {
4764        let just_self: Ancestors = Ancestors::from(vec![self.slot()]);
4765        if let Some((account, slot)) = self.load_slow_with_fixed_root(&just_self, pubkey) {
4766            if slot == self.slot() {
4767                return Some((account, slot));
4768            }
4769        }
4770        None
4771    }
4772
4773    pub fn get_largest_accounts(
4774        &self,
4775        num: usize,
4776        filter_by_address: &HashSet<Pubkey>,
4777        filter: AccountAddressFilter,
4778    ) -> ScanResult<Vec<(Pubkey, u64)>> {
4779        self.rc.accounts.load_largest_accounts(
4780            &self.ancestors,
4781            self.bank_id,
4782            num,
4783            filter_by_address,
4784            filter,
4785        )
4786    }
4787
4788    pub fn transaction_count(&self) -> u64 {
4789        self.transaction_count.load(Relaxed)
4790    }
4791
4792    pub fn transaction_error_count(&self) -> u64 {
4793        self.transaction_error_count.load(Relaxed)
4794    }
4795
4796    pub fn transaction_entries_count(&self) -> u64 {
4797        self.transaction_entries_count.load(Relaxed)
4798    }
4799
4800    pub fn transactions_per_entry_max(&self) -> u64 {
4801        self.transactions_per_entry_max.load(Relaxed)
4802    }
4803
4804    fn increment_transaction_count(&self, tx_count: u64) {
4805        self.transaction_count.fetch_add(tx_count, Relaxed);
4806    }
4807
4808    pub fn signature_count(&self) -> u64 {
4809        self.signature_count.load(Relaxed)
4810    }
4811
4812    fn increment_signature_count(&self, signature_count: u64) {
4813        self.signature_count.fetch_add(signature_count, Relaxed);
4814    }
4815
4816    pub fn get_signature_status_processed_since_parent(
4817        &self,
4818        signature: &Signature,
4819    ) -> Option<Result<()>> {
4820        if let Some((slot, status)) = self.get_signature_status_slot(signature) {
4821            if slot <= self.slot() {
4822                return Some(status);
4823            }
4824        }
4825        None
4826    }
4827
4828    pub fn get_signature_status_with_blockhash(
4829        &self,
4830        signature: &Signature,
4831        blockhash: &Hash,
4832    ) -> Option<Result<()>> {
4833        let rcache = self.src.status_cache.read().unwrap();
4834        rcache
4835            .get_status(signature, blockhash, &self.ancestors)
4836            .map(|v| v.1)
4837    }
4838
4839    pub fn get_signature_status_slot(&self, signature: &Signature) -> Option<(Slot, Result<()>)> {
4840        let rcache = self.src.status_cache.read().unwrap();
4841        rcache.get_status_any_blockhash(signature, &self.ancestors)
4842    }
4843
4844    pub fn get_signature_status(&self, signature: &Signature) -> Option<Result<()>> {
4845        self.get_signature_status_slot(signature).map(|v| v.1)
4846    }
4847
4848    pub fn has_signature(&self, signature: &Signature) -> bool {
4849        self.get_signature_status_slot(signature).is_some()
4850    }
4851
4852    /// Hash the `accounts` HashMap. This represents a validator's interpretation
4853    ///  of the delta of the ledger since the last vote and up to now
4854    fn hash_internal_state(&self) -> Hash {
4855        // If there are no accounts, return the hash of the previous state and the latest blockhash
4856        let accounts_delta_hash = self.rc.accounts.bank_hash_info_at(self.slot());
4857        let mut signature_count_buf = [0u8; 8];
4858        LittleEndian::write_u64(&mut signature_count_buf[..], self.signature_count() as u64);
4859
4860        let mut hash = hashv(&[
4861            self.parent_hash.as_ref(),
4862            accounts_delta_hash.hash.as_ref(),
4863            &signature_count_buf,
4864            self.last_blockhash().as_ref(),
4865        ]);
4866
4867        if let Some(buf) = self
4868            .hard_forks
4869            .read()
4870            .unwrap()
4871            .get_hash_data(self.slot(), self.parent_slot())
4872        {
4873            info!("hard fork at bank {}", self.slot());
4874            hash = extend_and_hash(&hash, &buf)
4875        }
4876
4877        info!(
4878            "bank frozen: {} hash: {} accounts_delta: {} signature_count: {} last_blockhash: {} capitalization: {}",
4879            self.slot(),
4880            hash,
4881            accounts_delta_hash.hash,
4882            self.signature_count(),
4883            self.last_blockhash(),
4884            self.capitalization(),
4885        );
4886
4887        info!(
4888            "accounts hash slot: {} stats: {:?}",
4889            self.slot(),
4890            accounts_delta_hash.stats,
4891        );
4892        hash
4893    }
4894
4895    /// Recalculate the hash_internal_state from the account stores. Would be used to verify a
4896    /// snapshot.
4897    #[must_use]
4898    fn verify_bank_hash(&self, test_hash_calculation: bool) -> bool {
4899        self.rc.accounts.verify_bank_hash_and_carats(
4900            self.slot(),
4901            &self.ancestors,
4902            self.capitalization(),
4903            test_hash_calculation,
4904        )
4905    }
4906
4907    pub fn get_snapshot_storages(&self, base_slot: Option<Slot>) -> SnapshotStorages {
4908        self.rc
4909            .accounts
4910            .accounts_db
4911            .get_snapshot_storages(self.slot(), base_slot, None)
4912            .0
4913    }
4914
4915    #[must_use]
4916    fn verify_hash(&self) -> bool {
4917        assert!(self.is_frozen());
4918        let calculated_hash = self.hash_internal_state();
4919        let expected_hash = self.hash();
4920
4921        if calculated_hash == expected_hash {
4922            true
4923        } else {
4924            warn!(
4925                "verify failed: slot: {}, {} (calculated) != {} (expected)",
4926                self.slot(),
4927                calculated_hash,
4928                expected_hash
4929            );
4930            false
4931        }
4932    }
4933
4934    pub fn verify_transaction(
4935        &self,
4936        tx: VersionedTransaction,
4937        skip_verification: bool,
4938    ) -> Result<SanitizedTransaction> {
4939        let sanitized_tx = {
4940            let size =
4941                bincode::serialized_size(&tx).map_err(|_| TransactionError::SanitizeFailure)?;
4942            if size > PACKET_DATA_SIZE as u64 {
4943                return Err(TransactionError::SanitizeFailure);
4944            }
4945            let message_hash = if !skip_verification {
4946                tx.verify_and_hash_message()?
4947            } else {
4948                tx.message.hash()
4949            };
4950
4951            SanitizedTransaction::try_create(tx, message_hash, |_| {
4952                Err(TransactionError::UnsupportedVersion)
4953            })
4954        }?;
4955
4956        if self.verify_tx_signatures_len_enabled() && !sanitized_tx.verify_signatures_len() {
4957            return Err(TransactionError::SanitizeFailure);
4958        }
4959
4960        if !skip_verification {
4961            sanitized_tx.verify_precompiles(&self.feature_set)?;
4962        }
4963
4964        Ok(sanitized_tx)
4965    }
4966
4967    pub fn calculate_capitalization(&self, debug_verify: bool) -> u64 {
4968        let can_cached_slot_be_unflushed = true; // implied yes
4969        self.rc.accounts.calculate_capitalization(
4970            &self.ancestors,
4971            self.slot(),
4972            can_cached_slot_be_unflushed,
4973            debug_verify,
4974        )
4975    }
4976
4977    pub fn calculate_and_verify_capitalization(&self, debug_verify: bool) -> bool {
4978        let calculated = self.calculate_capitalization(debug_verify);
4979        let expected = self.capitalization();
4980        if calculated == expected {
4981            true
4982        } else {
4983            warn!(
4984                "Capitalization mismatch: calculated: {} != expected: {}",
4985                calculated, expected
4986            );
4987            false
4988        }
4989    }
4990
4991    /// Forcibly overwrites current capitalization by actually recalculating accounts' balances.
4992    /// This should only be used for developing purposes.
4993    pub fn set_capitalization(&self) -> u64 {
4994        let old = self.capitalization();
4995        let debug_verify = true;
4996        self.capitalization
4997            .store(self.calculate_capitalization(debug_verify), Relaxed);
4998        old
4999    }
5000
5001    pub fn get_accounts_hash(&self) -> Hash {
5002        self.rc.accounts.accounts_db.get_accounts_hash(self.slot)
5003    }
5004
5005    pub fn get_thread_pool(&self) -> &ThreadPool {
5006        &self.rc.accounts.accounts_db.thread_pool_clean
5007    }
5008
5009    pub fn update_accounts_hash_with_index_option(
5010        &self,
5011        use_index: bool,
5012        debug_verify: bool,
5013        slots_per_epoch: Option<Slot>,
5014    ) -> Hash {
5015        let (hash, total_carats) = self
5016            .rc
5017            .accounts
5018            .accounts_db
5019            .update_accounts_hash_with_index_option(
5020                use_index,
5021                debug_verify,
5022                self.slot(),
5023                &self.ancestors,
5024                Some(self.capitalization()),
5025                false,
5026                slots_per_epoch,
5027            );
5028        if total_carats != self.capitalization() {
5029            datapoint_info!(
5030                "capitalization_mismatch",
5031                ("slot", self.slot(), i64),
5032                ("calculated_carats", total_carats, i64),
5033                ("capitalization", self.capitalization(), i64),
5034            );
5035
5036            panic!(
5037                "capitalization_mismatch. slot: {}, calculated_carats: {}, capitalization: {}",
5038                self.slot(),
5039                total_carats,
5040                self.capitalization()
5041            );
5042        }
5043        hash
5044    }
5045
5046    pub fn update_accounts_hash(&self) -> Hash {
5047        self.update_accounts_hash_with_index_option(true, false, None)
5048    }
5049
5050    /// A snapshot bank should be purged of 0 carat accounts which are not part of the hash
5051    /// calculation and could shield other real accounts.
5052    pub fn verify_snapshot_bank(
5053        &self,
5054        test_hash_calculation: bool,
5055        accounts_db_skip_shrink: bool,
5056        last_full_snapshot_slot: Option<Slot>,
5057    ) -> bool {
5058        info!("cleaning..");
5059        let mut clean_time = Measure::start("clean");
5060        if self.slot() > 0 {
5061            self.clean_accounts(true, true, last_full_snapshot_slot);
5062        }
5063        clean_time.stop();
5064
5065        let mut shrink_all_slots_time = Measure::start("shrink_all_slots");
5066        if !accounts_db_skip_shrink && self.slot() > 0 {
5067            info!("shrinking..");
5068            self.shrink_all_slots(true, last_full_snapshot_slot);
5069        }
5070        shrink_all_slots_time.stop();
5071
5072        info!("verify_bank_hash..");
5073        let mut verify_time = Measure::start("verify_bank_hash");
5074        let mut verify = self.verify_bank_hash(test_hash_calculation);
5075        verify_time.stop();
5076
5077        info!("verify_hash..");
5078        let mut verify2_time = Measure::start("verify_hash");
5079        // Order and short-circuiting is significant; verify_hash requires a valid bank hash
5080        verify = verify && self.verify_hash();
5081        verify2_time.stop();
5082
5083        datapoint_info!(
5084            "verify_snapshot_bank",
5085            ("clean_us", clean_time.as_us(), i64),
5086            ("shrink_all_slots_us", shrink_all_slots_time.as_us(), i64),
5087            ("verify_bank_hash_us", verify_time.as_us(), i64),
5088            ("verify_hash_us", verify2_time.as_us(), i64),
5089        );
5090
5091        verify
5092    }
5093
5094    /// Return the number of hashes per tick
5095    pub fn hashes_per_tick(&self) -> &Option<u64> {
5096        &self.hashes_per_tick
5097    }
5098
5099    /// Return the number of ticks per slot
5100    pub fn ticks_per_slot(&self) -> u64 {
5101        self.ticks_per_slot
5102    }
5103
5104    /// Return the number of slots per year
5105    pub fn slots_per_year(&self) -> f64 {
5106        self.slots_per_year
5107    }
5108
5109    /// Return the number of ticks since genesis.
5110    pub fn tick_height(&self) -> u64 {
5111        self.tick_height.load(Relaxed)
5112    }
5113
5114    /// Return the inflation parameters of the Bank
5115    pub fn inflation(&self) -> Inflation {
5116        *self.inflation.read().unwrap()
5117    }
5118
5119    pub fn rent_collector(&self) -> RentCollector {
5120        self.rent_collector.clone()
5121    }
5122
5123    /// Return the total capitalization of the Bank
5124    pub fn capitalization(&self) -> u64 {
5125        self.capitalization.load(Relaxed)
5126    }
5127
5128    /// Return this bank's max_tick_height
5129    pub fn max_tick_height(&self) -> u64 {
5130        self.max_tick_height
5131    }
5132
5133    /// Return the block_height of this bank
5134    pub fn block_height(&self) -> u64 {
5135        self.block_height
5136    }
5137
5138    /// Return the number of slots per epoch for the given epoch
5139    pub fn get_slots_in_epoch(&self, epoch: Epoch) -> u64 {
5140        self.epoch_schedule.get_slots_in_epoch(epoch)
5141    }
5142
5143    /// returns the epoch for which this bank's leader_schedule_slot_offset and slot would
5144    ///  need to cache leader_schedule
5145    pub fn get_leader_schedule_epoch(&self, slot: Slot) -> Epoch {
5146        self.epoch_schedule.get_leader_schedule_epoch(slot)
5147    }
5148
5149    /// a bank-level cache of vote accounts
5150    fn update_cached_accounts(
5151        &self,
5152        txs: &[SanitizedTransaction],
5153        res: &[TransactionExecutionResult],
5154        loaded_txs: &[TransactionLoadResult],
5155    ) -> Vec<OverwrittenVoteAccount> {
5156        let mut overwritten_vote_accounts = vec![];
5157        for (i, ((raccs, _load_nonce_rollback), tx)) in loaded_txs.iter().zip(txs).enumerate() {
5158            let (res, _res_nonce_rollback) = &res[i];
5159            if res.is_err() || raccs.is_err() {
5160                continue;
5161            }
5162
5163            let message = tx.message();
5164            let loaded_transaction = raccs.as_ref().unwrap();
5165
5166            for (_i, (pubkey, account)) in (0..message.account_keys_len())
5167                .zip(loaded_transaction.accounts.iter())
5168                .filter(|(_i, (_pubkey, account))| (Stakes::is_stake(account)))
5169            {
5170                if let Some(old_vote_account) = self.stakes.write().unwrap().store(
5171                    pubkey,
5172                    account,
5173                    self.check_init_vote_data_enabled(),
5174                    self.stakes_remove_delegation_if_inactive_enabled(),
5175                ) {
5176                    // TODO: one of the indices is redundant.
5177                    overwritten_vote_accounts.push(OverwrittenVoteAccount {
5178                        account: old_vote_account,
5179                        transaction_index: i,
5180                        transaction_result_index: i,
5181                    });
5182                }
5183            }
5184        }
5185
5186        overwritten_vote_accounts
5187    }
5188
5189    /// current stake delegations for this bank
5190    pub fn cloned_stake_delegations(&self) -> HashMap<Pubkey, Delegation> {
5191        self.stakes.read().unwrap().stake_delegations().clone()
5192    }
5193
5194    pub fn staked_nodes(&self) -> Arc<HashMap<Pubkey, u64>> {
5195        self.stakes.read().unwrap().staked_nodes()
5196    }
5197
5198    /// current vote accounts for this bank along with the stake
5199    ///   attributed to each account
5200    pub fn vote_accounts(&self) -> Arc<HashMap<Pubkey, (/*stake:*/ u64, VoteAccount)>> {
5201        let stakes = self.stakes.read().unwrap();
5202        Arc::from(stakes.vote_accounts())
5203    }
5204
5205    /// Vote account for the given vote account pubkey along with the stake.
5206    pub fn get_vote_account(&self, vote_account: &Pubkey) -> Option<(/*stake:*/ u64, VoteAccount)> {
5207        let stakes = self.stakes.read().unwrap();
5208        stakes.vote_accounts().get(vote_account).cloned()
5209    }
5210
5211    /// Get the EpochStakes for a given epoch
5212    pub fn epoch_stakes(&self, epoch: Epoch) -> Option<&EpochStakes> {
5213        self.epoch_stakes.get(&epoch)
5214    }
5215
5216    pub fn epoch_stakes_map(&self) -> &HashMap<Epoch, EpochStakes> {
5217        &self.epoch_stakes
5218    }
5219
5220    pub fn epoch_staked_nodes(&self, epoch: Epoch) -> Option<Arc<HashMap<Pubkey, u64>>> {
5221        Some(self.epoch_stakes.get(&epoch)?.stakes().staked_nodes())
5222    }
5223
5224    /// vote accounts for the specific epoch along with the stake
5225    ///   attributed to each account
5226    pub fn epoch_vote_accounts(
5227        &self,
5228        epoch: Epoch,
5229    ) -> Option<&HashMap<Pubkey, (u64, VoteAccount)>> {
5230        let epoch_stakes = self.epoch_stakes.get(&epoch)?.stakes();
5231        Some(epoch_stakes.vote_accounts().as_ref())
5232    }
5233
5234    /// Get the fixed authorized voter for the given vote account for the
5235    /// current epoch
5236    pub fn epoch_authorized_voter(&self, vote_account: &Pubkey) -> Option<&Pubkey> {
5237        self.epoch_stakes
5238            .get(&self.epoch)
5239            .expect("Epoch stakes for bank's own epoch must exist")
5240            .epoch_authorized_voters()
5241            .get(vote_account)
5242    }
5243
5244    /// Get the fixed set of vote accounts for the given node id for the
5245    /// current epoch
5246    pub fn epoch_vote_accounts_for_node_id(&self, node_id: &Pubkey) -> Option<&NodeVoteAccounts> {
5247        self.epoch_stakes
5248            .get(&self.epoch)
5249            .expect("Epoch stakes for bank's own epoch must exist")
5250            .node_id_to_vote_accounts()
5251            .get(node_id)
5252    }
5253
5254    /// Get the fixed total stake of all vote accounts for current epoch
5255    pub fn total_epoch_stake(&self) -> u64 {
5256        self.epoch_stakes
5257            .get(&self.epoch)
5258            .expect("Epoch stakes for bank's own epoch must exist")
5259            .total_stake()
5260    }
5261
5262    /// Get the fixed stake of the given vote account for the current epoch
5263    pub fn epoch_vote_account_stake(&self, vote_account: &Pubkey) -> u64 {
5264        *self
5265            .epoch_vote_accounts(self.epoch())
5266            .expect("Bank epoch vote accounts must contain entry for the bank's own epoch")
5267            .get(vote_account)
5268            .map(|(stake, _)| stake)
5269            .unwrap_or(&0)
5270    }
5271
5272    /// given a slot, return the epoch and offset into the epoch this slot falls
5273    /// e.g. with a fixed number for slots_per_epoch, the calculation is simply:
5274    ///
5275    ///  ( slot/slots_per_epoch, slot % slots_per_epoch )
5276    ///
5277    pub fn get_epoch_and_slot_index(&self, slot: Slot) -> (Epoch, SlotIndex) {
5278        self.epoch_schedule.get_epoch_and_slot_index(slot)
5279    }
5280
5281    pub fn get_epoch_info(&self) -> EpochInfo {
5282        let absolute_slot = self.slot();
5283        let block_height = self.block_height();
5284        let (epoch, slot_index) = self.get_epoch_and_slot_index(absolute_slot);
5285        let slots_in_epoch = self.get_slots_in_epoch(epoch);
5286        let transaction_count = Some(self.transaction_count());
5287        EpochInfo {
5288            epoch,
5289            slot_index,
5290            slots_in_epoch,
5291            absolute_slot,
5292            block_height,
5293            transaction_count,
5294        }
5295    }
5296
5297    pub fn is_empty(&self) -> bool {
5298        !self.is_delta.load(Relaxed)
5299    }
5300
5301    /// Add an instruction processor to intercept instructions before the dynamic loader.
5302    pub fn add_builtin(
5303        &mut self,
5304        name: &str,
5305        program_id: Pubkey,
5306        process_instruction_with_context: ProcessInstructionWithContext,
5307    ) {
5308        debug!("Adding program {} under {:?}", name, program_id);
5309        self.add_native_program(name, &program_id, false);
5310        self.message_processor
5311            .add_program(program_id, process_instruction_with_context);
5312    }
5313
5314    /// Replace a builtin instruction processor if it already exists
5315    pub fn replace_builtin(
5316        &mut self,
5317        name: &str,
5318        program_id: Pubkey,
5319        process_instruction_with_context: ProcessInstructionWithContext,
5320    ) {
5321        debug!("Replacing program {} under {:?}", name, program_id);
5322        self.add_native_program(name, &program_id, true);
5323        self.message_processor
5324            .add_program(program_id, process_instruction_with_context);
5325    }
5326
5327    pub fn clean_accounts(
5328        &self,
5329        skip_last: bool,
5330        is_startup: bool,
5331        last_full_snapshot_slot: Option<Slot>,
5332    ) {
5333        // Don't clean the slot we're snapshotting because it may have zero-carat
5334        // accounts that were included in the bank delta hash when the bank was frozen,
5335        // and if we clean them here, any newly created snapshot's hash for this bank
5336        // may not match the frozen hash.
5337        //
5338        // So when we're snapshotting, set `skip_last` to true so the highest slot to clean is
5339        // lowered by one.
5340        let highest_slot_to_clean = skip_last.then(|| self.slot().saturating_sub(1));
5341
5342        self.rc.accounts.accounts_db.clean_accounts(
5343            highest_slot_to_clean,
5344            is_startup,
5345            last_full_snapshot_slot,
5346        );
5347    }
5348
5349    pub fn shrink_all_slots(&self, is_startup: bool, last_full_snapshot_slot: Option<Slot>) {
5350        self.rc
5351            .accounts
5352            .accounts_db
5353            .shrink_all_slots(is_startup, last_full_snapshot_slot);
5354    }
5355
5356    pub fn print_accounts_stats(&self) {
5357        self.rc.accounts.accounts_db.print_accounts_stats("");
5358    }
5359
5360    pub fn process_stale_slot_with_budget(
5361        &self,
5362        mut consumed_budget: usize,
5363        budget_recovery_delta: usize,
5364    ) -> usize {
5365        if consumed_budget == 0 {
5366            let shrunken_account_count = self.rc.accounts.accounts_db.process_stale_slot_v1();
5367            if shrunken_account_count > 0 {
5368                datapoint_info!(
5369                    "stale_slot_shrink",
5370                    ("accounts", shrunken_account_count, i64)
5371                );
5372                consumed_budget += shrunken_account_count;
5373            }
5374        }
5375        consumed_budget.saturating_sub(budget_recovery_delta)
5376    }
5377
5378    pub fn shrink_candidate_slots(&self) -> usize {
5379        self.rc.accounts.accounts_db.shrink_candidate_slots()
5380    }
5381
5382    pub fn no_overflow_rent_distribution_enabled(&self) -> bool {
5383        self.feature_set
5384            .is_active(&feature_set::no_overflow_rent_distribution::id())
5385    }
5386
5387    pub fn check_init_vote_data_enabled(&self) -> bool {
5388        self.feature_set
5389            .is_active(&feature_set::check_init_vote_data::id())
5390    }
5391
5392    pub fn verify_tx_signatures_len_enabled(&self) -> bool {
5393        self.feature_set
5394            .is_active(&feature_set::verify_tx_signatures_len::id())
5395    }
5396
5397    pub fn merge_nonce_error_into_system_error(&self) -> bool {
5398        self.feature_set
5399            .is_active(&feature_set::merge_nonce_error_into_system_error::id())
5400    }
5401
5402    pub fn versioned_tx_message_enabled(&self) -> bool {
5403        self.feature_set
5404            .is_active(&feature_set::versioned_tx_message_enabled::id())
5405    }
5406
5407    pub fn stake_program_advance_activating_credits_observed(&self) -> bool {
5408        self.feature_set
5409            .is_active(&feature_set::stake_program_advance_activating_credits_observed::id())
5410    }
5411
5412    pub fn demote_program_write_locks(&self) -> bool {
5413        self.feature_set
5414            .is_active(&feature_set::demote_program_write_locks::id())
5415    }
5416
5417    pub fn stakes_remove_delegation_if_inactive_enabled(&self) -> bool {
5418        self.feature_set
5419            .is_active(&feature_set::stakes_remove_delegation_if_inactive::id())
5420    }
5421
5422    // Check if the wallclock time from bank creation to now has exceeded the allotted
5423    // time for transaction processing
5424    pub fn should_bank_still_be_processing_txs(
5425        bank_creation_time: &Instant,
5426        max_tx_ingestion_nanos: u128,
5427    ) -> bool {
5428        // Do this check outside of the poh lock, hence not a method on PohRecorder
5429        bank_creation_time.elapsed().as_nanos() <= max_tx_ingestion_nanos
5430    }
5431
5432    pub fn deactivate_feature(&mut self, id: &Pubkey) {
5433        let mut feature_set = Arc::make_mut(&mut self.feature_set).clone();
5434        feature_set.active.remove(id);
5435        feature_set.inactive.insert(*id);
5436        self.feature_set = Arc::new(feature_set);
5437    }
5438
5439    pub fn activate_feature(&mut self, id: &Pubkey) {
5440        let mut feature_set = Arc::make_mut(&mut self.feature_set).clone();
5441        feature_set.inactive.remove(id);
5442        feature_set.active.insert(*id, 0);
5443        self.feature_set = Arc::new(feature_set);
5444    }
5445
5446    pub fn fill_bank_with_ticks(&self) {
5447        let parent_distance = if self.slot() == 0 {
5448            1
5449        } else {
5450            self.slot() - self.parent_slot()
5451        };
5452        for _ in 0..parent_distance {
5453            let last_blockhash = self.last_blockhash();
5454            while self.last_blockhash() == last_blockhash {
5455                self.register_tick(&Hash::new_unique())
5456            }
5457        }
5458    }
5459
5460    // This is called from snapshot restore AND for each epoch boundary
5461    // The entire code path herein must be idempotent
5462    fn apply_feature_activations(
5463        &mut self,
5464        init_finish_or_warp: bool,
5465        debug_do_not_add_builtins: bool,
5466    ) {
5467        let new_feature_activations = self.compute_active_feature_set(!init_finish_or_warp);
5468
5469        if new_feature_activations.contains(&feature_set::pico_inflation::id()) {
5470            *self.inflation.write().unwrap() = Inflation::pico();
5471            self.fee_rate_governor.burn_percent = 50; // 50% fee burn
5472            self.rent_collector.rent.burn_percent = 50; // 50% rent burn
5473        }
5474
5475        if !new_feature_activations.is_disjoint(&self.feature_set.full_inflation_features_enabled())
5476        {
5477            *self.inflation.write().unwrap() = Inflation::full();
5478            self.fee_rate_governor.burn_percent = 50; // 50% fee burn
5479            self.rent_collector.rent.burn_percent = 50; // 50% rent burn
5480        }
5481
5482        if new_feature_activations.contains(&feature_set::spl_token_v2_set_authority_fix::id()) {
5483            self.apply_spl_token_v2_set_authority_fix();
5484        }
5485        if new_feature_activations.contains(&feature_set::rent_for_sysvars::id()) {
5486            // when this feature is activated, immediately all of existing sysvars are susceptible
5487            // to rent collection and account data removal due to insufficient balance due to only
5488            // having 1 carat.
5489            // so before any is accessed, reset the balance to be rent-exempt here at the same
5490            // timing when perpetual balance adjustment is started in update_sysvar_account().
5491            self.reset_all_sysvar_balances();
5492        }
5493
5494        if !debug_do_not_add_builtins {
5495            self.ensure_feature_builtins(init_finish_or_warp, &new_feature_activations);
5496            self.reconfigure_token2_native_mint();
5497        }
5498        self.ensure_no_storage_rewards_pool();
5499    }
5500
5501    fn reset_all_sysvar_balances(&self) {
5502        for sysvar_id in &[
5503            sysvar::clock::id(),
5504            sysvar::epoch_schedule::id(),
5505            #[allow(deprecated)]
5506            sysvar::fees::id(),
5507            #[allow(deprecated)]
5508            sysvar::recent_blockhashes::id(),
5509            sysvar::rent::id(),
5510            sysvar::rewards::id(),
5511            sysvar::slot_hashes::id(),
5512            sysvar::slot_history::id(),
5513            sysvar::stake_history::id(),
5514        ] {
5515            if let Some(mut account) = self.get_account(sysvar_id) {
5516                let (old_data_len, old_carats) = (account.data().len(), account.carats());
5517                self.adjust_sysvar_balance_for_rent(&mut account);
5518                info!(
5519                    "reset_all_sysvar_balances (slot: {}): {} ({} bytes) is reset from {} to {}",
5520                    self.slot(),
5521                    sysvar_id,
5522                    old_data_len,
5523                    old_carats,
5524                    account.carats()
5525                );
5526                self.store_account_and_update_capitalization(sysvar_id, &account);
5527            }
5528        }
5529    }
5530
5531    fn adjust_sysvar_balance_for_rent(&self, account: &mut AccountSharedData) {
5532        account.set_carats(
5533            self.get_minimum_balance_for_rent_exemption(account.data().len())
5534                .max(account.carats()),
5535        );
5536    }
5537
5538    // Compute the active feature set based on the current bank state, and return the set of newly activated features
5539    fn compute_active_feature_set(&mut self, allow_new_activations: bool) -> HashSet<Pubkey> {
5540        let mut active = self.feature_set.active.clone();
5541        let mut inactive = HashSet::new();
5542        let mut newly_activated = HashSet::new();
5543        let slot = self.slot();
5544
5545        for feature_id in &self.feature_set.inactive {
5546            let mut activated = None;
5547            if let Some(mut account) = self.get_account_with_fixed_root(feature_id) {
5548                if let Some(mut feature) = feature::from_account(&account) {
5549                    match feature.activated_at {
5550                        None => {
5551                            if allow_new_activations {
5552                                // Feature has been requested, activate it now
5553                                feature.activated_at = Some(slot);
5554                                if feature::to_account(&feature, &mut account).is_some() {
5555                                    self.store_account(feature_id, &account);
5556                                }
5557                                newly_activated.insert(*feature_id);
5558                                activated = Some(slot);
5559                                info!("Feature {} activated at slot {}", feature_id, slot);
5560                            }
5561                        }
5562                        Some(activation_slot) => {
5563                            if slot >= activation_slot {
5564                                // Feature is already active
5565                                activated = Some(activation_slot);
5566                            }
5567                        }
5568                    }
5569                }
5570            }
5571            if let Some(slot) = activated {
5572                active.insert(*feature_id, slot);
5573            } else {
5574                inactive.insert(*feature_id);
5575            }
5576        }
5577
5578        self.feature_set = Arc::new(FeatureSet { active, inactive });
5579        newly_activated
5580    }
5581
5582    fn ensure_feature_builtins(
5583        &mut self,
5584        init_or_warp: bool,
5585        new_feature_activations: &HashSet<Pubkey>,
5586    ) {
5587        let feature_builtins = self.feature_builtins.clone();
5588        for (builtin, feature, activation_type) in feature_builtins.iter() {
5589            let should_populate = init_or_warp && self.feature_set.is_active(feature)
5590                || !init_or_warp && new_feature_activations.contains(feature);
5591            if should_populate {
5592                match activation_type {
5593                    ActivationType::NewProgram => self.add_builtin(
5594                        &builtin.name,
5595                        builtin.id,
5596                        builtin.process_instruction_with_context,
5597                    ),
5598                    ActivationType::NewVersion => self.replace_builtin(
5599                        &builtin.name,
5600                        builtin.id,
5601                        builtin.process_instruction_with_context,
5602                    ),
5603                }
5604            }
5605        }
5606    }
5607
5608    fn apply_spl_token_v2_set_authority_fix(&mut self) {
5609        if let Some(old_account) = self.get_account_with_fixed_root(&inline_spl_token_v2_0::id()) {
5610            if let Some(new_account) =
5611                self.get_account_with_fixed_root(&inline_spl_token_v2_0::new_token_program::id())
5612            {
5613                datapoint_info!(
5614                    "bank-apply_spl_token_v2_set_authority_fix",
5615                    ("slot", self.slot, i64),
5616                );
5617
5618                // Burn carats in the old token account
5619                self.capitalization
5620                    .fetch_sub(old_account.carats(), Relaxed);
5621
5622                // Transfer new token account to old token account
5623                self.store_account(&inline_spl_token_v2_0::id(), &new_account);
5624
5625                // Clear new token account
5626                self.store_account(
5627                    &inline_spl_token_v2_0::new_token_program::id(),
5628                    &AccountSharedData::default(),
5629                );
5630
5631                self.remove_executor(&inline_spl_token_v2_0::id());
5632            }
5633        }
5634    }
5635    fn reconfigure_token2_native_mint(&mut self) {
5636        let reconfigure_token2_native_mint = match self.cluster_type() {
5637            ClusterType::Development => true,
5638            ClusterType::Devnet => true,
5639            ClusterType::Testnet => self.epoch() == 93,
5640            ClusterType::MainnetBeta => self.epoch() == 75,
5641        };
5642
5643        if reconfigure_token2_native_mint {
5644            let mut native_mint_account = gemachain_sdk::account::AccountSharedData::from(Account {
5645                owner: inline_spl_token_v2_0::id(),
5646                data: inline_spl_token_v2_0::native_mint::ACCOUNT_DATA.to_vec(),
5647                carats: gema_to_carats(1.),
5648                executable: false,
5649                rent_epoch: self.epoch() + 1,
5650            });
5651
5652            // As a workaround for
5653            // https://github.com/gemacoin/gemachain-program-library/issues/374, ensure that the
5654            // spl-token 2 native mint account is owned by the spl-token 2 program.
5655            let store = if let Some(existing_native_mint_account) =
5656                self.get_account_with_fixed_root(&inline_spl_token_v2_0::native_mint::id())
5657            {
5658                if existing_native_mint_account.owner() == &gemachain_sdk::system_program::id() {
5659                    native_mint_account.set_carats(existing_native_mint_account.carats());
5660                    true
5661                } else {
5662                    false
5663                }
5664            } else {
5665                self.capitalization
5666                    .fetch_add(native_mint_account.carats(), Relaxed);
5667                true
5668            };
5669
5670            if store {
5671                self.store_account(
5672                    &inline_spl_token_v2_0::native_mint::id(),
5673                    &native_mint_account,
5674                );
5675            }
5676        }
5677    }
5678
5679    fn ensure_no_storage_rewards_pool(&mut self) {
5680        let purge_window_epoch = match self.cluster_type() {
5681            ClusterType::Development => false,
5682            // never do this for devnet; we're pristine here. :)
5683            ClusterType::Devnet => false,
5684            // schedule to remove at testnet/tds
5685            ClusterType::Testnet => self.epoch() == 93,
5686            // never do this for stable; we're pristine here. :)
5687            ClusterType::MainnetBeta => false,
5688        };
5689
5690        if purge_window_epoch {
5691            for reward_pubkey in self.rewards_pool_pubkeys.iter() {
5692                if let Some(mut reward_account) = self.get_account_with_fixed_root(reward_pubkey) {
5693                    if reward_account.carats() == u64::MAX {
5694                        reward_account.set_carats(0);
5695                        self.store_account(reward_pubkey, &reward_account);
5696                        // Adjust capitalization.... it has been wrapping, reducing the real capitalization by 1-carat
5697                        self.capitalization.fetch_add(1, Relaxed);
5698                        info!(
5699                            "purged rewards pool accont: {}, new capitalization: {}",
5700                            reward_pubkey,
5701                            self.capitalization()
5702                        );
5703                    }
5704                };
5705            }
5706        }
5707    }
5708
5709    fn rent_for_sysvars(&self) -> bool {
5710        self.feature_set
5711            .is_active(&feature_set::rent_for_sysvars::id())
5712    }
5713}
5714
5715impl Drop for Bank {
5716    fn drop(&mut self) {
5717        if let Some(drop_callback) = self.drop_callback.read().unwrap().0.as_ref() {
5718            drop_callback.callback(self);
5719        } else {
5720            // Default case
5721            // 1. Tests
5722            // 2. At startup when replaying blockstore and there's no
5723            // AccountsBackgroundService to perform cleanups yet.
5724            self.rc
5725                .accounts
5726                .purge_slot(self.slot(), self.bank_id(), false);
5727        }
5728    }
5729}
5730
5731pub fn goto_end_of_slot(bank: &mut Bank) {
5732    let mut tick_hash = bank.last_blockhash();
5733    loop {
5734        tick_hash = hashv(&[tick_hash.as_ref(), &[42]]);
5735        bank.register_tick(&tick_hash);
5736        if tick_hash == bank.last_blockhash() {
5737            bank.freeze();
5738            return;
5739        }
5740    }
5741}
5742
5743pub fn is_simple_vote_transaction(transaction: &SanitizedTransaction) -> bool {
5744    if transaction.message().instructions().len() == 1 {
5745        let (program_pubkey, instruction) = transaction
5746            .message()
5747            .program_instructions_iter()
5748            .next()
5749            .unwrap();
5750        if program_pubkey == &gemachain_vote_program::id() {
5751            if let Ok(vote_instruction) = limited_deserialize::<VoteInstruction>(&instruction.data)
5752            {
5753                return matches!(
5754                    vote_instruction,
5755                    VoteInstruction::Vote(_) | VoteInstruction::VoteSwitch(_, _)
5756                );
5757            }
5758        }
5759    }
5760    false
5761}
5762
5763#[cfg(test)]
5764pub(crate) mod tests {
5765    use super::*;
5766    use crate::{
5767        accounts_background_service::{AbsRequestHandler, SendDroppedBankCallback},
5768        accounts_db::DEFAULT_ACCOUNTS_SHRINK_RATIO,
5769        accounts_index::{AccountIndex, AccountSecondaryIndexes, ScanError, ITER_BATCH_SIZE},
5770        ancestors::Ancestors,
5771        genesis_utils::{
5772            activate_all_features, bootstrap_validator_stake_carats,
5773            create_genesis_config_with_leader, create_genesis_config_with_vote_accounts,
5774            GenesisConfigInfo, ValidatorVoteKeypairs,
5775        },
5776        status_cache::MAX_CACHE_ENTRIES,
5777    };
5778    use crossbeam_channel::{bounded, unbounded};
5779    use gemachain_program_runtime::NativeLoaderError;
5780    #[allow(deprecated)]
5781    use gemachain_sdk::sysvar::fees::Fees;
5782    use gemachain_sdk::{
5783        account::Account,
5784        clock::{DEFAULT_SLOTS_PER_EPOCH, DEFAULT_TICKS_PER_SLOT},
5785        compute_budget::ComputeBudgetInstruction,
5786        epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
5787        feature::Feature,
5788        genesis_config::create_genesis_config,
5789        hash,
5790        instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
5791        message::{Message, MessageHeader},
5792        nonce,
5793        poh_config::PohConfig,
5794        process_instruction::InvokeContext,
5795        rent::Rent,
5796        signature::{keypair_from_seed, Keypair, Signer},
5797        stake::{
5798            instruction as stake_instruction,
5799            state::{Authorized, Delegation, Lockup, Stake},
5800        },
5801        system_instruction::{self, SystemError},
5802        system_program,
5803        sysvar::rewards::Rewards,
5804        timing::duration_as_s,
5805    };
5806    use gemachain_vote_program::{
5807        vote_instruction,
5808        vote_state::{
5809            self, BlockTimestamp, Vote, VoteInit, VoteState, VoteStateVersions, MAX_LOCKOUT_HISTORY,
5810        },
5811    };
5812    use std::{result, thread::Builder, time::Duration};
5813
5814    fn new_sanitized_message(
5815        instructions: &[Instruction],
5816        payer: Option<&Pubkey>,
5817    ) -> SanitizedMessage {
5818        Message::new(instructions, payer).try_into().unwrap()
5819    }
5820
5821    #[test]
5822    fn test_nonce_rollback_info() {
5823        let nonce_authority = keypair_from_seed(&[0; 32]).unwrap();
5824        let nonce_address = nonce_authority.pubkey();
5825        let fee_calculator = FeeCalculator::new(42);
5826        let state =
5827            nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data {
5828                authority: Pubkey::default(),
5829                blockhash: Hash::new_unique(),
5830                fee_calculator: fee_calculator.clone(),
5831            }));
5832        let nonce_account = AccountSharedData::new_data(43, &state, &system_program::id()).unwrap();
5833
5834        // NonceRollbackPartial create + NonceRollbackInfo impl
5835        let partial = NonceRollbackPartial::new(nonce_address, nonce_account.clone());
5836        assert_eq!(*partial.nonce_address(), nonce_address);
5837        assert_eq!(*partial.nonce_account(), nonce_account);
5838        assert_eq!(partial.fee_calculator(), Some(fee_calculator.clone()));
5839        assert_eq!(partial.fee_account(), None);
5840
5841        let from = keypair_from_seed(&[1; 32]).unwrap();
5842        let from_address = from.pubkey();
5843        let to_address = Pubkey::new_unique();
5844        let instructions = vec![
5845            system_instruction::advance_nonce_account(&nonce_address, &nonce_authority.pubkey()),
5846            system_instruction::transfer(&from_address, &to_address, 42),
5847        ];
5848        let message = new_sanitized_message(&instructions, Some(&from_address));
5849
5850        let from_account = AccountSharedData::new(44, 0, &Pubkey::default());
5851        let to_account = AccountSharedData::new(45, 0, &Pubkey::default());
5852        let recent_blockhashes_sysvar_account = AccountSharedData::new(4, 0, &Pubkey::default());
5853        let accounts = [
5854            (*message.get_account_key(0).unwrap(), from_account.clone()),
5855            (*message.get_account_key(1).unwrap(), nonce_account.clone()),
5856            (*message.get_account_key(2).unwrap(), to_account.clone()),
5857            (
5858                *message.get_account_key(3).unwrap(),
5859                recent_blockhashes_sysvar_account.clone(),
5860            ),
5861        ];
5862
5863        // NonceRollbackFull create + NonceRollbackInfo impl
5864        let full = NonceRollbackFull::from_partial(partial.clone(), &message, &accounts).unwrap();
5865        assert_eq!(*full.nonce_address(), nonce_address);
5866        assert_eq!(*full.nonce_account(), nonce_account);
5867        assert_eq!(full.fee_calculator(), Some(fee_calculator));
5868        assert_eq!(full.fee_account(), Some(&from_account));
5869
5870        let message = new_sanitized_message(&instructions, Some(&nonce_address));
5871        let accounts = [
5872            (*message.get_account_key(0).unwrap(), nonce_account),
5873            (*message.get_account_key(1).unwrap(), from_account),
5874            (*message.get_account_key(2).unwrap(), to_account),
5875            (
5876                *message.get_account_key(3).unwrap(),
5877                recent_blockhashes_sysvar_account,
5878            ),
5879        ];
5880
5881        // Nonce account is fee-payer
5882        let full = NonceRollbackFull::from_partial(partial.clone(), &message, &accounts).unwrap();
5883        assert_eq!(full.fee_account(), None);
5884
5885        // NonceRollbackFull create, fee-payer not in account_keys fails
5886        assert_eq!(
5887            NonceRollbackFull::from_partial(partial, &message, &[]).unwrap_err(),
5888            TransactionError::AccountNotFound,
5889        );
5890    }
5891
5892    #[test]
5893    fn test_bank_unix_timestamp_from_genesis() {
5894        let (genesis_config, _mint_keypair) = create_genesis_config(1);
5895        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
5896
5897        assert_eq!(
5898            genesis_config.creation_time,
5899            bank.unix_timestamp_from_genesis()
5900        );
5901        let slots_per_sec = 1.0
5902            / (duration_as_s(&genesis_config.poh_config.target_tick_duration)
5903                * genesis_config.ticks_per_slot as f32);
5904
5905        for _i in 0..slots_per_sec as usize + 1 {
5906            bank = Arc::new(new_from_parent(&bank));
5907        }
5908
5909        assert!(bank.unix_timestamp_from_genesis() - genesis_config.creation_time >= 1);
5910    }
5911
5912    #[test]
5913    #[allow(clippy::float_cmp)]
5914    fn test_bank_new() {
5915        let dummy_leader_pubkey = gemachain_sdk::pubkey::new_rand();
5916        let dummy_leader_stake_carats = bootstrap_validator_stake_carats();
5917        let mint_carats = 10_000;
5918        let GenesisConfigInfo {
5919            mut genesis_config,
5920            mint_keypair,
5921            voting_keypair,
5922            ..
5923        } = create_genesis_config_with_leader(
5924            mint_carats,
5925            &dummy_leader_pubkey,
5926            dummy_leader_stake_carats,
5927        );
5928
5929        genesis_config.rent = Rent {
5930            carats_per_byte_year: 5,
5931            exemption_threshold: 1.2,
5932            burn_percent: 5,
5933        };
5934
5935        let bank = Bank::new_for_tests(&genesis_config);
5936        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), mint_carats);
5937        assert_eq!(
5938            bank.get_balance(&voting_keypair.pubkey()),
5939            dummy_leader_stake_carats /* 1 token goes to the vote account associated with dummy_leader_carats */
5940        );
5941
5942        let rent_account = bank.get_account(&sysvar::rent::id()).unwrap();
5943        let rent = from_account::<sysvar::rent::Rent, _>(&rent_account).unwrap();
5944
5945        assert_eq!(rent.burn_percent, 5);
5946        assert_eq!(rent.exemption_threshold, 1.2);
5947        assert_eq!(rent.carats_per_byte_year, 5);
5948    }
5949
5950    #[test]
5951    fn test_bank_block_height() {
5952        let (genesis_config, _mint_keypair) = create_genesis_config(1);
5953        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
5954        assert_eq!(bank0.block_height(), 0);
5955        let bank1 = Arc::new(new_from_parent(&bank0));
5956        assert_eq!(bank1.block_height(), 1);
5957    }
5958
5959    #[test]
5960    fn test_bank_update_epoch_stakes() {
5961        impl Bank {
5962            fn epoch_stake_keys(&self) -> Vec<Epoch> {
5963                let mut keys: Vec<Epoch> = self.epoch_stakes.keys().copied().collect();
5964                keys.sort_unstable();
5965                keys
5966            }
5967
5968            fn epoch_stake_key_info(&self) -> (Epoch, Epoch, usize) {
5969                let mut keys: Vec<Epoch> = self.epoch_stakes.keys().copied().collect();
5970                keys.sort_unstable();
5971                (*keys.first().unwrap(), *keys.last().unwrap(), keys.len())
5972            }
5973        }
5974
5975        let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
5976        let mut bank = Bank::new_for_tests(&genesis_config);
5977
5978        let initial_epochs = bank.epoch_stake_keys();
5979        assert_eq!(initial_epochs, vec![0, 1]);
5980
5981        for existing_epoch in &initial_epochs {
5982            bank.update_epoch_stakes(*existing_epoch);
5983            assert_eq!(bank.epoch_stake_keys(), initial_epochs);
5984        }
5985
5986        for epoch in (initial_epochs.len() as Epoch)..MAX_LEADER_SCHEDULE_STAKES {
5987            bank.update_epoch_stakes(epoch);
5988            assert_eq!(bank.epoch_stakes.len() as Epoch, epoch + 1);
5989        }
5990
5991        assert_eq!(
5992            bank.epoch_stake_key_info(),
5993            (
5994                0,
5995                MAX_LEADER_SCHEDULE_STAKES - 1,
5996                MAX_LEADER_SCHEDULE_STAKES as usize
5997            )
5998        );
5999
6000        bank.update_epoch_stakes(MAX_LEADER_SCHEDULE_STAKES);
6001        assert_eq!(
6002            bank.epoch_stake_key_info(),
6003            (
6004                0,
6005                MAX_LEADER_SCHEDULE_STAKES,
6006                MAX_LEADER_SCHEDULE_STAKES as usize + 1
6007            )
6008        );
6009
6010        bank.update_epoch_stakes(MAX_LEADER_SCHEDULE_STAKES + 1);
6011        assert_eq!(
6012            bank.epoch_stake_key_info(),
6013            (
6014                1,
6015                MAX_LEADER_SCHEDULE_STAKES + 1,
6016                MAX_LEADER_SCHEDULE_STAKES as usize + 1
6017            )
6018        );
6019    }
6020
6021    #[test]
6022    fn test_bank_capitalization() {
6023        let bank0 = Arc::new(Bank::new_for_tests(&GenesisConfig {
6024            accounts: (0..42)
6025                .map(|_| {
6026                    (
6027                        gemachain_sdk::pubkey::new_rand(),
6028                        Account::new(42, 0, &Pubkey::default()),
6029                    )
6030                })
6031                .collect(),
6032            cluster_type: ClusterType::MainnetBeta,
6033            ..GenesisConfig::default()
6034        }));
6035        let sysvar_and_native_program_delta0 = 11;
6036        assert_eq!(
6037            bank0.capitalization(),
6038            42 * 42 + sysvar_and_native_program_delta0
6039        );
6040        let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
6041        let sysvar_and_native_program_delta1 = 2;
6042        assert_eq!(
6043            bank1.capitalization(),
6044            42 * 42 + sysvar_and_native_program_delta0 + sysvar_and_native_program_delta1,
6045        );
6046    }
6047
6048    #[test]
6049    fn test_credit_debit_rent_no_side_effect_on_hash() {
6050        gemachain_logger::setup();
6051
6052        let (mut genesis_config, _mint_keypair) = create_genesis_config(10);
6053        let keypair1: Keypair = Keypair::new();
6054        let keypair2: Keypair = Keypair::new();
6055        let keypair3: Keypair = Keypair::new();
6056        let keypair4: Keypair = Keypair::new();
6057
6058        // Transaction between these two keypairs will fail
6059        let keypair5: Keypair = Keypair::new();
6060        let keypair6: Keypair = Keypair::new();
6061
6062        genesis_config.rent = Rent {
6063            carats_per_byte_year: 1,
6064            exemption_threshold: 21.0,
6065            burn_percent: 10,
6066        };
6067
6068        let root_bank = Arc::new(Bank::new_for_tests(&genesis_config));
6069        let bank = Bank::new_from_parent(
6070            &root_bank,
6071            &Pubkey::default(),
6072            years_as_slots(
6073                2.0,
6074                &genesis_config.poh_config.target_tick_duration,
6075                genesis_config.ticks_per_slot,
6076            ) as u64,
6077        );
6078
6079        let root_bank_2 = Arc::new(Bank::new_for_tests(&genesis_config));
6080        let bank_with_success_txs = Bank::new_from_parent(
6081            &root_bank_2,
6082            &Pubkey::default(),
6083            years_as_slots(
6084                2.0,
6085                &genesis_config.poh_config.target_tick_duration,
6086                genesis_config.ticks_per_slot,
6087            ) as u64,
6088        );
6089
6090        assert_eq!(bank.last_blockhash(), genesis_config.hash());
6091
6092        // Initialize credit-debit and credit only accounts
6093        let account1 = AccountSharedData::new(264, 0, &Pubkey::default());
6094        let account2 = AccountSharedData::new(264, 1, &Pubkey::default());
6095        let account3 = AccountSharedData::new(264, 0, &Pubkey::default());
6096        let account4 = AccountSharedData::new(264, 1, &Pubkey::default());
6097        let account5 = AccountSharedData::new(10, 0, &Pubkey::default());
6098        let account6 = AccountSharedData::new(10, 1, &Pubkey::default());
6099
6100        bank.store_account(&keypair1.pubkey(), &account1);
6101        bank.store_account(&keypair2.pubkey(), &account2);
6102        bank.store_account(&keypair3.pubkey(), &account3);
6103        bank.store_account(&keypair4.pubkey(), &account4);
6104        bank.store_account(&keypair5.pubkey(), &account5);
6105        bank.store_account(&keypair6.pubkey(), &account6);
6106
6107        bank_with_success_txs.store_account(&keypair1.pubkey(), &account1);
6108        bank_with_success_txs.store_account(&keypair2.pubkey(), &account2);
6109        bank_with_success_txs.store_account(&keypair3.pubkey(), &account3);
6110        bank_with_success_txs.store_account(&keypair4.pubkey(), &account4);
6111        bank_with_success_txs.store_account(&keypair5.pubkey(), &account5);
6112        bank_with_success_txs.store_account(&keypair6.pubkey(), &account6);
6113
6114        // Make native instruction loader rent exempt
6115        let system_program_id = system_program::id();
6116        let mut system_program_account = bank.get_account(&system_program_id).unwrap();
6117        system_program_account.set_carats(
6118            bank.get_minimum_balance_for_rent_exemption(system_program_account.data().len()),
6119        );
6120        bank.store_account(&system_program_id, &system_program_account);
6121        bank_with_success_txs.store_account(&system_program_id, &system_program_account);
6122
6123        let t1 =
6124            system_transaction::transfer(&keypair1, &keypair2.pubkey(), 1, genesis_config.hash());
6125        let t2 =
6126            system_transaction::transfer(&keypair3, &keypair4.pubkey(), 1, genesis_config.hash());
6127        let t3 =
6128            system_transaction::transfer(&keypair5, &keypair6.pubkey(), 1, genesis_config.hash());
6129
6130        let txs = vec![t1.clone(), t2.clone(), t3];
6131        let res = bank.process_transactions(txs.iter());
6132
6133        assert_eq!(res.len(), 3);
6134        assert_eq!(res[0], Ok(()));
6135        assert_eq!(res[1], Ok(()));
6136        assert_eq!(res[2], Err(TransactionError::AccountNotFound));
6137
6138        bank.freeze();
6139
6140        let rwlockguard_bank_hash = bank.hash.read().unwrap();
6141        let bank_hash = rwlockguard_bank_hash.as_ref();
6142
6143        let txs = vec![t2, t1];
6144        let res = bank_with_success_txs.process_transactions(txs.iter());
6145
6146        assert_eq!(res.len(), 2);
6147        assert_eq!(res[0], Ok(()));
6148        assert_eq!(res[1], Ok(()));
6149
6150        bank_with_success_txs.freeze();
6151
6152        let rwlockguard_bank_with_success_txs_hash = bank_with_success_txs.hash.read().unwrap();
6153        let bank_with_success_txs_hash = rwlockguard_bank_with_success_txs_hash.as_ref();
6154
6155        assert_eq!(bank_with_success_txs_hash, bank_hash);
6156    }
6157
6158    #[derive(Serialize, Deserialize)]
6159    enum MockInstruction {
6160        Deduction,
6161    }
6162
6163    fn mock_process_instruction(
6164        _program_id: &Pubkey,
6165        data: &[u8],
6166        invoke_context: &mut dyn InvokeContext,
6167    ) -> result::Result<(), InstructionError> {
6168        let keyed_accounts = invoke_context.get_keyed_accounts()?;
6169        if let Ok(instruction) = bincode::deserialize(data) {
6170            match instruction {
6171                MockInstruction::Deduction => {
6172                    keyed_accounts[1]
6173                        .account
6174                        .borrow_mut()
6175                        .checked_add_carats(1)?;
6176                    keyed_accounts[2]
6177                        .account
6178                        .borrow_mut()
6179                        .checked_sub_carats(1)?;
6180                    Ok(())
6181                }
6182            }
6183        } else {
6184            Err(InstructionError::InvalidInstructionData)
6185        }
6186    }
6187
6188    fn create_mock_transaction(
6189        payer: &Keypair,
6190        keypair1: &Keypair,
6191        keypair2: &Keypair,
6192        read_only_keypair: &Keypair,
6193        mock_program_id: Pubkey,
6194        recent_blockhash: Hash,
6195    ) -> Transaction {
6196        let account_metas = vec![
6197            AccountMeta::new(payer.pubkey(), true),
6198            AccountMeta::new(keypair1.pubkey(), true),
6199            AccountMeta::new(keypair2.pubkey(), true),
6200            AccountMeta::new_readonly(read_only_keypair.pubkey(), false),
6201        ];
6202        let deduct_instruction = Instruction::new_with_bincode(
6203            mock_program_id,
6204            &MockInstruction::Deduction,
6205            account_metas,
6206        );
6207        Transaction::new_signed_with_payer(
6208            &[deduct_instruction],
6209            Some(&payer.pubkey()),
6210            &[payer, keypair1, keypair2],
6211            recent_blockhash,
6212        )
6213    }
6214
6215    fn store_accounts_for_rent_test(
6216        bank: &Bank,
6217        keypairs: &mut Vec<Keypair>,
6218        mock_program_id: Pubkey,
6219        generic_rent_due_for_system_account: u64,
6220    ) {
6221        let mut account_pairs: Vec<(Pubkey, AccountSharedData)> =
6222            Vec::with_capacity(keypairs.len() - 1);
6223        account_pairs.push((
6224            keypairs[0].pubkey(),
6225            AccountSharedData::new(
6226                generic_rent_due_for_system_account + 2,
6227                0,
6228                &Pubkey::default(),
6229            ),
6230        ));
6231        account_pairs.push((
6232            keypairs[1].pubkey(),
6233            AccountSharedData::new(
6234                generic_rent_due_for_system_account + 2,
6235                0,
6236                &Pubkey::default(),
6237            ),
6238        ));
6239        account_pairs.push((
6240            keypairs[2].pubkey(),
6241            AccountSharedData::new(
6242                generic_rent_due_for_system_account + 2,
6243                0,
6244                &Pubkey::default(),
6245            ),
6246        ));
6247        account_pairs.push((
6248            keypairs[3].pubkey(),
6249            AccountSharedData::new(
6250                generic_rent_due_for_system_account + 2,
6251                0,
6252                &Pubkey::default(),
6253            ),
6254        ));
6255        account_pairs.push((
6256            keypairs[4].pubkey(),
6257            AccountSharedData::new(10, 0, &Pubkey::default()),
6258        ));
6259        account_pairs.push((
6260            keypairs[5].pubkey(),
6261            AccountSharedData::new(10, 0, &Pubkey::default()),
6262        ));
6263        account_pairs.push((
6264            keypairs[6].pubkey(),
6265            AccountSharedData::new(
6266                (2 * generic_rent_due_for_system_account) + 24,
6267                0,
6268                &Pubkey::default(),
6269            ),
6270        ));
6271
6272        account_pairs.push((
6273            keypairs[8].pubkey(),
6274            AccountSharedData::new(
6275                generic_rent_due_for_system_account + 2 + 929,
6276                0,
6277                &Pubkey::default(),
6278            ),
6279        ));
6280        account_pairs.push((
6281            keypairs[9].pubkey(),
6282            AccountSharedData::new(10, 0, &Pubkey::default()),
6283        ));
6284
6285        // Feeding to MockProgram to test read only rent behaviour
6286        account_pairs.push((
6287            keypairs[10].pubkey(),
6288            AccountSharedData::new(
6289                generic_rent_due_for_system_account + 3,
6290                0,
6291                &Pubkey::default(),
6292            ),
6293        ));
6294        account_pairs.push((
6295            keypairs[11].pubkey(),
6296            AccountSharedData::new(generic_rent_due_for_system_account + 3, 0, &mock_program_id),
6297        ));
6298        account_pairs.push((
6299            keypairs[12].pubkey(),
6300            AccountSharedData::new(generic_rent_due_for_system_account + 3, 0, &mock_program_id),
6301        ));
6302        account_pairs.push((
6303            keypairs[13].pubkey(),
6304            AccountSharedData::new(14, 22, &mock_program_id),
6305        ));
6306
6307        for account_pair in account_pairs.iter() {
6308            bank.store_account(&account_pair.0, &account_pair.1);
6309        }
6310    }
6311
6312    fn create_child_bank_for_rent_test(
6313        root_bank: &Arc<Bank>,
6314        genesis_config: &GenesisConfig,
6315        mock_program_id: Pubkey,
6316    ) -> Bank {
6317        let mut bank = Bank::new_from_parent(
6318            root_bank,
6319            &Pubkey::default(),
6320            years_as_slots(
6321                2.0,
6322                &genesis_config.poh_config.target_tick_duration,
6323                genesis_config.ticks_per_slot,
6324            ) as u64,
6325        );
6326        bank.rent_collector.slots_per_year = 421_812.0;
6327        bank.add_builtin("mock_program", mock_program_id, mock_process_instruction);
6328
6329        bank
6330    }
6331
6332    fn assert_capitalization_diff(bank: &Bank, updater: impl Fn(), asserter: impl Fn(u64, u64)) {
6333        let old = bank.capitalization();
6334        updater();
6335        let new = bank.capitalization();
6336        asserter(old, new);
6337        assert_eq!(bank.capitalization(), bank.calculate_capitalization(true));
6338    }
6339
6340    fn assert_capitalization_diff_with_new_bank(
6341        bank: &Bank,
6342        updater: impl Fn() -> Bank,
6343        asserter: impl Fn(u64, u64),
6344    ) -> Bank {
6345        let old = bank.capitalization();
6346        let bank = updater();
6347        let new = bank.capitalization();
6348        asserter(old, new);
6349        assert_eq!(bank.capitalization(), bank.calculate_capitalization(true));
6350        bank
6351    }
6352
6353    #[test]
6354    fn test_store_account_and_update_capitalization_missing() {
6355        let (genesis_config, _mint_keypair) = create_genesis_config(0);
6356        let bank = Bank::new_for_tests(&genesis_config);
6357        let pubkey = gemachain_sdk::pubkey::new_rand();
6358
6359        let some_carats = 400;
6360        let account = AccountSharedData::new(some_carats, 0, &system_program::id());
6361
6362        assert_capitalization_diff(
6363            &bank,
6364            || bank.store_account_and_update_capitalization(&pubkey, &account),
6365            |old, new| assert_eq!(old + some_carats, new),
6366        );
6367        assert_eq!(account, bank.get_account(&pubkey).unwrap());
6368    }
6369
6370    #[test]
6371    fn test_store_account_and_update_capitalization_increased() {
6372        let old_carats = 400;
6373        let (genesis_config, mint_keypair) = create_genesis_config(old_carats);
6374        let bank = Bank::new_for_tests(&genesis_config);
6375        let pubkey = mint_keypair.pubkey();
6376
6377        let new_carats = 500;
6378        let account = AccountSharedData::new(new_carats, 0, &system_program::id());
6379
6380        assert_capitalization_diff(
6381            &bank,
6382            || bank.store_account_and_update_capitalization(&pubkey, &account),
6383            |old, new| assert_eq!(old + 100, new),
6384        );
6385        assert_eq!(account, bank.get_account(&pubkey).unwrap());
6386    }
6387
6388    #[test]
6389    fn test_store_account_and_update_capitalization_decreased() {
6390        let old_carats = 400;
6391        let (genesis_config, mint_keypair) = create_genesis_config(old_carats);
6392        let bank = Bank::new_for_tests(&genesis_config);
6393        let pubkey = mint_keypair.pubkey();
6394
6395        let new_carats = 100;
6396        let account = AccountSharedData::new(new_carats, 0, &system_program::id());
6397
6398        assert_capitalization_diff(
6399            &bank,
6400            || bank.store_account_and_update_capitalization(&pubkey, &account),
6401            |old, new| assert_eq!(old - 300, new),
6402        );
6403        assert_eq!(account, bank.get_account(&pubkey).unwrap());
6404    }
6405
6406    #[test]
6407    fn test_store_account_and_update_capitalization_unchanged() {
6408        let carats = 400;
6409        let (genesis_config, mint_keypair) = create_genesis_config(carats);
6410        let bank = Bank::new_for_tests(&genesis_config);
6411        let pubkey = mint_keypair.pubkey();
6412
6413        let account = AccountSharedData::new(carats, 1, &system_program::id());
6414
6415        assert_capitalization_diff(
6416            &bank,
6417            || bank.store_account_and_update_capitalization(&pubkey, &account),
6418            |old, new| assert_eq!(old, new),
6419        );
6420        assert_eq!(account, bank.get_account(&pubkey).unwrap());
6421    }
6422
6423    #[test]
6424    fn test_rent_distribution() {
6425        gemachain_logger::setup();
6426
6427        let bootstrap_validator_pubkey = gemachain_sdk::pubkey::new_rand();
6428        let bootstrap_validator_stake_carats = 30;
6429        let mut genesis_config = create_genesis_config_with_leader(
6430            10,
6431            &bootstrap_validator_pubkey,
6432            bootstrap_validator_stake_carats,
6433        )
6434        .genesis_config;
6435
6436        genesis_config.epoch_schedule = EpochSchedule::custom(
6437            MINIMUM_SLOTS_PER_EPOCH,
6438            genesis_config.epoch_schedule.leader_schedule_slot_offset,
6439            false,
6440        );
6441
6442        genesis_config.rent = Rent {
6443            carats_per_byte_year: 1,
6444            exemption_threshold: 2.0,
6445            burn_percent: 10,
6446        };
6447
6448        let rent = Rent::free();
6449
6450        let validator_1_pubkey = gemachain_sdk::pubkey::new_rand();
6451        let validator_1_stake_carats = 20;
6452        let validator_1_staking_keypair = Keypair::new();
6453        let validator_1_voting_keypair = Keypair::new();
6454
6455        let validator_1_vote_account = vote_state::create_account(
6456            &validator_1_voting_keypair.pubkey(),
6457            &validator_1_pubkey,
6458            0,
6459            validator_1_stake_carats,
6460        );
6461
6462        let validator_1_stake_account = stake_state::create_account(
6463            &validator_1_staking_keypair.pubkey(),
6464            &validator_1_voting_keypair.pubkey(),
6465            &validator_1_vote_account,
6466            &rent,
6467            validator_1_stake_carats,
6468        );
6469
6470        genesis_config.accounts.insert(
6471            validator_1_pubkey,
6472            Account::new(42, 0, &system_program::id()),
6473        );
6474        genesis_config.accounts.insert(
6475            validator_1_staking_keypair.pubkey(),
6476            Account::from(validator_1_stake_account),
6477        );
6478        genesis_config.accounts.insert(
6479            validator_1_voting_keypair.pubkey(),
6480            Account::from(validator_1_vote_account),
6481        );
6482
6483        let validator_2_pubkey = gemachain_sdk::pubkey::new_rand();
6484        let validator_2_stake_carats = 20;
6485        let validator_2_staking_keypair = Keypair::new();
6486        let validator_2_voting_keypair = Keypair::new();
6487
6488        let validator_2_vote_account = vote_state::create_account(
6489            &validator_2_voting_keypair.pubkey(),
6490            &validator_2_pubkey,
6491            0,
6492            validator_2_stake_carats,
6493        );
6494
6495        let validator_2_stake_account = stake_state::create_account(
6496            &validator_2_staking_keypair.pubkey(),
6497            &validator_2_voting_keypair.pubkey(),
6498            &validator_2_vote_account,
6499            &rent,
6500            validator_2_stake_carats,
6501        );
6502
6503        genesis_config.accounts.insert(
6504            validator_2_pubkey,
6505            Account::new(42, 0, &system_program::id()),
6506        );
6507        genesis_config.accounts.insert(
6508            validator_2_staking_keypair.pubkey(),
6509            Account::from(validator_2_stake_account),
6510        );
6511        genesis_config.accounts.insert(
6512            validator_2_voting_keypair.pubkey(),
6513            Account::from(validator_2_vote_account),
6514        );
6515
6516        let validator_3_pubkey = gemachain_sdk::pubkey::new_rand();
6517        let validator_3_stake_carats = 30;
6518        let validator_3_staking_keypair = Keypair::new();
6519        let validator_3_voting_keypair = Keypair::new();
6520
6521        let validator_3_vote_account = vote_state::create_account(
6522            &validator_3_voting_keypair.pubkey(),
6523            &validator_3_pubkey,
6524            0,
6525            validator_3_stake_carats,
6526        );
6527
6528        let validator_3_stake_account = stake_state::create_account(
6529            &validator_3_staking_keypair.pubkey(),
6530            &validator_3_voting_keypair.pubkey(),
6531            &validator_3_vote_account,
6532            &rent,
6533            validator_3_stake_carats,
6534        );
6535
6536        genesis_config.accounts.insert(
6537            validator_3_pubkey,
6538            Account::new(42, 0, &system_program::id()),
6539        );
6540        genesis_config.accounts.insert(
6541            validator_3_staking_keypair.pubkey(),
6542            Account::from(validator_3_stake_account),
6543        );
6544        genesis_config.accounts.insert(
6545            validator_3_voting_keypair.pubkey(),
6546            Account::from(validator_3_vote_account),
6547        );
6548
6549        genesis_config.rent = Rent {
6550            carats_per_byte_year: 1,
6551            exemption_threshold: 10.0,
6552            burn_percent: 10,
6553        };
6554
6555        let mut bank = Bank::new_for_tests(&genesis_config);
6556        // Enable rent collection
6557        bank.rent_collector.epoch = 5;
6558        bank.rent_collector.slots_per_year = 192.0;
6559
6560        let payer = Keypair::new();
6561        let payer_account = AccountSharedData::new(400, 0, &system_program::id());
6562        bank.store_account_and_update_capitalization(&payer.pubkey(), &payer_account);
6563
6564        let payee = Keypair::new();
6565        let payee_account = AccountSharedData::new(70, 1, &system_program::id());
6566        bank.store_account_and_update_capitalization(&payee.pubkey(), &payee_account);
6567
6568        let bootstrap_validator_initial_balance = bank.get_balance(&bootstrap_validator_pubkey);
6569
6570        let tx = system_transaction::transfer(&payer, &payee.pubkey(), 180, genesis_config.hash());
6571
6572        let result = bank.process_transaction(&tx);
6573        assert_eq!(result, Ok(()));
6574
6575        let mut total_rent_deducted = 0;
6576
6577        // 400 - 128(Rent) - 180(Transfer)
6578        assert_eq!(bank.get_balance(&payer.pubkey()), 92);
6579        total_rent_deducted += 128;
6580
6581        // 70 - 70(Rent) + 180(Transfer) - 21(Rent)
6582        assert_eq!(bank.get_balance(&payee.pubkey()), 159);
6583        total_rent_deducted += 70 + 21;
6584
6585        let previous_capitalization = bank.capitalization.load(Relaxed);
6586
6587        bank.freeze();
6588
6589        assert_eq!(bank.collected_rent.load(Relaxed), total_rent_deducted);
6590
6591        let burned_portion =
6592            total_rent_deducted * u64::from(bank.rent_collector.rent.burn_percent) / 100;
6593        let rent_to_be_distributed = total_rent_deducted - burned_portion;
6594
6595        let bootstrap_validator_portion =
6596            ((bootstrap_validator_stake_carats * rent_to_be_distributed) as f64 / 100.0) as u64
6597                + 1; // Leftover carat
6598        assert_eq!(
6599            bank.get_balance(&bootstrap_validator_pubkey),
6600            bootstrap_validator_portion + bootstrap_validator_initial_balance
6601        );
6602
6603        // Since, validator 1 and validator 2 has equal smallest stake, it comes down to comparison
6604        // between their pubkey.
6605        let tweak_1 = if validator_1_pubkey > validator_2_pubkey {
6606            1
6607        } else {
6608            0
6609        };
6610        let validator_1_portion =
6611            ((validator_1_stake_carats * rent_to_be_distributed) as f64 / 100.0) as u64 + tweak_1;
6612        assert_eq!(
6613            bank.get_balance(&validator_1_pubkey),
6614            validator_1_portion + 42 - tweak_1,
6615        );
6616
6617        // Since, validator 1 and validator 2 has equal smallest stake, it comes down to comparison
6618        // between their pubkey.
6619        let tweak_2 = if validator_2_pubkey > validator_1_pubkey {
6620            1
6621        } else {
6622            0
6623        };
6624        let validator_2_portion =
6625            ((validator_2_stake_carats * rent_to_be_distributed) as f64 / 100.0) as u64 + tweak_2;
6626        assert_eq!(
6627            bank.get_balance(&validator_2_pubkey),
6628            validator_2_portion + 42 - tweak_2,
6629        );
6630
6631        let validator_3_portion =
6632            ((validator_3_stake_carats * rent_to_be_distributed) as f64 / 100.0) as u64 + 1;
6633        assert_eq!(
6634            bank.get_balance(&validator_3_pubkey),
6635            validator_3_portion + 42
6636        );
6637
6638        let current_capitalization = bank.capitalization.load(Relaxed);
6639
6640        // only slot history is newly created
6641        let sysvar_and_native_program_delta =
6642            min_rent_excempt_balance_for_sysvars(&bank, &[sysvar::slot_history::id()]);
6643        assert_eq!(
6644            previous_capitalization - (current_capitalization - sysvar_and_native_program_delta),
6645            burned_portion
6646        );
6647
6648        assert!(bank.calculate_and_verify_capitalization(true));
6649
6650        assert_eq!(
6651            rent_to_be_distributed,
6652            bank.rewards
6653                .read()
6654                .unwrap()
6655                .iter()
6656                .map(|(address, reward)| {
6657                    if reward.carats > 0 {
6658                        assert_eq!(reward.reward_type, RewardType::Rent);
6659                        if *address == validator_2_pubkey {
6660                            assert_eq!(reward.post_balance, validator_2_portion + 42 - tweak_2);
6661                        } else if *address == validator_3_pubkey {
6662                            assert_eq!(reward.post_balance, validator_3_portion + 42);
6663                        }
6664                        reward.carats as u64
6665                    } else {
6666                        0
6667                    }
6668                })
6669                .sum::<u64>()
6670        );
6671    }
6672
6673    #[test]
6674    fn test_distribute_rent_to_validators_overflow() {
6675        gemachain_logger::setup();
6676
6677        // These values are taken from the real cluster (testnet)
6678        const RENT_TO_BE_DISTRIBUTED: u64 = 120_525;
6679        const VALIDATOR_STAKE: u64 = 374_999_998_287_840;
6680
6681        let validator_pubkey = gemachain_sdk::pubkey::new_rand();
6682        let mut genesis_config =
6683            create_genesis_config_with_leader(10, &validator_pubkey, VALIDATOR_STAKE)
6684                .genesis_config;
6685
6686        let bank = Bank::new_for_tests(&genesis_config);
6687        let old_validator_carats = bank.get_balance(&validator_pubkey);
6688        bank.distribute_rent_to_validators(&bank.vote_accounts(), RENT_TO_BE_DISTRIBUTED);
6689        let new_validator_carats = bank.get_balance(&validator_pubkey);
6690        assert_eq!(
6691            new_validator_carats,
6692            old_validator_carats + RENT_TO_BE_DISTRIBUTED
6693        );
6694
6695        genesis_config
6696            .accounts
6697            .remove(&feature_set::no_overflow_rent_distribution::id())
6698            .unwrap();
6699        let bank = std::panic::AssertUnwindSafe(Bank::new_for_tests(&genesis_config));
6700        let old_validator_carats = bank.get_balance(&validator_pubkey);
6701        let new_validator_carats = std::panic::catch_unwind(|| {
6702            bank.distribute_rent_to_validators(&bank.vote_accounts(), RENT_TO_BE_DISTRIBUTED);
6703            bank.get_balance(&validator_pubkey)
6704        });
6705
6706        if let Ok(new_validator_carats) = new_validator_carats {
6707            info!("asserting overflowing incorrect rent distribution");
6708            assert_ne!(
6709                new_validator_carats,
6710                old_validator_carats + RENT_TO_BE_DISTRIBUTED
6711            );
6712        } else {
6713            info!("NOT-asserting overflowing incorrect rent distribution");
6714        }
6715    }
6716
6717    #[test]
6718    fn test_rent_exempt_executable_account() {
6719        let (mut genesis_config, mint_keypair) = create_genesis_config(100_000);
6720        genesis_config.rent = Rent {
6721            carats_per_byte_year: 1,
6722            exemption_threshold: 1000.0,
6723            burn_percent: 10,
6724        };
6725
6726        let root_bank = Arc::new(Bank::new_for_tests(&genesis_config));
6727        let bank = create_child_bank_for_rent_test(
6728            &root_bank,
6729            &genesis_config,
6730            gemachain_sdk::pubkey::new_rand(),
6731        );
6732
6733        let account_pubkey = gemachain_sdk::pubkey::new_rand();
6734        let account_balance = 1;
6735        let mut account =
6736            AccountSharedData::new(account_balance, 0, &gemachain_sdk::pubkey::new_rand());
6737        account.set_executable(true);
6738        bank.store_account(&account_pubkey, &account);
6739
6740        let transfer_carats = 1;
6741        let tx = system_transaction::transfer(
6742            &mint_keypair,
6743            &account_pubkey,
6744            transfer_carats,
6745            genesis_config.hash(),
6746        );
6747
6748        assert_eq!(
6749            bank.process_transaction(&tx),
6750            Err(TransactionError::InstructionError(
6751                0,
6752                InstructionError::ExecutableCaratChange
6753            ))
6754        );
6755        assert_eq!(bank.get_balance(&account_pubkey), account_balance);
6756    }
6757
6758    #[test]
6759    #[allow(clippy::cognitive_complexity)]
6760    fn test_rent_complex() {
6761        gemachain_logger::setup();
6762        let mock_program_id = Pubkey::new(&[2u8; 32]);
6763
6764        let (mut genesis_config, _mint_keypair) = create_genesis_config(10);
6765        let mut keypairs: Vec<Keypair> = Vec::with_capacity(14);
6766        for _i in 0..14 {
6767            keypairs.push(Keypair::new());
6768        }
6769
6770        genesis_config.rent = Rent {
6771            carats_per_byte_year: 1,
6772            exemption_threshold: 1000.0,
6773            burn_percent: 10,
6774        };
6775
6776        let root_bank = Bank::new_for_tests(&genesis_config);
6777        // until we completely transition to the eager rent collection,
6778        // we must ensure lazy rent collection doens't get broken!
6779        root_bank.restore_old_behavior_for_fragile_tests();
6780        let root_bank = Arc::new(root_bank);
6781        let bank = create_child_bank_for_rent_test(&root_bank, &genesis_config, mock_program_id);
6782
6783        assert_eq!(bank.last_blockhash(), genesis_config.hash());
6784
6785        let slots_elapsed: u64 = (0..=bank.epoch)
6786            .map(|epoch| {
6787                bank.rent_collector
6788                    .epoch_schedule
6789                    .get_slots_in_epoch(epoch + 1)
6790            })
6791            .sum();
6792        let (generic_rent_due_for_system_account, _) = bank.rent_collector.rent.due(
6793            bank.get_minimum_balance_for_rent_exemption(0) - 1,
6794            0,
6795            slots_elapsed as f64 / bank.rent_collector.slots_per_year,
6796        );
6797
6798        store_accounts_for_rent_test(
6799            &bank,
6800            &mut keypairs,
6801            mock_program_id,
6802            generic_rent_due_for_system_account,
6803        );
6804
6805        let magic_rent_number = 131; // yuck, derive this value programmatically one day
6806
6807        let t1 = system_transaction::transfer(
6808            &keypairs[0],
6809            &keypairs[1].pubkey(),
6810            1,
6811            genesis_config.hash(),
6812        );
6813        let t2 = system_transaction::transfer(
6814            &keypairs[2],
6815            &keypairs[3].pubkey(),
6816            1,
6817            genesis_config.hash(),
6818        );
6819        let t3 = system_transaction::transfer(
6820            &keypairs[4],
6821            &keypairs[5].pubkey(),
6822            1,
6823            genesis_config.hash(),
6824        );
6825        let t4 = system_transaction::transfer(
6826            &keypairs[6],
6827            &keypairs[7].pubkey(),
6828            generic_rent_due_for_system_account + 1,
6829            genesis_config.hash(),
6830        );
6831        let t5 = system_transaction::transfer(
6832            &keypairs[8],
6833            &keypairs[9].pubkey(),
6834            929,
6835            genesis_config.hash(),
6836        );
6837
6838        let t6 = create_mock_transaction(
6839            &keypairs[10],
6840            &keypairs[11],
6841            &keypairs[12],
6842            &keypairs[13],
6843            mock_program_id,
6844            genesis_config.hash(),
6845        );
6846
6847        let txs = vec![t6, t5, t1, t2, t3, t4];
6848        let res = bank.process_transactions(txs.iter());
6849
6850        assert_eq!(res.len(), 6);
6851        assert_eq!(res[0], Ok(()));
6852        assert_eq!(res[1], Ok(()));
6853        assert_eq!(res[2], Ok(()));
6854        assert_eq!(res[3], Ok(()));
6855        assert_eq!(res[4], Err(TransactionError::AccountNotFound));
6856        assert_eq!(res[5], Ok(()));
6857
6858        bank.freeze();
6859
6860        let mut rent_collected = 0;
6861
6862        // 48992 - generic_rent_due_for_system_account(Rent) - 1(transfer)
6863        assert_eq!(bank.get_balance(&keypairs[0].pubkey()), 1);
6864        rent_collected += generic_rent_due_for_system_account;
6865
6866        // 48992 - generic_rent_due_for_system_account(Rent) + 1(transfer)
6867        assert_eq!(bank.get_balance(&keypairs[1].pubkey()), 3);
6868        rent_collected += generic_rent_due_for_system_account;
6869
6870        // 48992 - generic_rent_due_for_system_account(Rent) - 1(transfer)
6871        assert_eq!(bank.get_balance(&keypairs[2].pubkey()), 1);
6872        rent_collected += generic_rent_due_for_system_account;
6873
6874        // 48992 - generic_rent_due_for_system_account(Rent) + 1(transfer)
6875        assert_eq!(bank.get_balance(&keypairs[3].pubkey()), 3);
6876        rent_collected += generic_rent_due_for_system_account;
6877
6878        // No rent deducted
6879        assert_eq!(bank.get_balance(&keypairs[4].pubkey()), 10);
6880        assert_eq!(bank.get_balance(&keypairs[5].pubkey()), 10);
6881
6882        // 98004 - generic_rent_due_for_system_account(Rent) - 48991(transfer)
6883        assert_eq!(bank.get_balance(&keypairs[6].pubkey()), 23);
6884        rent_collected += generic_rent_due_for_system_account;
6885
6886        // 0 + 48990(transfer) - magic_rent_number(Rent)
6887        assert_eq!(
6888            bank.get_balance(&keypairs[7].pubkey()),
6889            generic_rent_due_for_system_account + 1 - magic_rent_number
6890        );
6891
6892        // Epoch should be updated
6893        // Rent deducted on store side
6894        let account8 = bank.get_account(&keypairs[7].pubkey()).unwrap();
6895        // Epoch should be set correctly.
6896        assert_eq!(account8.rent_epoch(), bank.epoch + 1);
6897        rent_collected += magic_rent_number;
6898
6899        // 49921 - generic_rent_due_for_system_account(Rent) - 929(Transfer)
6900        assert_eq!(bank.get_balance(&keypairs[8].pubkey()), 2);
6901        rent_collected += generic_rent_due_for_system_account;
6902
6903        let account10 = bank.get_account(&keypairs[9].pubkey()).unwrap();
6904        // Account was overwritten at load time, since it didn't have sufficient balance to pay rent
6905        // Then, at store time we deducted `magic_rent_number` rent for the current epoch, once it has balance
6906        assert_eq!(account10.rent_epoch(), bank.epoch + 1);
6907        // account data is blank now
6908        assert_eq!(account10.data().len(), 0);
6909        // 10 - 10(Rent) + 929(Transfer) - magic_rent_number(Rent)
6910        assert_eq!(account10.carats(), 929 - magic_rent_number);
6911        rent_collected += magic_rent_number + 10;
6912
6913        // 48993 - generic_rent_due_for_system_account(Rent)
6914        assert_eq!(bank.get_balance(&keypairs[10].pubkey()), 3);
6915        rent_collected += generic_rent_due_for_system_account;
6916
6917        // 48993 - generic_rent_due_for_system_account(Rent) + 1(Addition by program)
6918        assert_eq!(bank.get_balance(&keypairs[11].pubkey()), 4);
6919        rent_collected += generic_rent_due_for_system_account;
6920
6921        // 48993 - generic_rent_due_for_system_account(Rent) - 1(Deduction by program)
6922        assert_eq!(bank.get_balance(&keypairs[12].pubkey()), 2);
6923        rent_collected += generic_rent_due_for_system_account;
6924
6925        // No rent for read-only account
6926        assert_eq!(bank.get_balance(&keypairs[13].pubkey()), 14);
6927
6928        // Bank's collected rent should be sum of rent collected from all accounts
6929        assert_eq!(bank.collected_rent.load(Relaxed), rent_collected);
6930    }
6931
6932    #[test]
6933    fn test_rent_eager_across_epoch_without_gap() {
6934        let (genesis_config, _mint_keypair) = create_genesis_config(1);
6935
6936        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
6937        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 32)]);
6938
6939        bank = Arc::new(new_from_parent(&bank));
6940        assert_eq!(bank.rent_collection_partitions(), vec![(0, 1, 32)]);
6941        for _ in 2..32 {
6942            bank = Arc::new(new_from_parent(&bank));
6943        }
6944        assert_eq!(bank.rent_collection_partitions(), vec![(30, 31, 32)]);
6945        bank = Arc::new(new_from_parent(&bank));
6946        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 64)]);
6947    }
6948
6949    #[test]
6950    fn test_rent_eager_across_epoch_with_full_gap() {
6951        let (mut genesis_config, _mint_keypair) = create_genesis_config(1);
6952        activate_all_features(&mut genesis_config);
6953
6954        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
6955        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 32)]);
6956
6957        bank = Arc::new(new_from_parent(&bank));
6958        assert_eq!(bank.rent_collection_partitions(), vec![(0, 1, 32)]);
6959        for _ in 2..15 {
6960            bank = Arc::new(new_from_parent(&bank));
6961        }
6962        assert_eq!(bank.rent_collection_partitions(), vec![(13, 14, 32)]);
6963        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 49));
6964        assert_eq!(
6965            bank.rent_collection_partitions(),
6966            vec![(14, 31, 32), (0, 0, 64), (0, 17, 64)]
6967        );
6968        bank = Arc::new(new_from_parent(&bank));
6969        assert_eq!(bank.rent_collection_partitions(), vec![(17, 18, 64)]);
6970    }
6971
6972    #[test]
6973    fn test_rent_eager_across_epoch_with_half_gap() {
6974        let (mut genesis_config, _mint_keypair) = create_genesis_config(1);
6975        activate_all_features(&mut genesis_config);
6976
6977        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
6978        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 32)]);
6979
6980        bank = Arc::new(new_from_parent(&bank));
6981        assert_eq!(bank.rent_collection_partitions(), vec![(0, 1, 32)]);
6982        for _ in 2..15 {
6983            bank = Arc::new(new_from_parent(&bank));
6984        }
6985        assert_eq!(bank.rent_collection_partitions(), vec![(13, 14, 32)]);
6986        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 32));
6987        assert_eq!(
6988            bank.rent_collection_partitions(),
6989            vec![(14, 31, 32), (0, 0, 64)]
6990        );
6991        bank = Arc::new(new_from_parent(&bank));
6992        assert_eq!(bank.rent_collection_partitions(), vec![(0, 1, 64)]);
6993    }
6994
6995    #[test]
6996    #[allow(clippy::cognitive_complexity)]
6997    fn test_rent_eager_across_epoch_without_gap_under_multi_epoch_cycle() {
6998        let leader_pubkey = gemachain_sdk::pubkey::new_rand();
6999        let leader_carats = 3;
7000        let mut genesis_config =
7001            create_genesis_config_with_leader(5, &leader_pubkey, leader_carats).genesis_config;
7002        genesis_config.cluster_type = ClusterType::MainnetBeta;
7003
7004        const SLOTS_PER_EPOCH: u64 = MINIMUM_SLOTS_PER_EPOCH as u64;
7005        const LEADER_SCHEDULE_SLOT_OFFSET: u64 = SLOTS_PER_EPOCH * 3 - 3;
7006        genesis_config.epoch_schedule =
7007            EpochSchedule::custom(SLOTS_PER_EPOCH, LEADER_SCHEDULE_SLOT_OFFSET, false);
7008
7009        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
7010        assert_eq!(DEFAULT_SLOTS_PER_EPOCH, 432_000);
7011        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7012        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (0, 0));
7013        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 432_000)]);
7014
7015        bank = Arc::new(new_from_parent(&bank));
7016        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7017        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (0, 1));
7018        assert_eq!(bank.rent_collection_partitions(), vec![(0, 1, 432_000)]);
7019
7020        for _ in 2..32 {
7021            bank = Arc::new(new_from_parent(&bank));
7022        }
7023        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7024        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (0, 31));
7025        assert_eq!(bank.rent_collection_partitions(), vec![(30, 31, 432_000)]);
7026
7027        bank = Arc::new(new_from_parent(&bank));
7028        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7029        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (1, 0));
7030        assert_eq!(bank.rent_collection_partitions(), vec![(31, 32, 432_000)]);
7031
7032        bank = Arc::new(new_from_parent(&bank));
7033        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7034        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (1, 1));
7035        assert_eq!(bank.rent_collection_partitions(), vec![(32, 33, 432_000)]);
7036
7037        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 1000));
7038        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 1001));
7039        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7040        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (31, 9));
7041        assert_eq!(
7042            bank.rent_collection_partitions(),
7043            vec![(1000, 1001, 432_000)]
7044        );
7045
7046        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 431_998));
7047        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 431_999));
7048        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7049        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (13499, 31));
7050        assert_eq!(
7051            bank.rent_collection_partitions(),
7052            vec![(431_998, 431_999, 432_000)]
7053        );
7054
7055        bank = Arc::new(new_from_parent(&bank));
7056        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7057        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (13500, 0));
7058        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 432_000)]);
7059
7060        bank = Arc::new(new_from_parent(&bank));
7061        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7062        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (13500, 1));
7063        assert_eq!(bank.rent_collection_partitions(), vec![(0, 1, 432_000)]);
7064    }
7065
7066    #[test]
7067    fn test_rent_eager_across_epoch_with_gap_under_multi_epoch_cycle() {
7068        let leader_pubkey = gemachain_sdk::pubkey::new_rand();
7069        let leader_carats = 3;
7070        let mut genesis_config =
7071            create_genesis_config_with_leader(5, &leader_pubkey, leader_carats).genesis_config;
7072        genesis_config.cluster_type = ClusterType::MainnetBeta;
7073
7074        const SLOTS_PER_EPOCH: u64 = MINIMUM_SLOTS_PER_EPOCH as u64;
7075        const LEADER_SCHEDULE_SLOT_OFFSET: u64 = SLOTS_PER_EPOCH * 3 - 3;
7076        genesis_config.epoch_schedule =
7077            EpochSchedule::custom(SLOTS_PER_EPOCH, LEADER_SCHEDULE_SLOT_OFFSET, false);
7078
7079        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
7080        assert_eq!(DEFAULT_SLOTS_PER_EPOCH, 432_000);
7081        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7082        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (0, 0));
7083        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 432_000)]);
7084
7085        bank = Arc::new(new_from_parent(&bank));
7086        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7087        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (0, 1));
7088        assert_eq!(bank.rent_collection_partitions(), vec![(0, 1, 432_000)]);
7089
7090        for _ in 2..19 {
7091            bank = Arc::new(new_from_parent(&bank));
7092        }
7093        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7094        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (0, 18));
7095        assert_eq!(bank.rent_collection_partitions(), vec![(17, 18, 432_000)]);
7096
7097        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 44));
7098        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7099        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (1, 12));
7100        assert_eq!(
7101            bank.rent_collection_partitions(),
7102            vec![(18, 31, 432_000), (31, 31, 432_000), (31, 44, 432_000)]
7103        );
7104
7105        bank = Arc::new(new_from_parent(&bank));
7106        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7107        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (1, 13));
7108        assert_eq!(bank.rent_collection_partitions(), vec![(44, 45, 432_000)]);
7109
7110        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 431_993));
7111        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 432_011));
7112        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7113        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (13500, 11));
7114        assert_eq!(
7115            bank.rent_collection_partitions(),
7116            vec![
7117                (431_993, 431_999, 432_000),
7118                (0, 0, 432_000),
7119                (0, 11, 432_000)
7120            ]
7121        );
7122    }
7123
7124    #[test]
7125    fn test_rent_eager_with_warmup_epochs_under_multi_epoch_cycle() {
7126        let leader_pubkey = gemachain_sdk::pubkey::new_rand();
7127        let leader_carats = 3;
7128        let mut genesis_config =
7129            create_genesis_config_with_leader(5, &leader_pubkey, leader_carats).genesis_config;
7130        genesis_config.cluster_type = ClusterType::MainnetBeta;
7131
7132        const SLOTS_PER_EPOCH: u64 = MINIMUM_SLOTS_PER_EPOCH as u64 * 8;
7133        const LEADER_SCHEDULE_SLOT_OFFSET: u64 = SLOTS_PER_EPOCH * 3 - 3;
7134        genesis_config.epoch_schedule =
7135            EpochSchedule::custom(SLOTS_PER_EPOCH, LEADER_SCHEDULE_SLOT_OFFSET, true);
7136
7137        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
7138        assert_eq!(DEFAULT_SLOTS_PER_EPOCH, 432_000);
7139        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7140        assert_eq!(bank.first_normal_epoch(), 3);
7141        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (0, 0));
7142        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 32)]);
7143
7144        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 222));
7145        bank = Arc::new(new_from_parent(&bank));
7146        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 128);
7147        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (2, 127));
7148        assert_eq!(bank.rent_collection_partitions(), vec![(126, 127, 128)]);
7149
7150        bank = Arc::new(new_from_parent(&bank));
7151        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 256);
7152        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (3, 0));
7153        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 431_872)]);
7154        assert_eq!(431_872 % bank.get_slots_in_epoch(bank.epoch()), 0);
7155
7156        bank = Arc::new(new_from_parent(&bank));
7157        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 256);
7158        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (3, 1));
7159        assert_eq!(bank.rent_collection_partitions(), vec![(0, 1, 431_872)]);
7160
7161        bank = Arc::new(Bank::new_from_parent(
7162            &bank,
7163            &Pubkey::default(),
7164            431_872 + 223 - 1,
7165        ));
7166        bank = Arc::new(new_from_parent(&bank));
7167        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 256);
7168        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (1689, 255));
7169        assert_eq!(
7170            bank.rent_collection_partitions(),
7171            vec![(431_870, 431_871, 431_872)]
7172        );
7173
7174        bank = Arc::new(new_from_parent(&bank));
7175        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 256);
7176        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (1690, 0));
7177        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 431_872)]);
7178    }
7179
7180    #[test]
7181    fn test_rent_eager_under_fixed_cycle_for_development() {
7182        gemachain_logger::setup();
7183        let leader_pubkey = gemachain_sdk::pubkey::new_rand();
7184        let leader_carats = 3;
7185        let mut genesis_config =
7186            create_genesis_config_with_leader(5, &leader_pubkey, leader_carats).genesis_config;
7187
7188        const SLOTS_PER_EPOCH: u64 = MINIMUM_SLOTS_PER_EPOCH as u64 * 8;
7189        const LEADER_SCHEDULE_SLOT_OFFSET: u64 = SLOTS_PER_EPOCH * 3 - 3;
7190        genesis_config.epoch_schedule =
7191            EpochSchedule::custom(SLOTS_PER_EPOCH, LEADER_SCHEDULE_SLOT_OFFSET, true);
7192
7193        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
7194        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 32);
7195        assert_eq!(bank.first_normal_epoch(), 3);
7196        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (0, 0));
7197        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 432_000)]);
7198
7199        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), 222));
7200        bank = Arc::new(new_from_parent(&bank));
7201        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 128);
7202        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (2, 127));
7203        assert_eq!(bank.rent_collection_partitions(), vec![(222, 223, 432_000)]);
7204
7205        bank = Arc::new(new_from_parent(&bank));
7206        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 256);
7207        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (3, 0));
7208        assert_eq!(bank.rent_collection_partitions(), vec![(223, 224, 432_000)]);
7209
7210        bank = Arc::new(new_from_parent(&bank));
7211        assert_eq!(bank.get_slots_in_epoch(bank.epoch()), 256);
7212        assert_eq!(bank.get_epoch_and_slot_index(bank.slot()), (3, 1));
7213        assert_eq!(bank.rent_collection_partitions(), vec![(224, 225, 432_000)]);
7214
7215        bank = Arc::new(Bank::new_from_parent(
7216            &bank,
7217            &Pubkey::default(),
7218            432_000 - 2,
7219        ));
7220        bank = Arc::new(new_from_parent(&bank));
7221        assert_eq!(
7222            bank.rent_collection_partitions(),
7223            vec![(431_998, 431_999, 432_000)]
7224        );
7225        bank = Arc::new(new_from_parent(&bank));
7226        assert_eq!(bank.rent_collection_partitions(), vec![(0, 0, 432_000)]);
7227        bank = Arc::new(new_from_parent(&bank));
7228        assert_eq!(bank.rent_collection_partitions(), vec![(0, 1, 432_000)]);
7229
7230        bank = Arc::new(Bank::new_from_parent(
7231            &bank,
7232            &Pubkey::default(),
7233            864_000 - 20,
7234        ));
7235        bank = Arc::new(Bank::new_from_parent(
7236            &bank,
7237            &Pubkey::default(),
7238            864_000 + 39,
7239        ));
7240        assert_eq!(
7241            bank.rent_collection_partitions(),
7242            vec![
7243                (431_980, 431_999, 432_000),
7244                (0, 0, 432_000),
7245                (0, 39, 432_000)
7246            ]
7247        );
7248    }
7249
7250    #[test]
7251    fn test_rent_eager_pubkey_range_minimal() {
7252        let range = Bank::pubkey_range_from_partition((0, 0, 1));
7253        assert_eq!(
7254            range,
7255            Pubkey::new_from_array([0x00; 32])..=Pubkey::new_from_array([0xff; 32])
7256        );
7257    }
7258
7259    #[test]
7260    fn test_rent_eager_pubkey_range_maximum() {
7261        let max = !0;
7262
7263        let range = Bank::pubkey_range_from_partition((0, 0, max));
7264        assert_eq!(
7265            range,
7266            Pubkey::new_from_array([0x00; 32])
7267                ..=Pubkey::new_from_array([
7268                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
7269                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7270                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7271                ])
7272        );
7273        let range = Bank::pubkey_range_from_partition((0, 1, max));
7274        assert_eq!(
7275            range,
7276            Pubkey::new_from_array([
7277                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7278                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7279                0x00, 0x00, 0x00, 0x00,
7280            ])
7281                ..=Pubkey::new_from_array([
7282                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
7283                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7284                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7285                ])
7286        );
7287        let range = Bank::pubkey_range_from_partition((max - 3, max - 2, max));
7288        assert_eq!(
7289            range,
7290            Pubkey::new_from_array([
7291                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7292                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7293                0x00, 0x00, 0x00, 0x00,
7294            ])
7295                ..=Pubkey::new_from_array([
7296                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,
7297                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7298                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7299                ])
7300        );
7301        let range = Bank::pubkey_range_from_partition((max - 2, max - 1, max));
7302        assert_eq!(
7303            range,
7304            Pubkey::new_from_array([
7305                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7306                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7307                0x00, 0x00, 0x00, 0x00,
7308            ])
7309                ..=Pubkey::new_from_array([
7310                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7311                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7312                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7313                ])
7314        );
7315
7316        fn should_cause_overflow(partition_count: u64) -> bool {
7317            // Check `partition_width = (u64::max_value() + 1) / partition_count` is exact and
7318            // does not have a remainder.
7319            // This way, `partition_width * partition_count == (u64::max_value() + 1)`,
7320            // so the test actually tests for overflow
7321            (u64::max_value() - partition_count + 1) % partition_count == 0
7322        }
7323
7324        let max_exact = 64;
7325        // Make sure `max_exact` divides evenly when calculating `calculate_partition_width`
7326        assert!(should_cause_overflow(max_exact));
7327        // Make sure `max_inexact` doesn't divide evenly when calculating `calculate_partition_width`
7328        let max_inexact = 10;
7329        assert!(!should_cause_overflow(max_inexact));
7330
7331        for max in &[max_exact, max_inexact] {
7332            let range = Bank::pubkey_range_from_partition((max - 1, max - 1, *max));
7333            assert_eq!(
7334                range,
7335                Pubkey::new_from_array([
7336                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7337                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7338                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7339                ])
7340                    ..=Pubkey::new_from_array([
7341                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7342                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7343                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7344                    ])
7345            );
7346        }
7347    }
7348
7349    fn map_to_test_bad_range() -> std::collections::BTreeMap<Pubkey, i8> {
7350        let mut map = std::collections::BTreeMap::new();
7351        // when empty, std::collections::BTreeMap doesn't sanitize given range...
7352        map.insert(gemachain_sdk::pubkey::new_rand(), 1);
7353        map
7354    }
7355
7356    #[test]
7357    #[should_panic(expected = "range start is greater than range end in BTreeMap")]
7358    fn test_rent_eager_bad_range() {
7359        let test_map = map_to_test_bad_range();
7360        test_map.range(
7361            Pubkey::new_from_array([
7362                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7363                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7364                0x00, 0x00, 0x00, 0x01,
7365            ])
7366                ..=Pubkey::new_from_array([
7367                    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
7368                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7369                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7370                ]),
7371        );
7372    }
7373
7374    #[test]
7375    fn test_rent_eager_pubkey_range_noop_range() {
7376        let test_map = map_to_test_bad_range();
7377
7378        let range = Bank::pubkey_range_from_partition((0, 0, 3));
7379        assert_eq!(
7380            range,
7381            Pubkey::new_from_array([
7382                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7383                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7384                0x00, 0x00, 0x00, 0x00
7385            ])
7386                ..=Pubkey::new_from_array([
7387                    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xff, 0xff, 0xff, 0xff, 0xff,
7388                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7389                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7390                ])
7391        );
7392        test_map.range(range);
7393
7394        let range = Bank::pubkey_range_from_partition((1, 1, 3));
7395        assert_eq!(
7396            range,
7397            Pubkey::new_from_array([
7398                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7399                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7400                0x00, 0x00, 0x00, 0x00
7401            ])
7402                ..=Pubkey::new_from_array([
7403                    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
7404                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7405                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
7406                ])
7407        );
7408        test_map.range(range);
7409
7410        let range = Bank::pubkey_range_from_partition((2, 2, 3));
7411        assert_eq!(
7412            range,
7413            Pubkey::new_from_array([
7414                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7415                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7416                0xff, 0xff, 0xff, 0xff
7417            ])
7418                ..=Pubkey::new_from_array([
7419                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7420                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7421                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7422                ])
7423        );
7424        test_map.range(range);
7425    }
7426
7427    #[test]
7428    fn test_rent_eager_pubkey_range_dividable() {
7429        let test_map = map_to_test_bad_range();
7430        let range = Bank::pubkey_range_from_partition((0, 0, 2));
7431
7432        assert_eq!(
7433            range,
7434            Pubkey::new_from_array([
7435                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7436                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7437                0x00, 0x00, 0x00, 0x00
7438            ])
7439                ..=Pubkey::new_from_array([
7440                    0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7441                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7442                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7443                ])
7444        );
7445        test_map.range(range);
7446
7447        let range = Bank::pubkey_range_from_partition((0, 1, 2));
7448        assert_eq!(
7449            range,
7450            Pubkey::new_from_array([
7451                0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7452                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7453                0x00, 0x00, 0x00, 0x00
7454            ])
7455                ..=Pubkey::new_from_array([
7456                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7457                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7458                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7459                ])
7460        );
7461        test_map.range(range);
7462    }
7463
7464    #[test]
7465    fn test_rent_eager_pubkey_range_not_dividable() {
7466        gemachain_logger::setup();
7467
7468        let test_map = map_to_test_bad_range();
7469        let range = Bank::pubkey_range_from_partition((0, 0, 3));
7470        assert_eq!(
7471            range,
7472            Pubkey::new_from_array([
7473                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7474                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7475                0x00, 0x00, 0x00, 0x00
7476            ])
7477                ..=Pubkey::new_from_array([
7478                    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xff, 0xff, 0xff, 0xff, 0xff,
7479                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7480                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7481                ])
7482        );
7483        test_map.range(range);
7484
7485        let range = Bank::pubkey_range_from_partition((0, 1, 3));
7486        assert_eq!(
7487            range,
7488            Pubkey::new_from_array([
7489                0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7490                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7491                0x00, 0x00, 0x00, 0x00
7492            ])
7493                ..=Pubkey::new_from_array([
7494                    0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa9, 0xff, 0xff, 0xff, 0xff, 0xff,
7495                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7496                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7497                ])
7498        );
7499        test_map.range(range);
7500
7501        let range = Bank::pubkey_range_from_partition((1, 2, 3));
7502        assert_eq!(
7503            range,
7504            Pubkey::new_from_array([
7505                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7506                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7507                0x00, 0x00, 0x00, 0x00
7508            ])
7509                ..=Pubkey::new_from_array([
7510                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7511                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7512                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7513                ])
7514        );
7515        test_map.range(range);
7516    }
7517
7518    #[test]
7519    fn test_rent_eager_pubkey_range_gap() {
7520        gemachain_logger::setup();
7521
7522        let test_map = map_to_test_bad_range();
7523        let range = Bank::pubkey_range_from_partition((120, 1023, 12345));
7524        assert_eq!(
7525            range,
7526            Pubkey::new_from_array([
7527                0x02, 0x82, 0x5a, 0x89, 0xd1, 0xac, 0x58, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7528                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7529                0x00, 0x00, 0x00, 0x00
7530            ])
7531                ..=Pubkey::new_from_array([
7532                    0x15, 0x3c, 0x1d, 0xf1, 0xc6, 0x39, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7533                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7534                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7535                ])
7536        );
7537        test_map.range(range);
7538    }
7539
7540    impl Bank {
7541        fn slots_by_pubkey(&self, pubkey: &Pubkey, ancestors: &Ancestors) -> Vec<Slot> {
7542            let (locked_entry, _) = self
7543                .rc
7544                .accounts
7545                .accounts_db
7546                .accounts_index
7547                .get(pubkey, Some(ancestors), None)
7548                .unwrap();
7549            locked_entry
7550                .slot_list()
7551                .iter()
7552                .map(|(slot, _)| *slot)
7553                .collect::<Vec<Slot>>()
7554        }
7555
7556        fn first_slot_in_next_epoch(&self) -> Slot {
7557            self.epoch_schedule()
7558                .get_first_slot_in_epoch(self.epoch() + 1)
7559        }
7560    }
7561
7562    #[test]
7563    fn test_rent_eager_collect_rent_in_partition() {
7564        gemachain_logger::setup();
7565
7566        let (mut genesis_config, _mint_keypair) = create_genesis_config(1);
7567        activate_all_features(&mut genesis_config);
7568
7569        let zero_carat_pubkey = gemachain_sdk::pubkey::new_rand();
7570        let rent_due_pubkey = gemachain_sdk::pubkey::new_rand();
7571        let rent_exempt_pubkey = gemachain_sdk::pubkey::new_rand();
7572
7573        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
7574        let zero_carats = 0;
7575        let little_carats = 1234;
7576        let large_carats = 123_456_789;
7577        let rent_collected = 22;
7578
7579        bank.store_account(
7580            &zero_carat_pubkey,
7581            &AccountSharedData::new(zero_carats, 0, &Pubkey::default()),
7582        );
7583        bank.store_account(
7584            &rent_due_pubkey,
7585            &AccountSharedData::new(little_carats, 0, &Pubkey::default()),
7586        );
7587        bank.store_account(
7588            &rent_exempt_pubkey,
7589            &AccountSharedData::new(large_carats, 0, &Pubkey::default()),
7590        );
7591
7592        let genesis_slot = 0;
7593        let some_slot = 1000;
7594        let ancestors = vec![(some_slot, 0), (0, 1)].into_iter().collect();
7595
7596        bank = Arc::new(Bank::new_from_parent(&bank, &Pubkey::default(), some_slot));
7597
7598        assert_eq!(bank.collected_rent.load(Relaxed), 0);
7599        assert_eq!(
7600            bank.get_account(&rent_due_pubkey).unwrap().carats(),
7601            little_carats
7602        );
7603        assert_eq!(bank.get_account(&rent_due_pubkey).unwrap().rent_epoch(), 0);
7604        assert_eq!(
7605            bank.slots_by_pubkey(&rent_due_pubkey, &ancestors),
7606            vec![genesis_slot]
7607        );
7608        assert_eq!(
7609            bank.slots_by_pubkey(&rent_exempt_pubkey, &ancestors),
7610            vec![genesis_slot]
7611        );
7612        assert_eq!(
7613            bank.slots_by_pubkey(&zero_carat_pubkey, &ancestors),
7614            vec![genesis_slot]
7615        );
7616
7617        bank.collect_rent_in_partition((0, 0, 1)); // all range
7618
7619        // unrelated 1-carat accounts exists
7620        assert_eq!(bank.collected_rent.load(Relaxed), rent_collected + 2);
7621        assert_eq!(
7622            bank.get_account(&rent_due_pubkey).unwrap().carats(),
7623            little_carats - rent_collected
7624        );
7625        assert_eq!(bank.get_account(&rent_due_pubkey).unwrap().rent_epoch(), 6);
7626        assert_eq!(
7627            bank.get_account(&rent_exempt_pubkey).unwrap().carats(),
7628            large_carats
7629        );
7630        assert_eq!(
7631            bank.get_account(&rent_exempt_pubkey).unwrap().rent_epoch(),
7632            5
7633        );
7634        assert_eq!(
7635            bank.slots_by_pubkey(&rent_due_pubkey, &ancestors),
7636            vec![genesis_slot, some_slot]
7637        );
7638        assert_eq!(
7639            bank.slots_by_pubkey(&rent_exempt_pubkey, &ancestors),
7640            vec![genesis_slot, some_slot]
7641        );
7642        assert_eq!(
7643            bank.slots_by_pubkey(&zero_carat_pubkey, &ancestors),
7644            vec![genesis_slot]
7645        );
7646    }
7647
7648    #[test]
7649    fn test_rent_eager_collect_rent_zero_carat_deterministic() {
7650        gemachain_logger::setup();
7651
7652        let (genesis_config, _mint_keypair) = create_genesis_config(1);
7653
7654        let zero_carat_pubkey = gemachain_sdk::pubkey::new_rand();
7655
7656        let genesis_bank1 = Arc::new(Bank::new_for_tests(&genesis_config));
7657        let genesis_bank2 = Arc::new(Bank::new_for_tests(&genesis_config));
7658        let bank1_with_zero = Arc::new(new_from_parent(&genesis_bank1));
7659        let bank1_without_zero = Arc::new(new_from_parent(&genesis_bank2));
7660        let zero_carats = 0;
7661
7662        let account = AccountSharedData::new(zero_carats, 0, &Pubkey::default());
7663        bank1_with_zero.store_account(&zero_carat_pubkey, &account);
7664        bank1_without_zero.store_account(&zero_carat_pubkey, &account);
7665
7666        bank1_without_zero
7667            .rc
7668            .accounts
7669            .accounts_db
7670            .accounts_index
7671            .add_root(genesis_bank1.slot() + 1, false);
7672        bank1_without_zero
7673            .rc
7674            .accounts
7675            .accounts_db
7676            .accounts_index
7677            .purge_roots(&zero_carat_pubkey);
7678
7679        let some_slot = 1000;
7680        let bank2_with_zero = Arc::new(Bank::new_from_parent(
7681            &bank1_with_zero,
7682            &Pubkey::default(),
7683            some_slot,
7684        ));
7685        let bank2_without_zero = Arc::new(Bank::new_from_parent(
7686            &bank1_without_zero,
7687            &Pubkey::default(),
7688            some_slot,
7689        ));
7690        let hash1_with_zero = bank1_with_zero.hash();
7691        let hash1_without_zero = bank1_without_zero.hash();
7692        assert_eq!(hash1_with_zero, hash1_without_zero);
7693        assert_ne!(hash1_with_zero, Hash::default());
7694
7695        bank2_with_zero.collect_rent_in_partition((0, 0, 1)); // all
7696        bank2_without_zero.collect_rent_in_partition((0, 0, 1)); // all
7697
7698        bank2_with_zero.freeze();
7699        let hash2_with_zero = bank2_with_zero.hash();
7700        bank2_without_zero.freeze();
7701        let hash2_without_zero = bank2_without_zero.hash();
7702
7703        assert_eq!(hash2_with_zero, hash2_without_zero);
7704        assert_ne!(hash2_with_zero, Hash::default());
7705    }
7706
7707    #[test]
7708    fn test_bank_update_vote_stake_rewards() {
7709        gemachain_logger::setup();
7710
7711        // create a bank that ticks really slowly...
7712        let bank0 = Arc::new(Bank::new_for_tests(&GenesisConfig {
7713            accounts: (0..42)
7714                .map(|_| {
7715                    (
7716                        gemachain_sdk::pubkey::new_rand(),
7717                        Account::new(1_000_000_000, 0, &Pubkey::default()),
7718                    )
7719                })
7720                .collect(),
7721            // set it up so the first epoch is a full year long
7722            poh_config: PohConfig {
7723                target_tick_duration: Duration::from_secs(
7724                    SECONDS_PER_YEAR as u64
7725                        / MINIMUM_SLOTS_PER_EPOCH as u64
7726                        / DEFAULT_TICKS_PER_SLOT,
7727                ),
7728                hashes_per_tick: None,
7729                target_tick_count: None,
7730            },
7731            cluster_type: ClusterType::MainnetBeta,
7732
7733            ..GenesisConfig::default()
7734        }));
7735
7736        // enable lazy rent collection because this test depends on rent-due accounts
7737        // not being eagerly-collected for exact rewards calculation
7738        bank0.restore_old_behavior_for_fragile_tests();
7739
7740        let sysvar_and_native_program_delta0 = 11;
7741        assert_eq!(
7742            bank0.capitalization(),
7743            42 * 1_000_000_000 + sysvar_and_native_program_delta0
7744        );
7745        assert!(bank0.rewards.read().unwrap().is_empty());
7746
7747        let ((vote_id, mut vote_account), (stake_id, stake_account)) =
7748            crate::stakes::tests::create_staked_node_accounts(1_0000);
7749
7750        // set up accounts
7751        bank0.store_account_and_update_capitalization(&stake_id, &stake_account);
7752
7753        // generate some rewards
7754        let mut vote_state = Some(VoteState::from(&vote_account).unwrap());
7755        for i in 0..MAX_LOCKOUT_HISTORY + 42 {
7756            if let Some(v) = vote_state.as_mut() {
7757                v.process_slot_vote_unchecked(i as u64)
7758            }
7759            let versioned = VoteStateVersions::Current(Box::new(vote_state.take().unwrap()));
7760            VoteState::to(&versioned, &mut vote_account).unwrap();
7761            bank0.store_account_and_update_capitalization(&vote_id, &vote_account);
7762            match versioned {
7763                VoteStateVersions::Current(v) => {
7764                    vote_state = Some(*v);
7765                }
7766                _ => panic!("Has to be of type Current"),
7767            };
7768        }
7769        bank0.store_account_and_update_capitalization(&vote_id, &vote_account);
7770
7771        let validator_points: u128 = bank0
7772            .stake_delegation_accounts(&mut null_tracer())
7773            .iter()
7774            .flat_map(|(_vote_pubkey, (stake_group, vote_account))| {
7775                stake_group
7776                    .iter()
7777                    .map(move |(_stake_pubkey, stake_account)| (stake_account, vote_account))
7778            })
7779            .map(|(stake_account, vote_account)| {
7780                stake_state::calculate_points(stake_account, vote_account, None).unwrap_or(0)
7781            })
7782            .sum();
7783
7784        // put a child bank in epoch 1, which calls update_rewards()...
7785        let bank1 = Bank::new_from_parent(
7786            &bank0,
7787            &Pubkey::default(),
7788            bank0.get_slots_in_epoch(bank0.epoch()) + 1,
7789        );
7790        // verify that there's inflation
7791        assert_ne!(bank1.capitalization(), bank0.capitalization());
7792
7793        // verify the inflation is represented in validator_points *
7794        let sysvar_and_native_program_delta1 = 2;
7795        let paid_rewards =
7796            bank1.capitalization() - bank0.capitalization() - sysvar_and_native_program_delta1;
7797
7798        let rewards = bank1
7799            .get_account(&sysvar::rewards::id())
7800            .map(|account| from_account::<Rewards, _>(&account).unwrap())
7801            .unwrap();
7802
7803        // verify the stake and vote accounts are the right size
7804        assert!(
7805            ((bank1.get_balance(&stake_id) - stake_account.carats() + bank1.get_balance(&vote_id)
7806                - vote_account.carats()) as f64
7807                - rewards.validator_point_value * validator_points as f64)
7808                .abs()
7809                < 1.0
7810        );
7811
7812        // verify the rewards are the right size
7813        let allocated_rewards = rewards.validator_point_value * validator_points as f64;
7814        assert!((allocated_rewards - paid_rewards as f64).abs() < 1.0); // rounding, truncating
7815
7816        // verify validator rewards show up in bank1.rewards vector
7817        assert_eq!(
7818            *bank1.rewards.read().unwrap(),
7819            vec![(
7820                stake_id,
7821                RewardInfo {
7822                    reward_type: RewardType::Staking,
7823                    carats: (rewards.validator_point_value * validator_points as f64) as i64,
7824                    post_balance: bank1.get_balance(&stake_id),
7825                    commission: Some(0),
7826                }
7827            )]
7828        );
7829        bank1.freeze();
7830        assert!(bank1.calculate_and_verify_capitalization(true));
7831    }
7832
7833    fn do_test_bank_update_rewards_determinism() -> u64 {
7834        // create a bank that ticks really slowly...
7835        let bank = Arc::new(Bank::new_for_tests(&GenesisConfig {
7836            accounts: (0..42)
7837                .map(|_| {
7838                    (
7839                        gemachain_sdk::pubkey::new_rand(),
7840                        Account::new(1_000_000_000, 0, &Pubkey::default()),
7841                    )
7842                })
7843                .collect(),
7844            // set it up so the first epoch is a full year long
7845            poh_config: PohConfig {
7846                target_tick_duration: Duration::from_secs(
7847                    SECONDS_PER_YEAR as u64
7848                        / MINIMUM_SLOTS_PER_EPOCH as u64
7849                        / DEFAULT_TICKS_PER_SLOT,
7850                ),
7851                hashes_per_tick: None,
7852                target_tick_count: None,
7853            },
7854            cluster_type: ClusterType::MainnetBeta,
7855
7856            ..GenesisConfig::default()
7857        }));
7858
7859        // enable lazy rent collection because this test depends on rent-due accounts
7860        // not being eagerly-collected for exact rewards calculation
7861        bank.restore_old_behavior_for_fragile_tests();
7862
7863        let sysvar_and_native_program_delta = 11;
7864        assert_eq!(
7865            bank.capitalization(),
7866            42 * 1_000_000_000 + sysvar_and_native_program_delta
7867        );
7868        assert!(bank.rewards.read().unwrap().is_empty());
7869
7870        let vote_id = gemachain_sdk::pubkey::new_rand();
7871        let mut vote_account =
7872            vote_state::create_account(&vote_id, &gemachain_sdk::pubkey::new_rand(), 50, 100);
7873        let (stake_id1, stake_account1) = crate::stakes::tests::create_stake_account(123, &vote_id);
7874        let (stake_id2, stake_account2) = crate::stakes::tests::create_stake_account(456, &vote_id);
7875
7876        // set up accounts
7877        bank.store_account_and_update_capitalization(&stake_id1, &stake_account1);
7878        bank.store_account_and_update_capitalization(&stake_id2, &stake_account2);
7879
7880        // generate some rewards
7881        let mut vote_state = Some(VoteState::from(&vote_account).unwrap());
7882        for i in 0..MAX_LOCKOUT_HISTORY + 42 {
7883            if let Some(v) = vote_state.as_mut() {
7884                v.process_slot_vote_unchecked(i as u64)
7885            }
7886            let versioned = VoteStateVersions::Current(Box::new(vote_state.take().unwrap()));
7887            VoteState::to(&versioned, &mut vote_account).unwrap();
7888            bank.store_account_and_update_capitalization(&vote_id, &vote_account);
7889            match versioned {
7890                VoteStateVersions::Current(v) => {
7891                    vote_state = Some(*v);
7892                }
7893                _ => panic!("Has to be of type Current"),
7894            };
7895        }
7896        bank.store_account_and_update_capitalization(&vote_id, &vote_account);
7897
7898        // put a child bank in epoch 1, which calls update_rewards()...
7899        let bank1 = Bank::new_from_parent(
7900            &bank,
7901            &Pubkey::default(),
7902            bank.get_slots_in_epoch(bank.epoch()) + 1,
7903        );
7904        // verify that there's inflation
7905        assert_ne!(bank1.capitalization(), bank.capitalization());
7906
7907        bank1.freeze();
7908        assert!(bank1.calculate_and_verify_capitalization(true));
7909
7910        // verify voting and staking rewards are recorded
7911        let rewards = bank1.rewards.read().unwrap();
7912        rewards
7913            .iter()
7914            .find(|(_address, reward)| reward.reward_type == RewardType::Voting)
7915            .unwrap();
7916        rewards
7917            .iter()
7918            .find(|(_address, reward)| reward.reward_type == RewardType::Staking)
7919            .unwrap();
7920
7921        bank1.capitalization()
7922    }
7923
7924    #[test]
7925    fn test_bank_update_rewards_determinism() {
7926        gemachain_logger::setup();
7927
7928        // The same reward should be distributed given same credits
7929        let expected_capitalization = do_test_bank_update_rewards_determinism();
7930        // Repeat somewhat large number of iterations to expose possible different behavior
7931        // depending on the randomly-seeded HashMap ordering
7932        for _ in 0..30 {
7933            let actual_capitalization = do_test_bank_update_rewards_determinism();
7934            assert_eq!(actual_capitalization, expected_capitalization);
7935        }
7936    }
7937
7938    // Test that purging 0 carats accounts works.
7939    #[test]
7940    fn test_purge_empty_accounts() {
7941        gemachain_logger::setup();
7942        let (genesis_config, mint_keypair) = create_genesis_config(500_000);
7943        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
7944        let mut bank = parent;
7945        for _ in 0..10 {
7946            let blockhash = bank.last_blockhash();
7947            let pubkey = gemachain_sdk::pubkey::new_rand();
7948            let tx = system_transaction::transfer(&mint_keypair, &pubkey, 0, blockhash);
7949            bank.process_transaction(&tx).unwrap();
7950            bank.freeze();
7951            bank.squash();
7952            bank = Arc::new(new_from_parent(&bank));
7953        }
7954
7955        bank.freeze();
7956        bank.squash();
7957        bank.force_flush_accounts_cache();
7958        let hash = bank.update_accounts_hash();
7959        bank.clean_accounts(false, false, None);
7960        assert_eq!(bank.update_accounts_hash(), hash);
7961
7962        let bank0 = Arc::new(new_from_parent(&bank));
7963        let blockhash = bank.last_blockhash();
7964        let keypair = Keypair::new();
7965        let tx = system_transaction::transfer(&mint_keypair, &keypair.pubkey(), 10, blockhash);
7966        bank0.process_transaction(&tx).unwrap();
7967
7968        let bank1 = Arc::new(new_from_parent(&bank0));
7969        let pubkey = gemachain_sdk::pubkey::new_rand();
7970        let blockhash = bank.last_blockhash();
7971        let tx = system_transaction::transfer(&keypair, &pubkey, 10, blockhash);
7972        bank1.process_transaction(&tx).unwrap();
7973
7974        assert_eq!(bank0.get_account(&keypair.pubkey()).unwrap().carats(), 10);
7975        assert_eq!(bank1.get_account(&keypair.pubkey()), None);
7976
7977        info!("bank0 purge");
7978        let hash = bank0.update_accounts_hash();
7979        bank0.clean_accounts(false, false, None);
7980        assert_eq!(bank0.update_accounts_hash(), hash);
7981
7982        assert_eq!(bank0.get_account(&keypair.pubkey()).unwrap().carats(), 10);
7983        assert_eq!(bank1.get_account(&keypair.pubkey()), None);
7984
7985        info!("bank1 purge");
7986        bank1.clean_accounts(false, false, None);
7987
7988        assert_eq!(bank0.get_account(&keypair.pubkey()).unwrap().carats(), 10);
7989        assert_eq!(bank1.get_account(&keypair.pubkey()), None);
7990
7991        assert!(bank0.verify_bank_hash(true));
7992
7993        // Squash and then verify hash_internal value
7994        bank0.freeze();
7995        bank0.squash();
7996        assert!(bank0.verify_bank_hash(true));
7997
7998        bank1.freeze();
7999        bank1.squash();
8000        bank1.update_accounts_hash();
8001        assert!(bank1.verify_bank_hash(true));
8002
8003        // keypair should have 0 tokens on both forks
8004        assert_eq!(bank0.get_account(&keypair.pubkey()), None);
8005        assert_eq!(bank1.get_account(&keypair.pubkey()), None);
8006        bank1.force_flush_accounts_cache();
8007        bank1.clean_accounts(false, false, None);
8008
8009        assert!(bank1.verify_bank_hash(true));
8010    }
8011
8012    #[test]
8013    fn test_two_payments_to_one_party() {
8014        let (genesis_config, mint_keypair) = create_genesis_config(10_000);
8015        let pubkey = gemachain_sdk::pubkey::new_rand();
8016        let bank = Bank::new_for_tests(&genesis_config);
8017        assert_eq!(bank.last_blockhash(), genesis_config.hash());
8018
8019        bank.transfer(1_000, &mint_keypair, &pubkey).unwrap();
8020        assert_eq!(bank.get_balance(&pubkey), 1_000);
8021
8022        bank.transfer(500, &mint_keypair, &pubkey).unwrap();
8023        assert_eq!(bank.get_balance(&pubkey), 1_500);
8024        assert_eq!(bank.transaction_count(), 2);
8025    }
8026
8027    #[test]
8028    fn test_one_source_two_tx_one_batch() {
8029        let (genesis_config, mint_keypair) = create_genesis_config(1);
8030        let key1 = gemachain_sdk::pubkey::new_rand();
8031        let key2 = gemachain_sdk::pubkey::new_rand();
8032        let bank = Bank::new_for_tests(&genesis_config);
8033        assert_eq!(bank.last_blockhash(), genesis_config.hash());
8034
8035        let t1 = system_transaction::transfer(&mint_keypair, &key1, 1, genesis_config.hash());
8036        let t2 = system_transaction::transfer(&mint_keypair, &key2, 1, genesis_config.hash());
8037        let txs = vec![t1.clone(), t2.clone()];
8038        let res = bank.process_transactions(txs.iter());
8039
8040        assert_eq!(res.len(), 2);
8041        assert_eq!(res[0], Ok(()));
8042        assert_eq!(res[1], Err(TransactionError::AccountInUse));
8043        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 0);
8044        assert_eq!(bank.get_balance(&key1), 1);
8045        assert_eq!(bank.get_balance(&key2), 0);
8046        assert_eq!(bank.get_signature_status(&t1.signatures[0]), Some(Ok(())));
8047        // TODO: Transactions that fail to pay a fee could be dropped silently.
8048        // Non-instruction errors don't get logged in the signature cache
8049        assert_eq!(bank.get_signature_status(&t2.signatures[0]), None);
8050    }
8051
8052    #[test]
8053    fn test_one_tx_two_out_atomic_fail() {
8054        let (genesis_config, mint_keypair) = create_genesis_config(1);
8055        let key1 = gemachain_sdk::pubkey::new_rand();
8056        let key2 = gemachain_sdk::pubkey::new_rand();
8057        let bank = Bank::new_for_tests(&genesis_config);
8058        let instructions =
8059            system_instruction::transfer_many(&mint_keypair.pubkey(), &[(key1, 1), (key2, 1)]);
8060        let message = Message::new(&instructions, Some(&mint_keypair.pubkey()));
8061        let tx = Transaction::new(&[&mint_keypair], message, genesis_config.hash());
8062        assert_eq!(
8063            bank.process_transaction(&tx).unwrap_err(),
8064            TransactionError::InstructionError(1, SystemError::ResultWithNegativeCarats.into())
8065        );
8066        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 1);
8067        assert_eq!(bank.get_balance(&key1), 0);
8068        assert_eq!(bank.get_balance(&key2), 0);
8069    }
8070
8071    #[test]
8072    fn test_one_tx_two_out_atomic_pass() {
8073        let (genesis_config, mint_keypair) = create_genesis_config(2);
8074        let key1 = gemachain_sdk::pubkey::new_rand();
8075        let key2 = gemachain_sdk::pubkey::new_rand();
8076        let bank = Bank::new_for_tests(&genesis_config);
8077        let instructions =
8078            system_instruction::transfer_many(&mint_keypair.pubkey(), &[(key1, 1), (key2, 1)]);
8079        let message = Message::new(&instructions, Some(&mint_keypair.pubkey()));
8080        let tx = Transaction::new(&[&mint_keypair], message, genesis_config.hash());
8081        bank.process_transaction(&tx).unwrap();
8082        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 0);
8083        assert_eq!(bank.get_balance(&key1), 1);
8084        assert_eq!(bank.get_balance(&key2), 1);
8085    }
8086
8087    // This test demonstrates that fees are paid even when a program fails.
8088    #[test]
8089    fn test_detect_failed_duplicate_transactions() {
8090        let (mut genesis_config, mint_keypair) = create_genesis_config(2);
8091        genesis_config.fee_rate_governor = FeeRateGovernor::new(1, 0);
8092        let bank = Bank::new_for_tests(&genesis_config);
8093
8094        let dest = Keypair::new();
8095
8096        // source with 0 program context
8097        let tx =
8098            system_transaction::transfer(&mint_keypair, &dest.pubkey(), 2, genesis_config.hash());
8099        let signature = tx.signatures[0];
8100        assert!(!bank.has_signature(&signature));
8101
8102        assert_eq!(
8103            bank.process_transaction(&tx),
8104            Err(TransactionError::InstructionError(
8105                0,
8106                SystemError::ResultWithNegativeCarats.into(),
8107            ))
8108        );
8109
8110        // The carats didn't move, but the from address paid the transaction fee.
8111        assert_eq!(bank.get_balance(&dest.pubkey()), 0);
8112
8113        // This should be the original balance minus the transaction fee.
8114        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 1);
8115    }
8116
8117    #[test]
8118    fn test_account_not_found() {
8119        gemachain_logger::setup();
8120        let (genesis_config, mint_keypair) = create_genesis_config(0);
8121        let bank = Bank::new_for_tests(&genesis_config);
8122        let keypair = Keypair::new();
8123        assert_eq!(
8124            bank.transfer(1, &keypair, &mint_keypair.pubkey()),
8125            Err(TransactionError::AccountNotFound)
8126        );
8127        assert_eq!(bank.transaction_count(), 0);
8128    }
8129
8130    #[test]
8131    fn test_insufficient_funds() {
8132        let (genesis_config, mint_keypair) = create_genesis_config(11_000);
8133        let bank = Bank::new_for_tests(&genesis_config);
8134        let pubkey = gemachain_sdk::pubkey::new_rand();
8135        bank.transfer(1_000, &mint_keypair, &pubkey).unwrap();
8136        assert_eq!(bank.transaction_count(), 1);
8137        assert_eq!(bank.get_balance(&pubkey), 1_000);
8138        assert_eq!(
8139            bank.transfer(10_001, &mint_keypair, &pubkey),
8140            Err(TransactionError::InstructionError(
8141                0,
8142                SystemError::ResultWithNegativeCarats.into(),
8143            ))
8144        );
8145        assert_eq!(bank.transaction_count(), 1);
8146
8147        let mint_pubkey = mint_keypair.pubkey();
8148        assert_eq!(bank.get_balance(&mint_pubkey), 10_000);
8149        assert_eq!(bank.get_balance(&pubkey), 1_000);
8150    }
8151
8152    #[test]
8153    fn test_transfer_to_newb() {
8154        gemachain_logger::setup();
8155        let (genesis_config, mint_keypair) = create_genesis_config(10_000);
8156        let bank = Bank::new_for_tests(&genesis_config);
8157        let pubkey = gemachain_sdk::pubkey::new_rand();
8158        bank.transfer(500, &mint_keypair, &pubkey).unwrap();
8159        assert_eq!(bank.get_balance(&pubkey), 500);
8160    }
8161
8162    #[test]
8163    fn test_transfer_to_sysvar() {
8164        gemachain_logger::setup();
8165        let (genesis_config, mint_keypair) = create_genesis_config(10_000);
8166        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
8167
8168        let normal_pubkey = gemachain_sdk::pubkey::new_rand();
8169        let sysvar_pubkey = sysvar::clock::id();
8170        assert_eq!(bank.get_balance(&normal_pubkey), 0);
8171        assert_eq!(bank.get_balance(&sysvar_pubkey), 1);
8172
8173        bank.transfer(500, &mint_keypair, &normal_pubkey).unwrap();
8174        bank.transfer(500, &mint_keypair, &sysvar_pubkey)
8175            .unwrap_err();
8176        assert_eq!(bank.get_balance(&normal_pubkey), 500);
8177        assert_eq!(bank.get_balance(&sysvar_pubkey), 1);
8178
8179        let bank = Arc::new(new_from_parent(&bank));
8180        assert_eq!(bank.get_balance(&normal_pubkey), 500);
8181        assert_eq!(bank.get_balance(&sysvar_pubkey), 1);
8182    }
8183
8184    #[test]
8185    fn test_bank_deposit() {
8186        let (genesis_config, _mint_keypair) = create_genesis_config(100);
8187        let bank = Bank::new_for_tests(&genesis_config);
8188
8189        // Test new account
8190        let key = Keypair::new();
8191        let new_balance = bank.deposit(&key.pubkey(), 10).unwrap();
8192        assert_eq!(new_balance, 10);
8193        assert_eq!(bank.get_balance(&key.pubkey()), 10);
8194
8195        // Existing account
8196        let new_balance = bank.deposit(&key.pubkey(), 3).unwrap();
8197        assert_eq!(new_balance, 13);
8198        assert_eq!(bank.get_balance(&key.pubkey()), 13);
8199    }
8200
8201    #[test]
8202    fn test_bank_withdraw() {
8203        let (genesis_config, _mint_keypair) = create_genesis_config(100);
8204        let bank = Bank::new_for_tests(&genesis_config);
8205
8206        // Test no account
8207        let key = Keypair::new();
8208        assert_eq!(
8209            bank.withdraw(&key.pubkey(), 10),
8210            Err(TransactionError::AccountNotFound)
8211        );
8212
8213        bank.deposit(&key.pubkey(), 3).unwrap();
8214        assert_eq!(bank.get_balance(&key.pubkey()), 3);
8215
8216        // Low balance
8217        assert_eq!(
8218            bank.withdraw(&key.pubkey(), 10),
8219            Err(TransactionError::InsufficientFundsForFee)
8220        );
8221
8222        // Enough balance
8223        assert_eq!(bank.withdraw(&key.pubkey(), 2), Ok(()));
8224        assert_eq!(bank.get_balance(&key.pubkey()), 1);
8225    }
8226
8227    #[test]
8228    fn test_bank_withdraw_from_nonce_account() {
8229        let (mut genesis_config, _mint_keypair) = create_genesis_config(100_000);
8230        genesis_config.rent.carats_per_byte_year = 42;
8231        let bank = Bank::new_for_tests(&genesis_config);
8232
8233        let min_balance = bank.get_minimum_balance_for_rent_exemption(nonce::State::size());
8234        let nonce = Keypair::new();
8235        let nonce_account = AccountSharedData::new_data(
8236            min_balance + 42,
8237            &nonce::state::Versions::new_current(nonce::State::Initialized(
8238                nonce::state::Data::default(),
8239            )),
8240            &system_program::id(),
8241        )
8242        .unwrap();
8243        bank.store_account(&nonce.pubkey(), &nonce_account);
8244        assert_eq!(bank.get_balance(&nonce.pubkey()), min_balance + 42);
8245
8246        // Resulting in non-zero, but sub-min_balance balance fails
8247        assert_eq!(
8248            bank.withdraw(&nonce.pubkey(), min_balance / 2),
8249            Err(TransactionError::InsufficientFundsForFee)
8250        );
8251        assert_eq!(bank.get_balance(&nonce.pubkey()), min_balance + 42);
8252
8253        // Resulting in exactly rent-exempt balance succeeds
8254        bank.withdraw(&nonce.pubkey(), 42).unwrap();
8255        assert_eq!(bank.get_balance(&nonce.pubkey()), min_balance);
8256
8257        // Account closure fails
8258        assert_eq!(
8259            bank.withdraw(&nonce.pubkey(), min_balance),
8260            Err(TransactionError::InsufficientFundsForFee),
8261        );
8262    }
8263
8264    #[test]
8265    fn test_bank_tx_fee() {
8266        gemachain_logger::setup();
8267
8268        let arbitrary_transfer_amount = 42;
8269        let mint = arbitrary_transfer_amount * 100;
8270        let leader = gemachain_sdk::pubkey::new_rand();
8271        let GenesisConfigInfo {
8272            mut genesis_config,
8273            mint_keypair,
8274            ..
8275        } = create_genesis_config_with_leader(mint, &leader, 3);
8276        genesis_config.fee_rate_governor = FeeRateGovernor::new(4, 0); // something divisible by 2
8277
8278        let expected_fee_paid = genesis_config
8279            .fee_rate_governor
8280            .create_fee_calculator()
8281            .carats_per_signature;
8282        let (expected_fee_collected, expected_fee_burned) =
8283            genesis_config.fee_rate_governor.burn(expected_fee_paid);
8284
8285        let mut bank = Bank::new_for_tests(&genesis_config);
8286
8287        let capitalization = bank.capitalization();
8288
8289        let key = Keypair::new();
8290        let tx = system_transaction::transfer(
8291            &mint_keypair,
8292            &key.pubkey(),
8293            arbitrary_transfer_amount,
8294            bank.last_blockhash(),
8295        );
8296
8297        let initial_balance = bank.get_balance(&leader);
8298        assert_eq!(bank.process_transaction(&tx), Ok(()));
8299        assert_eq!(bank.get_balance(&key.pubkey()), arbitrary_transfer_amount);
8300        assert_eq!(
8301            bank.get_balance(&mint_keypair.pubkey()),
8302            mint - arbitrary_transfer_amount - expected_fee_paid
8303        );
8304
8305        assert_eq!(bank.get_balance(&leader), initial_balance);
8306        goto_end_of_slot(&mut bank);
8307        assert_eq!(bank.signature_count(), 1);
8308        assert_eq!(
8309            bank.get_balance(&leader),
8310            initial_balance + expected_fee_collected
8311        ); // Leader collects fee after the bank is frozen
8312
8313        // verify capitalization
8314        let sysvar_and_native_program_delta = 1;
8315        assert_eq!(
8316            capitalization - expected_fee_burned + sysvar_and_native_program_delta,
8317            bank.capitalization()
8318        );
8319
8320        assert_eq!(
8321            *bank.rewards.read().unwrap(),
8322            vec![(
8323                leader,
8324                RewardInfo {
8325                    reward_type: RewardType::Fee,
8326                    carats: expected_fee_collected as i64,
8327                    post_balance: initial_balance + expected_fee_collected,
8328                    commission: None,
8329                }
8330            )]
8331        );
8332
8333        // Verify that an InstructionError collects fees, too
8334        let mut bank = Bank::new_from_parent(&Arc::new(bank), &leader, 1);
8335        let mut tx =
8336            system_transaction::transfer(&mint_keypair, &key.pubkey(), 1, bank.last_blockhash());
8337        // Create a bogus instruction to system_program to cause an instruction error
8338        tx.message.instructions[0].data[0] = 40;
8339
8340        bank.process_transaction(&tx)
8341            .expect_err("instruction error");
8342        assert_eq!(bank.get_balance(&key.pubkey()), arbitrary_transfer_amount); // no change
8343        assert_eq!(
8344            bank.get_balance(&mint_keypair.pubkey()),
8345            mint - arbitrary_transfer_amount - 2 * expected_fee_paid
8346        ); // mint_keypair still pays a fee
8347        goto_end_of_slot(&mut bank);
8348        assert_eq!(bank.signature_count(), 1);
8349
8350        // Profit! 2 transaction signatures processed at 3 carats each
8351        assert_eq!(
8352            bank.get_balance(&leader),
8353            initial_balance + 2 * expected_fee_collected
8354        );
8355
8356        assert_eq!(
8357            *bank.rewards.read().unwrap(),
8358            vec![(
8359                leader,
8360                RewardInfo {
8361                    reward_type: RewardType::Fee,
8362                    carats: expected_fee_collected as i64,
8363                    post_balance: initial_balance + 2 * expected_fee_collected,
8364                    commission: None,
8365                }
8366            )]
8367        );
8368    }
8369
8370    #[test]
8371    fn test_bank_blockhash_fee_schedule() {
8372        //gemachain_logger::setup();
8373
8374        let leader = gemachain_sdk::pubkey::new_rand();
8375        let GenesisConfigInfo {
8376            mut genesis_config,
8377            mint_keypair,
8378            ..
8379        } = create_genesis_config_with_leader(1_000_000, &leader, 3);
8380        genesis_config
8381            .fee_rate_governor
8382            .target_carats_per_signature = 1000;
8383        genesis_config.fee_rate_governor.target_signatures_per_slot = 1;
8384
8385        let mut bank = Bank::new_for_tests(&genesis_config);
8386        goto_end_of_slot(&mut bank);
8387        #[allow(deprecated)]
8388        let (cheap_blockhash, cheap_fee_calculator) = bank.last_blockhash_with_fee_calculator();
8389        assert_eq!(cheap_fee_calculator.carats_per_signature, 0);
8390
8391        let mut bank = Bank::new_from_parent(&Arc::new(bank), &leader, 1);
8392        goto_end_of_slot(&mut bank);
8393        #[allow(deprecated)]
8394        let (expensive_blockhash, expensive_fee_calculator) =
8395            bank.last_blockhash_with_fee_calculator();
8396        assert!(
8397            cheap_fee_calculator.carats_per_signature
8398                < expensive_fee_calculator.carats_per_signature
8399        );
8400
8401        let bank = Bank::new_from_parent(&Arc::new(bank), &leader, 2);
8402
8403        // Send a transfer using cheap_blockhash
8404        let key = Keypair::new();
8405        let initial_mint_balance = bank.get_balance(&mint_keypair.pubkey());
8406        let tx = system_transaction::transfer(&mint_keypair, &key.pubkey(), 1, cheap_blockhash);
8407        assert_eq!(bank.process_transaction(&tx), Ok(()));
8408        assert_eq!(bank.get_balance(&key.pubkey()), 1);
8409        assert_eq!(
8410            bank.get_balance(&mint_keypair.pubkey()),
8411            initial_mint_balance - 1 - cheap_fee_calculator.carats_per_signature
8412        );
8413
8414        // Send a transfer using expensive_blockhash
8415        let key = Keypair::new();
8416        let initial_mint_balance = bank.get_balance(&mint_keypair.pubkey());
8417        let tx = system_transaction::transfer(&mint_keypair, &key.pubkey(), 1, expensive_blockhash);
8418        assert_eq!(bank.process_transaction(&tx), Ok(()));
8419        assert_eq!(bank.get_balance(&key.pubkey()), 1);
8420        assert_eq!(
8421            bank.get_balance(&mint_keypair.pubkey()),
8422            initial_mint_balance - 1 - expensive_fee_calculator.carats_per_signature
8423        );
8424    }
8425
8426    #[test]
8427    fn test_filter_program_errors_and_collect_fee() {
8428        let leader = gemachain_sdk::pubkey::new_rand();
8429        let GenesisConfigInfo {
8430            mut genesis_config,
8431            mint_keypair,
8432            ..
8433        } = create_genesis_config_with_leader(100, &leader, 3);
8434        genesis_config.fee_rate_governor = FeeRateGovernor::new(2, 0);
8435        let bank = Bank::new_for_tests(&genesis_config);
8436
8437        let key = Keypair::new();
8438        let tx1 =
8439            system_transaction::transfer(&mint_keypair, &key.pubkey(), 2, genesis_config.hash())
8440                .try_into()
8441                .unwrap();
8442        let tx2 =
8443            system_transaction::transfer(&mint_keypair, &key.pubkey(), 5, genesis_config.hash())
8444                .try_into()
8445                .unwrap();
8446
8447        let results = vec![
8448            (Ok(()), None),
8449            (
8450                Err(TransactionError::InstructionError(
8451                    1,
8452                    SystemError::ResultWithNegativeCarats.into(),
8453                )),
8454                None,
8455            ),
8456        ];
8457        let initial_balance = bank.get_balance(&leader);
8458
8459        let results = bank.filter_program_errors_and_collect_fee(&[tx1, tx2], &results);
8460        bank.freeze();
8461        assert_eq!(
8462            bank.get_balance(&leader),
8463            initial_balance
8464                + bank
8465                    .fee_rate_governor
8466                    .burn(bank.fee_calculator.carats_per_signature * 2)
8467                    .0
8468        );
8469        assert_eq!(results[0], Ok(()));
8470        assert_eq!(results[1], Ok(()));
8471    }
8472
8473    #[test]
8474    fn test_debits_before_credits() {
8475        let (genesis_config, mint_keypair) = create_genesis_config(2);
8476        let bank = Bank::new_for_tests(&genesis_config);
8477        let keypair = Keypair::new();
8478        let tx0 = system_transaction::transfer(
8479            &mint_keypair,
8480            &keypair.pubkey(),
8481            2,
8482            genesis_config.hash(),
8483        );
8484        let tx1 = system_transaction::transfer(
8485            &keypair,
8486            &mint_keypair.pubkey(),
8487            1,
8488            genesis_config.hash(),
8489        );
8490        let txs = vec![tx0, tx1];
8491        let results = bank.process_transactions(txs.iter());
8492        assert!(results[1].is_err());
8493
8494        // Assert bad transactions aren't counted.
8495        assert_eq!(bank.transaction_count(), 1);
8496    }
8497
8498    #[test]
8499    fn test_readonly_accounts() {
8500        let GenesisConfigInfo {
8501            genesis_config,
8502            mint_keypair,
8503            ..
8504        } = create_genesis_config_with_leader(500, &gemachain_sdk::pubkey::new_rand(), 0);
8505        let bank = Bank::new_for_tests(&genesis_config);
8506
8507        let vote_pubkey0 = gemachain_sdk::pubkey::new_rand();
8508        let vote_pubkey1 = gemachain_sdk::pubkey::new_rand();
8509        let vote_pubkey2 = gemachain_sdk::pubkey::new_rand();
8510        let authorized_voter = Keypair::new();
8511        let payer0 = Keypair::new();
8512        let payer1 = Keypair::new();
8513
8514        // Create vote accounts
8515        let vote_account0 =
8516            vote_state::create_account(&vote_pubkey0, &authorized_voter.pubkey(), 0, 100);
8517        let vote_account1 =
8518            vote_state::create_account(&vote_pubkey1, &authorized_voter.pubkey(), 0, 100);
8519        let vote_account2 =
8520            vote_state::create_account(&vote_pubkey2, &authorized_voter.pubkey(), 0, 100);
8521        bank.store_account(&vote_pubkey0, &vote_account0);
8522        bank.store_account(&vote_pubkey1, &vote_account1);
8523        bank.store_account(&vote_pubkey2, &vote_account2);
8524
8525        // Fund payers
8526        bank.transfer(10, &mint_keypair, &payer0.pubkey()).unwrap();
8527        bank.transfer(10, &mint_keypair, &payer1.pubkey()).unwrap();
8528        bank.transfer(1, &mint_keypair, &authorized_voter.pubkey())
8529            .unwrap();
8530
8531        let vote = Vote::new(vec![1], Hash::default());
8532        let ix0 = vote_instruction::vote(&vote_pubkey0, &authorized_voter.pubkey(), vote.clone());
8533        let tx0 = Transaction::new_signed_with_payer(
8534            &[ix0],
8535            Some(&payer0.pubkey()),
8536            &[&payer0, &authorized_voter],
8537            bank.last_blockhash(),
8538        );
8539        let ix1 = vote_instruction::vote(&vote_pubkey1, &authorized_voter.pubkey(), vote.clone());
8540        let tx1 = Transaction::new_signed_with_payer(
8541            &[ix1],
8542            Some(&payer1.pubkey()),
8543            &[&payer1, &authorized_voter],
8544            bank.last_blockhash(),
8545        );
8546        let txs = vec![tx0, tx1];
8547        let results = bank.process_transactions(txs.iter());
8548
8549        // If multiple transactions attempt to read the same account, they should succeed.
8550        // Vote authorized_voter and sysvar accounts are given read-only handling
8551        assert_eq!(results[0], Ok(()));
8552        assert_eq!(results[1], Ok(()));
8553
8554        let ix0 = vote_instruction::vote(&vote_pubkey2, &authorized_voter.pubkey(), vote);
8555        let tx0 = Transaction::new_signed_with_payer(
8556            &[ix0],
8557            Some(&payer0.pubkey()),
8558            &[&payer0, &authorized_voter],
8559            bank.last_blockhash(),
8560        );
8561        let tx1 = system_transaction::transfer(
8562            &authorized_voter,
8563            &gemachain_sdk::pubkey::new_rand(),
8564            1,
8565            bank.last_blockhash(),
8566        );
8567        let txs = vec![tx0, tx1];
8568        let results = bank.process_transactions(txs.iter());
8569        // However, an account may not be locked as read-only and writable at the same time.
8570        assert_eq!(results[0], Ok(()));
8571        assert_eq!(results[1], Err(TransactionError::AccountInUse));
8572    }
8573
8574    #[test]
8575    fn test_interleaving_locks() {
8576        let (genesis_config, mint_keypair) = create_genesis_config(3);
8577        let bank = Bank::new_for_tests(&genesis_config);
8578        let alice = Keypair::new();
8579        let bob = Keypair::new();
8580
8581        let tx1 =
8582            system_transaction::transfer(&mint_keypair, &alice.pubkey(), 1, genesis_config.hash());
8583        let pay_alice = vec![tx1];
8584
8585        let lock_result = bank.prepare_batch(pay_alice).unwrap();
8586        let results_alice = bank
8587            .load_execute_and_commit_transactions(
8588                &lock_result,
8589                MAX_PROCESSING_AGE,
8590                false,
8591                false,
8592                false,
8593                &mut ExecuteTimings::default(),
8594            )
8595            .0
8596            .fee_collection_results;
8597        assert_eq!(results_alice[0], Ok(()));
8598
8599        // try executing an interleaved transfer twice
8600        assert_eq!(
8601            bank.transfer(1, &mint_keypair, &bob.pubkey()),
8602            Err(TransactionError::AccountInUse)
8603        );
8604        // the second time should fail as well
8605        // this verifies that `unlock_accounts` doesn't unlock `AccountInUse` accounts
8606        assert_eq!(
8607            bank.transfer(1, &mint_keypair, &bob.pubkey()),
8608            Err(TransactionError::AccountInUse)
8609        );
8610
8611        drop(lock_result);
8612
8613        assert!(bank.transfer(2, &mint_keypair, &bob.pubkey()).is_ok());
8614    }
8615
8616    #[test]
8617    fn test_readonly_relaxed_locks() {
8618        let (genesis_config, _) = create_genesis_config(3);
8619        let bank = Bank::new_for_tests(&genesis_config);
8620        let key0 = Keypair::new();
8621        let key1 = Keypair::new();
8622        let key2 = Keypair::new();
8623        let key3 = gemachain_sdk::pubkey::new_rand();
8624
8625        let message = Message {
8626            header: MessageHeader {
8627                num_required_signatures: 1,
8628                num_readonly_signed_accounts: 0,
8629                num_readonly_unsigned_accounts: 1,
8630            },
8631            account_keys: vec![key0.pubkey(), key3],
8632            recent_blockhash: Hash::default(),
8633            instructions: vec![],
8634        };
8635        let tx = Transaction::new(&[&key0], message, genesis_config.hash());
8636        let txs = vec![tx];
8637
8638        let batch0 = bank.prepare_batch(txs).unwrap();
8639        assert!(batch0.lock_results()[0].is_ok());
8640
8641        // Try locking accounts, locking a previously read-only account as writable
8642        // should fail
8643        let message = Message {
8644            header: MessageHeader {
8645                num_required_signatures: 1,
8646                num_readonly_signed_accounts: 0,
8647                num_readonly_unsigned_accounts: 0,
8648            },
8649            account_keys: vec![key1.pubkey(), key3],
8650            recent_blockhash: Hash::default(),
8651            instructions: vec![],
8652        };
8653        let tx = Transaction::new(&[&key1], message, genesis_config.hash());
8654        let txs = vec![tx];
8655
8656        let batch1 = bank.prepare_batch(txs).unwrap();
8657        assert!(batch1.lock_results()[0].is_err());
8658
8659        // Try locking a previously read-only account a 2nd time; should succeed
8660        let message = Message {
8661            header: MessageHeader {
8662                num_required_signatures: 1,
8663                num_readonly_signed_accounts: 0,
8664                num_readonly_unsigned_accounts: 1,
8665            },
8666            account_keys: vec![key2.pubkey(), key3],
8667            recent_blockhash: Hash::default(),
8668            instructions: vec![],
8669        };
8670        let tx = Transaction::new(&[&key2], message, genesis_config.hash());
8671        let txs = vec![tx];
8672
8673        let batch2 = bank.prepare_batch(txs).unwrap();
8674        assert!(batch2.lock_results()[0].is_ok());
8675    }
8676
8677    #[test]
8678    fn test_bank_invalid_account_index() {
8679        let (genesis_config, mint_keypair) = create_genesis_config(1);
8680        let keypair = Keypair::new();
8681        let bank = Bank::new_for_tests(&genesis_config);
8682
8683        let tx = system_transaction::transfer(
8684            &mint_keypair,
8685            &keypair.pubkey(),
8686            1,
8687            genesis_config.hash(),
8688        );
8689
8690        let mut tx_invalid_program_index = tx.clone();
8691        tx_invalid_program_index.message.instructions[0].program_id_index = 42;
8692        assert_eq!(
8693            bank.process_transaction(&tx_invalid_program_index),
8694            Err(TransactionError::SanitizeFailure)
8695        );
8696
8697        let mut tx_invalid_account_index = tx;
8698        tx_invalid_account_index.message.instructions[0].accounts[0] = 42;
8699        assert_eq!(
8700            bank.process_transaction(&tx_invalid_account_index),
8701            Err(TransactionError::SanitizeFailure)
8702        );
8703    }
8704
8705    #[test]
8706    fn test_bank_pay_to_self() {
8707        let (genesis_config, mint_keypair) = create_genesis_config(1);
8708        let key1 = Keypair::new();
8709        let bank = Bank::new_for_tests(&genesis_config);
8710
8711        bank.transfer(1, &mint_keypair, &key1.pubkey()).unwrap();
8712        assert_eq!(bank.get_balance(&key1.pubkey()), 1);
8713        let tx = system_transaction::transfer(&key1, &key1.pubkey(), 1, genesis_config.hash());
8714        let _res = bank.process_transaction(&tx);
8715
8716        assert_eq!(bank.get_balance(&key1.pubkey()), 1);
8717        bank.get_signature_status(&tx.signatures[0])
8718            .unwrap()
8719            .unwrap();
8720    }
8721
8722    fn new_from_parent(parent: &Arc<Bank>) -> Bank {
8723        Bank::new_from_parent(parent, &Pubkey::default(), parent.slot() + 1)
8724    }
8725
8726    /// Verify that the parent's vector is computed correctly
8727    #[test]
8728    fn test_bank_parents() {
8729        let (genesis_config, _) = create_genesis_config(1);
8730        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
8731
8732        let bank = new_from_parent(&parent);
8733        assert!(Arc::ptr_eq(&bank.parents()[0], &parent));
8734    }
8735
8736    /// Verifies that transactions are dropped if they have already been processed
8737    #[test]
8738    fn test_tx_already_processed() {
8739        let (genesis_config, mint_keypair) = create_genesis_config(2);
8740        let bank = Bank::new_for_tests(&genesis_config);
8741
8742        let key1 = Keypair::new();
8743        let mut tx =
8744            system_transaction::transfer(&mint_keypair, &key1.pubkey(), 1, genesis_config.hash());
8745
8746        // First process `tx` so that the status cache is updated
8747        assert_eq!(bank.process_transaction(&tx), Ok(()));
8748
8749        // Ensure that signature check works
8750        assert_eq!(
8751            bank.process_transaction(&tx),
8752            Err(TransactionError::AlreadyProcessed)
8753        );
8754
8755        // Change transaction signature to simulate processing a transaction with a different signature
8756        // for the same message.
8757        tx.signatures[0] = Signature::default();
8758
8759        // Ensure that message hash check works
8760        assert_eq!(
8761            bank.process_transaction(&tx),
8762            Err(TransactionError::AlreadyProcessed)
8763        );
8764    }
8765
8766    /// Verifies that last ids and status cache are correctly referenced from parent
8767    #[test]
8768    fn test_bank_parent_already_processed() {
8769        let (genesis_config, mint_keypair) = create_genesis_config(2);
8770        let key1 = Keypair::new();
8771        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
8772
8773        let tx =
8774            system_transaction::transfer(&mint_keypair, &key1.pubkey(), 1, genesis_config.hash());
8775        assert_eq!(parent.process_transaction(&tx), Ok(()));
8776        let bank = new_from_parent(&parent);
8777        assert_eq!(
8778            bank.process_transaction(&tx),
8779            Err(TransactionError::AlreadyProcessed)
8780        );
8781    }
8782
8783    /// Verifies that last ids and accounts are correctly referenced from parent
8784    #[test]
8785    fn test_bank_parent_account_spend() {
8786        let (genesis_config, mint_keypair) = create_genesis_config(2);
8787        let key1 = Keypair::new();
8788        let key2 = Keypair::new();
8789        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
8790
8791        let tx =
8792            system_transaction::transfer(&mint_keypair, &key1.pubkey(), 1, genesis_config.hash());
8793        assert_eq!(parent.process_transaction(&tx), Ok(()));
8794        let bank = new_from_parent(&parent);
8795        let tx = system_transaction::transfer(&key1, &key2.pubkey(), 1, genesis_config.hash());
8796        assert_eq!(bank.process_transaction(&tx), Ok(()));
8797        assert_eq!(parent.get_signature_status(&tx.signatures[0]), None);
8798    }
8799
8800    #[test]
8801    fn test_bank_hash_internal_state() {
8802        let (genesis_config, mint_keypair) = create_genesis_config(2_000);
8803        let bank0 = Bank::new_for_tests(&genesis_config);
8804        let bank1 = Bank::new_for_tests(&genesis_config);
8805        let initial_state = bank0.hash_internal_state();
8806        assert_eq!(bank1.hash_internal_state(), initial_state);
8807
8808        let pubkey = gemachain_sdk::pubkey::new_rand();
8809        bank0.transfer(1_000, &mint_keypair, &pubkey).unwrap();
8810        assert_ne!(bank0.hash_internal_state(), initial_state);
8811        bank1.transfer(1_000, &mint_keypair, &pubkey).unwrap();
8812        assert_eq!(bank0.hash_internal_state(), bank1.hash_internal_state());
8813
8814        // Checkpointing should always result in a new state
8815        let bank2 = new_from_parent(&Arc::new(bank1));
8816        assert_ne!(bank0.hash_internal_state(), bank2.hash_internal_state());
8817
8818        let pubkey2 = gemachain_sdk::pubkey::new_rand();
8819        info!("transfer 2 {}", pubkey2);
8820        bank2.transfer(10, &mint_keypair, &pubkey2).unwrap();
8821        bank2.update_accounts_hash();
8822        assert!(bank2.verify_bank_hash(true));
8823    }
8824
8825    #[test]
8826    fn test_bank_hash_internal_state_verify() {
8827        gemachain_logger::setup();
8828        let (genesis_config, mint_keypair) = create_genesis_config(2_000);
8829        let bank0 = Bank::new_for_tests(&genesis_config);
8830
8831        let pubkey = gemachain_sdk::pubkey::new_rand();
8832        info!("transfer 0 {} mint: {}", pubkey, mint_keypair.pubkey());
8833        bank0.transfer(1_000, &mint_keypair, &pubkey).unwrap();
8834
8835        let bank0_state = bank0.hash_internal_state();
8836        let bank0 = Arc::new(bank0);
8837        // Checkpointing should result in a new state while freezing the parent
8838        let bank2 = Bank::new_from_parent(&bank0, &gemachain_sdk::pubkey::new_rand(), 1);
8839        assert_ne!(bank0_state, bank2.hash_internal_state());
8840        // Checkpointing should modify the checkpoint's state when freezed
8841        assert_ne!(bank0_state, bank0.hash_internal_state());
8842
8843        // Checkpointing should never modify the checkpoint's state once frozen
8844        let bank0_state = bank0.hash_internal_state();
8845        bank2.update_accounts_hash();
8846        assert!(bank2.verify_bank_hash(true));
8847        let bank3 = Bank::new_from_parent(&bank0, &gemachain_sdk::pubkey::new_rand(), 2);
8848        assert_eq!(bank0_state, bank0.hash_internal_state());
8849        assert!(bank2.verify_bank_hash(true));
8850        bank3.update_accounts_hash();
8851        assert!(bank3.verify_bank_hash(true));
8852
8853        let pubkey2 = gemachain_sdk::pubkey::new_rand();
8854        info!("transfer 2 {}", pubkey2);
8855        bank2.transfer(10, &mint_keypair, &pubkey2).unwrap();
8856        bank2.update_accounts_hash();
8857        assert!(bank2.verify_bank_hash(true));
8858        assert!(bank3.verify_bank_hash(true));
8859    }
8860
8861    #[test]
8862    #[should_panic(expected = "assertion failed: self.is_frozen()")]
8863    fn test_verify_hash_unfrozen() {
8864        let (genesis_config, _mint_keypair) = create_genesis_config(2_000);
8865        let bank = Bank::new_for_tests(&genesis_config);
8866        assert!(bank.verify_hash());
8867    }
8868
8869    #[test]
8870    fn test_verify_snapshot_bank() {
8871        gemachain_logger::setup();
8872        let pubkey = gemachain_sdk::pubkey::new_rand();
8873        let (genesis_config, mint_keypair) = create_genesis_config(2_000);
8874        let bank = Bank::new_for_tests(&genesis_config);
8875        bank.transfer(1_000, &mint_keypair, &pubkey).unwrap();
8876        bank.freeze();
8877        bank.update_accounts_hash();
8878        assert!(bank.verify_snapshot_bank(true, false, None));
8879
8880        // tamper the bank after freeze!
8881        bank.increment_signature_count(1);
8882        assert!(!bank.verify_snapshot_bank(true, false, None));
8883    }
8884
8885    // Test that two bank forks with the same accounts should not hash to the same value.
8886    #[test]
8887    fn test_bank_hash_internal_state_same_account_different_fork() {
8888        gemachain_logger::setup();
8889        let (genesis_config, mint_keypair) = create_genesis_config(2_000);
8890        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
8891        let initial_state = bank0.hash_internal_state();
8892        let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
8893        assert_ne!(bank1.hash_internal_state(), initial_state);
8894
8895        info!("transfer bank1");
8896        let pubkey = gemachain_sdk::pubkey::new_rand();
8897        bank1.transfer(1_000, &mint_keypair, &pubkey).unwrap();
8898        assert_ne!(bank1.hash_internal_state(), initial_state);
8899
8900        info!("transfer bank2");
8901        // bank2 should not hash the same as bank1
8902        let bank2 = Bank::new_from_parent(&bank0, &Pubkey::default(), 2);
8903        bank2.transfer(1_000, &mint_keypair, &pubkey).unwrap();
8904        assert_ne!(bank2.hash_internal_state(), initial_state);
8905        assert_ne!(bank1.hash_internal_state(), bank2.hash_internal_state());
8906    }
8907
8908    #[test]
8909    fn test_hash_internal_state_genesis() {
8910        let bank0 = Bank::new_for_tests(&create_genesis_config(10).0);
8911        let bank1 = Bank::new_for_tests(&create_genesis_config(20).0);
8912        assert_ne!(bank0.hash_internal_state(), bank1.hash_internal_state());
8913    }
8914
8915    // See that the order of two transfers does not affect the result
8916    // of hash_internal_state
8917    #[test]
8918    fn test_hash_internal_state_order() {
8919        let (genesis_config, mint_keypair) = create_genesis_config(100);
8920        let bank0 = Bank::new_for_tests(&genesis_config);
8921        let bank1 = Bank::new_for_tests(&genesis_config);
8922        assert_eq!(bank0.hash_internal_state(), bank1.hash_internal_state());
8923        let key0 = gemachain_sdk::pubkey::new_rand();
8924        let key1 = gemachain_sdk::pubkey::new_rand();
8925        bank0.transfer(10, &mint_keypair, &key0).unwrap();
8926        bank0.transfer(20, &mint_keypair, &key1).unwrap();
8927
8928        bank1.transfer(20, &mint_keypair, &key1).unwrap();
8929        bank1.transfer(10, &mint_keypair, &key0).unwrap();
8930
8931        assert_eq!(bank0.hash_internal_state(), bank1.hash_internal_state());
8932    }
8933
8934    #[test]
8935    fn test_hash_internal_state_error() {
8936        gemachain_logger::setup();
8937        let (genesis_config, mint_keypair) = create_genesis_config(100);
8938        let bank = Bank::new_for_tests(&genesis_config);
8939        let key0 = gemachain_sdk::pubkey::new_rand();
8940        bank.transfer(10, &mint_keypair, &key0).unwrap();
8941        let orig = bank.hash_internal_state();
8942
8943        // Transfer will error but still take a fee
8944        assert!(bank.transfer(1000, &mint_keypair, &key0).is_err());
8945        assert_ne!(orig, bank.hash_internal_state());
8946
8947        let orig = bank.hash_internal_state();
8948        let empty_keypair = Keypair::new();
8949        assert!(bank.transfer(1000, &empty_keypair, &key0).is_err());
8950        assert_eq!(orig, bank.hash_internal_state());
8951    }
8952
8953    #[test]
8954    fn test_bank_hash_internal_state_squash() {
8955        let collector_id = Pubkey::default();
8956        let bank0 = Arc::new(Bank::new_for_tests(&create_genesis_config(10).0));
8957        let hash0 = bank0.hash_internal_state();
8958        // save hash0 because new_from_parent
8959        // updates sysvar entries
8960
8961        let bank1 = Bank::new_from_parent(&bank0, &collector_id, 1);
8962
8963        // no delta in bank1, hashes should always update
8964        assert_ne!(hash0, bank1.hash_internal_state());
8965
8966        // remove parent
8967        bank1.squash();
8968        assert!(bank1.parents().is_empty());
8969    }
8970
8971    /// Verifies that last ids and accounts are correctly referenced from parent
8972    #[test]
8973    fn test_bank_squash() {
8974        gemachain_logger::setup();
8975        let (genesis_config, mint_keypair) = create_genesis_config(2);
8976        let key1 = Keypair::new();
8977        let key2 = Keypair::new();
8978        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
8979
8980        let tx_transfer_mint_to_1 =
8981            system_transaction::transfer(&mint_keypair, &key1.pubkey(), 1, genesis_config.hash());
8982        trace!("parent process tx ");
8983        assert_eq!(parent.process_transaction(&tx_transfer_mint_to_1), Ok(()));
8984        trace!("done parent process tx ");
8985        assert_eq!(parent.transaction_count(), 1);
8986        assert_eq!(
8987            parent.get_signature_status(&tx_transfer_mint_to_1.signatures[0]),
8988            Some(Ok(()))
8989        );
8990
8991        trace!("new from parent");
8992        let bank = new_from_parent(&parent);
8993        trace!("done new from parent");
8994        assert_eq!(
8995            bank.get_signature_status(&tx_transfer_mint_to_1.signatures[0]),
8996            Some(Ok(()))
8997        );
8998
8999        assert_eq!(bank.transaction_count(), parent.transaction_count());
9000        let tx_transfer_1_to_2 =
9001            system_transaction::transfer(&key1, &key2.pubkey(), 1, genesis_config.hash());
9002        assert_eq!(bank.process_transaction(&tx_transfer_1_to_2), Ok(()));
9003        assert_eq!(bank.transaction_count(), 2);
9004        assert_eq!(parent.transaction_count(), 1);
9005        assert_eq!(
9006            parent.get_signature_status(&tx_transfer_1_to_2.signatures[0]),
9007            None
9008        );
9009
9010        for _ in 0..3 {
9011            // first time these should match what happened above, assert that parents are ok
9012            assert_eq!(bank.get_balance(&key1.pubkey()), 0);
9013            assert_eq!(bank.get_account(&key1.pubkey()), None);
9014            assert_eq!(bank.get_balance(&key2.pubkey()), 1);
9015            trace!("start");
9016            assert_eq!(
9017                bank.get_signature_status(&tx_transfer_mint_to_1.signatures[0]),
9018                Some(Ok(()))
9019            );
9020            assert_eq!(
9021                bank.get_signature_status(&tx_transfer_1_to_2.signatures[0]),
9022                Some(Ok(()))
9023            );
9024
9025            // works iteration 0, no-ops on iteration 1 and 2
9026            trace!("SQUASH");
9027            bank.squash();
9028
9029            assert_eq!(parent.transaction_count(), 1);
9030            assert_eq!(bank.transaction_count(), 2);
9031        }
9032    }
9033
9034    #[test]
9035    fn test_bank_get_account_in_parent_after_squash() {
9036        let (genesis_config, mint_keypair) = create_genesis_config(500);
9037        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
9038
9039        let key1 = Keypair::new();
9040
9041        parent.transfer(1, &mint_keypair, &key1.pubkey()).unwrap();
9042        assert_eq!(parent.get_balance(&key1.pubkey()), 1);
9043        let bank = new_from_parent(&parent);
9044        bank.squash();
9045        assert_eq!(parent.get_balance(&key1.pubkey()), 1);
9046    }
9047
9048    #[test]
9049    fn test_bank_get_account_in_parent_after_squash2() {
9050        gemachain_logger::setup();
9051        let (genesis_config, mint_keypair) = create_genesis_config(500);
9052        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
9053
9054        let key1 = Keypair::new();
9055
9056        bank0.transfer(1, &mint_keypair, &key1.pubkey()).unwrap();
9057        assert_eq!(bank0.get_balance(&key1.pubkey()), 1);
9058
9059        let bank1 = Arc::new(Bank::new_from_parent(&bank0, &Pubkey::default(), 1));
9060        bank1.transfer(3, &mint_keypair, &key1.pubkey()).unwrap();
9061        let bank2 = Arc::new(Bank::new_from_parent(&bank0, &Pubkey::default(), 2));
9062        bank2.transfer(2, &mint_keypair, &key1.pubkey()).unwrap();
9063        let bank3 = Arc::new(Bank::new_from_parent(&bank1, &Pubkey::default(), 3));
9064        bank1.squash();
9065
9066        // This picks up the values from 1 which is the highest root:
9067        // TODO: if we need to access rooted banks older than this,
9068        // need to fix the lookup.
9069        assert_eq!(bank0.get_balance(&key1.pubkey()), 4);
9070        assert_eq!(bank3.get_balance(&key1.pubkey()), 4);
9071        assert_eq!(bank2.get_balance(&key1.pubkey()), 3);
9072        bank3.squash();
9073        assert_eq!(bank1.get_balance(&key1.pubkey()), 4);
9074
9075        let bank4 = Arc::new(Bank::new_from_parent(&bank3, &Pubkey::default(), 4));
9076        bank4.transfer(4, &mint_keypair, &key1.pubkey()).unwrap();
9077        assert_eq!(bank4.get_balance(&key1.pubkey()), 8);
9078        assert_eq!(bank3.get_balance(&key1.pubkey()), 4);
9079        bank4.squash();
9080        let bank5 = Arc::new(Bank::new_from_parent(&bank4, &Pubkey::default(), 5));
9081        bank5.squash();
9082        let bank6 = Arc::new(Bank::new_from_parent(&bank5, &Pubkey::default(), 6));
9083        bank6.squash();
9084
9085        // This picks up the values from 4 which is the highest root:
9086        // TODO: if we need to access rooted banks older than this,
9087        // need to fix the lookup.
9088        assert_eq!(bank3.get_balance(&key1.pubkey()), 8);
9089        assert_eq!(bank2.get_balance(&key1.pubkey()), 8);
9090
9091        assert_eq!(bank4.get_balance(&key1.pubkey()), 8);
9092    }
9093
9094    #[test]
9095    fn test_bank_get_account_modified_since_parent_with_fixed_root() {
9096        let pubkey = gemachain_sdk::pubkey::new_rand();
9097
9098        let (genesis_config, mint_keypair) = create_genesis_config(500);
9099        let bank1 = Arc::new(Bank::new_for_tests(&genesis_config));
9100        bank1.transfer(1, &mint_keypair, &pubkey).unwrap();
9101        let result = bank1.get_account_modified_since_parent_with_fixed_root(&pubkey);
9102        assert!(result.is_some());
9103        let (account, slot) = result.unwrap();
9104        assert_eq!(account.carats(), 1);
9105        assert_eq!(slot, 0);
9106
9107        let bank2 = Arc::new(Bank::new_from_parent(&bank1, &Pubkey::default(), 1));
9108        assert!(bank2
9109            .get_account_modified_since_parent_with_fixed_root(&pubkey)
9110            .is_none());
9111        bank2.transfer(100, &mint_keypair, &pubkey).unwrap();
9112        let result = bank1.get_account_modified_since_parent_with_fixed_root(&pubkey);
9113        assert!(result.is_some());
9114        let (account, slot) = result.unwrap();
9115        assert_eq!(account.carats(), 1);
9116        assert_eq!(slot, 0);
9117        let result = bank2.get_account_modified_since_parent_with_fixed_root(&pubkey);
9118        assert!(result.is_some());
9119        let (account, slot) = result.unwrap();
9120        assert_eq!(account.carats(), 101);
9121        assert_eq!(slot, 1);
9122
9123        bank1.squash();
9124
9125        let bank3 = Bank::new_from_parent(&bank2, &Pubkey::default(), 3);
9126        assert_eq!(
9127            None,
9128            bank3.get_account_modified_since_parent_with_fixed_root(&pubkey)
9129        );
9130    }
9131
9132    #[test]
9133    fn test_bank_update_sysvar_account() {
9134        use sysvar::clock::Clock;
9135
9136        let dummy_clock_id = gemachain_sdk::pubkey::new_rand();
9137        let dummy_rent_epoch = 44;
9138        let (mut genesis_config, _mint_keypair) = create_genesis_config(500);
9139
9140        let expected_previous_slot = 3;
9141        let mut expected_next_slot = expected_previous_slot + 1;
9142
9143        // First, initialize the clock sysvar
9144        activate_all_features(&mut genesis_config);
9145        let bank1 = Arc::new(Bank::new_for_tests(&genesis_config));
9146        assert_eq!(bank1.calculate_capitalization(true), bank1.capitalization());
9147
9148        assert_capitalization_diff(
9149            &bank1,
9150            || {
9151                bank1.update_sysvar_account(&dummy_clock_id, |optional_account| {
9152                    assert!(optional_account.is_none());
9153
9154                    let mut account = create_account(
9155                        &Clock {
9156                            slot: expected_previous_slot,
9157                            ..Clock::default()
9158                        },
9159                        bank1.inherit_specially_retained_account_fields(optional_account),
9160                    );
9161                    account.set_rent_epoch(dummy_rent_epoch);
9162                    account
9163                });
9164                let current_account = bank1.get_account(&dummy_clock_id).unwrap();
9165                assert_eq!(
9166                    expected_previous_slot,
9167                    from_account::<Clock, _>(&current_account).unwrap().slot
9168                );
9169                assert_eq!(dummy_rent_epoch, current_account.rent_epoch());
9170            },
9171            |old, new| {
9172                assert_eq!(
9173                    old + min_rent_excempt_balance_for_sysvars(&bank1, &[sysvar::clock::id()]),
9174                    new
9175                );
9176            },
9177        );
9178
9179        assert_capitalization_diff(
9180            &bank1,
9181            || {
9182                bank1.update_sysvar_account(&dummy_clock_id, |optional_account| {
9183                    assert!(optional_account.is_some());
9184
9185                    create_account(
9186                        &Clock {
9187                            slot: expected_previous_slot,
9188                            ..Clock::default()
9189                        },
9190                        bank1.inherit_specially_retained_account_fields(optional_account),
9191                    )
9192                })
9193            },
9194            |old, new| {
9195                // creating new sysvar twice in a slot shouldn't increment capitalization twice
9196                assert_eq!(old, new);
9197            },
9198        );
9199
9200        // Updating should increment the clock's slot
9201        let bank2 = Arc::new(Bank::new_from_parent(&bank1, &Pubkey::default(), 1));
9202        assert_capitalization_diff(
9203            &bank2,
9204            || {
9205                bank2.update_sysvar_account(&dummy_clock_id, |optional_account| {
9206                    let slot = from_account::<Clock, _>(optional_account.as_ref().unwrap())
9207                        .unwrap()
9208                        .slot
9209                        + 1;
9210
9211                    create_account(
9212                        &Clock {
9213                            slot,
9214                            ..Clock::default()
9215                        },
9216                        bank2.inherit_specially_retained_account_fields(optional_account),
9217                    )
9218                });
9219                let current_account = bank2.get_account(&dummy_clock_id).unwrap();
9220                assert_eq!(
9221                    expected_next_slot,
9222                    from_account::<Clock, _>(&current_account).unwrap().slot
9223                );
9224                // inherit_specially_retained_account_fields() now starts to inherit rent_epoch too
9225                // with rent_for_sysvars
9226                assert_eq!(dummy_rent_epoch, current_account.rent_epoch());
9227            },
9228            |old, new| {
9229                // if existing, capitalization shouldn't change
9230                assert_eq!(old, new);
9231            },
9232        );
9233
9234        // Updating again should give bank2's sysvar to the closure not bank1's.
9235        // Thus, increment expected_next_slot accordingly
9236        expected_next_slot += 1;
9237        assert_capitalization_diff(
9238            &bank2,
9239            || {
9240                bank2.update_sysvar_account(&dummy_clock_id, |optional_account| {
9241                    let slot = from_account::<Clock, _>(optional_account.as_ref().unwrap())
9242                        .unwrap()
9243                        .slot
9244                        + 1;
9245
9246                    create_account(
9247                        &Clock {
9248                            slot,
9249                            ..Clock::default()
9250                        },
9251                        bank2.inherit_specially_retained_account_fields(optional_account),
9252                    )
9253                });
9254                let current_account = bank2.get_account(&dummy_clock_id).unwrap();
9255                assert_eq!(
9256                    expected_next_slot,
9257                    from_account::<Clock, _>(&current_account).unwrap().slot
9258                );
9259            },
9260            |old, new| {
9261                // updating twice in a slot shouldn't increment capitalization twice
9262                assert_eq!(old, new);
9263            },
9264        );
9265    }
9266
9267    #[test]
9268    fn test_bank_epoch_vote_accounts() {
9269        let leader_pubkey = gemachain_sdk::pubkey::new_rand();
9270        let leader_carats = 3;
9271        let mut genesis_config =
9272            create_genesis_config_with_leader(5, &leader_pubkey, leader_carats).genesis_config;
9273
9274        // set this up weird, forces future generation, odd mod(), etc.
9275        //  this says: "vote_accounts for epoch X should be generated at slot index 3 in epoch X-2...
9276        const SLOTS_PER_EPOCH: u64 = MINIMUM_SLOTS_PER_EPOCH as u64;
9277        const LEADER_SCHEDULE_SLOT_OFFSET: u64 = SLOTS_PER_EPOCH * 3 - 3;
9278        // no warmup allows me to do the normal division stuff below
9279        genesis_config.epoch_schedule =
9280            EpochSchedule::custom(SLOTS_PER_EPOCH, LEADER_SCHEDULE_SLOT_OFFSET, false);
9281
9282        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
9283        let mut leader_vote_stake: Vec<_> = parent
9284            .epoch_vote_accounts(0)
9285            .map(|accounts| {
9286                accounts
9287                    .iter()
9288                    .filter_map(|(pubkey, (stake, account))| {
9289                        if let Ok(vote_state) = account.vote_state().as_ref() {
9290                            if vote_state.node_pubkey == leader_pubkey {
9291                                Some((*pubkey, *stake))
9292                            } else {
9293                                None
9294                            }
9295                        } else {
9296                            None
9297                        }
9298                    })
9299                    .collect()
9300            })
9301            .unwrap();
9302        assert_eq!(leader_vote_stake.len(), 1);
9303        let (leader_vote_account, leader_stake) = leader_vote_stake.pop().unwrap();
9304        assert!(leader_stake > 0);
9305
9306        let leader_stake = Stake {
9307            delegation: Delegation {
9308                stake: leader_carats,
9309                activation_epoch: std::u64::MAX, // bootstrap
9310                ..Delegation::default()
9311            },
9312            ..Stake::default()
9313        };
9314
9315        let mut epoch = 1;
9316        loop {
9317            if epoch > LEADER_SCHEDULE_SLOT_OFFSET / SLOTS_PER_EPOCH {
9318                break;
9319            }
9320            let vote_accounts = parent.epoch_vote_accounts(epoch);
9321            assert!(vote_accounts.is_some());
9322
9323            // epoch_stakes are a snapshot at the leader_schedule_slot_offset boundary
9324            //   in the prior epoch (0 in this case)
9325            assert_eq!(
9326                leader_stake.stake(0, None),
9327                vote_accounts.unwrap().get(&leader_vote_account).unwrap().0
9328            );
9329
9330            epoch += 1;
9331        }
9332
9333        // child crosses epoch boundary and is the first slot in the epoch
9334        let child = Bank::new_from_parent(
9335            &parent,
9336            &leader_pubkey,
9337            SLOTS_PER_EPOCH - (LEADER_SCHEDULE_SLOT_OFFSET % SLOTS_PER_EPOCH),
9338        );
9339
9340        assert!(child.epoch_vote_accounts(epoch).is_some());
9341        assert_eq!(
9342            leader_stake.stake(child.epoch(), None),
9343            child
9344                .epoch_vote_accounts(epoch)
9345                .unwrap()
9346                .get(&leader_vote_account)
9347                .unwrap()
9348                .0
9349        );
9350
9351        // child crosses epoch boundary but isn't the first slot in the epoch, still
9352        //  makes an epoch stakes snapshot at 1
9353        let child = Bank::new_from_parent(
9354            &parent,
9355            &leader_pubkey,
9356            SLOTS_PER_EPOCH - (LEADER_SCHEDULE_SLOT_OFFSET % SLOTS_PER_EPOCH) + 1,
9357        );
9358        assert!(child.epoch_vote_accounts(epoch).is_some());
9359        assert_eq!(
9360            leader_stake.stake(child.epoch(), None),
9361            child
9362                .epoch_vote_accounts(epoch)
9363                .unwrap()
9364                .get(&leader_vote_account)
9365                .unwrap()
9366                .0
9367        );
9368    }
9369
9370    #[test]
9371    fn test_zero_signatures() {
9372        gemachain_logger::setup();
9373        let (genesis_config, mint_keypair) = create_genesis_config(500);
9374        let mut bank = Bank::new_for_tests(&genesis_config);
9375        bank.fee_calculator.carats_per_signature = 2;
9376        let key = Keypair::new();
9377
9378        let mut transfer_instruction =
9379            system_instruction::transfer(&mint_keypair.pubkey(), &key.pubkey(), 0);
9380        transfer_instruction.accounts[0].is_signer = false;
9381        let message = Message::new(&[transfer_instruction], None);
9382        let tx = Transaction::new(&[&Keypair::new(); 0], message, bank.last_blockhash());
9383
9384        assert_eq!(
9385            bank.process_transaction(&tx),
9386            Err(TransactionError::SanitizeFailure)
9387        );
9388        assert_eq!(bank.get_balance(&key.pubkey()), 0);
9389    }
9390
9391    #[test]
9392    fn test_bank_get_slots_in_epoch() {
9393        let (genesis_config, _) = create_genesis_config(500);
9394
9395        let bank = Bank::new_for_tests(&genesis_config);
9396
9397        assert_eq!(bank.get_slots_in_epoch(0), MINIMUM_SLOTS_PER_EPOCH as u64);
9398        assert_eq!(
9399            bank.get_slots_in_epoch(2),
9400            (MINIMUM_SLOTS_PER_EPOCH * 4) as u64
9401        );
9402        assert_eq!(
9403            bank.get_slots_in_epoch(5000),
9404            genesis_config.epoch_schedule.slots_per_epoch
9405        );
9406    }
9407
9408    #[test]
9409    fn test_is_delta_true() {
9410        let (genesis_config, mint_keypair) = create_genesis_config(500);
9411        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
9412        let key1 = Keypair::new();
9413        let tx_transfer_mint_to_1 =
9414            system_transaction::transfer(&mint_keypair, &key1.pubkey(), 1, genesis_config.hash());
9415        assert_eq!(bank.process_transaction(&tx_transfer_mint_to_1), Ok(()));
9416        assert!(bank.is_delta.load(Relaxed));
9417
9418        let bank1 = new_from_parent(&bank);
9419        let hash1 = bank1.hash_internal_state();
9420        assert!(!bank1.is_delta.load(Relaxed));
9421        assert_ne!(hash1, bank.hash());
9422        // ticks don't make a bank into a delta or change its state unless a block boundary is crossed
9423        bank1.register_tick(&Hash::default());
9424        assert!(!bank1.is_delta.load(Relaxed));
9425        assert_eq!(bank1.hash_internal_state(), hash1);
9426    }
9427
9428    #[test]
9429    fn test_is_empty() {
9430        let (genesis_config, mint_keypair) = create_genesis_config(500);
9431        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
9432        let key1 = Keypair::new();
9433
9434        // The zeroth bank is empty becasue there are no transactions
9435        assert!(bank0.is_empty());
9436
9437        // Set is_delta to true, bank is no longer empty
9438        let tx_transfer_mint_to_1 =
9439            system_transaction::transfer(&mint_keypair, &key1.pubkey(), 1, genesis_config.hash());
9440        assert_eq!(bank0.process_transaction(&tx_transfer_mint_to_1), Ok(()));
9441        assert!(!bank0.is_empty());
9442    }
9443
9444    #[test]
9445    fn test_bank_inherit_tx_count() {
9446        let (genesis_config, mint_keypair) = create_genesis_config(500);
9447        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
9448
9449        // Bank 1
9450        let bank1 = Arc::new(Bank::new_from_parent(
9451            &bank0,
9452            &gemachain_sdk::pubkey::new_rand(),
9453            1,
9454        ));
9455        // Bank 2
9456        let bank2 = Bank::new_from_parent(&bank0, &gemachain_sdk::pubkey::new_rand(), 2);
9457
9458        // transfer a token
9459        assert_eq!(
9460            bank1.process_transaction(&system_transaction::transfer(
9461                &mint_keypair,
9462                &Keypair::new().pubkey(),
9463                1,
9464                genesis_config.hash(),
9465            )),
9466            Ok(())
9467        );
9468
9469        assert_eq!(bank0.transaction_count(), 0);
9470        assert_eq!(bank2.transaction_count(), 0);
9471        assert_eq!(bank1.transaction_count(), 1);
9472
9473        bank1.squash();
9474
9475        assert_eq!(bank0.transaction_count(), 0);
9476        assert_eq!(bank2.transaction_count(), 0);
9477        assert_eq!(bank1.transaction_count(), 1);
9478
9479        let bank6 = Bank::new_from_parent(&bank1, &gemachain_sdk::pubkey::new_rand(), 3);
9480        assert_eq!(bank1.transaction_count(), 1);
9481        assert_eq!(bank6.transaction_count(), 1);
9482
9483        bank6.squash();
9484        assert_eq!(bank6.transaction_count(), 1);
9485    }
9486
9487    #[test]
9488    fn test_bank_inherit_fee_rate_governor() {
9489        let (mut genesis_config, _mint_keypair) = create_genesis_config(500);
9490        genesis_config
9491            .fee_rate_governor
9492            .target_carats_per_signature = 123;
9493
9494        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
9495        let bank1 = Arc::new(new_from_parent(&bank0));
9496        assert_eq!(
9497            bank0.fee_rate_governor.target_carats_per_signature / 2,
9498            bank1
9499                .fee_rate_governor
9500                .create_fee_calculator()
9501                .carats_per_signature
9502        );
9503    }
9504
9505    #[test]
9506    fn test_bank_vote_accounts() {
9507        let GenesisConfigInfo {
9508            genesis_config,
9509            mint_keypair,
9510            ..
9511        } = create_genesis_config_with_leader(500, &gemachain_sdk::pubkey::new_rand(), 1);
9512        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
9513
9514        let vote_accounts = bank.vote_accounts();
9515        assert_eq!(vote_accounts.len(), 1); // bootstrap validator has
9516                                            // to have a vote account
9517
9518        let vote_keypair = Keypair::new();
9519        let instructions = vote_instruction::create_account(
9520            &mint_keypair.pubkey(),
9521            &vote_keypair.pubkey(),
9522            &VoteInit {
9523                node_pubkey: mint_keypair.pubkey(),
9524                authorized_voter: vote_keypair.pubkey(),
9525                authorized_withdrawer: vote_keypair.pubkey(),
9526                commission: 0,
9527            },
9528            10,
9529        );
9530
9531        let message = Message::new(&instructions, Some(&mint_keypair.pubkey()));
9532        let transaction = Transaction::new(
9533            &[&mint_keypair, &vote_keypair],
9534            message,
9535            bank.last_blockhash(),
9536        );
9537
9538        bank.process_transaction(&transaction).unwrap();
9539
9540        let vote_accounts = bank.vote_accounts();
9541
9542        assert_eq!(vote_accounts.len(), 2);
9543
9544        assert!(vote_accounts.get(&vote_keypair.pubkey()).is_some());
9545
9546        assert!(bank.withdraw(&vote_keypair.pubkey(), 10).is_ok());
9547
9548        let vote_accounts = bank.vote_accounts();
9549
9550        assert_eq!(vote_accounts.len(), 1);
9551    }
9552
9553    #[test]
9554    fn test_bank_cloned_stake_delegations() {
9555        let GenesisConfigInfo {
9556            genesis_config,
9557            mint_keypair,
9558            ..
9559        } = create_genesis_config_with_leader(500, &gemachain_sdk::pubkey::new_rand(), 1);
9560        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
9561
9562        let stake_delegations = bank.cloned_stake_delegations();
9563        assert_eq!(stake_delegations.len(), 1); // bootstrap validator has
9564                                                // to have a stake delegation
9565
9566        let vote_keypair = Keypair::new();
9567        let mut instructions = vote_instruction::create_account(
9568            &mint_keypair.pubkey(),
9569            &vote_keypair.pubkey(),
9570            &VoteInit {
9571                node_pubkey: mint_keypair.pubkey(),
9572                authorized_voter: vote_keypair.pubkey(),
9573                authorized_withdrawer: vote_keypair.pubkey(),
9574                commission: 0,
9575            },
9576            10,
9577        );
9578
9579        let stake_keypair = Keypair::new();
9580        instructions.extend(stake_instruction::create_account_and_delegate_stake(
9581            &mint_keypair.pubkey(),
9582            &stake_keypair.pubkey(),
9583            &vote_keypair.pubkey(),
9584            &Authorized::auto(&stake_keypair.pubkey()),
9585            &Lockup::default(),
9586            10,
9587        ));
9588
9589        let message = Message::new(&instructions, Some(&mint_keypair.pubkey()));
9590        let transaction = Transaction::new(
9591            &[&mint_keypair, &vote_keypair, &stake_keypair],
9592            message,
9593            bank.last_blockhash(),
9594        );
9595
9596        bank.process_transaction(&transaction).unwrap();
9597
9598        let stake_delegations = bank.cloned_stake_delegations();
9599        assert_eq!(stake_delegations.len(), 2);
9600        assert!(stake_delegations.get(&stake_keypair.pubkey()).is_some());
9601    }
9602
9603    #[allow(deprecated)]
9604    #[test]
9605    fn test_bank_fees_account() {
9606        let (mut genesis_config, _) = create_genesis_config(500);
9607        genesis_config.fee_rate_governor = FeeRateGovernor::new(12345, 0);
9608        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
9609
9610        let fees_account = bank.get_account(&sysvar::fees::id()).unwrap();
9611        let fees = from_account::<Fees, _>(&fees_account).unwrap();
9612        assert_eq!(
9613            bank.fee_calculator.carats_per_signature,
9614            fees.fee_calculator.carats_per_signature
9615        );
9616        assert_eq!(fees.fee_calculator.carats_per_signature, 12345);
9617    }
9618
9619    #[test]
9620    fn test_is_delta_with_no_committables() {
9621        let (genesis_config, mint_keypair) = create_genesis_config(8000);
9622        let bank = Bank::new_for_tests(&genesis_config);
9623        bank.is_delta.store(false, Relaxed);
9624
9625        let keypair1 = Keypair::new();
9626        let keypair2 = Keypair::new();
9627        let fail_tx =
9628            system_transaction::transfer(&keypair1, &keypair2.pubkey(), 1, bank.last_blockhash());
9629
9630        // Should fail with TransactionError::AccountNotFound, which means
9631        // the account which this tx operated on will not be committed. Thus
9632        // the bank is_delta should still be false
9633        assert_eq!(
9634            bank.process_transaction(&fail_tx),
9635            Err(TransactionError::AccountNotFound)
9636        );
9637
9638        // Check the bank is_delta is still false
9639        assert!(!bank.is_delta.load(Relaxed));
9640
9641        // Should fail with InstructionError, but InstructionErrors are committable,
9642        // so is_delta should be true
9643        assert_eq!(
9644            bank.transfer(10_001, &mint_keypair, &gemachain_sdk::pubkey::new_rand()),
9645            Err(TransactionError::InstructionError(
9646                0,
9647                SystemError::ResultWithNegativeCarats.into(),
9648            ))
9649        );
9650
9651        assert!(bank.is_delta.load(Relaxed));
9652    }
9653
9654    #[test]
9655    fn test_bank_get_program_accounts() {
9656        let (genesis_config, mint_keypair) = create_genesis_config(500);
9657        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
9658        parent.restore_old_behavior_for_fragile_tests();
9659
9660        let genesis_accounts: Vec<_> = parent.get_all_accounts_with_modified_slots().unwrap();
9661        assert!(
9662            genesis_accounts
9663                .iter()
9664                .any(|(pubkey, _, _)| *pubkey == mint_keypair.pubkey()),
9665            "mint pubkey not found"
9666        );
9667        assert!(
9668            genesis_accounts
9669                .iter()
9670                .any(|(pubkey, _, _)| gemachain_sdk::sysvar::is_sysvar_id(pubkey)),
9671            "no sysvars found"
9672        );
9673
9674        let bank0 = Arc::new(new_from_parent(&parent));
9675        let pubkey0 = gemachain_sdk::pubkey::new_rand();
9676        let program_id = Pubkey::new(&[2; 32]);
9677        let account0 = AccountSharedData::new(1, 0, &program_id);
9678        bank0.store_account(&pubkey0, &account0);
9679
9680        assert_eq!(
9681            bank0.get_program_accounts_modified_since_parent(&program_id),
9682            vec![(pubkey0, account0.clone())]
9683        );
9684
9685        let bank1 = Arc::new(new_from_parent(&bank0));
9686        bank1.squash();
9687        assert_eq!(
9688            bank0.get_program_accounts(&program_id).unwrap(),
9689            vec![(pubkey0, account0.clone())]
9690        );
9691        assert_eq!(
9692            bank1.get_program_accounts(&program_id).unwrap(),
9693            vec![(pubkey0, account0)]
9694        );
9695        assert_eq!(
9696            bank1.get_program_accounts_modified_since_parent(&program_id),
9697            vec![]
9698        );
9699
9700        let bank2 = Arc::new(new_from_parent(&bank1));
9701        let pubkey1 = gemachain_sdk::pubkey::new_rand();
9702        let account1 = AccountSharedData::new(3, 0, &program_id);
9703        bank2.store_account(&pubkey1, &account1);
9704        // Accounts with 0 carats should be filtered out by Accounts::load_by_program()
9705        let pubkey2 = gemachain_sdk::pubkey::new_rand();
9706        let account2 = AccountSharedData::new(0, 0, &program_id);
9707        bank2.store_account(&pubkey2, &account2);
9708
9709        let bank3 = Arc::new(new_from_parent(&bank2));
9710        bank3.squash();
9711        assert_eq!(bank1.get_program_accounts(&program_id).unwrap().len(), 2);
9712        assert_eq!(bank3.get_program_accounts(&program_id).unwrap().len(), 2);
9713    }
9714
9715    #[test]
9716    fn test_get_filtered_indexed_accounts() {
9717        let (genesis_config, _mint_keypair) = create_genesis_config(500);
9718        let mut account_indexes = AccountSecondaryIndexes::default();
9719        account_indexes.indexes.insert(AccountIndex::ProgramId);
9720        let bank = Arc::new(Bank::new_with_config(
9721            &genesis_config,
9722            account_indexes,
9723            false,
9724            AccountShrinkThreshold::default(),
9725        ));
9726
9727        let address = Pubkey::new_unique();
9728        let program_id = Pubkey::new_unique();
9729        let account = AccountSharedData::new(1, 0, &program_id);
9730        bank.store_account(&address, &account);
9731
9732        let indexed_accounts = bank
9733            .get_filtered_indexed_accounts(&IndexKey::ProgramId(program_id), |_| true)
9734            .unwrap();
9735        assert_eq!(indexed_accounts.len(), 1);
9736        assert_eq!(indexed_accounts[0], (address, account));
9737
9738        // Even though the account is re-stored in the bank (and the index) under a new program id,
9739        // it is still present in the index under the original program id as well. This
9740        // demonstrates the need for a redundant post-processing filter.
9741        let another_program_id = Pubkey::new_unique();
9742        let new_account = AccountSharedData::new(1, 0, &another_program_id);
9743        let bank = Arc::new(new_from_parent(&bank));
9744        bank.store_account(&address, &new_account);
9745        let indexed_accounts = bank
9746            .get_filtered_indexed_accounts(&IndexKey::ProgramId(program_id), |_| true)
9747            .unwrap();
9748        assert_eq!(indexed_accounts.len(), 1);
9749        assert_eq!(indexed_accounts[0], (address, new_account.clone()));
9750        let indexed_accounts = bank
9751            .get_filtered_indexed_accounts(&IndexKey::ProgramId(another_program_id), |_| true)
9752            .unwrap();
9753        assert_eq!(indexed_accounts.len(), 1);
9754        assert_eq!(indexed_accounts[0], (address, new_account.clone()));
9755
9756        // Post-processing filter
9757        let indexed_accounts = bank
9758            .get_filtered_indexed_accounts(&IndexKey::ProgramId(program_id), |account| {
9759                account.owner() == &program_id
9760            })
9761            .unwrap();
9762        assert!(indexed_accounts.is_empty());
9763        let indexed_accounts = bank
9764            .get_filtered_indexed_accounts(&IndexKey::ProgramId(another_program_id), |account| {
9765                account.owner() == &another_program_id
9766            })
9767            .unwrap();
9768        assert_eq!(indexed_accounts.len(), 1);
9769        assert_eq!(indexed_accounts[0], (address, new_account));
9770    }
9771
9772    #[test]
9773    fn test_status_cache_ancestors() {
9774        gemachain_logger::setup();
9775        let (genesis_config, _mint_keypair) = create_genesis_config(500);
9776        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
9777        let bank1 = Arc::new(new_from_parent(&parent));
9778        let mut bank = bank1;
9779        for _ in 0..MAX_CACHE_ENTRIES * 2 {
9780            bank = Arc::new(new_from_parent(&bank));
9781            bank.squash();
9782        }
9783
9784        let bank = new_from_parent(&bank);
9785        assert_eq!(
9786            bank.status_cache_ancestors(),
9787            (bank.slot() - MAX_CACHE_ENTRIES as u64..=bank.slot()).collect::<Vec<_>>()
9788        );
9789    }
9790
9791    #[test]
9792    fn test_add_builtin() {
9793        let (genesis_config, mint_keypair) = create_genesis_config(500);
9794        let mut bank = Bank::new_for_tests(&genesis_config);
9795
9796        fn mock_vote_program_id() -> Pubkey {
9797            Pubkey::new(&[42u8; 32])
9798        }
9799        fn mock_vote_processor(
9800            program_id: &Pubkey,
9801            _instruction_data: &[u8],
9802            _invoke_context: &mut dyn InvokeContext,
9803        ) -> std::result::Result<(), InstructionError> {
9804            if mock_vote_program_id() != *program_id {
9805                return Err(InstructionError::IncorrectProgramId);
9806            }
9807            Err(InstructionError::Custom(42))
9808        }
9809
9810        assert!(bank.get_account(&mock_vote_program_id()).is_none());
9811        bank.add_builtin(
9812            "mock_vote_program",
9813            mock_vote_program_id(),
9814            mock_vote_processor,
9815        );
9816        assert!(bank.get_account(&mock_vote_program_id()).is_some());
9817
9818        let mock_account = Keypair::new();
9819        let mock_validator_identity = Keypair::new();
9820        let mut instructions = vote_instruction::create_account(
9821            &mint_keypair.pubkey(),
9822            &mock_account.pubkey(),
9823            &VoteInit {
9824                node_pubkey: mock_validator_identity.pubkey(),
9825                ..VoteInit::default()
9826            },
9827            1,
9828        );
9829        instructions[1].program_id = mock_vote_program_id();
9830
9831        let message = Message::new(&instructions, Some(&mint_keypair.pubkey()));
9832        let transaction = Transaction::new(
9833            &[&mint_keypair, &mock_account, &mock_validator_identity],
9834            message,
9835            bank.last_blockhash(),
9836        );
9837
9838        assert_eq!(
9839            bank.process_transaction(&transaction),
9840            Err(TransactionError::InstructionError(
9841                1,
9842                InstructionError::Custom(42)
9843            ))
9844        );
9845    }
9846
9847    #[test]
9848    fn test_add_duplicate_static_program() {
9849        let GenesisConfigInfo {
9850            genesis_config,
9851            mint_keypair,
9852            ..
9853        } = create_genesis_config_with_leader(500, &gemachain_sdk::pubkey::new_rand(), 0);
9854        let mut bank = Bank::new_for_tests(&genesis_config);
9855
9856        fn mock_vote_processor(
9857            _pubkey: &Pubkey,
9858            _data: &[u8],
9859            _invoke_context: &mut dyn InvokeContext,
9860        ) -> std::result::Result<(), InstructionError> {
9861            Err(InstructionError::Custom(42))
9862        }
9863
9864        let mock_account = Keypair::new();
9865        let mock_validator_identity = Keypair::new();
9866        let instructions = vote_instruction::create_account(
9867            &mint_keypair.pubkey(),
9868            &mock_account.pubkey(),
9869            &VoteInit {
9870                node_pubkey: mock_validator_identity.pubkey(),
9871                ..VoteInit::default()
9872            },
9873            1,
9874        );
9875
9876        let message = Message::new(&instructions, Some(&mint_keypair.pubkey()));
9877        let transaction = Transaction::new(
9878            &[&mint_keypair, &mock_account, &mock_validator_identity],
9879            message,
9880            bank.last_blockhash(),
9881        );
9882
9883        let vote_loader_account = bank.get_account(&gemachain_vote_program::id()).unwrap();
9884        bank.add_builtin(
9885            "gemachain_vote_program",
9886            gemachain_vote_program::id(),
9887            mock_vote_processor,
9888        );
9889        let new_vote_loader_account = bank.get_account(&gemachain_vote_program::id()).unwrap();
9890        // Vote loader account should not be updated since it was included in the genesis config.
9891        assert_eq!(vote_loader_account.data(), new_vote_loader_account.data());
9892        assert_eq!(
9893            bank.process_transaction(&transaction),
9894            Err(TransactionError::InstructionError(
9895                1,
9896                InstructionError::Custom(42)
9897            ))
9898        );
9899    }
9900
9901    #[test]
9902    fn test_add_instruction_processor_for_existing_unrelated_accounts() {
9903        let (genesis_config, _mint_keypair) = create_genesis_config(500);
9904        let mut bank = Bank::new_for_tests(&genesis_config);
9905
9906        fn mock_ix_processor(
9907            _pubkey: &Pubkey,
9908            _data: &[u8],
9909            _invoke_context: &mut dyn InvokeContext,
9910        ) -> std::result::Result<(), InstructionError> {
9911            Err(InstructionError::Custom(42))
9912        }
9913
9914        // Non-native loader accounts can not be used for instruction processing
9915        {
9916            let stakes = bank.stakes.read().unwrap();
9917            assert!(stakes.vote_accounts().as_ref().is_empty());
9918        }
9919        assert!(bank.stakes.read().unwrap().stake_delegations().is_empty());
9920        assert_eq!(bank.calculate_capitalization(true), bank.capitalization());
9921
9922        let ((vote_id, vote_account), (stake_id, stake_account)) =
9923            crate::stakes::tests::create_staked_node_accounts(1_0000);
9924        bank.capitalization
9925            .fetch_add(vote_account.carats() + stake_account.carats(), Relaxed);
9926        bank.store_account(&vote_id, &vote_account);
9927        bank.store_account(&stake_id, &stake_account);
9928        {
9929            let stakes = bank.stakes.read().unwrap();
9930            assert!(!stakes.vote_accounts().as_ref().is_empty());
9931        }
9932        assert!(!bank.stakes.read().unwrap().stake_delegations().is_empty());
9933        assert_eq!(bank.calculate_capitalization(true), bank.capitalization());
9934
9935        bank.add_builtin("mock_program1", vote_id, mock_ix_processor);
9936        bank.add_builtin("mock_program2", stake_id, mock_ix_processor);
9937        {
9938            let stakes = bank.stakes.read().unwrap();
9939            assert!(stakes.vote_accounts().as_ref().is_empty());
9940        }
9941        assert!(bank.stakes.read().unwrap().stake_delegations().is_empty());
9942        assert_eq!(bank.calculate_capitalization(true), bank.capitalization());
9943        assert_eq!(
9944            "mock_program1",
9945            String::from_utf8_lossy(bank.get_account(&vote_id).unwrap_or_default().data())
9946        );
9947        assert_eq!(
9948            "mock_program2",
9949            String::from_utf8_lossy(bank.get_account(&stake_id).unwrap_or_default().data())
9950        );
9951
9952        // Re-adding builtin programs should be no-op
9953        bank.update_accounts_hash();
9954        let old_hash = bank.get_accounts_hash();
9955        bank.add_builtin("mock_program1", vote_id, mock_ix_processor);
9956        bank.add_builtin("mock_program2", stake_id, mock_ix_processor);
9957        bank.update_accounts_hash();
9958        let new_hash = bank.get_accounts_hash();
9959        assert_eq!(old_hash, new_hash);
9960        {
9961            let stakes = bank.stakes.read().unwrap();
9962            assert!(stakes.vote_accounts().as_ref().is_empty());
9963        }
9964        assert!(bank.stakes.read().unwrap().stake_delegations().is_empty());
9965        assert_eq!(bank.calculate_capitalization(true), bank.capitalization());
9966        assert_eq!(
9967            "mock_program1",
9968            String::from_utf8_lossy(bank.get_account(&vote_id).unwrap_or_default().data())
9969        );
9970        assert_eq!(
9971            "mock_program2",
9972            String::from_utf8_lossy(bank.get_account(&stake_id).unwrap_or_default().data())
9973        );
9974    }
9975
9976    #[allow(deprecated)]
9977    #[test]
9978    fn test_recent_blockhashes_sysvar() {
9979        let (genesis_config, _mint_keypair) = create_genesis_config(500);
9980        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
9981        for i in 1..5 {
9982            let bhq_account = bank.get_account(&sysvar::recent_blockhashes::id()).unwrap();
9983            let recent_blockhashes =
9984                from_account::<sysvar::recent_blockhashes::RecentBlockhashes, _>(&bhq_account)
9985                    .unwrap();
9986            // Check length
9987            assert_eq!(recent_blockhashes.len(), i);
9988            let most_recent_hash = recent_blockhashes.iter().next().unwrap().blockhash;
9989            // Check order
9990            assert_eq!(Some(true), bank.check_hash_age(&most_recent_hash, 0));
9991            goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
9992            bank = Arc::new(new_from_parent(&bank));
9993        }
9994    }
9995
9996    #[allow(deprecated)]
9997    #[test]
9998    fn test_blockhash_queue_sysvar_consistency() {
9999        let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
10000        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
10001        goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
10002
10003        let bhq_account = bank.get_account(&sysvar::recent_blockhashes::id()).unwrap();
10004        let recent_blockhashes =
10005            from_account::<sysvar::recent_blockhashes::RecentBlockhashes, _>(&bhq_account).unwrap();
10006
10007        let sysvar_recent_blockhash = recent_blockhashes[0].blockhash;
10008        let bank_last_blockhash = bank.last_blockhash();
10009        assert_eq!(sysvar_recent_blockhash, bank_last_blockhash);
10010    }
10011
10012    #[test]
10013    fn test_bank_inherit_last_vote_sync() {
10014        let (genesis_config, _) = create_genesis_config(500);
10015        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
10016        let last_ts = bank0.last_vote_sync.load(Relaxed);
10017        assert_eq!(last_ts, 0);
10018        bank0.last_vote_sync.store(1, Relaxed);
10019        let bank1 =
10020            Bank::new_from_parent(&bank0, &Pubkey::default(), bank0.get_slots_in_epoch(0) - 1);
10021        let last_ts = bank1.last_vote_sync.load(Relaxed);
10022        assert_eq!(last_ts, 1);
10023    }
10024
10025    #[test]
10026    fn test_hash_internal_state_unchanged() {
10027        let (genesis_config, _) = create_genesis_config(500);
10028        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
10029        bank0.freeze();
10030        let bank0_hash = bank0.hash();
10031        let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
10032        bank1.freeze();
10033        let bank1_hash = bank1.hash();
10034        // Checkpointing should always result in a new state
10035        assert_ne!(bank0_hash, bank1_hash);
10036    }
10037
10038    #[test]
10039    fn test_ticks_change_state() {
10040        let (genesis_config, _) = create_genesis_config(500);
10041        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
10042        let bank1 = new_from_parent(&bank);
10043        let hash1 = bank1.hash_internal_state();
10044        // ticks don't change its state unless a block boundary is crossed
10045        for _ in 0..genesis_config.ticks_per_slot {
10046            assert_eq!(bank1.hash_internal_state(), hash1);
10047            bank1.register_tick(&Hash::default());
10048        }
10049        assert_ne!(bank1.hash_internal_state(), hash1);
10050    }
10051
10052    #[ignore]
10053    #[test]
10054    fn test_banks_leak() {
10055        fn add_lotsa_stake_accounts(genesis_config: &mut GenesisConfig) {
10056            const LOTSA: usize = 4_096;
10057
10058            (0..LOTSA).for_each(|_| {
10059                let pubkey = gemachain_sdk::pubkey::new_rand();
10060                genesis_config.add_account(
10061                    pubkey,
10062                    stake_state::create_lockup_stake_account(
10063                        &Authorized::auto(&pubkey),
10064                        &Lockup::default(),
10065                        &Rent::default(),
10066                        50_000_000,
10067                    ),
10068                );
10069            });
10070        }
10071        gemachain_logger::setup();
10072        let (mut genesis_config, _) = create_genesis_config(100_000_000_000_000);
10073        add_lotsa_stake_accounts(&mut genesis_config);
10074        let mut bank = std::sync::Arc::new(Bank::new_for_tests(&genesis_config));
10075        let mut num_banks = 0;
10076        let pid = std::process::id();
10077        #[cfg(not(target_os = "linux"))]
10078        error!(
10079            "\nYou can run this to watch RAM:\n   while read -p 'banks: '; do echo $(( $(ps -o vsize= -p {})/$REPLY));done", pid
10080        );
10081        loop {
10082            num_banks += 1;
10083            bank = std::sync::Arc::new(new_from_parent(&bank));
10084            if num_banks % 100 == 0 {
10085                #[cfg(target_os = "linux")]
10086                {
10087                    let pages_consumed = std::fs::read_to_string(format!("/proc/{}/statm", pid))
10088                        .unwrap()
10089                        .split_whitespace()
10090                        .next()
10091                        .unwrap()
10092                        .parse::<usize>()
10093                        .unwrap();
10094                    error!(
10095                        "at {} banks: {} mem or {}kB/bank",
10096                        num_banks,
10097                        pages_consumed * 4096,
10098                        (pages_consumed * 4) / num_banks
10099                    );
10100                }
10101                #[cfg(not(target_os = "linux"))]
10102                {
10103                    error!("{} banks, sleeping for 5 sec", num_banks);
10104                    std::thread::sleep(Duration::new(5, 0));
10105                }
10106            }
10107        }
10108    }
10109
10110    fn get_nonce_account(bank: &Bank, nonce_pubkey: &Pubkey) -> Option<Hash> {
10111        bank.get_account(nonce_pubkey).and_then(|acc| {
10112            let state =
10113                StateMut::<nonce::state::Versions>::state(&acc).map(|v| v.convert_to_current());
10114            match state {
10115                Ok(nonce::State::Initialized(ref data)) => Some(data.blockhash),
10116                _ => None,
10117            }
10118        })
10119    }
10120
10121    fn nonce_setup(
10122        bank: &mut Arc<Bank>,
10123        mint_keypair: &Keypair,
10124        custodian_carats: u64,
10125        nonce_carats: u64,
10126        nonce_authority: Option<Pubkey>,
10127    ) -> Result<(Keypair, Keypair)> {
10128        let custodian_keypair = Keypair::new();
10129        let nonce_keypair = Keypair::new();
10130        /* Setup accounts */
10131        let mut setup_ixs = vec![system_instruction::transfer(
10132            &mint_keypair.pubkey(),
10133            &custodian_keypair.pubkey(),
10134            custodian_carats,
10135        )];
10136        let nonce_authority = nonce_authority.unwrap_or_else(|| nonce_keypair.pubkey());
10137        setup_ixs.extend_from_slice(&system_instruction::create_nonce_account(
10138            &custodian_keypair.pubkey(),
10139            &nonce_keypair.pubkey(),
10140            &nonce_authority,
10141            nonce_carats,
10142        ));
10143        let message = Message::new(&setup_ixs, Some(&mint_keypair.pubkey()));
10144        let setup_tx = Transaction::new(
10145            &[mint_keypair, &custodian_keypair, &nonce_keypair],
10146            message,
10147            bank.last_blockhash(),
10148        );
10149        bank.process_transaction(&setup_tx)?;
10150        Ok((custodian_keypair, nonce_keypair))
10151    }
10152
10153    fn setup_nonce_with_bank<F>(
10154        supply_carats: u64,
10155        mut genesis_cfg_fn: F,
10156        custodian_carats: u64,
10157        nonce_carats: u64,
10158        nonce_authority: Option<Pubkey>,
10159    ) -> Result<(Arc<Bank>, Keypair, Keypair, Keypair)>
10160    where
10161        F: FnMut(&mut GenesisConfig),
10162    {
10163        let (mut genesis_config, mint_keypair) = create_genesis_config(supply_carats);
10164        genesis_config.rent.carats_per_byte_year = 0;
10165        genesis_cfg_fn(&mut genesis_config);
10166        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
10167
10168        // Banks 0 and 1 have no fees, wait two blocks before
10169        // initializing our nonce accounts
10170        for _ in 0..2 {
10171            goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
10172            bank = Arc::new(new_from_parent(&bank));
10173        }
10174
10175        let (custodian_keypair, nonce_keypair) = nonce_setup(
10176            &mut bank,
10177            &mint_keypair,
10178            custodian_carats,
10179            nonce_carats,
10180            nonce_authority,
10181        )?;
10182        Ok((bank, mint_keypair, custodian_keypair, nonce_keypair))
10183    }
10184
10185    #[test]
10186    fn test_check_tx_durable_nonce_ok() {
10187        let (bank, _mint_keypair, custodian_keypair, nonce_keypair) =
10188            setup_nonce_with_bank(10_000_000, |_| {}, 5_000_000, 250_000, None).unwrap();
10189        let custodian_pubkey = custodian_keypair.pubkey();
10190        let nonce_pubkey = nonce_keypair.pubkey();
10191
10192        let nonce_hash = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10193        let tx = Transaction::new_signed_with_payer(
10194            &[
10195                system_instruction::advance_nonce_account(&nonce_pubkey, &nonce_pubkey),
10196                system_instruction::transfer(&custodian_pubkey, &nonce_pubkey, 100_000),
10197            ],
10198            Some(&custodian_pubkey),
10199            &[&custodian_keypair, &nonce_keypair],
10200            nonce_hash,
10201        );
10202        let nonce_account = bank.get_account(&nonce_pubkey).unwrap();
10203        assert_eq!(
10204            bank.check_tx_durable_nonce(&tx.try_into().unwrap()),
10205            Some((nonce_pubkey, nonce_account))
10206        );
10207    }
10208
10209    #[test]
10210    fn test_check_tx_durable_nonce_not_durable_nonce_fail() {
10211        let (bank, _mint_keypair, custodian_keypair, nonce_keypair) =
10212            setup_nonce_with_bank(10_000_000, |_| {}, 5_000_000, 250_000, None).unwrap();
10213        let custodian_pubkey = custodian_keypair.pubkey();
10214        let nonce_pubkey = nonce_keypair.pubkey();
10215
10216        let nonce_hash = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10217        let tx = Transaction::new_signed_with_payer(
10218            &[
10219                system_instruction::transfer(&custodian_pubkey, &nonce_pubkey, 100_000),
10220                system_instruction::advance_nonce_account(&nonce_pubkey, &nonce_pubkey),
10221            ],
10222            Some(&custodian_pubkey),
10223            &[&custodian_keypair, &nonce_keypair],
10224            nonce_hash,
10225        );
10226        assert!(bank
10227            .check_tx_durable_nonce(&tx.try_into().unwrap())
10228            .is_none());
10229    }
10230
10231    #[test]
10232    fn test_check_tx_durable_nonce_missing_ix_pubkey_fail() {
10233        let (bank, _mint_keypair, custodian_keypair, nonce_keypair) =
10234            setup_nonce_with_bank(10_000_000, |_| {}, 5_000_000, 250_000, None).unwrap();
10235        let custodian_pubkey = custodian_keypair.pubkey();
10236        let nonce_pubkey = nonce_keypair.pubkey();
10237
10238        let nonce_hash = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10239        let mut tx = Transaction::new_signed_with_payer(
10240            &[
10241                system_instruction::advance_nonce_account(&nonce_pubkey, &nonce_pubkey),
10242                system_instruction::transfer(&custodian_pubkey, &nonce_pubkey, 100_000),
10243            ],
10244            Some(&custodian_pubkey),
10245            &[&custodian_keypair, &nonce_keypair],
10246            nonce_hash,
10247        );
10248        tx.message.instructions[0].accounts.clear();
10249        assert!(bank
10250            .check_tx_durable_nonce(&tx.try_into().unwrap())
10251            .is_none());
10252    }
10253
10254    #[test]
10255    fn test_check_tx_durable_nonce_nonce_acc_does_not_exist_fail() {
10256        let (bank, _mint_keypair, custodian_keypair, nonce_keypair) =
10257            setup_nonce_with_bank(10_000_000, |_| {}, 5_000_000, 250_000, None).unwrap();
10258        let custodian_pubkey = custodian_keypair.pubkey();
10259        let nonce_pubkey = nonce_keypair.pubkey();
10260        let missing_keypair = Keypair::new();
10261        let missing_pubkey = missing_keypair.pubkey();
10262
10263        let nonce_hash = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10264        let tx = Transaction::new_signed_with_payer(
10265            &[
10266                system_instruction::advance_nonce_account(&missing_pubkey, &nonce_pubkey),
10267                system_instruction::transfer(&custodian_pubkey, &nonce_pubkey, 100_000),
10268            ],
10269            Some(&custodian_pubkey),
10270            &[&custodian_keypair, &nonce_keypair],
10271            nonce_hash,
10272        );
10273        assert!(bank
10274            .check_tx_durable_nonce(&tx.try_into().unwrap())
10275            .is_none());
10276    }
10277
10278    #[test]
10279    fn test_check_tx_durable_nonce_bad_tx_hash_fail() {
10280        let (bank, _mint_keypair, custodian_keypair, nonce_keypair) =
10281            setup_nonce_with_bank(10_000_000, |_| {}, 5_000_000, 250_000, None).unwrap();
10282        let custodian_pubkey = custodian_keypair.pubkey();
10283        let nonce_pubkey = nonce_keypair.pubkey();
10284
10285        let tx = Transaction::new_signed_with_payer(
10286            &[
10287                system_instruction::advance_nonce_account(&nonce_pubkey, &nonce_pubkey),
10288                system_instruction::transfer(&custodian_pubkey, &nonce_pubkey, 100_000),
10289            ],
10290            Some(&custodian_pubkey),
10291            &[&custodian_keypair, &nonce_keypair],
10292            Hash::default(),
10293        );
10294        assert!(bank
10295            .check_tx_durable_nonce(&tx.try_into().unwrap())
10296            .is_none());
10297    }
10298
10299    #[test]
10300    fn test_assign_from_nonce_account_fail() {
10301        let (genesis_config, _mint_keypair) = create_genesis_config(100_000_000);
10302        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
10303        let nonce = Keypair::new();
10304        let nonce_account = AccountSharedData::new_data(
10305            42_424_242,
10306            &nonce::state::Versions::new_current(nonce::State::Initialized(
10307                nonce::state::Data::default(),
10308            )),
10309            &system_program::id(),
10310        )
10311        .unwrap();
10312        let blockhash = bank.last_blockhash();
10313        bank.store_account(&nonce.pubkey(), &nonce_account);
10314
10315        let ix = system_instruction::assign(&nonce.pubkey(), &Pubkey::new(&[9u8; 32]));
10316        let message = Message::new(&[ix], Some(&nonce.pubkey()));
10317        let tx = Transaction::new(&[&nonce], message, blockhash);
10318
10319        let expect = Err(TransactionError::InstructionError(
10320            0,
10321            InstructionError::ModifiedProgramId,
10322        ));
10323        assert_eq!(bank.process_transaction(&tx), expect);
10324    }
10325
10326    #[test]
10327    fn test_durable_nonce_transaction() {
10328        let (mut bank, _mint_keypair, custodian_keypair, nonce_keypair) =
10329            setup_nonce_with_bank(10_000_000, |_| {}, 5_000_000, 250_000, None).unwrap();
10330        let alice_keypair = Keypair::new();
10331        let alice_pubkey = alice_keypair.pubkey();
10332        let custodian_pubkey = custodian_keypair.pubkey();
10333        let nonce_pubkey = nonce_keypair.pubkey();
10334
10335        assert_eq!(bank.get_balance(&custodian_pubkey), 4_750_000);
10336        assert_eq!(bank.get_balance(&nonce_pubkey), 250_000);
10337
10338        /* Grab the hash stored in the nonce account */
10339        let nonce_hash = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10340
10341        /* Kick nonce hash off the blockhash_queue */
10342        for _ in 0..MAX_RECENT_BLOCKHASHES + 1 {
10343            goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
10344            bank = Arc::new(new_from_parent(&bank));
10345        }
10346
10347        /* Expect a non-Durable Nonce transfer to fail */
10348        assert_eq!(
10349            bank.process_transaction(&system_transaction::transfer(
10350                &custodian_keypair,
10351                &alice_pubkey,
10352                100_000,
10353                nonce_hash
10354            ),),
10355            Err(TransactionError::BlockhashNotFound),
10356        );
10357        /* Check fee not charged */
10358        assert_eq!(bank.get_balance(&custodian_pubkey), 4_750_000);
10359
10360        /* Durable Nonce transfer */
10361        let durable_tx = Transaction::new_signed_with_payer(
10362            &[
10363                system_instruction::advance_nonce_account(&nonce_pubkey, &nonce_pubkey),
10364                system_instruction::transfer(&custodian_pubkey, &alice_pubkey, 100_000),
10365            ],
10366            Some(&custodian_pubkey),
10367            &[&custodian_keypair, &nonce_keypair],
10368            nonce_hash,
10369        );
10370        assert_eq!(bank.process_transaction(&durable_tx), Ok(()));
10371
10372        /* Check balances */
10373        let mut expected_balance = 4_650_000
10374            - bank
10375                .get_fee_for_message(
10376                    &bank.last_blockhash(),
10377                    &durable_tx.message.try_into().unwrap(),
10378                )
10379                .unwrap();
10380        assert_eq!(bank.get_balance(&custodian_pubkey), expected_balance);
10381        assert_eq!(bank.get_balance(&nonce_pubkey), 250_000);
10382        assert_eq!(bank.get_balance(&alice_pubkey), 100_000);
10383
10384        /* Confirm stored nonce has advanced */
10385        let new_nonce = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10386        assert_ne!(nonce_hash, new_nonce);
10387
10388        /* Durable Nonce re-use fails */
10389        let durable_tx = Transaction::new_signed_with_payer(
10390            &[
10391                system_instruction::advance_nonce_account(&nonce_pubkey, &nonce_pubkey),
10392                system_instruction::transfer(&custodian_pubkey, &alice_pubkey, 100_000),
10393            ],
10394            Some(&custodian_pubkey),
10395            &[&custodian_keypair, &nonce_keypair],
10396            nonce_hash,
10397        );
10398        assert_eq!(
10399            bank.process_transaction(&durable_tx),
10400            Err(TransactionError::BlockhashNotFound)
10401        );
10402        /* Check fee not charged and nonce not advanced */
10403        assert_eq!(bank.get_balance(&custodian_pubkey), expected_balance);
10404        assert_eq!(new_nonce, get_nonce_account(&bank, &nonce_pubkey).unwrap());
10405
10406        let nonce_hash = new_nonce;
10407
10408        /* Kick nonce hash off the blockhash_queue */
10409        for _ in 0..MAX_RECENT_BLOCKHASHES + 1 {
10410            goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
10411            bank = Arc::new(new_from_parent(&bank));
10412        }
10413
10414        let durable_tx = Transaction::new_signed_with_payer(
10415            &[
10416                system_instruction::advance_nonce_account(&nonce_pubkey, &nonce_pubkey),
10417                system_instruction::transfer(&custodian_pubkey, &alice_pubkey, 100_000_000),
10418            ],
10419            Some(&custodian_pubkey),
10420            &[&custodian_keypair, &nonce_keypair],
10421            nonce_hash,
10422        );
10423        assert_eq!(
10424            bank.process_transaction(&durable_tx),
10425            Err(TransactionError::InstructionError(
10426                1,
10427                system_instruction::SystemError::ResultWithNegativeCarats.into(),
10428            ))
10429        );
10430        /* Check fee charged and nonce has advanced */
10431        expected_balance -= bank
10432            .get_fee_for_message(
10433                &bank.last_blockhash(),
10434                &SanitizedMessage::try_from(durable_tx.message.clone()).unwrap(),
10435            )
10436            .unwrap();
10437        assert_eq!(bank.get_balance(&custodian_pubkey), expected_balance);
10438        assert_ne!(nonce_hash, get_nonce_account(&bank, &nonce_pubkey).unwrap());
10439        /* Confirm replaying a TX that failed with InstructionError::* now
10440         * fails with TransactionError::BlockhashNotFound
10441         */
10442        assert_eq!(
10443            bank.process_transaction(&durable_tx),
10444            Err(TransactionError::BlockhashNotFound),
10445        );
10446    }
10447
10448    #[test]
10449    fn test_nonce_authority() {
10450        gemachain_logger::setup();
10451        let (mut bank, _mint_keypair, custodian_keypair, nonce_keypair) =
10452            setup_nonce_with_bank(10_000_000, |_| {}, 5_000_000, 250_000, None).unwrap();
10453        let alice_keypair = Keypair::new();
10454        let alice_pubkey = alice_keypair.pubkey();
10455        let custodian_pubkey = custodian_keypair.pubkey();
10456        let nonce_pubkey = nonce_keypair.pubkey();
10457        let bad_nonce_authority_keypair = Keypair::new();
10458        let bad_nonce_authority = bad_nonce_authority_keypair.pubkey();
10459        let custodian_account = bank.get_account(&custodian_pubkey).unwrap();
10460
10461        debug!("alice: {}", alice_pubkey);
10462        debug!("custodian: {}", custodian_pubkey);
10463        debug!("nonce: {}", nonce_pubkey);
10464        debug!("nonce account: {:?}", bank.get_account(&nonce_pubkey));
10465        debug!("cust: {:?}", custodian_account);
10466        let nonce_hash = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10467
10468        Arc::get_mut(&mut bank)
10469            .unwrap()
10470            .activate_feature(&feature_set::merge_nonce_error_into_system_error::id());
10471        for _ in 0..MAX_RECENT_BLOCKHASHES + 1 {
10472            goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
10473            bank = Arc::new(new_from_parent(&bank));
10474        }
10475
10476        let durable_tx = Transaction::new_signed_with_payer(
10477            &[
10478                system_instruction::advance_nonce_account(&nonce_pubkey, &bad_nonce_authority),
10479                system_instruction::transfer(&custodian_pubkey, &alice_pubkey, 42),
10480            ],
10481            Some(&custodian_pubkey),
10482            &[&custodian_keypair, &bad_nonce_authority_keypair],
10483            nonce_hash,
10484        );
10485        debug!("{:?}", durable_tx);
10486        let initial_custodian_balance = custodian_account.carats();
10487        assert_eq!(
10488            bank.process_transaction(&durable_tx),
10489            Err(TransactionError::InstructionError(
10490                0,
10491                InstructionError::MissingRequiredSignature,
10492            ))
10493        );
10494        /* Check fee charged and nonce has *not* advanced */
10495        assert_eq!(
10496            bank.get_balance(&custodian_pubkey),
10497            initial_custodian_balance
10498                - bank
10499                    .get_fee_for_message(
10500                        &bank.last_blockhash(),
10501                        &durable_tx.message.try_into().unwrap()
10502                    )
10503                    .unwrap()
10504        );
10505        assert_eq!(nonce_hash, get_nonce_account(&bank, &nonce_pubkey).unwrap());
10506    }
10507
10508    #[test]
10509    fn test_nonce_payer() {
10510        gemachain_logger::setup();
10511        let nonce_starting_balance = 250_000;
10512        let (mut bank, _mint_keypair, custodian_keypair, nonce_keypair) =
10513            setup_nonce_with_bank(10_000_000, |_| {}, 5_000_000, nonce_starting_balance, None)
10514                .unwrap();
10515        let alice_keypair = Keypair::new();
10516        let alice_pubkey = alice_keypair.pubkey();
10517        let custodian_pubkey = custodian_keypair.pubkey();
10518        let nonce_pubkey = nonce_keypair.pubkey();
10519
10520        debug!("alice: {}", alice_pubkey);
10521        debug!("custodian: {}", custodian_pubkey);
10522        debug!("nonce: {}", nonce_pubkey);
10523        debug!("nonce account: {:?}", bank.get_account(&nonce_pubkey));
10524        debug!("cust: {:?}", bank.get_account(&custodian_pubkey));
10525        let nonce_hash = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10526
10527        for _ in 0..MAX_RECENT_BLOCKHASHES + 1 {
10528            goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
10529            bank = Arc::new(new_from_parent(&bank));
10530        }
10531
10532        let durable_tx = Transaction::new_signed_with_payer(
10533            &[
10534                system_instruction::advance_nonce_account(&nonce_pubkey, &nonce_pubkey),
10535                system_instruction::transfer(&custodian_pubkey, &alice_pubkey, 100_000_000),
10536            ],
10537            Some(&nonce_pubkey),
10538            &[&custodian_keypair, &nonce_keypair],
10539            nonce_hash,
10540        );
10541        debug!("{:?}", durable_tx);
10542        assert_eq!(
10543            bank.process_transaction(&durable_tx),
10544            Err(TransactionError::InstructionError(
10545                1,
10546                system_instruction::SystemError::ResultWithNegativeCarats.into(),
10547            ))
10548        );
10549        /* Check fee charged and nonce has advanced */
10550        assert_eq!(
10551            bank.get_balance(&nonce_pubkey),
10552            nonce_starting_balance
10553                - bank
10554                    .get_fee_for_message(
10555                        &bank.last_blockhash(),
10556                        &durable_tx.message.try_into().unwrap()
10557                    )
10558                    .unwrap()
10559        );
10560        assert_ne!(nonce_hash, get_nonce_account(&bank, &nonce_pubkey).unwrap());
10561    }
10562
10563    #[test]
10564    fn test_nonce_fee_calculator_updates() {
10565        let (mut genesis_config, mint_keypair) = create_genesis_config(1_000_000);
10566        genesis_config.rent.carats_per_byte_year = 0;
10567        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
10568
10569        // Deliberately use bank 0 to initialize nonce account, so that nonce account fee_calculator indicates 0 fees
10570        let (custodian_keypair, nonce_keypair) =
10571            nonce_setup(&mut bank, &mint_keypair, 500_000, 100_000, None).unwrap();
10572        let custodian_pubkey = custodian_keypair.pubkey();
10573        let nonce_pubkey = nonce_keypair.pubkey();
10574
10575        // Grab the hash and fee_calculator stored in the nonce account
10576        let (stored_nonce_hash, stored_fee_calculator) = bank
10577            .get_account(&nonce_pubkey)
10578            .and_then(|acc| {
10579                let state =
10580                    StateMut::<nonce::state::Versions>::state(&acc).map(|v| v.convert_to_current());
10581                match state {
10582                    Ok(nonce::State::Initialized(ref data)) => {
10583                        Some((data.blockhash, data.fee_calculator.clone()))
10584                    }
10585                    _ => None,
10586                }
10587            })
10588            .unwrap();
10589
10590        // Kick nonce hash off the blockhash_queue
10591        for _ in 0..MAX_RECENT_BLOCKHASHES + 1 {
10592            goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
10593            bank = Arc::new(new_from_parent(&bank));
10594        }
10595
10596        // Durable Nonce transfer
10597        let nonce_tx = Transaction::new_signed_with_payer(
10598            &[
10599                system_instruction::advance_nonce_account(&nonce_pubkey, &nonce_pubkey),
10600                system_instruction::transfer(
10601                    &custodian_pubkey,
10602                    &gemachain_sdk::pubkey::new_rand(),
10603                    100_000,
10604                ),
10605            ],
10606            Some(&custodian_pubkey),
10607            &[&custodian_keypair, &nonce_keypair],
10608            stored_nonce_hash,
10609        );
10610        bank.process_transaction(&nonce_tx).unwrap();
10611
10612        // Grab the new hash and fee_calculator; both should be updated
10613        let (nonce_hash, fee_calculator) = bank
10614            .get_account(&nonce_pubkey)
10615            .and_then(|acc| {
10616                let state =
10617                    StateMut::<nonce::state::Versions>::state(&acc).map(|v| v.convert_to_current());
10618                match state {
10619                    Ok(nonce::State::Initialized(ref data)) => {
10620                        Some((data.blockhash, data.fee_calculator.clone()))
10621                    }
10622                    _ => None,
10623                }
10624            })
10625            .unwrap();
10626
10627        assert_ne!(stored_nonce_hash, nonce_hash);
10628        assert_ne!(stored_fee_calculator, fee_calculator);
10629    }
10630
10631    #[test]
10632    fn test_collect_balances() {
10633        let (genesis_config, _mint_keypair) = create_genesis_config(500);
10634        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
10635        let bank0 = Arc::new(new_from_parent(&parent));
10636
10637        let keypair = Keypair::new();
10638        let pubkey0 = gemachain_sdk::pubkey::new_rand();
10639        let pubkey1 = gemachain_sdk::pubkey::new_rand();
10640        let program_id = Pubkey::new(&[2; 32]);
10641        let keypair_account = AccountSharedData::new(8, 0, &program_id);
10642        let account0 = AccountSharedData::new(11, 0, &program_id);
10643        let program_account = AccountSharedData::new(1, 10, &Pubkey::default());
10644        bank0.store_account(&keypair.pubkey(), &keypair_account);
10645        bank0.store_account(&pubkey0, &account0);
10646        bank0.store_account(&program_id, &program_account);
10647
10648        let instructions = vec![CompiledInstruction::new(1, &(), vec![0])];
10649        let tx0 = Transaction::new_with_compiled_instructions(
10650            &[&keypair],
10651            &[pubkey0],
10652            Hash::default(),
10653            vec![program_id],
10654            instructions,
10655        );
10656        let instructions = vec![CompiledInstruction::new(1, &(), vec![0])];
10657        let tx1 = Transaction::new_with_compiled_instructions(
10658            &[&keypair],
10659            &[pubkey1],
10660            Hash::default(),
10661            vec![program_id],
10662            instructions,
10663        );
10664        let txs = vec![tx0, tx1];
10665        let batch = bank0.prepare_batch(txs.clone()).unwrap();
10666        let balances = bank0.collect_balances(&batch);
10667        assert_eq!(balances.len(), 2);
10668        assert_eq!(balances[0], vec![8, 11, 1]);
10669        assert_eq!(balances[1], vec![8, 0, 1]);
10670
10671        let txs: Vec<_> = txs.into_iter().rev().collect();
10672        let batch = bank0.prepare_batch(txs).unwrap();
10673        let balances = bank0.collect_balances(&batch);
10674        assert_eq!(balances.len(), 2);
10675        assert_eq!(balances[0], vec![8, 0, 1]);
10676        assert_eq!(balances[1], vec![8, 11, 1]);
10677    }
10678
10679    #[test]
10680    fn test_pre_post_transaction_balances() {
10681        let (mut genesis_config, _mint_keypair) = create_genesis_config(500);
10682        let fee_rate_governor = FeeRateGovernor::new(1, 0);
10683        genesis_config.fee_rate_governor = fee_rate_governor;
10684        let parent = Arc::new(Bank::new_for_tests(&genesis_config));
10685        let bank0 = Arc::new(new_from_parent(&parent));
10686
10687        let keypair0 = Keypair::new();
10688        let keypair1 = Keypair::new();
10689        let pubkey0 = gemachain_sdk::pubkey::new_rand();
10690        let pubkey1 = gemachain_sdk::pubkey::new_rand();
10691        let pubkey2 = gemachain_sdk::pubkey::new_rand();
10692        let keypair0_account = AccountSharedData::new(8, 0, &Pubkey::default());
10693        let keypair1_account = AccountSharedData::new(9, 0, &Pubkey::default());
10694        let account0 = AccountSharedData::new(11, 0, &Pubkey::default());
10695        bank0.store_account(&keypair0.pubkey(), &keypair0_account);
10696        bank0.store_account(&keypair1.pubkey(), &keypair1_account);
10697        bank0.store_account(&pubkey0, &account0);
10698
10699        let blockhash = bank0.last_blockhash();
10700
10701        let tx0 = system_transaction::transfer(&keypair0, &pubkey0, 2, blockhash);
10702        let tx1 = system_transaction::transfer(&Keypair::new(), &pubkey1, 2, blockhash);
10703        let tx2 = system_transaction::transfer(&keypair1, &pubkey2, 12, blockhash);
10704        let txs = vec![tx0, tx1, tx2];
10705
10706        let lock_result = bank0.prepare_batch(txs).unwrap();
10707        let (transaction_results, transaction_balances_set, inner_instructions, transaction_logs) =
10708            bank0.load_execute_and_commit_transactions(
10709                &lock_result,
10710                MAX_PROCESSING_AGE,
10711                true,
10712                false,
10713                false,
10714                &mut ExecuteTimings::default(),
10715            );
10716
10717        assert!(inner_instructions.iter().all(Option::is_none));
10718        assert!(transaction_logs.iter().all(Option::is_none));
10719
10720        assert_eq!(inner_instructions.len(), 3);
10721        assert_eq!(transaction_logs.len(), 3);
10722        assert_eq!(transaction_balances_set.pre_balances.len(), 3);
10723        assert_eq!(transaction_balances_set.post_balances.len(), 3);
10724
10725        assert!(transaction_results.execution_results[0].0.is_ok());
10726        assert_eq!(transaction_balances_set.pre_balances[0], vec![8, 11, 1]);
10727        assert_eq!(transaction_balances_set.post_balances[0], vec![5, 13, 1]);
10728
10729        // Failed transactions still produce balance sets
10730        // This is a TransactionError - not possible to charge fees
10731        assert!(transaction_results.execution_results[1].0.is_err());
10732        assert_eq!(transaction_balances_set.pre_balances[1], vec![0, 0, 1]);
10733        assert_eq!(transaction_balances_set.post_balances[1], vec![0, 0, 1]);
10734
10735        // Failed transactions still produce balance sets
10736        // This is an InstructionError - fees charged
10737        assert!(transaction_results.execution_results[2].0.is_err());
10738        assert_eq!(transaction_balances_set.pre_balances[2], vec![9, 0, 1]);
10739        assert_eq!(transaction_balances_set.post_balances[2], vec![8, 0, 1]);
10740    }
10741
10742    #[test]
10743    fn test_transaction_with_duplicate_accounts_in_instruction() {
10744        let (genesis_config, mint_keypair) = create_genesis_config(500);
10745        let mut bank = Bank::new_for_tests(&genesis_config);
10746
10747        fn mock_process_instruction(
10748            _program_id: &Pubkey,
10749            data: &[u8],
10750            invoke_context: &mut dyn InvokeContext,
10751        ) -> result::Result<(), InstructionError> {
10752            let keyed_accounts = invoke_context.get_keyed_accounts()?;
10753            let carats = data[0] as u64;
10754            {
10755                let mut to_account = keyed_accounts[1].try_account_ref_mut()?;
10756                let mut dup_account = keyed_accounts[2].try_account_ref_mut()?;
10757                dup_account.checked_sub_carats(carats)?;
10758                to_account.checked_add_carats(carats)?;
10759            }
10760            keyed_accounts[0]
10761                .try_account_ref_mut()?
10762                .checked_sub_carats(carats)?;
10763            keyed_accounts[1]
10764                .try_account_ref_mut()?
10765                .checked_add_carats(carats)?;
10766            Ok(())
10767        }
10768
10769        let mock_program_id = Pubkey::new(&[2u8; 32]);
10770        bank.add_builtin("mock_program", mock_program_id, mock_process_instruction);
10771
10772        let from_pubkey = gemachain_sdk::pubkey::new_rand();
10773        let to_pubkey = gemachain_sdk::pubkey::new_rand();
10774        let dup_pubkey = from_pubkey;
10775        let from_account = AccountSharedData::new(100, 1, &mock_program_id);
10776        let to_account = AccountSharedData::new(0, 1, &mock_program_id);
10777        bank.store_account(&from_pubkey, &from_account);
10778        bank.store_account(&to_pubkey, &to_account);
10779
10780        let account_metas = vec![
10781            AccountMeta::new(from_pubkey, false),
10782            AccountMeta::new(to_pubkey, false),
10783            AccountMeta::new(dup_pubkey, false),
10784        ];
10785        let instruction = Instruction::new_with_bincode(mock_program_id, &10, account_metas);
10786        let tx = Transaction::new_signed_with_payer(
10787            &[instruction],
10788            Some(&mint_keypair.pubkey()),
10789            &[&mint_keypair],
10790            bank.last_blockhash(),
10791        );
10792
10793        let result = bank.process_transaction(&tx);
10794        assert_eq!(result, Ok(()));
10795        assert_eq!(bank.get_balance(&from_pubkey), 80);
10796        assert_eq!(bank.get_balance(&to_pubkey), 20);
10797    }
10798
10799    #[test]
10800    fn test_transaction_with_program_ids_passed_to_programs() {
10801        let (genesis_config, mint_keypair) = create_genesis_config(500);
10802        let mut bank = Bank::new_for_tests(&genesis_config);
10803
10804        #[allow(clippy::unnecessary_wraps)]
10805        fn mock_process_instruction(
10806            _program_id: &Pubkey,
10807            _data: &[u8],
10808            _invoke_context: &mut dyn InvokeContext,
10809        ) -> result::Result<(), InstructionError> {
10810            Ok(())
10811        }
10812
10813        let mock_program_id = Pubkey::new(&[2u8; 32]);
10814        bank.add_builtin("mock_program", mock_program_id, mock_process_instruction);
10815
10816        let from_pubkey = gemachain_sdk::pubkey::new_rand();
10817        let to_pubkey = gemachain_sdk::pubkey::new_rand();
10818        let dup_pubkey = from_pubkey;
10819        let from_account = AccountSharedData::new(100, 1, &mock_program_id);
10820        let to_account = AccountSharedData::new(0, 1, &mock_program_id);
10821        bank.store_account(&from_pubkey, &from_account);
10822        bank.store_account(&to_pubkey, &to_account);
10823
10824        let account_metas = vec![
10825            AccountMeta::new(from_pubkey, false),
10826            AccountMeta::new(to_pubkey, false),
10827            AccountMeta::new(dup_pubkey, false),
10828            AccountMeta::new(mock_program_id, false),
10829        ];
10830        let instruction = Instruction::new_with_bincode(mock_program_id, &10, account_metas);
10831        let tx = Transaction::new_signed_with_payer(
10832            &[instruction],
10833            Some(&mint_keypair.pubkey()),
10834            &[&mint_keypair],
10835            bank.last_blockhash(),
10836        );
10837
10838        let result = bank.process_transaction(&tx);
10839        assert_eq!(result, Ok(()));
10840    }
10841
10842    #[test]
10843    fn test_account_ids_after_program_ids() {
10844        gemachain_logger::setup();
10845        let (genesis_config, mint_keypair) = create_genesis_config(500);
10846        let mut bank = Bank::new_for_tests(&genesis_config);
10847
10848        let from_pubkey = gemachain_sdk::pubkey::new_rand();
10849        let to_pubkey = gemachain_sdk::pubkey::new_rand();
10850
10851        let account_metas = vec![
10852            AccountMeta::new(from_pubkey, false),
10853            AccountMeta::new(to_pubkey, false),
10854        ];
10855
10856        let instruction =
10857            Instruction::new_with_bincode(gemachain_vote_program::id(), &10, account_metas);
10858        let mut tx = Transaction::new_signed_with_payer(
10859            &[instruction],
10860            Some(&mint_keypair.pubkey()),
10861            &[&mint_keypair],
10862            bank.last_blockhash(),
10863        );
10864
10865        tx.message.account_keys.push(gemachain_sdk::pubkey::new_rand());
10866
10867        bank.add_builtin(
10868            "mock_vote",
10869            gemachain_vote_program::id(),
10870            mock_ok_vote_processor,
10871        );
10872        let result = bank.process_transaction(&tx);
10873        assert_eq!(result, Ok(()));
10874        let account = bank.get_account(&gemachain_vote_program::id()).unwrap();
10875        info!("account: {:?}", account);
10876        assert!(account.executable());
10877    }
10878
10879    #[test]
10880    fn test_incinerator() {
10881        let (genesis_config, mint_keypair) = create_genesis_config(1_000_000_000_000);
10882        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
10883
10884        // Move to the first normal slot so normal rent behaviour applies
10885        let bank = Bank::new_from_parent(
10886            &bank0,
10887            &Pubkey::default(),
10888            genesis_config.epoch_schedule.first_normal_slot,
10889        );
10890        let pre_capitalization = bank.capitalization();
10891
10892        // Burn a non-rent exempt amount
10893        let burn_amount = bank.get_minimum_balance_for_rent_exemption(0) - 1;
10894
10895        assert_eq!(bank.get_balance(&incinerator::id()), 0);
10896        bank.transfer(burn_amount, &mint_keypair, &incinerator::id())
10897            .unwrap();
10898        assert_eq!(bank.get_balance(&incinerator::id()), burn_amount);
10899        bank.freeze();
10900        assert_eq!(bank.get_balance(&incinerator::id()), 0);
10901
10902        // Ensure that no rent was collected, and the entire burn amount was removed from bank
10903        // capitalization
10904        assert_eq!(bank.capitalization(), pre_capitalization - burn_amount);
10905    }
10906
10907    #[test]
10908    fn test_duplicate_account_key() {
10909        gemachain_logger::setup();
10910        let (genesis_config, mint_keypair) = create_genesis_config(500);
10911        let mut bank = Bank::new_for_tests(&genesis_config);
10912
10913        let from_pubkey = gemachain_sdk::pubkey::new_rand();
10914        let to_pubkey = gemachain_sdk::pubkey::new_rand();
10915
10916        let account_metas = vec![
10917            AccountMeta::new(from_pubkey, false),
10918            AccountMeta::new(to_pubkey, false),
10919        ];
10920
10921        bank.add_builtin(
10922            "mock_vote",
10923            gemachain_vote_program::id(),
10924            mock_ok_vote_processor,
10925        );
10926
10927        let instruction =
10928            Instruction::new_with_bincode(gemachain_vote_program::id(), &10, account_metas);
10929        let mut tx = Transaction::new_signed_with_payer(
10930            &[instruction],
10931            Some(&mint_keypair.pubkey()),
10932            &[&mint_keypair],
10933            bank.last_blockhash(),
10934        );
10935        tx.message.account_keys.push(from_pubkey);
10936
10937        let result = bank.process_transaction(&tx);
10938        assert_eq!(result, Err(TransactionError::AccountLoadedTwice));
10939    }
10940
10941    #[test]
10942    fn test_program_id_as_payer() {
10943        gemachain_logger::setup();
10944        let (genesis_config, mint_keypair) = create_genesis_config(500);
10945        let mut bank = Bank::new_for_tests(&genesis_config);
10946
10947        let from_pubkey = gemachain_sdk::pubkey::new_rand();
10948        let to_pubkey = gemachain_sdk::pubkey::new_rand();
10949
10950        let account_metas = vec![
10951            AccountMeta::new(from_pubkey, false),
10952            AccountMeta::new(to_pubkey, false),
10953        ];
10954
10955        bank.add_builtin(
10956            "mock_vote",
10957            gemachain_vote_program::id(),
10958            mock_ok_vote_processor,
10959        );
10960
10961        let instruction =
10962            Instruction::new_with_bincode(gemachain_vote_program::id(), &10, account_metas);
10963        let mut tx = Transaction::new_signed_with_payer(
10964            &[instruction],
10965            Some(&mint_keypair.pubkey()),
10966            &[&mint_keypair],
10967            bank.last_blockhash(),
10968        );
10969
10970        info!(
10971            "mint: {} account keys: {:?}",
10972            mint_keypair.pubkey(),
10973            tx.message.account_keys
10974        );
10975        assert_eq!(tx.message.account_keys.len(), 4);
10976        tx.message.account_keys.clear();
10977        tx.message.account_keys.push(gemachain_vote_program::id());
10978        tx.message.account_keys.push(mint_keypair.pubkey());
10979        tx.message.account_keys.push(from_pubkey);
10980        tx.message.account_keys.push(to_pubkey);
10981        tx.message.instructions[0].program_id_index = 0;
10982        tx.message.instructions[0].accounts.clear();
10983        tx.message.instructions[0].accounts.push(2);
10984        tx.message.instructions[0].accounts.push(3);
10985
10986        let result = bank.process_transaction(&tx);
10987        assert_eq!(result, Err(TransactionError::SanitizeFailure));
10988    }
10989
10990    #[allow(clippy::unnecessary_wraps)]
10991    fn mock_ok_vote_processor(
10992        _pubkey: &Pubkey,
10993        _data: &[u8],
10994        _invoke_context: &mut dyn InvokeContext,
10995    ) -> std::result::Result<(), InstructionError> {
10996        Ok(())
10997    }
10998
10999    #[test]
11000    fn test_ref_account_key_after_program_id() {
11001        let (genesis_config, mint_keypair) = create_genesis_config(500);
11002        let mut bank = Bank::new_for_tests(&genesis_config);
11003
11004        let from_pubkey = gemachain_sdk::pubkey::new_rand();
11005        let to_pubkey = gemachain_sdk::pubkey::new_rand();
11006
11007        let account_metas = vec![
11008            AccountMeta::new(from_pubkey, false),
11009            AccountMeta::new(to_pubkey, false),
11010        ];
11011
11012        bank.add_builtin(
11013            "mock_vote",
11014            gemachain_vote_program::id(),
11015            mock_ok_vote_processor,
11016        );
11017
11018        let instruction =
11019            Instruction::new_with_bincode(gemachain_vote_program::id(), &10, account_metas);
11020        let mut tx = Transaction::new_signed_with_payer(
11021            &[instruction],
11022            Some(&mint_keypair.pubkey()),
11023            &[&mint_keypair],
11024            bank.last_blockhash(),
11025        );
11026
11027        tx.message.account_keys.push(gemachain_sdk::pubkey::new_rand());
11028        assert_eq!(tx.message.account_keys.len(), 5);
11029        tx.message.instructions[0].accounts.remove(0);
11030        tx.message.instructions[0].accounts.push(4);
11031
11032        let result = bank.process_transaction(&tx);
11033        assert_eq!(result, Ok(()));
11034    }
11035
11036    #[test]
11037    fn test_fuzz_instructions() {
11038        gemachain_logger::setup();
11039        use rand::{thread_rng, Rng};
11040        let (genesis_config, _mint_keypair) = create_genesis_config(1_000_000_000);
11041        let mut bank = Bank::new_for_tests(&genesis_config);
11042
11043        let max_programs = 5;
11044        let program_keys: Vec<_> = (0..max_programs)
11045            .enumerate()
11046            .map(|i| {
11047                let key = gemachain_sdk::pubkey::new_rand();
11048                let name = format!("program{:?}", i);
11049                bank.add_builtin(&name, key, mock_ok_vote_processor);
11050                (key, name.as_bytes().to_vec())
11051            })
11052            .collect();
11053        let max_keys = 100;
11054        let keys: Vec<_> = (0..max_keys)
11055            .enumerate()
11056            .map(|_| {
11057                let key = gemachain_sdk::pubkey::new_rand();
11058                let balance = if thread_rng().gen_ratio(9, 10) {
11059                    let carats = if thread_rng().gen_ratio(1, 5) {
11060                        thread_rng().gen_range(0, 10)
11061                    } else {
11062                        thread_rng().gen_range(20, 100)
11063                    };
11064                    let space = thread_rng().gen_range(0, 10);
11065                    let owner = Pubkey::default();
11066                    let account = AccountSharedData::new(carats, space, &owner);
11067                    bank.store_account(&key, &account);
11068                    carats
11069                } else {
11070                    0
11071                };
11072                (key, balance)
11073            })
11074            .collect();
11075        let mut results = HashMap::new();
11076        for _ in 0..2_000 {
11077            let num_keys = if thread_rng().gen_ratio(1, 5) {
11078                thread_rng().gen_range(0, max_keys)
11079            } else {
11080                thread_rng().gen_range(1, 4)
11081            };
11082            let num_instructions = thread_rng().gen_range(0, max_keys - num_keys);
11083
11084            let mut account_keys: Vec<_> = if thread_rng().gen_ratio(1, 5) {
11085                (0..num_keys)
11086                    .map(|_| {
11087                        let idx = thread_rng().gen_range(0, keys.len());
11088                        keys[idx].0
11089                    })
11090                    .collect()
11091            } else {
11092                let mut inserted = HashSet::new();
11093                (0..num_keys)
11094                    .map(|_| {
11095                        let mut idx;
11096                        loop {
11097                            idx = thread_rng().gen_range(0, keys.len());
11098                            if !inserted.contains(&idx) {
11099                                break;
11100                            }
11101                        }
11102                        inserted.insert(idx);
11103                        keys[idx].0
11104                    })
11105                    .collect()
11106            };
11107
11108            let instructions: Vec<_> = if num_keys > 0 {
11109                (0..num_instructions)
11110                    .map(|_| {
11111                        let num_accounts_to_pass = thread_rng().gen_range(0, num_keys);
11112                        let account_indexes = (0..num_accounts_to_pass)
11113                            .map(|_| thread_rng().gen_range(0, num_keys))
11114                            .collect();
11115                        let program_index: u8 = thread_rng().gen_range(0, num_keys) as u8;
11116                        if thread_rng().gen_ratio(4, 5) {
11117                            let programs_index = thread_rng().gen_range(0, program_keys.len());
11118                            account_keys[program_index as usize] = program_keys[programs_index].0;
11119                        }
11120                        CompiledInstruction::new(program_index, &10, account_indexes)
11121                    })
11122                    .collect()
11123            } else {
11124                vec![]
11125            };
11126
11127            let account_keys_len = std::cmp::max(account_keys.len(), 2);
11128            let num_signatures = if thread_rng().gen_ratio(1, 5) {
11129                thread_rng().gen_range(0, account_keys_len + 10)
11130            } else {
11131                thread_rng().gen_range(1, account_keys_len)
11132            };
11133
11134            let num_required_signatures = if thread_rng().gen_ratio(1, 5) {
11135                thread_rng().gen_range(0, account_keys_len + 10) as u8
11136            } else {
11137                thread_rng().gen_range(1, std::cmp::max(2, num_signatures)) as u8
11138            };
11139            let num_readonly_signed_accounts = if thread_rng().gen_ratio(1, 5) {
11140                thread_rng().gen_range(0, account_keys_len) as u8
11141            } else {
11142                let max = if num_required_signatures > 1 {
11143                    num_required_signatures - 1
11144                } else {
11145                    1
11146                };
11147                thread_rng().gen_range(0, max) as u8
11148            };
11149
11150            let num_readonly_unsigned_accounts = if thread_rng().gen_ratio(1, 5)
11151                || (num_required_signatures as usize) >= account_keys_len
11152            {
11153                thread_rng().gen_range(0, account_keys_len) as u8
11154            } else {
11155                thread_rng().gen_range(0, account_keys_len - num_required_signatures as usize) as u8
11156            };
11157
11158            let header = MessageHeader {
11159                num_required_signatures,
11160                num_readonly_signed_accounts,
11161                num_readonly_unsigned_accounts,
11162            };
11163            let message = Message {
11164                header,
11165                account_keys,
11166                recent_blockhash: bank.last_blockhash(),
11167                instructions,
11168            };
11169
11170            let tx = Transaction {
11171                signatures: vec![Signature::default(); num_signatures],
11172                message,
11173            };
11174
11175            let result = bank.process_transaction(&tx);
11176            for (key, balance) in &keys {
11177                assert_eq!(bank.get_balance(key), *balance);
11178            }
11179            for (key, name) in &program_keys {
11180                let account = bank.get_account(key).unwrap();
11181                assert!(account.executable());
11182                assert_eq!(account.data(), name);
11183            }
11184            info!("result: {:?}", result);
11185            let result_key = format!("{:?}", result);
11186            *results.entry(result_key).or_insert(0) += 1;
11187        }
11188        info!("results: {:?}", results);
11189    }
11190
11191    #[test]
11192    fn test_bank_hash_consistency() {
11193        gemachain_logger::setup();
11194
11195        let mut genesis_config = GenesisConfig::new(
11196            &[(
11197                Pubkey::new(&[42; 32]),
11198                AccountSharedData::new(1_000_000_000_000, 0, &system_program::id()),
11199            )],
11200            &[],
11201        );
11202        genesis_config.creation_time = 0;
11203        genesis_config.cluster_type = ClusterType::MainnetBeta;
11204        genesis_config.rent.burn_percent = 100;
11205        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
11206        // Check a few slots, cross an epoch boundary
11207        assert_eq!(bank.get_slots_in_epoch(0), 32);
11208        loop {
11209            goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
11210            if bank.slot == 0 {
11211                assert_eq!(
11212                    bank.hash().to_string(),
11213                    "DqaWg7EVKzb5Fpe92zNBtXAWqLwcedgHDicYrCBnf3QK"
11214                );
11215            }
11216            if bank.slot == 32 {
11217                assert_eq!(
11218                    bank.hash().to_string(),
11219                    "AYdhzhKrM74r9XuZBDGcHeFzg2DEtp1boggnEnzDjZSq"
11220                );
11221            }
11222            if bank.slot == 64 {
11223                assert_eq!(
11224                    bank.hash().to_string(),
11225                    "EsbPVYzo1qz5reEUH5okKW4ExB6WbcidkVdW5mzpFn7C"
11226                );
11227            }
11228            if bank.slot == 128 {
11229                assert_eq!(
11230                    bank.hash().to_string(),
11231                    "H3DWrQ6FqbLkFNDxbWQ62UKRbw2dbuxf3oVF2VpBk6Ga"
11232                );
11233                break;
11234            }
11235            bank = Arc::new(new_from_parent(&bank));
11236        }
11237    }
11238
11239    #[test]
11240    fn test_same_program_id_uses_unqiue_executable_accounts() {
11241        fn nested_processor(
11242            _program_id: &Pubkey,
11243            _data: &[u8],
11244            invoke_context: &mut dyn InvokeContext,
11245        ) -> result::Result<(), InstructionError> {
11246            let keyed_accounts = invoke_context.get_keyed_accounts()?;
11247            assert_eq!(42, keyed_accounts[0].carats().unwrap());
11248            let mut account = keyed_accounts[0].try_account_ref_mut()?;
11249            account.checked_add_carats(1)?;
11250            Ok(())
11251        }
11252
11253        let (genesis_config, mint_keypair) = create_genesis_config(50000);
11254        let mut bank = Bank::new_for_tests(&genesis_config);
11255
11256        // Add a new program
11257        let program1_pubkey = gemachain_sdk::pubkey::new_rand();
11258        bank.add_builtin("program", program1_pubkey, nested_processor);
11259
11260        // Add a new program owned by the first
11261        let program2_pubkey = gemachain_sdk::pubkey::new_rand();
11262        let mut program2_account = AccountSharedData::new(42, 1, &program1_pubkey);
11263        program2_account.set_executable(true);
11264        bank.store_account(&program2_pubkey, &program2_account);
11265
11266        let instruction = Instruction::new_with_bincode(program2_pubkey, &10, vec![]);
11267        let tx = Transaction::new_signed_with_payer(
11268            &[instruction.clone(), instruction],
11269            Some(&mint_keypair.pubkey()),
11270            &[&mint_keypair],
11271            bank.last_blockhash(),
11272        );
11273        assert!(bank.process_transaction(&tx).is_ok());
11274        assert_eq!(1, bank.get_balance(&program1_pubkey));
11275        assert_eq!(42, bank.get_balance(&program2_pubkey));
11276    }
11277
11278    fn get_shrink_account_size() -> usize {
11279        let (genesis_config, _mint_keypair) = create_genesis_config(1_000_000_000);
11280
11281        // Set root for bank 0, with caching disabled so we can get the size
11282        // of the storage for this slot
11283        let mut bank0 = Arc::new(Bank::new_with_config(
11284            &genesis_config,
11285            AccountSecondaryIndexes::default(),
11286            false,
11287            AccountShrinkThreshold::default(),
11288        ));
11289        bank0.restore_old_behavior_for_fragile_tests();
11290        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank0).unwrap());
11291        bank0.freeze();
11292        bank0.squash();
11293
11294        let sizes = bank0
11295            .rc
11296            .accounts
11297            .scan_slot(0, |stored_account| Some(stored_account.stored_size()));
11298
11299        // Create an account such that it takes DEFAULT_ACCOUNTS_SHRINK_RATIO of the total account space for
11300        // the slot, so when it gets pruned, the storage entry will become a shrink candidate.
11301        let bank0_total_size: usize = sizes.into_iter().sum();
11302        let pubkey0_size = (bank0_total_size as f64 / (1.0 - DEFAULT_ACCOUNTS_SHRINK_RATIO)).ceil();
11303        assert!(
11304            pubkey0_size / (pubkey0_size + bank0_total_size as f64) > DEFAULT_ACCOUNTS_SHRINK_RATIO
11305        );
11306        pubkey0_size as usize
11307    }
11308
11309    #[test]
11310    fn test_clean_nonrooted() {
11311        gemachain_logger::setup();
11312
11313        let (genesis_config, _mint_keypair) = create_genesis_config(1_000_000_000);
11314        let pubkey0 = Pubkey::new(&[0; 32]);
11315        let pubkey1 = Pubkey::new(&[1; 32]);
11316
11317        info!("pubkey0: {}", pubkey0);
11318        info!("pubkey1: {}", pubkey1);
11319
11320        // Set root for bank 0, with caching enabled
11321        let mut bank0 = Arc::new(Bank::new_with_config(
11322            &genesis_config,
11323            AccountSecondaryIndexes::default(),
11324            true,
11325            AccountShrinkThreshold::default(),
11326        ));
11327
11328        let account_zero = AccountSharedData::new(0, 0, &Pubkey::new_unique());
11329
11330        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank0).unwrap());
11331        bank0.freeze();
11332        bank0.squash();
11333        // Flush now so that accounts cache cleaning doesn't clean up bank 0 when later
11334        // slots add updates to the cache
11335        bank0.force_flush_accounts_cache();
11336
11337        // Store some carats in bank 1
11338        let some_carats = 123;
11339        let mut bank1 = Arc::new(Bank::new_from_parent(&bank0, &Pubkey::default(), 1));
11340        bank1.deposit(&pubkey0, some_carats).unwrap();
11341        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank1).unwrap());
11342        bank1.freeze();
11343        bank1.flush_accounts_cache_slot();
11344
11345        bank1.print_accounts_stats();
11346
11347        // Store some carats for pubkey1 in bank 2, root bank 2
11348        // bank2's parent is bank0
11349        let mut bank2 = Arc::new(Bank::new_from_parent(&bank0, &Pubkey::default(), 2));
11350        bank2.deposit(&pubkey1, some_carats).unwrap();
11351        bank2.store_account(&pubkey0, &account_zero);
11352        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank2).unwrap());
11353        bank2.freeze();
11354        bank2.squash();
11355        bank2.force_flush_accounts_cache();
11356
11357        bank2.print_accounts_stats();
11358        drop(bank1);
11359
11360        // Clean accounts, which should add earlier slots to the shrink
11361        // candidate set
11362        bank2.clean_accounts(false, false, None);
11363
11364        let mut bank3 = Arc::new(Bank::new_from_parent(&bank2, &Pubkey::default(), 3));
11365        bank3.deposit(&pubkey1, some_carats + 1).unwrap();
11366        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank3).unwrap());
11367        bank3.freeze();
11368        bank3.squash();
11369        bank3.force_flush_accounts_cache();
11370
11371        bank3.clean_accounts(false, false, None);
11372        assert_eq!(
11373            bank3.rc.accounts.accounts_db.ref_count_for_pubkey(&pubkey0),
11374            2
11375        );
11376        assert!(bank3
11377            .rc
11378            .accounts
11379            .accounts_db
11380            .storage
11381            .get_slot_stores(1)
11382            .is_none());
11383
11384        bank3.print_accounts_stats();
11385    }
11386
11387    #[test]
11388    fn test_shrink_candidate_slots_cached() {
11389        gemachain_logger::setup();
11390
11391        let (genesis_config, _mint_keypair) = create_genesis_config(1_000_000_000);
11392        let pubkey0 = gemachain_sdk::pubkey::new_rand();
11393        let pubkey1 = gemachain_sdk::pubkey::new_rand();
11394        let pubkey2 = gemachain_sdk::pubkey::new_rand();
11395
11396        // Set root for bank 0, with caching enabled
11397        let mut bank0 = Arc::new(Bank::new_with_config(
11398            &genesis_config,
11399            AccountSecondaryIndexes::default(),
11400            true,
11401            AccountShrinkThreshold::default(),
11402        ));
11403        bank0.restore_old_behavior_for_fragile_tests();
11404
11405        let pubkey0_size = get_shrink_account_size();
11406
11407        let account0 = AccountSharedData::new(1000, pubkey0_size as usize, &Pubkey::new_unique());
11408        bank0.store_account(&pubkey0, &account0);
11409
11410        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank0).unwrap());
11411        bank0.freeze();
11412        bank0.squash();
11413        // Flush now so that accounts cache cleaning doesn't clean up bank 0 when later
11414        // slots add updates to the cache
11415        bank0.force_flush_accounts_cache();
11416
11417        // Store some carats in bank 1
11418        let some_carats = 123;
11419        let mut bank1 = Arc::new(new_from_parent(&bank0));
11420        bank1.deposit(&pubkey1, some_carats).unwrap();
11421        bank1.deposit(&pubkey2, some_carats).unwrap();
11422        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank1).unwrap());
11423        bank1.freeze();
11424        bank1.squash();
11425        // Flush now so that accounts cache cleaning doesn't clean up bank 0 when later
11426        // slots add updates to the cache
11427        bank1.force_flush_accounts_cache();
11428
11429        // Store some carats for pubkey1 in bank 2, root bank 2
11430        let mut bank2 = Arc::new(new_from_parent(&bank1));
11431        bank2.deposit(&pubkey1, some_carats).unwrap();
11432        bank2.store_account(&pubkey0, &account0);
11433        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank2).unwrap());
11434        bank2.freeze();
11435        bank2.squash();
11436        bank2.force_flush_accounts_cache();
11437
11438        // Clean accounts, which should add earlier slots to the shrink
11439        // candidate set
11440        bank2.clean_accounts(false, false, None);
11441
11442        // Slots 0 and 1 should be candidates for shrinking, but slot 2
11443        // shouldn't because none of its accounts are outdated by a later
11444        // root
11445        assert_eq!(bank2.shrink_candidate_slots(), 2);
11446        let alive_counts: Vec<usize> = (0..3)
11447            .map(|slot| {
11448                bank2
11449                    .rc
11450                    .accounts
11451                    .accounts_db
11452                    .alive_account_count_in_slot(slot)
11453            })
11454            .collect();
11455
11456        // No more slots should be shrunk
11457        assert_eq!(bank2.shrink_candidate_slots(), 0);
11458        // alive_counts represents the count of alive accounts in the three slots 0,1,2
11459        assert_eq!(alive_counts, vec![10, 1, 7]);
11460    }
11461
11462    #[test]
11463    fn test_process_stale_slot_with_budget() {
11464        gemachain_logger::setup();
11465
11466        let (genesis_config, _mint_keypair) = create_genesis_config(1_000_000_000);
11467        let pubkey1 = gemachain_sdk::pubkey::new_rand();
11468        let pubkey2 = gemachain_sdk::pubkey::new_rand();
11469
11470        let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));
11471        bank.restore_old_behavior_for_fragile_tests();
11472        assert_eq!(bank.process_stale_slot_with_budget(0, 0), 0);
11473        assert_eq!(bank.process_stale_slot_with_budget(133, 0), 133);
11474
11475        assert_eq!(bank.process_stale_slot_with_budget(0, 100), 0);
11476        assert_eq!(bank.process_stale_slot_with_budget(33, 100), 0);
11477        assert_eq!(bank.process_stale_slot_with_budget(133, 100), 33);
11478
11479        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank).unwrap());
11480
11481        bank.squash();
11482
11483        let some_carats = 123;
11484        let mut bank = Arc::new(new_from_parent(&bank));
11485        bank.deposit(&pubkey1, some_carats).unwrap();
11486        bank.deposit(&pubkey2, some_carats).unwrap();
11487
11488        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank).unwrap());
11489
11490        let mut bank = Arc::new(new_from_parent(&bank));
11491        bank.deposit(&pubkey1, some_carats).unwrap();
11492
11493        goto_end_of_slot(Arc::<Bank>::get_mut(&mut bank).unwrap());
11494
11495        bank.squash();
11496        bank.clean_accounts(false, false, None);
11497        let force_to_return_alive_account = 0;
11498        assert_eq!(
11499            bank.process_stale_slot_with_budget(22, force_to_return_alive_account),
11500            22
11501        );
11502
11503        let consumed_budgets: usize = (0..3)
11504            .map(|_| bank.process_stale_slot_with_budget(0, force_to_return_alive_account))
11505            .sum();
11506        // consumed_budgets represents the count of alive accounts in the three slots 0,1,2
11507        assert_eq!(consumed_budgets, 11);
11508    }
11509
11510    #[test]
11511    fn test_upgrade_epoch() {
11512        gemachain_logger::setup();
11513        let GenesisConfigInfo {
11514            mut genesis_config,
11515            mint_keypair,
11516            ..
11517        } = create_genesis_config_with_leader(500, &gemachain_sdk::pubkey::new_rand(), 0);
11518        genesis_config.fee_rate_governor = FeeRateGovernor::new(1, 0);
11519        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
11520        // Jump to the test-only upgrade epoch -- see `Bank::upgrade_epoch()`
11521        let bank = Bank::new_from_parent(
11522            &bank,
11523            &Pubkey::default(),
11524            genesis_config
11525                .epoch_schedule
11526                .get_first_slot_in_epoch(0xdead),
11527        );
11528
11529        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 500);
11530
11531        // Normal transfers are not allowed
11532        assert_eq!(
11533            bank.transfer(2, &mint_keypair, &mint_keypair.pubkey()),
11534            Err(TransactionError::ClusterMaintenance)
11535        );
11536        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 500); // no transaction fee charged
11537
11538        let vote_pubkey = gemachain_sdk::pubkey::new_rand();
11539        let authorized_voter = Keypair::new();
11540
11541        // VoteInstruction::Vote is allowed.  The transaction fails with a vote program instruction
11542        // error because the vote account is not actually setup
11543        let tx = Transaction::new_signed_with_payer(
11544            &[vote_instruction::vote(
11545                &vote_pubkey,
11546                &authorized_voter.pubkey(),
11547                Vote::new(vec![1], Hash::default()),
11548            )],
11549            Some(&mint_keypair.pubkey()),
11550            &[&mint_keypair, &authorized_voter],
11551            bank.last_blockhash(),
11552        );
11553        assert_eq!(
11554            bank.process_transaction(&tx),
11555            Err(TransactionError::InstructionError(
11556                0,
11557                InstructionError::InvalidAccountOwner
11558            ))
11559        );
11560        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 498); // transaction fee charged
11561
11562        // VoteInstruction::VoteSwitch is allowed.  The transaction fails with a vote program
11563        // instruction error because the vote account is not actually setup
11564        let tx = Transaction::new_signed_with_payer(
11565            &[vote_instruction::vote_switch(
11566                &vote_pubkey,
11567                &authorized_voter.pubkey(),
11568                Vote::new(vec![1], Hash::default()),
11569                Hash::default(),
11570            )],
11571            Some(&mint_keypair.pubkey()),
11572            &[&mint_keypair, &authorized_voter],
11573            bank.last_blockhash(),
11574        );
11575        assert_eq!(
11576            bank.process_transaction(&tx),
11577            Err(TransactionError::InstructionError(
11578                0,
11579                InstructionError::InvalidAccountOwner
11580            ))
11581        );
11582        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 496); // transaction fee charged
11583
11584        // Other vote program instructions, like VoteInstruction::UpdateCommission are not allowed
11585        let tx = Transaction::new_signed_with_payer(
11586            &[vote_instruction::update_commission(
11587                &vote_pubkey,
11588                &authorized_voter.pubkey(),
11589                123,
11590            )],
11591            Some(&mint_keypair.pubkey()),
11592            &[&mint_keypair, &authorized_voter],
11593            bank.last_blockhash(),
11594        );
11595        assert_eq!(
11596            bank.process_transaction(&tx),
11597            Err(TransactionError::ClusterMaintenance)
11598        );
11599        assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 496); // no transaction fee charged
11600    }
11601
11602    #[test]
11603    fn test_add_builtin_no_overwrite() {
11604        let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
11605
11606        #[allow(clippy::unnecessary_wraps)]
11607        fn mock_ix_processor(
11608            _pubkey: &Pubkey,
11609            _data: &[u8],
11610            _invoke_context: &mut dyn InvokeContext,
11611        ) -> std::result::Result<(), InstructionError> {
11612            Ok(())
11613        }
11614
11615        let slot = 123;
11616        let program_id = gemachain_sdk::pubkey::new_rand();
11617
11618        let mut bank = Arc::new(Bank::new_from_parent(
11619            &Arc::new(Bank::new_for_tests(&genesis_config)),
11620            &Pubkey::default(),
11621            slot,
11622        ));
11623        assert_eq!(bank.get_account_modified_slot(&program_id), None);
11624
11625        Arc::get_mut(&mut bank)
11626            .unwrap()
11627            .add_builtin("mock_program", program_id, mock_ix_processor);
11628        assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
11629
11630        let mut bank = Arc::new(new_from_parent(&bank));
11631        Arc::get_mut(&mut bank)
11632            .unwrap()
11633            .add_builtin("mock_program", program_id, mock_ix_processor);
11634        assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
11635
11636        Arc::get_mut(&mut bank).unwrap().replace_builtin(
11637            "mock_program v2",
11638            program_id,
11639            mock_ix_processor,
11640        );
11641        assert_eq!(
11642            bank.get_account_modified_slot(&program_id).unwrap().1,
11643            bank.slot()
11644        );
11645    }
11646
11647    #[test]
11648    fn test_add_builtin_loader_no_overwrite() {
11649        let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
11650
11651        #[allow(clippy::unnecessary_wraps)]
11652        fn mock_ix_processor(
11653            _pubkey: &Pubkey,
11654            _data: &[u8],
11655            _context: &mut dyn InvokeContext,
11656        ) -> std::result::Result<(), InstructionError> {
11657            Ok(())
11658        }
11659
11660        let slot = 123;
11661        let loader_id = gemachain_sdk::pubkey::new_rand();
11662
11663        let mut bank = Arc::new(Bank::new_from_parent(
11664            &Arc::new(Bank::new_for_tests(&genesis_config)),
11665            &Pubkey::default(),
11666            slot,
11667        ));
11668        assert_eq!(bank.get_account_modified_slot(&loader_id), None);
11669
11670        Arc::get_mut(&mut bank)
11671            .unwrap()
11672            .add_builtin("mock_program", loader_id, mock_ix_processor);
11673        assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
11674
11675        let mut bank = Arc::new(new_from_parent(&bank));
11676        Arc::get_mut(&mut bank)
11677            .unwrap()
11678            .add_builtin("mock_program", loader_id, mock_ix_processor);
11679        assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
11680    }
11681
11682    #[test]
11683    fn test_add_native_program() {
11684        let (mut genesis_config, _mint_keypair) = create_genesis_config(100_000);
11685        activate_all_features(&mut genesis_config);
11686
11687        let slot = 123;
11688        let program_id = gemachain_sdk::pubkey::new_rand();
11689
11690        let bank = Arc::new(Bank::new_from_parent(
11691            &Arc::new(Bank::new_for_tests(&genesis_config)),
11692            &Pubkey::default(),
11693            slot,
11694        ));
11695        assert_eq!(bank.get_account_modified_slot(&program_id), None);
11696
11697        assert_capitalization_diff(
11698            &bank,
11699            || bank.add_native_program("mock_program", &program_id, false),
11700            |old, new| {
11701                assert_eq!(old + 1, new);
11702            },
11703        );
11704
11705        assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
11706
11707        let bank = Arc::new(new_from_parent(&bank));
11708        assert_capitalization_diff(
11709            &bank,
11710            || bank.add_native_program("mock_program", &program_id, false),
11711            |old, new| assert_eq!(old, new),
11712        );
11713
11714        assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
11715
11716        let bank = Arc::new(new_from_parent(&bank));
11717        // When replacing native_program, name must change to disambiguate from repeated
11718        // invocations.
11719        assert_capitalization_diff(
11720            &bank,
11721            || bank.add_native_program("mock_program v2", &program_id, true),
11722            |old, new| assert_eq!(old, new),
11723        );
11724
11725        assert_eq!(
11726            bank.get_account_modified_slot(&program_id).unwrap().1,
11727            bank.slot()
11728        );
11729
11730        let bank = Arc::new(new_from_parent(&bank));
11731        assert_capitalization_diff(
11732            &bank,
11733            || bank.add_native_program("mock_program v2", &program_id, true),
11734            |old, new| assert_eq!(old, new),
11735        );
11736
11737        // replacing with same name shouldn't update account
11738        assert_eq!(
11739            bank.get_account_modified_slot(&program_id).unwrap().1,
11740            bank.parent_slot()
11741        );
11742    }
11743
11744    #[test]
11745    fn test_add_native_program_inherited_cap_while_replacing() {
11746        let (genesis_config, mint_keypair) = create_genesis_config(100_000);
11747        let bank = Bank::new_for_tests(&genesis_config);
11748        let program_id = gemachain_sdk::pubkey::new_rand();
11749
11750        bank.add_native_program("mock_program", &program_id, false);
11751        assert_eq!(bank.capitalization(), bank.calculate_capitalization(true));
11752
11753        // someone mess with program_id's balance
11754        bank.withdraw(&mint_keypair.pubkey(), 10).unwrap();
11755        assert_ne!(bank.capitalization(), bank.calculate_capitalization(true));
11756        bank.deposit(&program_id, 10).unwrap();
11757        assert_eq!(bank.capitalization(), bank.calculate_capitalization(true));
11758
11759        bank.add_native_program("mock_program v2", &program_id, true);
11760        assert_eq!(bank.capitalization(), bank.calculate_capitalization(true));
11761    }
11762
11763    #[test]
11764    fn test_add_native_program_squatted_while_not_replacing() {
11765        let (genesis_config, mint_keypair) = create_genesis_config(100_000);
11766        let bank = Bank::new_for_tests(&genesis_config);
11767        let program_id = gemachain_sdk::pubkey::new_rand();
11768
11769        // someone managed to squat at program_id!
11770        bank.withdraw(&mint_keypair.pubkey(), 10).unwrap();
11771        assert_ne!(bank.capitalization(), bank.calculate_capitalization(true));
11772        bank.deposit(&program_id, 10).unwrap();
11773        assert_eq!(bank.capitalization(), bank.calculate_capitalization(true));
11774
11775        bank.add_native_program("mock_program", &program_id, false);
11776        assert_eq!(bank.capitalization(), bank.calculate_capitalization(true));
11777    }
11778
11779    #[test]
11780    #[should_panic(
11781        expected = "Can't change frozen bank by adding not-existing new native \
11782                   program (mock_program, CiXgo2KHKSDmDnV1F6B69eWFgNAPiSBjjYvfB4cvRNre). \
11783                   Maybe, inconsistent program activation is detected on snapshot restore?"
11784    )]
11785    fn test_add_native_program_after_frozen() {
11786        use std::str::FromStr;
11787        let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
11788
11789        let slot = 123;
11790        let program_id = Pubkey::from_str("CiXgo2KHKSDmDnV1F6B69eWFgNAPiSBjjYvfB4cvRNre").unwrap();
11791
11792        let bank = Bank::new_from_parent(
11793            &Arc::new(Bank::new_for_tests(&genesis_config)),
11794            &Pubkey::default(),
11795            slot,
11796        );
11797        bank.freeze();
11798
11799        bank.add_native_program("mock_program", &program_id, false);
11800    }
11801
11802    #[test]
11803    #[should_panic(
11804        expected = "There is no account to replace with native program (mock_program, \
11805                    CiXgo2KHKSDmDnV1F6B69eWFgNAPiSBjjYvfB4cvRNre)."
11806    )]
11807    fn test_add_native_program_replace_none() {
11808        use std::str::FromStr;
11809        let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
11810
11811        let slot = 123;
11812        let program_id = Pubkey::from_str("CiXgo2KHKSDmDnV1F6B69eWFgNAPiSBjjYvfB4cvRNre").unwrap();
11813
11814        let bank = Bank::new_from_parent(
11815            &Arc::new(Bank::new_for_tests(&genesis_config)),
11816            &Pubkey::default(),
11817            slot,
11818        );
11819
11820        bank.add_native_program("mock_program", &program_id, true);
11821    }
11822
11823    #[test]
11824    fn test_reconfigure_token2_native_mint() {
11825        gemachain_logger::setup();
11826
11827        let mut genesis_config =
11828            create_genesis_config_with_leader(5, &gemachain_sdk::pubkey::new_rand(), 0).genesis_config;
11829
11830        // ClusterType::Development - Native mint exists immediately
11831        assert_eq!(genesis_config.cluster_type, ClusterType::Development);
11832        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
11833        assert_eq!(
11834            bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
11835            1000000000
11836        );
11837
11838        // Testnet - Native mint blinks into existence at epoch 93
11839        genesis_config.cluster_type = ClusterType::Testnet;
11840        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
11841        assert_eq!(
11842            bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
11843            0
11844        );
11845        bank.deposit(&inline_spl_token_v2_0::native_mint::id(), 4200000000)
11846            .unwrap();
11847
11848        let bank = Bank::new_from_parent(
11849            &bank,
11850            &Pubkey::default(),
11851            genesis_config.epoch_schedule.get_first_slot_in_epoch(93),
11852        );
11853
11854        let native_mint_account = bank
11855            .get_account(&inline_spl_token_v2_0::native_mint::id())
11856            .unwrap();
11857        assert_eq!(native_mint_account.data().len(), 82);
11858        assert_eq!(
11859            bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
11860            4200000000
11861        );
11862        assert_eq!(native_mint_account.owner(), &inline_spl_token_v2_0::id());
11863
11864        // MainnetBeta - Native mint blinks into existence at epoch 75
11865        genesis_config.cluster_type = ClusterType::MainnetBeta;
11866        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
11867        assert_eq!(
11868            bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
11869            0
11870        );
11871        bank.deposit(&inline_spl_token_v2_0::native_mint::id(), 4200000000)
11872            .unwrap();
11873
11874        let bank = Bank::new_from_parent(
11875            &bank,
11876            &Pubkey::default(),
11877            genesis_config.epoch_schedule.get_first_slot_in_epoch(75),
11878        );
11879
11880        let native_mint_account = bank
11881            .get_account(&inline_spl_token_v2_0::native_mint::id())
11882            .unwrap();
11883        assert_eq!(native_mint_account.data().len(), 82);
11884        assert_eq!(
11885            bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
11886            4200000000
11887        );
11888        assert_eq!(native_mint_account.owner(), &inline_spl_token_v2_0::id());
11889    }
11890
11891    #[test]
11892    fn test_ensure_no_storage_rewards_pool() {
11893        gemachain_logger::setup();
11894
11895        let mut genesis_config =
11896            create_genesis_config_with_leader(5, &gemachain_sdk::pubkey::new_rand(), 0).genesis_config;
11897
11898        // Testnet - Storage rewards pool is purged at epoch 93
11899        // Also this is with bad capitalization
11900        genesis_config.cluster_type = ClusterType::Testnet;
11901        genesis_config.inflation = Inflation::default();
11902        let reward_pubkey = gemachain_sdk::pubkey::new_rand();
11903        genesis_config.rewards_pools.insert(
11904            reward_pubkey,
11905            Account::new(u64::MAX, 0, &gemachain_sdk::pubkey::new_rand()),
11906        );
11907        let bank0 = Bank::new_for_tests(&genesis_config);
11908        // because capitalization has been reset with bogus capitalization calculation allowing overflows,
11909        // deliberately substract 1 carat to simulate it
11910        bank0.capitalization.fetch_sub(1, Relaxed);
11911        let bank0 = Arc::new(bank0);
11912        assert_eq!(bank0.get_balance(&reward_pubkey), u64::MAX,);
11913
11914        let bank1 = Bank::new_from_parent(
11915            &bank0,
11916            &Pubkey::default(),
11917            genesis_config.epoch_schedule.get_first_slot_in_epoch(93),
11918        );
11919
11920        // assert that everything gets in order....
11921        assert!(bank1.get_account(&reward_pubkey).is_none());
11922        let sysvar_and_native_program_delta = 1;
11923        assert_eq!(
11924            bank0.capitalization() + 1 + 1_000_000_000 + sysvar_and_native_program_delta,
11925            bank1.capitalization()
11926        );
11927        assert_eq!(bank1.capitalization(), bank1.calculate_capitalization(true));
11928
11929        // Depending on RUSTFLAGS, this test exposes rust's checked math behavior or not...
11930        // So do some convolted setup; anyway this test itself will just be temporary
11931        let bank0 = std::panic::AssertUnwindSafe(bank0);
11932        let overflowing_capitalization =
11933            std::panic::catch_unwind(|| bank0.calculate_capitalization(true));
11934        if let Ok(overflowing_capitalization) = overflowing_capitalization {
11935            info!("asserting overflowing capitalization for bank0");
11936            assert_eq!(overflowing_capitalization, bank0.capitalization());
11937        } else {
11938            info!("NOT-asserting overflowing capitalization for bank0");
11939        }
11940    }
11941
11942    #[derive(Debug)]
11943    struct TestExecutor {}
11944    impl Executor for TestExecutor {
11945        fn execute(
11946            &self,
11947            _loader_id: &Pubkey,
11948            _program_id: &Pubkey,
11949            _instruction_data: &[u8],
11950            _invoke_context: &mut dyn InvokeContext,
11951            _use_jit: bool,
11952        ) -> std::result::Result<(), InstructionError> {
11953            Ok(())
11954        }
11955    }
11956
11957    #[test]
11958    fn test_cached_executors() {
11959        let key1 = gemachain_sdk::pubkey::new_rand();
11960        let key2 = gemachain_sdk::pubkey::new_rand();
11961        let key3 = gemachain_sdk::pubkey::new_rand();
11962        let key4 = gemachain_sdk::pubkey::new_rand();
11963        let executor: Arc<dyn Executor> = Arc::new(TestExecutor {});
11964        let mut cache = CachedExecutors::new(3, 0);
11965
11966        cache.put(&key1, executor.clone());
11967        cache.put(&key2, executor.clone());
11968        cache.put(&key3, executor.clone());
11969        assert!(cache.get(&key1).is_some());
11970        assert!(cache.get(&key2).is_some());
11971        assert!(cache.get(&key3).is_some());
11972
11973        assert!(cache.get(&key1).is_some());
11974        assert!(cache.get(&key1).is_some());
11975        assert!(cache.get(&key2).is_some());
11976        cache.put(&key4, executor.clone());
11977        assert!(cache.get(&key1).is_some());
11978        assert!(cache.get(&key2).is_some());
11979        assert!(cache.get(&key3).is_none());
11980        assert!(cache.get(&key4).is_some());
11981
11982        assert!(cache.get(&key4).is_some());
11983        assert!(cache.get(&key4).is_some());
11984        assert!(cache.get(&key4).is_some());
11985        cache.put(&key3, executor.clone());
11986        assert!(cache.get(&key1).is_some());
11987        assert!(cache.get(&key2).is_none());
11988        assert!(cache.get(&key3).is_some());
11989        assert!(cache.get(&key4).is_some());
11990    }
11991
11992    #[test]
11993    fn test_cached_executors_eviction() {
11994        let key1 = gemachain_sdk::pubkey::new_rand();
11995        let key2 = gemachain_sdk::pubkey::new_rand();
11996        let key3 = gemachain_sdk::pubkey::new_rand();
11997        let key4 = gemachain_sdk::pubkey::new_rand();
11998        let executor: Arc<dyn Executor> = Arc::new(TestExecutor {});
11999        let mut cache = CachedExecutors::new(3, 0);
12000        assert!(cache.current_epoch == 0);
12001
12002        cache.put(&key1, executor.clone());
12003        cache.put(&key2, executor.clone());
12004        cache.put(&key3, executor.clone());
12005        assert!(cache.get(&key1).is_some());
12006        assert!(cache.get(&key1).is_some());
12007        assert!(cache.get(&key1).is_some());
12008
12009        cache = cache.clone_with_epoch(1);
12010        assert!(cache.current_epoch == 1);
12011
12012        assert!(cache.get(&key2).is_some());
12013        assert!(cache.get(&key2).is_some());
12014        assert!(cache.get(&key3).is_some());
12015        cache.put(&key4, executor.clone());
12016
12017        assert!(cache.get(&key4).is_some());
12018        assert!(cache.get(&key3).is_none());
12019
12020        cache = cache.clone_with_epoch(2);
12021        assert!(cache.current_epoch == 2);
12022
12023        cache.put(&key3, executor.clone());
12024        assert!(cache.get(&key3).is_some());
12025    }
12026
12027    #[test]
12028    fn test_bank_executor_cache() {
12029        gemachain_logger::setup();
12030
12031        let (genesis_config, _) = create_genesis_config(1);
12032        let bank = Bank::new_for_tests(&genesis_config);
12033
12034        let key1 = gemachain_sdk::pubkey::new_rand();
12035        let key2 = gemachain_sdk::pubkey::new_rand();
12036        let key3 = gemachain_sdk::pubkey::new_rand();
12037        let key4 = gemachain_sdk::pubkey::new_rand();
12038        let executor: Arc<dyn Executor> = Arc::new(TestExecutor {});
12039
12040        let message = Message {
12041            header: MessageHeader {
12042                num_required_signatures: 1,
12043                num_readonly_signed_accounts: 0,
12044                num_readonly_unsigned_accounts: 1,
12045            },
12046            account_keys: vec![key1, key2],
12047            recent_blockhash: Hash::default(),
12048            instructions: vec![],
12049        }
12050        .try_into()
12051        .unwrap();
12052
12053        let program_indices = &[vec![0, 1], vec![2]];
12054        let accounts = &[
12055            (key3, AccountSharedData::default()),
12056            (key4, AccountSharedData::default()),
12057            (key1, AccountSharedData::default()),
12058        ];
12059
12060        // don't do any work if not dirty
12061        let mut executors = Executors::default();
12062        executors.insert(key1, executor.clone());
12063        executors.insert(key2, executor.clone());
12064        executors.insert(key3, executor.clone());
12065        executors.insert(key4, executor.clone());
12066        let executors = Rc::new(RefCell::new(executors));
12067        executors.borrow_mut().is_dirty = false;
12068        bank.update_executors(executors);
12069        let executors = bank.get_executors(&message, accounts, program_indices);
12070        assert_eq!(executors.borrow().executors.len(), 0);
12071
12072        // do work
12073        let mut executors = Executors::default();
12074        executors.insert(key1, executor.clone());
12075        executors.insert(key2, executor.clone());
12076        executors.insert(key3, executor.clone());
12077        executors.insert(key4, executor.clone());
12078        let executors = Rc::new(RefCell::new(executors));
12079        bank.update_executors(executors);
12080        let executors = bank.get_executors(&message, accounts, program_indices);
12081        assert_eq!(executors.borrow().executors.len(), 4);
12082        assert!(executors.borrow().executors.contains_key(&key1));
12083        assert!(executors.borrow().executors.contains_key(&key2));
12084        assert!(executors.borrow().executors.contains_key(&key3));
12085        assert!(executors.borrow().executors.contains_key(&key4));
12086
12087        // Check inheritance
12088        let bank = Bank::new_from_parent(&Arc::new(bank), &gemachain_sdk::pubkey::new_rand(), 1);
12089        let executors = bank.get_executors(&message, accounts, program_indices);
12090        assert_eq!(executors.borrow().executors.len(), 4);
12091        assert!(executors.borrow().executors.contains_key(&key1));
12092        assert!(executors.borrow().executors.contains_key(&key2));
12093        assert!(executors.borrow().executors.contains_key(&key3));
12094        assert!(executors.borrow().executors.contains_key(&key4));
12095
12096        bank.remove_executor(&key1);
12097        bank.remove_executor(&key2);
12098        bank.remove_executor(&key3);
12099        bank.remove_executor(&key4);
12100        let executors = bank.get_executors(&message, accounts, program_indices);
12101        assert_eq!(executors.borrow().executors.len(), 0);
12102        assert!(!executors.borrow().executors.contains_key(&key1));
12103        assert!(!executors.borrow().executors.contains_key(&key2));
12104        assert!(!executors.borrow().executors.contains_key(&key3));
12105        assert!(!executors.borrow().executors.contains_key(&key4));
12106    }
12107
12108    #[test]
12109    fn test_bank_executor_cow() {
12110        gemachain_logger::setup();
12111
12112        let (genesis_config, _) = create_genesis_config(1);
12113        let root = Arc::new(Bank::new_for_tests(&genesis_config));
12114
12115        let key1 = gemachain_sdk::pubkey::new_rand();
12116        let key2 = gemachain_sdk::pubkey::new_rand();
12117        let executor: Arc<dyn Executor> = Arc::new(TestExecutor {});
12118        let message =
12119            SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap();
12120
12121        let program_indices = &[vec![0, 1]];
12122        let accounts = &[
12123            (key1, AccountSharedData::default()),
12124            (key2, AccountSharedData::default()),
12125        ];
12126
12127        // add one to root bank
12128        let mut executors = Executors::default();
12129        executors.insert(key1, executor.clone());
12130        let executors = Rc::new(RefCell::new(executors));
12131        root.update_executors(executors);
12132        let executors = root.get_executors(&message, accounts, program_indices);
12133        assert_eq!(executors.borrow().executors.len(), 1);
12134
12135        let fork1 = Bank::new_from_parent(&root, &Pubkey::default(), 1);
12136        let fork2 = Bank::new_from_parent(&root, &Pubkey::default(), 1);
12137
12138        let executors = fork1.get_executors(&message, accounts, program_indices);
12139        assert_eq!(executors.borrow().executors.len(), 1);
12140        let executors = fork2.get_executors(&message, accounts, program_indices);
12141        assert_eq!(executors.borrow().executors.len(), 1);
12142
12143        let mut executors = Executors::default();
12144        executors.insert(key2, executor.clone());
12145        let executors = Rc::new(RefCell::new(executors));
12146        fork1.update_executors(executors);
12147
12148        let executors = fork1.get_executors(&message, accounts, program_indices);
12149        assert_eq!(executors.borrow().executors.len(), 2);
12150        let executors = fork2.get_executors(&message, accounts, program_indices);
12151        assert_eq!(executors.borrow().executors.len(), 1);
12152
12153        fork1.remove_executor(&key1);
12154
12155        let executors = fork1.get_executors(&message, accounts, program_indices);
12156        assert_eq!(executors.borrow().executors.len(), 1);
12157        let executors = fork2.get_executors(&message, accounts, program_indices);
12158        assert_eq!(executors.borrow().executors.len(), 1);
12159    }
12160
12161    #[test]
12162    fn test_compute_active_feature_set() {
12163        let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
12164        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
12165        let mut bank = Bank::new_from_parent(&bank0, &Pubkey::default(), 1);
12166
12167        let test_feature = "TestFeature11111111111111111111111111111111"
12168            .parse::<Pubkey>()
12169            .unwrap();
12170        let mut feature_set = FeatureSet::default();
12171        feature_set.inactive.insert(test_feature);
12172        bank.feature_set = Arc::new(feature_set.clone());
12173
12174        let new_activations = bank.compute_active_feature_set(true);
12175        assert!(new_activations.is_empty());
12176        assert!(!bank.feature_set.is_active(&test_feature));
12177
12178        // Depositing into the `test_feature` account should do nothing
12179        bank.deposit(&test_feature, 42).unwrap();
12180        let new_activations = bank.compute_active_feature_set(true);
12181        assert!(new_activations.is_empty());
12182        assert!(!bank.feature_set.is_active(&test_feature));
12183
12184        // Request `test_feature` activation
12185        let feature = Feature::default();
12186        assert_eq!(feature.activated_at, None);
12187        bank.store_account(&test_feature, &feature::create_account(&feature, 42));
12188
12189        // Run `compute_active_feature_set` disallowing new activations
12190        let new_activations = bank.compute_active_feature_set(false);
12191        assert!(new_activations.is_empty());
12192        assert!(!bank.feature_set.is_active(&test_feature));
12193        let feature = feature::from_account(&bank.get_account(&test_feature).expect("get_account"))
12194            .expect("from_account");
12195        assert_eq!(feature.activated_at, None);
12196
12197        // Run `compute_active_feature_set` allowing new activations
12198        let new_activations = bank.compute_active_feature_set(true);
12199        assert_eq!(new_activations.len(), 1);
12200        assert!(bank.feature_set.is_active(&test_feature));
12201        let feature = feature::from_account(&bank.get_account(&test_feature).expect("get_account"))
12202            .expect("from_account");
12203        assert_eq!(feature.activated_at, Some(1));
12204
12205        // Reset the bank's feature set
12206        bank.feature_set = Arc::new(feature_set);
12207        assert!(!bank.feature_set.is_active(&test_feature));
12208
12209        // Running `compute_active_feature_set` will not cause new activations, but
12210        // `test_feature` is now be active
12211        let new_activations = bank.compute_active_feature_set(true);
12212        assert!(new_activations.is_empty());
12213        assert!(bank.feature_set.is_active(&test_feature));
12214    }
12215
12216    #[test]
12217    fn test_spl_token_v2_replacement() {
12218        let (genesis_config, _mint_keypair) = create_genesis_config(0);
12219        let mut bank = Bank::new_for_tests(&genesis_config);
12220
12221        // Setup original token account
12222        bank.store_account_and_update_capitalization(
12223            &inline_spl_token_v2_0::id(),
12224            &AccountSharedData::from(Account {
12225                carats: 100,
12226                ..Account::default()
12227            }),
12228        );
12229        assert_eq!(bank.get_balance(&inline_spl_token_v2_0::id()), 100);
12230
12231        // Setup new token account
12232        let new_token_account = AccountSharedData::from(Account {
12233            carats: 123,
12234            ..Account::default()
12235        });
12236        bank.store_account_and_update_capitalization(
12237            &inline_spl_token_v2_0::new_token_program::id(),
12238            &new_token_account,
12239        );
12240        assert_eq!(
12241            bank.get_balance(&inline_spl_token_v2_0::new_token_program::id()),
12242            123
12243        );
12244
12245        let original_capitalization = bank.capitalization();
12246
12247        bank.apply_spl_token_v2_set_authority_fix();
12248
12249        // New token account is now empty
12250        assert_eq!(
12251            bank.get_balance(&inline_spl_token_v2_0::new_token_program::id()),
12252            0
12253        );
12254
12255        // Old token account holds the new token account
12256        assert_eq!(
12257            bank.get_account(&inline_spl_token_v2_0::id()),
12258            Some(new_token_account)
12259        );
12260
12261        // Carats in the old token account were burnt
12262        assert_eq!(bank.capitalization(), original_capitalization - 100);
12263    }
12264
12265    pub fn update_vote_account_timestamp(
12266        timestamp: BlockTimestamp,
12267        bank: &Bank,
12268        vote_pubkey: &Pubkey,
12269    ) {
12270        let mut vote_account = bank.get_account(vote_pubkey).unwrap_or_default();
12271        let mut vote_state = VoteState::from(&vote_account).unwrap_or_default();
12272        vote_state.last_timestamp = timestamp;
12273        let versioned = VoteStateVersions::new_current(vote_state);
12274        VoteState::to(&versioned, &mut vote_account).unwrap();
12275        bank.store_account(vote_pubkey, &vote_account);
12276    }
12277
12278    fn min_rent_excempt_balance_for_sysvars(bank: &Bank, sysvar_ids: &[Pubkey]) -> u64 {
12279        sysvar_ids
12280            .iter()
12281            .map(|sysvar_id| {
12282                trace!("min_rent_excempt_balance_for_sysvars: {}", sysvar_id);
12283                bank.get_minimum_balance_for_rent_exemption(
12284                    bank.get_account(sysvar_id).unwrap().data().len(),
12285                )
12286            })
12287            .sum()
12288    }
12289
12290    fn expected_cap_delta_after_sysvar_reset(bank: &Bank, sysvar_ids: &[Pubkey]) -> u64 {
12291        min_rent_excempt_balance_for_sysvars(bank, sysvar_ids) - sysvar_ids.len() as u64
12292    }
12293
12294    #[test]
12295    fn test_adjust_sysvar_balance_for_rent() {
12296        let (genesis_config, _mint_keypair) = create_genesis_config(0);
12297        let bank = Bank::new_for_tests(&genesis_config);
12298        let mut smaller_sample_sysvar = bank.get_account(&sysvar::clock::id()).unwrap();
12299        assert_eq!(smaller_sample_sysvar.carats(), 1);
12300        bank.adjust_sysvar_balance_for_rent(&mut smaller_sample_sysvar);
12301        assert_eq!(
12302            smaller_sample_sysvar.carats(),
12303            bank.get_minimum_balance_for_rent_exemption(smaller_sample_sysvar.data().len()),
12304        );
12305
12306        let mut bigger_sample_sysvar = AccountSharedData::new(
12307            1,
12308            smaller_sample_sysvar.data().len() + 1,
12309            &Pubkey::default(),
12310        );
12311        bank.adjust_sysvar_balance_for_rent(&mut bigger_sample_sysvar);
12312        assert!(smaller_sample_sysvar.carats() < bigger_sample_sysvar.carats());
12313
12314        // excess carats shouldn't be reduced by adjust_sysvar_balance_for_rent()
12315        let excess_carats = smaller_sample_sysvar.carats() + 999;
12316        smaller_sample_sysvar.set_carats(excess_carats);
12317        bank.adjust_sysvar_balance_for_rent(&mut smaller_sample_sysvar);
12318        assert_eq!(smaller_sample_sysvar.carats(), excess_carats);
12319    }
12320
12321    // this test can be removed after rent_for_sysvars activation on mainnet-beta
12322    #[test]
12323    fn test_no_deletion_due_to_rent_upon_rent_for_sysvar_activation() {
12324        gemachain_logger::setup();
12325
12326        let (mut genesis_config, _mint_keypair) = create_genesis_config(0);
12327        let feature_balance =
12328            std::cmp::max(genesis_config.rent.minimum_balance(Feature::size_of()), 1);
12329
12330        // activate all features but rent_for_sysvars
12331        activate_all_features(&mut genesis_config);
12332        genesis_config
12333            .accounts
12334            .remove(&feature_set::rent_for_sysvars::id());
12335        let bank0 = Bank::new_for_tests(&genesis_config);
12336        let bank1 = Arc::new(new_from_parent(&Arc::new(bank0)));
12337
12338        // schedule activation of simple capitalization
12339        bank1.store_account_and_update_capitalization(
12340            &feature_set::rent_for_sysvars::id(),
12341            &feature::create_account(&Feature { activated_at: None }, feature_balance),
12342        );
12343
12344        let bank2 =
12345            Bank::new_from_parent(&bank1, &Pubkey::default(), bank1.first_slot_in_next_epoch());
12346        assert_eq!(bank2.get_program_accounts(&sysvar::id()).unwrap().len(), 8);
12347
12348        // force rent collection for sysvars
12349        bank2.collect_rent_in_partition((0, 0, 1)); // all range
12350
12351        // no sysvar should be deleted due to rent
12352        assert_eq!(bank2.get_program_accounts(&sysvar::id()).unwrap().len(), 8);
12353    }
12354
12355    // this test can be removed after rent_for_sysvars activation on mainnet-beta
12356    #[test]
12357    fn test_rent_for_sysvars_adjustment_minimum_genesis_set() {
12358        gemachain_logger::setup();
12359
12360        let (mut genesis_config, _mint_keypair) = create_genesis_config(0);
12361        let feature_balance =
12362            std::cmp::max(genesis_config.rent.minimum_balance(Feature::size_of()), 1);
12363
12364        // inhibit deprecated rewards sysvar creation altogether
12365        genesis_config.accounts.insert(
12366            feature_set::deprecate_rewards_sysvar::id(),
12367            Account::from(feature::create_account(
12368                &Feature {
12369                    activated_at: Some(0),
12370                },
12371                feature_balance,
12372            )),
12373        );
12374
12375        let bank0 = Bank::new_for_tests(&genesis_config);
12376        let bank1 = Arc::new(new_from_parent(&Arc::new(bank0)));
12377
12378        // schedule activation of rent_for_sysvars
12379        bank1.store_account_and_update_capitalization(
12380            &feature_set::rent_for_sysvars::id(),
12381            &feature::create_account(&Feature { activated_at: None }, feature_balance),
12382        );
12383
12384        {
12385            let sysvars = bank1.get_program_accounts(&sysvar::id()).unwrap();
12386            assert_eq!(sysvars.len(), 8);
12387            assert!(sysvars
12388                .iter()
12389                .map(|(_pubkey, account)| account.carats())
12390                .all(|carats| carats == 1));
12391        }
12392
12393        // 8 sysvars should be reset by reset_all_sysvar_balances()
12394        let bank2 = assert_capitalization_diff_with_new_bank(
12395            &bank1,
12396            || Bank::new_from_parent(&bank1, &Pubkey::default(), bank1.first_slot_in_next_epoch()),
12397            |old, new| {
12398                assert_eq!(
12399                    old + expected_cap_delta_after_sysvar_reset(
12400                        &bank1,
12401                        &[
12402                            sysvar::clock::id(),
12403                            sysvar::epoch_schedule::id(),
12404                            #[allow(deprecated)]
12405                            sysvar::fees::id(),
12406                            #[allow(deprecated)]
12407                            sysvar::recent_blockhashes::id(),
12408                            sysvar::rent::id(),
12409                            sysvar::slot_hashes::id(),
12410                            sysvar::slot_history::id(),
12411                            sysvar::stake_history::id(),
12412                        ]
12413                    ),
12414                    new
12415                )
12416            },
12417        );
12418
12419        {
12420            let sysvars = bank2.get_program_accounts(&sysvar::id()).unwrap();
12421            assert_eq!(sysvars.len(), 8);
12422            assert!(sysvars
12423                .iter()
12424                .map(|(_pubkey, account)| account.carats())
12425                .all(|carats| carats > 1));
12426        }
12427    }
12428
12429    // this test can be removed after rent_for_sysvars activation on mainnet-beta
12430    #[test]
12431    fn test_rent_for_sysvars_adjustment_full_set() {
12432        gemachain_logger::setup();
12433
12434        let (mut genesis_config, _mint_keypair) = create_genesis_config(0);
12435        let feature_balance =
12436            std::cmp::max(genesis_config.rent.minimum_balance(Feature::size_of()), 1);
12437
12438        // activate all features but rent_for_sysvars
12439        activate_all_features(&mut genesis_config);
12440        genesis_config
12441            .accounts
12442            .remove(&feature_set::rent_for_sysvars::id());
12443        // intentionally create deprecated rewards sysvar creation
12444        genesis_config
12445            .accounts
12446            .remove(&feature_set::deprecate_rewards_sysvar::id());
12447
12448        // intentionally create bogus native programs
12449        #[allow(clippy::unnecessary_wraps)]
12450        fn mock_process_instruction(
12451            _program_id: &Pubkey,
12452            _data: &[u8],
12453            _invoke_context: &mut dyn InvokeContext,
12454        ) -> std::result::Result<(), gemachain_sdk::instruction::InstructionError> {
12455            Ok(())
12456        }
12457        let builtins = Builtins {
12458            genesis_builtins: vec![
12459                Builtin::new(
12460                    "mock bpf",
12461                    gemachain_sdk::bpf_loader::id(),
12462                    mock_process_instruction,
12463                ),
12464                Builtin::new(
12465                    "mock bpf",
12466                    gemachain_sdk::bpf_loader_deprecated::id(),
12467                    mock_process_instruction,
12468                ),
12469            ],
12470            feature_builtins: (vec![]),
12471        };
12472
12473        let bank0 = Arc::new(Bank::new_with_paths_for_tests(
12474            &genesis_config,
12475            Vec::new(),
12476            &[],
12477            None,
12478            Some(&builtins),
12479            AccountSecondaryIndexes::default(),
12480            false,
12481            AccountShrinkThreshold::default(),
12482            false,
12483        ));
12484        // move to next epoch to create now deprecated rewards sysvar intentionally
12485        let bank1 = Arc::new(Bank::new_from_parent(
12486            &bank0,
12487            &Pubkey::default(),
12488            bank0.first_slot_in_next_epoch(),
12489        ));
12490
12491        // schedule activation of simple capitalization
12492        bank1.store_account_and_update_capitalization(
12493            &feature_set::rent_for_sysvars::id(),
12494            &feature::create_account(&Feature { activated_at: None }, feature_balance),
12495        );
12496        {
12497            let sysvars = bank1.get_program_accounts(&sysvar::id()).unwrap();
12498            assert_eq!(sysvars.len(), 9);
12499            assert!(sysvars
12500                .iter()
12501                .map(|(_pubkey, account)| account.carats())
12502                .all(|carats| carats == 1));
12503        }
12504
12505        // 9 sysvars should be reset by reset_all_sysvar_balances()
12506        let bank2 = assert_capitalization_diff_with_new_bank(
12507            &bank1,
12508            || Bank::new_from_parent(&bank1, &Pubkey::default(), bank1.first_slot_in_next_epoch()),
12509            |old, new| {
12510                assert_eq!(
12511                    old + expected_cap_delta_after_sysvar_reset(
12512                        &bank1,
12513                        &[
12514                            sysvar::clock::id(),
12515                            sysvar::epoch_schedule::id(),
12516                            #[allow(deprecated)]
12517                            sysvar::fees::id(),
12518                            #[allow(deprecated)]
12519                            sysvar::recent_blockhashes::id(),
12520                            sysvar::rent::id(),
12521                            sysvar::rewards::id(),
12522                            sysvar::slot_hashes::id(),
12523                            sysvar::slot_history::id(),
12524                            sysvar::stake_history::id(),
12525                        ]
12526                    ),
12527                    new
12528                )
12529            },
12530        );
12531        {
12532            let sysvars = bank2.get_program_accounts(&sysvar::id()).unwrap();
12533            assert_eq!(sysvars.len(), 9);
12534            assert!(sysvars
12535                .iter()
12536                .map(|(_pubkey, account)| account.carats())
12537                .all(|carats| carats > 1));
12538        }
12539    }
12540
12541    #[test]
12542    fn test_update_clock_timestamp() {
12543        let leader_pubkey = gemachain_sdk::pubkey::new_rand();
12544        let GenesisConfigInfo {
12545            genesis_config,
12546            voting_keypair,
12547            ..
12548        } = create_genesis_config_with_leader(5, &leader_pubkey, 3);
12549        let mut bank = Bank::new_for_tests(&genesis_config);
12550        // Advance past slot 0, which has special handling.
12551        bank = new_from_parent(&Arc::new(bank));
12552        bank = new_from_parent(&Arc::new(bank));
12553        assert_eq!(
12554            bank.clock().unix_timestamp,
12555            bank.unix_timestamp_from_genesis()
12556        );
12557
12558        bank.update_clock(None);
12559        assert_eq!(
12560            bank.clock().unix_timestamp,
12561            bank.unix_timestamp_from_genesis()
12562        );
12563
12564        update_vote_account_timestamp(
12565            BlockTimestamp {
12566                slot: bank.slot(),
12567                timestamp: bank.unix_timestamp_from_genesis() - 1,
12568            },
12569            &bank,
12570            &voting_keypair.pubkey(),
12571        );
12572        bank.update_clock(None);
12573        assert_eq!(
12574            bank.clock().unix_timestamp,
12575            bank.unix_timestamp_from_genesis()
12576        );
12577
12578        update_vote_account_timestamp(
12579            BlockTimestamp {
12580                slot: bank.slot(),
12581                timestamp: bank.unix_timestamp_from_genesis(),
12582            },
12583            &bank,
12584            &voting_keypair.pubkey(),
12585        );
12586        bank.update_clock(None);
12587        assert_eq!(
12588            bank.clock().unix_timestamp,
12589            bank.unix_timestamp_from_genesis()
12590        );
12591
12592        update_vote_account_timestamp(
12593            BlockTimestamp {
12594                slot: bank.slot(),
12595                timestamp: bank.unix_timestamp_from_genesis() + 1,
12596            },
12597            &bank,
12598            &voting_keypair.pubkey(),
12599        );
12600        bank.update_clock(None);
12601        assert_eq!(
12602            bank.clock().unix_timestamp,
12603            bank.unix_timestamp_from_genesis() + 1
12604        );
12605
12606        // Timestamp cannot go backward from ancestor Bank to child
12607        bank = new_from_parent(&Arc::new(bank));
12608        update_vote_account_timestamp(
12609            BlockTimestamp {
12610                slot: bank.slot(),
12611                timestamp: bank.unix_timestamp_from_genesis() - 1,
12612            },
12613            &bank,
12614            &voting_keypair.pubkey(),
12615        );
12616        bank.update_clock(None);
12617        assert_eq!(
12618            bank.clock().unix_timestamp,
12619            bank.unix_timestamp_from_genesis()
12620        );
12621    }
12622
12623    fn poh_estimate_offset(bank: &Bank) -> Duration {
12624        let mut epoch_start_slot = bank.epoch_schedule.get_first_slot_in_epoch(bank.epoch());
12625        if epoch_start_slot == bank.slot() {
12626            epoch_start_slot = bank
12627                .epoch_schedule
12628                .get_first_slot_in_epoch(bank.epoch() - 1);
12629        }
12630        bank.slot().saturating_sub(epoch_start_slot) as u32
12631            * Duration::from_nanos(bank.ns_per_slot as u64)
12632    }
12633
12634    #[test]
12635    fn test_warp_timestamp_again_feature_slow() {
12636        fn max_allowable_delta_since_epoch(bank: &Bank, max_allowable_drift: u32) -> i64 {
12637            let poh_estimate_offset = poh_estimate_offset(bank);
12638            (poh_estimate_offset.as_secs()
12639                + (poh_estimate_offset * max_allowable_drift / 100).as_secs()) as i64
12640        }
12641
12642        let leader_pubkey = gemachain_sdk::pubkey::new_rand();
12643        let GenesisConfigInfo {
12644            mut genesis_config,
12645            voting_keypair,
12646            ..
12647        } = create_genesis_config_with_leader(5, &leader_pubkey, 3);
12648        let slots_in_epoch = 32;
12649        genesis_config
12650            .accounts
12651            .remove(&feature_set::warp_timestamp_again::id())
12652            .unwrap();
12653        genesis_config.epoch_schedule = EpochSchedule::new(slots_in_epoch);
12654        let mut bank = Bank::new_for_tests(&genesis_config);
12655
12656        let recent_timestamp: UnixTimestamp = bank.unix_timestamp_from_genesis();
12657        let additional_secs = 8; // Greater than MAX_ALLOWABLE_DRIFT_PERCENTAGE for full epoch
12658        update_vote_account_timestamp(
12659            BlockTimestamp {
12660                slot: bank.slot(),
12661                timestamp: recent_timestamp + additional_secs,
12662            },
12663            &bank,
12664            &voting_keypair.pubkey(),
12665        );
12666
12667        // additional_secs greater than MAX_ALLOWABLE_DRIFT_PERCENTAGE for an epoch
12668        // timestamp bounded to 50% deviation
12669        for _ in 0..31 {
12670            bank = new_from_parent(&Arc::new(bank));
12671            assert_eq!(
12672                bank.clock().unix_timestamp,
12673                bank.clock().epoch_start_timestamp
12674                    + max_allowable_delta_since_epoch(&bank, MAX_ALLOWABLE_DRIFT_PERCENTAGE),
12675            );
12676            assert_eq!(bank.clock().epoch_start_timestamp, recent_timestamp);
12677        }
12678
12679        // Request `warp_timestamp_again` activation
12680        let feature = Feature { activated_at: None };
12681        bank.store_account(
12682            &feature_set::warp_timestamp_again::id(),
12683            &feature::create_account(&feature, 42),
12684        );
12685        let previous_epoch_timestamp = bank.clock().epoch_start_timestamp;
12686        let previous_timestamp = bank.clock().unix_timestamp;
12687
12688        // Advance to epoch boundary to activate; time is warped to estimate with no bounding
12689        bank = new_from_parent(&Arc::new(bank));
12690        assert_ne!(bank.clock().epoch_start_timestamp, previous_timestamp);
12691        assert!(
12692            bank.clock().epoch_start_timestamp
12693                > previous_epoch_timestamp
12694                    + max_allowable_delta_since_epoch(&bank, MAX_ALLOWABLE_DRIFT_PERCENTAGE)
12695        );
12696
12697        // Refresh vote timestamp
12698        let recent_timestamp: UnixTimestamp = bank.clock().unix_timestamp;
12699        let additional_secs = 8;
12700        update_vote_account_timestamp(
12701            BlockTimestamp {
12702                slot: bank.slot(),
12703                timestamp: recent_timestamp + additional_secs,
12704            },
12705            &bank,
12706            &voting_keypair.pubkey(),
12707        );
12708
12709        // additional_secs greater than MAX_ALLOWABLE_DRIFT_PERCENTAGE for 22 slots
12710        // timestamp bounded to 80% deviation
12711        for _ in 0..23 {
12712            bank = new_from_parent(&Arc::new(bank));
12713            assert_eq!(
12714                bank.clock().unix_timestamp,
12715                bank.clock().epoch_start_timestamp
12716                    + max_allowable_delta_since_epoch(&bank, MAX_ALLOWABLE_DRIFT_PERCENTAGE_SLOW),
12717            );
12718            assert_eq!(bank.clock().epoch_start_timestamp, recent_timestamp);
12719        }
12720        for _ in 0..8 {
12721            bank = new_from_parent(&Arc::new(bank));
12722            assert_eq!(
12723                bank.clock().unix_timestamp,
12724                bank.clock().epoch_start_timestamp
12725                    + poh_estimate_offset(&bank).as_secs() as i64
12726                    + additional_secs,
12727            );
12728            assert_eq!(bank.clock().epoch_start_timestamp, recent_timestamp);
12729        }
12730    }
12731
12732    #[test]
12733    fn test_timestamp_fast() {
12734        fn max_allowable_delta_since_epoch(bank: &Bank, max_allowable_drift: u32) -> i64 {
12735            let poh_estimate_offset = poh_estimate_offset(bank);
12736            (poh_estimate_offset.as_secs()
12737                - (poh_estimate_offset * max_allowable_drift / 100).as_secs()) as i64
12738        }
12739
12740        let leader_pubkey = gemachain_sdk::pubkey::new_rand();
12741        let GenesisConfigInfo {
12742            mut genesis_config,
12743            voting_keypair,
12744            ..
12745        } = create_genesis_config_with_leader(5, &leader_pubkey, 3);
12746        let slots_in_epoch = 32;
12747        genesis_config.epoch_schedule = EpochSchedule::new(slots_in_epoch);
12748        let mut bank = Bank::new_for_tests(&genesis_config);
12749
12750        let recent_timestamp: UnixTimestamp = bank.unix_timestamp_from_genesis();
12751        let additional_secs = 5; // Greater than MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST for full epoch
12752        update_vote_account_timestamp(
12753            BlockTimestamp {
12754                slot: bank.slot(),
12755                timestamp: recent_timestamp - additional_secs,
12756            },
12757            &bank,
12758            &voting_keypair.pubkey(),
12759        );
12760
12761        // additional_secs greater than MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST for an epoch
12762        // timestamp bounded to 25% deviation
12763        for _ in 0..31 {
12764            bank = new_from_parent(&Arc::new(bank));
12765            assert_eq!(
12766                bank.clock().unix_timestamp,
12767                bank.clock().epoch_start_timestamp
12768                    + max_allowable_delta_since_epoch(&bank, MAX_ALLOWABLE_DRIFT_PERCENTAGE_FAST),
12769            );
12770            assert_eq!(bank.clock().epoch_start_timestamp, recent_timestamp);
12771        }
12772    }
12773
12774    #[test]
12775    fn test_program_is_native_loader() {
12776        let (genesis_config, mint_keypair) = create_genesis_config(50000);
12777        let bank = Bank::new_for_tests(&genesis_config);
12778
12779        let tx = Transaction::new_signed_with_payer(
12780            &[Instruction::new_with_bincode(
12781                native_loader::id(),
12782                &(),
12783                vec![],
12784            )],
12785            Some(&mint_keypair.pubkey()),
12786            &[&mint_keypair],
12787            bank.last_blockhash(),
12788        );
12789        assert_eq!(
12790            bank.process_transaction(&tx),
12791            Err(TransactionError::InstructionError(
12792                0,
12793                InstructionError::UnsupportedProgramId
12794            ))
12795        );
12796    }
12797
12798    #[test]
12799    fn test_bad_native_loader() {
12800        let (genesis_config, mint_keypair) = create_genesis_config(50000);
12801        let bank = Bank::new_for_tests(&genesis_config);
12802        let to_keypair = Keypair::new();
12803
12804        let tx = Transaction::new_signed_with_payer(
12805            &[
12806                system_instruction::create_account(
12807                    &mint_keypair.pubkey(),
12808                    &to_keypair.pubkey(),
12809                    10000,
12810                    0,
12811                    &native_loader::id(),
12812                ),
12813                Instruction::new_with_bincode(
12814                    native_loader::id(),
12815                    &(),
12816                    vec![AccountMeta::new(to_keypair.pubkey(), false)],
12817                ),
12818            ],
12819            Some(&mint_keypair.pubkey()),
12820            &[&mint_keypair, &to_keypair],
12821            bank.last_blockhash(),
12822        );
12823        assert_eq!(
12824            bank.process_transaction(&tx),
12825            Err(TransactionError::InstructionError(
12826                1,
12827                InstructionError::Custom(NativeLoaderError::InvalidAccountData as u32)
12828            ))
12829        );
12830
12831        let tx = Transaction::new_signed_with_payer(
12832            &[
12833                system_instruction::create_account(
12834                    &mint_keypair.pubkey(),
12835                    &to_keypair.pubkey(),
12836                    10000,
12837                    100,
12838                    &native_loader::id(),
12839                ),
12840                Instruction::new_with_bincode(
12841                    native_loader::id(),
12842                    &(),
12843                    vec![AccountMeta::new(to_keypair.pubkey(), false)],
12844                ),
12845            ],
12846            Some(&mint_keypair.pubkey()),
12847            &[&mint_keypair, &to_keypair],
12848            bank.last_blockhash(),
12849        );
12850        assert_eq!(
12851            bank.process_transaction(&tx),
12852            Err(TransactionError::InstructionError(
12853                1,
12854                InstructionError::Custom(NativeLoaderError::InvalidAccountData as u32)
12855            ))
12856        );
12857    }
12858
12859    #[test]
12860    fn test_debug_bank() {
12861        let (genesis_config, _mint_keypair) = create_genesis_config(50000);
12862        let mut bank = Bank::new_for_tests(&genesis_config);
12863        bank.finish_init(&genesis_config, None, false);
12864        let debug = format!("{:#?}", bank);
12865        assert!(!debug.is_empty());
12866    }
12867
12868    #[derive(Debug)]
12869    enum AcceptableScanResults {
12870        DroppedSlotError,
12871        NoFailure,
12872        Both,
12873    }
12874
12875    fn test_store_scan_consistency<F: 'static>(
12876        accounts_db_caching_enabled: bool,
12877        update_f: F,
12878        drop_callback: Option<Box<dyn DropCallback + Send + Sync>>,
12879        acceptable_scan_results: AcceptableScanResults,
12880    ) where
12881        F: Fn(
12882                Arc<Bank>,
12883                crossbeam_channel::Sender<Arc<Bank>>,
12884                crossbeam_channel::Receiver<BankId>,
12885                Arc<HashSet<Pubkey>>,
12886                Pubkey,
12887                u64,
12888            ) + std::marker::Send,
12889    {
12890        gemachain_logger::setup();
12891        // Set up initial bank
12892        let mut genesis_config = create_genesis_config_with_leader(
12893            10,
12894            &gemachain_sdk::pubkey::new_rand(),
12895            374_999_998_287_840,
12896        )
12897        .genesis_config;
12898        genesis_config.rent = Rent::free();
12899        let bank0 = Arc::new(Bank::new_with_config(
12900            &genesis_config,
12901            AccountSecondaryIndexes::default(),
12902            accounts_db_caching_enabled,
12903            AccountShrinkThreshold::default(),
12904        ));
12905        bank0.set_callback(drop_callback);
12906
12907        // Set up pubkeys to write to
12908        let total_pubkeys = ITER_BATCH_SIZE * 10;
12909        let total_pubkeys_to_modify = 10;
12910        let all_pubkeys: Vec<Pubkey> = std::iter::repeat_with(gemachain_sdk::pubkey::new_rand)
12911            .take(total_pubkeys)
12912            .collect();
12913        let program_id = system_program::id();
12914        let starting_carats = 1;
12915        let starting_account = AccountSharedData::new(starting_carats, 0, &program_id);
12916
12917        // Write accounts to the store
12918        for key in &all_pubkeys {
12919            bank0.store_account(key, &starting_account);
12920        }
12921
12922        // Set aside a subset of accounts to modify
12923        let pubkeys_to_modify: Arc<HashSet<Pubkey>> = Arc::new(
12924            all_pubkeys
12925                .into_iter()
12926                .take(total_pubkeys_to_modify)
12927                .collect(),
12928        );
12929        let exit = Arc::new(AtomicBool::new(false));
12930
12931        // Thread that runs scan and constantly checks for
12932        // consistency
12933        let pubkeys_to_modify_ = pubkeys_to_modify.clone();
12934
12935        // Channel over which the bank to scan is sent
12936        let (bank_to_scan_sender, bank_to_scan_receiver): (
12937            crossbeam_channel::Sender<Arc<Bank>>,
12938            crossbeam_channel::Receiver<Arc<Bank>>,
12939        ) = bounded(1);
12940
12941        let (scan_finished_sender, scan_finished_receiver): (
12942            crossbeam_channel::Sender<BankId>,
12943            crossbeam_channel::Receiver<BankId>,
12944        ) = unbounded();
12945        let num_banks_scanned = Arc::new(AtomicU64::new(0));
12946        let scan_thread = {
12947            let exit = exit.clone();
12948            let num_banks_scanned = num_banks_scanned.clone();
12949            Builder::new()
12950                .name("scan".to_string())
12951                .spawn(move || {
12952                    loop {
12953                        info!("starting scan iteration");
12954                        if exit.load(Relaxed) {
12955                            info!("scan exiting");
12956                            return;
12957                        }
12958                        if let Ok(bank_to_scan) =
12959                            bank_to_scan_receiver.recv_timeout(Duration::from_millis(10))
12960                        {
12961                            info!("scanning program accounts for slot {}", bank_to_scan.slot());
12962                            let accounts_result = bank_to_scan.get_program_accounts(&program_id);
12963                            let _ = scan_finished_sender.send(bank_to_scan.bank_id());
12964                            num_banks_scanned.fetch_add(1, Relaxed);
12965                            match (&acceptable_scan_results, accounts_result.is_err()) {
12966                                (AcceptableScanResults::DroppedSlotError, _)
12967                                | (AcceptableScanResults::Both, true) => {
12968                                    assert_eq!(
12969                                        accounts_result,
12970                                        Err(ScanError::SlotRemoved {
12971                                            slot: bank_to_scan.slot(),
12972                                            bank_id: bank_to_scan.bank_id()
12973                                        })
12974                                    );
12975                                }
12976                                (AcceptableScanResults::NoFailure, _)
12977                                | (AcceptableScanResults::Both, false) => {
12978                                    assert!(accounts_result.is_ok())
12979                                }
12980                            }
12981
12982                            // Should never see empty accounts because no slot ever deleted
12983                            // any of the original accounts, and the scan should reflect the
12984                            // account state at some frozen slot `X` (no partial updates).
12985                            if let Ok(accounts) = accounts_result {
12986                                assert!(!accounts.is_empty());
12987                                let mut expected_carats = None;
12988                                let mut target_accounts_found = HashSet::new();
12989                                for (pubkey, account) in accounts {
12990                                    let account_balance = account.carats();
12991                                    if pubkeys_to_modify_.contains(&pubkey) {
12992                                        target_accounts_found.insert(pubkey);
12993                                        if let Some(expected_carats) = expected_carats {
12994                                            assert_eq!(account_balance, expected_carats);
12995                                        } else {
12996                                            // All pubkeys in the specified set should have the same balance
12997                                            expected_carats = Some(account_balance);
12998                                        }
12999                                    }
13000                                }
13001
13002                                // Should've found all the accounts, i.e. no partial cleans should
13003                                // be detected
13004                                assert_eq!(target_accounts_found.len(), total_pubkeys_to_modify);
13005                            }
13006                        }
13007                    }
13008                })
13009                .unwrap()
13010        };
13011
13012        // Thread that constantly updates the accounts, sets
13013        // roots, and cleans
13014        let update_thread = Builder::new()
13015            .name("update".to_string())
13016            .spawn(move || {
13017                update_f(
13018                    bank0,
13019                    bank_to_scan_sender,
13020                    scan_finished_receiver,
13021                    pubkeys_to_modify,
13022                    program_id,
13023                    starting_carats,
13024                );
13025            })
13026            .unwrap();
13027
13028        // Let threads run for a while, check the scans didn't see any mixed slots
13029        let min_expected_number_of_scans = 5;
13030        std::thread::sleep(Duration::new(5, 0));
13031        let mut remaining_loops = 1000;
13032        loop {
13033            if num_banks_scanned.load(Relaxed) > min_expected_number_of_scans {
13034                break;
13035            } else {
13036                std::thread::sleep(Duration::from_millis(100));
13037            }
13038            remaining_loops -= 1;
13039            if remaining_loops == 0 {
13040                break; // just quit and try to get the thread result (panic, etc.)
13041            }
13042        }
13043        exit.store(true, Relaxed);
13044        scan_thread.join().unwrap();
13045        update_thread.join().unwrap();
13046        assert!(remaining_loops > 0, "test timed out");
13047    }
13048
13049    #[test]
13050    fn test_store_scan_consistency_unrooted() {
13051        for accounts_db_caching_enabled in &[false, true] {
13052            let (pruned_banks_sender, pruned_banks_receiver) = unbounded();
13053            let abs_request_handler = AbsRequestHandler {
13054                snapshot_request_handler: None,
13055                pruned_banks_receiver,
13056            };
13057            test_store_scan_consistency(
13058                *accounts_db_caching_enabled,
13059                move |bank0,
13060                      bank_to_scan_sender,
13061                      _scan_finished_receiver,
13062                      pubkeys_to_modify,
13063                      program_id,
13064                      starting_carats| {
13065                    let mut current_major_fork_bank = bank0;
13066                    loop {
13067                        let mut current_minor_fork_bank = current_major_fork_bank.clone();
13068                        let num_new_banks = 2;
13069                        let carats = current_minor_fork_bank.slot() + starting_carats + 1;
13070                        // Modify banks on the two banks on the minor fork
13071                        for pubkeys_to_modify in &pubkeys_to_modify
13072                            .iter()
13073                            .chunks(pubkeys_to_modify.len() / num_new_banks)
13074                        {
13075                            current_minor_fork_bank = Arc::new(Bank::new_from_parent(
13076                                &current_minor_fork_bank,
13077                                &gemachain_sdk::pubkey::new_rand(),
13078                                current_minor_fork_bank.slot() + 2,
13079                            ));
13080                            let account = AccountSharedData::new(carats, 0, &program_id);
13081                            // Write partial updates to each of the banks in the minor fork so if any of them
13082                            // get cleaned up, there will be keys with the wrong account value/missing.
13083                            for key in pubkeys_to_modify {
13084                                current_minor_fork_bank.store_account(key, &account);
13085                            }
13086                            current_minor_fork_bank.freeze();
13087                        }
13088
13089                        // All the parent banks made in this iteration of the loop
13090                        // are currently discoverable, previous parents should have
13091                        // been squashed
13092                        assert_eq!(
13093                            current_minor_fork_bank.clone().parents_inclusive().len(),
13094                            num_new_banks + 1,
13095                        );
13096
13097                        // `next_major_bank` needs to be sandwiched between the minor fork banks
13098                        // That way, after the squash(), the minor fork has the potential to see a
13099                        // *partial* clean of the banks < `next_major_bank`.
13100                        current_major_fork_bank = Arc::new(Bank::new_from_parent(
13101                            &current_major_fork_bank,
13102                            &gemachain_sdk::pubkey::new_rand(),
13103                            current_minor_fork_bank.slot() - 1,
13104                        ));
13105                        let carats = current_major_fork_bank.slot() + starting_carats + 1;
13106                        let account = AccountSharedData::new(carats, 0, &program_id);
13107                        for key in pubkeys_to_modify.iter() {
13108                            // Store rooted updates to these pubkeys such that the minor
13109                            // fork updates to the same keys will be deleted by clean
13110                            current_major_fork_bank.store_account(key, &account);
13111                        }
13112
13113                        // Send the last new bank to the scan thread to perform the scan.
13114                        // Meanwhile this thread will continually set roots on a separate fork
13115                        // and squash/clean, purging the account entries from the minor forks
13116                        /*
13117                                    bank 0
13118                                /         \
13119                        minor bank 1       \
13120                            /         current_major_fork_bank
13121                        minor bank 2
13122
13123                        */
13124                        // The capacity of the channel is 1 so that this thread will wait for the scan to finish before starting
13125                        // the next iteration, allowing the scan to stay in sync with these updates
13126                        // such that every scan will see this interruption.
13127                        if bank_to_scan_sender.send(current_minor_fork_bank).is_err() {
13128                            // Channel was disconnected, exit
13129                            return;
13130                        }
13131                        current_major_fork_bank.freeze();
13132                        current_major_fork_bank.squash();
13133                        // Try to get cache flush/clean to overlap with the scan
13134                        current_major_fork_bank.force_flush_accounts_cache();
13135                        current_major_fork_bank.clean_accounts(false, false, None);
13136                        // Move purge here so that Bank::drop()->purge_slots() doesn't race
13137                        // with clean. Simulates the call from AccountsBackgroundService
13138                        let is_abs_service = true;
13139                        abs_request_handler
13140                            .handle_pruned_banks(&current_major_fork_bank, is_abs_service);
13141                    }
13142                },
13143                Some(Box::new(SendDroppedBankCallback::new(
13144                    pruned_banks_sender.clone(),
13145                ))),
13146                AcceptableScanResults::NoFailure,
13147            )
13148        }
13149    }
13150
13151    #[test]
13152    fn test_store_scan_consistency_root() {
13153        for accounts_db_caching_enabled in &[false, true] {
13154            test_store_scan_consistency(
13155                *accounts_db_caching_enabled,
13156                |bank0,
13157                 bank_to_scan_sender,
13158                 _scan_finished_receiver,
13159                 pubkeys_to_modify,
13160                 program_id,
13161                 starting_carats| {
13162                    let mut current_bank = bank0.clone();
13163                    let mut prev_bank = bank0;
13164                    loop {
13165                        let carats_this_round = current_bank.slot() + starting_carats + 1;
13166                        let account = AccountSharedData::new(carats_this_round, 0, &program_id);
13167                        for key in pubkeys_to_modify.iter() {
13168                            current_bank.store_account(key, &account);
13169                        }
13170                        current_bank.freeze();
13171                        // Send the previous bank to the scan thread to perform the scan.
13172                        // Meanwhile this thread will squash and update roots immediately after
13173                        // so the roots will update while scanning.
13174                        //
13175                        // The capacity of the channel is 1 so that this thread will wait for the scan to finish before starting
13176                        // the next iteration, allowing the scan to stay in sync with these updates
13177                        // such that every scan will see this interruption.
13178                        if bank_to_scan_sender.send(prev_bank).is_err() {
13179                            // Channel was disconnected, exit
13180                            return;
13181                        }
13182                        current_bank.squash();
13183                        if current_bank.slot() % 2 == 0 {
13184                            current_bank.force_flush_accounts_cache();
13185                            current_bank.clean_accounts(true, false, None);
13186                        }
13187                        prev_bank = current_bank.clone();
13188                        current_bank = Arc::new(Bank::new_from_parent(
13189                            &current_bank,
13190                            &gemachain_sdk::pubkey::new_rand(),
13191                            current_bank.slot() + 1,
13192                        ));
13193                    }
13194                },
13195                None,
13196                AcceptableScanResults::NoFailure,
13197            );
13198        }
13199    }
13200
13201    fn setup_banks_on_fork_to_remove(
13202        bank0: Arc<Bank>,
13203        pubkeys_to_modify: Arc<HashSet<Pubkey>>,
13204        program_id: &Pubkey,
13205        starting_carats: u64,
13206        num_banks_on_fork: usize,
13207        step_size: usize,
13208    ) -> (Arc<Bank>, Vec<(Slot, BankId)>, Ancestors) {
13209        // Need at least 2 keys to create inconsistency in account balances when deleting
13210        // slots
13211        assert!(pubkeys_to_modify.len() > 1);
13212
13213        // Tracks the bank at the tip of the to be created fork
13214        let mut bank_at_fork_tip = bank0;
13215
13216        // All the slots on the fork except slot 0
13217        let mut slots_on_fork = Vec::with_capacity(num_banks_on_fork);
13218
13219        // All accounts in each set of `step_size` slots will have the same account balances.
13220        // The account balances of the accounts changes every `step_size` banks. Thus if you
13221        // delete any one of the latest `step_size` slots, then you will see varying account
13222        // balances when loading the accounts.
13223        assert!(num_banks_on_fork >= 2);
13224        assert!(step_size >= 2);
13225        let pubkeys_to_modify: Vec<Pubkey> = pubkeys_to_modify.iter().cloned().collect();
13226        let pubkeys_to_modify_per_slot = (pubkeys_to_modify.len() / step_size).max(1);
13227        for _ in (0..num_banks_on_fork).step_by(step_size) {
13228            let mut carats_this_round = 0;
13229            for i in 0..step_size {
13230                bank_at_fork_tip = Arc::new(Bank::new_from_parent(
13231                    &bank_at_fork_tip,
13232                    &gemachain_sdk::pubkey::new_rand(),
13233                    bank_at_fork_tip.slot() + 1,
13234                ));
13235                if carats_this_round == 0 {
13236                    carats_this_round = bank_at_fork_tip.bank_id() + starting_carats + 1;
13237                }
13238                let pubkey_to_modify_starting_index = i * pubkeys_to_modify_per_slot;
13239                let account = AccountSharedData::new(carats_this_round, 0, program_id);
13240                for pubkey_index_to_modify in pubkey_to_modify_starting_index
13241                    ..pubkey_to_modify_starting_index + pubkeys_to_modify_per_slot
13242                {
13243                    let key = pubkeys_to_modify[pubkey_index_to_modify % pubkeys_to_modify.len()];
13244                    bank_at_fork_tip.store_account(&key, &account);
13245                }
13246                bank_at_fork_tip.freeze();
13247                slots_on_fork.push((bank_at_fork_tip.slot(), bank_at_fork_tip.bank_id()));
13248            }
13249        }
13250
13251        let ancestors: Vec<(Slot, usize)> = slots_on_fork.iter().map(|(s, _)| (*s, 0)).collect();
13252        let ancestors = Ancestors::from(ancestors);
13253
13254        (bank_at_fork_tip, slots_on_fork, ancestors)
13255    }
13256
13257    #[test]
13258    fn test_remove_unrooted_before_scan() {
13259        for accounts_db_caching_enabled in &[false, true] {
13260            test_store_scan_consistency(
13261                *accounts_db_caching_enabled,
13262                |bank0,
13263                 bank_to_scan_sender,
13264                 scan_finished_receiver,
13265                 pubkeys_to_modify,
13266                 program_id,
13267                 starting_carats| {
13268                    loop {
13269                        let (bank_at_fork_tip, slots_on_fork, ancestors) =
13270                            setup_banks_on_fork_to_remove(
13271                                bank0.clone(),
13272                                pubkeys_to_modify.clone(),
13273                                &program_id,
13274                                starting_carats,
13275                                10,
13276                                2,
13277                            );
13278                        // Test removing the slot before the scan starts, should cause
13279                        // SlotRemoved error every time
13280                        for k in pubkeys_to_modify.iter() {
13281                            assert!(bank_at_fork_tip.load_slow(&ancestors, k).is_some());
13282                        }
13283                        bank_at_fork_tip.remove_unrooted_slots(&slots_on_fork);
13284
13285                        // Accounts on this fork should not be found after removal
13286                        for k in pubkeys_to_modify.iter() {
13287                            assert!(bank_at_fork_tip.load_slow(&ancestors, k).is_none());
13288                        }
13289                        if bank_to_scan_sender.send(bank_at_fork_tip.clone()).is_err() {
13290                            return;
13291                        }
13292
13293                        // Wait for scan to finish before starting next iteration
13294                        let finished_scan_bank_id = scan_finished_receiver.recv();
13295                        if finished_scan_bank_id.is_err() {
13296                            return;
13297                        }
13298                        assert_eq!(finished_scan_bank_id.unwrap(), bank_at_fork_tip.bank_id());
13299                    }
13300                },
13301                None,
13302                // Test removing the slot before the scan starts, should error every time
13303                AcceptableScanResults::DroppedSlotError,
13304            );
13305        }
13306    }
13307
13308    #[test]
13309    fn test_remove_unrooted_scan_then_recreate_same_slot_before_scan() {
13310        for accounts_db_caching_enabled in &[false, true] {
13311            test_store_scan_consistency(
13312                *accounts_db_caching_enabled,
13313                |bank0,
13314                 bank_to_scan_sender,
13315                 scan_finished_receiver,
13316                 pubkeys_to_modify,
13317                 program_id,
13318                 starting_carats| {
13319                    let mut prev_bank = bank0.clone();
13320                    loop {
13321                        let start = Instant::now();
13322                        let (bank_at_fork_tip, slots_on_fork, ancestors) =
13323                            setup_banks_on_fork_to_remove(
13324                                bank0.clone(),
13325                                pubkeys_to_modify.clone(),
13326                                &program_id,
13327                                starting_carats,
13328                                10,
13329                                2,
13330                            );
13331                        info!("setting up banks elapsed: {}", start.elapsed().as_millis());
13332                        // Remove the fork. Then we'll recreate the slots and only after we've
13333                        // recreated the slots, do we send this old bank for scanning.
13334                        // Skip scanning bank 0 on first iteration of loop, since those accounts
13335                        // aren't being removed
13336                        if prev_bank.slot() != 0 {
13337                            info!(
13338                                "sending bank with slot: {:?}, elapsed: {}",
13339                                prev_bank.slot(),
13340                                start.elapsed().as_millis()
13341                            );
13342                            // Although we dumped the slots last iteration via `remove_unrooted_slots()`,
13343                            // we've recreated those slots this iteration, so they should be findable
13344                            // again
13345                            for k in pubkeys_to_modify.iter() {
13346                                assert!(bank_at_fork_tip.load_slow(&ancestors, k).is_some());
13347                            }
13348
13349                            // Now after we've recreated the slots removed in the previous loop
13350                            // iteration, send the previous bank, should fail even though the
13351                            // same slots were recreated
13352                            if bank_to_scan_sender.send(prev_bank.clone()).is_err() {
13353                                return;
13354                            }
13355
13356                            let finished_scan_bank_id = scan_finished_receiver.recv();
13357                            if finished_scan_bank_id.is_err() {
13358                                return;
13359                            }
13360                            // Wait for scan to finish before starting next iteration
13361                            assert_eq!(finished_scan_bank_id.unwrap(), prev_bank.bank_id());
13362                        }
13363                        bank_at_fork_tip.remove_unrooted_slots(&slots_on_fork);
13364                        prev_bank = bank_at_fork_tip;
13365                    }
13366                },
13367                None,
13368                // Test removing the slot before the scan starts, should error every time
13369                AcceptableScanResults::DroppedSlotError,
13370            );
13371        }
13372    }
13373
13374    #[test]
13375    fn test_remove_unrooted_scan_interleaved_with_remove_unrooted_slots() {
13376        for accounts_db_caching_enabled in &[false, true] {
13377            test_store_scan_consistency(
13378                *accounts_db_caching_enabled,
13379                |bank0,
13380                 bank_to_scan_sender,
13381                 scan_finished_receiver,
13382                 pubkeys_to_modify,
13383                 program_id,
13384                 starting_carats| {
13385                    loop {
13386                        let step_size = 2;
13387                        let (bank_at_fork_tip, slots_on_fork, ancestors) =
13388                            setup_banks_on_fork_to_remove(
13389                                bank0.clone(),
13390                                pubkeys_to_modify.clone(),
13391                                &program_id,
13392                                starting_carats,
13393                                10,
13394                                step_size,
13395                            );
13396                        // Although we dumped the slots last iteration via `remove_unrooted_slots()`,
13397                        // we've recreated those slots this iteration, so they should be findable
13398                        // again
13399                        for k in pubkeys_to_modify.iter() {
13400                            assert!(bank_at_fork_tip.load_slow(&ancestors, k).is_some());
13401                        }
13402
13403                        // Now after we've recreated the slots removed in the previous loop
13404                        // iteration, send the previous bank, should fail even though the
13405                        // same slots were recreated
13406                        if bank_to_scan_sender.send(bank_at_fork_tip.clone()).is_err() {
13407                            return;
13408                        }
13409
13410                        // Remove 1 < `step_size` of the *latest* slots while the scan is happening.
13411                        // This should create inconsistency between the account balances of accounts
13412                        // stored in that slot, and the accounts stored in earlier slots
13413                        let slot_to_remove = *slots_on_fork.last().unwrap();
13414                        bank_at_fork_tip.remove_unrooted_slots(&[slot_to_remove]);
13415
13416                        // Wait for scan to finish before starting next iteration
13417                        let finished_scan_bank_id = scan_finished_receiver.recv();
13418                        if finished_scan_bank_id.is_err() {
13419                            return;
13420                        }
13421                        assert_eq!(finished_scan_bank_id.unwrap(), bank_at_fork_tip.bank_id());
13422
13423                        // Remove the rest of the slots before the next iteration
13424                        for (slot, bank_id) in slots_on_fork {
13425                            bank_at_fork_tip.remove_unrooted_slots(&[(slot, bank_id)]);
13426                        }
13427                    }
13428                },
13429                None,
13430                // Test removing the slot before the scan starts, should error every time
13431                AcceptableScanResults::Both,
13432            );
13433        }
13434    }
13435
13436    #[test]
13437    fn test_get_inflation_start_slot_devnet_testnet() {
13438        let GenesisConfigInfo {
13439            mut genesis_config, ..
13440        } = create_genesis_config_with_leader(42, &gemachain_sdk::pubkey::new_rand(), 42);
13441        genesis_config
13442            .accounts
13443            .remove(&feature_set::pico_inflation::id())
13444            .unwrap();
13445        genesis_config
13446            .accounts
13447            .remove(&feature_set::full_inflation::devnet_and_testnet::id())
13448            .unwrap();
13449        for pair in feature_set::FULL_INFLATION_FEATURE_PAIRS.iter() {
13450            genesis_config.accounts.remove(&pair.vote_id).unwrap();
13451            genesis_config.accounts.remove(&pair.enable_id).unwrap();
13452        }
13453
13454        let bank = Bank::new_for_tests(&genesis_config);
13455
13456        // Advance slot
13457        let mut bank = new_from_parent(&Arc::new(bank));
13458        bank = new_from_parent(&Arc::new(bank));
13459        assert_eq!(bank.get_inflation_start_slot(), 0);
13460        assert_eq!(bank.slot(), 2);
13461
13462        // Request `pico_inflation` activation
13463        bank.store_account(
13464            &feature_set::pico_inflation::id(),
13465            &feature::create_account(
13466                &Feature {
13467                    activated_at: Some(1),
13468                },
13469                42,
13470            ),
13471        );
13472        bank.compute_active_feature_set(true);
13473        assert_eq!(bank.get_inflation_start_slot(), 1);
13474
13475        // Advance slot
13476        bank = new_from_parent(&Arc::new(bank));
13477        assert_eq!(bank.slot(), 3);
13478
13479        // Request `full_inflation::devnet_and_testnet` activation,
13480        // which takes priority over pico_inflation
13481        bank.store_account(
13482            &feature_set::full_inflation::devnet_and_testnet::id(),
13483            &feature::create_account(
13484                &Feature {
13485                    activated_at: Some(2),
13486                },
13487                42,
13488            ),
13489        );
13490        bank.compute_active_feature_set(true);
13491        assert_eq!(bank.get_inflation_start_slot(), 2);
13492
13493        // Request `full_inflation::mainnet::certusone` activation,
13494        // which should have no effect on `get_inflation_start_slot`
13495        bank.store_account(
13496            &feature_set::full_inflation::mainnet::certusone::vote::id(),
13497            &feature::create_account(
13498                &Feature {
13499                    activated_at: Some(3),
13500                },
13501                42,
13502            ),
13503        );
13504        bank.store_account(
13505            &feature_set::full_inflation::mainnet::certusone::enable::id(),
13506            &feature::create_account(
13507                &Feature {
13508                    activated_at: Some(3),
13509                },
13510                42,
13511            ),
13512        );
13513        bank.compute_active_feature_set(true);
13514        assert_eq!(bank.get_inflation_start_slot(), 2);
13515    }
13516
13517    #[test]
13518    fn test_get_inflation_start_slot_mainnet() {
13519        let GenesisConfigInfo {
13520            mut genesis_config, ..
13521        } = create_genesis_config_with_leader(42, &gemachain_sdk::pubkey::new_rand(), 42);
13522        genesis_config
13523            .accounts
13524            .remove(&feature_set::pico_inflation::id())
13525            .unwrap();
13526        genesis_config
13527            .accounts
13528            .remove(&feature_set::full_inflation::devnet_and_testnet::id())
13529            .unwrap();
13530        for pair in feature_set::FULL_INFLATION_FEATURE_PAIRS.iter() {
13531            genesis_config.accounts.remove(&pair.vote_id).unwrap();
13532            genesis_config.accounts.remove(&pair.enable_id).unwrap();
13533        }
13534
13535        let bank = Bank::new_for_tests(&genesis_config);
13536
13537        // Advance slot
13538        let mut bank = new_from_parent(&Arc::new(bank));
13539        bank = new_from_parent(&Arc::new(bank));
13540        assert_eq!(bank.get_inflation_start_slot(), 0);
13541        assert_eq!(bank.slot(), 2);
13542
13543        // Request `pico_inflation` activation
13544        bank.store_account(
13545            &feature_set::pico_inflation::id(),
13546            &feature::create_account(
13547                &Feature {
13548                    activated_at: Some(1),
13549                },
13550                42,
13551            ),
13552        );
13553        bank.compute_active_feature_set(true);
13554        assert_eq!(bank.get_inflation_start_slot(), 1);
13555
13556        // Advance slot
13557        bank = new_from_parent(&Arc::new(bank));
13558        assert_eq!(bank.slot(), 3);
13559
13560        // Request `full_inflation::mainnet::certusone` activation,
13561        // which takes priority over pico_inflation
13562        bank.store_account(
13563            &feature_set::full_inflation::mainnet::certusone::vote::id(),
13564            &feature::create_account(
13565                &Feature {
13566                    activated_at: Some(2),
13567                },
13568                42,
13569            ),
13570        );
13571        bank.store_account(
13572            &feature_set::full_inflation::mainnet::certusone::enable::id(),
13573            &feature::create_account(
13574                &Feature {
13575                    activated_at: Some(2),
13576                },
13577                42,
13578            ),
13579        );
13580        bank.compute_active_feature_set(true);
13581        assert_eq!(bank.get_inflation_start_slot(), 2);
13582
13583        // Advance slot
13584        bank = new_from_parent(&Arc::new(bank));
13585        assert_eq!(bank.slot(), 4);
13586
13587        // Request `full_inflation::devnet_and_testnet` activation,
13588        // which should have no effect on `get_inflation_start_slot`
13589        bank.store_account(
13590            &feature_set::full_inflation::devnet_and_testnet::id(),
13591            &feature::create_account(
13592                &Feature {
13593                    activated_at: Some(bank.slot()),
13594                },
13595                42,
13596            ),
13597        );
13598        bank.compute_active_feature_set(true);
13599        assert_eq!(bank.get_inflation_start_slot(), 2);
13600    }
13601
13602    #[test]
13603    fn test_get_inflation_num_slots_with_activations() {
13604        let GenesisConfigInfo {
13605            mut genesis_config, ..
13606        } = create_genesis_config_with_leader(42, &gemachain_sdk::pubkey::new_rand(), 42);
13607        let slots_per_epoch = 32;
13608        genesis_config.epoch_schedule = EpochSchedule::new(slots_per_epoch);
13609        genesis_config
13610            .accounts
13611            .remove(&feature_set::pico_inflation::id())
13612            .unwrap();
13613        genesis_config
13614            .accounts
13615            .remove(&feature_set::full_inflation::devnet_and_testnet::id())
13616            .unwrap();
13617        for pair in feature_set::FULL_INFLATION_FEATURE_PAIRS.iter() {
13618            genesis_config.accounts.remove(&pair.vote_id).unwrap();
13619            genesis_config.accounts.remove(&pair.enable_id).unwrap();
13620        }
13621
13622        let mut bank = Bank::new_for_tests(&genesis_config);
13623        assert_eq!(bank.get_inflation_num_slots(), 0);
13624        for _ in 0..2 * slots_per_epoch {
13625            bank = new_from_parent(&Arc::new(bank));
13626        }
13627        assert_eq!(bank.get_inflation_num_slots(), 2 * slots_per_epoch);
13628
13629        // Activate pico_inflation
13630        let pico_inflation_activation_slot = bank.slot();
13631        bank.store_account(
13632            &feature_set::pico_inflation::id(),
13633            &feature::create_account(
13634                &Feature {
13635                    activated_at: Some(pico_inflation_activation_slot),
13636                },
13637                42,
13638            ),
13639        );
13640        bank.compute_active_feature_set(true);
13641        assert_eq!(bank.get_inflation_num_slots(), slots_per_epoch);
13642        for _ in 0..slots_per_epoch {
13643            bank = new_from_parent(&Arc::new(bank));
13644        }
13645        assert_eq!(bank.get_inflation_num_slots(), 2 * slots_per_epoch);
13646
13647        // Activate full_inflation::devnet_and_testnet
13648        let full_inflation_activation_slot = bank.slot();
13649        bank.store_account(
13650            &feature_set::full_inflation::devnet_and_testnet::id(),
13651            &feature::create_account(
13652                &Feature {
13653                    activated_at: Some(full_inflation_activation_slot),
13654                },
13655                42,
13656            ),
13657        );
13658        bank.compute_active_feature_set(true);
13659        assert_eq!(bank.get_inflation_num_slots(), slots_per_epoch);
13660        for _ in 0..slots_per_epoch {
13661            bank = new_from_parent(&Arc::new(bank));
13662        }
13663        assert_eq!(bank.get_inflation_num_slots(), 2 * slots_per_epoch);
13664    }
13665
13666    #[test]
13667    fn test_get_inflation_num_slots_already_activated() {
13668        let GenesisConfigInfo {
13669            mut genesis_config, ..
13670        } = create_genesis_config_with_leader(42, &gemachain_sdk::pubkey::new_rand(), 42);
13671        let slots_per_epoch = 32;
13672        genesis_config.epoch_schedule = EpochSchedule::new(slots_per_epoch);
13673        let mut bank = Bank::new_for_tests(&genesis_config);
13674        assert_eq!(bank.get_inflation_num_slots(), 0);
13675        for _ in 0..slots_per_epoch {
13676            bank = new_from_parent(&Arc::new(bank));
13677        }
13678        assert_eq!(bank.get_inflation_num_slots(), slots_per_epoch);
13679        for _ in 0..slots_per_epoch {
13680            bank = new_from_parent(&Arc::new(bank));
13681        }
13682        assert_eq!(bank.get_inflation_num_slots(), 2 * slots_per_epoch);
13683    }
13684
13685    #[test]
13686    fn test_stake_vote_account_validity() {
13687        let validator_vote_keypairs0 = ValidatorVoteKeypairs::new_rand();
13688        let validator_vote_keypairs1 = ValidatorVoteKeypairs::new_rand();
13689        let validator_keypairs = vec![&validator_vote_keypairs0, &validator_vote_keypairs1];
13690        let GenesisConfigInfo {
13691            genesis_config,
13692            mint_keypair: _,
13693            voting_keypair: _,
13694        } = create_genesis_config_with_vote_accounts(
13695            1_000_000_000,
13696            &validator_keypairs,
13697            vec![10_000; 2],
13698        );
13699        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
13700        let stake_delegation_accounts = bank.stake_delegation_accounts(&mut null_tracer());
13701        assert_eq!(stake_delegation_accounts.len(), 2);
13702
13703        let mut vote_account = bank
13704            .get_account(&validator_vote_keypairs0.vote_keypair.pubkey())
13705            .unwrap_or_default();
13706        let original_carats = vote_account.carats();
13707        vote_account.set_carats(0);
13708        // Simulate vote account removal via full withdrawal
13709        bank.store_account(
13710            &validator_vote_keypairs0.vote_keypair.pubkey(),
13711            &vote_account,
13712        );
13713
13714        // Modify staked vote account owner; a vote account owned by another program could be
13715        // freely modified with malicious data
13716        let bogus_vote_program = Pubkey::new_unique();
13717        vote_account.set_carats(original_carats);
13718        vote_account.set_owner(bogus_vote_program);
13719        bank.store_account(
13720            &validator_vote_keypairs0.vote_keypair.pubkey(),
13721            &vote_account,
13722        );
13723
13724        assert_eq!(bank.vote_accounts().len(), 1);
13725
13726        // Modify stake account owner; a stake account owned by another program could be freely
13727        // modified with malicious data
13728        let bogus_stake_program = Pubkey::new_unique();
13729        let mut stake_account = bank
13730            .get_account(&validator_vote_keypairs1.stake_keypair.pubkey())
13731            .unwrap_or_default();
13732        stake_account.set_owner(bogus_stake_program);
13733        bank.store_account(
13734            &validator_vote_keypairs1.stake_keypair.pubkey(),
13735            &stake_account,
13736        );
13737
13738        // Accounts must be valid stake and vote accounts
13739        let stake_delegation_accounts = bank.stake_delegation_accounts(&mut null_tracer());
13740        assert_eq!(stake_delegation_accounts.len(), 0);
13741    }
13742
13743    #[test]
13744    fn test_vote_epoch_panic() {
13745        let GenesisConfigInfo {
13746            genesis_config,
13747            mint_keypair,
13748            ..
13749        } = create_genesis_config_with_leader(
13750            1_000_000_000_000_000,
13751            &Pubkey::new_unique(),
13752            bootstrap_validator_stake_carats(),
13753        );
13754        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
13755
13756        let vote_keypair = keypair_from_seed(&[1u8; 32]).unwrap();
13757        let stake_keypair = keypair_from_seed(&[2u8; 32]).unwrap();
13758
13759        let mut setup_ixs = Vec::new();
13760        setup_ixs.extend(
13761            vote_instruction::create_account(
13762                &mint_keypair.pubkey(),
13763                &vote_keypair.pubkey(),
13764                &VoteInit {
13765                    node_pubkey: mint_keypair.pubkey(),
13766                    authorized_voter: vote_keypair.pubkey(),
13767                    authorized_withdrawer: mint_keypair.pubkey(),
13768                    commission: 0,
13769                },
13770                1_000_000_000,
13771            )
13772            .into_iter(),
13773        );
13774        setup_ixs.extend(
13775            stake_instruction::create_account_and_delegate_stake(
13776                &mint_keypair.pubkey(),
13777                &stake_keypair.pubkey(),
13778                &vote_keypair.pubkey(),
13779                &Authorized::auto(&mint_keypair.pubkey()),
13780                &Lockup::default(),
13781                1_000_000_000_000,
13782            )
13783            .into_iter(),
13784        );
13785        setup_ixs.push(vote_instruction::withdraw(
13786            &vote_keypair.pubkey(),
13787            &mint_keypair.pubkey(),
13788            1_000_000_000,
13789            &mint_keypair.pubkey(),
13790        ));
13791        setup_ixs.push(system_instruction::transfer(
13792            &mint_keypair.pubkey(),
13793            &vote_keypair.pubkey(),
13794            1_000_000_000,
13795        ));
13796
13797        let result = bank.process_transaction(&Transaction::new(
13798            &[&mint_keypair, &vote_keypair, &stake_keypair],
13799            Message::new(&setup_ixs, Some(&mint_keypair.pubkey())),
13800            bank.last_blockhash(),
13801        ));
13802        assert!(result.is_ok());
13803
13804        let _bank = Bank::new_from_parent(
13805            &bank,
13806            &mint_keypair.pubkey(),
13807            genesis_config.epoch_schedule.get_first_slot_in_epoch(1),
13808        );
13809    }
13810
13811    #[test]
13812    fn test_tx_log_order() {
13813        let GenesisConfigInfo {
13814            genesis_config,
13815            mint_keypair,
13816            ..
13817        } = create_genesis_config_with_leader(
13818            1_000_000_000_000_000,
13819            &Pubkey::new_unique(),
13820            bootstrap_validator_stake_carats(),
13821        );
13822        let bank = Arc::new(Bank::new_for_tests(&genesis_config));
13823        *bank.transaction_log_collector_config.write().unwrap() = TransactionLogCollectorConfig {
13824            mentioned_addresses: HashSet::new(),
13825            filter: TransactionLogCollectorFilter::All,
13826        };
13827        let blockhash = bank.last_blockhash();
13828
13829        let sender0 = Keypair::new();
13830        let sender1 = Keypair::new();
13831        bank.transfer(100, &mint_keypair, &sender0.pubkey())
13832            .unwrap();
13833        bank.transfer(100, &mint_keypair, &sender1.pubkey())
13834            .unwrap();
13835
13836        let recipient0 = Pubkey::new_unique();
13837        let recipient1 = Pubkey::new_unique();
13838        let tx0 = system_transaction::transfer(&sender0, &recipient0, 10, blockhash);
13839        let success_sig = tx0.signatures[0];
13840        let tx1 = system_transaction::transfer(&sender1, &recipient1, 110, blockhash); // Should produce insufficient funds log
13841        let failure_sig = tx1.signatures[0];
13842        let tx2 = system_transaction::transfer(&sender0, &recipient0, 1, blockhash);
13843        let txs = vec![tx0, tx1, tx2];
13844        let batch = bank.prepare_batch(txs).unwrap();
13845
13846        let log_results = bank
13847            .load_execute_and_commit_transactions(
13848                &batch,
13849                MAX_PROCESSING_AGE,
13850                false,
13851                false,
13852                true,
13853                &mut ExecuteTimings::default(),
13854            )
13855            .3;
13856        assert_eq!(log_results.len(), 3);
13857        assert!(log_results[0].as_ref().unwrap()[1].contains(&"success".to_string()));
13858        assert!(log_results[1].as_ref().unwrap()[2].contains(&"failed".to_string()));
13859        assert!(log_results[2].as_ref().is_none());
13860
13861        let stored_logs = &bank.transaction_log_collector.read().unwrap().logs;
13862        let success_log_info = stored_logs
13863            .iter()
13864            .find(|transaction_log_info| transaction_log_info.signature == success_sig)
13865            .unwrap();
13866        assert!(success_log_info.result.is_ok());
13867        let success_log = success_log_info.log_messages.clone().pop().unwrap();
13868        assert!(success_log.contains(&"success".to_string()));
13869        let failure_log_info = stored_logs
13870            .iter()
13871            .find(|transaction_log_info| transaction_log_info.signature == failure_sig)
13872            .unwrap();
13873        assert!(failure_log_info.result.is_err());
13874        let failure_log = failure_log_info.log_messages.clone().pop().unwrap();
13875        assert!(failure_log.contains(&"failed".to_string()));
13876    }
13877
13878    #[test]
13879    fn test_get_largest_accounts() {
13880        let GenesisConfigInfo { genesis_config, .. } =
13881            create_genesis_config_with_leader(42, &gemachain_sdk::pubkey::new_rand(), 42);
13882        let bank = Bank::new_for_tests(&genesis_config);
13883
13884        let pubkeys: Vec<_> = (0..5).map(|_| Pubkey::new_unique()).collect();
13885        let pubkeys_hashset: HashSet<_> = pubkeys.iter().cloned().collect();
13886
13887        let pubkeys_balances: Vec<_> = pubkeys
13888            .iter()
13889            .cloned()
13890            .zip(vec![
13891                gema_to_carats(2.0),
13892                gema_to_carats(3.0),
13893                gema_to_carats(3.0),
13894                gema_to_carats(4.0),
13895                gema_to_carats(5.0),
13896            ])
13897            .collect();
13898
13899        // Initialize accounts; all have larger GEMA balances than current Bank built-ins
13900        let account0 = AccountSharedData::new(pubkeys_balances[0].1, 0, &Pubkey::default());
13901        bank.store_account(&pubkeys_balances[0].0, &account0);
13902        let account1 = AccountSharedData::new(pubkeys_balances[1].1, 0, &Pubkey::default());
13903        bank.store_account(&pubkeys_balances[1].0, &account1);
13904        let account2 = AccountSharedData::new(pubkeys_balances[2].1, 0, &Pubkey::default());
13905        bank.store_account(&pubkeys_balances[2].0, &account2);
13906        let account3 = AccountSharedData::new(pubkeys_balances[3].1, 0, &Pubkey::default());
13907        bank.store_account(&pubkeys_balances[3].0, &account3);
13908        let account4 = AccountSharedData::new(pubkeys_balances[4].1, 0, &Pubkey::default());
13909        bank.store_account(&pubkeys_balances[4].0, &account4);
13910
13911        // Create HashSet to exclude an account
13912        let exclude4: HashSet<_> = pubkeys[4..].iter().cloned().collect();
13913
13914        let mut sorted_accounts = pubkeys_balances.clone();
13915        sorted_accounts.sort_by(|a, b| a.1.cmp(&b.1).reverse());
13916
13917        // Return only one largest account
13918        assert_eq!(
13919            bank.get_largest_accounts(1, &pubkeys_hashset, AccountAddressFilter::Include)
13920                .unwrap(),
13921            vec![(pubkeys[4], gema_to_carats(5.0))]
13922        );
13923        assert_eq!(
13924            bank.get_largest_accounts(1, &HashSet::new(), AccountAddressFilter::Exclude)
13925                .unwrap(),
13926            vec![(pubkeys[4], gema_to_carats(5.0))]
13927        );
13928        assert_eq!(
13929            bank.get_largest_accounts(1, &exclude4, AccountAddressFilter::Exclude)
13930                .unwrap(),
13931            vec![(pubkeys[3], gema_to_carats(4.0))]
13932        );
13933
13934        // Return all added accounts
13935        let results = bank
13936            .get_largest_accounts(10, &pubkeys_hashset, AccountAddressFilter::Include)
13937            .unwrap();
13938        assert_eq!(results.len(), sorted_accounts.len());
13939        for pubkey_balance in sorted_accounts.iter() {
13940            assert!(results.contains(pubkey_balance));
13941        }
13942        let mut sorted_results = results.clone();
13943        sorted_results.sort_by(|a, b| a.1.cmp(&b.1).reverse());
13944        assert_eq!(sorted_results, results);
13945
13946        let expected_accounts = sorted_accounts[1..].to_vec();
13947        let results = bank
13948            .get_largest_accounts(10, &exclude4, AccountAddressFilter::Exclude)
13949            .unwrap();
13950        // results include 5 Bank builtins
13951        assert_eq!(results.len(), 10);
13952        for pubkey_balance in expected_accounts.iter() {
13953            assert!(results.contains(pubkey_balance));
13954        }
13955        let mut sorted_results = results.clone();
13956        sorted_results.sort_by(|a, b| a.1.cmp(&b.1).reverse());
13957        assert_eq!(sorted_results, results);
13958
13959        // Return 3 added accounts
13960        let expected_accounts = sorted_accounts[0..4].to_vec();
13961        let results = bank
13962            .get_largest_accounts(4, &pubkeys_hashset, AccountAddressFilter::Include)
13963            .unwrap();
13964        assert_eq!(results.len(), expected_accounts.len());
13965        for pubkey_balance in expected_accounts.iter() {
13966            assert!(results.contains(pubkey_balance));
13967        }
13968
13969        let expected_accounts = expected_accounts[1..4].to_vec();
13970        let results = bank
13971            .get_largest_accounts(3, &exclude4, AccountAddressFilter::Exclude)
13972            .unwrap();
13973        assert_eq!(results.len(), expected_accounts.len());
13974        for pubkey_balance in expected_accounts.iter() {
13975            assert!(results.contains(pubkey_balance));
13976        }
13977
13978        // Exclude more, and non-sequential, accounts
13979        let exclude: HashSet<_> = vec![pubkeys[0], pubkeys[2], pubkeys[4]]
13980            .iter()
13981            .cloned()
13982            .collect();
13983        assert_eq!(
13984            bank.get_largest_accounts(2, &exclude, AccountAddressFilter::Exclude)
13985                .unwrap(),
13986            vec![pubkeys_balances[3], pubkeys_balances[1]]
13987        );
13988    }
13989
13990    #[test]
13991    fn test_transfer_sysvar() {
13992        gemachain_logger::setup();
13993        let GenesisConfigInfo {
13994            genesis_config,
13995            mint_keypair,
13996            ..
13997        } = create_genesis_config_with_leader(
13998            1_000_000_000_000_000,
13999            &Pubkey::new_unique(),
14000            bootstrap_validator_stake_carats(),
14001        );
14002        let mut bank = Bank::new_for_tests(&genesis_config);
14003
14004        fn mock_ix_processor(
14005            _pubkey: &Pubkey,
14006            _data: &[u8],
14007            invoke_context: &mut dyn InvokeContext,
14008        ) -> std::result::Result<(), InstructionError> {
14009            use gemachain_sdk::account::WritableAccount;
14010            let keyed_accounts = invoke_context.get_keyed_accounts()?;
14011            let mut data = keyed_accounts[1].try_account_ref_mut()?;
14012            data.data_as_mut_slice()[0] = 5;
14013            Ok(())
14014        }
14015
14016        let program_id = gemachain_sdk::pubkey::new_rand();
14017        bank.add_builtin("mock_program1", program_id, mock_ix_processor);
14018
14019        let blockhash = bank.last_blockhash();
14020        #[allow(deprecated)]
14021        let blockhash_sysvar = sysvar::clock::id();
14022        #[allow(deprecated)]
14023        let orig_carats = bank.get_account(&sysvar::clock::id()).unwrap().carats();
14024        info!("{:?}", bank.get_account(&sysvar::clock::id()));
14025        let tx = system_transaction::transfer(&mint_keypair, &blockhash_sysvar, 10, blockhash);
14026        assert_eq!(
14027            bank.process_transaction(&tx),
14028            Err(TransactionError::InstructionError(
14029                0,
14030                InstructionError::ReadonlyCaratChange
14031            ))
14032        );
14033        assert_eq!(
14034            bank.get_account(&sysvar::clock::id()).unwrap().carats(),
14035            orig_carats
14036        );
14037        info!("{:?}", bank.get_account(&sysvar::clock::id()));
14038
14039        let accounts = vec![
14040            AccountMeta::new(mint_keypair.pubkey(), true),
14041            AccountMeta::new(blockhash_sysvar, false),
14042        ];
14043        let ix = Instruction::new_with_bincode(program_id, &0, accounts);
14044        let message = Message::new(&[ix], Some(&mint_keypair.pubkey()));
14045        let tx = Transaction::new(&[&mint_keypair], message, blockhash);
14046        assert_eq!(
14047            bank.process_transaction(&tx),
14048            Err(TransactionError::InstructionError(
14049                0,
14050                InstructionError::ReadonlyDataModified
14051            ))
14052        );
14053    }
14054
14055    #[test]
14056    fn test_clean_dropped_unrooted_frozen_banks() {
14057        gemachain_logger::setup();
14058        do_test_clean_dropped_unrooted_banks(FreezeBank1::Yes);
14059    }
14060
14061    #[test]
14062    fn test_clean_dropped_unrooted_unfrozen_banks() {
14063        gemachain_logger::setup();
14064        do_test_clean_dropped_unrooted_banks(FreezeBank1::No);
14065    }
14066
14067    /// A simple enum to toggle freezing Bank1 or not.  Used in the clean_dropped_unrooted tests.
14068    enum FreezeBank1 {
14069        No,
14070        Yes,
14071    }
14072
14073    fn do_test_clean_dropped_unrooted_banks(freeze_bank1: FreezeBank1) {
14074        //! Test that dropped unrooted banks are cleaned up properly
14075        //!
14076        //! slot 0:       bank0 (rooted)
14077        //!               /   \
14078        //! slot 1:      /   bank1 (unrooted and dropped)
14079        //!             /
14080        //! slot 2:  bank2 (rooted)
14081        //!
14082        //! In the scenario above, when `clean_accounts()` is called on bank2, the keys that exist
14083        //! _only_ in bank1 should be cleaned up, since those keys are unreachable.
14084        //!
14085        //! The following scenarios are tested:
14086        //!
14087        //! 1. A key is written _only_ in an unrooted bank (key1)
14088        //!     - In this case, key1 should be cleaned up
14089        //! 2. A key is written in both an unrooted _and_ rooted bank (key3)
14090        //!     - In this case, key3's ref-count should be decremented correctly
14091        //! 3. A key with zero carats is _only_ in an unrooted bank (key4)
14092        //!     - In this case, key4 should be cleaned up
14093        //! 4. A key with zero carats is in both an unrooted _and_ rooted bank (key5)
14094        //!     - In this case, key5's ref-count should be decremented correctly
14095
14096        let (genesis_config, mint_keypair) = create_genesis_config(100);
14097        let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
14098
14099        let collector = Pubkey::new_unique();
14100        let owner = Pubkey::new_unique();
14101
14102        let key1 = Keypair::new(); // only touched in bank1
14103        let key2 = Keypair::new(); // only touched in bank2
14104        let key3 = Keypair::new(); // touched in both bank1 and bank2
14105        let key4 = Keypair::new(); // in only bank1, and has zero carats
14106        let key5 = Keypair::new(); // in both bank1 and bank2, and has zero carats
14107        bank0.transfer(2, &mint_keypair, &key2.pubkey()).unwrap();
14108        bank0.freeze();
14109
14110        let slot = 1;
14111        let bank1 = Bank::new_from_parent(&bank0, &collector, slot);
14112        bank1.transfer(3, &mint_keypair, &key1.pubkey()).unwrap();
14113        bank1.store_account(&key4.pubkey(), &AccountSharedData::new(0, 0, &owner));
14114        bank1.store_account(&key5.pubkey(), &AccountSharedData::new(0, 0, &owner));
14115
14116        if let FreezeBank1::Yes = freeze_bank1 {
14117            bank1.freeze();
14118        }
14119
14120        let slot = slot + 1;
14121        let bank2 = Bank::new_from_parent(&bank0, &collector, slot);
14122        bank2.transfer(4, &mint_keypair, &key2.pubkey()).unwrap();
14123        bank2.transfer(6, &mint_keypair, &key3.pubkey()).unwrap();
14124        bank2.store_account(&key5.pubkey(), &AccountSharedData::new(0, 0, &owner));
14125
14126        bank2.freeze(); // the freeze here is not strictly necessary, but more for illustration
14127        bank2.squash();
14128
14129        drop(bank1);
14130        bank2.clean_accounts(false, false, None);
14131
14132        let expected_ref_count_for_cleaned_up_keys = 0;
14133        let expected_ref_count_for_keys_in_both_slot1_and_slot2 = 1;
14134
14135        assert_eq!(
14136            bank2
14137                .rc
14138                .accounts
14139                .accounts_db
14140                .accounts_index
14141                .ref_count_from_storage(&key1.pubkey()),
14142            expected_ref_count_for_cleaned_up_keys
14143        );
14144        assert_ne!(
14145            bank2
14146                .rc
14147                .accounts
14148                .accounts_db
14149                .accounts_index
14150                .ref_count_from_storage(&key3.pubkey()),
14151            expected_ref_count_for_cleaned_up_keys
14152        );
14153        assert_eq!(
14154            bank2
14155                .rc
14156                .accounts
14157                .accounts_db
14158                .accounts_index
14159                .ref_count_from_storage(&key4.pubkey()),
14160            expected_ref_count_for_cleaned_up_keys
14161        );
14162        assert_eq!(
14163            bank2
14164                .rc
14165                .accounts
14166                .accounts_db
14167                .accounts_index
14168                .ref_count_from_storage(&key5.pubkey()),
14169            expected_ref_count_for_keys_in_both_slot1_and_slot2,
14170        );
14171
14172        assert_eq!(
14173            bank2.rc.accounts.accounts_db.alive_account_count_in_slot(1),
14174            0
14175        );
14176    }
14177
14178    #[test]
14179    fn test_rent_debits() {
14180        let mut rent_debits = RentDebits::default();
14181
14182        // No entry for 0 rewards
14183        rent_debits.push(&Pubkey::default(), 0, 0);
14184        assert_eq!(rent_debits.0.len(), 0);
14185
14186        // Doesn't fit an `i64`, no entry. (we'll die elsewhere)
14187        rent_debits.push(&Pubkey::default(), u64::MAX, 0);
14188        assert_eq!(rent_debits.0.len(), 0);
14189
14190        // Since we're casting from `u64` the `i64::checked_neg()` is infallible
14191
14192        // Some that actually work
14193        rent_debits.push(&Pubkey::default(), 1, 0);
14194        assert_eq!(rent_debits.0.len(), 1);
14195        rent_debits.push(&Pubkey::default(), i64::MAX as u64, 0);
14196        assert_eq!(rent_debits.0.len(), 2);
14197    }
14198
14199    #[test]
14200    fn test_compute_request_instruction() {
14201        gemachain_logger::setup();
14202        let GenesisConfigInfo {
14203            genesis_config,
14204            mint_keypair,
14205            ..
14206        } = create_genesis_config_with_leader(
14207            1_000_000_000_000_000,
14208            &Pubkey::new_unique(),
14209            bootstrap_validator_stake_carats(),
14210        );
14211        let mut bank = Bank::new_for_tests(&genesis_config);
14212
14213        fn mock_ix_processor(
14214            _pubkey: &Pubkey,
14215            _data: &[u8],
14216            invoke_context: &mut dyn InvokeContext,
14217        ) -> std::result::Result<(), InstructionError> {
14218            let compute_budget = invoke_context.get_compute_budget();
14219            assert_eq!(
14220                *compute_budget,
14221                ComputeBudget {
14222                    max_units: 1,
14223                    ..ComputeBudget::default()
14224                }
14225            );
14226            Ok(())
14227        }
14228        let program_id = gemachain_sdk::pubkey::new_rand();
14229        bank.add_builtin("mock_program", program_id, mock_ix_processor);
14230
14231        let message = Message::new(
14232            &[
14233                ComputeBudgetInstruction::request_units(1),
14234                Instruction::new_with_bincode(program_id, &0, vec![]),
14235            ],
14236            Some(&mint_keypair.pubkey()),
14237        );
14238        let tx = Transaction::new(&[&mint_keypair], message, bank.last_blockhash());
14239        bank.process_transaction(&tx).unwrap();
14240    }
14241
14242    #[test]
14243    fn test_verify_and_hash_transaction_sig_len() {
14244        let GenesisConfigInfo {
14245            mut genesis_config, ..
14246        } = create_genesis_config_with_leader(42, &gemachain_sdk::pubkey::new_rand(), 42);
14247
14248        // activate all features but verify_tx_signatures_len
14249        activate_all_features(&mut genesis_config);
14250        genesis_config
14251            .accounts
14252            .remove(&feature_set::verify_tx_signatures_len::id());
14253        let bank = Bank::new_for_tests(&genesis_config);
14254
14255        let mut rng = rand::thread_rng();
14256        let recent_blockhash = hash::new_rand(&mut rng);
14257        let from_keypair = Keypair::new();
14258        let to_keypair = Keypair::new();
14259        let from_pubkey = from_keypair.pubkey();
14260        let to_pubkey = to_keypair.pubkey();
14261
14262        enum TestCase {
14263            AddSignature,
14264            RemoveSignature,
14265        }
14266
14267        let make_transaction = |case: TestCase| {
14268            let message = Message::new(
14269                &[system_instruction::transfer(&from_pubkey, &to_pubkey, 1)],
14270                Some(&from_pubkey),
14271            );
14272            let mut tx = Transaction::new(&[&from_keypair], message, recent_blockhash);
14273            assert_eq!(tx.message.header.num_required_signatures, 1);
14274            match case {
14275                TestCase::AddSignature => {
14276                    let signature = to_keypair.sign_message(&tx.message.serialize());
14277                    tx.signatures.push(signature);
14278                }
14279                TestCase::RemoveSignature => {
14280                    tx.signatures.remove(0);
14281                }
14282            }
14283            tx
14284        };
14285
14286        // Too few signatures: Sanitization failure
14287        {
14288            let tx = make_transaction(TestCase::RemoveSignature);
14289            assert_eq!(
14290                bank.verify_transaction(tx.into(), false).err(),
14291                Some(TransactionError::SanitizeFailure),
14292            );
14293        }
14294        // Too many signatures: Success without feature switch
14295        {
14296            let tx = make_transaction(TestCase::AddSignature);
14297            assert!(bank.verify_transaction(tx.into(), false).is_ok());
14298        }
14299    }
14300
14301    #[test]
14302    fn test_verify_transactions_load_duplicate_account() {
14303        let GenesisConfigInfo { genesis_config, .. } =
14304            create_genesis_config_with_leader(42, &gemachain_sdk::pubkey::new_rand(), 42);
14305        let bank = Bank::new_for_tests(&genesis_config);
14306
14307        let mut rng = rand::thread_rng();
14308        let recent_blockhash = hash::new_rand(&mut rng);
14309        let from_keypair = Keypair::new();
14310        let to_keypair = Keypair::new();
14311        let from_pubkey = from_keypair.pubkey();
14312        let to_pubkey = to_keypair.pubkey();
14313
14314        let make_transaction = || {
14315            let mut message = Message::new(
14316                &[system_instruction::transfer(&from_pubkey, &to_pubkey, 1)],
14317                Some(&from_pubkey),
14318            );
14319            let to_index = message
14320                .account_keys
14321                .iter()
14322                .position(|k| k == &to_pubkey)
14323                .unwrap();
14324            message.account_keys[to_index] = from_pubkey;
14325            Transaction::new(&[&from_keypair], message, recent_blockhash)
14326        };
14327
14328        // Duplicate account
14329        {
14330            let tx = make_transaction();
14331            assert_eq!(
14332                bank.verify_transaction(tx.into(), false).err(),
14333                Some(TransactionError::AccountLoadedTwice),
14334            );
14335        }
14336    }
14337
14338    #[test]
14339    fn test_verify_transactions_packet_data_size() {
14340        let GenesisConfigInfo { genesis_config, .. } =
14341            create_genesis_config_with_leader(42, &gemachain_sdk::pubkey::new_rand(), 42);
14342        let bank = Bank::new_for_tests(&genesis_config);
14343
14344        let mut rng = rand::thread_rng();
14345        let recent_blockhash = hash::new_rand(&mut rng);
14346        let keypair = Keypair::new();
14347        let pubkey = keypair.pubkey();
14348        let make_transaction = |size| {
14349            let ixs: Vec<_> = std::iter::repeat_with(|| {
14350                system_instruction::transfer(&pubkey, &Pubkey::new_unique(), 1)
14351            })
14352            .take(size)
14353            .collect();
14354            let message = Message::new(&ixs[..], Some(&pubkey));
14355            Transaction::new(&[&keypair], message, recent_blockhash)
14356        };
14357        // Small transaction.
14358        {
14359            let tx = make_transaction(5);
14360            assert!(bincode::serialized_size(&tx).unwrap() <= PACKET_DATA_SIZE as u64);
14361            assert!(bank.verify_transaction(tx.into(), false).is_ok(),);
14362        }
14363        // Big transaction.
14364        {
14365            let tx = make_transaction(25);
14366            assert!(bincode::serialized_size(&tx).unwrap() > PACKET_DATA_SIZE as u64);
14367            assert_eq!(
14368                bank.verify_transaction(tx.into(), false).err(),
14369                Some(TransactionError::SanitizeFailure),
14370            );
14371        }
14372        // Assert that verify fails as soon as serialized
14373        // size exceeds packet data size.
14374        for size in 1..30 {
14375            let tx = make_transaction(size);
14376            assert_eq!(
14377                bincode::serialized_size(&tx).unwrap() <= PACKET_DATA_SIZE as u64,
14378                bank.verify_transaction(tx.into(), false).is_ok(),
14379            );
14380        }
14381    }
14382}