Simd 118: extend EpochRewards sysvar (#428)
* Update EpochRewards sysvar * Update Clone trait * Update doctests * Update bank to new sysvar fields * Update runtime tests * Update syscall test * Update tests * Clean up doctest EpochRewards construction
This commit is contained in:
parent
8246590f47
commit
ecb4f62887
|
@ -372,9 +372,11 @@ mod test {
|
||||||
);
|
);
|
||||||
|
|
||||||
let epoch_rewards = EpochRewards {
|
let epoch_rewards = EpochRewards {
|
||||||
|
distribution_starting_block_height: 42,
|
||||||
total_rewards: 100,
|
total_rewards: 100,
|
||||||
distributed_rewards: 20,
|
distributed_rewards: 20,
|
||||||
distribution_complete_block_height: 42,
|
active: true,
|
||||||
|
..EpochRewards::default()
|
||||||
};
|
};
|
||||||
let epoch_rewards_sysvar = create_account_for_test(&epoch_rewards);
|
let epoch_rewards_sysvar = create_account_for_test(&epoch_rewards);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -3317,16 +3317,20 @@ mod tests {
|
||||||
src_rent.burn_percent = 3;
|
src_rent.burn_percent = 3;
|
||||||
|
|
||||||
let mut src_rewards = create_filled_type::<EpochRewards>(false);
|
let mut src_rewards = create_filled_type::<EpochRewards>(false);
|
||||||
|
src_rewards.distribution_starting_block_height = 42;
|
||||||
|
src_rewards.num_partitions = 2;
|
||||||
|
src_rewards.parent_blockhash = Hash::new(&[3; 32]);
|
||||||
|
src_rewards.total_points = 4;
|
||||||
src_rewards.total_rewards = 100;
|
src_rewards.total_rewards = 100;
|
||||||
src_rewards.distributed_rewards = 10;
|
src_rewards.distributed_rewards = 10;
|
||||||
src_rewards.distribution_complete_block_height = 42;
|
src_rewards.active = true;
|
||||||
|
|
||||||
let mut sysvar_cache = SysvarCache::default();
|
let mut sysvar_cache = SysvarCache::default();
|
||||||
sysvar_cache.set_clock(src_clock.clone());
|
sysvar_cache.set_clock(src_clock.clone());
|
||||||
sysvar_cache.set_epoch_schedule(src_epochschedule.clone());
|
sysvar_cache.set_epoch_schedule(src_epochschedule.clone());
|
||||||
sysvar_cache.set_fees(src_fees.clone());
|
sysvar_cache.set_fees(src_fees.clone());
|
||||||
sysvar_cache.set_rent(src_rent.clone());
|
sysvar_cache.set_rent(src_rent.clone());
|
||||||
sysvar_cache.set_epoch_rewards(src_rewards);
|
sysvar_cache.set_epoch_rewards(src_rewards.clone());
|
||||||
|
|
||||||
let transaction_accounts = vec![
|
let transaction_accounts = vec![
|
||||||
(
|
(
|
||||||
|
@ -3519,10 +3523,14 @@ mod tests {
|
||||||
assert_eq!(got_rewards, src_rewards);
|
assert_eq!(got_rewards, src_rewards);
|
||||||
|
|
||||||
let mut clean_rewards = create_filled_type::<EpochRewards>(true);
|
let mut clean_rewards = create_filled_type::<EpochRewards>(true);
|
||||||
|
clean_rewards.distribution_starting_block_height =
|
||||||
|
src_rewards.distribution_starting_block_height;
|
||||||
|
clean_rewards.num_partitions = src_rewards.num_partitions;
|
||||||
|
clean_rewards.parent_blockhash = src_rewards.parent_blockhash;
|
||||||
|
clean_rewards.total_points = src_rewards.total_points;
|
||||||
clean_rewards.total_rewards = src_rewards.total_rewards;
|
clean_rewards.total_rewards = src_rewards.total_rewards;
|
||||||
clean_rewards.distributed_rewards = src_rewards.distributed_rewards;
|
clean_rewards.distributed_rewards = src_rewards.distributed_rewards;
|
||||||
clean_rewards.distribution_complete_block_height =
|
clean_rewards.active = src_rewards.active;
|
||||||
src_rewards.distribution_complete_block_height;
|
|
||||||
assert!(are_bytes_equal(&got_rewards, &clean_rewards));
|
assert!(are_bytes_equal(&got_rewards, &clean_rewards));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,11 @@ async fn test_sysvars() {
|
||||||
);
|
);
|
||||||
|
|
||||||
let epoch_rewards = epoch_rewards::EpochRewards {
|
let epoch_rewards = epoch_rewards::EpochRewards {
|
||||||
|
distribution_starting_block_height: 42,
|
||||||
total_rewards: 100,
|
total_rewards: 100,
|
||||||
distributed_rewards: 50,
|
distributed_rewards: 50,
|
||||||
distribution_complete_block_height: 42,
|
active: true,
|
||||||
|
..epoch_rewards::EpochRewards::default()
|
||||||
};
|
};
|
||||||
program_test.add_sysvar_account(epoch_rewards::id(), &epoch_rewards);
|
program_test.add_sysvar_account(epoch_rewards::id(), &epoch_rewards);
|
||||||
let (mut banks_client, payer, recent_blockhash) = program_test.start().await;
|
let (mut banks_client, payer, recent_blockhash) = program_test.start().await;
|
||||||
|
|
|
@ -1673,13 +1673,12 @@ impl Bank {
|
||||||
|
|
||||||
let slot = self.slot();
|
let slot = self.slot();
|
||||||
let credit_start = self.block_height() + self.get_reward_calculation_num_blocks();
|
let credit_start = self.block_height() + self.get_reward_calculation_num_blocks();
|
||||||
let credit_end_exclusive = credit_start + stake_rewards_by_partition.len() as u64;
|
|
||||||
|
|
||||||
self.set_epoch_reward_status_active(stake_rewards_by_partition);
|
self.set_epoch_reward_status_active(stake_rewards_by_partition);
|
||||||
|
|
||||||
// create EpochRewards sysvar that holds the balance of undistributed rewards with
|
// create EpochRewards sysvar that holds the balance of undistributed rewards with
|
||||||
// (total_rewards, distributed_rewards, credit_end_exclusive), total capital will increase by (total_rewards - distributed_rewards)
|
// (total_rewards, distributed_rewards, credit_start), total capital will increase by (total_rewards - distributed_rewards)
|
||||||
self.create_epoch_rewards_sysvar(total_rewards, distributed_rewards, credit_end_exclusive);
|
self.create_epoch_rewards_sysvar(total_rewards, distributed_rewards, credit_start);
|
||||||
|
|
||||||
datapoint_info!(
|
datapoint_info!(
|
||||||
"epoch-rewards-status-update",
|
"epoch-rewards-status-update",
|
||||||
|
@ -3615,14 +3614,16 @@ impl Bank {
|
||||||
&self,
|
&self,
|
||||||
total_rewards: u64,
|
total_rewards: u64,
|
||||||
distributed_rewards: u64,
|
distributed_rewards: u64,
|
||||||
distribution_complete_block_height: u64,
|
distribution_starting_block_height: u64,
|
||||||
) {
|
) {
|
||||||
assert!(self.is_partitioned_rewards_code_enabled());
|
assert!(self.is_partitioned_rewards_code_enabled());
|
||||||
|
|
||||||
let epoch_rewards = sysvar::epoch_rewards::EpochRewards {
|
let epoch_rewards = sysvar::epoch_rewards::EpochRewards {
|
||||||
total_rewards,
|
total_rewards,
|
||||||
distributed_rewards,
|
distributed_rewards,
|
||||||
distribution_complete_block_height,
|
distribution_starting_block_height,
|
||||||
|
active: true,
|
||||||
|
..sysvar::epoch_rewards::EpochRewards::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
self.update_sysvar_account(&sysvar::epoch_rewards::id(), |account| {
|
self.update_sysvar_account(&sysvar::epoch_rewards::id(), |account| {
|
||||||
|
|
|
@ -6,7 +6,7 @@ mod tests {
|
||||||
use {
|
use {
|
||||||
super::*,
|
super::*,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
feature_set, genesis_config::create_genesis_config, pubkey::Pubkey,
|
feature_set, genesis_config::create_genesis_config, hash::Hash, pubkey::Pubkey,
|
||||||
sysvar::epoch_rewards::EpochRewards,
|
sysvar::epoch_rewards::EpochRewards,
|
||||||
},
|
},
|
||||||
std::sync::Arc,
|
std::sync::Arc,
|
||||||
|
@ -121,14 +121,18 @@ mod tests {
|
||||||
// inject a reward sysvar for test
|
// inject a reward sysvar for test
|
||||||
bank1.activate_feature(&feature_set::enable_partitioned_epoch_reward::id());
|
bank1.activate_feature(&feature_set::enable_partitioned_epoch_reward::id());
|
||||||
let expected_epoch_rewards = EpochRewards {
|
let expected_epoch_rewards = EpochRewards {
|
||||||
|
distribution_starting_block_height: 42,
|
||||||
|
num_partitions: 0,
|
||||||
|
parent_blockhash: Hash::default(),
|
||||||
|
total_points: 0,
|
||||||
total_rewards: 100,
|
total_rewards: 100,
|
||||||
distributed_rewards: 10,
|
distributed_rewards: 10,
|
||||||
distribution_complete_block_height: 42,
|
active: true,
|
||||||
};
|
};
|
||||||
bank1.create_epoch_rewards_sysvar(
|
bank1.create_epoch_rewards_sysvar(
|
||||||
expected_epoch_rewards.total_rewards,
|
expected_epoch_rewards.total_rewards,
|
||||||
expected_epoch_rewards.distributed_rewards,
|
expected_epoch_rewards.distributed_rewards,
|
||||||
expected_epoch_rewards.distribution_complete_block_height,
|
expected_epoch_rewards.distribution_starting_block_height,
|
||||||
);
|
);
|
||||||
|
|
||||||
bank1
|
bank1
|
||||||
|
|
|
@ -12715,9 +12715,13 @@ fn test_epoch_rewards_sysvar() {
|
||||||
|
|
||||||
// create epoch rewards sysvar
|
// create epoch rewards sysvar
|
||||||
let expected_epoch_rewards = sysvar::epoch_rewards::EpochRewards {
|
let expected_epoch_rewards = sysvar::epoch_rewards::EpochRewards {
|
||||||
|
distribution_starting_block_height: 42,
|
||||||
|
num_partitions: 0,
|
||||||
|
parent_blockhash: Hash::default(),
|
||||||
|
total_points: 0,
|
||||||
total_rewards,
|
total_rewards,
|
||||||
distributed_rewards: 10,
|
distributed_rewards: 10,
|
||||||
distribution_complete_block_height: 42,
|
active: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
bank.create_epoch_rewards_sysvar(total_rewards, 10, 42);
|
bank.create_epoch_rewards_sysvar(total_rewards, 10, 42);
|
||||||
|
@ -12732,9 +12736,13 @@ fn test_epoch_rewards_sysvar() {
|
||||||
assert_eq!(account.lamports(), total_rewards - 20);
|
assert_eq!(account.lamports(), total_rewards - 20);
|
||||||
let epoch_rewards: sysvar::epoch_rewards::EpochRewards = from_account(&account).unwrap();
|
let epoch_rewards: sysvar::epoch_rewards::EpochRewards = from_account(&account).unwrap();
|
||||||
let expected_epoch_rewards = sysvar::epoch_rewards::EpochRewards {
|
let expected_epoch_rewards = sysvar::epoch_rewards::EpochRewards {
|
||||||
|
distribution_starting_block_height: 42,
|
||||||
|
num_partitions: 0,
|
||||||
|
parent_blockhash: Hash::default(),
|
||||||
|
total_points: 0,
|
||||||
total_rewards,
|
total_rewards,
|
||||||
distributed_rewards: 20,
|
distributed_rewards: 20,
|
||||||
distribution_complete_block_height: 42,
|
active: true,
|
||||||
};
|
};
|
||||||
assert_eq!(epoch_rewards, expected_epoch_rewards);
|
assert_eq!(epoch_rewards, expected_epoch_rewards);
|
||||||
|
|
||||||
|
|
|
@ -6,20 +6,37 @@
|
||||||
//!
|
//!
|
||||||
//! [`sysvar::epoch_rewards`]: crate::sysvar::epoch_rewards
|
//! [`sysvar::epoch_rewards`]: crate::sysvar::epoch_rewards
|
||||||
|
|
||||||
use std::ops::AddAssign;
|
use {crate::hash::Hash, solana_sdk_macro::CloneZeroed, std::ops::AddAssign};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C, align(16))]
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default, Clone, Copy, AbiExample)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default, AbiExample, CloneZeroed)]
|
||||||
pub struct EpochRewards {
|
pub struct EpochRewards {
|
||||||
/// total rewards for the current epoch, in lamports
|
/// The starting block height of the rewards distribution in the current
|
||||||
|
/// epoch
|
||||||
|
pub distribution_starting_block_height: u64,
|
||||||
|
|
||||||
|
/// Number of partitions in the rewards distribution in the current epoch,
|
||||||
|
/// used to generate an EpochRewardsHasher
|
||||||
|
pub num_partitions: u64,
|
||||||
|
|
||||||
|
/// The blockhash of the parent block of the first block in the epoch, used
|
||||||
|
/// to seed an EpochRewardsHasher
|
||||||
|
pub parent_blockhash: Hash,
|
||||||
|
|
||||||
|
/// The total rewards points calculated for the current epoch, where points
|
||||||
|
/// equals the sum of (delegated stake * credits observed) for all
|
||||||
|
/// delegations
|
||||||
|
pub total_points: u128,
|
||||||
|
|
||||||
|
/// The total rewards for the current epoch, in lamports
|
||||||
pub total_rewards: u64,
|
pub total_rewards: u64,
|
||||||
|
|
||||||
/// distributed rewards for the current epoch, in lamports
|
/// The rewards currently distributed for the current epoch, in lamports
|
||||||
pub distributed_rewards: u64,
|
pub distributed_rewards: u64,
|
||||||
|
|
||||||
/// distribution of all staking rewards for the current
|
/// Whether the rewards period (including calculation and distribution) is
|
||||||
/// epoch will be completed at this block height
|
/// active
|
||||||
pub distribution_complete_block_height: u64,
|
pub active: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EpochRewards {
|
impl EpochRewards {
|
||||||
|
@ -38,12 +55,13 @@ mod tests {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
total_rewards: u64,
|
total_rewards: u64,
|
||||||
distributed_rewards: u64,
|
distributed_rewards: u64,
|
||||||
distribution_complete_block_height: u64,
|
distribution_starting_block_height: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
total_rewards,
|
total_rewards,
|
||||||
distributed_rewards,
|
distributed_rewards,
|
||||||
distribution_complete_block_height,
|
distribution_starting_block_height,
|
||||||
|
..Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +72,7 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(epoch_rewards.total_rewards, 100);
|
assert_eq!(epoch_rewards.total_rewards, 100);
|
||||||
assert_eq!(epoch_rewards.distributed_rewards, 0);
|
assert_eq!(epoch_rewards.distributed_rewards, 0);
|
||||||
assert_eq!(epoch_rewards.distribution_complete_block_height, 64);
|
assert_eq!(epoch_rewards.distribution_starting_block_height, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
//! Epoch rewards for current epoch
|
//! Epoch rewards for current epoch
|
||||||
//!
|
//!
|
||||||
//! The _epoch rewards_ sysvar provides access to the [`EpochRewards`] type,
|
//! The _epoch rewards_ sysvar provides access to the [`EpochRewards`] type,
|
||||||
//! which tracks the progress of epoch rewards distribution. It includes the
|
//! which tracks whether the rewards period (including calculation and
|
||||||
//! - total rewards for the current epoch, in lamports
|
//! distribution) is in progress, as well as the details needed to resume
|
||||||
//! - rewards for the current epoch distributed so far, in lamports
|
//! distribution when starting from a snapshot during the rewards period. The
|
||||||
//! - distribution completed block height, i.e. distribution of all staking rewards for the current
|
//! sysvar is repopulated at the start of the first block of each epoch.
|
||||||
//! epoch will be completed at this block height
|
//! Therefore, the sysvar contains data about the current epoch until a new
|
||||||
|
//! epoch begins. Fields in the sysvar include:
|
||||||
|
//! - distribution starting block height
|
||||||
|
//! - the number of partitions in the distribution
|
||||||
|
//! - the parent-blockhash seed used to generate the partition hasher
|
||||||
|
//! - the total rewards points calculated for the epoch
|
||||||
|
//! - total rewards for epoch, in lamports
|
||||||
|
//! - rewards for the epoch distributed so far, in lamports
|
||||||
|
//! - whether the rewards period is active
|
||||||
//!
|
//!
|
||||||
//! [`EpochRewards`] implements [`Sysvar::get`] and can be loaded efficiently without
|
//! [`EpochRewards`] implements [`Sysvar::get`] and can be loaded efficiently without
|
||||||
//! passing the sysvar account ID to the program.
|
//! passing the sysvar account ID to the program.
|
||||||
|
@ -43,9 +51,16 @@
|
||||||
//! #
|
//! #
|
||||||
//! # use solana_program::sysvar::SysvarId;
|
//! # use solana_program::sysvar::SysvarId;
|
||||||
//! # let p = EpochRewards::id();
|
//! # let p = EpochRewards::id();
|
||||||
//! # let l = &mut 1120560;
|
//! # let l = &mut 1559040;
|
||||||
//! # let d = &mut vec![0, 202, 154, 59, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0];
|
//! # let epoch_rewards = EpochRewards {
|
||||||
//! # let a = AccountInfo::new(&p, false, false, l, d, &p, false, 0);
|
//! # distribution_starting_block_height: 42,
|
||||||
|
//! # total_rewards: 100,
|
||||||
|
//! # distributed_rewards: 10,
|
||||||
|
//! # active: true,
|
||||||
|
//! # ..EpochRewards::default()
|
||||||
|
//! # };
|
||||||
|
//! # let mut d: Vec<u8> = bincode::serialize(&epoch_rewards).unwrap();
|
||||||
|
//! # let a = AccountInfo::new(&p, false, false, l, &mut d, &p, false, 0);
|
||||||
//! # let accounts = &[a.clone(), a];
|
//! # let accounts = &[a.clone(), a];
|
||||||
//! # process_instruction(
|
//! # process_instruction(
|
||||||
//! # &Pubkey::new_unique(),
|
//! # &Pubkey::new_unique(),
|
||||||
|
@ -86,9 +101,16 @@
|
||||||
//! #
|
//! #
|
||||||
//! # use solana_program::sysvar::SysvarId;
|
//! # use solana_program::sysvar::SysvarId;
|
||||||
//! # let p = EpochRewards::id();
|
//! # let p = EpochRewards::id();
|
||||||
//! # let l = &mut 1120560;
|
//! # let l = &mut 1559040;
|
||||||
//! # let d = &mut vec![0, 202, 154, 59, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0];
|
//! # let epoch_rewards = EpochRewards {
|
||||||
//! # let a = AccountInfo::new(&p, false, false, l, d, &p, false, 0);
|
//! # distribution_starting_block_height: 42,
|
||||||
|
//! # total_rewards: 100,
|
||||||
|
//! # distributed_rewards: 10,
|
||||||
|
//! # active: true,
|
||||||
|
//! # ..EpochRewards::default()
|
||||||
|
//! # };
|
||||||
|
//! # let mut d: Vec<u8> = bincode::serialize(&epoch_rewards).unwrap();
|
||||||
|
//! # let a = AccountInfo::new(&p, false, false, l, &mut d, &p, false, 0);
|
||||||
//! # let accounts = &[a.clone(), a];
|
//! # let accounts = &[a.clone(), a];
|
||||||
//! # process_instruction(
|
//! # process_instruction(
|
||||||
//! # &Pubkey::new_unique(),
|
//! # &Pubkey::new_unique(),
|
||||||
|
@ -109,9 +131,17 @@
|
||||||
//! # use anyhow::Result;
|
//! # use anyhow::Result;
|
||||||
//! #
|
//! #
|
||||||
//! fn print_sysvar_epoch_rewards(client: &RpcClient) -> Result<()> {
|
//! fn print_sysvar_epoch_rewards(client: &RpcClient) -> Result<()> {
|
||||||
|
//! # let epoch_rewards = EpochRewards {
|
||||||
|
//! # distribution_starting_block_height: 42,
|
||||||
|
//! # total_rewards: 100,
|
||||||
|
//! # distributed_rewards: 10,
|
||||||
|
//! # active: true,
|
||||||
|
//! # ..EpochRewards::default()
|
||||||
|
//! # };
|
||||||
|
//! # let data: Vec<u8> = bincode::serialize(&epoch_rewards)?;
|
||||||
//! # client.set_get_account_response(epoch_rewards::ID, Account {
|
//! # client.set_get_account_response(epoch_rewards::ID, Account {
|
||||||
//! # lamports: 1120560,
|
//! # lamports: 1120560,
|
||||||
//! # data: vec![0, 202, 154, 59, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0],
|
//! # data,
|
||||||
//! # owner: solana_sdk::system_program::ID,
|
//! # owner: solana_sdk::system_program::ID,
|
||||||
//! # executable: false,
|
//! # executable: false,
|
||||||
//! # rent_epoch: 307,
|
//! # rent_epoch: 307,
|
||||||
|
|
Loading…
Reference in New Issue