forked from solana-labs/solana
-
Notifications
You must be signed in to change notification settings - Fork 254
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0b19841
commit 31c05c1
Showing
7 changed files
with
174 additions
and
107 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
[package] | ||
name = "solana-precompiles" | ||
description = "Solana precompiled programs." | ||
documentation = "https://docs.rs/solana-precompiles" | ||
version = { workspace = true } | ||
authors = { workspace = true } | ||
repository = { workspace = true } | ||
homepage = { workspace = true } | ||
license = { workspace = true } | ||
edition = { workspace = true } | ||
|
||
[dependencies] | ||
lazy_static = { workspace = true } | ||
solana-ed25519-instructions = { workspace = true } | ||
solana-feature-set = { workspace = true } | ||
solana-precompile-error = { workspace = true } | ||
solana-program = { workspace = true, default-features = false } | ||
solana-pubkey = { workspace = true } | ||
solana-secp256k1-instruction = { workspace = true } | ||
solana-sdk-ids = { workspace = true } | ||
|
||
[package.metadata.docs.rs] | ||
targets = ["x86_64-unknown-linux-gnu"] | ||
all-features = true | ||
rustdoc-args = ["--cfg=docsrs"] | ||
|
||
[lints] | ||
workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
use { | ||
lazy_static::lazy_static, solana_feature_set::FeatureSet, | ||
solana_precompile_error::PrecompileError, solana_program::instruction::CompiledInstruction, | ||
solana_pubkey::Pubkey, | ||
}; | ||
|
||
/// All precompiled programs must implement the `Verify` function | ||
pub type Verify = fn(&[u8], &[&[u8]], &FeatureSet) -> std::result::Result<(), PrecompileError>; | ||
|
||
/// Information on a precompiled program | ||
pub struct Precompile { | ||
/// Program id | ||
pub program_id: Pubkey, | ||
/// Feature to enable on, `None` indicates always enabled | ||
pub feature: Option<Pubkey>, | ||
/// Verification function | ||
pub verify_fn: Verify, | ||
} | ||
impl Precompile { | ||
/// Creates a new `Precompile` | ||
pub fn new(program_id: Pubkey, feature: Option<Pubkey>, verify_fn: Verify) -> Self { | ||
Precompile { | ||
program_id, | ||
feature, | ||
verify_fn, | ||
} | ||
} | ||
/// Check if a program id is this precompiled program | ||
pub fn check_id<F>(&self, program_id: &Pubkey, is_enabled: F) -> bool | ||
where | ||
F: Fn(&Pubkey) -> bool, | ||
{ | ||
self.feature | ||
.map_or(true, |ref feature_id| is_enabled(feature_id)) | ||
&& self.program_id == *program_id | ||
} | ||
/// Verify this precompiled program | ||
pub fn verify( | ||
&self, | ||
data: &[u8], | ||
instruction_datas: &[&[u8]], | ||
feature_set: &FeatureSet, | ||
) -> std::result::Result<(), PrecompileError> { | ||
(self.verify_fn)(data, instruction_datas, feature_set) | ||
} | ||
} | ||
|
||
lazy_static! { | ||
/// The list of all precompiled programs | ||
static ref PRECOMPILES: Vec<Precompile> = vec![ | ||
Precompile::new( | ||
solana_sdk_ids::secp256k1_program::id(), | ||
None, // always enabled | ||
solana_secp256k1_instruction::verify, | ||
), | ||
Precompile::new( | ||
solana_sdk_ids::ed25519_program::id(), | ||
None, // always enabled | ||
solana_ed25519_instructions::verify, | ||
), | ||
]; | ||
} | ||
|
||
/// Check if a program is a precompiled program | ||
pub fn is_precompile<F>(program_id: &Pubkey, is_enabled: F) -> bool | ||
where | ||
F: Fn(&Pubkey) -> bool, | ||
{ | ||
PRECOMPILES | ||
.iter() | ||
.any(|precompile| precompile.check_id(program_id, |feature_id| is_enabled(feature_id))) | ||
} | ||
|
||
/// Find an enabled precompiled program | ||
pub fn get_precompile<F>(program_id: &Pubkey, is_enabled: F) -> Option<&Precompile> | ||
where | ||
F: Fn(&Pubkey) -> bool, | ||
{ | ||
PRECOMPILES | ||
.iter() | ||
.find(|precompile| precompile.check_id(program_id, |feature_id| is_enabled(feature_id))) | ||
} | ||
|
||
pub fn get_precompiles<'a>() -> &'a [Precompile] { | ||
&PRECOMPILES | ||
} | ||
|
||
/// Check that a program is precompiled and if so verify it | ||
pub fn verify_if_precompile( | ||
program_id: &Pubkey, | ||
precompile_instruction: &CompiledInstruction, | ||
all_instructions: &[CompiledInstruction], | ||
feature_set: &FeatureSet, | ||
) -> Result<(), PrecompileError> { | ||
for precompile in PRECOMPILES.iter() { | ||
if precompile.check_id(program_id, |feature_id| feature_set.is_active(feature_id)) { | ||
let instruction_datas: Vec<_> = all_instructions | ||
.iter() | ||
.map(|instruction| instruction.data.as_ref()) | ||
.collect(); | ||
return precompile.verify( | ||
&precompile_instruction.data, | ||
&instruction_datas, | ||
feature_set, | ||
); | ||
} | ||
} | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters