solana_precompiles/
lib.rs1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2#![deprecated(since = "2.2.2", note = "Use agave-precompiles instead")]
3#![allow(deprecated)]
4use {
5 lazy_static::lazy_static, solana_feature_set::FeatureSet,
6 solana_message::compiled_instruction::CompiledInstruction,
7 solana_precompile_error::PrecompileError, solana_pubkey::Pubkey,
8};
9
10pub type Verify = fn(&[u8], &[&[u8]], &FeatureSet) -> std::result::Result<(), PrecompileError>;
12
13pub struct Precompile {
15 pub program_id: Pubkey,
17 pub feature: Option<Pubkey>,
19 pub verify_fn: Verify,
21}
22impl Precompile {
23 pub fn new(program_id: Pubkey, feature: Option<Pubkey>, verify_fn: Verify) -> Self {
25 Precompile {
26 program_id,
27 feature,
28 verify_fn,
29 }
30 }
31 pub fn check_id<F>(&self, program_id: &Pubkey, is_enabled: F) -> bool
33 where
34 F: Fn(&Pubkey) -> bool,
35 {
36 self.feature
37 .is_none_or(|ref feature_id| is_enabled(feature_id))
38 && self.program_id == *program_id
39 }
40 pub fn verify(
42 &self,
43 data: &[u8],
44 instruction_datas: &[&[u8]],
45 feature_set: &FeatureSet,
46 ) -> std::result::Result<(), PrecompileError> {
47 (self.verify_fn)(data, instruction_datas, feature_set)
48 }
49}
50
51lazy_static! {
52 static ref PRECOMPILES: Vec<Precompile> = vec![
54 Precompile::new(
55 solana_sdk_ids::secp256k1_program::id(),
56 None, solana_secp256k1_program::verify,
58 ),
59 Precompile::new(
60 solana_sdk_ids::ed25519_program::id(),
61 None, solana_ed25519_program::verify,
63 ),
64 Precompile::new(
65 solana_sdk_ids::secp256r1_program::id(),
66 Some(solana_feature_set::enable_secp256r1_precompile::id()),
67 solana_secp256r1_program::verify,
68 )
69 ];
70}
71
72pub fn is_precompile<F>(program_id: &Pubkey, is_enabled: F) -> bool
74where
75 F: Fn(&Pubkey) -> bool,
76{
77 PRECOMPILES
78 .iter()
79 .any(|precompile| precompile.check_id(program_id, |feature_id| is_enabled(feature_id)))
80}
81
82pub fn get_precompile<F>(program_id: &Pubkey, is_enabled: F) -> Option<&Precompile>
84where
85 F: Fn(&Pubkey) -> bool,
86{
87 PRECOMPILES
88 .iter()
89 .find(|precompile| precompile.check_id(program_id, |feature_id| is_enabled(feature_id)))
90}
91
92pub fn get_precompiles<'a>() -> &'a [Precompile] {
93 &PRECOMPILES
94}
95
96pub fn verify_if_precompile(
98 program_id: &Pubkey,
99 precompile_instruction: &CompiledInstruction,
100 all_instructions: &[CompiledInstruction],
101 feature_set: &FeatureSet,
102) -> Result<(), PrecompileError> {
103 for precompile in PRECOMPILES.iter() {
104 if precompile.check_id(program_id, |feature_id| feature_set.is_active(feature_id)) {
105 let instruction_datas: Vec<_> = all_instructions
106 .iter()
107 .map(|instruction| instruction.data.as_ref())
108 .collect();
109 return precompile.verify(
110 &precompile_instruction.data,
111 &instruction_datas,
112 feature_set,
113 );
114 }
115 }
116 Ok(())
117}