Cleanup: InvokeContext accessors (#21574)

* Removes blockhash accessors from InvokeContext.

* Removes lamports_per_signature accessors from InvokeContext.

* Removes return_data accessors from InvokeContext.

* Removes feature_set accessor from InvokeContext.

* Removes instruction_recorders and instruction_index accessors from InvokeContext.

* Moves get_sysvars() into InvokeContext.

* Removes compute_meter parameter from InvokeContext::new().

* Removes InvokeContext::new_mock_with_sysvars_and_features().

* Removes InvokeContext::update_timing().
This commit is contained in:
Alexander Meißner
2021-12-03 12:15:22 +01:00
committed by GitHub
parent dab0e8fdc7
commit a9d5ef2055
14 changed files with 314 additions and 343 deletions

View File

@ -99,6 +99,10 @@ fn bench_program_alu(bencher: &mut Bencher) {
let elf = load_elf("bench_alu").unwrap();
let loader_id = bpf_loader::id();
with_mock_invoke_context(loader_id, 10000001, |invoke_context| {
invoke_context
.get_compute_meter()
.borrow_mut()
.mock_set_remaining(std::i64::MAX as u64);
let mut executable = Executable::<BpfError, ThisInstructionMeter>::from_elf(
&elf,
None,
@ -109,13 +113,7 @@ fn bench_program_alu(bencher: &mut Bencher) {
executable.jit_compile().unwrap();
let compute_meter = invoke_context.get_compute_meter();
let mut instruction_meter = ThisInstructionMeter { compute_meter };
let mut vm = create_vm(
&executable,
&mut inner_iter,
invoke_context,
&[],
)
.unwrap();
let mut vm = create_vm(&executable, &mut inner_iter, invoke_context, &[]).unwrap();
println!("Interpreted:");
assert_eq!(
@ -205,7 +203,10 @@ fn bench_create_vm(bencher: &mut Bencher) {
let loader_id = bpf_loader::id();
with_mock_invoke_context(loader_id, 10000001, |invoke_context| {
const BUDGET: u64 = 200_000;
invoke_context.get_compute_meter().borrow_mut().mock_set_remaining(BUDGET);
invoke_context
.get_compute_meter()
.borrow_mut()
.mock_set_remaining(BUDGET);
// Serialize account data
let keyed_accounts = invoke_context.get_keyed_accounts().unwrap();
@ -243,7 +244,10 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
let loader_id = bpf_loader::id();
with_mock_invoke_context(loader_id, 10000001, |invoke_context| {
const BUDGET: u64 = 200_000;
invoke_context.get_compute_meter().borrow_mut().mock_set_remaining(BUDGET);
invoke_context
.get_compute_meter()
.borrow_mut()
.mock_set_remaining(BUDGET);
// Serialize account data
let keyed_accounts = invoke_context.get_keyed_accounts().unwrap();

View File

@ -223,7 +223,7 @@ fn run_program(name: &str) -> u64 {
let mut instruction_count = 0;
let mut tracer = None;
for i in 0..2 {
invoke_context.set_return_data(Vec::new()).unwrap();
invoke_context.return_data = (*invoke_context.get_caller().unwrap(), Vec::new());
let mut parameter_bytes = parameter_bytes.clone();
{
let mut vm = create_vm(

View File

@ -91,9 +91,12 @@ pub fn create_executor(
stack_frame_size: compute_budget.stack_frame_size,
enable_instruction_tracing: log_enabled!(Trace),
reject_unresolved_syscalls: reject_unresolved_syscalls
&& invoke_context.is_feature_active(&reject_deployment_of_unresolved_syscalls::id()),
&& invoke_context
.feature_set
.is_active(&reject_deployment_of_unresolved_syscalls::id()),
verify_mul64_imm_nonzero: !invoke_context
.is_feature_active(&stop_verify_mul64_imm_nonzero::id()), // TODO: Feature gate and then remove me
.feature_set
.is_active(&stop_verify_mul64_imm_nonzero::id()), // TODO: Feature gate and then remove me
..Config::default()
};
let mut executable = {
@ -158,7 +161,10 @@ pub fn create_vm<'a, 'b>(
) -> Result<EbpfVm<'a, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> {
let compute_budget = invoke_context.get_compute_budget();
let heap_size = compute_budget.heap_size.unwrap_or(HEAP_LENGTH);
if invoke_context.is_feature_active(&requestable_heap_size::id()) {
if invoke_context
.feature_set
.is_active(&requestable_heap_size::id())
{
let _ = invoke_context
.get_compute_meter()
.borrow_mut()
@ -450,8 +456,9 @@ fn process_loader_upgradeable_instruction(
return Err(InstructionError::InvalidArgument);
}
let predrain_buffer =
invoke_context.is_feature_active(&reduce_required_deploy_balance::id());
let predrain_buffer = invoke_context
.feature_set
.is_active(&reduce_required_deploy_balance::id());
if predrain_buffer {
// Drain the Buffer account to payer before paying for programdata account
payer
@ -1014,7 +1021,7 @@ impl Executor for BpfExecutor {
trace!("BPF Program Instruction Trace:\n{}", trace_string);
}
drop(vm);
let (_returned_from_program_id, return_data) = invoke_context.get_return_data();
let (_returned_from_program_id, return_data) = &invoke_context.return_data;
if !return_data.is_empty() {
stable_log::program_return(&log_collector, &program_id, return_data);
}
@ -1049,15 +1056,18 @@ impl Executor for BpfExecutor {
&keyed_accounts[first_instruction_account + 1..],
parameter_bytes.as_slice(),
&account_lengths,
invoke_context.is_feature_active(&do_support_realloc::id()),
invoke_context
.feature_set
.is_active(&do_support_realloc::id()),
)?;
deserialize_time.stop();
invoke_context.update_timing(
serialize_time.as_us(),
create_vm_time.as_us(),
execute_time.as_us(),
deserialize_time.as_us(),
);
let timings = &mut invoke_context.timings;
timings.serialize_us = timings.serialize_us.saturating_add(serialize_time.as_us());
timings.create_vm_us = timings.create_vm_us.saturating_add(create_vm_time.as_us());
timings.execute_us = timings.execute_us.saturating_add(execute_time.as_us());
timings.deserialize_us = timings
.deserialize_us
.saturating_add(deserialize_time.as_us());
stable_log::program_success(&log_collector, &program_id);
Ok(())
}

View File

@ -141,12 +141,18 @@ pub fn register_syscalls(
syscall_registry.register_syscall_by_name(b"sol_sha256", SyscallSha256::call)?;
syscall_registry.register_syscall_by_name(b"sol_keccak256", SyscallKeccak256::call)?;
if invoke_context.is_feature_active(&secp256k1_recover_syscall_enabled::id()) {
if invoke_context
.feature_set
.is_active(&secp256k1_recover_syscall_enabled::id())
{
syscall_registry
.register_syscall_by_name(b"sol_secp256k1_recover", SyscallSecp256k1Recover::call)?;
}
if invoke_context.is_feature_active(&blake3_syscall_enabled::id()) {
if invoke_context
.feature_set
.is_active(&blake3_syscall_enabled::id())
{
syscall_registry.register_syscall_by_name(b"sol_blake3", SyscallBlake3::call)?;
}
@ -156,7 +162,10 @@ pub fn register_syscalls(
b"sol_get_epoch_schedule_sysvar",
SyscallGetEpochScheduleSysvar::call,
)?;
if !invoke_context.is_feature_active(&disable_fees_sysvar::id()) {
if !invoke_context
.feature_set
.is_active(&disable_fees_sysvar::id())
{
syscall_registry
.register_syscall_by_name(b"sol_get_fees_sysvar", SyscallGetFeesSysvar::call)?;
}
@ -178,7 +187,10 @@ pub fn register_syscalls(
syscall_registry.register_syscall_by_name(b"sol_alloc_free_", SyscallAllocFree::call)?;
// Return data
if invoke_context.is_feature_active(&return_data_syscall_enabled::id()) {
if invoke_context
.feature_set
.is_active(&return_data_syscall_enabled::id())
{
syscall_registry
.register_syscall_by_name(b"sol_set_return_data", SyscallSetReturnData::call)?;
syscall_registry
@ -186,7 +198,10 @@ pub fn register_syscalls(
}
// Log data
if invoke_context.is_feature_active(&sol_log_data_syscall_enabled::id()) {
if invoke_context
.feature_set
.is_active(&sol_log_data_syscall_enabled::id())
{
syscall_registry.register_syscall_by_name(b"sol_log_data", SyscallLogData::call)?;
}
@ -212,15 +227,21 @@ pub fn bind_syscall_context_objects<'a, 'b>(
heap: AlignedMemory,
orig_data_lens: &'a [usize],
) -> Result<(), EbpfError<BpfError>> {
let is_blake3_syscall_active = invoke_context.is_feature_active(&blake3_syscall_enabled::id());
let is_secp256k1_recover_syscall_active =
invoke_context.is_feature_active(&secp256k1_recover_syscall_enabled::id());
let is_fee_sysvar_via_syscall_active =
!invoke_context.is_feature_active(&disable_fees_sysvar::id());
let is_return_data_syscall_active =
invoke_context.is_feature_active(&return_data_syscall_enabled::id());
let is_sol_log_data_syscall_active =
invoke_context.is_feature_active(&sol_log_data_syscall_enabled::id());
let is_blake3_syscall_active = invoke_context
.feature_set
.is_active(&blake3_syscall_enabled::id());
let is_secp256k1_recover_syscall_active = invoke_context
.feature_set
.is_active(&secp256k1_recover_syscall_enabled::id());
let is_fee_sysvar_via_syscall_active = !invoke_context
.feature_set
.is_active(&disable_fees_sysvar::id());
let is_return_data_syscall_active = invoke_context
.feature_set
.is_active(&return_data_syscall_enabled::id());
let is_sol_log_data_syscall_active = invoke_context
.feature_set
.is_active(&sol_log_data_syscall_enabled::id());
let loader_id = invoke_context
.get_loader()
@ -1004,18 +1025,15 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId>(
var_addr: u64,
loader_id: &Pubkey,
memory_mapping: &MemoryMapping,
invoke_context: Rc<RefCell<&mut InvokeContext>>,
invoke_context: &mut InvokeContext,
) -> Result<u64, EbpfError<BpfError>> {
let invoke_context = invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed)?;
invoke_context
.get_compute_meter()
.consume(invoke_context.get_compute_budget().sysvar_base_cost + size_of::<T>() as u64)?;
let var = translate_type_mut::<T>(memory_mapping, var_addr, loader_id)?;
*var = solana_program_runtime::invoke_context::get_sysvar::<T>(*invoke_context, id)
*var = invoke_context
.get_sysvar::<T>(id)
.map_err(SyscallError::InstructionError)?;
Ok(SUCCESS)
@ -1036,9 +1054,9 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetClockSysvar<'a, 'b> {
memory_mapping: &MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let invoke_context = question_mark!(
let mut invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
@ -1053,7 +1071,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetClockSysvar<'a, 'b> {
var_addr,
&loader_id,
memory_mapping,
self.invoke_context.clone(),
&mut invoke_context,
);
}
}
@ -1072,9 +1090,9 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a, 'b> {
memory_mapping: &MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let invoke_context = question_mark!(
let mut invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
@ -1089,7 +1107,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetEpochScheduleSysvar<'a, 'b> {
var_addr,
&loader_id,
memory_mapping,
self.invoke_context.clone(),
&mut invoke_context,
);
}
}
@ -1109,9 +1127,9 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a, 'b> {
memory_mapping: &MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let invoke_context = question_mark!(
let mut invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
@ -1126,7 +1144,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetFeesSysvar<'a, 'b> {
var_addr,
&loader_id,
memory_mapping,
self.invoke_context.clone(),
&mut invoke_context,
);
}
}
@ -1145,9 +1163,9 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetRentSysvar<'a, 'b> {
memory_mapping: &MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let invoke_context = question_mark!(
let mut invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
@ -1162,7 +1180,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetRentSysvar<'a, 'b> {
var_addr,
&loader_id,
memory_mapping,
self.invoke_context.clone(),
&mut invoke_context,
);
}
}
@ -1509,12 +1527,14 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSecp256k1Recover<'a, 'b> {
return;
}
};
let sig_parse_result =
if invoke_context.is_feature_active(&libsecp256k1_0_5_upgrade_enabled::id()) {
libsecp256k1::Signature::parse_standard_slice(signature)
} else {
libsecp256k1::Signature::parse_overflowing_slice(signature)
};
let sig_parse_result = if invoke_context
.feature_set
.is_active(&libsecp256k1_0_5_upgrade_enabled::id())
{
libsecp256k1::Signature::parse_standard_slice(signature)
} else {
libsecp256k1::Signature::parse_overflowing_slice(signature)
};
let signature = match sig_parse_result {
Ok(sig) => sig,
@ -2157,8 +2177,9 @@ fn get_translated_accounts<'a, T, F>(
where
F: Fn(&T, &InvokeContext) -> Result<CallerAccount<'a>, EbpfError<BpfError>>,
{
let demote_program_write_locks =
invoke_context.is_feature_active(&demote_program_write_locks::id());
let demote_program_write_locks = invoke_context
.feature_set
.is_active(&demote_program_write_locks::id());
let keyed_accounts = invoke_context
.get_instruction_keyed_accounts()
.map_err(SyscallError::InstructionError)?;
@ -2275,9 +2296,11 @@ fn check_authorized_program(
&& !(bpf_loader_upgradeable::is_upgrade_instruction(instruction_data)
|| bpf_loader_upgradeable::is_set_authority_instruction(instruction_data)
|| bpf_loader_upgradeable::is_close_instruction(instruction_data)))
|| (invoke_context.is_feature_active(&prevent_calling_precompiles_as_programs::id())
|| (invoke_context
.feature_set
.is_active(&prevent_calling_precompiles_as_programs::id())
&& is_precompile(program_id, |feature_id: &Pubkey| {
invoke_context.is_feature_active(feature_id)
invoke_context.feature_set.is_active(feature_id)
}))
{
return Err(SyscallError::ProgramNotSupported(*program_id).into());
@ -2299,7 +2322,9 @@ fn call<'a, 'b: 'a>(
invoke_context
.get_compute_meter()
.consume(invoke_context.get_compute_budget().invoke_units)?;
let do_support_realloc = invoke_context.is_feature_active(&do_support_realloc::id());
let do_support_realloc = invoke_context
.feature_set
.is_active(&do_support_realloc::id());
// Translate and verify caller's data
let loader_id = invoke_context
@ -2335,7 +2360,9 @@ fn call<'a, 'b: 'a>(
)?;
// Record the instruction
invoke_context.record_instruction(&instruction);
if let Some(instruction_recorder) = &invoke_context.instruction_recorder {
instruction_recorder.record_instruction(instruction);
}
// Process instruction
invoke_context
@ -2453,12 +2480,13 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallSetReturnData<'a, 'b> {
)
.to_vec()
};
question_mark!(
let program_id = question_mark!(
invoke_context
.set_return_data(return_data)
.get_caller()
.map_err(SyscallError::InstructionError),
result
);
invoke_context.return_data = (*program_id, return_data);
*result = Ok(0);
}
@ -2500,7 +2528,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetReturnData<'a, 'b> {
result
);
let (program_id, return_data) = invoke_context.get_return_data();
let (program_id, return_data) = &invoke_context.return_data;
length = length.min(return_data.len() as u64);
if length != 0 {
question_mark!(
@ -2522,7 +2550,7 @@ impl<'a, 'b> SyscallObject<BpfError> for SyscallGetReturnData<'a, 'b> {
result
);
program_id_result[0] = program_id;
program_id_result[0] = *program_id;
}
// Return the actual length, rather the length returned
@ -2618,10 +2646,8 @@ mod tests {
use solana_rbpf::{
ebpf::HOST_ALIGN, memory_region::MemoryRegion, user_error::UserError, vm::Config,
};
use solana_sdk::{
bpf_loader, feature_set::FeatureSet, fee_calculator::FeeCalculator, hash::hashv,
};
use std::{str::FromStr, sync::Arc};
use solana_sdk::{bpf_loader, fee_calculator::FeeCalculator, hash::hashv};
use std::str::FromStr;
macro_rules! assert_access_violation {
($result:expr, $va:expr, $len:expr) => {
@ -3529,13 +3555,9 @@ mod tests {
};
let mut data = vec![];
bincode::serialize_into(&mut data, &src_clock).unwrap();
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let sysvars = [(sysvar::clock::id(), data)];
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&accounts,
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
invoke_context.sysvars = &sysvars;
invoke_context
.push(&message, &message.instructions[0], &[0], None)
.unwrap();
@ -3578,13 +3600,9 @@ mod tests {
};
let mut data = vec![];
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let sysvars = [(sysvar::epoch_schedule::id(), data)];
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&accounts,
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
invoke_context.sysvars = &sysvars;
invoke_context
.push(&message, &message.instructions[0], &[0], None)
.unwrap();
@ -3634,13 +3652,9 @@ mod tests {
};
let mut data = vec![];
bincode::serialize_into(&mut data, &src_fees).unwrap();
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let sysvars = [(sysvar::fees::id(), data)];
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&accounts,
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
invoke_context.sysvars = &sysvars;
invoke_context
.push(&message, &message.instructions[0], &[0], None)
.unwrap();
@ -3681,13 +3695,9 @@ mod tests {
};
let mut data = vec![];
bincode::serialize_into(&mut data, &src_rent).unwrap();
let mut invoke_context = InvokeContext::new_mock(&accounts, &[]);
let sysvars = [(sysvar::rent::id(), data)];
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&accounts,
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
invoke_context.sysvars = &sysvars;
invoke_context
.push(&message, &message.instructions[0], &[0], None)
.unwrap();
@ -3949,9 +3959,14 @@ mod tests {
.get_compute_budget()
.create_program_address_units;
let address = bpf_loader_upgradeable::id();
let max_tries = 256; // one per seed
for _ in 0..1_000 {
let address = Pubkey::new_unique();
invoke_context
.get_compute_meter()
.borrow_mut()
.mock_set_remaining(cost * max_tries);
let (found_address, bump_seed) =
try_find_program_address(&mut invoke_context, &[b"Lil'", b"Bits"], &address)
.unwrap();
@ -3966,7 +3981,6 @@ mod tests {
);
}
let max_tries = 256; // one per seed
let seeds: &[&[u8]] = &[b""];
invoke_context
.get_compute_meter()

View File

@ -100,7 +100,10 @@ pub fn process_instruction(
}
}
if invoke_context.is_feature_active(&feature_set::dedupe_config_program_signers::id()) {
if invoke_context
.feature_set
.is_active(&feature_set::dedupe_config_program_signers::id())
{
let total_new_keys = key_list.keys.len();
let unique_new_keys = key_list.keys.into_iter().collect::<BTreeSet<_>>();
if unique_new_keys.len() != total_new_keys {

View File

@ -1,7 +1,7 @@
use {
crate::{config, stake_state::StakeAccount},
log::*,
solana_program_runtime::invoke_context::{get_sysvar, InvokeContext},
solana_program_runtime::invoke_context::InvokeContext,
solana_sdk::{
feature_set,
instruction::InstructionError,
@ -48,9 +48,9 @@ pub fn process_instruction(
)?)?,
),
StakeInstruction::Authorize(authorized_pubkey, stake_authorize) => {
let require_custodian_for_locked_stake_authorize = invoke_context.is_feature_active(
&feature_set::require_custodian_for_locked_stake_authorize::id(),
);
let require_custodian_for_locked_stake_authorize = invoke_context
.feature_set
.is_active(&feature_set::require_custodian_for_locked_stake_authorize::id());
if require_custodian_for_locked_stake_authorize {
let clock = from_keyed_account::<Clock>(keyed_account_at_index(
@ -86,9 +86,9 @@ pub fn process_instruction(
StakeInstruction::AuthorizeWithSeed(args) => {
let authority_base =
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?;
let require_custodian_for_locked_stake_authorize = invoke_context.is_feature_active(
&feature_set::require_custodian_for_locked_stake_authorize::id(),
);
let require_custodian_for_locked_stake_authorize = invoke_context
.feature_set
.is_active(&feature_set::require_custodian_for_locked_stake_authorize::id());
if require_custodian_for_locked_stake_authorize {
let clock = from_keyed_account::<Clock>(keyed_account_at_index(
@ -124,8 +124,9 @@ pub fn process_instruction(
}
}
StakeInstruction::DelegateStake => {
let can_reverse_deactivation =
invoke_context.is_feature_active(&feature_set::stake_program_v4::id());
let can_reverse_deactivation = invoke_context
.feature_set
.is_active(&feature_set::stake_program_v4::id());
let vote = keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?;
me.delegate(
@ -154,8 +155,9 @@ pub fn process_instruction(
StakeInstruction::Merge => {
let source_stake =
&keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?;
let can_merge_expired_lockups =
invoke_context.is_feature_active(&feature_set::stake_program_v4::id());
let can_merge_expired_lockups = invoke_context
.feature_set
.is_active(&feature_set::stake_program_v4::id());
me.merge(
invoke_context,
source_stake,
@ -186,7 +188,9 @@ pub fn process_instruction(
)?)?,
keyed_account_at_index(keyed_accounts, first_instruction_account + 4)?,
keyed_account_at_index(keyed_accounts, first_instruction_account + 5).ok(),
invoke_context.is_feature_active(&feature_set::stake_program_v4::id()),
invoke_context
.feature_set
.is_active(&feature_set::stake_program_v4::id()),
)
}
StakeInstruction::Deactivate => me.deactivate(
@ -197,15 +201,20 @@ pub fn process_instruction(
&signers,
),
StakeInstruction::SetLockup(lockup) => {
let clock = if invoke_context.is_feature_active(&feature_set::stake_program_v4::id()) {
Some(get_sysvar::<Clock>(invoke_context, &sysvar::clock::id())?)
let clock = if invoke_context
.feature_set
.is_active(&feature_set::stake_program_v4::id())
{
Some(invoke_context.get_sysvar::<Clock>(&sysvar::clock::id())?)
} else {
None
};
me.set_lockup(&lockup, &signers, clock.as_ref())
}
StakeInstruction::InitializeChecked => {
if invoke_context.is_feature_active(&feature_set::vote_stake_checked_instructions::id())
if invoke_context
.feature_set
.is_active(&feature_set::vote_stake_checked_instructions::id())
{
let authorized = Authorized {
staker: *keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?
@ -231,7 +240,9 @@ pub fn process_instruction(
}
}
StakeInstruction::AuthorizeChecked(stake_authorize) => {
if invoke_context.is_feature_active(&feature_set::vote_stake_checked_instructions::id())
if invoke_context
.feature_set
.is_active(&feature_set::vote_stake_checked_instructions::id())
{
let clock = from_keyed_account::<Clock>(keyed_account_at_index(
keyed_accounts,
@ -261,7 +272,9 @@ pub fn process_instruction(
}
}
StakeInstruction::AuthorizeCheckedWithSeed(args) => {
if invoke_context.is_feature_active(&feature_set::vote_stake_checked_instructions::id())
if invoke_context
.feature_set
.is_active(&feature_set::vote_stake_checked_instructions::id())
{
let authority_base =
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?;
@ -293,7 +306,9 @@ pub fn process_instruction(
}
}
StakeInstruction::SetLockupChecked(lockup_checked) => {
if invoke_context.is_feature_active(&feature_set::vote_stake_checked_instructions::id())
if invoke_context
.feature_set
.is_active(&feature_set::vote_stake_checked_instructions::id())
{
let custodian = if let Ok(custodian) =
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)
@ -312,7 +327,7 @@ pub fn process_instruction(
epoch: lockup_checked.epoch,
custodian,
};
let clock = Some(get_sysvar::<Clock>(invoke_context, &sysvar::clock::id())?);
let clock = Some(invoke_context.get_sysvar::<Clock>(&sysvar::clock::id())?);
me.set_lockup(&lockup, &signers, clock.as_ref())
} else {
Err(InstructionError::InvalidInstructionData)
@ -331,7 +346,6 @@ mod tests {
};
use solana_sdk::{
account::{self, AccountSharedData},
feature_set::FeatureSet,
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
rent::Rent,
@ -342,7 +356,7 @@ mod tests {
},
sysvar::{stake_history::StakeHistory, Sysvar},
};
use std::{cell::RefCell, rc::Rc, str::FromStr, sync::Arc};
use std::{cell::RefCell, rc::Rc, str::FromStr};
fn create_default_account() -> Rc<RefCell<AccountSharedData>> {
AccountSharedData::new_ref(0, 0, &Pubkey::new_unique())
@ -415,13 +429,9 @@ mod tests {
preparation.accounts.push((id(), processor_account));
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
let mut invoke_context = InvokeContext::new_mock(&preparation.accounts, &[]);
let sysvars = [(sysvar::clock::id(), data)];
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&preparation.accounts,
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
invoke_context.sysvars = &sysvars;
invoke_context.push(
&preparation.message,
&preparation.message.instructions[0],
@ -1065,13 +1075,9 @@ mod tests {
preparation.accounts.push((id(), processor_account));
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
let mut invoke_context = InvokeContext::new_mock(&preparation.accounts, &[]);
let sysvars = [(sysvar::clock::id(), data)];
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
&preparation.accounts,
&[],
&sysvars,
Arc::new(FeatureSet::all_enabled()),
);
invoke_context.sysvars = &sysvars;
invoke_context
.push(
&preparation.message,

View File

@ -978,7 +978,8 @@ impl MergeKind {
.zip(source.active_stake())
.map(|(stake, source)| {
if invoke_context
.is_feature_active(&stake_merge_with_unmatched_credits_observed::id())
.feature_set
.is_active(&stake_merge_with_unmatched_credits_observed::id())
{
Self::active_delegations_can_merge(
invoke_context,
@ -1038,7 +1039,10 @@ fn merge_delegation_stake_and_credits_observed(
absorbed_lamports: u64,
absorbed_credits_observed: u64,
) -> Result<(), InstructionError> {
if invoke_context.is_feature_active(&stake_merge_with_unmatched_credits_observed::id()) {
if invoke_context
.feature_set
.is_active(&stake_merge_with_unmatched_credits_observed::id())
{
stake.credits_observed =
stake_weighted_credits_observed(stake, absorbed_lamports, absorbed_credits_observed)
.ok_or(InstructionError::ArithmeticOverflow)?;

View File

@ -378,7 +378,9 @@ pub fn process_instruction(
vote_state::withdraw(me, lamports, to, &signers)
}
VoteInstruction::AuthorizeChecked(vote_authorize) => {
if invoke_context.is_feature_active(&feature_set::vote_stake_checked_instructions::id())
if invoke_context
.feature_set
.is_active(&feature_set::vote_stake_checked_instructions::id())
{
let voter_pubkey =
&keyed_account_at_index(keyed_accounts, first_instruction_account + 3)?