Skip to content

Commit

Permalink
added test_mips_elf
Browse files Browse the repository at this point in the history
  • Loading branch information
martyall committed Jan 3, 2025
1 parent be3660f commit 539751f
Show file tree
Hide file tree
Showing 7 changed files with 310 additions and 150 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions o1vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ log.workspace = true
mina-curves.workspace = true
mina-poseidon.workspace = true
o1-utils.workspace = true
once_cell.workspace = true
os_pipe.workspace = true
poly-commitment.workspace = true
rand.workspace = true
Expand Down
19 changes: 19 additions & 0 deletions o1vm/src/cannon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,25 @@ pub struct VmConfiguration {
pub host: Option<HostProgram>,
}

impl Default for VmConfiguration {
fn default() -> Self {
VmConfiguration {
input_state_file: "state.json".to_string(),
output_state_file: "out.json".to_string(),
metadata_file: None,
proof_at: StepFrequency::Never,
stop_at: StepFrequency::Never,
snapshot_state_at: StepFrequency::Never,
info_at: StepFrequency::Never,
proof_fmt: "proof-%d.json".to_string(),
snapshot_fmt: "state-%d.json".to_string(),
pprof_cpu: false,
halt_address: None,
host: None,
}
}
}

#[derive(Debug, Clone)]
pub struct Start {
pub time: std::time::Instant,
Expand Down
213 changes: 65 additions & 148 deletions o1vm/src/pickles/main.rs
Original file line number Diff line number Diff line change
@@ -1,159 +1,16 @@
use ark_ff::UniformRand;
use clap::Parser;
use kimchi::circuits::domains::EvaluationDomains;
use log::debug;
use mina_curves::pasta::{Fp, Vesta, VestaParameters};
use mina_poseidon::{
constants::PlonkSpongeConstantsKimchi,
sponge::{DefaultFqSponge, DefaultFrSponge},
};
use mina_curves::pasta::{Fp, Vesta};
use o1vm::{
cannon::{self, Start, State},
cli, elf_loader,
interpreters::mips::{
column::N_MIPS_REL_COLS,
constraints as mips_constraints,
witness::{self as mips_witness},
Instruction,
},
pickles::{proof::ProofInputs, prover, verifier},
interpreters::mips::witness::{self as mips_witness},
pickles::{cannon_main, DOMAIN_FP, DOMAIN_SIZE},
preimage_oracle::{NullPreImageOracle, PreImageOracle, PreImageOracleT},
test_preimage_read,
};
use poly_commitment::{ipa::SRS, SRS as _};
use std::{fs::File, io::BufReader, path::Path, process::ExitCode, time::Instant};

pub const DOMAIN_SIZE: usize = 1 << 15;

pub fn cannon_main(args: cli::cannon::RunArgs) {
let mut rng = rand::thread_rng();

let configuration: cannon::VmConfiguration = args.vm_cfg.into();

let file =
File::open(&configuration.input_state_file).expect("Error opening input state file ");

let reader = BufReader::new(file);
// Read the JSON contents of the file as an instance of `State`.
let state: State = serde_json::from_reader(reader).expect("Error reading input state file");

let meta = &configuration.metadata_file.as_ref().map(|f| {
let meta_file =
File::open(f).unwrap_or_else(|_| panic!("Could not open metadata file {}", f));
serde_json::from_reader(BufReader::new(meta_file))
.unwrap_or_else(|_| panic!("Error deserializing metadata file {}", f))
});

// Initialize some data used for statistical computations
let start = Start::create(state.step as usize);

let domain_fp = EvaluationDomains::<Fp>::create(DOMAIN_SIZE).unwrap();

let srs: SRS<Vesta> = match &args.srs_cache {
Some(cache) => {
debug!("Loading SRS from cache {}", cache);
let file = File::open(cache).expect("Error opening srs_cache file ");
let reader = BufReader::new(file);
let srs: SRS<Vesta> = rmp_serde::from_read(reader).unwrap();
debug!("SRS loaded successfully from cache");
srs
}
None => {
debug!("No SRS cache provided. Creating SRS from scratch");
let srs = SRS::create(DOMAIN_SIZE);
srs.get_lagrange_basis(domain_fp.d1);
debug!("SRS created successfully");
srs
}
};

// Initialize the environments
let mut mips_wit_env = match configuration.host.clone() {
Some(host) => {
let mut po = PreImageOracle::create(host);
let _child = po.start();
mips_witness::Env::<Fp, Box<dyn PreImageOracleT>>::create(
cannon::PAGE_SIZE as usize,
state,
Box::new(po),
)
}
None => {
debug!("No preimage oracle provided 🤞");
// warning: the null preimage oracle has no data and will crash the program if used
mips_witness::Env::<Fp, Box<dyn PreImageOracleT>>::create(
cannon::PAGE_SIZE as usize,
state,
Box::new(NullPreImageOracle),
)
}
};

let constraints = mips_constraints::get_all_constraints::<Fp>();

let mut curr_proof_inputs: ProofInputs<Vesta> = ProofInputs::new(DOMAIN_SIZE);
while !mips_wit_env.halt {
let _instr: Instruction = mips_wit_env.step(&configuration, meta, &start);
for (scratch, scratch_chunk) in mips_wit_env
.scratch_state
.iter()
.zip(curr_proof_inputs.evaluations.scratch.iter_mut())
{
scratch_chunk.push(*scratch);
}
for (scratch, scratch_chunk) in mips_wit_env
.scratch_state_inverse
.iter()
.zip(curr_proof_inputs.evaluations.scratch_inverse.iter_mut())
{
scratch_chunk.push(*scratch);
}
curr_proof_inputs
.evaluations
.instruction_counter
.push(Fp::from(mips_wit_env.instruction_counter));
// FIXME: Might be another value
curr_proof_inputs.evaluations.error.push(Fp::rand(&mut rng));

curr_proof_inputs
.evaluations
.selector
.push(Fp::from((mips_wit_env.selector - N_MIPS_REL_COLS) as u64));

if curr_proof_inputs.evaluations.instruction_counter.len() == DOMAIN_SIZE {
let start_iteration = Instant::now();
debug!("Limit of {DOMAIN_SIZE} reached. We make a proof, verify it (for testing) and start with a new chunk");
let proof = prover::prove::<
Vesta,
DefaultFqSponge<VestaParameters, PlonkSpongeConstantsKimchi>,
DefaultFrSponge<Fp, PlonkSpongeConstantsKimchi>,
_,
>(domain_fp, &srs, curr_proof_inputs, &constraints, &mut rng)
.unwrap();
// Check that the proof is correct. This is for testing purposes.
// Leaving like this for now.
debug!(
"Proof generated in {elapsed} μs",
elapsed = start_iteration.elapsed().as_micros()
);
{
let start_iteration = Instant::now();
let verif = verifier::verify::<
Vesta,
DefaultFqSponge<VestaParameters, PlonkSpongeConstantsKimchi>,
DefaultFrSponge<Fp, PlonkSpongeConstantsKimchi>,
>(domain_fp, &srs, &constraints, &proof);
debug!(
"Verification done in {elapsed} μs",
elapsed = start_iteration.elapsed().as_micros()
);
assert!(verif);
}

curr_proof_inputs = ProofInputs::new(DOMAIN_SIZE);
}
}
}
use std::{fs::File, io::BufReader, path::Path, process::ExitCode};

fn gen_state_json(arg: cli::cannon::GenStateJsonArgs) -> Result<(), String> {
let path = Path::new(&arg.input);
Expand All @@ -169,7 +26,67 @@ pub fn main() -> ExitCode {
match args {
cli::Commands::Cannon(args) => match args {
cli::cannon::Cannon::Run(args) => {
cannon_main(args);
let configuration: cannon::VmConfiguration = args.vm_cfg.into();

// Read the JSON contents of the file as an instance of `State`.
let state: State = {
let file = File::open(&configuration.input_state_file)
.expect("Error opening input state file ");
let reader = BufReader::new(file);
serde_json::from_reader(reader).expect("Error reading input state file")
};

// Initialize some data used for statistical computations
let start = Start::create(state.step as usize);

let meta = &configuration.metadata_file.as_ref().map(|f| {
let meta_file = File::open(f)
.unwrap_or_else(|_| panic!("Could not open metadata file {}", f));
serde_json::from_reader(BufReader::new(meta_file))
.unwrap_or_else(|_| panic!("Error deserializing metadata file {}", f))
});

// Initialize the environments
let mips_wit_env = match configuration.host.clone() {
Some(host) => {
let mut po = PreImageOracle::create(host);
let _child = po.start();
mips_witness::Env::<Fp, Box<dyn PreImageOracleT>>::create(
cannon::PAGE_SIZE as usize,
state,
Box::new(po),
)
}
None => {
debug!("No preimage oracle provided 🤞");
// warning: the null preimage oracle has no data and will crash the program if used
mips_witness::Env::<Fp, Box<dyn PreImageOracleT>>::create(
cannon::PAGE_SIZE as usize,
state,
Box::new(NullPreImageOracle),
)
}
};

let srs: SRS<Vesta> = match &args.srs_cache {
Some(cache) => {
debug!("Loading SRS from cache {}", cache);
let file = File::open(cache).expect("Error opening srs_cache file ");
let reader = BufReader::new(file);
let srs: SRS<Vesta> = rmp_serde::from_read(reader).unwrap();
debug!("SRS loaded successfully from cache");
srs
}
None => {
debug!("No SRS cache provided. Creating SRS from scratch");
let srs = SRS::create(DOMAIN_SIZE);
srs.get_lagrange_basis(DOMAIN_FP.d1);
debug!("SRS created successfully");
srs
}
};

cannon_main(configuration, mips_wit_env, &srs, start, meta);
}
cli::cannon::Cannon::TestPreimageRead(args) => {
test_preimage_read::main(args);
Expand Down
Loading

0 comments on commit 539751f

Please sign in to comment.