use alloc::{format, vec::Vec};
use super::{DeferredContext, Node, NodeType, Payload, PrecompileError};
use crate::{Felt, utils::hash_string_to_word};
pub trait Precompile: Send + Sync {
fn name(&self) -> &'static str;
fn id(&self) -> Felt;
fn init(&self) -> Vec<Node> {
Vec::new()
}
fn decode(&self, args: [Felt; 3]) -> Option<NodeType>;
fn evaluate(
&self,
args: [Felt; 3],
payload: &Payload,
context: &mut DeferredContext<'_>,
) -> Result<Node, PrecompileError>;
}
const PRECOMPILE_ID_DOMSEP: &str = "miden-deferred-precompile/v1";
pub fn precompile_id(name: &str) -> Felt {
let domain_separated = format!("{PRECOMPILE_ID_DOMSEP}:{}:{name}", name.len());
hash_string_to_word(domain_separated.as_str())[0]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn id_derivation_is_stable_unique_and_domain_separated() {
assert_eq!(precompile_id("foo"), precompile_id("foo"));
assert_ne!(precompile_id("foo"), precompile_id("bar"));
let name = "my_precompile";
assert_ne!(precompile_id(name), crate::events::EventId::from_name(name).as_felt());
}
}