use clap::{Args, Subcommand};
use cortex_core::{AuthorityClass, ClaimCeiling, ClaimProofState, MemoryId, RuntimeMode};
use cortex_runtime::{compile_runtime_claim, RuntimeClaimKind};
use cortex_store::verify_memory_proof_closure;
use crate::cmd::open_default_store;
use crate::exit::Exit;
#[derive(Debug, Subcommand)]
pub enum ProofSub {
Memory(MemoryProofArgs),
}
#[derive(Debug, Args)]
pub struct MemoryProofArgs {
#[arg(value_name = "MEMORY_ID")]
pub memory_id: MemoryId,
}
pub fn run(sub: ProofSub) -> Exit {
match sub {
ProofSub::Memory(args) => memory(args),
}
}
fn memory(args: MemoryProofArgs) -> Exit {
let pool = match open_default_store("proof memory") {
Ok(pool) => pool,
Err(exit) => return exit,
};
match verify_memory_proof_closure(&pool, &args.memory_id) {
Ok(report) => match proof_memory_payload(&report) {
Ok(payload) => match serde_json::to_string_pretty(&payload) {
Ok(serialized) => {
println!("{serialized}");
Exit::Ok
}
Err(err) => {
eprintln!("cortex proof memory: failed to serialize report: {err}");
Exit::Internal
}
},
Err(err) => {
eprintln!("cortex proof memory: failed to build report payload: {err}");
Exit::Internal
}
},
Err(err) => {
eprintln!("cortex proof memory: {err}");
Exit::Internal
}
}
}
fn proof_memory_payload(
report: &cortex_core::ProofClosureReport,
) -> Result<serde_json::Value, serde_json::Error> {
let proof_state = ClaimProofState::from(report.state());
let claim = compile_runtime_claim(
"store-local memory proof closure",
RuntimeClaimKind::Advisory,
RuntimeMode::LocalUnsigned,
AuthorityClass::Observed,
proof_state,
ClaimCeiling::LocalUnsigned,
);
let policy = report.policy_decision();
let mut payload = serde_json::to_value(report)?;
if let serde_json::Value::Object(fields) = &mut payload {
fields.insert(
"runtime_mode".into(),
serde_json::to_value(claim.runtime_mode)?,
);
fields.insert(
"claim_ceiling".into(),
serde_json::to_value(claim.effective_ceiling)?,
);
fields.insert(
"downgrade_reasons".into(),
serde_json::to_value(claim.reasons)?,
);
fields.insert("claim_allowed".into(), serde_json::to_value(claim.allowed)?);
fields.insert(
"policy_outcome".into(),
serde_json::to_value(policy.final_outcome)?,
);
fields.insert(
"policy_contributing".into(),
serde_json::to_value(policy.contributing)?,
);
}
Ok(payload)
}