Skip to content

Commit

Permalink
update nexus tools with proof commands
Browse files Browse the repository at this point in the history
  • Loading branch information
govereau committed Nov 29, 2023
1 parent 343d2f2 commit a102584
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 68 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ publish = false
[workspace.dependencies]
clap = { version = "4.3", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

supernova = { git = "ssh://git@github.com:22/nexus-xyz/supernova.git", rev="fe89f3e" }
#supernova = { path = "../supernova" }
Expand Down
45 changes: 33 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,44 @@ to `runtime` rather than the default git repo.

If successful, you can run the new project binary with `cargo run`.

Proving programs can be done with either `msnova` or `prover`.
The first uses the Microsoft Nova implementation, and the second uses
the Nexus Nova implementation. For example:
Proving programs can be done with either locally or using the Nexus network.
To prove using the nexus network, use the `prove` command.

```
cd msnova
cargo run -r riscv_elf_file
cargo nexus prove # prove debug build
cargo nexus prove -r # prove release build
```

If your project contains multiple binaries, you may need to
specify the binary to use:

```
cargo nexus prove --bin name
```
You can check on the status of your proof, and download the result
using the `query` command:

```
cd prover
# generate public parameters to file
cargo run -r -- gen
cargo nexus query --hash e087116c0b13fb1a66af46d572b78e98b76c0bf814bd4f5df781469a3755fd33
```

If the proof is complete it will be saved to `nexus-proof.json`; this filename
can be changed on the command line (see -h for help).

# prove using saves parameters
cargo run -r -- prove riscv_elf_file
You can check a proof using the `verify` command:

# generate public parameter and prove
cargo run -r -- prove -g riscv_elf_file
```
cargo nexus verify
```

You may need to specify the input files on the command line:

```
cargo nexus verify --public-params nexus-public.zst -f nexus-proof.json
```

Local proofs can be done using the `local-prove` command:

```
cargo nexus local-prove --bin example
```
2 changes: 1 addition & 1 deletion network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ reqwest = { version = "0.11.22", default-features = false, features = [ "blockin
snmalloc-rs = { version = "0.3.4", optional = true }

serde.workspace = true
serde_json = "1.0"
serde_json.workspace = true
postcard = { version = "1.0", features = ["use-std"] }
lz4 = "1.24"

Expand Down
4 changes: 4 additions & 0 deletions tools/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,9 @@ name = "nexus-run"
path = "src/nexus-run.rs"

[dependencies]
cargo_metadata = "0.18.1"
clap.workspace = true
serde_json.workspace = true
nexus-riscv = { path = "../riscv" }
nexus-prover = { path = "../prover" }
nexus-network = { path = "../network" }
23 changes: 16 additions & 7 deletions tools/src/cargo-nexus.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
mod new;
mod options;
mod util;
mod new;
mod run;
mod prove;

pub use options::*;
pub use util::*;

fn main() -> CmdResult {
match &options().command {
fn main() {
let res = match &options().command {
New { .. } => new::new(),
cmd => {
println!("Not Yet Implemented: {:?}", cmd);
Err("TODO".into())
}
Run { .. } => run::run(),
Prove { .. } => prove::prove(),
Query { .. } => prove::query(),
Verify { .. } => prove::verify(),
LocalProve { .. } => prove::local(),
cmd => Err(format!("Not Yet Implemented: {:?}", cmd).into()),
};

match res {
Ok(_) => (),
Err(CmdErr(s)) => eprintln!("{}", s),
}
}
6 changes: 3 additions & 3 deletions tools/src/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ use std::path::Path;
const CONFIG: &[u8] = include_bytes!("config.toml");
const SRC: &[u8] = include_bytes!("template.rs");

fn write_to_file(root: &Path, dir: &str, file: &str, contents: &[u8]) -> CmdResult {
fn write_to_file(root: &Path, dir: &str, file: &str, contents: &[u8]) -> CmdResult<()> {
let mut path = root.to_path_buf();
path.push(dir);
path.push(file);
write_file(path, contents)?;
Ok(())
}

pub fn new() -> CmdResult {
pub fn new() -> CmdResult<()> {
let Opts { command: New { path } } = options() else {
panic!("")
panic!()
};

// run cargo to setup project
Expand Down
72 changes: 58 additions & 14 deletions tools/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,74 @@ pub enum Command {

/// Run a Nexus binary
Run {
/// Name of the binary to run
/// Print instruction trace
#[arg(short)]
verbose: bool,

/// Use release mode artifacts
#[arg(short, long)]
release: bool,

/// Name of the bin target to run
#[arg(long)]
bin: Option<String>,
},

/// Create a Nexus package
Package {},
/// Send program to Nexus prover network
Prove {
/// Use release mode artifacts
#[arg(short, long)]
release: bool,

/// Display information about a Nexus package file
Info {
/// Display more information (max:3)
#[arg(short, long, action = clap::ArgAction::Count)]
verbose: u8,
/// Name of the bin target to run
#[arg(long)]
bin: Option<String>,
},

/// Input file
#[arg(name = "Package File")]
/// Query status of a proof
Query {
/// Proof identifier
#[arg(long)]
hash: String,

/// File to save completed proof
#[arg(short, long, default_value = "nexus-proof.json")]
file: std::path::PathBuf,
},

/// Send Nexus package to prover network
Prove {},

/// Verify a Nexus proof
Verify {},
Verify {
/// public parameters file
#[arg(
short = 'p',
long = "public-params",
default_value = "nexus-public.zst"
)]
pp_file: String,

/// File containing completed proof
#[arg(short, long, default_value = "nexus-proof.json")]
file: std::path::PathBuf,
},

/// Run a Nexus proof locally
LocalProve {
/// public parameters file
#[arg(
short = 'p',
long = "public-params",
default_value = "nexus-public.zst"
)]
pp_file: String,

/// Use release mode artifacts
#[arg(short, long)]
release: bool,

/// Name of the bin target to run
#[arg(long)]
bin: Option<String>,
},

/// Export proof artifacts
Export {
Expand Down
87 changes: 87 additions & 0 deletions tools/src/prove.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use std::io::BufReader;
use std::fs::File;

use nexus_riscv::VMOpts;
use nexus_prover::{pp::gen_or_load, run, prove_par};
use nexus_network::pcd::{decode, NexusMsg::PCDRes};
use nexus_network::api::Proof;
use nexus_network::client::*;

use crate::*;

pub fn prove() -> CmdResult<()> {
let Opts { command: Prove { release, bin } } = options() else {
panic!()
};
let t = get_target(*release, bin)?;
let proof = submit_proof("account".to_string(), &t)?;

println!("{} submitted", proof.hash);

Ok(())
}

pub fn query() -> CmdResult<()> {
let Opts { command: Query { hash, file } } = options() else {
panic!()
};

let proof = fetch_proof(hash)?;

if proof.total_nodes > proof.complete_nodes {
let pct = (proof.complete_nodes as f32) / (proof.total_nodes as f32);
println!("{} {:.2}% complete", proof.hash, pct);
} else {
println!("{} 100% complete, saving...", proof.hash);
let vec = serde_json::to_vec(&proof)?;
write_file(file.clone(), &vec)?;
}

Ok(())
}

pub fn verify() -> CmdResult<()> {
let Opts { command: Verify { pp_file, file } } = options() else {
panic!()
};

let file = File::open(file)?;
let reader = BufReader::new(file);
let proof: Proof = serde_json::from_reader(reader)?;

let Some(vec) = proof.proof else {
return Err("invalid proof object".into());
};

let PCDRes(node) = decode(&vec)? else {
return Err("invalid proof object".into());
};

let state = gen_or_load(false, 1, pp_file)?;

match node.verify(&state) {
Ok(_) => println!("{} verified", proof.hash),
Err(_) => println!("{} NOT verified", proof.hash),
}
Ok(())
}

pub fn local() -> CmdResult<()> {
let Opts {
command: LocalProve { pp_file, release, bin },
} = options()
else {
panic!()
};
let t = get_target(*release, bin)?;
let opts = VMOpts {
k: 1,
nop: None,
loopk: None,
file: Some(t),
};
let trace = run(&opts, true)?;
let state = gen_or_load(false, 1, pp_file)?;
prove_par(state, trace)?;
Ok(())
}
19 changes: 19 additions & 0 deletions tools/src/run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use nexus_riscv::*;

use crate::*;

pub fn run() -> CmdResult<()> {
let Opts { command: Run { verbose, release, bin } } = options() else {
panic!()
};
let t = get_target(*release, bin)?;

let opts = VMOpts {
k: 1,
nop: None,
loopk: None,
file: Some(t),
};

Ok(run_vm(&opts, *verbose)?)
}
Loading

0 comments on commit a102584

Please sign in to comment.