use crate::Result;
use crate::error::Error;
use dusk_core::plonk::PlonkVersion;
use dusk_core::transfer::moonlight::Transaction as MoonlightTransaction;
use dusk_core::transfer::phoenix::Transaction as PhoenixTransaction;
use dusk_vm::host_queries;
#[cfg(not(feature = "dynamic-verifier"))]
mod embed {
pub static VD_EXEC_1_2: &[u8] = include_bytes!(
"../assets/vd/c8fed2bfcc0e0e64709586b56636fc1831be5f0227e533363e9a49b8fae5cd2f.vd"
);
pub static VD_EXEC_2_2: &[u8] = include_bytes!(
"../assets/vd/98c9786a8cf36f19bcbdf97f4bc140fe402ae5f72cef3f60f24b96071c0faa73.vd"
);
pub static VD_EXEC_3_2: &[u8] = include_bytes!(
"../assets/vd/1210b96327d25a0403be7b8e027cfe964370700b94ec7f47d22128ecbe7e9803.vd"
);
pub static VD_EXEC_4_2: &[u8] = include_bytes!(
"../assets/vd/0095785bd378e5cd3c7427c03b6d4420966c03156bf045b556f22419252fc8bc.vd"
);
}
#[cfg(not(feature = "dynamic-verifier"))]
use embed::*;
#[cfg(feature = "dynamic-verifier")]
mod runtime {
use rusk_profile::Circuit as CircuitProfile;
use std::sync::LazyLock;
pub static VD_EXEC_1_2: LazyLock<Vec<u8>> =
LazyLock::new(|| fetch_verifier("TxCircuitOneTwo"));
pub static VD_EXEC_2_2: LazyLock<Vec<u8>> =
LazyLock::new(|| fetch_verifier("TxCircuitTwoTwo"));
pub static VD_EXEC_3_2: LazyLock<Vec<u8>> =
LazyLock::new(|| fetch_verifier("TxCircuitThreeTwo"));
pub static VD_EXEC_4_2: LazyLock<Vec<u8>> =
LazyLock::new(|| fetch_verifier("TxCircuitFourTwo"));
fn fetch_verifier(circuit_name: &str) -> Vec<u8> {
let circuit_profile = CircuitProfile::from_name(circuit_name)
.unwrap_or_else(|_| {
panic!(
"There should be circuit data stored for {}",
circuit_name
)
});
circuit_profile.get_verifier().unwrap_or_else(|_| {
panic!("there should be a verifier key stored for {}", circuit_name)
})
}
}
#[cfg(feature = "dynamic-verifier")]
use runtime::*;
pub fn verify_proof_with_version(
tx: &PhoenixTransaction,
version: PlonkVersion,
) -> Result<bool> {
let vd = vd_for_phoenix(tx)?;
Ok(host_queries::verify_plonk_with_version(
version,
vd.to_vec(),
tx.proof().to_vec(),
tx.public_inputs(),
))
}
fn vd_for_phoenix(tx: &PhoenixTransaction) -> Result<&[u8]> {
let inputs_len = tx.nullifiers().len();
let vd = match inputs_len {
1 => &VD_EXEC_1_2,
2 => &VD_EXEC_2_2,
3 => &VD_EXEC_3_2,
4 => &VD_EXEC_4_2,
_ => {
return Err(Error::InvalidCircuitArguments(
inputs_len,
tx.outputs().len(),
));
}
};
Ok(vd)
}
pub fn verify_signature(tx: &MoonlightTransaction) -> Result<bool> {
Ok(tx
.sender()
.verify(tx.signature(), &tx.signature_message())
.is_ok())
}