Add epoch_rewards syscalls (#32159)
Co-authored-by: HaoranYi <haoran.yi@solana.com>
This commit is contained in:
parent
6f72258e3e
commit
b12180b863
|
@ -15,7 +15,9 @@ use {
|
|||
slot_hashes::SlotHashes,
|
||||
slot_history::{self, SlotHistory},
|
||||
stake_history::{StakeHistory, StakeHistoryEntry},
|
||||
sysvar::{self, last_restart_slot::LastRestartSlot, rewards::Rewards},
|
||||
sysvar::{
|
||||
self, epoch_rewards::EpochRewards, last_restart_slot::LastRestartSlot, rewards::Rewards,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -89,6 +91,10 @@ pub fn parse_sysvar(data: &[u8], pubkey: &Pubkey) -> Result<SysvarAccountType, P
|
|||
let last_restart_slot = last_restart_slot.last_restart_slot;
|
||||
SysvarAccountType::LastRestartSlot(UiLastRestartSlot { last_restart_slot })
|
||||
})
|
||||
} else if pubkey == &sysvar::epoch_rewards::id() {
|
||||
deserialize::<EpochRewards>(data)
|
||||
.ok()
|
||||
.map(SysvarAccountType::EpochRewards)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -113,6 +119,7 @@ pub enum SysvarAccountType {
|
|||
SlotHistory(UiSlotHistory),
|
||||
StakeHistory(Vec<UiStakeHistoryEntry>),
|
||||
LastRestartSlot(UiLastRestartSlot),
|
||||
EpochRewards(EpochRewards),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
|
||||
|
@ -363,5 +370,16 @@ mod test {
|
|||
last_restart_slot: 1282
|
||||
})
|
||||
);
|
||||
|
||||
let epoch_rewards = EpochRewards {
|
||||
total_rewards: 100,
|
||||
distributed_rewards: 20,
|
||||
distribution_complete_block_height: 42,
|
||||
};
|
||||
let epoch_rewards_sysvar = create_account_for_test(&epoch_rewards);
|
||||
assert_eq!(
|
||||
parse_sysvar(&epoch_rewards_sysvar.data, &sysvar::epoch_rewards::id()).unwrap(),
|
||||
SysvarAccountType::EpochRewards(epoch_rewards),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ pub use self::{
|
|||
},
|
||||
mem_ops::{SyscallMemcmp, SyscallMemcpy, SyscallMemmove, SyscallMemset},
|
||||
sysvar::{
|
||||
SyscallGetClockSysvar, SyscallGetEpochScheduleSysvar, SyscallGetFeesSysvar,
|
||||
SyscallGetLastRestartSlotSysvar, SyscallGetRentSysvar,
|
||||
SyscallGetClockSysvar, SyscallGetEpochRewardsSysvar, SyscallGetEpochScheduleSysvar,
|
||||
SyscallGetFeesSysvar, SyscallGetLastRestartSlotSysvar, SyscallGetRentSysvar,
|
||||
},
|
||||
};
|
||||
#[allow(deprecated)]
|
||||
|
@ -36,7 +36,7 @@ use {
|
|||
self, blake3_syscall_enabled, curve25519_syscall_enabled,
|
||||
disable_cpi_setting_executable_and_rent_epoch, disable_deploy_of_alloc_free_syscall,
|
||||
disable_fees_sysvar, enable_alt_bn128_syscall, enable_big_mod_exp_syscall,
|
||||
enable_early_verification_of_account_modifications,
|
||||
enable_early_verification_of_account_modifications, enable_partitioned_epoch_reward,
|
||||
error_on_syscall_bpf_function_hash_collisions, last_restart_slot_sysvar,
|
||||
libsecp256k1_0_5_upgrade_enabled, reject_callx_r10,
|
||||
stop_sibling_instruction_search_at_parent, stop_truncating_strings_in_syscalls,
|
||||
|
@ -186,6 +186,8 @@ pub fn create_program_runtime_environment<'a>(
|
|||
let blake3_syscall_enabled = feature_set.is_active(&blake3_syscall_enabled::id());
|
||||
let curve25519_syscall_enabled = feature_set.is_active(&curve25519_syscall_enabled::id());
|
||||
let disable_fees_sysvar = feature_set.is_active(&disable_fees_sysvar::id());
|
||||
let epoch_rewards_syscall_enabled =
|
||||
feature_set.is_active(&enable_partitioned_epoch_reward::id());
|
||||
let disable_deploy_of_alloc_free_syscall = reject_deployment_of_broken_elfs
|
||||
&& feature_set.is_active(&disable_deploy_of_alloc_free_syscall::id());
|
||||
let last_restart_slot_syscall_enabled = feature_set.is_active(&last_restart_slot_sysvar::id());
|
||||
|
@ -272,6 +274,13 @@ pub fn create_program_runtime_environment<'a>(
|
|||
SyscallGetLastRestartSlotSysvar::call,
|
||||
)?;
|
||||
|
||||
register_feature_gated_function!(
|
||||
result,
|
||||
epoch_rewards_syscall_enabled,
|
||||
b"sol_get_epoch_rewrds_sysvar",
|
||||
SyscallGetEpochRewardsSysvar::call,
|
||||
)?;
|
||||
|
||||
// Memory ops
|
||||
result.register_function(b"sol_memcpy_", SyscallMemcpy::call)?;
|
||||
result.register_function(b"sol_memmove_", SyscallMemmove::call)?;
|
||||
|
@ -1807,7 +1816,9 @@ mod tests {
|
|||
instruction::Instruction,
|
||||
program::check_type_assumptions,
|
||||
stable_layout::stable_instruction::StableInstruction,
|
||||
sysvar::{self, clock::Clock, epoch_schedule::EpochSchedule},
|
||||
sysvar::{
|
||||
self, clock::Clock, epoch_rewards::EpochRewards, epoch_schedule::EpochSchedule,
|
||||
},
|
||||
},
|
||||
std::{mem, str::FromStr},
|
||||
};
|
||||
|
@ -3177,11 +3188,17 @@ mod tests {
|
|||
src_rent.exemption_threshold = 2.0;
|
||||
src_rent.burn_percent = 3;
|
||||
|
||||
let mut src_rewards = create_filled_type::<EpochRewards>(false);
|
||||
src_rewards.total_rewards = 100;
|
||||
src_rewards.distributed_rewards = 10;
|
||||
src_rewards.distribution_complete_block_height = 42;
|
||||
|
||||
let mut sysvar_cache = SysvarCache::default();
|
||||
sysvar_cache.set_clock(src_clock.clone());
|
||||
sysvar_cache.set_epoch_schedule(src_epochschedule);
|
||||
sysvar_cache.set_fees(src_fees.clone());
|
||||
sysvar_cache.set_rent(src_rent);
|
||||
sysvar_cache.set_epoch_rewards(src_rewards);
|
||||
|
||||
let transaction_accounts = vec![
|
||||
(
|
||||
|
@ -3200,6 +3217,10 @@ mod tests {
|
|||
sysvar::rent::id(),
|
||||
create_account_shared_data_for_test(&src_rent),
|
||||
),
|
||||
(
|
||||
sysvar::epoch_rewards::id(),
|
||||
create_account_shared_data_for_test(&src_rewards),
|
||||
),
|
||||
];
|
||||
with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts);
|
||||
|
||||
|
@ -3345,6 +3366,42 @@ mod tests {
|
|||
clean_rent.burn_percent = src_rent.burn_percent;
|
||||
assert!(are_bytes_equal(&got_rent, &clean_rent));
|
||||
}
|
||||
|
||||
// Test epoch rewards sysvar
|
||||
{
|
||||
let mut got_rewards = create_filled_type::<EpochRewards>(true);
|
||||
let got_rewards_va = 0x100000000;
|
||||
|
||||
let mut memory_mapping = MemoryMapping::new(
|
||||
vec![MemoryRegion::new_writable(
|
||||
bytes_of_mut(&mut got_rewards),
|
||||
got_rewards_va,
|
||||
)],
|
||||
&config,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
SyscallGetEpochRewardsSysvar::call(
|
||||
&mut invoke_context,
|
||||
got_rewards_va,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut memory_mapping,
|
||||
&mut result,
|
||||
);
|
||||
result.unwrap();
|
||||
assert_eq!(got_rewards, src_rewards);
|
||||
|
||||
let mut clean_rewards = create_filled_type::<EpochRewards>(true);
|
||||
clean_rewards.total_rewards = src_rewards.total_rewards;
|
||||
clean_rewards.distributed_rewards = src_rewards.distributed_rewards;
|
||||
clean_rewards.distribution_complete_block_height =
|
||||
src_rewards.distribution_complete_block_height;
|
||||
assert!(are_bytes_equal(&got_rewards, &clean_rewards));
|
||||
}
|
||||
}
|
||||
|
||||
fn call_program_address_common<'a, 'b: 'a>(
|
||||
|
|
|
@ -66,6 +66,28 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
/// Get a EpochRewards sysvar
|
||||
SyscallGetEpochRewardsSysvar,
|
||||
fn inner_call(
|
||||
invoke_context: &mut InvokeContext,
|
||||
var_addr: u64,
|
||||
_arg2: u64,
|
||||
_arg3: u64,
|
||||
_arg4: u64,
|
||||
_arg5: u64,
|
||||
memory_mapping: &mut MemoryMapping,
|
||||
) -> Result<u64, Error> {
|
||||
get_sysvar(
|
||||
invoke_context.get_sysvar_cache().get_epoch_rewards(),
|
||||
var_addr,
|
||||
invoke_context.get_check_aligned(),
|
||||
memory_mapping,
|
||||
invoke_context,
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
/// Get a Fees sysvar
|
||||
SyscallGetFeesSysvar,
|
||||
|
|
|
@ -13,8 +13,9 @@ use solana_program::{
|
|||
program_error::ProgramError,
|
||||
pubkey::Pubkey,
|
||||
sysvar::{
|
||||
self, clock::Clock, epoch_schedule::EpochSchedule, instructions, rent::Rent,
|
||||
slot_hashes::SlotHashes, slot_history::SlotHistory, stake_history::StakeHistory, Sysvar,
|
||||
self, clock::Clock, epoch_rewards::EpochRewards, epoch_schedule::EpochSchedule,
|
||||
instructions, rent::Rent, slot_hashes::SlotHashes, slot_history::SlotHistory,
|
||||
stake_history::StakeHistory, Sysvar,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -69,6 +70,7 @@ pub fn process_instruction(
|
|||
AccountMeta::new_readonly(*accounts[8].key, false),
|
||||
AccountMeta::new_readonly(*accounts[9].key, false),
|
||||
AccountMeta::new_readonly(*accounts[10].key, false),
|
||||
AccountMeta::new_readonly(*accounts[11].key, false),
|
||||
],
|
||||
)
|
||||
);
|
||||
|
@ -123,5 +125,18 @@ pub fn process_instruction(
|
|||
assert_eq!(fees, got_fees);
|
||||
}
|
||||
|
||||
// Epoch Rewards
|
||||
{
|
||||
msg!("EpochRewards identifier:");
|
||||
sysvar::epoch_rewards::id().log();
|
||||
let epoch_rewards = EpochRewards::from_account_info(&accounts[11]);
|
||||
// epoch_rewards sysvar should only be valid during epoch reward period. In this test case,
|
||||
// the test bank is outside reward period. Therefore, we expect that the epoch_rewards
|
||||
// sysvar doesn't exist.
|
||||
assert!(epoch_rewards.is_err());
|
||||
let got_epoch_rewards = EpochRewards::get();
|
||||
assert!(got_epoch_rewards.is_err());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ use {
|
|||
pubkey::Pubkey,
|
||||
signature::Signer,
|
||||
sysvar::{
|
||||
clock, epoch_schedule, fees, instructions, recent_blockhashes, rent, slot_hashes,
|
||||
slot_history, stake_history,
|
||||
clock, epoch_rewards, epoch_schedule, fees, instructions, recent_blockhashes, rent,
|
||||
slot_hashes, slot_history, stake_history,
|
||||
},
|
||||
transaction::Transaction,
|
||||
},
|
||||
|
@ -45,6 +45,7 @@ async fn test_sysvars() {
|
|||
AccountMeta::new_readonly(stake_history::id(), false),
|
||||
#[allow(deprecated)]
|
||||
AccountMeta::new_readonly(fees::id(), false),
|
||||
AccountMeta::new_readonly(epoch_rewards::id(), false),
|
||||
],
|
||||
)],
|
||||
Some(&payer.pubkey()),
|
||||
|
@ -78,6 +79,7 @@ async fn test_sysvars() {
|
|||
AccountMeta::new_readonly(stake_history::id(), false),
|
||||
#[allow(deprecated)]
|
||||
AccountMeta::new_readonly(fees::id(), false),
|
||||
AccountMeta::new_readonly(epoch_rewards::id(), false),
|
||||
],
|
||||
)],
|
||||
Some(&payer.pubkey()),
|
||||
|
|
Loading…
Reference in New Issue