mod error;
mod fields;
pub mod groth16;
pub mod risc0;
pub mod tags;
pub mod tests;
use crate::{
data_stack::Stack,
runtime_resource_meter::RuntimeResourceMeter,
zk_precompiles::{error::ZkIntegrityError, groth16::Groth16Precompile, risc0::R0SuccinctPrecompile, tags::ZkTag},
};
use kaspa_consensus_core::mass::ScriptUnits;
use kaspa_txscript_errors::TxScriptError;
trait ZkPrecompile {
type Error: Into<ZkIntegrityError> + std::fmt::Display;
fn verify_zk(dstack: &mut Stack, meter: &mut RuntimeResourceMeter) -> Result<(), Self::Error>;
}
pub(crate) fn parse_tag(dstack: &mut Stack) -> Result<ZkTag, TxScriptError> {
let tag_bytes = dstack.pop()?;
match tag_bytes.as_slice() {
[tag_byte] => ZkTag::try_from(*tag_byte).map_err(|e| TxScriptError::ZkIntegrity(e.to_string())),
[] => Err(TxScriptError::ZkIntegrity("Tag byte is missing".to_string())),
_ => Err(TxScriptError::ZkIntegrity(format!("Tag byte length {} is invalid", tag_bytes.len()))),
}
}
pub(crate) fn verify_zk(tag: ZkTag, dstack: &mut Stack, meter: &mut RuntimeResourceMeter) -> Result<(), TxScriptError> {
match tag {
ZkTag::Groth16 => Groth16Precompile::verify_zk(dstack, meter).map_err(|e| TxScriptError::ZkIntegrity(e.to_string())),
ZkTag::R0Succinct => R0SuccinctPrecompile::verify_zk(dstack, meter).map_err(|e| TxScriptError::ZkIntegrity(e.to_string())),
}
}
pub fn compute_zk_cost(tag: u8) -> ScriptUnits {
ZkTag::try_from(tag).map(|t| t.cost()).unwrap_or(ZkTag::max_cost()) }