55 lazy_static:: lazy_static,
66 solana_sdk:: {
77 address_lookup_table, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
8- compute_budget, ed25519_program, loader_v4, pubkey:: Pubkey , secp256k1_program,
8+ compute_budget, ed25519_program,
9+ feature_set:: { self , FeatureSet } ,
10+ loader_v4,
11+ pubkey:: Pubkey ,
12+ secp256k1_program,
913 } ,
1014} ;
1115
12- // Number of compute units for each built-in programs
16+ /// DEVELOPER: when a builtin is migrated to sbpf, please add its corresponding
17+ /// migration feature ID to BUILTIN_INSTRUCTION_COSTS, so the builtin's default
18+ /// cost can be determined properly based on feature status.
19+ /// When migration completed, eg the feature gate is enabled everywhere, please
20+ /// remove that builtin entry from BUILTIN_INSTRUCTION_COSTS.
21+ #[ derive( Clone ) ]
22+ struct BuiltinCost {
23+ native_cost : u64 ,
24+ core_bpf_migration_feature : Option < Pubkey > ,
25+ }
26+
1327lazy_static ! {
1428 /// Number of compute units for each built-in programs
1529 ///
@@ -20,21 +34,95 @@ lazy_static! {
2034 /// calculate the cost of a transaction which is used in replay to enforce
2135 /// block cost limits as of
2236 /// https://github.com/solana-labs/solana/issues/29595.
23- pub static ref BUILTIN_INSTRUCTION_COSTS : AHashMap <Pubkey , u64 > = [
24- ( solana_stake_program:: id( ) , solana_stake_program:: stake_instruction:: DEFAULT_COMPUTE_UNITS ) ,
25- ( solana_config_program:: id( ) , solana_config_program:: config_processor:: DEFAULT_COMPUTE_UNITS ) ,
26- ( solana_vote_program:: id( ) , solana_vote_program:: vote_processor:: DEFAULT_COMPUTE_UNITS ) ,
27- ( solana_system_program:: id( ) , solana_system_program:: system_processor:: DEFAULT_COMPUTE_UNITS ) ,
28- ( compute_budget:: id( ) , solana_compute_budget_program:: DEFAULT_COMPUTE_UNITS ) ,
29- ( address_lookup_table:: program:: id( ) , solana_address_lookup_table_program:: processor:: DEFAULT_COMPUTE_UNITS ) ,
30- ( bpf_loader_upgradeable:: id( ) , solana_bpf_loader_program:: UPGRADEABLE_LOADER_COMPUTE_UNITS ) ,
31- ( bpf_loader_deprecated:: id( ) , solana_bpf_loader_program:: DEPRECATED_LOADER_COMPUTE_UNITS ) ,
32- ( bpf_loader:: id( ) , solana_bpf_loader_program:: DEFAULT_LOADER_COMPUTE_UNITS ) ,
33- ( loader_v4:: id( ) , solana_loader_v4_program:: DEFAULT_COMPUTE_UNITS ) ,
34- // Note: These are precompile, run directly in bank during sanitizing;
35- ( secp256k1_program:: id( ) , 0 ) ,
36- ( ed25519_program:: id( ) , 0 ) ,
37- // DO NOT ADD MORE ENTRIES TO THIS MAP
37+ static ref BUILTIN_INSTRUCTION_COSTS : AHashMap <Pubkey , BuiltinCost > = [
38+ (
39+ solana_stake_program:: id( ) ,
40+ BuiltinCost {
41+ native_cost: solana_stake_program:: stake_instruction:: DEFAULT_COMPUTE_UNITS ,
42+ core_bpf_migration_feature: Some ( feature_set:: migrate_stake_program_to_core_bpf:: id( ) ) ,
43+ } ,
44+ ) ,
45+ (
46+ solana_config_program:: id( ) ,
47+ BuiltinCost {
48+ native_cost: solana_config_program:: config_processor:: DEFAULT_COMPUTE_UNITS ,
49+ core_bpf_migration_feature: Some ( feature_set:: migrate_config_program_to_core_bpf:: id( ) ) ,
50+ } ,
51+ ) ,
52+ (
53+ solana_vote_program:: id( ) ,
54+ BuiltinCost {
55+ native_cost: solana_vote_program:: vote_processor:: DEFAULT_COMPUTE_UNITS ,
56+ core_bpf_migration_feature: None ,
57+ } ,
58+ ) ,
59+ (
60+ solana_system_program:: id( ) ,
61+ BuiltinCost {
62+ native_cost: solana_system_program:: system_processor:: DEFAULT_COMPUTE_UNITS ,
63+ core_bpf_migration_feature: None ,
64+ } ,
65+ ) ,
66+ (
67+ compute_budget:: id( ) ,
68+ BuiltinCost {
69+ native_cost: solana_compute_budget_program:: DEFAULT_COMPUTE_UNITS ,
70+ core_bpf_migration_feature: None ,
71+ } ,
72+ ) ,
73+ (
74+ address_lookup_table:: program:: id( ) ,
75+ BuiltinCost {
76+ native_cost: solana_address_lookup_table_program:: processor:: DEFAULT_COMPUTE_UNITS ,
77+ core_bpf_migration_feature: Some (
78+ feature_set:: migrate_address_lookup_table_program_to_core_bpf:: id( ) ,
79+ ) ,
80+ } ,
81+ ) ,
82+ (
83+ bpf_loader_upgradeable:: id( ) ,
84+ BuiltinCost {
85+ native_cost: solana_bpf_loader_program:: UPGRADEABLE_LOADER_COMPUTE_UNITS ,
86+ core_bpf_migration_feature: None ,
87+ } ,
88+ ) ,
89+ (
90+ bpf_loader_deprecated:: id( ) ,
91+ BuiltinCost {
92+ native_cost: solana_bpf_loader_program:: DEPRECATED_LOADER_COMPUTE_UNITS ,
93+ core_bpf_migration_feature: None ,
94+ } ,
95+ ) ,
96+ (
97+ bpf_loader:: id( ) ,
98+ BuiltinCost {
99+ native_cost: solana_bpf_loader_program:: DEFAULT_LOADER_COMPUTE_UNITS ,
100+ core_bpf_migration_feature: None ,
101+ } ,
102+ ) ,
103+ (
104+ loader_v4:: id( ) ,
105+ BuiltinCost {
106+ native_cost: solana_loader_v4_program:: DEFAULT_COMPUTE_UNITS ,
107+ core_bpf_migration_feature: None ,
108+ } ,
109+ ) ,
110+ // Note: These are precompile, run directly in bank during sanitizing;
111+ (
112+ secp256k1_program:: id( ) ,
113+ BuiltinCost {
114+ native_cost: 0 ,
115+ core_bpf_migration_feature: None ,
116+ } ,
117+ ) ,
118+ (
119+ ed25519_program:: id( ) ,
120+ BuiltinCost {
121+ native_cost: 0 ,
122+ core_bpf_migration_feature: None ,
123+ } ,
124+ ) ,
125+ // DO NOT ADD MORE ENTRIES TO THIS MAP
38126 ]
39127 . iter( )
40128 . cloned( )
@@ -54,3 +142,58 @@ lazy_static! {
54142 temp_table
55143 } ;
56144}
145+
146+ pub fn get_builtin_instruction_cost < ' a > (
147+ program_id : & ' a Pubkey ,
148+ feature_set : & ' a FeatureSet ,
149+ ) -> Option < u64 > {
150+ BUILTIN_INSTRUCTION_COSTS
151+ . get ( program_id)
152+ . filter (
153+ // Returns true if builtin program id has no core_bpf_migration_feature or feature is not activated;
154+ // otherwise returns false because it's not considered as builtin
155+ |builtin_cost| -> bool {
156+ builtin_cost
157+ . core_bpf_migration_feature
158+ . map ( |feature_id| !feature_set. is_active ( & feature_id) )
159+ . unwrap_or ( true )
160+ } ,
161+ )
162+ . map ( |builtin_cost| builtin_cost. native_cost )
163+ }
164+
165+ #[ cfg( test) ]
166+ mod test {
167+ use super :: * ;
168+
169+ #[ test]
170+ fn test_get_builtin_instruction_cost ( ) {
171+ // use native cost if no migration planned
172+ assert_eq ! (
173+ Some ( solana_compute_budget_program:: DEFAULT_COMPUTE_UNITS ) ,
174+ get_builtin_instruction_cost( & compute_budget:: id( ) , & FeatureSet :: all_enabled( ) )
175+ ) ;
176+
177+ // use native cost if migration is planned but not activated
178+ assert_eq ! (
179+ Some ( solana_stake_program:: stake_instruction:: DEFAULT_COMPUTE_UNITS ) ,
180+ get_builtin_instruction_cost( & solana_stake_program:: id( ) , & FeatureSet :: default ( ) )
181+ ) ;
182+
183+ // None if migration is planned and activated, in which case, it's no longer builtin
184+ assert ! ( get_builtin_instruction_cost(
185+ & solana_stake_program:: id( ) ,
186+ & FeatureSet :: all_enabled( )
187+ )
188+ . is_none( ) ) ;
189+
190+ // None if not builtin
191+ assert ! (
192+ get_builtin_instruction_cost( & Pubkey :: new_unique( ) , & FeatureSet :: default ( ) ) . is_none( )
193+ ) ;
194+ assert ! (
195+ get_builtin_instruction_cost( & Pubkey :: new_unique( ) , & FeatureSet :: all_enabled( ) )
196+ . is_none( )
197+ ) ;
198+ }
199+ }
0 commit comments