Skip to content

Commit

Permalink
Bump solana_rbpf to v0.8.0 (#33679)
Browse files Browse the repository at this point in the history
* Bumps solana_rbpf to v0.8.0

* Adjustments:
Replaces declare_syscall!() with declare_builtin_function!().
Removes Config::encrypt_runtime_environment.
Simplifies error propagation.

(cherry picked from commit a5c7c99)
  • Loading branch information
Lichtso committed Oct 21, 2023
1 parent 3a425d1 commit 3e56c55
Show file tree
Hide file tree
Showing 34 changed files with 1,440 additions and 1,749 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ siphasher = "0.3.11"
smpl_jwt = "0.7.1"
socket2 = "0.5.4"
soketto = "0.7"
solana_rbpf = "=0.7.2"
solana_rbpf = "=0.8.0"
solana-account-decoder = { path = "account-decoder", version = "=1.17.4" }
solana-accounts-db = { path = "accounts-db", version = "=1.17.4" }
solana-address-lookup-table-program = { path = "programs/address-lookup-table", version = "=1.17.4" }
Expand Down
8 changes: 4 additions & 4 deletions ledger/src/blockstore_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2989,15 +2989,15 @@ pub mod tests {
]
}

declare_process_instruction!(mock_processor_ok, 1, |_invoke_context| {
declare_process_instruction!(MockBuiltinOk, 1, |_invoke_context| {
// Always succeeds
Ok(())
});

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(
Expand All @@ -3018,7 +3018,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
Expand All @@ -3038,7 +3038,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(
Expand Down
125 changes: 69 additions & 56 deletions program-runtime/src/invoke_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,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, ReadableAccount},
Expand Down Expand Up @@ -44,44 +45,46 @@ 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(
invoke_context: &mut $crate::invoke_context::InvokeContext,
_arg0: u64,
_arg1: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_memory_mapping: &mut $crate::solana_rbpf::memory_region::MemoryMapping,
result: &mut $crate::solana_rbpf::vm::ProgramResult,
) {
fn process_instruction_inner(
$invoke_context: &mut $crate::invoke_context::InvokeContext,
) -> std::result::Result<(), solana_sdk::instruction::InstructionError> {
$inner
$crate::solana_rbpf::declare_builtin_function!(
$process_instruction,
fn rust(
invoke_context: &mut $crate::invoke_context::InvokeContext,
_arg0: u64,
_arg1: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_memory_mapping: &mut $crate::solana_rbpf::memory_region::MemoryMapping,
) -> 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> {
$inner
}
let consumption_result = if $cu_to_consume > 0
&& invoke_context
.feature_set
.is_active(&solana_sdk::feature_set::native_programs_consume_cu::id())
{
invoke_context.consume_checked($cu_to_consume)
} else {
Ok(())
};
consumption_result
.and_then(|_| {
process_instruction_inner(invoke_context)
.map(|_| 0)
.map_err(|err| Box::new(err) as Box<dyn std::error::Error>)
})
.into()
}
let consumption_result = if $cu_to_consume > 0
&& invoke_context
.feature_set
.is_active(&solana_sdk::feature_set::native_programs_consume_cu::id())
{
invoke_context.consume_checked($cu_to_consume)
} else {
Ok(())
};
*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();
}
);
};
}

Expand Down Expand Up @@ -746,11 +749,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)?;
Expand All @@ -762,31 +765,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)
}
}
Expand Down Expand Up @@ -979,7 +992,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> {
Expand Down Expand Up @@ -1014,7 +1027,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);
Expand Down Expand Up @@ -1062,7 +1075,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;
Expand Down Expand Up @@ -1268,7 +1281,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;

Expand Down Expand Up @@ -1414,7 +1427,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;

Expand Down
13 changes: 7 additions & 6 deletions program-runtime/src/loaded_programs.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use {
crate::{
invoke_context::{InvokeContext, ProcessInstructionWithContext},
invoke_context::{BuiltinFunctionWithContext, InvokeContext},
timings::ExecuteDetailsTimings,
},
itertools::Itertools,
log::{debug, log_enabled, trace},
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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -928,7 +929,7 @@ mod tests {
},
assert_matches::assert_matches,
percentage::Percentage,
solana_rbpf::vm::BuiltinProgram,
solana_rbpf::program::BuiltinProgram,
solana_sdk::{
clock::{Epoch, Slot},
pubkey::Pubkey,
Expand Down
12 changes: 6 additions & 6 deletions program-runtime/src/message_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,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();
Expand Down Expand Up @@ -274,7 +274,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| {
Expand Down Expand Up @@ -438,7 +438,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();
Expand Down Expand Up @@ -507,7 +507,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(
Expand Down Expand Up @@ -655,7 +655,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))
});

Expand Down Expand Up @@ -695,7 +695,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();
Expand Down
4 changes: 2 additions & 2 deletions program-runtime/src/stable_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions program-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
Expand Down
Loading

0 comments on commit 3e56c55

Please sign in to comment.