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:
Alexander Meißner 2023-10-20 21:39:50 +02:00 committed by GitHub
parent dc3c827299
commit a5c7c999e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 1387 additions and 1596 deletions

5
Cargo.lock generated
View File

@ -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",

View File

@ -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"

View File

@ -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(

View File

@ -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;

View File

@ -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,

View File

@ -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();

View File

@ -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);
}

View File

@ -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"] }

View File

@ -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),
));
}

View File

@ -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
}

View File

@ -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(),
);

View File

@ -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)

View File

@ -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
}

View File

@ -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| {},
)

View File

@ -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},

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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(())
}
);
});

View File

@ -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| {},
)

View File

@ -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

View File

@ -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",

View File

@ -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"

View File

@ -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);

View File

@ -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);
},

View File

@ -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());
},

View File

@ -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| {},
);

View File

@ -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());
},

View File

@ -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

View File

@ -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());

View File

@ -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),
);
}

View File

@ -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();

View File

@ -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,
},
];