mirror of
https://github.com/eth-act/ere.git
synced 2026-04-03 03:00:17 -04:00
Upgrade openvm (#98)
This commit is contained in:
2
.github/workflows/test-zkvm-jolt.yml
vendored
2
.github/workflows/test-zkvm-jolt.yml
vendored
@@ -14,6 +14,6 @@ jobs:
|
||||
packages: write
|
||||
with:
|
||||
zkvm: jolt
|
||||
toolchain: 1.85.0
|
||||
toolchain: 1.86.0
|
||||
test_ere_dockerized: false
|
||||
test_options: ''
|
||||
|
||||
2
.github/workflows/test-zkvm-openvm.yml
vendored
2
.github/workflows/test-zkvm-openvm.yml
vendored
@@ -14,6 +14,6 @@ jobs:
|
||||
packages: write
|
||||
with:
|
||||
zkvm: openvm
|
||||
toolchain: 1.85.0
|
||||
toolchain: 1.86.0
|
||||
test_ere_dockerized: true
|
||||
test_options: ''
|
||||
|
||||
2
.github/workflows/test-zkvm-risc0.yml
vendored
2
.github/workflows/test-zkvm-risc0.yml
vendored
@@ -14,6 +14,6 @@ jobs:
|
||||
packages: write
|
||||
with:
|
||||
zkvm: risc0
|
||||
toolchain: 1.85.0
|
||||
toolchain: 1.86.0
|
||||
test_ere_dockerized: true
|
||||
test_options: ''
|
||||
|
||||
2
.github/workflows/test-zkvm-sp1.yml
vendored
2
.github/workflows/test-zkvm-sp1.yml
vendored
@@ -14,6 +14,6 @@ jobs:
|
||||
packages: write
|
||||
with:
|
||||
zkvm: sp1
|
||||
toolchain: 1.85.0
|
||||
toolchain: 1.86.0
|
||||
test_ere_dockerized: true
|
||||
test_options: ''
|
||||
|
||||
2
.github/workflows/test-zkvm-zisk.yml
vendored
2
.github/workflows/test-zkvm-zisk.yml
vendored
@@ -14,6 +14,6 @@ jobs:
|
||||
packages: write
|
||||
with:
|
||||
zkvm: zisk
|
||||
toolchain: 1.85.0
|
||||
toolchain: 1.86.0
|
||||
test_ere_dockerized: false
|
||||
test_options: 'execute compile'
|
||||
|
||||
2
.github/workflows/test-zkvm.yml
vendored
2
.github/workflows/test-zkvm.yml
vendored
@@ -11,7 +11,7 @@ on:
|
||||
description: 'Rust toolchain to use'
|
||||
required: false
|
||||
type: string
|
||||
default: 1.85.0
|
||||
default: 1.86.0
|
||||
test_ere_dockerized:
|
||||
description: 'Whether test ere-dockerized with the selected zkVM or not'
|
||||
required: false
|
||||
|
||||
476
Cargo.lock
generated
476
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
11
Cargo.toml
11
Cargo.toml
@@ -58,11 +58,12 @@ jolt-sdk = { git = "https://github.com/a16z/jolt.git", rev = "55b9830a3944dde55d
|
||||
nexus-sdk = { git = "https://github.com/nexus-xyz/nexus-zkvm.git", tag = "v0.3.4" }
|
||||
|
||||
# OpenVM dependencies
|
||||
openvm-build = { git = "https://github.com/openvm-org/openvm.git", tag = "v1.2.0", default-features = false }
|
||||
openvm-circuit = { git = "https://github.com/openvm-org/openvm.git", tag = "v1.2.0", default-features = false }
|
||||
openvm-sdk = { git = "https://github.com/openvm-org/openvm.git", tag = "v1.2.0", default-features = false }
|
||||
openvm-stark-sdk = { git = "https://github.com/openvm-org/stark-backend.git", tag = "v1.1.0" }
|
||||
openvm-transpiler = { git = "https://github.com/openvm-org/openvm.git", tag = "v1.2.0", default-features = false }
|
||||
openvm-build = { git = "https://github.com/openvm-org/openvm.git", tag = "v1.4.0-rc.4", default-features = false }
|
||||
openvm-circuit = { git = "https://github.com/openvm-org/openvm.git", tag = "v1.4.0-rc.4", default-features = false }
|
||||
openvm-continuations = { git = "https://github.com/openvm-org/openvm.git", tag = "v1.4.0-rc.4", default-features = false }
|
||||
openvm-sdk = { git = "https://github.com/openvm-org/openvm.git", tag = "v1.4.0-rc.4", default-features = false }
|
||||
openvm-stark-sdk = { git = "https://github.com/openvm-org/stark-backend.git", tag = "v1.2.0-rc.1" }
|
||||
openvm-transpiler = { git = "https://github.com/openvm-org/openvm.git", tag = "v1.4.0-rc.4", default-features = false }
|
||||
|
||||
# Pico dependencies
|
||||
pico-vm = { git = "https://github.com/brevis-network/pico.git", tag = "v1.1.4" }
|
||||
|
||||
@@ -13,6 +13,7 @@ toml.workspace = true
|
||||
# OpenVM dependencies
|
||||
openvm-build.workspace = true
|
||||
openvm-circuit.workspace = true
|
||||
openvm-continuations.workspace = true
|
||||
openvm-sdk.workspace = true
|
||||
openvm-stark-sdk.workspace = true
|
||||
openvm-transpiler.workspace = true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use openvm_sdk::{SdkError, commit::AppExecutionCommit};
|
||||
use std::{io, path::PathBuf};
|
||||
use thiserror::Error;
|
||||
use zkvm_interface::zkVMError;
|
||||
@@ -8,6 +9,12 @@ impl From<OpenVMError> for zkVMError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CommonError> for zkVMError {
|
||||
fn from(value: CommonError) -> Self {
|
||||
zkVMError::Other(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum OpenVMError {
|
||||
#[error(transparent)]
|
||||
@@ -36,27 +43,50 @@ pub enum CompileError {
|
||||
#[error("Failed to read OpenVM's config file at {path}: {source}")]
|
||||
ReadConfigFailed { source: io::Error, path: PathBuf },
|
||||
#[error("Failed to deserialize OpenVM's config file: {0}")]
|
||||
DeserializeConfigFailed(Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
#[error("Failed to decode elf: {0}")]
|
||||
DecodeFailed(Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
#[error("Failed to transpile elf: {0}")]
|
||||
TranspileFailed(Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
DeserializeConfigFailed(toml::de::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ExecuteError {
|
||||
#[error("OpenVM execute failed: {0}")]
|
||||
Client(#[source] Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
Execute(#[source] SdkError),
|
||||
#[error(transparent)]
|
||||
Common(#[from] CommonError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ProveError {
|
||||
#[error("OpenVM prove failed: {0}")]
|
||||
Client(#[source] Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
Prove(#[source] SdkError),
|
||||
#[error("Unexpected app commit: {proved:?}, expected: {preprocessed:?}")]
|
||||
UnexpectedAppCommit {
|
||||
preprocessed: AppExecutionCommit,
|
||||
proved: AppExecutionCommit,
|
||||
},
|
||||
#[error("Serialize proof failed: {0}")]
|
||||
SerializeProof(io::Error),
|
||||
#[error(transparent)]
|
||||
Common(#[from] CommonError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum VerifyError {
|
||||
#[error("OpenVM verification failed: {0}")]
|
||||
Client(#[source] Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
Verify(#[source] SdkError),
|
||||
#[error("Deserialize proof failed: {0}")]
|
||||
DeserializeProof(io::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CommonError {
|
||||
#[error("Initialize SDK failed: {0}")]
|
||||
SdkInit(SdkError),
|
||||
#[error("Decode elf failed: {0}")]
|
||||
ElfDecode(Box<dyn std::error::Error + Send + Sync + 'static>),
|
||||
#[error("Transpile elf failed: {0}")]
|
||||
Transpile(SdkError),
|
||||
#[error("Agg keygen failed: {0}")]
|
||||
AggKeyGen(SdkError),
|
||||
#[error("Initialize prover failed: {0}")]
|
||||
ProverInit(SdkError),
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
|
||||
|
||||
use crate::error::{CompileError, ExecuteError, OpenVMError, VerifyError};
|
||||
use crate::error::{CommonError, CompileError, ExecuteError, OpenVMError, ProveError, VerifyError};
|
||||
use openvm_build::GuestOptions;
|
||||
use openvm_circuit::{
|
||||
arch::{ContinuationVmProof, instructions::exe::VmExe},
|
||||
system::program::trace::VmCommittedExe,
|
||||
};
|
||||
use openvm_circuit::arch::instructions::exe::VmExe;
|
||||
use openvm_continuations::verifier::internal::types::VmStarkProof;
|
||||
use openvm_sdk::{
|
||||
F, SC, Sdk, StdIn,
|
||||
codec::{Decode, Encode},
|
||||
commit::AppExecutionCommit,
|
||||
config::{AppConfig, DEFAULT_APP_LOG_BLOWUP, DEFAULT_LEAF_LOG_BLOWUP, SdkVmConfig},
|
||||
keygen::AppProvingKey,
|
||||
keygen::AggVerifyingKey,
|
||||
};
|
||||
use openvm_stark_sdk::config::FriParameters;
|
||||
use openvm_transpiler::{elf::Elf, openvm_platform::memory::MEM_SIZE};
|
||||
@@ -44,8 +43,8 @@ impl Compiler for OPENVM_TARGET {
|
||||
let guest_opts = GuestOptions::default().with_profile("release".to_string());
|
||||
let target_dir = match openvm_build::build_guest_package(&pkg, &guest_opts, None, &None) {
|
||||
Ok(target_dir) => target_dir,
|
||||
Err(Some(code)) => return Err(CompileError::BuildFailed(code).into()),
|
||||
Err(None) => return Err(CompileError::BuildSkipped.into()),
|
||||
Err(Some(code)) => return Err(CompileError::BuildFailed(code))?,
|
||||
Err(None) => return Err(CompileError::BuildSkipped)?,
|
||||
};
|
||||
|
||||
let elf_path = openvm_build::find_unique_executable(guest_directory, target_dir, &None)
|
||||
@@ -63,8 +62,7 @@ impl Compiler for OPENVM_TARGET {
|
||||
path: app_config_path.to_path_buf(),
|
||||
}
|
||||
})?;
|
||||
toml::from_str(&toml)
|
||||
.map_err(|err| CompileError::DeserializeConfigFailed(err.into()))?
|
||||
toml::from_str(&toml).map_err(CompileError::DeserializeConfigFailed)?
|
||||
} else {
|
||||
// The default `AppConfig` copied from https://github.com/openvm-org/openvm/blob/ca36de3/crates/cli/src/default.rs#L31.
|
||||
AppConfig {
|
||||
@@ -93,56 +91,55 @@ impl Compiler for OPENVM_TARGET {
|
||||
|
||||
pub struct EreOpenVM {
|
||||
app_config: AppConfig<SdkVmConfig>,
|
||||
app_exe: VmExe<F>,
|
||||
app_committed_exe: Arc<VmCommittedExe<SC>>,
|
||||
app_pk: Arc<AppProvingKey<SdkVmConfig>>,
|
||||
app_exe: Arc<VmExe<F>>,
|
||||
agg_vk: AggVerifyingKey,
|
||||
app_commit: AppExecutionCommit,
|
||||
_resource: ProverResourceType,
|
||||
}
|
||||
|
||||
impl EreOpenVM {
|
||||
pub fn new(program: OpenVMProgram, _resource: ProverResourceType) -> Result<Self, zkVMError> {
|
||||
let sdk = Sdk::new();
|
||||
let sdk = Sdk::new(program.app_config.clone()).map_err(CommonError::SdkInit)?;
|
||||
|
||||
let elf = Elf::decode(&program.elf, MEM_SIZE as u32)
|
||||
.map_err(|e| OpenVMError::from(CompileError::DecodeFailed(e.into())))?;
|
||||
.map_err(|e| CommonError::ElfDecode(e.into()))?;
|
||||
|
||||
let app_exe = sdk
|
||||
.transpile(elf, program.app_config.app_vm_config.transpiler())
|
||||
.map_err(|e| OpenVMError::from(CompileError::TranspileFailed(e.into())))?;
|
||||
let app_exe = sdk.convert_to_exe(elf).map_err(CommonError::Transpile)?;
|
||||
|
||||
let app_pk = sdk
|
||||
.app_keygen(program.app_config.clone())
|
||||
.map_err(|e| zkVMError::Other(e.into()))?;
|
||||
let (_, agg_vk) = sdk.agg_keygen().map_err(CommonError::AggKeyGen)?;
|
||||
|
||||
let app_committed_exe = sdk
|
||||
.commit_app_exe(app_pk.app_fri_params(), app_exe.clone())
|
||||
.map_err(|e| zkVMError::Other(e.into()))?;
|
||||
let app_commit = sdk
|
||||
.prover(app_exe.clone())
|
||||
.map_err(CommonError::ProverInit)?
|
||||
.app_commit();
|
||||
|
||||
Ok(Self {
|
||||
app_config: program.app_config,
|
||||
app_exe,
|
||||
app_committed_exe,
|
||||
app_pk: Arc::new(app_pk),
|
||||
agg_vk,
|
||||
app_commit,
|
||||
_resource,
|
||||
})
|
||||
}
|
||||
|
||||
fn sdk(&self) -> Result<Sdk, CommonError> {
|
||||
Sdk::new_without_transpiler(self.app_config.clone()).map_err(CommonError::SdkInit)
|
||||
}
|
||||
}
|
||||
|
||||
impl zkVM for EreOpenVM {
|
||||
fn execute(&self, inputs: &Input) -> Result<zkvm_interface::ProgramExecutionReport, zkVMError> {
|
||||
let sdk = Sdk::new();
|
||||
let sdk = self
|
||||
.sdk()
|
||||
.map_err(|e| OpenVMError::from(ExecuteError::from(e)))?;
|
||||
|
||||
let mut stdin = StdIn::default();
|
||||
serialize_inputs(&mut stdin, inputs);
|
||||
|
||||
let start = Instant::now();
|
||||
let _outputs = sdk
|
||||
.execute(
|
||||
self.app_exe.clone(),
|
||||
self.app_config.app_vm_config.clone(),
|
||||
stdin,
|
||||
)
|
||||
.map_err(|e| OpenVMError::from(ExecuteError::Client(e.into())))?;
|
||||
.execute(self.app_exe.clone(), stdin)
|
||||
.map_err(|e| OpenVMError::from(ExecuteError::Execute(e)))?;
|
||||
|
||||
Ok(ProgramExecutionReport {
|
||||
execution_duration: start.elapsed(),
|
||||
@@ -154,32 +151,41 @@ impl zkVM for EreOpenVM {
|
||||
&self,
|
||||
inputs: &Input,
|
||||
) -> Result<(Vec<u8>, zkvm_interface::ProgramProvingReport), zkVMError> {
|
||||
let sdk = Sdk::new();
|
||||
let sdk = self
|
||||
.sdk()
|
||||
.map_err(|e| OpenVMError::from(ProveError::from(e)))?;
|
||||
|
||||
let mut stdin = StdIn::default();
|
||||
serialize_inputs(&mut stdin, inputs);
|
||||
|
||||
let now = std::time::Instant::now();
|
||||
let proof = sdk
|
||||
.generate_app_proof(self.app_pk.clone(), self.app_committed_exe.clone(), stdin)
|
||||
.unwrap();
|
||||
let (proof, app_commit) = sdk
|
||||
.prove(self.app_exe.clone(), stdin)
|
||||
.map_err(|e| OpenVMError::from(ProveError::Prove(e)))?;
|
||||
let elapsed = now.elapsed();
|
||||
|
||||
let proof_bytes = proof.encode_to_vec().unwrap();
|
||||
if app_commit != self.app_commit {
|
||||
return Err(OpenVMError::from(ProveError::UnexpectedAppCommit {
|
||||
preprocessed: self.app_commit,
|
||||
proved: app_commit,
|
||||
}))?;
|
||||
}
|
||||
|
||||
let proof_bytes = proof
|
||||
.encode_to_vec()
|
||||
.map_err(|e| OpenVMError::from(ProveError::SerializeProof(e)))?;
|
||||
|
||||
Ok((proof_bytes, ProgramProvingReport::new(elapsed)))
|
||||
}
|
||||
|
||||
fn verify(&self, mut proof: &[u8]) -> Result<(), zkVMError> {
|
||||
let sdk = Sdk::new();
|
||||
let proof = VmStarkProof::<SC>::decode(&mut proof)
|
||||
.map_err(|e| OpenVMError::from(VerifyError::DeserializeProof(e)))?;
|
||||
|
||||
let proof = ContinuationVmProof::<SC>::decode(&mut proof).unwrap();
|
||||
Sdk::verify_proof(&self.agg_vk, self.app_commit, &proof)
|
||||
.map_err(|e| OpenVMError::Verify(VerifyError::Verify(e)))?;
|
||||
|
||||
let app_vk = self.app_pk.get_app_vk();
|
||||
sdk.verify_app_proof(&app_vk, &proof)
|
||||
.map(|_payload| ())
|
||||
.map_err(|e| OpenVMError::Verify(VerifyError::Client(e.into())))
|
||||
.map_err(zkVMError::from)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
@@ -205,15 +211,14 @@ fn serialize_inputs(stdin: &mut StdIn, inputs: &Input) {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::{panic, sync::OnceLock};
|
||||
use std::sync::OnceLock;
|
||||
use test_utils::host::{
|
||||
BasicProgramInputGen, run_zkvm_execute, run_zkvm_prove, testing_guest_directory,
|
||||
};
|
||||
|
||||
static BASIC_PRORGAM: OnceLock<OpenVMProgram> = OnceLock::new();
|
||||
|
||||
fn basic_program() -> OpenVMProgram {
|
||||
BASIC_PRORGAM
|
||||
static PROGRAM: OnceLock<OpenVMProgram> = OnceLock::new();
|
||||
PROGRAM
|
||||
.get_or_init(|| {
|
||||
OPENVM_TARGET
|
||||
.compile(&testing_guest_directory("openvm", "basic"))
|
||||
@@ -222,6 +227,11 @@ mod tests {
|
||||
.clone()
|
||||
}
|
||||
|
||||
fn basic_program_ere_openvm() -> &'static EreOpenVM {
|
||||
static ERE_OPENVM: OnceLock<EreOpenVM> = OnceLock::new();
|
||||
ERE_OPENVM.get_or_init(|| EreOpenVM::new(basic_program(), ProverResourceType::Cpu).unwrap())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compiler_impl() {
|
||||
let program = basic_program();
|
||||
@@ -230,8 +240,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_execute() {
|
||||
let program = basic_program();
|
||||
let zkvm = EreOpenVM::new(program, ProverResourceType::Cpu).unwrap();
|
||||
let zkvm = basic_program_ere_openvm();
|
||||
|
||||
let inputs = BasicProgramInputGen::valid();
|
||||
run_zkvm_execute(&zkvm, &inputs);
|
||||
@@ -239,8 +248,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_execute_invalid_inputs() {
|
||||
let program = basic_program();
|
||||
let zkvm = EreOpenVM::new(program, ProverResourceType::Cpu).unwrap();
|
||||
let zkvm = basic_program_ere_openvm();
|
||||
|
||||
for inputs in [
|
||||
BasicProgramInputGen::empty(),
|
||||
@@ -253,8 +261,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_prove() {
|
||||
let program = basic_program();
|
||||
let zkvm = EreOpenVM::new(program, ProverResourceType::Cpu).unwrap();
|
||||
let zkvm = basic_program_ere_openvm();
|
||||
|
||||
let inputs = BasicProgramInputGen::valid();
|
||||
run_zkvm_prove(&zkvm, &inputs);
|
||||
@@ -262,15 +269,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_prove_invalid_inputs() {
|
||||
let program = basic_program();
|
||||
let zkvm = EreOpenVM::new(program, ProverResourceType::Cpu).unwrap();
|
||||
let zkvm = basic_program_ere_openvm();
|
||||
|
||||
for inputs_gen in [
|
||||
BasicProgramInputGen::empty,
|
||||
BasicProgramInputGen::invalid_string,
|
||||
BasicProgramInputGen::invalid_type,
|
||||
for inputs in [
|
||||
BasicProgramInputGen::empty(),
|
||||
BasicProgramInputGen::invalid_string(),
|
||||
BasicProgramInputGen::invalid_type(),
|
||||
] {
|
||||
panic::catch_unwind(|| zkvm.prove(&inputs_gen()).unwrap_err()).unwrap_err();
|
||||
zkvm.prove(&inputs).unwrap_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ RUN apt-get update && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install rustup.
|
||||
# RUST_VERSION can be 1.85, stable, nightly, etc
|
||||
ARG RUST_VERSION=1.85.0
|
||||
# RUST_VERSION can be 1.86, stable, nightly, etc
|
||||
ARG RUST_VERSION=1.86.0
|
||||
|
||||
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
|
||||
@@ -14,11 +14,7 @@ RUN chmod +x /tmp/install_openvm_sdk.sh
|
||||
# and installs cargo-openvm.
|
||||
RUN /tmp/install_openvm_sdk.sh && rm /tmp/install_openvm_sdk.sh
|
||||
|
||||
# The specific Rust toolchain for OpenVM is now installed.
|
||||
# cargo-openvm is installed in $CARGO_HOME/bin, which is already in PATH from ere-base.
|
||||
ENV OPENVM_TOOLCHAIN_VERSION="nightly-2025-02-14"
|
||||
|
||||
# Verify cargo-openvm is accessible with the correct toolchain
|
||||
RUN cargo "+${OPENVM_TOOLCHAIN_VERSION}" openvm --version
|
||||
RUN cargo openvm --version
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
@@ -28,22 +28,16 @@ ensure_tool_installed "rustup" "to manage Rust toolchains"
|
||||
ensure_tool_installed "git" "to install cargo-openvm from a git repository"
|
||||
ensure_tool_installed "cargo" "to build and install Rust packages"
|
||||
|
||||
OPENVM_TOOLCHAIN_VERSION="nightly-2025-02-14"
|
||||
OPENVM_CLI_VERSION_TAG="v1.2.0"
|
||||
|
||||
# Install the specific nightly toolchain for OpenVM
|
||||
echo "Installing OpenVM-specific Rust toolchain: ${OPENVM_TOOLCHAIN_VERSION}..."
|
||||
rustup install "${OPENVM_TOOLCHAIN_VERSION}"
|
||||
rustup component add rust-src --toolchain "${OPENVM_TOOLCHAIN_VERSION}"
|
||||
OPENVM_CLI_VERSION_TAG="v1.4.0-rc.4"
|
||||
|
||||
# Install cargo-openvm using the specified toolchain and version tag
|
||||
echo "Installing cargo-openvm (version ${OPENVM_CLI_VERSION_TAG}) from GitHub repository (openvm-org/openvm)..."
|
||||
cargo "+${OPENVM_TOOLCHAIN_VERSION}" install --locked --git https://github.com/openvm-org/openvm.git --tag "${OPENVM_CLI_VERSION_TAG}" cargo-openvm
|
||||
cargo install --locked --git https://github.com/openvm-org/openvm.git --tag "${OPENVM_CLI_VERSION_TAG}" cargo-openvm
|
||||
|
||||
# Verify cargo-openvm installation
|
||||
echo "Verifying cargo-openvm installation..."
|
||||
# The cargo-openvm is installed as `cargo-openvm`, so it's invoked as `cargo openvm`
|
||||
if cargo "+${OPENVM_TOOLCHAIN_VERSION}" openvm --version; then
|
||||
if cargo openvm --version; then
|
||||
echo "cargo-openvm installation verified successfully."
|
||||
else
|
||||
echo "Error: 'cargo openvm --version' failed. cargo-openvm might not have installed correctly." >&2
|
||||
|
||||
Reference in New Issue
Block a user