mirror of
https://github.com/logos-blockchain/logos-blockchain-circuits.git
synced 2026-05-18 15:29:26 +00:00
Various fixes and improvements.
This commit is contained in:
parent
67b35faf4f
commit
f91bd073d1
56
rust/Cargo.lock
generated
56
rust/Cargo.lock
generated
@ -166,7 +166,6 @@ name = "logos-blockchain-circuits-types"
|
||||
version = "0.4.2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -197,24 +196,6 @@ version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.7.4"
|
||||
@ -304,17 +285,6 @@ version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.45"
|
||||
@ -326,32 +296,6 @@ dependencies = [
|
||||
"xattr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
|
||||
@ -24,5 +24,4 @@ lbc-types = { default-features = false, package = "logos-blockchain-circuits-typ
|
||||
flate2 = "1"
|
||||
libc = "0.2.185"
|
||||
tar = "0.4"
|
||||
thiserror = "2.0.18"
|
||||
ureq = "3.3.0"
|
||||
|
||||
@ -10,7 +10,7 @@ repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
lbc-types = { workspace = true}
|
||||
lbc-types = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
flate2 = { workspace = true }
|
||||
|
||||
@ -20,6 +20,7 @@ fn get_artifact_url(version: &str, os: &str, arch: &str) -> String {
|
||||
|
||||
fn fetch_library(version: &str, os: &str, arch: &str) -> Response<Body> {
|
||||
let url = get_artifact_url(version, os, arch);
|
||||
// TODO: Verify checksum.
|
||||
ureq::get(&url).call().unwrap_or_else(|error| {
|
||||
panic!(
|
||||
"Failed to download a prebuilt library for {os}-{arch} v{version}: {error}. \
|
||||
@ -35,7 +36,11 @@ fn unpack_library(response: Response<Body>, version: &str, os: &str, arch: &str,
|
||||
|
||||
let unpacked_artifact_path = output_dir.join(get_artifact_name(version, os, arch));
|
||||
let unpacked_library_directory = unpacked_artifact_path.join(CIRCUIT_NAME);
|
||||
assert!(unpacked_library_directory.exists(), "Expected the unpacked library at {}.", unpacked_library_directory.display());
|
||||
|
||||
if !unpacked_library_directory.exists() {
|
||||
panic!("Failed to find the unpacked library at {}.", unpacked_library_directory.display());
|
||||
}
|
||||
|
||||
unpacked_library_directory
|
||||
}
|
||||
|
||||
@ -57,12 +62,18 @@ fn provision_library() -> PathBuf {
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-env-changed={LIB_VAR_NAME}");
|
||||
println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION");
|
||||
println!("cargo:rerun-if-changed=Cargo.toml");
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
let lib_dir = std::env::var(LIB_VAR_NAME).map(
|
||||
|lib_dir| {
|
||||
println!("Using a library directory from {LIB_VAR_NAME}: {lib_dir}");
|
||||
let lib_dir_path = PathBuf::from(lib_dir);
|
||||
assert!(lib_dir_path.exists(), "The library directory at {} does not exist.", lib_dir_path.display());
|
||||
if !lib_dir_path.exists() {
|
||||
panic!("The library directory specified in {LIB_VAR_NAME} at {} does not exist.", lib_dir_path.display());
|
||||
|
||||
}
|
||||
lib_dir_path
|
||||
}
|
||||
).unwrap_or_else(|_| {
|
||||
|
||||
@ -1,18 +1,28 @@
|
||||
use std::ffi::c_char;
|
||||
use std::path::Path;
|
||||
use lbc_types::{ffi, native::{Bytes, Error, WitnessInput}};
|
||||
use crate::ffi::{poq_generate_witness, poq_generate_witness_from_files};
|
||||
|
||||
fn into_null_terminated_string(
|
||||
string: &str,
|
||||
) -> Result<std::ffi::CString, Error> {
|
||||
std::ffi::CString::new(string)
|
||||
.map_err(|error| Error::InvalidInput(Some(format!("Could not convert string to CString: {error}"))))
|
||||
}
|
||||
|
||||
fn path_as_null_terminated_string(
|
||||
path: &Path,
|
||||
) -> Result<std::ffi::CString, Error> {
|
||||
let path = path.to_str().ok_or(Error::InvalidInput(Some(format!("Could not convert the path to a string: {}", path.display()))))?;
|
||||
into_null_terminated_string(path)
|
||||
}
|
||||
|
||||
pub fn generate_witness(
|
||||
input: WitnessInput,
|
||||
) -> Result<Bytes, Error> {
|
||||
let ffi_input_guard = input.as_ffi();
|
||||
let ffi_input = ffi_input_guard.as_ref();
|
||||
|
||||
let mut ffi_output_bytes = ffi::Bytes {
|
||||
data: std::ptr::null_mut(),
|
||||
size: 0
|
||||
};
|
||||
let mut ffi_output_bytes = ffi::Bytes::null();
|
||||
|
||||
let status = unsafe {
|
||||
poq_generate_witness(
|
||||
@ -29,15 +39,15 @@ pub fn generate_witness_from_files(
|
||||
inputs: &Path,
|
||||
output: &Path,
|
||||
) -> Result<(), Error> {
|
||||
let dat = dat.to_str().ok_or_else(|| Error::InvalidInput)?; // TODO: Message
|
||||
let inputs = inputs.to_str().ok_or_else(|| Error::InvalidInput)?;
|
||||
let output = output.to_str().ok_or_else(|| Error::InvalidInput)?;
|
||||
let c_dat = path_as_null_terminated_string(dat)?;
|
||||
let c_inputs = path_as_null_terminated_string(inputs)?;
|
||||
let c_output = path_as_null_terminated_string(output)?;
|
||||
|
||||
unsafe {
|
||||
poq_generate_witness_from_files (
|
||||
dat.as_ptr() as *const c_char,
|
||||
inputs.as_ptr() as *const c_char,
|
||||
output.as_ptr() as *const c_char
|
||||
c_dat.as_ptr(),
|
||||
c_inputs.as_ptr(),
|
||||
c_output.as_ptr(),
|
||||
)
|
||||
}.try_into()
|
||||
}
|
||||
|
||||
@ -11,4 +11,3 @@ version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
libc = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
@ -8,6 +8,24 @@ mod inner {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> inner::Buffer<*const T> {
|
||||
pub fn null() -> Self {
|
||||
Self {
|
||||
data: std::ptr::null(),
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> inner::Buffer<*mut T> {
|
||||
pub fn null() -> Self {
|
||||
Self {
|
||||
data: std::ptr::null_mut(),
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Owned byte buffer returned by the C witness generator functions.
|
||||
///
|
||||
/// The inner `data` pointer must be null-initialized. It's heap-allocated by the C side and must be
|
||||
@ -29,7 +47,7 @@ pub type ConstBytes = inner::Buffer<*const u8>;
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Dereferences raw pointers. The caller must ensure that the pointer is valid.
|
||||
/// Dereferences raw pointers.
|
||||
pub unsafe fn free_bytes(bytes: *mut Bytes) {
|
||||
if bytes.is_null() {
|
||||
return;
|
||||
|
||||
@ -1,17 +1,20 @@
|
||||
use std::ffi::c_char;
|
||||
|
||||
/// Status codes for C API functions.
|
||||
#[repr(C)]
|
||||
pub enum Code {
|
||||
Ok = 0,
|
||||
DynError = 1,
|
||||
InvalidInput = 2,
|
||||
OutOfMemory = 3,
|
||||
#[derive(PartialEq, Eq)] // Enables comparisons with named constants.
|
||||
#[repr(transparent)]
|
||||
pub struct Code(pub i32);
|
||||
|
||||
impl Code {
|
||||
pub const OK: Self = Self(0);
|
||||
pub const DYN_ERROR: Self = Self(1);
|
||||
pub const INVALID_INPUT: Self = Self(2);
|
||||
pub const OUT_OF_MEMORY: Self = Self(3);
|
||||
}
|
||||
|
||||
impl Code {
|
||||
pub fn is_ok(&self) -> bool {
|
||||
matches!(self, Code::Ok)
|
||||
self == &Self::OK
|
||||
}
|
||||
|
||||
pub fn is_error(&self) -> bool {
|
||||
@ -29,7 +32,7 @@ pub struct Status {
|
||||
impl Status {
|
||||
pub fn ok() -> Self {
|
||||
Status {
|
||||
code: Code::Ok,
|
||||
code: Code::OK,
|
||||
message: [0; 256],
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,10 +26,14 @@ impl From<Vec<u8>> for Bytes {
|
||||
|
||||
impl From<ffi::Bytes> for Bytes {
|
||||
fn from(mut ffi_value: ffi::Bytes) -> Self {
|
||||
let raw = unsafe {
|
||||
std::slice::from_raw_parts(ffi_value.data, ffi_value.size).to_vec()
|
||||
let vec = if ffi_value.size == 0 || ffi_value.data.is_null() {
|
||||
Vec::new()
|
||||
} else {
|
||||
unsafe {
|
||||
std::slice::from_raw_parts(ffi_value.data, ffi_value.size).to_vec()
|
||||
}
|
||||
};
|
||||
unsafe { ffi::free_bytes(&mut ffi_value); }
|
||||
Self(raw)
|
||||
unsafe { ffi::free_bytes(&mut ffi_value) };
|
||||
Self(vec)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,44 +1,52 @@
|
||||
use std::ffi::CStr;
|
||||
use thiserror::Error;
|
||||
use std::fmt::Display;
|
||||
use crate::ffi::status::Code as FfiStatusCode;
|
||||
|
||||
pub type DynError = Box<dyn std::error::Error + Send + Sync>;
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// Error returned when a witness generator call does not succeed.
|
||||
#[derive(Debug, Error)]
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
#[error("Invalid input")]
|
||||
InvalidInput,
|
||||
#[error("Out of memory")]
|
||||
OutOfMemory,
|
||||
#[error(transparent)]
|
||||
Other(#[from] DynError),
|
||||
InvalidInput(Option<String>),
|
||||
OutOfMemory(Option<String>),
|
||||
Other(Option<String>),
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let (kind, message) = match self {
|
||||
Error::InvalidInput(msg) => ("Invalid input", msg),
|
||||
Error::OutOfMemory(msg) => ("Out of memory", msg),
|
||||
Error::Other(msg) => ("Other error", msg),
|
||||
};
|
||||
match message {
|
||||
Some(message) => write!(f, "{kind}: {message}"),
|
||||
None => write!(f, "{kind}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::ffi::Status> for () {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(status: crate::ffi::Status) -> Result<()> {
|
||||
let message: Option<String> = if status.has_message() {
|
||||
let status_message = unsafe {
|
||||
CStr::from_ptr(status.message.as_ptr())
|
||||
};
|
||||
Some(status_message.to_string_lossy().into_owned())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
match status.code {
|
||||
FfiStatusCode::Ok => Ok(()),
|
||||
FfiStatusCode::DynError => {
|
||||
let message: Option<&CStr> =
|
||||
if status.has_message() {
|
||||
let status_message = unsafe {
|
||||
CStr::from_ptr(status.message.as_ptr())
|
||||
};
|
||||
Some(status_message)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let error_message = message
|
||||
.map(|inner| DynError::from(inner.to_string_lossy().into_owned()))
|
||||
.unwrap_or_else(|| DynError::from("Unknown error"));
|
||||
Err(error_message.into())
|
||||
},
|
||||
FfiStatusCode::InvalidInput => Err(Error::InvalidInput),
|
||||
FfiStatusCode::OutOfMemory => Err(Error::OutOfMemory),
|
||||
FfiStatusCode::OK => Ok(()),
|
||||
FfiStatusCode::DYN_ERROR => Err(Error::Other(message)),
|
||||
FfiStatusCode::INVALID_INPUT => Err(Error::InvalidInput(message)),
|
||||
FfiStatusCode::OUT_OF_MEMORY => Err(Error::OutOfMemory(message)),
|
||||
other => Err(Error::Other(Some(format!("Unknown status code: {}", other.0))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use std::ffi::{CString, NulError};
|
||||
use std::ffi::CString;
|
||||
use crate::ffi;
|
||||
use crate::native::Error;
|
||||
|
||||
/// Input for witness generators
|
||||
pub struct WitnessInput {
|
||||
@ -10,8 +11,12 @@ pub struct WitnessInput {
|
||||
}
|
||||
|
||||
impl WitnessInput {
|
||||
pub fn new(dat: Vec<u8>, inputs_json: String) -> Result<Self, NulError> {
|
||||
let inputs_json = CString::new(inputs_json)?;
|
||||
pub fn new(dat: Vec<u8>, inputs_json: String) -> Result<Self, Error> {
|
||||
let inputs_json = CString::new(inputs_json).map_err(
|
||||
|error| Error::InvalidInput(Some(
|
||||
format!("The parameter inputs_json could not be converted to CString: {}", error)
|
||||
))
|
||||
)?;
|
||||
Ok(Self { dat, inputs_json })
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user