mirror of
https://github.com/eth-act/ere.git
synced 2026-02-19 11:54:42 -05:00
Add crate test-utils (#82)
This commit is contained in:
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -2276,6 +2276,7 @@ dependencies = [
|
||||
"risc0-zkvm",
|
||||
"serde",
|
||||
"tempfile",
|
||||
"test-utils",
|
||||
"thiserror 2.0.12",
|
||||
"zkvm-interface",
|
||||
]
|
||||
@@ -2367,6 +2368,7 @@ dependencies = [
|
||||
"build-utils",
|
||||
"sp1-sdk",
|
||||
"tempfile",
|
||||
"test-utils",
|
||||
"thiserror 2.0.12",
|
||||
"toml",
|
||||
"tracing",
|
||||
@@ -9410,6 +9412,14 @@ dependencies = [
|
||||
"test-case-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test-utils"
|
||||
version = "0.0.11"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"zkvm-interface",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"crates/build-utils",
|
||||
"crates/test-utils",
|
||||
# zkVMs
|
||||
"crates/ere-jolt",
|
||||
"crates/ere-nexus",
|
||||
@@ -77,6 +78,7 @@ sp1-sdk = "5.1.0"
|
||||
# Local dependencies
|
||||
zkvm-interface = { path = "crates/zkvm-interface" }
|
||||
build-utils = { path = "crates/build-utils" }
|
||||
test-utils = { path = "crates/test-utils" }
|
||||
ere-cli = { path = "crates/ere-cli", default-features = false }
|
||||
ere-dockerized = { path = "crates/ere-dockerized" }
|
||||
ere-jolt = { path = "crates/ere-jolt" }
|
||||
|
||||
@@ -20,6 +20,7 @@ zkvm-interface = { workspace = true, features = ["clap"] }
|
||||
ere-cli.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
test-utils = { workspace = true, features = ["host"] }
|
||||
|
||||
[build-dependencies]
|
||||
build-utils.workspace = true
|
||||
|
||||
@@ -453,6 +453,9 @@ fn workspace_dir() -> PathBuf {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{EreDockerizedCompiler, EreDockerizedzkVM, ErezkVM, workspace_dir};
|
||||
use test_utils::host::{
|
||||
BasicProgramInputGen, run_zkvm_execute, run_zkvm_prove, testing_guest_directory,
|
||||
};
|
||||
use zkvm_interface::{Compiler, Input, ProverResourceType, zkVM};
|
||||
|
||||
// TODO: Test other ere-{zkvm} when they are end-to-end ready:
|
||||
@@ -506,22 +509,16 @@ mod test {
|
||||
fn dockerized_sp1() {
|
||||
let zkvm = ErezkVM::SP1;
|
||||
|
||||
let guest_directory = workspace_dir().join(format!("tests/{zkvm}/prove/basic"));
|
||||
let guest_directory = testing_guest_directory(zkvm.as_str(), "basic");
|
||||
let program = EreDockerizedCompiler::new(zkvm, workspace_dir())
|
||||
.compile(&guest_directory)
|
||||
.unwrap();
|
||||
|
||||
let zkvm = EreDockerizedzkVM::new(zkvm, program, ProverResourceType::Cpu).unwrap();
|
||||
|
||||
let mut inputs = Input::new();
|
||||
inputs.write(42u32);
|
||||
inputs.write(42u16);
|
||||
|
||||
let _report = zkvm.execute(&inputs).unwrap();
|
||||
|
||||
let (proof, _report) = zkvm.prove(&inputs).unwrap();
|
||||
|
||||
zkvm.verify(&proof).unwrap();
|
||||
let inputs = BasicProgramInputGen::valid();
|
||||
run_zkvm_execute(&zkvm, &inputs);
|
||||
run_zkvm_prove(&zkvm, &inputs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[package]
|
||||
name = "ere-sp1"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
name = "ere-sp1"
|
||||
rust-version.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
bincode.workspace = true
|
||||
@@ -18,5 +18,8 @@ sp1-sdk.workspace = true
|
||||
# Local dependencies
|
||||
zkvm-interface.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
test-utils = { workspace = true, features = ["host"] }
|
||||
|
||||
[build-dependencies]
|
||||
build-utils.workspace = true
|
||||
|
||||
@@ -95,50 +95,14 @@ pub fn compile(guest_directory: &Path) -> Result<Vec<u8>, CompileError> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::RV32_IM_SUCCINCT_ZKVM_ELF;
|
||||
use test_utils::host::testing_guest_directory;
|
||||
use zkvm_interface::Compiler;
|
||||
|
||||
use crate::RV32_IM_SUCCINCT_ZKVM_ELF;
|
||||
|
||||
use super::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
// TODO: for now, we just get one test file
|
||||
// TODO: but this should get the whole directory and compile each test
|
||||
fn get_compile_test_guest_program_path() -> PathBuf {
|
||||
let workspace_dir = env!("CARGO_WORKSPACE_DIR");
|
||||
PathBuf::from(workspace_dir)
|
||||
.join("tests")
|
||||
.join("sp1")
|
||||
.join("compile")
|
||||
.join("basic")
|
||||
.canonicalize()
|
||||
.expect("Failed to find or canonicalize test guest program at <CARGO_WORKSPACE_DIR>/tests/compile/sp1")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compile_sp1_program() {
|
||||
let test_guest_path = get_compile_test_guest_program_path();
|
||||
|
||||
match compile(&test_guest_path) {
|
||||
Ok(elf_bytes) => {
|
||||
assert!(!elf_bytes.is_empty(), "ELF bytes should not be empty.");
|
||||
}
|
||||
Err(err) => {
|
||||
panic!("compile failed for dedicated guest: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compile_trait() {
|
||||
let test_guest_path = get_compile_test_guest_program_path();
|
||||
match RV32_IM_SUCCINCT_ZKVM_ELF.compile(&test_guest_path) {
|
||||
Ok(elf_bytes) => {
|
||||
assert!(!elf_bytes.is_empty(), "ELF bytes should not be empty.");
|
||||
}
|
||||
Err(err) => {
|
||||
panic!("compile_sp1_program direct call failed for dedicated guest: {err}");
|
||||
}
|
||||
}
|
||||
fn test_compiler_impl() {
|
||||
let guest_directory = testing_guest_directory("sp1", "basic");
|
||||
let elf_bytes = RV32_IM_SUCCINCT_ZKVM_ELF.compile(&guest_directory).unwrap();
|
||||
assert!(!elf_bytes.is_empty(), "ELF bytes should not be empty.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,127 +225,74 @@ fn serialize_inputs(stdin: &mut SP1Stdin, inputs: &Input) {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod execute_tests {
|
||||
use std::path::PathBuf;
|
||||
|
||||
mod tests {
|
||||
use super::*;
|
||||
use zkvm_interface::Input;
|
||||
use std::{panic, sync::OnceLock};
|
||||
use test_utils::host::{
|
||||
BasicProgramInputGen, run_zkvm_execute, run_zkvm_prove, testing_guest_directory,
|
||||
};
|
||||
|
||||
fn get_compiled_test_sp1_elf() -> Result<Vec<u8>, SP1Error> {
|
||||
let test_guest_path = get_execute_test_guest_program_path();
|
||||
RV32_IM_SUCCINCT_ZKVM_ELF.compile(&test_guest_path)
|
||||
}
|
||||
static BASIC_PRORGAM: OnceLock<Vec<u8>> = OnceLock::new();
|
||||
|
||||
fn get_execute_test_guest_program_path() -> PathBuf {
|
||||
let workspace_dir = env!("CARGO_WORKSPACE_DIR");
|
||||
PathBuf::from(workspace_dir)
|
||||
.join("tests")
|
||||
.join("sp1")
|
||||
.join("execute")
|
||||
.join("basic")
|
||||
.canonicalize()
|
||||
.expect("Failed to find or canonicalize test guest program at <CARGO_WORKSPACE_DIR>/tests/execute/sp1")
|
||||
fn basic_program() -> Vec<u8> {
|
||||
BASIC_PRORGAM
|
||||
.get_or_init(|| {
|
||||
RV32_IM_SUCCINCT_ZKVM_ELF
|
||||
.compile(&testing_guest_directory("sp1", "basic"))
|
||||
.unwrap()
|
||||
})
|
||||
.to_vec()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_execute_sp1_dummy_input() {
|
||||
let elf_bytes = get_compiled_test_sp1_elf()
|
||||
.expect("Failed to compile test SP1 guest for execution test");
|
||||
fn test_execute() {
|
||||
let program = basic_program();
|
||||
let zkvm = EreSP1::new(program, ProverResourceType::Cpu);
|
||||
|
||||
let mut input_builder = Input::new();
|
||||
let n: u32 = 42;
|
||||
let a: u16 = 42;
|
||||
input_builder.write(n);
|
||||
input_builder.write(a);
|
||||
let inputs = BasicProgramInputGen::valid();
|
||||
run_zkvm_execute(&zkvm, &inputs);
|
||||
}
|
||||
|
||||
let zkvm = EreSP1::new(elf_bytes, ProverResourceType::Cpu);
|
||||
#[test]
|
||||
fn test_execute_invalid_inputs() {
|
||||
let program = basic_program();
|
||||
let zkvm = EreSP1::new(program, ProverResourceType::Cpu);
|
||||
|
||||
let result = zkvm.execute(&input_builder);
|
||||
|
||||
if let Err(err) = &result {
|
||||
panic!("Execution error: {err}");
|
||||
for inputs in [
|
||||
BasicProgramInputGen::empty(),
|
||||
BasicProgramInputGen::invalid_string(),
|
||||
BasicProgramInputGen::invalid_type(),
|
||||
] {
|
||||
zkvm.execute(&inputs).unwrap_err();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_execute_sp1_no_input_for_guest_expecting_input() {
|
||||
let elf_bytes = get_compiled_test_sp1_elf()
|
||||
.expect("Failed to compile test SP1 guest for execution test");
|
||||
fn test_prove() {
|
||||
let program = basic_program();
|
||||
let zkvm = EreSP1::new(program, ProverResourceType::Cpu);
|
||||
|
||||
let empty_input = Input::new();
|
||||
|
||||
let zkvm = EreSP1::new(elf_bytes, ProverResourceType::Cpu);
|
||||
let result = zkvm.execute(&empty_input);
|
||||
|
||||
assert!(
|
||||
result.is_err(),
|
||||
"execute should fail if guest expects input but none is provided."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod prove_tests {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::*;
|
||||
use zkvm_interface::Input;
|
||||
|
||||
fn get_prove_test_guest_program_path() -> PathBuf {
|
||||
let workspace_dir = env!("CARGO_WORKSPACE_DIR");
|
||||
PathBuf::from(workspace_dir)
|
||||
.join("tests")
|
||||
.join("sp1")
|
||||
.join("prove")
|
||||
.join("basic")
|
||||
.canonicalize()
|
||||
.expect("Failed to find or canonicalize test guest program at <CARGO_WORKSPACE_DIR>/tests/execute/sp1")
|
||||
}
|
||||
|
||||
fn get_compiled_test_sp1_elf_for_prove() -> Result<Vec<u8>, SP1Error> {
|
||||
let test_guest_path = get_prove_test_guest_program_path();
|
||||
RV32_IM_SUCCINCT_ZKVM_ELF.compile(&test_guest_path)
|
||||
let inputs = BasicProgramInputGen::valid();
|
||||
run_zkvm_prove(&zkvm, &inputs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prove_sp1_dummy_input() {
|
||||
let elf_bytes = get_compiled_test_sp1_elf_for_prove()
|
||||
.expect("Failed to compile test SP1 guest for proving test");
|
||||
fn test_prove_invalid_inputs() {
|
||||
let program = basic_program();
|
||||
let zkvm = EreSP1::new(program, ProverResourceType::Cpu);
|
||||
|
||||
let mut input_builder = Input::new();
|
||||
let n: u32 = 42;
|
||||
let a: u16 = 42;
|
||||
input_builder.write(n);
|
||||
input_builder.write(a);
|
||||
|
||||
let zkvm = EreSP1::new(elf_bytes, ProverResourceType::Cpu);
|
||||
|
||||
let proof_bytes = match zkvm.prove(&input_builder) {
|
||||
Ok((prove_result, _)) => prove_result,
|
||||
Err(err) => {
|
||||
panic!("Proving error in test: {err}");
|
||||
}
|
||||
};
|
||||
|
||||
assert!(!proof_bytes.is_empty(), "Proof bytes should not be empty.");
|
||||
|
||||
let verify_results = zkvm.verify(&proof_bytes).is_ok();
|
||||
assert!(verify_results);
|
||||
|
||||
// TODO: Check public inputs
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_prove_sp1_fails_on_bad_input_causing_execution_failure() {
|
||||
let elf_bytes = get_compiled_test_sp1_elf_for_prove()
|
||||
.expect("Failed to compile test SP1 guest for proving test");
|
||||
|
||||
let empty_input = Input::new();
|
||||
|
||||
let zkvm = EreSP1::new(elf_bytes, ProverResourceType::Cpu);
|
||||
let prove_result = zkvm.prove(&empty_input);
|
||||
assert!(prove_result.is_err())
|
||||
// On invalid inputs SP1 prove will panics, the issue for tracking:
|
||||
// https://github.com/eth-act/ere/issues/16.
|
||||
//
|
||||
// Note that we iterate on methods because `InputItem::Object` doesn't
|
||||
// implement `RefUnwindSafe`.
|
||||
for inputs_gen in [
|
||||
BasicProgramInputGen::empty,
|
||||
BasicProgramInputGen::invalid_string,
|
||||
BasicProgramInputGen::invalid_type,
|
||||
] {
|
||||
panic::catch_unwind(|| zkvm.prove(&inputs_gen())).unwrap_err();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -357,42 +304,15 @@ mod prove_tests {
|
||||
return;
|
||||
}
|
||||
|
||||
let elf_bytes = get_compiled_test_sp1_elf_for_prove()
|
||||
.expect("Failed to compile test SP1 guest for proving test");
|
||||
|
||||
let mut input_builder = Input::new();
|
||||
let n: u32 = 42;
|
||||
let a: u16 = 42;
|
||||
input_builder.write(n);
|
||||
input_builder.write(a);
|
||||
|
||||
// Create a network prover configuration
|
||||
let network_config = NetworkProverConfig {
|
||||
endpoint: std::env::var("NETWORK_RPC_URL").unwrap_or_default(),
|
||||
api_key: std::env::var("NETWORK_PRIVATE_KEY").ok(),
|
||||
};
|
||||
let program = basic_program();
|
||||
let zkvm = EreSP1::new(program, ProverResourceType::Network(network_config));
|
||||
|
||||
let zkvm = EreSP1::new(elf_bytes, ProverResourceType::Network(network_config));
|
||||
|
||||
// Execute first to ensure the program works
|
||||
let exec_result = zkvm.execute(&input_builder);
|
||||
assert!(exec_result.is_ok(), "Execution should succeed");
|
||||
|
||||
// Now prove using the network
|
||||
let proof_bytes = match zkvm.prove(&input_builder) {
|
||||
Ok((prove_result, report)) => {
|
||||
println!("Network proving completed in {:?}", report.proving_time);
|
||||
prove_result
|
||||
}
|
||||
Err(err) => {
|
||||
panic!("Network proving error: {err}");
|
||||
}
|
||||
};
|
||||
|
||||
assert!(!proof_bytes.is_empty(), "Proof bytes should not be empty.");
|
||||
|
||||
// Verify the proof
|
||||
let verify_result = zkvm.verify(&proof_bytes);
|
||||
assert!(verify_result.is_ok(), "Verification should succeed");
|
||||
let inputs = BasicProgramInputGen::valid();
|
||||
run_zkvm_prove(&zkvm, &inputs);
|
||||
}
|
||||
}
|
||||
|
||||
19
crates/test-utils/Cargo.toml
Normal file
19
crates/test-utils/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "test-utils"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
|
||||
# Local dependencies
|
||||
zkvm-interface = { workspace = true, optional = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
host = ["dep:zkvm-interface"]
|
||||
28
crates/test-utils/src/guest.rs
Normal file
28
crates/test-utils/src/guest.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use alloc::vec::Vec;
|
||||
use core::iter;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct BasicStruct {
|
||||
pub a: u8,
|
||||
pub b: u16,
|
||||
pub c: u32,
|
||||
pub d: u64,
|
||||
pub e: Vec<u8>,
|
||||
}
|
||||
|
||||
impl BasicStruct {
|
||||
/// Performs some computation (Xoring all fields as bytes into `[u8; 32]`).
|
||||
pub fn output(&self) -> [u8; 32] {
|
||||
let mut output = [0; 32];
|
||||
iter::empty()
|
||||
.chain(self.a.to_le_bytes())
|
||||
.chain(self.b.to_le_bytes())
|
||||
.chain(self.c.to_le_bytes())
|
||||
.chain(self.d.to_le_bytes())
|
||||
.chain(self.e.iter().copied())
|
||||
.enumerate()
|
||||
.for_each(|(idx, byte)| output[idx % output.len()] ^= byte);
|
||||
output
|
||||
}
|
||||
}
|
||||
73
crates/test-utils/src/host.rs
Normal file
73
crates/test-utils/src/host.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use crate::guest::BasicStruct;
|
||||
use std::path::PathBuf;
|
||||
use zkvm_interface::{Input, zkVM};
|
||||
|
||||
fn workspace() -> PathBuf {
|
||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
path.pop();
|
||||
path.pop();
|
||||
path
|
||||
}
|
||||
|
||||
pub fn testing_guest_directory(zkvm_name: &str, program: &str) -> PathBuf {
|
||||
workspace().join("tests").join(zkvm_name).join(program)
|
||||
}
|
||||
|
||||
pub fn run_zkvm_execute(zkvm: &impl zkVM, inputs: &Input) {
|
||||
let _report = zkvm
|
||||
.execute(inputs)
|
||||
.expect("execute should not fail with valid input");
|
||||
|
||||
// TODO: Check output are expected.
|
||||
}
|
||||
|
||||
pub fn run_zkvm_prove(zkvm: &impl zkVM, inputs: &Input) {
|
||||
let (proof, _report) = zkvm
|
||||
.prove(inputs)
|
||||
.expect("prove should not fail with valid input");
|
||||
|
||||
zkvm.verify(&proof)
|
||||
.expect("verify should not fail with valid input");
|
||||
|
||||
// TODO: Check output are expected.
|
||||
}
|
||||
|
||||
/// The basic program takes 2 inputs:
|
||||
/// - `Vec<u8>` that supposed to be "Hello world"
|
||||
/// - `BasicStruct`
|
||||
///
|
||||
/// Outputs `[u8; 32]` which computed by xoring fields of `BasicStruct`.
|
||||
pub struct BasicProgramInputGen;
|
||||
|
||||
impl BasicProgramInputGen {
|
||||
pub fn valid() -> Input {
|
||||
let mut inputs = Input::new();
|
||||
inputs.write_bytes("Hello world".as_bytes().to_vec());
|
||||
inputs.write(BasicStruct {
|
||||
a: 0xff,
|
||||
b: 0x7777,
|
||||
c: 0xffffffff,
|
||||
d: 0x7777777777777777,
|
||||
e: (0..u8::MAX).collect(),
|
||||
});
|
||||
inputs
|
||||
}
|
||||
|
||||
pub fn invalid_string() -> Input {
|
||||
let mut inputs = Input::new();
|
||||
inputs.write_bytes("Unexpected string".as_bytes().to_vec());
|
||||
inputs.write(BasicStruct::default());
|
||||
inputs
|
||||
}
|
||||
|
||||
pub fn invalid_type() -> Input {
|
||||
let mut inputs = Input::new();
|
||||
inputs.write(BasicStruct::default());
|
||||
inputs.write_bytes("Hello world".as_bytes().to_vec());
|
||||
inputs
|
||||
}
|
||||
|
||||
pub fn empty() -> Input {
|
||||
Input::new()
|
||||
}
|
||||
}
|
||||
8
crates/test-utils/src/lib.rs
Normal file
8
crates/test-utils/src/lib.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
#![cfg_attr(not(feature = "host"), no_std)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
pub mod guest;
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
pub mod host;
|
||||
@@ -7,3 +7,4 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
sp1-zkvm = "5.1.0"
|
||||
test-utils = { path = "../../../crates/test-utils" }
|
||||
18
tests/sp1/basic/src/main.rs
Normal file
18
tests/sp1/basic/src/main.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
#![no_main]
|
||||
|
||||
use test_utils::guest::BasicStruct;
|
||||
|
||||
sp1_zkvm::entrypoint!(main);
|
||||
|
||||
pub fn main() {
|
||||
// Read `Hello world` bytes.
|
||||
let bytes = sp1_zkvm::io::read_vec();
|
||||
assert_eq!(String::from_utf8_lossy(&bytes), "Hello world");
|
||||
|
||||
// Read `BasicStruct`.
|
||||
let basic_struct = sp1_zkvm::io::read::<BasicStruct>();
|
||||
let output = basic_struct.output();
|
||||
|
||||
// Write `output`
|
||||
sp1_zkvm::io::commit(&output);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#![no_main]
|
||||
|
||||
sp1_zkvm::entrypoint!(main);
|
||||
|
||||
pub fn main() {
|
||||
// Read an input
|
||||
let n = sp1_zkvm::io::read::<u32>();
|
||||
// Write n*2 to output
|
||||
sp1_zkvm::io::commit(&(n * 2));
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
[package]
|
||||
name = "ere-test-sp1-guest"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
sp1-zkvm = "5.1.0"
|
||||
@@ -1,10 +0,0 @@
|
||||
#![no_main]
|
||||
|
||||
sp1_zkvm::entrypoint!(main);
|
||||
pub fn main() {
|
||||
// Read an input
|
||||
let n = sp1_zkvm::io::read::<u32>();
|
||||
let a = sp1_zkvm::io::read::<u16>() as u32;
|
||||
|
||||
sp1_zkvm::io::commit(&((n + a) * 2));
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
[package]
|
||||
name = "ere-test-sp1-guest"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
sp1-zkvm = "5.1.0"
|
||||
@@ -1,10 +0,0 @@
|
||||
#![no_main]
|
||||
|
||||
sp1_zkvm::entrypoint!(main);
|
||||
pub fn main() {
|
||||
// Read an input
|
||||
let n = sp1_zkvm::io::read::<u32>();
|
||||
let a = sp1_zkvm::io::read::<u16>() as u32;
|
||||
|
||||
sp1_zkvm::io::commit(&((n + a) * 2));
|
||||
}
|
||||
Reference in New Issue
Block a user