diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index bd11e97668eec0..0d83d9bad5eda9 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -36,6 +36,7 @@ pub mod stakes; pub mod static_ids; pub mod status_cache; pub mod transaction_batch; +mod verify_precompiles; pub mod vote_sender_types; #[macro_use] diff --git a/runtime/src/verify_precompiles.rs b/runtime/src/verify_precompiles.rs new file mode 100644 index 00000000000000..6d203d856c14e4 --- /dev/null +++ b/runtime/src/verify_precompiles.rs @@ -0,0 +1,28 @@ +use { + solana_feature_set::FeatureSet, + solana_sdk::{ + precompiles::get_precompiles, + transaction::{Result, TransactionError}, + }, + solana_svm_transaction::svm_message::SVMMessage, +}; + +pub fn verify_precompiles(message: &impl SVMMessage, feature_set: &FeatureSet) -> Result<()> { + let mut all_instruction_data = None; // lazily collect this on first pre-compile + + let precompiles = get_precompiles(); + for (program_id, instruction) in message.program_instructions_iter() { + for precompile in precompiles { + if program_id == &precompile.program_id { + let all_instruction_data: &Vec<&[u8]> = all_instruction_data + .get_or_insert_with(|| message.instructions_iter().map(|ix| ix.data).collect()); + precompile + .verify(instruction.data, all_instruction_data, feature_set) + .map_err(|_| TransactionError::InvalidAccountIndex)?; + break; + } + } + } + + Ok(()) +}