solana_builtins/
lib.rs

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