1use 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, };
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
193type 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#[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; #[derive(Debug)]
257struct CachedExecutorsEntry {
258 prev_epoch_count: u64,
259 epoch_count: AtomicU64,
260 executor: Arc<dyn Executor>,
261}
262#[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 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 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 pub accounts: Arc<Accounts>,
400
401 pub(crate) parent: RwLock<Option<Arc<Bank>>>,
403
404 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 parent: RwLock::new(None),
419 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 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
503pub type InnerInstructions = Vec<CompiledInstruction>;
505
506pub type InnerInstructionsList = Vec<InnerInstructions>;
508
509pub 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 pub logs: Vec<TransactionLogInfo>,
545
546 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#[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#[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
737impl 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, pub post_balance: u64, pub commission: Option<u8>, }
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#[derive(AbiExample, Debug)]
836pub struct Bank {
837 pub rc: BankRc,
839
840 pub src: StatusCacheRc,
841
842 blockhash_queue: RwLock<BlockhashQueue>,
844
845 pub ancestors: Ancestors,
847
848 hash: RwLock<Hash>,
850
851 parent_hash: Hash,
853
854 parent_slot: Slot,
856
857 hard_forks: Arc<RwLock<HardForks>>,
859
860 transaction_count: AtomicU64,
862
863 transaction_error_count: AtomicU64,
865
866 transaction_entries_count: AtomicU64,
868
869 transactions_per_entry_max: AtomicU64,
871
872 tick_height: AtomicU64,
874
875 signature_count: AtomicU64,
877
878 capitalization: AtomicU64,
880
881 max_tick_height: u64,
883
884 hashes_per_tick: Option<u64>,
886
887 ticks_per_slot: u64,
889
890 pub ns_per_slot: u128,
892
893 genesis_creation_time: UnixTimestamp,
895
896 slots_per_year: f64,
898
899 unused: u64,
901
902 slot: Slot,
904
905 bank_id: BankId,
906
907 epoch: Epoch,
909
910 block_height: u64,
912
913 collector_id: Pubkey,
915
916 collector_fees: AtomicU64,
918
919 fee_calculator: FeeCalculator,
921
922 fee_rate_governor: FeeRateGovernor,
924
925 collected_rent: AtomicU64,
927
928 rent_collector: RentCollector,
930
931 epoch_schedule: EpochSchedule,
933
934 inflation: Arc<RwLock<Inflation>>,
936
937 stakes: RwLock<Stakes>,
939
940 epoch_stakes: HashMap<Epoch, EpochStakes>,
943
944 is_delta: AtomicBool,
947
948 message_processor: MessageProcessor,
950
951 compute_budget: Option<ComputeBudget>,
952
953 #[allow(clippy::rc_buffer)]
955 feature_builtins: Arc<Vec<(Builtin, Pubkey, ActivationType)>>,
956
957 pub last_vote_sync: AtomicU64,
959
960 pub rewards: RwLock<Vec<(Pubkey, RewardInfo)>>,
962
963 pub cluster_type: Option<ClusterType>,
964
965 pub lazy_rent_collection: AtomicBool,
966
967 pub rewards_pool_pubkeys: Arc<HashSet<Pubkey>>,
969
970 cached_executors: RwLock<CowCachedExecutors>,
972
973 transaction_debug_keys: Option<Arc<HashSet<Pubkey>>>,
974
975 pub transaction_log_collector_config: Arc<RwLock<TransactionLogCollectorConfig>>,
977
978 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 Self::new_for_tests(genesis_config)
1005 }
1006
1007 pub fn new_for_tests(genesis_config: &GenesisConfig) -> Self {
1008 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 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 {
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 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 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 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 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 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 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 #[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 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 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 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 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 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 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 old_account
1697 .as_ref()
1698 .map(|a| a.rent_epoch())
1699 .unwrap_or(INITIAL_RENT_EPOCH)
1700 },
1701 )
1702 }
1703
1704 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 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 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 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 self.epoch_schedule.get_slots_in_epoch(prev_epoch) as f64 / self.slots_per_year
1902 }
1903
1904 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 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 num_slots as f64 / self.slots_per_year
1940 }
1941
1942 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 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 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 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 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 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 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 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 let mut reward_calc_tracer = reward_calc_tracer.as_mut().map(|outer| {
2157 let stake_pubkey = *stake_pubkey;
2158 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 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 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 let mut hash = self.hash.write().unwrap();
2355 if *hash == Hash::default() {
2356 self.collect_rent_eagerly();
2358 self.collect_fees();
2359 self.distribute_rent();
2360 self.update_slot_history();
2361 self.run_incinerator();
2362
2363 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 pub fn exhaustively_free_unused_resource(&self, last_full_snapshot_slot: Option<Slot>) {
2373 const IS_STARTUP: bool = true; let mut flush = Measure::start("flush");
2375 self.force_flush_accounts_cache();
2378 flush.stop();
2379
2380 let mut clean = Measure::start("clean");
2381 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 pub fn squash(&self) {
2405 self.freeze();
2406
2407 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 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 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 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 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 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 for (name, program_id) in &genesis_config.native_instruction_processors {
2503 self.add_native_program(name, program_id, false);
2504 }
2505 }
2506
2507 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 if native_loader::check_id(account.owner()) {
2515 Some(account)
2516 } else {
2517 self.capitalization.fetch_sub(account.carats(), Relaxed);
2521
2522 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 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 return;
2544 }
2545 }
2547 }
2548 } else {
2549 match &existing_genuine_program {
2552 None => (), Some(_account) => {
2554 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 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 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 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 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 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 status_cache.insert(
2729 tx.message().recent_blockhash(),
2730 tx.message_hash(),
2731 self.slot(),
2732 res.clone(),
2733 );
2734 status_cache.insert(
2738 tx.message().recent_blockhash(),
2739 tx.signature(),
2740 self.slot(),
2741 res.clone(),
2742 );
2743 }
2744 }
2745 }
2746
2747 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 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 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 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 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 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 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 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 fn upgrade_epoch(&self) -> bool {
3032 match self.cluster_type() {
3033 #[cfg(test)]
3034 ClusterType::Development => self.epoch == 0xdead, #[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 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 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 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 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 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 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 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) && 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 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 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 #[allow(clippy::needless_collect)]
3704 fn distribute_rent_to_validators(
3705 &self,
3706 vote_accounts: &HashMap<Pubkey, (u64, VoteAccount)>,
3707 rent_to_be_distributed: u64,
3708 ) {
3709 let mut total_staked = 0;
3710
3711 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 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 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 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 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 self.variable_cycle_partitions()
3916 } else {
3917 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 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 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 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 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 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 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 let parent_last_cycle_index = slot_count_in_two_day - 1;
4045
4046 partitions.push((
4048 parent_cycle_index,
4049 parent_last_cycle_index,
4050 slot_count_in_two_day,
4051 ));
4052
4053 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 let parent_last_slot_index = self.get_slots_in_epoch(parent_epoch) - 1;
4081
4082 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 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 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 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 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 fn use_multi_epoch_collection_cycle(&self, epoch: Epoch) -> bool {
4236 #[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 #[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 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 self.cluster_type.unwrap()
4274 }
4275
4276 #[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 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 #[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 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 #[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 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 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 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 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 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 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 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 pub fn get_account(&self, pubkey: &Pubkey) -> Option<AccountSharedData> {
4625 self.get_account_modified_slot(pubkey)
4626 .map(|(acc, _slot)| acc)
4627 }
4628
4629 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 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 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 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 fn hash_internal_state(&self) -> Hash {
4855 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 #[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; 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 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 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 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 pub fn hashes_per_tick(&self) -> &Option<u64> {
5096 &self.hashes_per_tick
5097 }
5098
5099 pub fn ticks_per_slot(&self) -> u64 {
5101 self.ticks_per_slot
5102 }
5103
5104 pub fn slots_per_year(&self) -> f64 {
5106 self.slots_per_year
5107 }
5108
5109 pub fn tick_height(&self) -> u64 {
5111 self.tick_height.load(Relaxed)
5112 }
5113
5114 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 pub fn capitalization(&self) -> u64 {
5125 self.capitalization.load(Relaxed)
5126 }
5127
5128 pub fn max_tick_height(&self) -> u64 {
5130 self.max_tick_height
5131 }
5132
5133 pub fn block_height(&self) -> u64 {
5135 self.block_height
5136 }
5137
5138 pub fn get_slots_in_epoch(&self, epoch: Epoch) -> u64 {
5140 self.epoch_schedule.get_slots_in_epoch(epoch)
5141 }
5142
5143 pub fn get_leader_schedule_epoch(&self, slot: Slot) -> Epoch {
5146 self.epoch_schedule.get_leader_schedule_epoch(slot)
5147 }
5148
5149 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 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 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 pub fn vote_accounts(&self) -> Arc<HashMap<Pubkey, (u64, VoteAccount)>> {
5201 let stakes = self.stakes.read().unwrap();
5202 Arc::from(stakes.vote_accounts())
5203 }
5204
5205 pub fn get_vote_account(&self, vote_account: &Pubkey) -> Option<(u64, VoteAccount)> {
5207 let stakes = self.stakes.read().unwrap();
5208 stakes.vote_accounts().get(vote_account).cloned()
5209 }
5210
5211 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 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 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 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 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 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 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 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 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 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 pub fn should_bank_still_be_processing_txs(
5425 bank_creation_time: &Instant,
5426 max_tx_ingestion_nanos: u128,
5427 ) -> bool {
5428 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 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; self.rent_collector.rent.burn_percent = 50; }
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; self.rent_collector.rent.burn_percent = 50; }
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 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 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.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 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 self.capitalization
5620 .fetch_sub(old_account.carats(), Relaxed);
5621
5622 self.store_account(&inline_spl_token_v2_0::id(), &new_account);
5624
5625 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 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 ClusterType::Devnet => false,
5684 ClusterType::Testnet => self.epoch() == 93,
5686 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 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 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 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 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 let full = NonceRollbackFull::from_partial(partial.clone(), &message, &accounts).unwrap();
5883 assert_eq!(full.fee_account(), None);
5884
5885 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 );
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 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 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 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 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 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 assert_eq!(bank.get_balance(&payer.pubkey()), 92);
6579 total_rent_deducted += 128;
6580
6581 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; assert_eq!(
6599 bank.get_balance(&bootstrap_validator_pubkey),
6600 bootstrap_validator_portion + bootstrap_validator_initial_balance
6601 );
6602
6603 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 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 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 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 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; 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 assert_eq!(bank.get_balance(&keypairs[0].pubkey()), 1);
6864 rent_collected += generic_rent_due_for_system_account;
6865
6866 assert_eq!(bank.get_balance(&keypairs[1].pubkey()), 3);
6868 rent_collected += generic_rent_due_for_system_account;
6869
6870 assert_eq!(bank.get_balance(&keypairs[2].pubkey()), 1);
6872 rent_collected += generic_rent_due_for_system_account;
6873
6874 assert_eq!(bank.get_balance(&keypairs[3].pubkey()), 3);
6876 rent_collected += generic_rent_due_for_system_account;
6877
6878 assert_eq!(bank.get_balance(&keypairs[4].pubkey()), 10);
6880 assert_eq!(bank.get_balance(&keypairs[5].pubkey()), 10);
6881
6882 assert_eq!(bank.get_balance(&keypairs[6].pubkey()), 23);
6884 rent_collected += generic_rent_due_for_system_account;
6885
6886 assert_eq!(
6888 bank.get_balance(&keypairs[7].pubkey()),
6889 generic_rent_due_for_system_account + 1 - magic_rent_number
6890 );
6891
6892 let account8 = bank.get_account(&keypairs[7].pubkey()).unwrap();
6895 assert_eq!(account8.rent_epoch(), bank.epoch + 1);
6897 rent_collected += magic_rent_number;
6898
6899 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 assert_eq!(account10.rent_epoch(), bank.epoch + 1);
6907 assert_eq!(account10.data().len(), 0);
6909 assert_eq!(account10.carats(), 929 - magic_rent_number);
6911 rent_collected += magic_rent_number + 10;
6912
6913 assert_eq!(bank.get_balance(&keypairs[10].pubkey()), 3);
6915 rent_collected += generic_rent_due_for_system_account;
6916
6917 assert_eq!(bank.get_balance(&keypairs[11].pubkey()), 4);
6919 rent_collected += generic_rent_due_for_system_account;
6920
6921 assert_eq!(bank.get_balance(&keypairs[12].pubkey()), 2);
6923 rent_collected += generic_rent_due_for_system_account;
6924
6925 assert_eq!(bank.get_balance(&keypairs[13].pubkey()), 14);
6927
6928 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 (u64::max_value() - partition_count + 1) % partition_count == 0
7322 }
7323
7324 let max_exact = 64;
7325 assert!(should_cause_overflow(max_exact));
7327 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 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)); 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)); bank2_without_zero.collect_rent_in_partition((0, 0, 1)); 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 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 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 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 bank0.store_account_and_update_capitalization(&stake_id, &stake_account);
7752
7753 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 let bank1 = Bank::new_from_parent(
7786 &bank0,
7787 &Pubkey::default(),
7788 bank0.get_slots_in_epoch(bank0.epoch()) + 1,
7789 );
7790 assert_ne!(bank1.capitalization(), bank0.capitalization());
7792
7793 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 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 let allocated_rewards = rewards.validator_point_value * validator_points as f64;
7814 assert!((allocated_rewards - paid_rewards as f64).abs() < 1.0); 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 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 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 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 bank.store_account_and_update_capitalization(&stake_id1, &stake_account1);
7878 bank.store_account_and_update_capitalization(&stake_id2, &stake_account2);
7879
7880 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 let bank1 = Bank::new_from_parent(
7900 &bank,
7901 &Pubkey::default(),
7902 bank.get_slots_in_epoch(bank.epoch()) + 1,
7903 );
7904 assert_ne!(bank1.capitalization(), bank.capitalization());
7906
7907 bank1.freeze();
7908 assert!(bank1.calculate_and_verify_capitalization(true));
7909
7910 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 let expected_capitalization = do_test_bank_update_rewards_determinism();
7930 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]
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 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 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 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 #[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 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 assert_eq!(bank.get_balance(&dest.pubkey()), 0);
8112
8113 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 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 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 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 assert_eq!(
8218 bank.withdraw(&key.pubkey(), 10),
8219 Err(TransactionError::InsufficientFundsForFee)
8220 );
8221
8222 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 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 bank.withdraw(&nonce.pubkey(), 42).unwrap();
8255 assert_eq!(bank.get_balance(&nonce.pubkey()), min_balance);
8256
8257 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); 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 ); 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 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 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); assert_eq!(
8344 bank.get_balance(&mint_keypair.pubkey()),
8345 mint - arbitrary_transfer_amount - 2 * expected_fee_paid
8346 ); goto_end_of_slot(&mut bank);
8348 assert_eq!(bank.signature_count(), 1);
8349
8350 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 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 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 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_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 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 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 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 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 assert_eq!(
8601 bank.transfer(1, &mint_keypair, &bob.pubkey()),
8602 Err(TransactionError::AccountInUse)
8603 );
8604 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 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 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 #[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 #[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 assert_eq!(bank.process_transaction(&tx), Ok(()));
8748
8749 assert_eq!(
8751 bank.process_transaction(&tx),
8752 Err(TransactionError::AlreadyProcessed)
8753 );
8754
8755 tx.signatures[0] = Signature::default();
8758
8759 assert_eq!(
8761 bank.process_transaction(&tx),
8762 Err(TransactionError::AlreadyProcessed)
8763 );
8764 }
8765
8766 #[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 #[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 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 let bank2 = Bank::new_from_parent(&bank0, &gemachain_sdk::pubkey::new_rand(), 1);
8839 assert_ne!(bank0_state, bank2.hash_internal_state());
8840 assert_ne!(bank0_state, bank0.hash_internal_state());
8842
8843 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 bank.increment_signature_count(1);
8882 assert!(!bank.verify_snapshot_bank(true, false, None));
8883 }
8884
8885 #[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 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 #[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 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 let bank1 = Bank::new_from_parent(&bank0, &collector_id, 1);
8962
8963 assert_ne!(hash0, bank1.hash_internal_state());
8965
8966 bank1.squash();
8968 assert!(bank1.parents().is_empty());
8969 }
8970
8971 #[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 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 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 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 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 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, _>(¤t_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 assert_eq!(old, new);
9197 },
9198 );
9199
9200 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, _>(¤t_account).unwrap().slot
9223 );
9224 assert_eq!(dummy_rent_epoch, current_account.rent_epoch());
9227 },
9228 |old, new| {
9229 assert_eq!(old, new);
9231 },
9232 );
9233
9234 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, _>(¤t_account).unwrap().slot
9258 );
9259 },
9260 |old, new| {
9261 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 const SLOTS_PER_EPOCH: u64 = MINIMUM_SLOTS_PER_EPOCH as u64;
9277 const LEADER_SCHEDULE_SLOT_OFFSET: u64 = SLOTS_PER_EPOCH * 3 - 3;
9278 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, ..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 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 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 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 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 assert!(bank0.is_empty());
9436
9437 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 let bank1 = Arc::new(Bank::new_from_parent(
9451 &bank0,
9452 &gemachain_sdk::pubkey::new_rand(),
9453 1,
9454 ));
9455 let bank2 = Bank::new_from_parent(&bank0, &gemachain_sdk::pubkey::new_rand(), 2);
9457
9458 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); 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); 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 assert_eq!(
9634 bank.process_transaction(&fail_tx),
9635 Err(TransactionError::AccountNotFound)
9636 );
9637
9638 assert!(!bank.is_delta.load(Relaxed));
9640
9641 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 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 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 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 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 {
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 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 assert_eq!(recent_blockhashes.len(), i);
9988 let most_recent_hash = recent_blockhashes.iter().next().unwrap().blockhash;
9989 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 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 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 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 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 let nonce_hash = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10340
10341 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 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 assert_eq!(bank.get_balance(&custodian_pubkey), 4_750_000);
10359
10360 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 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 let new_nonce = get_nonce_account(&bank, &nonce_pubkey).unwrap();
10386 assert_ne!(nonce_hash, new_nonce);
10387
10388 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 let program1_pubkey = gemachain_sdk::pubkey::new_rand();
11258 bank.add_builtin("program", program1_pubkey, nested_processor);
11259
11260 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 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 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 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 bank0.force_flush_accounts_cache();
11336
11337 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 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 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 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 bank0.force_flush_accounts_cache();
11416
11417 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 bank1.force_flush_accounts_cache();
11428
11429 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 bank2.clean_accounts(false, false, None);
11441
11442 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 assert_eq!(bank2.shrink_candidate_slots(), 0);
11458 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 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 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 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); let vote_pubkey = gemachain_sdk::pubkey::new_rand();
11539 let authorized_voter = Keypair::new();
11540
11541 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); 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); 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); }
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 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 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 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 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 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 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 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 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 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!(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 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 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 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 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 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 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 let feature = Feature::default();
12186 assert_eq!(feature.activated_at, None);
12187 bank.store_account(&test_feature, &feature::create_account(&feature, 42));
12188
12189 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 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 bank.feature_set = Arc::new(feature_set);
12207 assert!(!bank.feature_set.is_active(&test_feature));
12208
12209 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 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 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 assert_eq!(
12251 bank.get_balance(&inline_spl_token_v2_0::new_token_program::id()),
12252 0
12253 );
12254
12255 assert_eq!(
12257 bank.get_account(&inline_spl_token_v2_0::id()),
12258 Some(new_token_account)
12259 );
12260
12261 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 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 #[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(&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 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 bank2.collect_rent_in_partition((0, 0, 1)); assert_eq!(bank2.get_program_accounts(&sysvar::id()).unwrap().len(), 8);
12353 }
12354
12355 #[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 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 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 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 #[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(&mut genesis_config);
12440 genesis_config
12441 .accounts
12442 .remove(&feature_set::rent_for_sysvars::id());
12443 genesis_config
12445 .accounts
12446 .remove(&feature_set::deprecate_rewards_sysvar::id());
12447
12448 #[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 let bank1 = Arc::new(Bank::new_from_parent(
12486 &bank0,
12487 &Pubkey::default(),
12488 bank0.first_slot_in_next_epoch(),
12489 ));
12490
12491 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 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 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 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; 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 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 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 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 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 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; 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 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 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 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 for key in &all_pubkeys {
12919 bank0.store_account(key, &starting_account);
12920 }
12921
12922 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 let pubkeys_to_modify_ = pubkeys_to_modify.clone();
12934
12935 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 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 expected_carats = Some(account_balance);
12998 }
12999 }
13000 }
13001
13002 assert_eq!(target_accounts_found.len(), total_pubkeys_to_modify);
13005 }
13006 }
13007 }
13008 })
13009 .unwrap()
13010 };
13011
13012 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 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; }
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 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 ¤t_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 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 assert_eq!(
13093 current_minor_fork_bank.clone().parents_inclusive().len(),
13094 num_new_banks + 1,
13095 );
13096
13097 current_major_fork_bank = Arc::new(Bank::new_from_parent(
13101 ¤t_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 current_major_fork_bank.store_account(key, &account);
13111 }
13112
13113 if bank_to_scan_sender.send(current_minor_fork_bank).is_err() {
13128 return;
13130 }
13131 current_major_fork_bank.freeze();
13132 current_major_fork_bank.squash();
13133 current_major_fork_bank.force_flush_accounts_cache();
13135 current_major_fork_bank.clean_accounts(false, false, None);
13136 let is_abs_service = true;
13139 abs_request_handler
13140 .handle_pruned_banks(¤t_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 if bank_to_scan_sender.send(prev_bank).is_err() {
13179 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 ¤t_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 assert!(pubkeys_to_modify.len() > 1);
13212
13213 let mut bank_at_fork_tip = bank0;
13215
13216 let mut slots_on_fork = Vec::with_capacity(num_banks_on_fork);
13218
13219 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 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 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 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 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 if prev_bank.slot() != 0 {
13337 info!(
13338 "sending bank with slot: {:?}, elapsed: {}",
13339 prev_bank.slot(),
13340 start.elapsed().as_millis()
13341 );
13342 for k in pubkeys_to_modify.iter() {
13346 assert!(bank_at_fork_tip.load_slow(&ancestors, k).is_some());
13347 }
13348
13349 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 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 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 for k in pubkeys_to_modify.iter() {
13400 assert!(bank_at_fork_tip.load_slow(&ancestors, k).is_some());
13401 }
13402
13403 if bank_to_scan_sender.send(bank_at_fork_tip.clone()).is_err() {
13407 return;
13408 }
13409
13410 let slot_to_remove = *slots_on_fork.last().unwrap();
13414 bank_at_fork_tip.remove_unrooted_slots(&[slot_to_remove]);
13415
13416 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 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 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 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 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 bank = new_from_parent(&Arc::new(bank));
13477 assert_eq!(bank.slot(), 3);
13478
13479 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 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 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 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 bank = new_from_parent(&Arc::new(bank));
13558 assert_eq!(bank.slot(), 3);
13559
13560 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 bank = new_from_parent(&Arc::new(bank));
13585 assert_eq!(bank.slot(), 4);
13586
13587 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 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 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 bank.store_account(
13710 &validator_vote_keypairs0.vote_keypair.pubkey(),
13711 &vote_account,
13712 );
13713
13714 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 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 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); 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 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 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 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 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 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 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 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 enum FreezeBank1 {
14069 No,
14070 Yes,
14071 }
14072
14073 fn do_test_clean_dropped_unrooted_banks(freeze_bank1: FreezeBank1) {
14074 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(); let key2 = Keypair::new(); let key3 = Keypair::new(); let key4 = Keypair::new(); let key5 = Keypair::new(); 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(); 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 rent_debits.push(&Pubkey::default(), 0, 0);
14184 assert_eq!(rent_debits.0.len(), 0);
14185
14186 rent_debits.push(&Pubkey::default(), u64::MAX, 0);
14188 assert_eq!(rent_debits.0.len(), 0);
14189
14190 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(&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 {
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 {
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 {
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 {
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 {
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 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}