sysvar.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. use {
  2. solana_account_info::AccountInfo,
  3. solana_clock::Clock,
  4. solana_epoch_rewards::EpochRewards,
  5. solana_epoch_schedule::EpochSchedule,
  6. solana_instruction::Instruction,
  7. solana_msg::msg,
  8. solana_program_error::ProgramResult,
  9. solana_program_test::{processor, ProgramTest},
  10. solana_pubkey::Pubkey,
  11. solana_rent::Rent,
  12. solana_signer::Signer,
  13. solana_sysvar::Sysvar,
  14. solana_transaction::Transaction,
  15. };
  16. // Process instruction to invoke into another program
  17. fn sysvar_getter_process_instruction(
  18. _program_id: &Pubkey,
  19. _accounts: &[AccountInfo],
  20. _input: &[u8],
  21. ) -> ProgramResult {
  22. msg!("sysvar_getter");
  23. let clock = Clock::get()?;
  24. assert_eq!(42, clock.slot);
  25. let epoch_schedule = EpochSchedule::get()?;
  26. assert_eq!(epoch_schedule, EpochSchedule::default());
  27. let rent = Rent::get()?;
  28. assert_eq!(rent, Rent::default());
  29. Ok(())
  30. }
  31. #[tokio::test]
  32. async fn get_sysvar() {
  33. let program_id = Pubkey::new_unique();
  34. let program_test = ProgramTest::new(
  35. "sysvar_getter",
  36. program_id,
  37. processor!(sysvar_getter_process_instruction),
  38. );
  39. let mut context = program_test.start_with_context().await;
  40. context.warp_to_slot(42).unwrap();
  41. let instructions = vec![Instruction::new_with_bincode(program_id, &(), vec![])];
  42. let transaction = Transaction::new_signed_with_payer(
  43. &instructions,
  44. Some(&context.payer.pubkey()),
  45. &[&context.payer],
  46. context.last_blockhash,
  47. );
  48. context
  49. .banks_client
  50. .process_transaction(transaction)
  51. .await
  52. .unwrap();
  53. }
  54. fn epoch_reward_sysvar_getter_process_instruction(
  55. _program_id: &Pubkey,
  56. _accounts: &[AccountInfo],
  57. input: &[u8],
  58. ) -> ProgramResult {
  59. msg!("epoch_reward_sysvar_getter");
  60. // input[0] == 0 indicates the bank is not in reward period.
  61. // input[0] == 1 indicates the bank is in reward period.
  62. if input[0] == 0 {
  63. // epoch rewards sysvar should not exist for banks that are not in reward period
  64. let epoch_rewards = EpochRewards::get()?;
  65. assert!(!epoch_rewards.active);
  66. } else {
  67. let epoch_rewards = EpochRewards::get()?;
  68. assert!(epoch_rewards.active);
  69. }
  70. Ok(())
  71. }
  72. #[tokio::test]
  73. async fn get_epoch_rewards_sysvar() {
  74. let program_id = Pubkey::new_unique();
  75. let program_test = ProgramTest::new(
  76. "epoch_reward_sysvar_getter",
  77. program_id,
  78. processor!(epoch_reward_sysvar_getter_process_instruction),
  79. );
  80. let mut context = program_test.start_with_context().await;
  81. // wrap to 1st slot before next epoch (outside reward interval)
  82. let first_normal_slot = context.genesis_config().epoch_schedule.first_normal_slot;
  83. let slots_per_epoch = context.genesis_config().epoch_schedule.slots_per_epoch;
  84. let last_slot_before_new_epoch = first_normal_slot
  85. .saturating_add(slots_per_epoch)
  86. .saturating_sub(1);
  87. context.warp_to_slot(last_slot_before_new_epoch).unwrap();
  88. // outside of reward interval, set input[0] == 0, so that the program assert that epoch_rewards sysvar doesn't exist.
  89. let instructions = vec![Instruction::new_with_bincode(program_id, &[0u8], vec![])];
  90. let transaction = Transaction::new_signed_with_payer(
  91. &instructions,
  92. Some(&context.payer.pubkey()),
  93. &[&context.payer],
  94. context.last_blockhash,
  95. );
  96. context
  97. .banks_client
  98. .process_transaction(transaction)
  99. .await
  100. .unwrap();
  101. // wrap to 1st slot of next epoch (inside reward interval)
  102. let first_slot_in_new_epoch = first_normal_slot.saturating_add(slots_per_epoch);
  103. context.warp_to_slot(first_slot_in_new_epoch).unwrap();
  104. // inside of reward interval, set input[0] == 1, so that the program assert that epoch_rewards sysvar exist.
  105. let instructions = vec![Instruction::new_with_bincode(program_id, &[1u8], vec![])];
  106. let transaction = Transaction::new_signed_with_payer(
  107. &instructions,
  108. Some(&context.payer.pubkey()),
  109. &[&context.payer],
  110. context.last_blockhash,
  111. );
  112. context
  113. .banks_client
  114. .process_transaction(transaction)
  115. .await
  116. .unwrap();
  117. }