feat(lints): add rustfmt options (#23)

This commit is contained in:
Álex 2026-05-20 15:26:24 +02:00 committed by GitHub
parent cf7cbbe20f
commit 9d1f058338
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 109 additions and 74 deletions

View File

@ -3,8 +3,8 @@ use std::path::PathBuf;
#[cfg(feature = "prebuilt")]
mod prebuilt {
use std::path::{Path, PathBuf};
use ureq::Body;
use ureq::http::Response;
use ureq::{Body, http::Response};
static REPO: &str = "logos-blockchain/logos-blockchain-circuits";
static ARTIFACT_PREFIX: &str = "logos-blockchain-circuits";
@ -22,9 +22,9 @@ mod prebuilt {
fn fetch_library(version: &str, os: &str, arch: &str, lib_var_name: &str) -> Response<Body> {
let url = build_artifact_url(version, os, arch);
// We skip checksum verification intentionally.
// Hardcoded hashes would protect against a silently replaced release asset but require a
// two-step release (build → hash → commit → tag) which feels overkill for a first-party
// library.
// Hardcoded hashes would protect against a silently replaced release asset but
// require a two-step release (build → hash → commit → tag) which feels
// overkill for a first-party library.
ureq::get(&url).call().unwrap_or_else(|error| {
panic!(
"Failed to download a prebuilt library for {os}-{arch} v{version}: {error}. \
@ -83,18 +83,19 @@ mod prebuilt {
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let cache = get_cache_dir();
// The tarball unpacks to a top-level `{artifact_name}/` dir, so the circuit lives at
// `cache/{artifact_name}/{circuit_name}/`.
// The tarball unpacks to a top-level `{artifact_name}/` dir, so the circuit
// lives at `cache/{artifact_name}/{circuit_name}/`.
let circuit_dir = cache
.join(build_artifact_name(version, &os, &arch))
.join(circuit_name);
std::fs::create_dir_all(&cache).expect("Failed to create the cache directory.");
// Since the circuits' libraries are all contained in the same single artifact, each crate
// will try to download the same circuits.
// To avoid redundant downloads, we use a lock to ensure that only one process fetches the
// circuits while the others wait for it to complete and then re-check the cache.
// Since the circuits' libraries are all contained in the same single artifact,
// each crate will try to download the same circuits.
// To avoid redundant downloads, we use a lock to ensure that only one process
// fetches the circuits while the others wait for it to complete and
// then re-check the cache.
let mut lock = get_lockfile(&cache);
let _guard = lock.write().expect("Failed to acquire cache lock.");

View File

@ -1,6 +1,7 @@
use lbc_types::native::Error;
use std::path::Path;
use lbc_types::native::Error;
pub fn as_null_terminated_string(string: &str) -> Result<std::ffi::CString, Error> {
std::ffi::CString::new(string).map_err(|error| {
Error::InvalidInput(Some(format!(

View File

@ -1,6 +1,7 @@
use lbc_types::ffi::{Bytes, Status, WitnessInput};
use std::ffi::c_char;
use lbc_types::ffi::{Bytes, Status, WitnessInput};
unsafe extern "C" {
pub fn poc_generate_witness(input: *const WitnessInput, output: *mut Bytes) -> Status;

View File

@ -1,10 +1,12 @@
use crate::ffi::{poc_generate_witness, poc_generate_witness_from_files};
use std::path::Path;
use lbc_common::string::path_as_null_terminated_string;
use lbc_types::{
ffi,
native::{Error, Witness},
};
use std::path::Path;
use crate::ffi::{poc_generate_witness, poc_generate_witness_from_files};
static RAW_CIRCUIT_DAT: &[u8] =
include_bytes!(concat!(env!("LBC_POC_LIB_DIR"), "/witness_generator.dat"));
@ -22,7 +24,8 @@ pub fn generate_witness(input: &PocWitnessInput) -> Result<Witness, Error> {
let mut ffi_output_bytes = ffi::Bytes::null();
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally initialized null Bytes.
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally
// initialized null Bytes.
let status =
unsafe { poc_generate_witness(std::ptr::from_ref(ffi_input), &raw mut ffi_output_bytes) };
@ -34,16 +37,17 @@ pub fn generate_witness_from_files(dat: &Path, inputs: &Path, output: &Path) ->
let c_inputs = path_as_null_terminated_string(inputs)?;
let c_output = path_as_null_terminated_string(output)?;
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for the duration of the call.
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for
// the duration of the call.
unsafe { poc_generate_witness_from_files(c_dat.as_ptr(), c_inputs.as_ptr(), c_output.as_ptr()) }
.try_into()
}
#[cfg(test)]
mod tests {
use std::{path::PathBuf, sync::LazyLock};
use super::{PocWitnessInput, generate_witness, generate_witness_from_files};
use std::path::PathBuf;
use std::sync::LazyLock;
static LIB_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
const ENV_VAR: &str = "LBC_POC_LIB_DIR";

View File

@ -1,6 +1,7 @@
use lbc_types::ffi::{Bytes, Status, WitnessInput};
use std::ffi::c_char;
use lbc_types::ffi::{Bytes, Status, WitnessInput};
unsafe extern "C" {
pub fn pol_generate_witness(input: *const WitnessInput, output: *mut Bytes) -> Status;

View File

@ -1,10 +1,12 @@
use crate::ffi::{pol_generate_witness, pol_generate_witness_from_files};
use std::path::Path;
use lbc_common::string::path_as_null_terminated_string;
use lbc_types::{
ffi,
native::{Error, Witness},
};
use std::path::Path;
use crate::ffi::{pol_generate_witness, pol_generate_witness_from_files};
static RAW_CIRCUIT_DAT: &[u8] =
include_bytes!(concat!(env!("LBC_POL_LIB_DIR"), "/witness_generator.dat"));
@ -22,7 +24,8 @@ pub fn generate_witness(input: &PolWitnessInput) -> Result<Witness, Error> {
let mut ffi_output_bytes = ffi::Bytes::null();
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally initialized null Bytes.
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally
// initialized null Bytes.
let status =
unsafe { pol_generate_witness(std::ptr::from_ref(ffi_input), &raw mut ffi_output_bytes) };
@ -34,16 +37,17 @@ pub fn generate_witness_from_files(dat: &Path, inputs: &Path, output: &Path) ->
let c_inputs = path_as_null_terminated_string(inputs)?;
let c_output = path_as_null_terminated_string(output)?;
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for the duration of the call.
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for
// the duration of the call.
unsafe { pol_generate_witness_from_files(c_dat.as_ptr(), c_inputs.as_ptr(), c_output.as_ptr()) }
.try_into()
}
#[cfg(test)]
mod tests {
use std::{path::PathBuf, sync::LazyLock};
use super::{PolWitnessInput, generate_witness, generate_witness_from_files};
use std::path::PathBuf;
use std::sync::LazyLock;
static LIB_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
const ENV_VAR: &str = "LBC_POL_LIB_DIR";

View File

@ -1,6 +1,7 @@
use lbc_types::ffi::{Bytes, Status, WitnessInput};
use std::ffi::c_char;
use lbc_types::ffi::{Bytes, Status, WitnessInput};
unsafe extern "C" {
pub fn poq_generate_witness(input: *const WitnessInput, output: *mut Bytes) -> Status;

View File

@ -1,10 +1,12 @@
use crate::ffi::{poq_generate_witness, poq_generate_witness_from_files};
use std::path::Path;
use lbc_common::string::path_as_null_terminated_string;
use lbc_types::{
ffi,
native::{Error, Witness},
};
use std::path::Path;
use crate::ffi::{poq_generate_witness, poq_generate_witness_from_files};
static RAW_CIRCUIT_DAT: &[u8] =
include_bytes!(concat!(env!("LBC_POQ_LIB_DIR"), "/witness_generator.dat"));
@ -22,7 +24,8 @@ pub fn generate_witness(input: &PoqWitnessInput) -> Result<Witness, Error> {
let mut ffi_output_bytes = ffi::Bytes::null();
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally initialized null Bytes.
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally
// initialized null Bytes.
let status =
unsafe { poq_generate_witness(std::ptr::from_ref(ffi_input), &raw mut ffi_output_bytes) };
@ -34,16 +37,17 @@ pub fn generate_witness_from_files(dat: &Path, inputs: &Path, output: &Path) ->
let c_inputs = path_as_null_terminated_string(inputs)?;
let c_output = path_as_null_terminated_string(output)?;
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for the duration of the call.
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for
// the duration of the call.
unsafe { poq_generate_witness_from_files(c_dat.as_ptr(), c_inputs.as_ptr(), c_output.as_ptr()) }
.try_into()
}
#[cfg(test)]
mod tests {
use std::{path::PathBuf, sync::LazyLock};
use super::{PoqWitnessInput, generate_witness, generate_witness_from_files};
use std::path::PathBuf;
use std::sync::LazyLock;
static LIB_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
const ENV_VAR: &str = "LBC_POQ_LIB_DIR";

View File

@ -1,6 +1,7 @@
use lbc_types::ffi::{Bytes, Status, WitnessInput};
use std::ffi::c_char;
use lbc_types::ffi::{Bytes, Status, WitnessInput};
unsafe extern "C" {
pub fn signature_generate_witness(input: *const WitnessInput, output: *mut Bytes) -> Status;

View File

@ -1,10 +1,12 @@
use crate::ffi::{signature_generate_witness, signature_generate_witness_from_files};
use std::path::Path;
use lbc_common::string::path_as_null_terminated_string;
use lbc_types::{
ffi,
native::{Error, Witness},
};
use std::path::Path;
use crate::ffi::{signature_generate_witness, signature_generate_witness_from_files};
static RAW_CIRCUIT_DAT: &[u8] = include_bytes!(concat!(
env!("LBC_SIGNATURE_LIB_DIR"),
@ -24,7 +26,8 @@ pub fn generate_witness(input: &SignatureWitnessInput) -> Result<Witness, Error>
let mut ffi_output_bytes = ffi::Bytes::null();
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally initialized null Bytes.
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally
// initialized null Bytes.
let status = unsafe {
signature_generate_witness(std::ptr::from_ref(ffi_input), &raw mut ffi_output_bytes)
};
@ -37,7 +40,8 @@ pub fn generate_witness_from_files(dat: &Path, inputs: &Path, output: &Path) ->
let c_inputs = path_as_null_terminated_string(inputs)?;
let c_output = path_as_null_terminated_string(output)?;
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for the duration of the call.
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for
// the duration of the call.
unsafe {
signature_generate_witness_from_files(c_dat.as_ptr(), c_inputs.as_ptr(), c_output.as_ptr())
}
@ -46,9 +50,9 @@ pub fn generate_witness_from_files(dat: &Path, inputs: &Path, output: &Path) ->
#[cfg(test)]
mod tests {
use std::{path::PathBuf, sync::LazyLock};
use super::{SignatureWitnessInput, generate_witness, generate_witness_from_files};
use std::path::PathBuf;
use std::sync::LazyLock;
static LIB_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
const ENV_VAR: &str = "LBC_SIGNATURE_LIB_DIR";

View File

@ -1,6 +1,8 @@
pub mod roots {
use std::path::{Path, PathBuf};
use std::sync::LazyLock;
use std::{
path::{Path, PathBuf},
sync::LazyLock,
};
pub static TESTS: LazyLock<PathBuf> =
LazyLock::new(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")));
@ -13,9 +15,9 @@ pub mod roots {
}
pub mod inputs {
use std::{path::PathBuf, sync::LazyLock};
use super::roots;
use std::path::PathBuf;
use std::sync::LazyLock;
pub static POL: LazyLock<PathBuf> = LazyLock::new(|| roots::POL.join("sample.input.json"));
pub static POQ: LazyLock<PathBuf> = LazyLock::new(|| roots::POQ.join("sample.input.json"));

View File

@ -8,12 +8,13 @@ mod tests {
let pol_inputs_raw = std::fs::read_to_string(inputs::POL.as_path()).unwrap();
let pol_witness_input = lbc_pol_sys::PolWitnessInput::new(pol_inputs_raw).unwrap();
// Each sys crate compiles a copy of the same C++ runtime (loadCircuit, get_size_of_witness,
// ...) under identical symbol names. When two crates are linked into the same binary, the
// linker silently keeps one definition of each symbol, so one circuit ends up using the
// Each sys crate compiles a copy of the same C++ runtime (loadCircuit,
// get_size_of_witness, ...) under identical symbol names. When two
// crates are linked into the same binary, the linker silently keeps one
// definition of each symbol, so one circuit ends up using the
// other's size constants — corrupting dat parsing and causing a SIGSEGV.
// This test reproduces the conflict by calling generate_witness on both circuits in the
// same binary.
// This test reproduces the conflict by calling generate_witness on both
// circuits in the same binary.
let _pol_witness = lbc_pol_sys::generate_witness(&pol_witness_input);
let inputs_json_raw = std::fs::read_to_string(inputs::POQ.as_path()).unwrap();

View File

@ -28,8 +28,8 @@ impl<T> inner::Buffer<*mut T> {
/// 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
/// freed with [`free_bytes`] after use.
/// The inner `data` pointer must be null-initialized. It's heap-allocated by
/// the C side and must be freed with [`free_bytes`] after use.
pub type Bytes = inner::Buffer<*mut u8>;
/// Read-only byte slice passed into the C witness generator functions.
@ -37,13 +37,13 @@ pub type ConstBytes = inner::Buffer<*const u8>;
/// Frees the data buffer inside a [`Bytes`] struct allocated by the C API.
///
/// Only the inner data buffer is freed, not the struct itself, since the latter is managed by the
/// caller.
/// Only the inner data buffer is freed, not the struct itself, since the latter
/// is managed by the caller.
///
/// # Arguments
///
/// - `bytes`: A pointer to a [`Bytes`] struct whose data buffer was allocated by the C API and
/// needs to be freed.
/// - `bytes`: A pointer to a [`Bytes`] struct whose data buffer was allocated
/// by the C API and needs to be freed.
///
/// # Safety
///

View File

@ -1,7 +1,7 @@
//! Raw `#[repr(C)]` types that mirror the C witness generator API.
//!
//! These types map directly to the C header structs and are used at the FFI boundary. Prefer the
//! wrappers in [`crate::native`] for ordinary Rust code.
//! These types map directly to the C header structs and are used at the FFI
//! boundary. Prefer the wrappers in [`crate::native`] for ordinary Rust code.
pub mod bytes;
pub mod status;

View File

@ -1,6 +1,7 @@
use crate::ffi::ConstBytes;
use std::ffi::c_char;
use crate::ffi::ConstBytes;
/// Input to a witness generator function.
///
/// Both pointers must remain valid for the duration of the C call.

View File

@ -1,8 +1,8 @@
//! Raw FFI types and Rust-safe wrappers for the witness generator C API.
//!
//! The [`ffi`] module contains `#[repr(C)]` types that mirror the C headers directly. The
//! [`native`] module re-exposes those through idiomatic Rust types that own their memory and
//! convert FFI return values into [`Result`]s.
//! The [`ffi`] module contains `#[repr(C)]` types that mirror the C headers
//! directly. The [`native`] module re-exposes those through idiomatic Rust
//! types that own their memory and convert FFI return values into [`Result`]s.
pub mod ffi;
pub mod native;

View File

@ -1,6 +1,6 @@
use std::{marker::PhantomData, ops::Deref};
use crate::native::{Error, WitnessInput};
use std::marker::PhantomData;
use std::ops::Deref;
pub trait CircuitDat<'dat> {
const DAT: &'dat [u8];

View File

@ -1,6 +1,6 @@
use std::{ffi::CStr, fmt::Display};
use crate::ffi::status::Code as FfiStatusCode;
use std::ffi::CStr;
use std::fmt::Display;
pub type Result<T> = std::result::Result<T, Error>;
@ -33,7 +33,8 @@ impl TryFrom<crate::ffi::Status> for () {
fn try_from(status: crate::ffi::Status) -> Result<()> {
let message: Option<String> = status.has_message().then(|| {
// SAFETY: `status.message` is non-empty (checked by `has_message()`) and null-terminated as guaranteed by the C API.
// SAFETY: `status.message` is non-empty (checked by `has_message()`) and
// null-terminated as guaranteed by the C API.
let status_message = unsafe { CStr::from_ptr(status.message.as_ptr()) };
status_message.to_string_lossy().into_owned()
});

View File

@ -2,8 +2,8 @@ use crate::ffi;
/// Byte buffer
///
/// When constructing from [`From<ffi::Bytes>`], it takes ownership of the underlying value and
/// frees it.
/// When constructing from [`From<ffi::Bytes>`], it takes ownership of the
/// underlying value and frees it.
pub struct Witness(bytes::Bytes);
impl From<bytes::Bytes> for Witness {
@ -23,11 +23,13 @@ impl From<ffi::Bytes> for Witness {
let vec = if ffi_value.size == 0 || ffi_value.data.is_null() {
Vec::new()
} else {
// SAFETY: `ffi_value.data` is non-null and `ffi_value.size > 0` (checked above),
// pointing to a valid C-allocated buffer of at least `size` bytes.
// SAFETY: `ffi_value.data` is non-null and `ffi_value.size > 0` (checked
// above), pointing to a valid C-allocated buffer of at least `size`
// bytes.
unsafe { std::slice::from_raw_parts(ffi_value.data, ffi_value.size).to_vec() }
};
// SAFETY: `ffi_value` is a local variable, so the raw pointer is valid for this call.
// SAFETY: `ffi_value` is a local variable, so the raw pointer is valid for this
// call.
unsafe { ffi::free_bytes(&raw mut ffi_value) };
Self::from(bytes::Bytes::from(vec))
}

View File

@ -1,7 +1,7 @@
use crate::ffi;
use crate::native::Error;
use std::ffi::CString;
use crate::{ffi, native::Error};
/// Input for witness generators
pub struct WitnessInput<'dat> {
/// The circuit's dat file contents.
@ -27,7 +27,8 @@ impl<'dat> WitnessInput<'dat> {
}
}
/// Temporary FFI view of a [`WitnessInput`], which makes [`ffi::WitnessInput`] lifetime-aware.
/// Temporary FFI view of a [`WitnessInput`], which makes [`ffi::WitnessInput`]
/// lifetime-aware.
pub struct WitnessInputFfiGuard<'dat> {
ffi: ffi::WitnessInput,
_lifetime: std::marker::PhantomData<&'dat WitnessInput<'dat>>,

5
rustfmt.toml Normal file
View File

@ -0,0 +1,5 @@
group_imports = "StdExternalCrate"
imports_granularity = "Crate"
reorder_imports = true
reorder_modules = true
wrap_comments = true