use neptune_primitives::network::Network;
use tasm_lib::triton_vm;
use tasm_lib::triton_vm::proof::Claim;
use tasm_lib::triton_vm::stark::Stark;
use tokio::task;
use crate::transaction::validity::neptune_proof::Proof;
pub const CHECKPOINT_MAIN: &str = include_str!("../assets/main/checkpoint.dat");
pub const CHECKPOINT_TESTNET_0: &str = include_str!("../assets/testnet-0/checkpoint.dat");
static CLAIMS_CACHE: std::sync::LazyLock<tokio::sync::Mutex<std::collections::HashSet<Claim>>> =
std::sync::LazyLock::new(|| tokio::sync::Mutex::new(std::collections::HashSet::new()));
static CLAIMS_CACHE_ENABLED: std::sync::LazyLock<tokio::sync::Mutex<bool>> =
std::sync::LazyLock::new(|| tokio::sync::Mutex::new(true));
pub async fn verify(claim: Claim, proof: Proof, network: Network) -> bool {
if network.use_mock_proof() {
return proof.is_valid_mock();
}
{
let is_enabled = *CLAIMS_CACHE_ENABLED.lock().await;
if is_enabled && CLAIMS_CACHE.lock().await.contains(&claim) {
return true;
}
}
#[cfg(test)]
let claim_clone = claim.clone();
let verdict =
task::spawn_blocking(move || triton_vm::verify(Stark::default(), &claim, &proof.into()))
.await
.expect("should be able to verify proof in new tokio task");
#[cfg(test)]
if verdict {
cache_true_claims([claim_clone]).await;
}
verdict
}
pub async fn cache_true_claims<IterClaims: IntoIterator<Item = Claim>>(claims: IterClaims) {
let mut cache = CLAIMS_CACHE.lock().await;
for claim in claims {
cache.insert(claim);
}
}
#[cfg(any(test, feature = "test-helpers"))]
pub async fn disable_true_claims_cache() {
*CLAIMS_CACHE_ENABLED.lock().await = false;
}
#[cfg(any(test, feature = "test-helpers"))]
pub async fn enable_true_claims_cache() {
*CLAIMS_CACHE_ENABLED.lock().await = true;
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
pub(crate) mod tests {
use itertools::Itertools;
use macro_rules_attr::apply;
use rand::Rng;
use tasm_lib::prelude::Tip5;
use triton_vm::prelude::BFieldCodec;
use super::*;
use crate::proof_abstractions::test_runtime::shared_tokio_runtime;
pub(crate) fn bogus_proof(claim: &Claim) -> Proof {
Proof::from(Tip5::hash_varlen(&claim.encode()).values().to_vec())
}
#[apply(shared_tokio_runtime)]
async fn test_claims_cache() {
let network = Network::Main;
let mut rng = rand::rng();
let some_claim = Claim::new(rng.random())
.with_input((0..10).map(|_| rng.random()).collect_vec())
.with_output((0..10).map(|_| rng.random()).collect_vec());
let some_proof = bogus_proof(&some_claim);
assert!(!verify(some_claim.clone(), some_proof.clone(), network).await);
cache_true_claims(vec![some_claim.clone()]).await;
assert!(verify(some_claim, some_proof, network).await);
}
}