solana_builtins/
lib.rs

1//! Solana builtin programs.
2//!
3//! Warning: This crate is not for public consumption. It will change, and
4//! could possibly be removed altogether in the future. For now, it is purely
5//! for the purpose of managing the migration of builtins to Core BPF.
6//!
7//! It serves as a source of truth for:
8//! * The list of builtins that a Bank should add.
9//! * Which of those builtins have been assigned a feature gate to migrate to
10//!   Core BPF, as well as whether or not that feature gate has been activated.
11
12pub mod core_bpf_migration;
13pub mod prototype;
14
15use {
16    crate::{
17        core_bpf_migration::{CoreBpfMigrationConfig, CoreBpfMigrationTargetType},
18        prototype::{BuiltinPrototype, StatelessBuiltinPrototype},
19    },
20    solana_feature_set as feature_set,
21    solana_sdk_ids::{bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable},
22};
23
24macro_rules! testable_prototype {
25    ($prototype:ident {
26        core_bpf_migration_config: $core_bpf_migration_config:expr,
27        name: $name:ident,
28        $($field:ident : $value:expr),* $(,)?
29    }) => {
30        $prototype {
31            core_bpf_migration_config: {
32                #[cfg(not(feature = "dev-context-only-utils"))]
33                {
34                    $core_bpf_migration_config
35                }
36                #[cfg(feature = "dev-context-only-utils")]
37                {
38                    Some( test_only::$name::CONFIG )
39                }
40            },
41            name: stringify!($name),
42            $($field: $value),*
43        }
44    };
45}
46
47/// DEVELOPER: when a builtin is migrated to sbpf, please add its corresponding
48/// migration feature ID to solana-builtin-default-costs::BUILTIN_INSTRUCTION_COSTS,
49/// so the builtin's default cost can be determined properly based on feature status.
50/// When migration completed, and the feature gate is enabled everywhere, please
51/// remove that builtin entry from solana-builtin-default-costs::BUILTIN_INSTRUCTION_COSTS.
52pub static BUILTINS: &[BuiltinPrototype] = &[
53    testable_prototype!(BuiltinPrototype {
54        core_bpf_migration_config: None,
55        name: system_program,
56        enable_feature_id: None,
57        program_id: solana_system_program::id(),
58        entrypoint: solana_system_program::system_processor::Entrypoint::vm,
59    }),
60    testable_prototype!(BuiltinPrototype {
61        core_bpf_migration_config: None,
62        name: vote_program,
63        enable_feature_id: None,
64        program_id: solana_vote_program::id(),
65        entrypoint: solana_vote_program::vote_processor::Entrypoint::vm,
66    }),
67    BuiltinPrototype {
68        core_bpf_migration_config: Some(CoreBpfMigrationConfig {
69            source_buffer_address: buffer_accounts::stake_program::id(),
70            upgrade_authority_address: None,
71            feature_id: solana_feature_set::migrate_stake_program_to_core_bpf::id(),
72            migration_target: CoreBpfMigrationTargetType::Builtin,
73            datapoint_name: "migrate_builtin_to_core_bpf_stake_program",
74        }),
75        name: "stake_program",
76        enable_feature_id: None,
77        program_id: solana_stake_program::id(),
78        entrypoint: solana_stake_program::stake_instruction::Entrypoint::vm,
79    },
80    BuiltinPrototype {
81        core_bpf_migration_config: Some(CoreBpfMigrationConfig {
82            source_buffer_address: buffer_accounts::config_program::id(),
83            upgrade_authority_address: None,
84            feature_id: solana_feature_set::migrate_config_program_to_core_bpf::id(),
85            migration_target: CoreBpfMigrationTargetType::Builtin,
86            datapoint_name: "migrate_builtin_to_core_bpf_config_program",
87        }),
88        name: "config_program",
89        enable_feature_id: None,
90        program_id: solana_config_program::id(),
91        entrypoint: solana_config_program::config_processor::Entrypoint::vm,
92    },
93    testable_prototype!(BuiltinPrototype {
94        core_bpf_migration_config: None,
95        name: solana_bpf_loader_deprecated_program,
96        enable_feature_id: None,
97        program_id: bpf_loader_deprecated::id(),
98        entrypoint: solana_bpf_loader_program::Entrypoint::vm,
99    }),
100    testable_prototype!(BuiltinPrototype {
101        core_bpf_migration_config: None,
102        name: solana_bpf_loader_program,
103        enable_feature_id: None,
104        program_id: bpf_loader::id(),
105        entrypoint: solana_bpf_loader_program::Entrypoint::vm,
106    }),
107    testable_prototype!(BuiltinPrototype {
108        core_bpf_migration_config: None,
109        name: solana_bpf_loader_upgradeable_program,
110        enable_feature_id: None,
111        program_id: bpf_loader_upgradeable::id(),
112        entrypoint: solana_bpf_loader_program::Entrypoint::vm,
113    }),
114    testable_prototype!(BuiltinPrototype {
115        core_bpf_migration_config: None,
116        name: compute_budget_program,
117        enable_feature_id: None,
118        program_id: solana_sdk_ids::compute_budget::id(),
119        entrypoint: solana_compute_budget_program::Entrypoint::vm,
120    }),
121    BuiltinPrototype {
122        core_bpf_migration_config: Some(CoreBpfMigrationConfig {
123            source_buffer_address: buffer_accounts::address_lookup_table_program::id(),
124            upgrade_authority_address: None,
125            feature_id: solana_feature_set::migrate_address_lookup_table_program_to_core_bpf::id(),
126            migration_target: CoreBpfMigrationTargetType::Builtin,
127            datapoint_name: "migrate_builtin_to_core_bpf_address_lookup_table_program",
128        }),
129        name: "address_lookup_table_program",
130        enable_feature_id: None,
131        program_id: solana_sdk_ids::address_lookup_table::id(),
132        entrypoint: solana_address_lookup_table_program::processor::Entrypoint::vm,
133    },
134    testable_prototype!(BuiltinPrototype {
135        core_bpf_migration_config: None,
136        name: zk_token_proof_program,
137        enable_feature_id: Some(feature_set::zk_token_sdk_enabled::id()),
138        program_id: solana_sdk_ids::zk_token_proof_program::id(),
139        entrypoint: solana_zk_token_proof_program::Entrypoint::vm,
140    }),
141    testable_prototype!(BuiltinPrototype {
142        core_bpf_migration_config: None,
143        name: loader_v4,
144        enable_feature_id: Some(feature_set::enable_loader_v4::id()),
145        program_id: solana_sdk_ids::loader_v4::id(),
146        entrypoint: solana_loader_v4_program::Entrypoint::vm,
147    }),
148    testable_prototype!(BuiltinPrototype {
149        core_bpf_migration_config: None,
150        name: zk_elgamal_proof_program,
151        enable_feature_id: Some(feature_set::zk_elgamal_proof_program_enabled::id()),
152        program_id: solana_sdk_ids::zk_elgamal_proof_program::id(),
153        entrypoint: solana_zk_elgamal_proof_program::Entrypoint::vm,
154    }),
155];
156
157pub static STATELESS_BUILTINS: &[StatelessBuiltinPrototype] = &[StatelessBuiltinPrototype {
158    core_bpf_migration_config: Some(CoreBpfMigrationConfig {
159        source_buffer_address: buffer_accounts::feature_gate_program::id(),
160        upgrade_authority_address: None,
161        feature_id: solana_feature_set::migrate_feature_gate_program_to_core_bpf::id(),
162        migration_target: CoreBpfMigrationTargetType::Stateless,
163        datapoint_name: "migrate_stateless_to_core_bpf_feature_gate_program",
164    }),
165    name: "feature_gate_program",
166    program_id: solana_sdk_ids::feature::id(),
167}];
168
169/// Live source buffer accounts for builtin migrations.
170mod buffer_accounts {
171    pub mod address_lookup_table_program {
172        solana_pubkey::declare_id!("AhXWrD9BBUYcKjtpA3zuiiZG4ysbo6C6wjHo1QhERk6A");
173    }
174    pub mod config_program {
175        solana_pubkey::declare_id!("BuafH9fBv62u6XjzrzS4ZjAE8963ejqF5rt1f8Uga4Q3");
176    }
177    pub mod feature_gate_program {
178        solana_pubkey::declare_id!("3D3ydPWvmEszrSjrickCtnyRSJm1rzbbSsZog8Ub6vLh");
179    }
180    pub mod stake_program {
181        solana_pubkey::declare_id!("8t3vv6v99tQA6Gp7fVdsBH66hQMaswH5qsJVqJqo8xvG");
182    }
183}
184
185// This module contains a number of arbitrary addresses used for testing Core
186// BPF migrations.
187// Since the list of builtins is static, using `declare_id!` with constant
188// values is arguably the least-overhead approach to injecting static addresses
189// into the builtins list for both the feature ID and the source program ID.
190// These arbitrary IDs can then be used to configure feature-activation runtime
191// tests.
192#[cfg(any(test, feature = "dev-context-only-utils"))]
193pub mod test_only {
194    use crate::core_bpf_migration::{CoreBpfMigrationConfig, CoreBpfMigrationTargetType};
195    pub mod system_program {
196        pub mod feature {
197            solana_pubkey::declare_id!("AnjsdWg7LXFbjDdy78wncCJs9PyTdWpKkFmHAwQU1mQ6");
198        }
199        pub mod source_buffer {
200            solana_pubkey::declare_id!("EDEhzg1Jk79Wrk4mwpRa7txjgRxcE6igXwd6egFDVhuz");
201        }
202        pub mod upgrade_authority {
203            solana_pubkey::declare_id!("4d14UK2o1FKKoecEBWhVDZrBBbRuhug75G1j9XYCawC2");
204        }
205        pub const CONFIG: super::CoreBpfMigrationConfig = super::CoreBpfMigrationConfig {
206            source_buffer_address: source_buffer::id(),
207            upgrade_authority_address: Some(upgrade_authority::id()),
208            feature_id: feature::id(),
209            migration_target: super::CoreBpfMigrationTargetType::Builtin,
210            datapoint_name: "migrate_builtin_to_core_bpf_system_program",
211        };
212    }
213
214    pub mod vote_program {
215        pub mod feature {
216            solana_pubkey::declare_id!("5wDLHMasPmtrcpfRZX67RVkBXBbSTQ9S4C8EJomD3yAk");
217        }
218        pub mod source_buffer {
219            solana_pubkey::declare_id!("6T9s4PTcHnpq2AVAqoCbJd4FuHsdD99MjSUEbS7qb1tT");
220        }
221        pub mod upgrade_authority {
222            solana_pubkey::declare_id!("2N4JfyYub6cWUP9R4JrsFHv6FYKT7JnoRX8GQUH9MdT3");
223        }
224        pub const CONFIG: super::CoreBpfMigrationConfig = super::CoreBpfMigrationConfig {
225            source_buffer_address: source_buffer::id(),
226            upgrade_authority_address: Some(upgrade_authority::id()),
227            feature_id: feature::id(),
228            migration_target: super::CoreBpfMigrationTargetType::Builtin,
229            datapoint_name: "migrate_builtin_to_core_bpf_vote_program",
230        };
231    }
232
233    pub mod solana_bpf_loader_deprecated_program {
234        pub mod feature {
235            solana_pubkey::declare_id!("8gpakCv5Pk5PZGv9RUjzdkk2GVQPGx12cNRUDMQ3bP86");
236        }
237        pub mod source_buffer {
238            solana_pubkey::declare_id!("DveUYB5m9G3ce4zpV3fxg9pCNkvH1wDsyd8XberZ47JL");
239        }
240        pub mod upgrade_authority {
241            solana_pubkey::declare_id!("8Y5VTHdadnz4rZZWdUA4Qq2m2zWoCwwtb38spPZCXuGU");
242        }
243        pub const CONFIG: super::CoreBpfMigrationConfig = super::CoreBpfMigrationConfig {
244            source_buffer_address: source_buffer::id(),
245            upgrade_authority_address: Some(upgrade_authority::id()),
246            feature_id: feature::id(),
247            migration_target: super::CoreBpfMigrationTargetType::Builtin,
248            datapoint_name: "migrate_builtin_to_core_bpf_bpf_loader_deprecated_program",
249        };
250    }
251
252    pub mod solana_bpf_loader_program {
253        pub mod feature {
254            solana_pubkey::declare_id!("8yEdUm4SaP1yNq2MczEVdrM48SucvZCTDSqjcAKfYfL6");
255        }
256        pub mod source_buffer {
257            solana_pubkey::declare_id!("2EWMYGJPuGLW4TexLLEMeXP2BkB1PXEKBFb698yw6LhT");
258        }
259        pub mod upgrade_authority {
260            solana_pubkey::declare_id!("3sQ9VZ1Lvuvs6NpFXFV3ByFAf52ajPPdXwuhYERJR3iJ");
261        }
262        pub const CONFIG: super::CoreBpfMigrationConfig = super::CoreBpfMigrationConfig {
263            source_buffer_address: source_buffer::id(),
264            upgrade_authority_address: Some(upgrade_authority::id()),
265            feature_id: feature::id(),
266            migration_target: super::CoreBpfMigrationTargetType::Builtin,
267            datapoint_name: "migrate_builtin_to_core_bpf_bpf_loader_program",
268        };
269    }
270
271    pub mod solana_bpf_loader_upgradeable_program {
272        pub mod feature {
273            solana_pubkey::declare_id!("oPQbVjgoQ7SaQmzZiiHW4xqHbh4BJqqrFhxEJZiMiwY");
274        }
275        pub mod source_buffer {
276            solana_pubkey::declare_id!("6bTmA9iefD57GDoQ9wUjG8SeYkSpRw3EkKzxZCbhkavq");
277        }
278        pub mod upgrade_authority {
279            solana_pubkey::declare_id!("CuJvJY1K2wx82oLrQGSSWtw4AF7nVifEHupzSC2KEcq5");
280        }
281        pub const CONFIG: super::CoreBpfMigrationConfig = super::CoreBpfMigrationConfig {
282            source_buffer_address: source_buffer::id(),
283            upgrade_authority_address: Some(upgrade_authority::id()),
284            feature_id: feature::id(),
285            migration_target: super::CoreBpfMigrationTargetType::Builtin,
286            datapoint_name: "migrate_builtin_to_core_bpf_bpf_loader_upgradeable_program",
287        };
288    }
289
290    pub mod compute_budget_program {
291        pub mod feature {
292            solana_pubkey::declare_id!("D39vUspVfhjPVD7EtMJZrA5j1TSMp4LXfb43nxumGdHT");
293        }
294        pub mod source_buffer {
295            solana_pubkey::declare_id!("KfX1oLpFC5CwmFeSgXrNcXaouKjFkPuSJ4UsKb3zKMX");
296        }
297        pub mod upgrade_authority {
298            solana_pubkey::declare_id!("HGTbQhaCXNTbpgpLb2KNjqWSwpJyb2dqDB66Lc3Ph4aN");
299        }
300        pub const CONFIG: super::CoreBpfMigrationConfig = super::CoreBpfMigrationConfig {
301            source_buffer_address: source_buffer::id(),
302            upgrade_authority_address: Some(upgrade_authority::id()),
303            feature_id: feature::id(),
304            migration_target: super::CoreBpfMigrationTargetType::Builtin,
305            datapoint_name: "migrate_builtin_to_core_bpf_compute_budget_program",
306        };
307    }
308
309    pub mod zk_token_proof_program {
310        pub mod feature {
311            solana_pubkey::declare_id!("GfeFwUzKP9NmaP5u4VfnFgEvQoeQc2wPgnBFrUZhpib5");
312        }
313        pub mod source_buffer {
314            solana_pubkey::declare_id!("Ffe9gL8vXraBkiv3HqbLvBqY7i9V4qtZxjH83jYYDe1V");
315        }
316        pub mod upgrade_authority {
317            solana_pubkey::declare_id!("6zkXWHR8YeCvfMqHwyiz2n7g6hMUKCFhrVccZZTDk4ei");
318        }
319        pub const CONFIG: super::CoreBpfMigrationConfig = super::CoreBpfMigrationConfig {
320            source_buffer_address: source_buffer::id(),
321            upgrade_authority_address: Some(upgrade_authority::id()),
322            feature_id: feature::id(),
323            migration_target: super::CoreBpfMigrationTargetType::Builtin,
324            datapoint_name: "migrate_builtin_to_core_bpf_zk_token_proof_program",
325        };
326    }
327
328    pub mod loader_v4 {
329        pub mod feature {
330            solana_pubkey::declare_id!("Cz5JthYp27KR3rwTCtVJhbRgwHCurbwcYX46D8setL22");
331        }
332        pub mod source_buffer {
333            solana_pubkey::declare_id!("EH45pKy1kzjifB93wEJi91js3S4HETdsteywR7ZCNPn5");
334        }
335        pub mod upgrade_authority {
336            solana_pubkey::declare_id!("AWbiYRbFts9GVX5uwUkwV46hTFP85PxCAM8e8ir8Hqtq");
337        }
338        pub const CONFIG: super::CoreBpfMigrationConfig = super::CoreBpfMigrationConfig {
339            source_buffer_address: source_buffer::id(),
340            upgrade_authority_address: Some(upgrade_authority::id()),
341            feature_id: feature::id(),
342            migration_target: super::CoreBpfMigrationTargetType::Builtin,
343            datapoint_name: "migrate_builtin_to_core_bpf_loader_v4_program",
344        };
345    }
346
347    pub mod zk_elgamal_proof_program {
348        pub mod feature {
349            solana_pubkey::declare_id!("EYtuxScWqGWmcPEDmeUsEt3iPkvWE26EWLfSxUvWP2WN");
350        }
351        pub mod source_buffer {
352            solana_pubkey::declare_id!("AaVrLPurAUmjw6XRNGr6ezQfHaJWpBGHhcRSJmNjoVpQ");
353        }
354        pub mod upgrade_authority {
355            solana_pubkey::declare_id!("EyGkQYHgynUdvdNPNiWbJQk9roFCexgdJQMNcWbuvp78");
356        }
357        pub const CONFIG: super::CoreBpfMigrationConfig = super::CoreBpfMigrationConfig {
358            source_buffer_address: source_buffer::id(),
359            upgrade_authority_address: Some(upgrade_authority::id()),
360            feature_id: feature::id(),
361            migration_target: super::CoreBpfMigrationTargetType::Builtin,
362            datapoint_name: "migrate_builtin_to_core_bpf_zk_elgamal_proof_program",
363        };
364    }
365}
366
367#[cfg(test)]
368mod tests {
369    // Since a macro is used to initialize the test IDs from the `test_only`
370    // module, best to ensure the lists have the expected values within a test
371    // context.
372    #[test]
373    fn test_testable_prototypes() {
374        assert_eq!(
375            &super::BUILTINS[0].core_bpf_migration_config,
376            &Some(super::test_only::system_program::CONFIG)
377        );
378        assert_eq!(
379            &super::BUILTINS[1].core_bpf_migration_config,
380            &Some(super::test_only::vote_program::CONFIG)
381        );
382        // Stake has a live migration config, so it has no test-only configs
383        // to test here.
384        // Config has a live migration config, so it has no test-only configs
385        // to test here.
386        assert_eq!(
387            &super::BUILTINS[4].core_bpf_migration_config,
388            &Some(super::test_only::solana_bpf_loader_deprecated_program::CONFIG)
389        );
390        assert_eq!(
391            &super::BUILTINS[5].core_bpf_migration_config,
392            &Some(super::test_only::solana_bpf_loader_program::CONFIG)
393        );
394        assert_eq!(
395            &super::BUILTINS[6].core_bpf_migration_config,
396            &Some(super::test_only::solana_bpf_loader_upgradeable_program::CONFIG)
397        );
398        assert_eq!(
399            &super::BUILTINS[7].core_bpf_migration_config,
400            &Some(super::test_only::compute_budget_program::CONFIG)
401        );
402        // Address Lookup Table has a live migration config, so it has no
403        // test-only configs to test here.
404        assert_eq!(
405            &super::BUILTINS[9].core_bpf_migration_config,
406            &Some(super::test_only::zk_token_proof_program::CONFIG)
407        );
408        assert_eq!(
409            &super::BUILTINS[10].core_bpf_migration_config,
410            &Some(super::test_only::loader_v4::CONFIG)
411        );
412        assert_eq!(
413            &super::BUILTINS[11].core_bpf_migration_config,
414            &Some(super::test_only::zk_elgamal_proof_program::CONFIG)
415        );
416        // Feature Gate has a live migration config, so it has no test-only
417        // configs to test here.
418    }
419}