Skip to content

Commit

Permalink
extract solana-precompiles crate
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinheavey committed Nov 14, 2024
1 parent 0b19841 commit 31c05c1
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 107 deletions.
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ members = [
"sdk/package-metadata-macro",
"sdk/packet",
"sdk/precompile-error",
"sdk/precompiles",
"sdk/presigner",
"sdk/program",
"sdk/program-entrypoint",
Expand Down Expand Up @@ -488,6 +489,7 @@ solana-perf = { path = "perf", version = "=2.2.0" }
solana-poh = { path = "poh", version = "=2.2.0" }
solana-poseidon = { path = "poseidon", version = "=2.2.0" }
solana-precompile-error = { path = "sdk/precompile-error", version = "=2.2.0" }
solana-precompiles = { path = "sdk/precompiles", version = "=2.2.0" }
solana-presigner = { path = "sdk/presigner", version = "=2.2.0" }
solana-program = { path = "sdk/program", version = "=2.2.0", default-features = false }
solana-program-error = { path = "sdk/program-error", version = "=2.2.0" }
Expand Down
15 changes: 15 additions & 0 deletions programs/sbf/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ full = [
"dep:solana-ed25519-instructions",
"dep:solana-keypair",
"dep:solana-precompile-error",
"dep:solana-precompiles",
"dep:solana-presigner",
"dep:solana-quic-definitions",
"dep:solana-secp256k1-instruction",
Expand Down Expand Up @@ -121,6 +122,7 @@ solana-keypair = { workspace = true, optional = true, features = ["seed-derivabl
solana-native-token = { workspace = true }
solana-packet = { workspace = true, features = ["bincode", "serde"] }
solana-precompile-error = { workspace = true, optional = true }
solana-precompiles = { workspace = true, optional = true }
solana-presigner = { workspace = true, optional = true }
solana-program = { workspace = true }
solana-program-memory = { workspace = true }
Expand Down
28 changes: 28 additions & 0 deletions sdk/precompiles/Cargo.toml
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
109 changes: 109 additions & 0 deletions sdk/precompiles/src/lib.rs
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(())
}
110 changes: 3 additions & 107 deletions sdk/src/precompiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,111 +4,7 @@

#[deprecated(since = "2.1.0", note = "Use `solana-precompile-error` crate instead.")]
pub use solana_precompile_error::PrecompileError;
use {
lazy_static::lazy_static, solana_feature_set::FeatureSet,
solana_program::instruction::CompiledInstruction, solana_pubkey::Pubkey,
#[deprecated(since = "2.2.0", note = "Use `solana-precompiles` crate instead.")]
pub use solana_precompiles::{
get_precompile, get_precompiles, is_precompile, verify_if_precompile, Precompile, Verify,
};

/// 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(
crate::secp256k1_program::id(),
None, // always enabled
crate::secp256k1_instruction::verify,
),
Precompile::new(
crate::ed25519_program::id(),
None, // always enabled
crate::ed25519_instruction::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(())
}

0 comments on commit 31c05c1

Please sign in to comment.