Add markdown linting to pre-commit and format files.

This commit is contained in:
Alejandro Cabeza Romero 2026-05-27 16:41:00 +02:00
parent 83f399a583
commit 1800aa59b3
No known key found for this signature in database
GPG Key ID: DA3D14AE478030FD
7 changed files with 46 additions and 35 deletions

3
.markdownlint.json Normal file
View File

@ -0,0 +1,3 @@
{
"MD013": { "line_length": 120, "tables": false }
}

View File

@ -37,6 +37,11 @@ repos:
hooks:
- id: cargo-machete
args: ["rust/"]
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: e72a3ca1632f0b11a07d171449fe447a7ff6795e # v0.48.0
hooks:
- id: markdownlint
args: ["-f"]
- repo: local
hooks:
- id: cargo-hack-check

View File

@ -13,9 +13,9 @@ All notable changes to this project will be documented in this file.
Each circuit is now a linkable static archive (`lib{circuit}.a`) with a stable C FFI.
Two entry points per circuit:
- `{circuit}_generate_witness(WitnessInput*, Bytes*)`: Generates a witness in memory from a
- `{circuit}_generate_witness(WitnessInput*, Bytes*)`: Generates a witness in memory from a
JSON input string and an embedded `.dat` buffer; the caller owns the output buffer.
- `{circuit}_generate_witness_from_files(dat, inputs, output)`: Generates a witness from a `.dat` file and a JSON
- `{circuit}_generate_witness_from_files(dat, inputs, output)`: Generates a witness from a `.dat` file and a JSON
input file, writing the witness to an output file.
The Rust crates (`lbc-{circuit}-sys`) wrap this FFI directly and can either link against a local build or download a
@ -25,7 +25,7 @@ All notable changes to this project will be documented in this file.
- **Bundled static GMP** (#19)
`libgmp` is now compiled from source and statically linked, removing the runtime dependency on a system GMP
`libgmp` is now compiled from source and statically linked, removing the runtime dependency on a system GMP
installation, and standardizing the GMP version used across all platforms.
- **Older glibc compatibility** (#21)
@ -38,7 +38,7 @@ All notable changes to this project will be documented in this file.
- **Symbol resolution conflicts** (#22, #28, #29)
When multiple circuit libraries are linked into the same binary, the linker silently collapsed shared internal
When multiple circuit libraries are linked into the same binary, the linker silently collapsed shared internal
symbols to a single definition, corrupting witness parsing and causing SIGSEGV.
See [CONTRIBUTING.md](CONTRIBUTING.md#symbol-isolation-in-circuit-libraries) for a full explanation and maintenance

View File

@ -6,16 +6,20 @@
#### Sys development
- [Rust](https://rustup.rs/) — the pinned toolchain version is in `rust-toolchain.toml` and will be installed automatically by `rustup`.
- Compiled circuit libraries (`.a` files and `witness_generator.dat`) — see [rust/README.md](rust/README.md) for how to provide them.
- [Rust](https://rustup.rs/) — the pinned toolchain version is in `rust-toolchain.toml` and will be installed
automatically by `rustup`.
- Compiled circuit libraries (`.a` files and `witness_generator.dat`) — see [rust/README.md](rust/README.md) for how to
provide them.
#### Building circuits
- `llvm-objcopy` — required for symbol isolation when building circuit static libraries. On macOS, install via `brew install llvm` (LLVM 20+ required).
- `llvm-objcopy` — required for symbol isolation when building circuit static libraries. On macOS, install via `brew
install llvm` (LLVM 20+ required).
### Pre-Commit
[pre-commit](https://pre-commit.com/) covers most of the lints required by CI. It's not mandatory — you can run checks however you like — but it's the easiest way to catch issues before pushing.
[pre-commit](https://pre-commit.com/) covers most of the lints required by CI. It's not mandatory — you can run checks
however you like — but it's the easiest way to catch issues before pushing.
#### Installation
@ -43,6 +47,7 @@ The comment there lists every other place that must be updated in sync (nightly
#### Tool Versions
`taplo`, `cargo-deny`, and `cargo-machete` are pinned in two places that must stay in sync:
- `.pre-commit-config.yaml` (hook `rev`)
- `.github/workflows/lint.yml` (`cargo install --version`)
@ -60,11 +65,11 @@ For a full walkthrough of the CI build steps, from `.circom` source to release a
Each circuit (PoQ, PoL, PoC, Signature) is compiled into a static archive (`libpoq.a`, `libpol.a`, etc.).
All archives share the same symbols, compiled from the same source files but with **different
constant values per circuit** (e.g. `get_size_of_witness()` returns 18149 for PoQ and 20531 for PoL).
When two or more circuit libraries are linked into the same binary, the linker silently picks the first definition it
When two or more circuit libraries are linked into the same binary, the linker silently picks the first definition it
encounters for each symbol and discards the rest without any sort of error or warning.
The result is that one circuit's constants end up hardwired into functions shared by both circuits, corrupting witness
parsing.
In practice: the wrong `get_size_of_witness()` value causes `loadCircuit` to compute an incorrect buffer size, `pu32`
The result is that one circuit's constants end up hardwired into functions shared by both circuits, corrupting witness
parsing.
In practice: the wrong `get_size_of_witness()` value causes `loadCircuit` to compute an incorrect buffer size, `pu32`
walks off the end of the buffer, reads garbage as a length field, and the subsequent `memcpy` reads past the stack guard
page, which results in a **SIGSEGV**.
@ -86,26 +91,24 @@ symbols to local, confusing the linker's deduplication logic and causing "reloca
symbol in discarded section" errors. `llvm-objcopy` additionally clears the `GRP_COMDAT` flag,
turning affected sections into regular non-COMDAT sections. Slightly larger binary, no linker errors.
**Platform notes**
**macOS**
##### macOS
Uses `llvm-objcopy` (from `brew install llvm`, LLVM 20+).
Mach-O prepends `_` to every C symbol, so `--keep-global-symbol` arguments must include the
leading `_`. The Makefile's `SYM_PREFIX` variable handles this automatically.
**Windows**
##### Windows
Uses GNU's `objcopy` (from MinGW binutils).
GNU's `objcopy` works correctly on COFF, mapping local binding to storage class `C_STAT`.
The ELF `GRP_COMDAT` problem doesn't apply: COFF COMDAT is per-section rather than group-based.
#### Maintenance
#### FFI Maintenance
`PUBLIC_SYMS` is hardcoded to `$(PROJECT)_generate_witness` and `$(PROJECT)_generate_witness_from_files` in the
Makefile. If the public FFI API ever changes — entry points renamed or new ones added — update that variable, otherwise
Makefile. If the public FFI API ever changes — entry points renamed or new ones added — update that variable, otherwise
the affected symbols will be localized and linking will fail.
---
@ -117,27 +120,28 @@ the affected symbols will be localized and linking will fail.
To trigger a release build:
1. Create and push a tag in the format `vX.Y.Z`:
```bash
git tag v1.2.3 -m "Release v1.2.3"
git push --tags
```
2. This will automatically trigger the `.github/workflows/build_circuits.yml` workflow.
3. Once the workflow finishes, the generated artifacts will be attached to a new release.
> Pull Requests will also generate artifacts, which may be found in the job's page, but won't generate a new release.
> Currently, releases published this way are marked as **Draft** and **Pre-Release** to ensure that the changelog and
> pre-release steps are manually reviewed first.
> Pull Requests will also generate artifacts, which may be found on the job's page, but won't generate a new release.
#### Generated artifacts
For each supported platform (Linux x86_64, Linux aarch64, macOS aarch64, Windows x86_64), a release artifact is generated:
For each supported platform (Linux x86_64, Linux aarch64, macOS aarch64, Windows x86_64), a release artifact is
generated:
**`logos-blockchain-circuits-{version}-{os}-{arch}.tar.gz`** — a complete bundle containing all components needed to generate and verify proofs for all circuits.
**`logos-blockchain-circuits-{version}-{os}-{arch}.tar.gz`** — a complete bundle containing all components needed to
generate and verify proofs for all circuits.
**Bundle Structure:**
```
```text
logos-blockchain-circuits-{version}-{os}-{arch}/
├── lib/
│ └── libgmp.a
@ -158,8 +162,8 @@ The proving keys are generated using the Hermez Powers of Tau ceremony — see [
### Publishing
After triggering the release, it will appear as a **Draft** and **Pre-Release**.
Before making it public, make sure to:
Releases are marked as **Draft** and **Pre-Release** to ensure the changelog and pre-release steps are manually reviewed
before going public. Before publishing:
1. **Review the changelog**
Ensure that all relevant changes are clearly listed and properly formatted.
@ -169,4 +173,3 @@ Before making it public, make sure to:
3. **Mark the release as published**
- Uncheck **“This is a pre-release.”**
- Publish the release (removing the Draft state).

View File

@ -12,7 +12,6 @@ ZK-SNARK circuits for the [Logos Blockchain](https://github.com/logos-blockchain
| **PoC** — Proof of Claim | A voucher is validly owned and its nullifier is correctly derived |
| **Signature** | Knowledge of secret keys and their corresponding public keys |
## Architecture
```mermaid
@ -40,7 +39,8 @@ flowchart TD
DAT -->|Embedded into| G
```
Each circuit is compiled from Circom source to C++, combined with shared common files (`circom_adapter`, `types`, ...) and a circuit-specific FFI layer (`src/{circuit}/ffi.cpp`), and built into a static library.
Each circuit is compiled from Circom source to C++, combined with shared common files (`circom_adapter`, `types`, ...)
and a circuit-specific FFI layer (`src/{circuit}/ffi.cpp`), and built into a static library.
The Rust sys crates link directly against these libraries.

View File

@ -61,7 +61,7 @@ It consists of two groups of files copied into `{circuit}_cpp/` before compilati
- **Circuit-specific entry points** (`src/{circuit}/ffi.cpp`): The public `extern "C"` functions
that become the library's API.
```
```text
src/
types.hpp → copied into {circuit}_cpp/
circom_adapter.cpp → copied into {circuit}_cpp/

View File

@ -32,6 +32,7 @@ lbc-poq-sys = { version = "0.5", features = ["prebuilt"] }
```
The cache location depends on the operating system:
- Linux: `~/.cache/logos/blockchain/`
- macOS: `~/Library/Caches/logos/blockchain/`
- Windows: `%LOCALAPPDATA%\logos\blockchain\`
@ -51,10 +52,10 @@ LBC_LIB_DIR=/path/to/lib # Directory containing the required lib
# If using a release bundle, this is the included lib/ directory
```
> The `justfile` at the repo root contains recipes (`just poq`, `just pol`, etc.) that build the circuit libraries from
> The `justfile` at the repo root contains recipes (`just poq`, `just pol`, etc.) that build the circuit libraries from
> source.
>
> This is not yet an officially supported workflow, but it can serve as a reference if you need to produce the
>
> This is not yet an officially supported workflow, but it can serve as a reference if you need to produce the
> libraries yourself.
## Usage
@ -91,7 +92,6 @@ fn main() -> Result<(), Error> {
The other circuits follow the same pattern under `lbc_pol_sys`, `lbc_poc_sys` and `lbc_signature_sys`.
## Running tests
```bash