Bump solana_rbpf to v0.8.0 (#33679)
* Bumps solana_rbpf to v0.8.0 * Adjustments: Replaces declare_syscall!() with declare_builtin_function!(). Removes Config::encrypt_runtime_environment. Simplifies error propagation.
This commit is contained in:
parent
dc3c827299
commit
a5c7c999e2
|
@ -6640,6 +6640,7 @@ dependencies = [
|
|||
"solana-sdk",
|
||||
"solana-stake-program",
|
||||
"solana-vote-program",
|
||||
"solana_rbpf",
|
||||
"test-case",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
|
@ -7625,9 +7626,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "solana_rbpf"
|
||||
version = "0.7.2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "103318aa365ff7caa8cf534f2246b5eb7e5b34668736d52b1266b143f7a21196"
|
||||
checksum = "3d457cc2ba742c120492a64b7fa60e22c575e891f6b55039f4d736568fb112a3"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"combine",
|
||||
|
|
|
@ -378,7 +378,7 @@ solana-wen-restart = { path = "wen-restart", version = "=1.18.0" }
|
|||
solana-zk-keygen = { path = "zk-keygen", version = "=1.18.0" }
|
||||
solana-zk-token-proof-program = { path = "programs/zk-token-proof", version = "=1.18.0" }
|
||||
solana-zk-token-sdk = { path = "zk-token-sdk", version = "=1.18.0" }
|
||||
solana_rbpf = "=0.7.2"
|
||||
solana_rbpf = "=0.8.0"
|
||||
spl-associated-token-account = "=2.2.0"
|
||||
spl-instruction-padding = "0.1"
|
||||
spl-memo = "=4.0.0"
|
||||
|
|
|
@ -2994,7 +2994,7 @@ pub mod tests {
|
|||
]
|
||||
}
|
||||
|
||||
declare_process_instruction!(mock_processor_ok, 1, |_invoke_context| {
|
||||
declare_process_instruction!(MockBuiltinOk, 1, |_invoke_context| {
|
||||
// Always succeeds
|
||||
Ok(())
|
||||
});
|
||||
|
@ -3002,7 +3002,7 @@ pub mod tests {
|
|||
let mock_program_id = solana_sdk::pubkey::new_rand();
|
||||
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
bank.add_mockup_builtin(mock_program_id, mock_processor_ok);
|
||||
bank.add_mockup_builtin(mock_program_id, MockBuiltinOk::vm);
|
||||
|
||||
let tx = Transaction::new_signed_with_payer(
|
||||
&[Instruction::new_with_bincode(
|
||||
|
@ -3023,7 +3023,7 @@ pub mod tests {
|
|||
let bankhash_ok = bank.hash();
|
||||
assert!(result.is_ok());
|
||||
|
||||
declare_process_instruction!(mock_processor_err, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltinErr, 1, |invoke_context| {
|
||||
let instruction_errors = get_instruction_errors();
|
||||
|
||||
let err = invoke_context
|
||||
|
@ -3043,7 +3043,7 @@ pub mod tests {
|
|||
|
||||
(0..get_instruction_errors().len()).for_each(|err| {
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
bank.add_mockup_builtin(mock_program_id, mock_processor_err);
|
||||
bank.add_mockup_builtin(mock_program_id, MockBuiltinErr::vm);
|
||||
|
||||
let tx = Transaction::new_signed_with_payer(
|
||||
&[Instruction::new_with_bincode(
|
||||
|
|
|
@ -12,9 +12,10 @@ use {
|
|||
solana_measure::measure::Measure,
|
||||
solana_rbpf::{
|
||||
ebpf::MM_HEAP_START,
|
||||
elf::SBPFVersion,
|
||||
error::{EbpfError, ProgramResult},
|
||||
memory_region::MemoryMapping,
|
||||
vm::{BuiltinFunction, Config, ContextObject, ProgramResult},
|
||||
program::{BuiltinFunction, SBPFVersion},
|
||||
vm::{Config, ContextObject, EbpfVm},
|
||||
},
|
||||
solana_sdk::{
|
||||
account::AccountSharedData,
|
||||
|
@ -39,13 +40,15 @@ use {
|
|||
},
|
||||
};
|
||||
|
||||
pub type ProcessInstructionWithContext = BuiltinFunction<InvokeContext<'static>>;
|
||||
pub type BuiltinFunctionWithContext = BuiltinFunction<InvokeContext<'static>>;
|
||||
|
||||
/// Adapter so we can unify the interfaces of built-in programs and syscalls
|
||||
#[macro_export]
|
||||
macro_rules! declare_process_instruction {
|
||||
($process_instruction:ident, $cu_to_consume:expr, |$invoke_context:ident| $inner:tt) => {
|
||||
pub fn $process_instruction(
|
||||
$crate::solana_rbpf::declare_builtin_function!(
|
||||
$process_instruction,
|
||||
fn rust(
|
||||
invoke_context: &mut $crate::invoke_context::InvokeContext,
|
||||
_arg0: u64,
|
||||
_arg1: u64,
|
||||
|
@ -53,8 +56,7 @@ macro_rules! declare_process_instruction {
|
|||
_arg3: u64,
|
||||
_arg4: u64,
|
||||
_memory_mapping: &mut $crate::solana_rbpf::memory_region::MemoryMapping,
|
||||
result: &mut $crate::solana_rbpf::vm::ProgramResult,
|
||||
) {
|
||||
) -> std::result::Result<u64, Box<dyn std::error::Error>> {
|
||||
fn process_instruction_inner(
|
||||
$invoke_context: &mut $crate::invoke_context::InvokeContext,
|
||||
) -> std::result::Result<(), solana_sdk::instruction::InstructionError> {
|
||||
|
@ -69,14 +71,15 @@ macro_rules! declare_process_instruction {
|
|||
} else {
|
||||
Ok(())
|
||||
};
|
||||
*result = consumption_result
|
||||
consumption_result
|
||||
.and_then(|_| {
|
||||
process_instruction_inner(invoke_context)
|
||||
.map(|_| 0)
|
||||
.map_err(|err| Box::new(err) as Box<dyn std::error::Error>)
|
||||
})
|
||||
.into();
|
||||
.into()
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -468,11 +471,11 @@ impl<'a> InvokeContext<'a> {
|
|||
.programs_loaded_for_tx_batch
|
||||
.find(&builtin_id)
|
||||
.ok_or(InstructionError::UnsupportedProgramId)?;
|
||||
let process_instruction = match &entry.program {
|
||||
let function = match &entry.program {
|
||||
LoadedProgramType::Builtin(program) => program
|
||||
.get_function_registry()
|
||||
.lookup_by_key(ENTRYPOINT_KEY)
|
||||
.map(|(_name, process_instruction)| process_instruction),
|
||||
.map(|(_name, function)| function),
|
||||
_ => None,
|
||||
}
|
||||
.ok_or(InstructionError::UnsupportedProgramId)?;
|
||||
|
@ -484,31 +487,41 @@ impl<'a> InvokeContext<'a> {
|
|||
let logger = self.get_log_collector();
|
||||
stable_log::program_invoke(&logger, &program_id, self.get_stack_height());
|
||||
let pre_remaining_units = self.get_remaining();
|
||||
// In program-runtime v2 we will create this VM instance only once per transaction.
|
||||
// `program_runtime_environment_v2.get_config()` will be used instead of `mock_config`.
|
||||
// For now, only built-ins are invoked from here, so the VM and its Config are irrelevant.
|
||||
let mock_config = Config::default();
|
||||
let mut mock_memory_mapping =
|
||||
MemoryMapping::new(Vec::new(), &mock_config, &SBPFVersion::V2).unwrap();
|
||||
let mut result = ProgramResult::Ok(0);
|
||||
process_instruction(
|
||||
let empty_memory_mapping =
|
||||
MemoryMapping::new(Vec::new(), &mock_config, &SBPFVersion::V1).unwrap();
|
||||
let mut vm = EbpfVm::new(
|
||||
self.programs_loaded_for_tx_batch
|
||||
.environments
|
||||
.program_runtime_v2
|
||||
.clone(),
|
||||
&SBPFVersion::V1,
|
||||
// Removes lifetime tracking
|
||||
unsafe { std::mem::transmute::<&mut InvokeContext, &mut InvokeContext>(self) },
|
||||
empty_memory_mapping,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&mut mock_memory_mapping,
|
||||
&mut result,
|
||||
);
|
||||
let result = match result {
|
||||
vm.invoke_function(function);
|
||||
let result = match vm.program_result {
|
||||
ProgramResult::Ok(_) => {
|
||||
stable_log::program_success(&logger, &program_id);
|
||||
Ok(())
|
||||
}
|
||||
ProgramResult::Err(err) => {
|
||||
stable_log::program_failure(&logger, &program_id, err.as_ref());
|
||||
if let Some(err) = err.downcast_ref::<InstructionError>() {
|
||||
Err(err.clone())
|
||||
ProgramResult::Err(ref err) => {
|
||||
if let EbpfError::SyscallError(syscall_error) = err {
|
||||
if let Some(instruction_err) = syscall_error.downcast_ref::<InstructionError>()
|
||||
{
|
||||
stable_log::program_failure(&logger, &program_id, instruction_err);
|
||||
Err(instruction_err.clone())
|
||||
} else {
|
||||
stable_log::program_failure(&logger, &program_id, syscall_error);
|
||||
Err(InstructionError::ProgramFailedToComplete)
|
||||
}
|
||||
} else {
|
||||
stable_log::program_failure(&logger, &program_id, err);
|
||||
Err(InstructionError::ProgramFailedToComplete)
|
||||
}
|
||||
}
|
||||
|
@ -699,7 +712,7 @@ pub fn mock_process_instruction<F: FnMut(&mut InvokeContext), G: FnMut(&mut Invo
|
|||
mut transaction_accounts: Vec<TransactionAccount>,
|
||||
instruction_account_metas: Vec<AccountMeta>,
|
||||
expected_result: Result<(), InstructionError>,
|
||||
process_instruction: ProcessInstructionWithContext,
|
||||
builtin_function: BuiltinFunctionWithContext,
|
||||
mut pre_adjustments: F,
|
||||
mut post_adjustments: G,
|
||||
) -> Vec<AccountSharedData> {
|
||||
|
@ -734,7 +747,7 @@ pub fn mock_process_instruction<F: FnMut(&mut InvokeContext), G: FnMut(&mut Invo
|
|||
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
|
||||
programs_loaded_for_tx_batch.replenish(
|
||||
*loader_id,
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, builtin_function)),
|
||||
);
|
||||
invoke_context.programs_loaded_for_tx_batch = &programs_loaded_for_tx_batch;
|
||||
pre_adjustments(&mut invoke_context);
|
||||
|
@ -782,7 +795,7 @@ mod tests {
|
|||
const MOCK_BUILTIN_COMPUTE_UNIT_COST: u64 = 1;
|
||||
|
||||
declare_process_instruction!(
|
||||
process_instruction,
|
||||
MockBuiltin,
|
||||
MOCK_BUILTIN_COMPUTE_UNIT_COST,
|
||||
|invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
|
@ -988,7 +1001,7 @@ mod tests {
|
|||
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
|
||||
programs_loaded_for_tx_batch.replenish(
|
||||
callee_program_id,
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
|
||||
);
|
||||
invoke_context.programs_loaded_for_tx_batch = &programs_loaded_for_tx_batch;
|
||||
|
||||
|
@ -1134,7 +1147,7 @@ mod tests {
|
|||
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
|
||||
programs_loaded_for_tx_batch.replenish(
|
||||
program_key,
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
|
||||
);
|
||||
invoke_context.programs_loaded_for_tx_batch = &programs_loaded_for_tx_batch;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
invoke_context::{InvokeContext, ProcessInstructionWithContext},
|
||||
invoke_context::{BuiltinFunctionWithContext, InvokeContext},
|
||||
timings::ExecuteDetailsTimings,
|
||||
},
|
||||
itertools::Itertools,
|
||||
|
@ -8,9 +8,10 @@ use {
|
|||
percentage::PercentageInteger,
|
||||
solana_measure::measure::Measure,
|
||||
solana_rbpf::{
|
||||
elf::{Executable, FunctionRegistry},
|
||||
elf::Executable,
|
||||
program::{BuiltinProgram, FunctionRegistry},
|
||||
verifier::RequisiteVerifier,
|
||||
vm::{BuiltinProgram, Config},
|
||||
vm::Config,
|
||||
},
|
||||
solana_sdk::{
|
||||
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
|
||||
|
@ -370,11 +371,11 @@ impl LoadedProgram {
|
|||
pub fn new_builtin(
|
||||
deployment_slot: Slot,
|
||||
account_size: usize,
|
||||
entrypoint: ProcessInstructionWithContext,
|
||||
builtin_function: BuiltinFunctionWithContext,
|
||||
) -> Self {
|
||||
let mut function_registry = FunctionRegistry::default();
|
||||
function_registry
|
||||
.register_function_hashed(*b"entrypoint", entrypoint)
|
||||
.register_function_hashed(*b"entrypoint", builtin_function)
|
||||
.unwrap();
|
||||
Self {
|
||||
deployment_slot,
|
||||
|
@ -949,7 +950,7 @@ mod tests {
|
|||
},
|
||||
assert_matches::assert_matches,
|
||||
percentage::Percentage,
|
||||
solana_rbpf::vm::BuiltinProgram,
|
||||
solana_rbpf::program::BuiltinProgram,
|
||||
solana_sdk::{
|
||||
clock::{Epoch, Slot},
|
||||
pubkey::Pubkey,
|
||||
|
|
|
@ -220,7 +220,7 @@ mod tests {
|
|||
ChangeData { data: u8 },
|
||||
}
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let instruction_data = instruction_context.get_instruction_data();
|
||||
|
@ -271,7 +271,7 @@ mod tests {
|
|||
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
|
||||
programs_loaded_for_tx_batch.replenish(
|
||||
mock_system_program_id,
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
|
||||
);
|
||||
let account_keys = (0..transaction_context.get_number_of_accounts())
|
||||
.map(|index| {
|
||||
|
@ -432,7 +432,7 @@ mod tests {
|
|||
DoWork { lamports: u64, data: u8 },
|
||||
}
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let instruction_data = instruction_context.get_instruction_data();
|
||||
|
@ -500,7 +500,7 @@ mod tests {
|
|||
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
|
||||
programs_loaded_for_tx_batch.replenish(
|
||||
mock_program_id,
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
|
||||
);
|
||||
let account_metas = vec![
|
||||
AccountMeta::new(
|
||||
|
@ -645,7 +645,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_precompile() {
|
||||
let mock_program_id = Pubkey::new_unique();
|
||||
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |_invoke_context| {
|
||||
Err(InstructionError::Custom(0xbabb1e))
|
||||
});
|
||||
|
||||
|
@ -684,7 +684,7 @@ mod tests {
|
|||
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
|
||||
programs_loaded_for_tx_batch.replenish(
|
||||
mock_program_id,
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
|
||||
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
|
||||
);
|
||||
let mut programs_modified_by_tx = LoadedProgramsForTxBatch::default();
|
||||
let mut programs_updated_only_for_global_cache = LoadedProgramsForTxBatch::default();
|
||||
|
|
|
@ -101,10 +101,10 @@ pub fn program_success(log_collector: &Option<Rc<RefCell<LogCollector>>>, progra
|
|||
/// ```notrust
|
||||
/// "Program <address> failed: <program error details>"
|
||||
/// ```
|
||||
pub fn program_failure(
|
||||
pub fn program_failure<E: std::fmt::Display>(
|
||||
log_collector: &Option<Rc<RefCell<LogCollector>>>,
|
||||
program_id: &Pubkey,
|
||||
err: &dyn std::error::Error,
|
||||
err: &E,
|
||||
) {
|
||||
ic_logger_msg!(log_collector, "Program {} failed: {}", program_id, err);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ solana-program-runtime = { workspace = true }
|
|||
solana-runtime = { workspace = true }
|
||||
solana-sdk = { workspace = true }
|
||||
solana-vote-program = { workspace = true }
|
||||
solana_rbpf = { workspace = true }
|
||||
test-case = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
|
|
|
@ -13,7 +13,7 @@ use {
|
|||
solana_banks_server::banks_server::start_local_server,
|
||||
solana_bpf_loader_program::serialization::serialize_parameters,
|
||||
solana_program_runtime::{
|
||||
compute_budget::ComputeBudget, ic_msg, invoke_context::ProcessInstructionWithContext,
|
||||
compute_budget::ComputeBudget, ic_msg, invoke_context::BuiltinFunctionWithContext,
|
||||
loaded_programs::LoadedProgram, stable_log, timings::ExecuteTimings,
|
||||
},
|
||||
solana_runtime::{
|
||||
|
@ -66,6 +66,10 @@ pub use {
|
|||
solana_banks_client::{BanksClient, BanksClientError},
|
||||
solana_banks_interface::BanksTransactionResultWithMetadata,
|
||||
solana_program_runtime::invoke_context::InvokeContext,
|
||||
solana_rbpf::{
|
||||
error::EbpfError,
|
||||
vm::{get_runtime_environment_key, EbpfVm},
|
||||
},
|
||||
solana_sdk::transaction_context::IndexOfAccount,
|
||||
};
|
||||
|
||||
|
@ -94,10 +98,10 @@ fn get_invoke_context<'a, 'b>() -> &'a mut InvokeContext<'b> {
|
|||
unsafe { transmute::<usize, &mut InvokeContext>(ptr) }
|
||||
}
|
||||
|
||||
pub fn builtin_process_instruction(
|
||||
process_instruction: solana_sdk::entrypoint::ProcessInstruction,
|
||||
pub fn invoke_builtin_function(
|
||||
builtin_function: solana_sdk::entrypoint::ProcessInstruction,
|
||||
invoke_context: &mut InvokeContext,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
) -> Result<u64, Box<dyn std::error::Error>> {
|
||||
set_invoke_context(invoke_context);
|
||||
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
|
@ -130,9 +134,10 @@ pub fn builtin_process_instruction(
|
|||
unsafe { deserialize(&mut parameter_bytes.as_slice_mut()[0] as *mut u8) };
|
||||
|
||||
// Execute the program
|
||||
process_instruction(program_id, &account_infos, instruction_data).map_err(|err| {
|
||||
let err: Box<dyn std::error::Error> = Box::new(InstructionError::from(u64::from(err)));
|
||||
stable_log::program_failure(&log_collector, program_id, err.as_ref());
|
||||
builtin_function(program_id, &account_infos, instruction_data).map_err(|err| {
|
||||
let err = InstructionError::from(u64::from(err));
|
||||
stable_log::program_failure(&log_collector, program_id, &err);
|
||||
let err: Box<dyn std::error::Error> = Box::new(err);
|
||||
err
|
||||
})?;
|
||||
stable_log::program_success(&log_collector, program_id);
|
||||
|
@ -169,21 +174,24 @@ pub fn builtin_process_instruction(
|
|||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
/// Converts a `solana-program`-style entrypoint into the runtime's entrypoint style, for
|
||||
/// use with `ProgramTest::add_program`
|
||||
#[macro_export]
|
||||
macro_rules! processor {
|
||||
($process_instruction:expr) => {
|
||||
Some(
|
||||
|invoke_context, _arg0, _arg1, _arg2, _arg3, _arg4, _memory_mapping, result| {
|
||||
*result = $crate::builtin_process_instruction($process_instruction, invoke_context)
|
||||
.map(|_| 0)
|
||||
($builtin_function:expr) => {
|
||||
Some(|vm, _arg0, _arg1, _arg2, _arg3, _arg4| {
|
||||
let vm = unsafe {
|
||||
&mut *((vm as *mut u64).offset(-($crate::get_runtime_environment_key() as isize))
|
||||
as *mut $crate::EbpfVm<$crate::InvokeContext>)
|
||||
};
|
||||
vm.program_result =
|
||||
$crate::invoke_builtin_function($builtin_function, vm.context_object_pointer)
|
||||
.map_err(|err| $crate::EbpfError::SyscallError(err))
|
||||
.into();
|
||||
},
|
||||
)
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -506,10 +514,10 @@ impl ProgramTest {
|
|||
pub fn new(
|
||||
program_name: &str,
|
||||
program_id: Pubkey,
|
||||
process_instruction: Option<ProcessInstructionWithContext>,
|
||||
builtin_function: Option<BuiltinFunctionWithContext>,
|
||||
) -> Self {
|
||||
let mut me = Self::default();
|
||||
me.add_program(program_name, program_id, process_instruction);
|
||||
me.add_program(program_name, program_id, builtin_function);
|
||||
me
|
||||
}
|
||||
|
||||
|
@ -600,13 +608,13 @@ impl ProgramTest {
|
|||
/// `program_name` will also be used to locate the SBF shared object in the current or fixtures
|
||||
/// directory.
|
||||
///
|
||||
/// If `process_instruction` is provided, the natively built-program may be used instead of the
|
||||
/// If `builtin_function` is provided, the natively built-program may be used instead of the
|
||||
/// SBF shared object depending on the `BPF_OUT_DIR` environment variable.
|
||||
pub fn add_program(
|
||||
&mut self,
|
||||
program_name: &str,
|
||||
program_id: Pubkey,
|
||||
process_instruction: Option<ProcessInstructionWithContext>,
|
||||
builtin_function: Option<BuiltinFunctionWithContext>,
|
||||
) {
|
||||
let add_bpf = |this: &mut ProgramTest, program_file: PathBuf| {
|
||||
let data = read_file(&program_file);
|
||||
|
@ -680,7 +688,7 @@ impl ProgramTest {
|
|||
};
|
||||
|
||||
let program_file = find_file(&format!("{program_name}.so"));
|
||||
match (self.prefer_bpf, program_file, process_instruction) {
|
||||
match (self.prefer_bpf, program_file, builtin_function) {
|
||||
// If SBF is preferred (i.e., `test-sbf` is invoked) and a BPF shared object exists,
|
||||
// use that as the program data.
|
||||
(true, Some(file), _) => add_bpf(self, file),
|
||||
|
@ -689,8 +697,8 @@ impl ProgramTest {
|
|||
// processor function as is.
|
||||
//
|
||||
// TODO: figure out why tests hang if a processor panics when running native code.
|
||||
(false, _, Some(process)) => {
|
||||
self.add_builtin_program(program_name, program_id, process)
|
||||
(false, _, Some(builtin_function)) => {
|
||||
self.add_builtin_program(program_name, program_id, builtin_function)
|
||||
}
|
||||
|
||||
// Invalid: `test-sbf` invocation with no matching SBF shared object.
|
||||
|
@ -713,13 +721,13 @@ impl ProgramTest {
|
|||
&mut self,
|
||||
program_name: &str,
|
||||
program_id: Pubkey,
|
||||
process_instruction: ProcessInstructionWithContext,
|
||||
builtin_function: BuiltinFunctionWithContext,
|
||||
) {
|
||||
info!("\"{}\" builtin program", program_name);
|
||||
self.builtin_programs.push((
|
||||
program_id,
|
||||
program_name.to_string(),
|
||||
LoadedProgram::new_builtin(0, program_name.len(), process_instruction),
|
||||
LoadedProgram::new_builtin(0, program_name.len(), builtin_function),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#![allow(dead_code)]
|
||||
use {
|
||||
solana_address_lookup_table_program::processor::process_instruction,
|
||||
solana_program_test::*,
|
||||
solana_sdk::{
|
||||
account::AccountSharedData,
|
||||
|
@ -20,7 +19,11 @@ use {
|
|||
};
|
||||
|
||||
pub async fn setup_test_context() -> ProgramTestContext {
|
||||
let program_test = ProgramTest::new("", id(), Some(process_instruction));
|
||||
let program_test = ProgramTest::new(
|
||||
"",
|
||||
id(),
|
||||
Some(solana_address_lookup_table_program::processor::Entrypoint::vm),
|
||||
);
|
||||
program_test.start_with_context().await
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use {
|
||||
assert_matches::assert_matches,
|
||||
common::{assert_ix_error, overwrite_slot_hashes_with_slots, setup_test_context},
|
||||
solana_address_lookup_table_program::processor::process_instruction,
|
||||
solana_program_test::*,
|
||||
solana_sdk::{
|
||||
address_lookup_table::{
|
||||
|
@ -23,7 +22,11 @@ use {
|
|||
mod common;
|
||||
|
||||
pub async fn setup_test_context_without_authority_feature() -> ProgramTestContext {
|
||||
let mut program_test = ProgramTest::new("", id(), Some(process_instruction));
|
||||
let mut program_test = ProgramTest::new(
|
||||
"",
|
||||
id(),
|
||||
Some(solana_address_lookup_table_program::processor::Entrypoint::vm),
|
||||
);
|
||||
program_test.deactivate_feature(
|
||||
feature_set::relax_authority_signer_check_for_lookup_table_creation::id(),
|
||||
);
|
||||
|
|
|
@ -21,10 +21,7 @@ use {
|
|||
|
||||
pub const DEFAULT_COMPUTE_UNITS: u64 = 750;
|
||||
|
||||
declare_process_instruction!(
|
||||
process_instruction,
|
||||
DEFAULT_COMPUTE_UNITS,
|
||||
|invoke_context| {
|
||||
declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let instruction_data = instruction_context.get_instruction_data();
|
||||
|
@ -42,8 +39,7 @@ declare_process_instruction!(
|
|||
}
|
||||
ProgramInstruction::CloseLookupTable => Processor::close_lookup_table(invoke_context),
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
fn checked_add(a: usize, b: usize) -> Result<usize, InstructionError> {
|
||||
a.checked_add(b).ok_or(InstructionError::ArithmeticOverflow)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use {
|
||||
solana_bpf_loader_program::process_instruction,
|
||||
solana_program_test::*,
|
||||
solana_sdk::{
|
||||
account::AccountSharedData,
|
||||
|
@ -15,7 +14,7 @@ use {
|
|||
};
|
||||
|
||||
pub async fn setup_test_context() -> ProgramTestContext {
|
||||
let program_test = ProgramTest::new("", id(), Some(process_instruction));
|
||||
let program_test = ProgramTest::new("", id(), Some(solana_bpf_loader_program::Entrypoint::vm));
|
||||
program_test.start_with_context().await
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,14 @@ use {
|
|||
},
|
||||
solana_rbpf::{
|
||||
aligned_memory::AlignedMemory,
|
||||
declare_builtin_function,
|
||||
ebpf::{self, HOST_ALIGN, MM_HEAP_START},
|
||||
elf::Executable,
|
||||
error::EbpfError,
|
||||
error::{EbpfError, ProgramResult},
|
||||
memory_region::{AccessType, MemoryCowCallback, MemoryMapping, MemoryRegion},
|
||||
program::BuiltinProgram,
|
||||
verifier::RequisiteVerifier,
|
||||
vm::{BuiltinProgram, ContextObject, EbpfVm, ProgramResult},
|
||||
vm::{ContextObject, EbpfVm},
|
||||
},
|
||||
solana_sdk::{
|
||||
account::WritableAccount,
|
||||
|
@ -265,7 +267,7 @@ pub fn create_vm<'a, 'b>(
|
|||
trace_log: Vec::new(),
|
||||
})?;
|
||||
Ok(EbpfVm::new(
|
||||
program.get_config(),
|
||||
program.get_loader().clone(),
|
||||
program.get_sbpf_version(),
|
||||
invoke_context,
|
||||
memory_mapping,
|
||||
|
@ -317,7 +319,7 @@ macro_rules! create_vm {
|
|||
macro_rules! mock_create_vm {
|
||||
($vm:ident, $additional_regions:expr, $accounts_metadata:expr, $invoke_context:expr $(,)?) => {
|
||||
let loader = std::sync::Arc::new(BuiltinProgram::new_mock());
|
||||
let function_registry = solana_rbpf::elf::FunctionRegistry::default();
|
||||
let function_registry = solana_rbpf::program::FunctionRegistry::default();
|
||||
let executable = solana_rbpf::elf::Executable::<InvokeContext>::from_text_bytes(
|
||||
&[0x95, 0, 0, 0, 0, 0, 0, 0],
|
||||
loader,
|
||||
|
@ -371,7 +373,9 @@ fn create_memory_mapping<'a, 'b, C: ContextObject>(
|
|||
})
|
||||
}
|
||||
|
||||
pub fn process_instruction(
|
||||
declare_builtin_function!(
|
||||
Entrypoint,
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
_arg0: u64,
|
||||
_arg1: u64,
|
||||
|
@ -379,12 +383,12 @@ pub fn process_instruction(
|
|||
_arg3: u64,
|
||||
_arg4: u64,
|
||||
_memory_mapping: &mut MemoryMapping,
|
||||
result: &mut ProgramResult,
|
||||
) {
|
||||
*result = process_instruction_inner(invoke_context).into();
|
||||
) -> Result<u64, Box<dyn std::error::Error>> {
|
||||
process_instruction_inner(invoke_context)
|
||||
}
|
||||
);
|
||||
|
||||
fn process_instruction_inner(
|
||||
pub fn process_instruction_inner(
|
||||
invoke_context: &mut InvokeContext,
|
||||
) -> Result<u64, Box<dyn std::error::Error>> {
|
||||
let log_collector = invoke_context.get_log_collector();
|
||||
|
@ -1607,13 +1611,12 @@ fn execute<'a, 'b: 'a>(
|
|||
}
|
||||
ProgramResult::Err(mut error) => {
|
||||
if direct_mapping {
|
||||
if let Some(EbpfError::AccessViolation(
|
||||
_pc,
|
||||
if let EbpfError::AccessViolation(
|
||||
AccessType::Store,
|
||||
address,
|
||||
_size,
|
||||
_section_name,
|
||||
)) = error.downcast_ref()
|
||||
) = error
|
||||
{
|
||||
// If direct_mapping is enabled and a program tries to write to a readonly
|
||||
// region we'll get a memory access violation. Map it to a more specific
|
||||
|
@ -1621,7 +1624,7 @@ fn execute<'a, 'b: 'a>(
|
|||
if let Some((instruction_account_index, _)) = account_region_addrs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, vm_region)| vm_region.contains(address))
|
||||
.find(|(_, vm_region)| vm_region.contains(&address))
|
||||
{
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context =
|
||||
|
@ -1632,18 +1635,22 @@ fn execute<'a, 'b: 'a>(
|
|||
instruction_account_index as IndexOfAccount,
|
||||
)?;
|
||||
|
||||
error = Box::new(if account.is_executable() {
|
||||
error = EbpfError::SyscallError(Box::new(if account.is_executable() {
|
||||
InstructionError::ExecutableDataModified
|
||||
} else if account.is_writable() {
|
||||
InstructionError::ExternalAccountDataModified
|
||||
} else {
|
||||
InstructionError::ReadonlyDataModified
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(if let EbpfError::SyscallError(err) = error {
|
||||
err
|
||||
} else {
|
||||
error.into()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(error)
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
};
|
||||
|
@ -1790,7 +1797,7 @@ mod tests {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
expected_result,
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|invoke_context| {
|
||||
test_utils::load_all_invoked_programs(invoke_context);
|
||||
},
|
||||
|
@ -2009,7 +2016,7 @@ mod tests {
|
|||
vec![(program_id, program_account.clone())],
|
||||
Vec::new(),
|
||||
Err(InstructionError::ProgramFailedToComplete),
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|invoke_context| {
|
||||
invoke_context.mock_set_remaining(0);
|
||||
test_utils::load_all_invoked_programs(invoke_context);
|
||||
|
@ -2555,7 +2562,7 @@ mod tests {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
expected_result,
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|_invoke_context| {},
|
||||
|_invoke_context| {},
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
super::*,
|
||||
crate::{declare_syscall, serialization::account_data_region_memory_state},
|
||||
crate::serialization::account_data_region_memory_state,
|
||||
scopeguard::defer,
|
||||
solana_program_runtime::invoke_context::SerializedAccountMetadata,
|
||||
solana_rbpf::{
|
||||
|
@ -455,10 +455,10 @@ trait SyscallInvokeSigned {
|
|||
) -> Result<Vec<Pubkey>, Error>;
|
||||
}
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Cross-program invocation called from Rust
|
||||
SyscallInvokeSignedRust,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
instruction_addr: u64,
|
||||
account_infos_addr: u64,
|
||||
|
@ -689,10 +689,10 @@ struct SolSignerSeedsC {
|
|||
len: u64,
|
||||
}
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Cross-program invocation called from C
|
||||
SyscallInvokeSignedC,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
instruction_addr: u64,
|
||||
account_infos_addr: u64,
|
||||
|
@ -1730,7 +1730,7 @@ mod tests {
|
|||
invoke_context::SerializedAccountMetadata, with_mock_invoke_context,
|
||||
},
|
||||
solana_rbpf::{
|
||||
ebpf::MM_INPUT_START, elf::SBPFVersion, memory_region::MemoryRegion, vm::Config,
|
||||
ebpf::MM_INPUT_START, memory_region::MemoryRegion, program::SBPFVersion, vm::Config,
|
||||
},
|
||||
solana_sdk::{
|
||||
account::{Account, AccountSharedData},
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use {super::*, crate::declare_syscall, solana_rbpf::vm::ContextObject};
|
||||
use {super::*, solana_rbpf::vm::ContextObject};
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Log a user's info message
|
||||
SyscallLog,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
addr: u64,
|
||||
len: u64,
|
||||
|
@ -36,10 +36,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Log 5 64-bit values
|
||||
SyscallLogU64,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
arg1: u64,
|
||||
arg2: u64,
|
||||
|
@ -59,10 +59,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Log current compute consumption
|
||||
SyscallLogBpfComputeUnits,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
_arg1: u64,
|
||||
_arg2: u64,
|
||||
|
@ -83,10 +83,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Log 5 64-bit values
|
||||
SyscallLogPubkey,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
pubkey_addr: u64,
|
||||
_arg2: u64,
|
||||
|
@ -108,10 +108,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Log data handling
|
||||
SyscallLogData,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
addr: u64,
|
||||
len: u64,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use {
|
||||
super::*,
|
||||
crate::declare_syscall,
|
||||
solana_rbpf::{error::EbpfError, memory_region::MemoryRegion},
|
||||
std::slice,
|
||||
};
|
||||
|
@ -14,10 +13,10 @@ fn mem_op_consume(invoke_context: &mut InvokeContext, n: u64) -> Result<(), Erro
|
|||
consume_compute_meter(invoke_context, cost)
|
||||
}
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// memcpy
|
||||
SyscallMemcpy,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
dst_addr: u64,
|
||||
src_addr: u64,
|
||||
|
@ -37,10 +36,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// memmove
|
||||
SyscallMemmove,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
dst_addr: u64,
|
||||
src_addr: u64,
|
||||
|
@ -55,10 +54,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// memcmp
|
||||
SyscallMemcmp,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
s1_addr: u64,
|
||||
s2_addr: u64,
|
||||
|
@ -113,10 +112,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// memset
|
||||
SyscallMemset,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
dst_addr: u64,
|
||||
c: u64,
|
||||
|
@ -375,7 +374,6 @@ impl<'a> MemoryChunkIterator<'a> {
|
|||
len: u64,
|
||||
) -> Result<MemoryChunkIterator<'a>, EbpfError> {
|
||||
let vm_addr_end = vm_addr.checked_add(len).ok_or(EbpfError::AccessViolation(
|
||||
0,
|
||||
access_type,
|
||||
vm_addr,
|
||||
len,
|
||||
|
@ -394,26 +392,19 @@ impl<'a> MemoryChunkIterator<'a> {
|
|||
fn region(&mut self, vm_addr: u64) -> Result<&'a MemoryRegion, Error> {
|
||||
match self.memory_mapping.region(self.access_type, vm_addr) {
|
||||
Ok(region) => Ok(region),
|
||||
Err(error) => match error.downcast_ref() {
|
||||
Some(EbpfError::AccessViolation(pc, access_type, _vm_addr, _len, name)) => {
|
||||
Err(Box::new(EbpfError::AccessViolation(
|
||||
*pc,
|
||||
*access_type,
|
||||
self.initial_vm_addr,
|
||||
self.len,
|
||||
name,
|
||||
)))
|
||||
}
|
||||
Some(EbpfError::StackAccessViolation(pc, access_type, _vm_addr, _len, frame)) => {
|
||||
Err(error) => match error {
|
||||
EbpfError::AccessViolation(access_type, _vm_addr, _len, name) => Err(Box::new(
|
||||
EbpfError::AccessViolation(access_type, self.initial_vm_addr, self.len, name),
|
||||
)),
|
||||
EbpfError::StackAccessViolation(access_type, _vm_addr, _len, frame) => {
|
||||
Err(Box::new(EbpfError::StackAccessViolation(
|
||||
*pc,
|
||||
*access_type,
|
||||
access_type,
|
||||
self.initial_vm_addr,
|
||||
self.len,
|
||||
*frame,
|
||||
frame,
|
||||
)))
|
||||
}
|
||||
_ => Err(error),
|
||||
_ => Err(error.into()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -489,7 +480,7 @@ mod tests {
|
|||
use {
|
||||
super::*,
|
||||
assert_matches::assert_matches,
|
||||
solana_rbpf::{ebpf::MM_PROGRAM_START, elf::SBPFVersion},
|
||||
solana_rbpf::{ebpf::MM_PROGRAM_START, program::SBPFVersion},
|
||||
};
|
||||
|
||||
fn to_chunk_vec<'a>(
|
||||
|
@ -547,7 +538,7 @@ mod tests {
|
|||
.unwrap();
|
||||
assert_matches!(
|
||||
src_chunk_iter.next().unwrap().unwrap_err().downcast_ref().unwrap(),
|
||||
EbpfError::AccessViolation(0, AccessType::Load, addr, 42, "unknown") if *addr == MM_PROGRAM_START - 1
|
||||
EbpfError::AccessViolation(AccessType::Load, addr, 42, "unknown") if *addr == MM_PROGRAM_START - 1
|
||||
);
|
||||
|
||||
// check oob at the upper bound. Since the memory mapping isn't empty,
|
||||
|
@ -558,7 +549,7 @@ mod tests {
|
|||
assert!(src_chunk_iter.next().unwrap().is_ok());
|
||||
assert_matches!(
|
||||
src_chunk_iter.next().unwrap().unwrap_err().downcast_ref().unwrap(),
|
||||
EbpfError::AccessViolation(0, AccessType::Load, addr, 43, "program") if *addr == MM_PROGRAM_START
|
||||
EbpfError::AccessViolation(AccessType::Load, addr, 43, "program") if *addr == MM_PROGRAM_START
|
||||
);
|
||||
|
||||
// check oob at the upper bound on the first next_back()
|
||||
|
@ -568,7 +559,7 @@ mod tests {
|
|||
.rev();
|
||||
assert_matches!(
|
||||
src_chunk_iter.next().unwrap().unwrap_err().downcast_ref().unwrap(),
|
||||
EbpfError::AccessViolation(0, AccessType::Load, addr, 43, "program") if *addr == MM_PROGRAM_START
|
||||
EbpfError::AccessViolation(AccessType::Load, addr, 43, "program") if *addr == MM_PROGRAM_START
|
||||
);
|
||||
|
||||
// check oob at the upper bound on the 2nd next_back()
|
||||
|
@ -579,7 +570,7 @@ mod tests {
|
|||
assert!(src_chunk_iter.next().unwrap().is_ok());
|
||||
assert_matches!(
|
||||
src_chunk_iter.next().unwrap().unwrap_err().downcast_ref().unwrap(),
|
||||
EbpfError::AccessViolation(0, AccessType::Load, addr, 43, "unknown") if *addr == MM_PROGRAM_START - 1
|
||||
EbpfError::AccessViolation(AccessType::Load, addr, 43, "unknown") if *addr == MM_PROGRAM_START - 1
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -707,7 +698,7 @@ mod tests {
|
|||
false,
|
||||
|_src, _dst, _len| Ok::<_, Error>(0),
|
||||
).unwrap_err().downcast_ref().unwrap(),
|
||||
EbpfError::AccessViolation(0, AccessType::Load, addr, 8, "program") if *addr == MM_PROGRAM_START + 8
|
||||
EbpfError::AccessViolation(AccessType::Load, addr, 8, "program") if *addr == MM_PROGRAM_START + 8
|
||||
);
|
||||
|
||||
// src is shorter than dst
|
||||
|
@ -722,12 +713,12 @@ mod tests {
|
|||
false,
|
||||
|_src, _dst, _len| Ok::<_, Error>(0),
|
||||
).unwrap_err().downcast_ref().unwrap(),
|
||||
EbpfError::AccessViolation(0, AccessType::Load, addr, 3, "program") if *addr == MM_PROGRAM_START + 10
|
||||
EbpfError::AccessViolation(AccessType::Load, addr, 3, "program") if *addr == MM_PROGRAM_START + 10
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "AccessViolation(0, Store, 4294967296, 4")]
|
||||
#[should_panic(expected = "AccessViolation(Store, 4294967296, 4")]
|
||||
fn test_memmove_non_contiguous_readonly() {
|
||||
let config = Config {
|
||||
aligned_memory_mapping: false,
|
||||
|
@ -817,7 +808,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "AccessViolation(0, Store, 4294967296, 9")]
|
||||
#[should_panic(expected = "AccessViolation(Store, 4294967296, 9")]
|
||||
fn test_memset_non_contiguous_readonly() {
|
||||
let config = Config {
|
||||
aligned_memory_mapping: false,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
use {super::*, crate::declare_syscall};
|
||||
use super::*;
|
||||
|
||||
fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId + Clone>(
|
||||
sysvar: Result<Arc<T>, InstructionError>,
|
||||
|
@ -22,10 +22,10 @@ fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId + Clone>(
|
|||
Ok(SUCCESS)
|
||||
}
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Get a Clock sysvar
|
||||
SyscallGetClockSysvar,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
var_addr: u64,
|
||||
_arg2: u64,
|
||||
|
@ -44,10 +44,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Get a EpochSchedule sysvar
|
||||
SyscallGetEpochScheduleSysvar,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
var_addr: u64,
|
||||
_arg2: u64,
|
||||
|
@ -66,10 +66,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Get a EpochRewards sysvar
|
||||
SyscallGetEpochRewardsSysvar,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
var_addr: u64,
|
||||
_arg2: u64,
|
||||
|
@ -88,10 +88,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Get a Fees sysvar
|
||||
SyscallGetFeesSysvar,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
var_addr: u64,
|
||||
_arg2: u64,
|
||||
|
@ -113,10 +113,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Get a Rent sysvar
|
||||
SyscallGetRentSysvar,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
var_addr: u64,
|
||||
_arg2: u64,
|
||||
|
@ -135,10 +135,10 @@ declare_syscall!(
|
|||
}
|
||||
);
|
||||
|
||||
declare_syscall!(
|
||||
declare_builtin_function!(
|
||||
/// Get a Last Restart Slot sysvar
|
||||
SyscallGetLastRestartSlotSysvar,
|
||||
fn inner_call(
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
var_addr: u64,
|
||||
_arg2: u64,
|
||||
|
|
|
@ -2,11 +2,7 @@ use solana_program_runtime::declare_process_instruction;
|
|||
|
||||
pub const DEFAULT_COMPUTE_UNITS: u64 = 150;
|
||||
|
||||
declare_process_instruction!(
|
||||
process_instruction,
|
||||
DEFAULT_COMPUTE_UNITS,
|
||||
|_invoke_context| {
|
||||
declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |_invoke_context| {
|
||||
// Do nothing, compute budget instructions handled by the runtime
|
||||
Ok(())
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
@ -13,10 +13,7 @@ use {
|
|||
|
||||
pub const DEFAULT_COMPUTE_UNITS: u64 = 450;
|
||||
|
||||
declare_process_instruction!(
|
||||
process_instruction,
|
||||
DEFAULT_COMPUTE_UNITS,
|
||||
|invoke_context| {
|
||||
declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let data = instruction_context.get_instruction_data();
|
||||
|
@ -136,8 +133,7 @@ declare_process_instruction!(
|
|||
}
|
||||
config_account.get_data_mut()?[..data.len()].copy_from_slice(data);
|
||||
Ok(())
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -169,7 +165,7 @@ mod tests {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
expected_result,
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|_invoke_context| {},
|
||||
|_invoke_context| {},
|
||||
)
|
||||
|
|
|
@ -12,10 +12,12 @@ use {
|
|||
},
|
||||
solana_rbpf::{
|
||||
aligned_memory::AlignedMemory,
|
||||
ebpf,
|
||||
elf::{Executable, FunctionRegistry},
|
||||
declare_builtin_function, ebpf,
|
||||
elf::Executable,
|
||||
error::ProgramResult,
|
||||
memory_region::{MemoryMapping, MemoryRegion},
|
||||
vm::{BuiltinProgram, Config, ContextObject, EbpfVm, ProgramResult},
|
||||
program::{BuiltinProgram, FunctionRegistry},
|
||||
vm::{Config, ContextObject, EbpfVm},
|
||||
},
|
||||
solana_sdk::{
|
||||
entrypoint::SUCCESS,
|
||||
|
@ -81,7 +83,6 @@ pub fn create_program_runtime_environment_v2<'a>(
|
|||
reject_broken_elfs: true,
|
||||
noop_instruction_rate: 256,
|
||||
sanitize_user_provided_values: true,
|
||||
encrypt_runtime_environment: true,
|
||||
external_internal_function_hash_collision: true,
|
||||
reject_callx_r10: true,
|
||||
enable_sbpf_v1: false,
|
||||
|
@ -131,7 +132,7 @@ pub fn create_vm<'a, 'b>(
|
|||
Box::new(InstructionError::ProgramEnvironmentSetupFailure)
|
||||
})?;
|
||||
Ok(EbpfVm::new(
|
||||
config,
|
||||
program.get_loader().clone(),
|
||||
sbpf_version,
|
||||
invoke_context,
|
||||
memory_mapping,
|
||||
|
@ -182,9 +183,9 @@ fn execute<'a, 'b: 'a>(
|
|||
match result {
|
||||
ProgramResult::Ok(status) if status != SUCCESS => {
|
||||
let error: InstructionError = status.into();
|
||||
Err(Box::new(error) as Box<dyn std::error::Error>)
|
||||
Err(error.into())
|
||||
}
|
||||
ProgramResult::Err(error) => Err(error),
|
||||
ProgramResult::Err(error) => Err(error.into()),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
@ -527,7 +528,9 @@ pub fn process_instruction_transfer_authority(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn process_instruction(
|
||||
declare_builtin_function!(
|
||||
Entrypoint,
|
||||
fn rust(
|
||||
invoke_context: &mut InvokeContext,
|
||||
_arg0: u64,
|
||||
_arg1: u64,
|
||||
|
@ -535,10 +538,10 @@ pub fn process_instruction(
|
|||
_arg3: u64,
|
||||
_arg4: u64,
|
||||
_memory_mapping: &mut MemoryMapping,
|
||||
result: &mut ProgramResult,
|
||||
) {
|
||||
*result = process_instruction_inner(invoke_context).into();
|
||||
) -> Result<u64, Box<dyn std::error::Error>> {
|
||||
process_instruction_inner(invoke_context)
|
||||
}
|
||||
);
|
||||
|
||||
pub fn process_instruction_inner(
|
||||
invoke_context: &mut InvokeContext,
|
||||
|
@ -700,7 +703,7 @@ mod tests {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
expected_result,
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|invoke_context| {
|
||||
invoke_context
|
||||
.programs_modified_by_tx
|
||||
|
|
|
@ -5341,6 +5341,7 @@ dependencies = [
|
|||
"solana-runtime",
|
||||
"solana-sdk",
|
||||
"solana-vote-program",
|
||||
"solana_rbpf",
|
||||
"test-case",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
|
@ -6514,9 +6515,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "solana_rbpf"
|
||||
version = "0.7.2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "103318aa365ff7caa8cf534f2246b5eb7e5b34668736d52b1266b143f7a21196"
|
||||
checksum = "3d457cc2ba742c120492a64b7fa60e22c575e891f6b55039f4d736568fb112a3"
|
||||
dependencies = [
|
||||
"byteorder 1.5.0",
|
||||
"combine",
|
||||
|
|
|
@ -48,7 +48,7 @@ solana-sdk = { path = "../../sdk", version = "=1.18.0" }
|
|||
solana-transaction-status = { path = "../../transaction-status", version = "=1.18.0" }
|
||||
solana-validator = { path = "../../validator", version = "=1.18.0" }
|
||||
solana-zk-token-sdk = { path = "../../zk-token-sdk", version = "=1.18.0" }
|
||||
solana_rbpf = "=0.7.2"
|
||||
solana_rbpf = "=0.8.0"
|
||||
static_assertions = "1.1.0"
|
||||
thiserror = "1.0"
|
||||
|
||||
|
|
|
@ -1449,7 +1449,7 @@ fn assert_instruction_count() {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
Ok(()),
|
||||
solana_bpf_loader_program::process_instruction,
|
||||
solana_bpf_loader_program::Entrypoint::vm,
|
||||
|invoke_context| {
|
||||
*prev_compute_meter.borrow_mut() = invoke_context.get_remaining();
|
||||
solana_bpf_loader_program::test_utils::load_all_invoked_programs(invoke_context);
|
||||
|
@ -4397,7 +4397,7 @@ fn test_cpi_change_account_data_memory_allocation() {
|
|||
let feature_set = FeatureSet::all_enabled();
|
||||
bank.feature_set = Arc::new(feature_set);
|
||||
|
||||
declare_process_instruction!(process_instruction, 42, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 42, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let instruction_data = instruction_context.get_instruction_data();
|
||||
|
@ -4428,7 +4428,7 @@ fn test_cpi_change_account_data_memory_allocation() {
|
|||
bank.add_builtin(
|
||||
builtin_program_id,
|
||||
"test_cpi_change_account_data_memory_allocation_builtin".to_string(),
|
||||
LoadedProgram::new_builtin(0, 42, process_instruction),
|
||||
LoadedProgram::new_builtin(0, 42, MockBuiltin::vm),
|
||||
);
|
||||
|
||||
let bank = Arc::new(bank);
|
||||
|
|
|
@ -54,10 +54,7 @@ fn get_optional_pubkey<'a>(
|
|||
|
||||
pub const DEFAULT_COMPUTE_UNITS: u64 = 750;
|
||||
|
||||
declare_process_instruction!(
|
||||
process_instruction,
|
||||
DEFAULT_COMPUTE_UNITS,
|
||||
|invoke_context| {
|
||||
declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let data = instruction_context.get_instruction_data();
|
||||
|
@ -76,8 +73,7 @@ declare_process_instruction!(
|
|||
match limited_deserialize(data) {
|
||||
Ok(StakeInstruction::Initialize(authorized, lockup)) => {
|
||||
let mut me = get_stake_account()?;
|
||||
let rent =
|
||||
get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?;
|
||||
let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?;
|
||||
initialize(&mut me, &authorized, &lockup, &rent)
|
||||
}
|
||||
Ok(StakeInstruction::Authorize(authorized_pubkey, stake_authorize)) => {
|
||||
|
@ -87,11 +83,8 @@ declare_process_instruction!(
|
|||
.is_active(&feature_set::require_custodian_for_locked_stake_authorize::id());
|
||||
|
||||
if require_custodian_for_locked_stake_authorize {
|
||||
let clock = get_sysvar_with_account_check::clock(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
1,
|
||||
)?;
|
||||
let clock =
|
||||
get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?;
|
||||
instruction_context.check_number_of_instruction_accounts(3)?;
|
||||
let custodian_pubkey =
|
||||
get_optional_pubkey(transaction_context, instruction_context, 3, false)?;
|
||||
|
@ -124,11 +117,8 @@ declare_process_instruction!(
|
|||
.feature_set
|
||||
.is_active(&feature_set::require_custodian_for_locked_stake_authorize::id());
|
||||
if require_custodian_for_locked_stake_authorize {
|
||||
let clock = get_sysvar_with_account_check::clock(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
2,
|
||||
)?;
|
||||
let clock =
|
||||
get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
|
||||
let custodian_pubkey =
|
||||
get_optional_pubkey(transaction_context, instruction_context, 3, false)?;
|
||||
|
||||
|
@ -178,8 +168,8 @@ declare_process_instruction!(
|
|||
.is_active(&feature_set::reduce_stake_warmup_cooldown::id())
|
||||
{
|
||||
// Post feature activation, remove both the feature gate code and the config completely in the interface
|
||||
let config_account = instruction_context
|
||||
.try_borrow_instruction_account(transaction_context, 4)?;
|
||||
let config_account =
|
||||
instruction_context.try_borrow_instruction_account(transaction_context, 4)?;
|
||||
#[allow(deprecated)]
|
||||
if !config::check_id(config_account.get_key()) {
|
||||
return Err(InstructionError::InvalidArgument);
|
||||
|
@ -296,11 +286,8 @@ declare_process_instruction!(
|
|||
withdrawer: *withdrawer_pubkey,
|
||||
};
|
||||
|
||||
let rent = get_sysvar_with_account_check::rent(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
1,
|
||||
)?;
|
||||
let rent =
|
||||
get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?;
|
||||
initialize(&mut me, &authorized, &Lockup::default(), &rent)
|
||||
} else {
|
||||
Err(InstructionError::InvalidInstructionData)
|
||||
|
@ -312,11 +299,8 @@ declare_process_instruction!(
|
|||
.feature_set
|
||||
.is_active(&feature_set::vote_stake_checked_instructions::id())
|
||||
{
|
||||
let clock = get_sysvar_with_account_check::clock(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
1,
|
||||
)?;
|
||||
let clock =
|
||||
get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?;
|
||||
instruction_context.check_number_of_instruction_accounts(4)?;
|
||||
let authorized_pubkey = transaction_context.get_key_of_account_at_index(
|
||||
instruction_context.get_index_of_instruction_account_in_transaction(3)?,
|
||||
|
@ -347,11 +331,8 @@ declare_process_instruction!(
|
|||
.is_active(&feature_set::vote_stake_checked_instructions::id())
|
||||
{
|
||||
instruction_context.check_number_of_instruction_accounts(2)?;
|
||||
let clock = get_sysvar_with_account_check::clock(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
2,
|
||||
)?;
|
||||
let clock =
|
||||
get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
|
||||
instruction_context.check_number_of_instruction_accounts(4)?;
|
||||
let authorized_pubkey = transaction_context.get_key_of_account_at_index(
|
||||
instruction_context.get_index_of_instruction_account_in_transaction(3)?,
|
||||
|
@ -457,8 +438,7 @@ declare_process_instruction!(
|
|||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -572,7 +552,7 @@ mod tests {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
expected_result,
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|invoke_context| {
|
||||
invoke_context.feature_set = Arc::clone(&feature_set);
|
||||
},
|
||||
|
@ -7046,7 +7026,7 @@ mod tests {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
Ok(()),
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|invoke_context| {
|
||||
invoke_context.feature_set = Arc::clone(&feature_set);
|
||||
},
|
||||
|
|
|
@ -314,10 +314,7 @@ fn transfer_with_seed(
|
|||
|
||||
pub const DEFAULT_COMPUTE_UNITS: u64 = 150;
|
||||
|
||||
declare_process_instruction!(
|
||||
process_instruction,
|
||||
DEFAULT_COMPUTE_UNITS,
|
||||
|invoke_context| {
|
||||
declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let instruction_data = instruction_context.get_instruction_data();
|
||||
|
@ -450,8 +447,7 @@ declare_process_instruction!(
|
|||
instruction_context,
|
||||
2,
|
||||
)?;
|
||||
let rent =
|
||||
get_sysvar_with_account_check::rent(invoke_context, instruction_context, 3)?;
|
||||
let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 3)?;
|
||||
withdraw_nonce_account(
|
||||
0,
|
||||
lamports,
|
||||
|
@ -480,8 +476,7 @@ declare_process_instruction!(
|
|||
);
|
||||
return Err(SystemError::NonceNoRecentBlockhashes.into());
|
||||
}
|
||||
let rent =
|
||||
get_sysvar_with_account_check::rent(invoke_context, instruction_context, 2)?;
|
||||
let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 2)?;
|
||||
initialize_nonce_account(&mut me, &authorized, &rent, invoke_context)
|
||||
}
|
||||
SystemInstruction::AuthorizeNonceAccount(nonce_authority) => {
|
||||
|
@ -558,8 +553,7 @@ declare_process_instruction!(
|
|||
assign(&mut account, &address, &owner, &signers, invoke_context)
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -609,7 +603,7 @@ mod tests {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
expected_result,
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|_invoke_context| {},
|
||||
|_invoke_context| {},
|
||||
)
|
||||
|
@ -1599,7 +1593,7 @@ mod tests {
|
|||
},
|
||||
],
|
||||
Ok(()),
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|invoke_context: &mut InvokeContext| {
|
||||
invoke_context.blockhash = hash(&serialize(&0).unwrap());
|
||||
},
|
||||
|
@ -1946,7 +1940,7 @@ mod tests {
|
|||
},
|
||||
],
|
||||
Err(SystemError::NonceNoRecentBlockhashes.into()),
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|invoke_context: &mut InvokeContext| {
|
||||
invoke_context.blockhash = hash(&serialize(&0).unwrap());
|
||||
},
|
||||
|
|
|
@ -108,7 +108,7 @@ fn bench_process_vote_instruction(
|
|||
transaction_accounts.clone(),
|
||||
instruction_account_metas.clone(),
|
||||
Ok(()),
|
||||
solana_vote_program::vote_processor::process_instruction,
|
||||
solana_vote_program::vote_processor::Entrypoint::vm,
|
||||
|_invoke_context| {},
|
||||
|_invoke_context| {},
|
||||
);
|
||||
|
|
|
@ -54,10 +54,7 @@ fn process_authorize_with_seed_instruction(
|
|||
// units; can consume based on instructions in the future like `bpf_loader` does.
|
||||
pub const DEFAULT_COMPUTE_UNITS: u64 = 2_100;
|
||||
|
||||
declare_process_instruction!(
|
||||
process_instruction,
|
||||
DEFAULT_COMPUTE_UNITS,
|
||||
|invoke_context| {
|
||||
declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let data = instruction_context.get_instruction_data();
|
||||
|
@ -72,8 +69,7 @@ declare_process_instruction!(
|
|||
let signers = instruction_context.get_signers(transaction_context)?;
|
||||
match limited_deserialize(data)? {
|
||||
VoteInstruction::InitializeAccount(vote_init) => {
|
||||
let rent =
|
||||
get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?;
|
||||
let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?;
|
||||
if !rent.is_exempt(me.get_lamports(), me.get_data().len()) {
|
||||
return Err(InstructionError::InsufficientFunds);
|
||||
}
|
||||
|
@ -162,11 +158,8 @@ declare_process_instruction!(
|
|||
)
|
||||
}
|
||||
VoteInstruction::Vote(vote) | VoteInstruction::VoteSwitch(vote, _) => {
|
||||
let slot_hashes = get_sysvar_with_account_check::slot_hashes(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
1,
|
||||
)?;
|
||||
let slot_hashes =
|
||||
get_sysvar_with_account_check::slot_hashes(invoke_context, instruction_context, 1)?;
|
||||
let clock =
|
||||
get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?;
|
||||
vote_state::process_vote_with_account(
|
||||
|
@ -237,11 +230,8 @@ declare_process_instruction!(
|
|||
if !instruction_context.is_instruction_account_signer(3)? {
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
}
|
||||
let clock = get_sysvar_with_account_check::clock(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
1,
|
||||
)?;
|
||||
let clock =
|
||||
get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?;
|
||||
vote_state::authorize(
|
||||
&mut me,
|
||||
voter_pubkey,
|
||||
|
@ -255,8 +245,7 @@ declare_process_instruction!(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -320,7 +309,7 @@ mod tests {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
expected_result,
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|_invoke_context| {},
|
||||
|_invoke_context| {},
|
||||
)
|
||||
|
@ -339,7 +328,7 @@ mod tests {
|
|||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
expected_result,
|
||||
super::process_instruction,
|
||||
Entrypoint::vm,
|
||||
|invoke_context| {
|
||||
invoke_context.feature_set = std::sync::Arc::new(FeatureSet::default());
|
||||
},
|
||||
|
|
|
@ -130,7 +130,7 @@ fn process_close_proof_context(invoke_context: &mut InvokeContext) -> Result<(),
|
|||
Ok(())
|
||||
}
|
||||
|
||||
declare_process_instruction!(process_instruction, 0, |invoke_context| {
|
||||
declare_process_instruction!(Entrypoint, 0, |invoke_context| {
|
||||
// Consume compute units if feature `native_programs_consume_cu` is activated
|
||||
let native_programs_consume_cu = invoke_context
|
||||
.feature_set
|
||||
|
|
|
@ -125,13 +125,13 @@ fn do_bench_transactions(
|
|||
// freeze bank so that slot hashes is populated
|
||||
bank.freeze();
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |_invoke_context| {
|
||||
// Do nothing
|
||||
Ok(())
|
||||
});
|
||||
|
||||
let mut bank = Bank::new_from_parent(Arc::new(bank), &Pubkey::default(), 1);
|
||||
bank.add_mockup_builtin(Pubkey::from(BUILTIN_PROGRAM_ID), process_instruction);
|
||||
bank.add_mockup_builtin(Pubkey::from(BUILTIN_PROGRAM_ID), MockBuiltin::vm);
|
||||
bank.add_builtin_account("solana_noop_program", &Pubkey::from(NOOP_PROGRAM_ID), false);
|
||||
let bank = Arc::new(bank);
|
||||
let bank_client = BankClient::new_shared(bank.clone());
|
||||
|
|
|
@ -107,7 +107,7 @@ use {
|
|||
solana_program_runtime::{
|
||||
accounts_data_meter::MAX_ACCOUNTS_DATA_LEN,
|
||||
compute_budget::{self, ComputeBudget},
|
||||
invoke_context::ProcessInstructionWithContext,
|
||||
invoke_context::BuiltinFunctionWithContext,
|
||||
loaded_programs::{
|
||||
LoadProgramMetrics, LoadedProgram, LoadedProgramMatchCriteria, LoadedProgramType,
|
||||
LoadedPrograms, LoadedProgramsForTxBatch, WorkingSlot, DELAY_VISIBILITY_SLOT_OFFSET,
|
||||
|
@ -7885,12 +7885,12 @@ impl Bank {
|
|||
pub fn add_mockup_builtin(
|
||||
&mut self,
|
||||
program_id: Pubkey,
|
||||
entrypoint: ProcessInstructionWithContext,
|
||||
builtin_function: BuiltinFunctionWithContext,
|
||||
) {
|
||||
self.add_builtin(
|
||||
program_id,
|
||||
"mockup".to_string(),
|
||||
LoadedProgram::new_builtin(self.slot, 0, entrypoint),
|
||||
LoadedProgram::new_builtin(self.slot, 0, builtin_function),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -653,7 +653,7 @@ fn assert_capitalization_diff(
|
|||
}
|
||||
}
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |_invoke_context| {
|
||||
// Default for all tests which don't bring their own processor
|
||||
Ok(())
|
||||
});
|
||||
|
@ -1246,7 +1246,7 @@ fn test_rent_complex() {
|
|||
Deduction,
|
||||
}
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let instruction_data = instruction_context.get_instruction_data();
|
||||
|
@ -1281,7 +1281,7 @@ fn test_rent_complex() {
|
|||
root_bank.restore_old_behavior_for_fragile_tests();
|
||||
let root_bank = Arc::new(root_bank);
|
||||
let mut bank = create_child_bank_for_rent_test(root_bank, &genesis_config);
|
||||
bank.add_mockup_builtin(mock_program_id, process_instruction);
|
||||
bank.add_mockup_builtin(mock_program_id, MockBuiltin::vm);
|
||||
|
||||
assert_eq!(bank.last_blockhash(), genesis_config.hash());
|
||||
|
||||
|
@ -4684,7 +4684,7 @@ fn test_add_builtin() {
|
|||
fn mock_vote_program_id() -> Pubkey {
|
||||
Pubkey::from([42u8; 32])
|
||||
}
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let program_id = instruction_context.get_last_program_key(transaction_context)?;
|
||||
|
@ -4695,7 +4695,7 @@ fn test_add_builtin() {
|
|||
});
|
||||
|
||||
assert!(bank.get_account(&mock_vote_program_id()).is_none());
|
||||
bank.add_mockup_builtin(mock_vote_program_id(), process_instruction);
|
||||
bank.add_mockup_builtin(mock_vote_program_id(), MockBuiltin::vm);
|
||||
assert!(bank.get_account(&mock_vote_program_id()).is_some());
|
||||
|
||||
let mock_account = Keypair::new();
|
||||
|
@ -4740,7 +4740,7 @@ fn test_add_duplicate_static_program() {
|
|||
} = create_genesis_config_with_leader(500, &solana_sdk::pubkey::new_rand(), 0);
|
||||
let bank = Bank::new_for_tests(&genesis_config);
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |_invoke_context| {
|
||||
Err(InstructionError::Custom(42))
|
||||
});
|
||||
|
||||
|
@ -4771,7 +4771,7 @@ fn test_add_duplicate_static_program() {
|
|||
let mut bank = Bank::new_from_parent(Arc::new(bank), &Pubkey::default(), slot);
|
||||
|
||||
let vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap();
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), process_instruction);
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), MockBuiltin::vm);
|
||||
let new_vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap();
|
||||
// Vote loader account should not be updated since it was included in the genesis config.
|
||||
assert_eq!(vote_loader_account.data(), new_vote_loader_account.data());
|
||||
|
@ -4789,7 +4789,7 @@ fn test_add_instruction_processor_for_existing_unrelated_accounts() {
|
|||
for pass in 0..5 {
|
||||
let mut bank = create_simple_test_bank(500);
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |_invoke_context| {
|
||||
Err(InstructionError::Custom(42))
|
||||
});
|
||||
|
||||
|
@ -4825,12 +4825,12 @@ fn test_add_instruction_processor_for_existing_unrelated_accounts() {
|
|||
bank.add_builtin(
|
||||
vote_id,
|
||||
"mock_program1".to_string(),
|
||||
LoadedProgram::new_builtin(0, 0, process_instruction),
|
||||
LoadedProgram::new_builtin(0, 0, MockBuiltin::vm),
|
||||
);
|
||||
bank.add_builtin(
|
||||
stake_id,
|
||||
"mock_program2".to_string(),
|
||||
LoadedProgram::new_builtin(0, 0, process_instruction),
|
||||
LoadedProgram::new_builtin(0, 0, MockBuiltin::vm),
|
||||
);
|
||||
{
|
||||
let stakes = bank.stakes_cache.stakes();
|
||||
|
@ -4854,8 +4854,8 @@ fn test_add_instruction_processor_for_existing_unrelated_accounts() {
|
|||
// Re-adding builtin programs should be no-op
|
||||
bank.update_accounts_hash_for_tests();
|
||||
let old_hash = bank.get_accounts_hash().unwrap();
|
||||
bank.add_mockup_builtin(vote_id, process_instruction);
|
||||
bank.add_mockup_builtin(stake_id, process_instruction);
|
||||
bank.add_mockup_builtin(vote_id, MockBuiltin::vm);
|
||||
bank.add_mockup_builtin(stake_id, MockBuiltin::vm);
|
||||
add_root_and_flush_write_cache(&bank);
|
||||
bank.update_accounts_hash_for_tests();
|
||||
let new_hash = bank.get_accounts_hash().unwrap();
|
||||
|
@ -6086,7 +6086,7 @@ fn test_transaction_with_duplicate_accounts_in_instruction() {
|
|||
let (genesis_config, mint_keypair) = create_genesis_config(500);
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let instruction_data = instruction_context.get_instruction_data();
|
||||
|
@ -6107,7 +6107,7 @@ fn test_transaction_with_duplicate_accounts_in_instruction() {
|
|||
});
|
||||
|
||||
let mock_program_id = Pubkey::from([2u8; 32]);
|
||||
bank.add_mockup_builtin(mock_program_id, process_instruction);
|
||||
bank.add_mockup_builtin(mock_program_id, MockBuiltin::vm);
|
||||
|
||||
let from_pubkey = solana_sdk::pubkey::new_rand();
|
||||
let to_pubkey = solana_sdk::pubkey::new_rand();
|
||||
|
@ -6143,7 +6143,7 @@ fn test_transaction_with_program_ids_passed_to_programs() {
|
|||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
|
||||
let mock_program_id = Pubkey::from([2u8; 32]);
|
||||
bank.add_mockup_builtin(mock_program_id, process_instruction);
|
||||
bank.add_mockup_builtin(mock_program_id, MockBuiltin::vm);
|
||||
|
||||
let from_pubkey = solana_sdk::pubkey::new_rand();
|
||||
let to_pubkey = solana_sdk::pubkey::new_rand();
|
||||
|
@ -6198,7 +6198,7 @@ fn test_account_ids_after_program_ids() {
|
|||
let slot = bank.slot().saturating_add(1);
|
||||
let mut bank = Bank::new_from_parent(Arc::new(bank), &Pubkey::default(), slot);
|
||||
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), process_instruction);
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), MockBuiltin::vm);
|
||||
let result = bank.process_transaction(&tx);
|
||||
assert_eq!(result, Ok(()));
|
||||
let account = bank.get_account(&solana_vote_program::id()).unwrap();
|
||||
|
@ -6248,7 +6248,7 @@ fn test_duplicate_account_key() {
|
|||
AccountMeta::new(to_pubkey, false),
|
||||
];
|
||||
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), process_instruction);
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), MockBuiltin::vm);
|
||||
|
||||
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
||||
let mut tx = Transaction::new_signed_with_payer(
|
||||
|
@ -6277,7 +6277,7 @@ fn test_process_transaction_with_too_many_account_locks() {
|
|||
AccountMeta::new(to_pubkey, false),
|
||||
];
|
||||
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), process_instruction);
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), MockBuiltin::vm);
|
||||
|
||||
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
||||
let mut tx = Transaction::new_signed_with_payer(
|
||||
|
@ -6310,7 +6310,7 @@ fn test_program_id_as_payer() {
|
|||
AccountMeta::new(to_pubkey, false),
|
||||
];
|
||||
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), process_instruction);
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), MockBuiltin::vm);
|
||||
|
||||
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
||||
let mut tx = Transaction::new_signed_with_payer(
|
||||
|
@ -6356,7 +6356,7 @@ fn test_ref_account_key_after_program_id() {
|
|||
let slot = bank.slot().saturating_add(1);
|
||||
let mut bank = Bank::new_from_parent(Arc::new(bank), &Pubkey::default(), slot);
|
||||
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), process_instruction);
|
||||
bank.add_mockup_builtin(solana_vote_program::id(), MockBuiltin::vm);
|
||||
|
||||
let instruction = Instruction::new_with_bincode(solana_vote_program::id(), &10, account_metas);
|
||||
let mut tx = Transaction::new_signed_with_payer(
|
||||
|
@ -6390,7 +6390,7 @@ fn test_fuzz_instructions() {
|
|||
bank.add_builtin(
|
||||
key,
|
||||
name.clone(),
|
||||
LoadedProgram::new_builtin(0, 0, process_instruction),
|
||||
LoadedProgram::new_builtin(0, 0, MockBuiltin::vm),
|
||||
);
|
||||
(key, name.as_bytes().to_vec())
|
||||
})
|
||||
|
@ -6584,7 +6584,7 @@ fn test_bank_hash_consistency() {
|
|||
#[ignore]
|
||||
#[test]
|
||||
fn test_same_program_id_uses_unique_executable_accounts() {
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
instruction_context
|
||||
|
@ -6597,7 +6597,7 @@ fn test_same_program_id_uses_unique_executable_accounts() {
|
|||
|
||||
// Add a new program
|
||||
let program1_pubkey = solana_sdk::pubkey::new_rand();
|
||||
bank.add_mockup_builtin(program1_pubkey, process_instruction);
|
||||
bank.add_mockup_builtin(program1_pubkey, MockBuiltin::vm);
|
||||
|
||||
// Add a new program owned by the first
|
||||
let program2_pubkey = solana_sdk::pubkey::new_rand();
|
||||
|
@ -6814,13 +6814,13 @@ fn test_add_builtin_no_overwrite() {
|
|||
|
||||
Arc::get_mut(&mut bank)
|
||||
.unwrap()
|
||||
.add_mockup_builtin(program_id, process_instruction);
|
||||
.add_mockup_builtin(program_id, MockBuiltin::vm);
|
||||
assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
|
||||
|
||||
let mut bank = Arc::new(new_from_parent(bank));
|
||||
Arc::get_mut(&mut bank)
|
||||
.unwrap()
|
||||
.add_mockup_builtin(program_id, process_instruction);
|
||||
.add_mockup_builtin(program_id, MockBuiltin::vm);
|
||||
assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
|
||||
}
|
||||
|
||||
|
@ -6838,13 +6838,13 @@ fn test_add_builtin_loader_no_overwrite() {
|
|||
|
||||
Arc::get_mut(&mut bank)
|
||||
.unwrap()
|
||||
.add_mockup_builtin(loader_id, process_instruction);
|
||||
.add_mockup_builtin(loader_id, MockBuiltin::vm);
|
||||
assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
|
||||
|
||||
let mut bank = Arc::new(new_from_parent(bank));
|
||||
Arc::get_mut(&mut bank)
|
||||
.unwrap()
|
||||
.add_mockup_builtin(loader_id, process_instruction);
|
||||
.add_mockup_builtin(loader_id, MockBuiltin::vm);
|
||||
assert_eq!(bank.get_account_modified_slot(&loader_id).unwrap().1, slot);
|
||||
}
|
||||
|
||||
|
@ -7403,7 +7403,7 @@ fn test_bpf_loader_upgradeable_deploy_with_max_len() {
|
|||
],
|
||||
Vec::new(),
|
||||
Ok(()),
|
||||
solana_bpf_loader_program::process_instruction,
|
||||
solana_bpf_loader_program::Entrypoint::vm,
|
||||
|invoke_context| {
|
||||
invoke_context
|
||||
.programs_modified_by_tx
|
||||
|
@ -9708,7 +9708,7 @@ fn test_tx_return_data() {
|
|||
);
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let mock_program_id = Pubkey::from([2u8; 32]);
|
||||
let transaction_context = &mut invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
|
@ -9726,7 +9726,7 @@ fn test_tx_return_data() {
|
|||
|
||||
let mock_program_id = Pubkey::from([2u8; 32]);
|
||||
let blockhash = bank.last_blockhash();
|
||||
bank.add_mockup_builtin(mock_program_id, process_instruction);
|
||||
bank.add_mockup_builtin(mock_program_id, MockBuiltin::vm);
|
||||
|
||||
for index in [
|
||||
None,
|
||||
|
@ -9906,7 +9906,7 @@ fn test_transfer_sysvar() {
|
|||
);
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
instruction_context
|
||||
|
@ -9916,7 +9916,7 @@ fn test_transfer_sysvar() {
|
|||
});
|
||||
|
||||
let program_id = solana_sdk::pubkey::new_rand();
|
||||
bank.add_mockup_builtin(program_id, process_instruction);
|
||||
bank.add_mockup_builtin(program_id, MockBuiltin::vm);
|
||||
|
||||
let blockhash = bank.last_blockhash();
|
||||
#[allow(deprecated)]
|
||||
|
@ -10115,7 +10115,7 @@ fn test_compute_budget_program_noop() {
|
|||
);
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let compute_budget = invoke_context.get_compute_budget();
|
||||
assert_eq!(
|
||||
*compute_budget,
|
||||
|
@ -10128,7 +10128,7 @@ fn test_compute_budget_program_noop() {
|
|||
Ok(())
|
||||
});
|
||||
let program_id = solana_sdk::pubkey::new_rand();
|
||||
bank.add_mockup_builtin(program_id, process_instruction);
|
||||
bank.add_mockup_builtin(program_id, MockBuiltin::vm);
|
||||
|
||||
let message = Message::new(
|
||||
&[
|
||||
|
@ -10158,7 +10158,7 @@ fn test_compute_request_instruction() {
|
|||
);
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let compute_budget = invoke_context.get_compute_budget();
|
||||
assert_eq!(
|
||||
*compute_budget,
|
||||
|
@ -10171,7 +10171,7 @@ fn test_compute_request_instruction() {
|
|||
Ok(())
|
||||
});
|
||||
let program_id = solana_sdk::pubkey::new_rand();
|
||||
bank.add_mockup_builtin(program_id, process_instruction);
|
||||
bank.add_mockup_builtin(program_id, MockBuiltin::vm);
|
||||
|
||||
let message = Message::new(
|
||||
&[
|
||||
|
@ -10208,7 +10208,7 @@ fn test_failed_compute_request_instruction() {
|
|||
bank.transfer(10, &mint_keypair, &payer1_keypair.pubkey())
|
||||
.unwrap();
|
||||
|
||||
declare_process_instruction!(process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
|
||||
let compute_budget = invoke_context.get_compute_budget();
|
||||
assert_eq!(
|
||||
*compute_budget,
|
||||
|
@ -10221,7 +10221,7 @@ fn test_failed_compute_request_instruction() {
|
|||
Ok(())
|
||||
});
|
||||
let program_id = solana_sdk::pubkey::new_rand();
|
||||
bank.add_mockup_builtin(program_id, process_instruction);
|
||||
bank.add_mockup_builtin(program_id, MockBuiltin::vm);
|
||||
|
||||
// This message will not be executed because the compute budget request is invalid
|
||||
let message0 = Message::new(
|
||||
|
@ -10825,7 +10825,7 @@ enum MockTransferInstruction {
|
|||
Transfer(u64),
|
||||
}
|
||||
|
||||
declare_process_instruction!(mock_transfer_process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockTransferBuiltin, 1, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let instruction_data = instruction_context.get_instruction_data();
|
||||
|
@ -10908,7 +10908,7 @@ fn test_invalid_rent_state_changes_existing_accounts() {
|
|||
);
|
||||
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
bank.add_mockup_builtin(mock_program_id, mock_transfer_process_instruction);
|
||||
bank.add_mockup_builtin(mock_program_id, MockTransferBuiltin::vm);
|
||||
let recent_blockhash = bank.last_blockhash();
|
||||
|
||||
let check_account_is_rent_exempt = |pubkey: &Pubkey| -> bool {
|
||||
|
@ -10991,7 +10991,7 @@ fn test_invalid_rent_state_changes_new_accounts() {
|
|||
let rent_exempt_minimum = genesis_config.rent.minimum_balance(account_data_size);
|
||||
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
bank.add_mockup_builtin(mock_program_id, mock_transfer_process_instruction);
|
||||
bank.add_mockup_builtin(mock_program_id, MockTransferBuiltin::vm);
|
||||
let recent_blockhash = bank.last_blockhash();
|
||||
|
||||
let check_account_is_rent_exempt = |pubkey: &Pubkey| -> bool {
|
||||
|
@ -11050,7 +11050,7 @@ fn test_drained_created_account() {
|
|||
let created_keypair = Keypair::new();
|
||||
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
bank.add_mockup_builtin(mock_program_id, mock_transfer_process_instruction);
|
||||
bank.add_mockup_builtin(mock_program_id, MockTransferBuiltin::vm);
|
||||
let recent_blockhash = bank.last_blockhash();
|
||||
|
||||
// Create and drain a small data size account
|
||||
|
@ -11578,7 +11578,7 @@ enum MockReallocInstruction {
|
|||
Realloc(usize, u64, Pubkey),
|
||||
}
|
||||
|
||||
declare_process_instruction!(mock_realloc_process_instruction, 1, |invoke_context| {
|
||||
declare_process_instruction!(MockReallocBuiltin, 1, |invoke_context| {
|
||||
let transaction_context = &invoke_context.transaction_context;
|
||||
let instruction_context = transaction_context.get_current_instruction_context()?;
|
||||
let instruction_data = instruction_context.get_instruction_data();
|
||||
|
@ -11658,7 +11658,7 @@ fn test_resize_and_rent() {
|
|||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
|
||||
let mock_program_id = Pubkey::new_unique();
|
||||
bank.add_mockup_builtin(mock_program_id, mock_realloc_process_instruction);
|
||||
bank.add_mockup_builtin(mock_program_id, MockReallocBuiltin::vm);
|
||||
let recent_blockhash = bank.last_blockhash();
|
||||
|
||||
let account_data_size_small = 1024;
|
||||
|
@ -11929,7 +11929,7 @@ fn test_accounts_data_size_and_resize_transactions() {
|
|||
} = genesis_utils::create_genesis_config(100 * LAMPORTS_PER_SOL);
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
let mock_program_id = Pubkey::new_unique();
|
||||
bank.add_mockup_builtin(mock_program_id, mock_realloc_process_instruction);
|
||||
bank.add_mockup_builtin(mock_program_id, MockReallocBuiltin::vm);
|
||||
|
||||
let recent_blockhash = bank.last_blockhash();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use {
|
||||
solana_program_runtime::invoke_context::ProcessInstructionWithContext,
|
||||
solana_program_runtime::invoke_context::BuiltinFunctionWithContext,
|
||||
solana_sdk::{
|
||||
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, feature_set, pubkey::Pubkey,
|
||||
},
|
||||
|
@ -10,7 +10,7 @@ pub struct BuiltinPrototype {
|
|||
pub feature_id: Option<Pubkey>,
|
||||
pub program_id: Pubkey,
|
||||
pub name: &'static str,
|
||||
pub entrypoint: ProcessInstructionWithContext,
|
||||
pub entrypoint: BuiltinFunctionWithContext,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for BuiltinPrototype {
|
||||
|
@ -27,7 +27,7 @@ impl std::fmt::Debug for BuiltinPrototype {
|
|||
impl solana_frozen_abi::abi_example::AbiExample for BuiltinPrototype {
|
||||
fn example() -> Self {
|
||||
// BuiltinPrototype isn't serializable by definition.
|
||||
solana_program_runtime::declare_process_instruction!(entrypoint, 0, |_invoke_context| {
|
||||
solana_program_runtime::declare_process_instruction!(MockBuiltin, 0, |_invoke_context| {
|
||||
// Do nothing
|
||||
Ok(())
|
||||
});
|
||||
|
@ -35,7 +35,7 @@ impl solana_frozen_abi::abi_example::AbiExample for BuiltinPrototype {
|
|||
feature_id: None,
|
||||
program_id: Pubkey::default(),
|
||||
name: "",
|
||||
entrypoint,
|
||||
entrypoint: MockBuiltin::vm,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,66 +45,66 @@ pub static BUILTINS: &[BuiltinPrototype] = &[
|
|||
feature_id: None,
|
||||
program_id: solana_system_program::id(),
|
||||
name: "system_program",
|
||||
entrypoint: solana_system_program::system_processor::process_instruction,
|
||||
entrypoint: solana_system_program::system_processor::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: None,
|
||||
program_id: solana_vote_program::id(),
|
||||
name: "vote_program",
|
||||
entrypoint: solana_vote_program::vote_processor::process_instruction,
|
||||
entrypoint: solana_vote_program::vote_processor::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: None,
|
||||
program_id: solana_stake_program::id(),
|
||||
name: "stake_program",
|
||||
entrypoint: solana_stake_program::stake_instruction::process_instruction,
|
||||
entrypoint: solana_stake_program::stake_instruction::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: None,
|
||||
program_id: solana_config_program::id(),
|
||||
name: "config_program",
|
||||
entrypoint: solana_config_program::config_processor::process_instruction,
|
||||
entrypoint: solana_config_program::config_processor::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: None,
|
||||
program_id: bpf_loader_deprecated::id(),
|
||||
name: "solana_bpf_loader_deprecated_program",
|
||||
entrypoint: solana_bpf_loader_program::process_instruction,
|
||||
entrypoint: solana_bpf_loader_program::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: None,
|
||||
program_id: bpf_loader::id(),
|
||||
name: "solana_bpf_loader_program",
|
||||
entrypoint: solana_bpf_loader_program::process_instruction,
|
||||
entrypoint: solana_bpf_loader_program::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: None,
|
||||
program_id: bpf_loader_upgradeable::id(),
|
||||
name: "solana_bpf_loader_upgradeable_program",
|
||||
entrypoint: solana_bpf_loader_program::process_instruction,
|
||||
entrypoint: solana_bpf_loader_program::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: None,
|
||||
program_id: solana_sdk::compute_budget::id(),
|
||||
name: "compute_budget_program",
|
||||
entrypoint: solana_compute_budget_program::process_instruction,
|
||||
entrypoint: solana_compute_budget_program::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: None,
|
||||
program_id: solana_sdk::address_lookup_table::program::id(),
|
||||
name: "address_lookup_table_program",
|
||||
entrypoint: solana_address_lookup_table_program::processor::process_instruction,
|
||||
entrypoint: solana_address_lookup_table_program::processor::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: Some(feature_set::zk_token_sdk_enabled::id()),
|
||||
program_id: solana_zk_token_sdk::zk_token_proof_program::id(),
|
||||
name: "zk_token_proof_program",
|
||||
entrypoint: solana_zk_token_proof_program::process_instruction,
|
||||
entrypoint: solana_zk_token_proof_program::Entrypoint::vm,
|
||||
},
|
||||
BuiltinPrototype {
|
||||
feature_id: Some(feature_set::enable_program_runtime_v2_and_loader_v4::id()),
|
||||
program_id: solana_sdk::loader_v4::id(),
|
||||
name: "loader_v4",
|
||||
entrypoint: solana_loader_v4_program::process_instruction,
|
||||
entrypoint: solana_loader_v4_program::Entrypoint::vm,
|
||||
},
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue