Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 7356fe4

Browse files
committed
Adjustments:
Replaces declare_syscall!() with declare_builtin_function!(). Removes Config::encrypt_runtime_environment. Simplifies error propagation.
1 parent 699c226 commit 7356fe4

File tree

32 files changed

+1363
-1575
lines changed

32 files changed

+1363
-1575
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ledger/src/blockstore_processor.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2989,15 +2989,15 @@ pub mod tests {
29892989
]
29902990
}
29912991

2992-
declare_process_instruction!(mock_processor_ok, 1, |_invoke_context| {
2992+
declare_process_instruction!(MockBuiltinOk, 1, |_invoke_context| {
29932993
// Always succeeds
29942994
Ok(())
29952995
});
29962996

29972997
let mock_program_id = solana_sdk::pubkey::new_rand();
29982998

29992999
let mut bank = Bank::new_for_tests(&genesis_config);
3000-
bank.add_mockup_builtin(mock_program_id, mock_processor_ok);
3000+
bank.add_mockup_builtin(mock_program_id, MockBuiltinOk::vm);
30013001

30023002
let tx = Transaction::new_signed_with_payer(
30033003
&[Instruction::new_with_bincode(
@@ -3018,7 +3018,7 @@ pub mod tests {
30183018
let bankhash_ok = bank.hash();
30193019
assert!(result.is_ok());
30203020

3021-
declare_process_instruction!(mock_processor_err, 1, |invoke_context| {
3021+
declare_process_instruction!(MockBuiltinErr, 1, |invoke_context| {
30223022
let instruction_errors = get_instruction_errors();
30233023

30243024
let err = invoke_context
@@ -3038,7 +3038,7 @@ pub mod tests {
30383038

30393039
(0..get_instruction_errors().len()).for_each(|err| {
30403040
let mut bank = Bank::new_for_tests(&genesis_config);
3041-
bank.add_mockup_builtin(mock_program_id, mock_processor_err);
3041+
bank.add_mockup_builtin(mock_program_id, MockBuiltinErr::vm);
30423042

30433043
let tx = Transaction::new_signed_with_payer(
30443044
&[Instruction::new_with_bincode(

program-runtime/src/invoke_context.rs

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ use {
1212
solana_measure::measure::Measure,
1313
solana_rbpf::{
1414
ebpf::MM_HEAP_START,
15-
elf::SBPFVersion,
15+
error::{EbpfError, ProgramResult},
1616
memory_region::MemoryMapping,
17-
vm::{BuiltinFunction, Config, ContextObject, ProgramResult},
17+
program::{BuiltinFunction, SBPFVersion},
18+
vm::{Config, ContextObject, EbpfVm},
1819
},
1920
solana_sdk::{
2021
account::AccountSharedData,
@@ -39,44 +40,46 @@ use {
3940
},
4041
};
4142

42-
pub type ProcessInstructionWithContext = BuiltinFunction<InvokeContext<'static>>;
43+
pub type BuiltinFunctionWithContext = BuiltinFunction<InvokeContext<'static>>;
4344

4445
/// Adapter so we can unify the interfaces of built-in programs and syscalls
4546
#[macro_export]
4647
macro_rules! declare_process_instruction {
4748
($process_instruction:ident, $cu_to_consume:expr, |$invoke_context:ident| $inner:tt) => {
48-
pub fn $process_instruction(
49-
invoke_context: &mut $crate::invoke_context::InvokeContext,
50-
_arg0: u64,
51-
_arg1: u64,
52-
_arg2: u64,
53-
_arg3: u64,
54-
_arg4: u64,
55-
_memory_mapping: &mut $crate::solana_rbpf::memory_region::MemoryMapping,
56-
result: &mut $crate::solana_rbpf::vm::ProgramResult,
57-
) {
58-
fn process_instruction_inner(
59-
$invoke_context: &mut $crate::invoke_context::InvokeContext,
60-
) -> std::result::Result<(), solana_sdk::instruction::InstructionError> {
61-
$inner
49+
$crate::solana_rbpf::declare_builtin_function!(
50+
$process_instruction,
51+
fn rust(
52+
invoke_context: &mut $crate::invoke_context::InvokeContext,
53+
_arg0: u64,
54+
_arg1: u64,
55+
_arg2: u64,
56+
_arg3: u64,
57+
_arg4: u64,
58+
_memory_mapping: &mut $crate::solana_rbpf::memory_region::MemoryMapping,
59+
) -> std::result::Result<u64, Box<dyn std::error::Error>> {
60+
fn process_instruction_inner(
61+
$invoke_context: &mut $crate::invoke_context::InvokeContext,
62+
) -> std::result::Result<(), solana_sdk::instruction::InstructionError> {
63+
$inner
64+
}
65+
let consumption_result = if $cu_to_consume > 0
66+
&& invoke_context
67+
.feature_set
68+
.is_active(&solana_sdk::feature_set::native_programs_consume_cu::id())
69+
{
70+
invoke_context.consume_checked($cu_to_consume)
71+
} else {
72+
Ok(())
73+
};
74+
consumption_result
75+
.and_then(|_| {
76+
process_instruction_inner(invoke_context)
77+
.map(|_| 0)
78+
.map_err(|err| Box::new(err) as Box<dyn std::error::Error>)
79+
})
80+
.into()
6281
}
63-
let consumption_result = if $cu_to_consume > 0
64-
&& invoke_context
65-
.feature_set
66-
.is_active(&solana_sdk::feature_set::native_programs_consume_cu::id())
67-
{
68-
invoke_context.consume_checked($cu_to_consume)
69-
} else {
70-
Ok(())
71-
};
72-
*result = consumption_result
73-
.and_then(|_| {
74-
process_instruction_inner(invoke_context)
75-
.map(|_| 0)
76-
.map_err(|err| Box::new(err) as Box<dyn std::error::Error>)
77-
})
78-
.into();
79-
}
82+
);
8083
};
8184
}
8285

@@ -468,11 +471,11 @@ impl<'a> InvokeContext<'a> {
468471
.programs_loaded_for_tx_batch
469472
.find(&builtin_id)
470473
.ok_or(InstructionError::UnsupportedProgramId)?;
471-
let process_instruction = match &entry.program {
474+
let function = match &entry.program {
472475
LoadedProgramType::Builtin(program) => program
473476
.get_function_registry()
474477
.lookup_by_key(ENTRYPOINT_KEY)
475-
.map(|(_name, process_instruction)| process_instruction),
478+
.map(|(_name, function)| function),
476479
_ => None,
477480
}
478481
.ok_or(InstructionError::UnsupportedProgramId)?;
@@ -485,30 +488,37 @@ impl<'a> InvokeContext<'a> {
485488
stable_log::program_invoke(&logger, &program_id, self.get_stack_height());
486489
let pre_remaining_units = self.get_remaining();
487490
let mock_config = Config::default();
488-
let mut mock_memory_mapping =
491+
let mock_memory_mapping =
489492
MemoryMapping::new(Vec::new(), &mock_config, &SBPFVersion::V2).unwrap();
490-
let mut result = ProgramResult::Ok(0);
491-
process_instruction(
493+
let mut vm = EbpfVm::new(
494+
self.programs_loaded_for_tx_batch
495+
.environments
496+
.program_runtime_v2
497+
.clone(),
498+
&SBPFVersion::V2,
492499
// Removes lifetime tracking
493500
unsafe { std::mem::transmute::<&mut InvokeContext, &mut InvokeContext>(self) },
501+
mock_memory_mapping,
494502
0,
495-
0,
496-
0,
497-
0,
498-
0,
499-
&mut mock_memory_mapping,
500-
&mut result,
501503
);
502-
let result = match result {
504+
vm.invoke_function(function);
505+
let result = match vm.program_result {
503506
ProgramResult::Ok(_) => {
504507
stable_log::program_success(&logger, &program_id);
505508
Ok(())
506509
}
507-
ProgramResult::Err(err) => {
508-
stable_log::program_failure(&logger, &program_id, err.as_ref());
509-
if let Some(err) = err.downcast_ref::<InstructionError>() {
510-
Err(err.clone())
510+
ProgramResult::Err(ref err) => {
511+
if let EbpfError::SyscallError(syscall_error) = err {
512+
if let Some(instruction_err) = syscall_error.downcast_ref::<InstructionError>()
513+
{
514+
stable_log::program_failure(&logger, &program_id, instruction_err);
515+
Err(instruction_err.clone())
516+
} else {
517+
stable_log::program_failure(&logger, &program_id, syscall_error);
518+
Err(InstructionError::ProgramFailedToComplete)
519+
}
511520
} else {
521+
stable_log::program_failure(&logger, &program_id, err);
512522
Err(InstructionError::ProgramFailedToComplete)
513523
}
514524
}
@@ -699,7 +709,7 @@ pub fn mock_process_instruction<F: FnMut(&mut InvokeContext), G: FnMut(&mut Invo
699709
mut transaction_accounts: Vec<TransactionAccount>,
700710
instruction_account_metas: Vec<AccountMeta>,
701711
expected_result: Result<(), InstructionError>,
702-
process_instruction: ProcessInstructionWithContext,
712+
builtin_function: BuiltinFunctionWithContext,
703713
mut pre_adjustments: F,
704714
mut post_adjustments: G,
705715
) -> Vec<AccountSharedData> {
@@ -734,7 +744,7 @@ pub fn mock_process_instruction<F: FnMut(&mut InvokeContext), G: FnMut(&mut Invo
734744
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
735745
programs_loaded_for_tx_batch.replenish(
736746
*loader_id,
737-
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
747+
Arc::new(LoadedProgram::new_builtin(0, 0, builtin_function)),
738748
);
739749
invoke_context.programs_loaded_for_tx_batch = &programs_loaded_for_tx_batch;
740750
pre_adjustments(&mut invoke_context);
@@ -782,7 +792,7 @@ mod tests {
782792
const MOCK_BUILTIN_COMPUTE_UNIT_COST: u64 = 1;
783793

784794
declare_process_instruction!(
785-
process_instruction,
795+
MockBuiltin,
786796
MOCK_BUILTIN_COMPUTE_UNIT_COST,
787797
|invoke_context| {
788798
let transaction_context = &invoke_context.transaction_context;
@@ -988,7 +998,7 @@ mod tests {
988998
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
989999
programs_loaded_for_tx_batch.replenish(
9901000
callee_program_id,
991-
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
1001+
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
9921002
);
9931003
invoke_context.programs_loaded_for_tx_batch = &programs_loaded_for_tx_batch;
9941004

@@ -1134,7 +1144,7 @@ mod tests {
11341144
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
11351145
programs_loaded_for_tx_batch.replenish(
11361146
program_key,
1137-
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
1147+
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
11381148
);
11391149
invoke_context.programs_loaded_for_tx_batch = &programs_loaded_for_tx_batch;
11401150

program-runtime/src/loaded_programs.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
use {
22
crate::{
3-
invoke_context::{InvokeContext, ProcessInstructionWithContext},
3+
invoke_context::{BuiltinFunctionWithContext, InvokeContext},
44
timings::ExecuteDetailsTimings,
55
},
66
itertools::Itertools,
77
log::{debug, log_enabled, trace},
88
percentage::PercentageInteger,
99
solana_measure::measure::Measure,
1010
solana_rbpf::{
11-
elf::{Executable, FunctionRegistry},
11+
elf::Executable,
12+
program::{BuiltinProgram, FunctionRegistry},
1213
verifier::RequisiteVerifier,
13-
vm::{BuiltinProgram, Config},
14+
vm::Config,
1415
},
1516
solana_sdk::{
1617
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
@@ -370,11 +371,11 @@ impl LoadedProgram {
370371
pub fn new_builtin(
371372
deployment_slot: Slot,
372373
account_size: usize,
373-
entrypoint: ProcessInstructionWithContext,
374+
builtin_function: BuiltinFunctionWithContext,
374375
) -> Self {
375376
let mut function_registry = FunctionRegistry::default();
376377
function_registry
377-
.register_function_hashed(*b"entrypoint", entrypoint)
378+
.register_function_hashed(*b"entrypoint", builtin_function)
378379
.unwrap();
379380
Self {
380381
deployment_slot,
@@ -928,7 +929,7 @@ mod tests {
928929
},
929930
assert_matches::assert_matches,
930931
percentage::Percentage,
931-
solana_rbpf::vm::BuiltinProgram,
932+
solana_rbpf::program::BuiltinProgram,
932933
solana_sdk::{
933934
clock::{Epoch, Slot},
934935
pubkey::Pubkey,

program-runtime/src/message_processor.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ mod tests {
220220
ChangeData { data: u8 },
221221
}
222222

223-
declare_process_instruction!(process_instruction, 1, |invoke_context| {
223+
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
224224
let transaction_context = &invoke_context.transaction_context;
225225
let instruction_context = transaction_context.get_current_instruction_context()?;
226226
let instruction_data = instruction_context.get_instruction_data();
@@ -271,7 +271,7 @@ mod tests {
271271
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
272272
programs_loaded_for_tx_batch.replenish(
273273
mock_system_program_id,
274-
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
274+
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
275275
);
276276
let account_keys = (0..transaction_context.get_number_of_accounts())
277277
.map(|index| {
@@ -432,7 +432,7 @@ mod tests {
432432
DoWork { lamports: u64, data: u8 },
433433
}
434434

435-
declare_process_instruction!(process_instruction, 1, |invoke_context| {
435+
declare_process_instruction!(MockBuiltin, 1, |invoke_context| {
436436
let transaction_context = &invoke_context.transaction_context;
437437
let instruction_context = transaction_context.get_current_instruction_context()?;
438438
let instruction_data = instruction_context.get_instruction_data();
@@ -500,7 +500,7 @@ mod tests {
500500
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
501501
programs_loaded_for_tx_batch.replenish(
502502
mock_program_id,
503-
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
503+
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
504504
);
505505
let account_metas = vec![
506506
AccountMeta::new(
@@ -645,7 +645,7 @@ mod tests {
645645
#[test]
646646
fn test_precompile() {
647647
let mock_program_id = Pubkey::new_unique();
648-
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
648+
declare_process_instruction!(MockBuiltin, 1, |_invoke_context| {
649649
Err(InstructionError::Custom(0xbabb1e))
650650
});
651651

@@ -684,7 +684,7 @@ mod tests {
684684
let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch::default();
685685
programs_loaded_for_tx_batch.replenish(
686686
mock_program_id,
687-
Arc::new(LoadedProgram::new_builtin(0, 0, process_instruction)),
687+
Arc::new(LoadedProgram::new_builtin(0, 0, MockBuiltin::vm)),
688688
);
689689
let mut programs_modified_by_tx = LoadedProgramsForTxBatch::default();
690690
let mut programs_updated_only_for_global_cache = LoadedProgramsForTxBatch::default();

program-runtime/src/stable_log.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ pub fn program_success(log_collector: &Option<Rc<RefCell<LogCollector>>>, progra
101101
/// ```notrust
102102
/// "Program <address> failed: <program error details>"
103103
/// ```
104-
pub fn program_failure(
104+
pub fn program_failure<E: std::fmt::Display>(
105105
log_collector: &Option<Rc<RefCell<LogCollector>>>,
106106
program_id: &Pubkey,
107-
err: &dyn std::error::Error,
107+
err: &E,
108108
) {
109109
ic_logger_msg!(log_collector, "Program {} failed: {}", program_id, err);
110110
}

program-test/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ solana-program-runtime = { workspace = true }
2727
solana-runtime = { workspace = true }
2828
solana-sdk = { workspace = true }
2929
solana-vote-program = { workspace = true }
30+
solana_rbpf = { workspace = true }
3031
test-case = { workspace = true }
3132
thiserror = { workspace = true }
3233
tokio = { workspace = true, features = ["full"] }

0 commit comments

Comments
 (0)