88 solana_loader_v3_interface:: state:: UpgradeableLoaderState ,
99 solana_loader_v4_interface:: state:: { LoaderV4State , LoaderV4Status } ,
1010 solana_program_runtime:: {
11- invoke_context:: BuiltinFunctionWithContext ,
11+ invoke_context:: { BuiltinFunctionWithContext , InvokeContext } ,
1212 loaded_programs:: { LoadProgramMetrics , ProgramCacheEntry , ProgramCacheForTxBatch } ,
13+ solana_sbpf:: program:: BuiltinProgram ,
1314 } ,
1415 solana_pubkey:: Pubkey ,
1516 solana_rent:: Rent ,
@@ -57,13 +58,23 @@ pub struct ProgramCache {
5758 //
5859 // K: program ID, V: loader key
5960 entries_cache : Rc < RefCell < HashMap < Pubkey , Pubkey > > > ,
61+ // The function registry (syscalls) to use for verifying and loading
62+ // program ELFs.
63+ pub program_runtime_environment : BuiltinProgram < InvokeContext < ' static > > ,
6064}
6165
62- impl Default for ProgramCache {
63- fn default ( ) -> Self {
66+ impl ProgramCache {
67+ pub fn new ( feature_set : & FeatureSet , compute_budget : & ComputeBudget ) -> Self {
6468 let me = Self {
6569 cache : Rc :: new ( RefCell :: new ( ProgramCacheForTxBatch :: default ( ) ) ) ,
6670 entries_cache : Rc :: new ( RefCell :: new ( HashMap :: new ( ) ) ) ,
71+ program_runtime_environment : create_program_runtime_environment_v1 (
72+ feature_set,
73+ compute_budget,
74+ /* reject_deployment_of_broken_elfs */ false ,
75+ /* debugging_features */ false ,
76+ )
77+ . unwrap ( ) ,
6778 } ;
6879 BUILTINS . iter ( ) . for_each ( |builtin| {
6980 let program_id = builtin. program_id ;
@@ -72,9 +83,7 @@ impl Default for ProgramCache {
7283 } ) ;
7384 me
7485 }
75- }
7686
77- impl ProgramCache {
7887 pub ( crate ) fn cache ( & self ) -> RefMut < ProgramCacheForTxBatch > {
7988 self . cache . borrow_mut ( )
8089 }
@@ -94,18 +103,24 @@ impl ProgramCache {
94103 }
95104
96105 /// Add a program to the cache.
97- pub fn add_program (
98- & mut self ,
99- program_id : & Pubkey ,
100- loader_key : & Pubkey ,
101- elf : & [ u8 ] ,
102- compute_budget : & ComputeBudget ,
103- feature_set : & FeatureSet ,
104- ) {
105- let environment = Arc :: new (
106- create_program_runtime_environment_v1 ( feature_set, compute_budget, false , false )
107- . unwrap ( ) ,
108- ) ;
106+ pub fn add_program ( & mut self , program_id : & Pubkey , loader_key : & Pubkey , elf : & [ u8 ] ) {
107+ // This might look rough, but it's actually functionally the same as
108+ // calling `create_program_runtime_environment_v1` on every addition.
109+ let environment = {
110+ let config = self . program_runtime_environment . get_config ( ) . clone ( ) ;
111+ let mut loader = BuiltinProgram :: new_loader ( config) ;
112+
113+ for ( _key, ( name, value) ) in self
114+ . program_runtime_environment
115+ . get_function_registry ( )
116+ . iter ( )
117+ {
118+ let name = std:: str:: from_utf8 ( name) . unwrap ( ) ;
119+ loader. register_function ( name, value) . unwrap ( ) ;
120+ }
121+
122+ Arc :: new ( loader)
123+ } ;
109124 self . replenish (
110125 * program_id,
111126 Arc :: new (
0 commit comments