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]
4647macro_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
0 commit comments