#![cfg(all(feature = "attestation", feature = "rpc"))]
use sp1_sdk::{
network::FulfillmentStrategy, Elf, HashableKey, ProveRequest, Prover, ProverClient, ProvingKey, SP1Stdin,
};
use std::time::Duration;
use crate::zk::{Proof, SP1_ATTESTATION_ELF};
#[derive(Debug, Clone)]
pub struct AttestationProofInput {
pub attestation_bytes: Vec<u8>,
pub cached_cert_hashes: Vec<[u8; 32]>,
pub root_cert_der: Vec<u8>,
pub task_id: [u8; 32],
pub response_digest: [u8; 32],
}
pub async fn prove_attestation_invalid(input: AttestationProofInput) -> eyre::Result<Proof> {
tracing::info!("generating SP1 attestation invalidity proof");
crate::config::dotenv::init().unwrap();
let mut stdin = SP1Stdin::new();
stdin.write_vec(input.attestation_bytes);
stdin.write(&input.cached_cert_hashes);
stdin.write_vec(input.root_cert_der);
stdin.write(&input.task_id);
stdin.write(&input.response_digest);
let client = ProverClient::builder()
.network()
.private_key(&crate::config::dotenv::get::<String>("NETWORK_PRIVATE_KEY"))
.build()
.await;
let pk = client
.setup(Elf::Static(SP1_ATTESTATION_ELF))
.await
.map_err(|e| eyre::eyre!("SP1 attestation setup failed: {e}"))?;
let vk = pk.verifying_key().clone();
tracing::info!(
"requesting attestation proof, vkey={}",
vk.bytes32().to_string().as_str()
);
let request_id = client
.prove(&pk, stdin)
.groth16()
.strategy(FulfillmentStrategy::Reserved)
.request()
.await
.map_err(|e| eyre::eyre!("SP1 attestation proof request failed: {e}"))?;
tracing::info!("attestation proof request ID: {}", crate::hex!(request_id));
let proof = client
.wait_proof(request_id, Some(Duration::from_secs(600)), None)
.await
.map_err(|e| eyre::eyre!("SP1 attestation proof generation failed: {e}"))?;
tracing::info!("attestation proof generated successfully");
Ok(Proof::Sp1 {
journal: proof.public_values.to_vec(),
vk,
proof,
request_id,
})
}