diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index ea2966aa1..d83c96ee1 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -179,7 +179,9 @@ jobs: uses: Swatinem/rust-cache@v2 with: workspaces: "rust -> target" - key: ${{ runner.os }}-cargo-docker-${{ hashFiles('**/Cargo.lock') }} + # See cache-key rationale in ci.yml `lint` job (#903): include the + # rust workspace Cargo.toml so profile changes bust the cache. + key: ${{ runner.os }}-cargo-docker-${{ hashFiles('**/Cargo.lock', 'rust/Cargo.toml') }} - name: Build zeam natively run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d2a388cb..9521469ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,7 +69,13 @@ jobs: with: workspaces: "rust -> target" cache-bin: false - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + # PR #903 introduced a `multisig-release` cargo profile and pointed the + # default (dummy) prover at `rust/target/multisig-release/libzeam_glue.a`. + # Hashing `rust/Cargo.toml` here (in addition to Cargo.lock) busts the + # cache automatically on any future profile change, avoiding the + # "restored cache lacks the new profile dir → confusing linker error" + # failure mode flagged in #903 review. + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock', 'rust/Cargo.toml') }} - name: Check Rust formatting run: | @@ -152,7 +158,8 @@ jobs: with: cache-bin: false workspaces: "rust -> target" - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + # See cache-key rationale in the `lint` job. + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock', 'rust/Cargo.toml') }} - name: Fetch Zig dependencies run: | @@ -255,7 +262,8 @@ jobs: with: cache-bin: false workspaces: "rust -> target" - key: ${{ runner.os }}-cargo-all-provers-${{ hashFiles('**/Cargo.lock') }} + # See cache-key rationale in the `lint` job. + key: ${{ runner.os }}-cargo-all-provers-${{ hashFiles('**/Cargo.lock', 'rust/Cargo.toml') }} - name: Fetch Zig dependencies run: | @@ -366,7 +374,9 @@ jobs: with: cache-bin: false workspaces: "rust -> target" - key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }} + # See cache-key rationale in the `lint` job. Also shared with `dummy-prove` + # (same key prefix) — busting via `rust/Cargo.toml` keeps both in sync. + key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock', 'rust/Cargo.toml') }} - name: Fetch Zig dependencies run: | @@ -497,7 +507,10 @@ jobs: with: cache-bin: false workspaces: "rust -> target" - key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }} + # See cache-key rationale in the `lint` job. Shared key prefix with + # `test`/`simtest` so all three jobs invalidate together when the rust + # workspace profile set changes (e.g. PR #903's `multisig-release`). + key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock', 'rust/Cargo.toml') }} - name: Fetch Zig dependencies run: | @@ -571,7 +584,8 @@ jobs: with: cache-bin: false workspaces: "rust -> target" - key: ${{ runner.os }}-cargo-docker-${{ hashFiles('**/Cargo.lock') }} + # See cache-key rationale in the `lint` job. + key: ${{ runner.os }}-cargo-docker-${{ hashFiles('**/Cargo.lock', 'rust/Cargo.toml') }} - name: Fetch Zig dependencies run: | diff --git a/build.zig b/build.zig index a84b285ae..02492a0d2 100644 --- a/build.zig +++ b/build.zig @@ -50,7 +50,11 @@ fn defaultSimpleTestRunner(b: *Builder) std.Build.Step.Compile.TestRunner { // See blockblaz/zeam#773. fn addRustGlueLib(b: *Builder, comp: *Builder.Step.Compile, target: Builder.ResolvedTarget, prover: ProverChoice) void { const glue_path = switch (prover) { - .dummy, .all => "rust/target/release/libzeam_glue.a", + // `.dummy` uses the dedicated multisig-only Cargo profile (ThinLTO, + // codegen-units=1) to give the leanMultisig prover the same level of + // cross-crate inlining that single-prover builds already get. + .dummy => "rust/target/multisig-release/libzeam_glue.a", + .all => "rust/target/release/libzeam_glue.a", .risc0 => "rust/target/risc0-release/libzeam_glue.a", .openvm => "rust/target/openvm-release/libzeam_glue.a", }; @@ -881,10 +885,10 @@ fn build_rust_project(b: *Builder, path: []const u8, prover: ProverChoice) *Buil // any more than it satisfied the previous `cargo +nightly` shape. const cargo_build = switch (prover) { .dummy => b.addSystemCommand(&.{ - "rustup", "run", "nightly", "cargo", - "-C", path, "-Z", "unstable-options", - "build", "--release", "-p", "zeam-glue", - "--no-default-features", "--features", "libp2p,hashsig,multisig", + "rustup", "run", "nightly", "cargo", + "-C", path, "-Z", "unstable-options", + "build", "--profile", "multisig-release", "-p", + "zeam-glue", "--no-default-features", "--features", "libp2p,hashsig,multisig", }), .risc0 => b.addSystemCommand(&.{ "rustup", "run", "nightly", "cargo", diff --git a/pkgs/cli/src/main.zig b/pkgs/cli/src/main.zig index d58281e35..b30dda4ea 100644 --- a/pkgs/cli/src/main.zig +++ b/pkgs/cli/src/main.zig @@ -82,6 +82,13 @@ pub const NodeCommand = struct { /// worker path is the supported prod path; the synchronous path /// stays in place as a kill-switch via `--chain-worker false`. @"chain-worker": bool = true, + /// Override the rayon worker count used by the multisig (XMSS) aggregate + /// prover. `null` (the default, surfaced as omitted on the CLI) keeps the + /// existing post-system-thread split that gives roughly half of the + /// remaining cores to the Zig pool and half to rayon — fine for non- + /// aggregator nodes. Aggregators on CPU-rich hosts can pass a value here + /// to give the prover more parallelism without rebuilding (#899). + @"rayon-threads": ?u32 = null, pub const __shorts__ = .{ .help = .h, @@ -107,6 +114,7 @@ pub const NodeCommand = struct { .@"db-backend" = "Database backend to use for on-disk state: 'rocksdb' (default) or 'lmdb'", .@"chain-spec" = "Path to the chain specification file, if unspecified falls back to the default setting", .@"chain-worker" = "Route gossip block + attestation handlers through the dedicated chain-worker thread. On by default; pass `--chain-worker false` to fall back to the legacy synchronous path as a kill-switch.", + .@"rayon-threads" = "Override the rayon worker count used by the multisig aggregate prover. If unset, half of the post-system-thread budget goes to the Zig pool and half to rayon. Aggregators in CPU-rich environments benefit from a higher value (e.g. 12 on a 16-vCPU host); non-aggregators can leave it unset.", .help = "Show help information for the node command", }; }; @@ -842,6 +850,7 @@ fn mainInner(init: std.process.Init) !void { .hash_sig_key_dir = &.{}, // Initialize to empty slice to avoid segfault in deinit .node_registry = node_registry, .db_backend = leancmd.@"db-backend", + .rayon_threads = leancmd.@"rayon-threads", }; defer start_options.deinit(allocator); diff --git a/pkgs/cli/src/node.zig b/pkgs/cli/src/node.zig index 66480ed1c..be8f4669c 100644 --- a/pkgs/cli/src/node.zig +++ b/pkgs/cli/src/node.zig @@ -103,6 +103,13 @@ pub const NodeOptions = struct { /// `--chain-worker false` as the kill-switch for the legacy /// synchronous path. chain_worker_enabled: bool = true, + /// Override the rayon worker count for the multisig aggregate prover. + /// `null` keeps the existing automatic split (half of the post-system- + /// thread budget to Zig workers, half to rayon). Aggregators in + /// CPU-rich environments can set this higher to give the prover more + /// parallelism without rebuilding (#899). Surfaced as `--rayon-threads` + /// on the `zeam node` CLI. + rayon_threads: ?u32 = null, pub fn deinit(self: *NodeOptions, allocator: std.mem.Allocator) void { for (self.bootnodes) |b| allocator.free(b); @@ -417,9 +424,43 @@ pub const Node = struct { // the extra worker on odd counts since aggregate verification enters // rayon from Zig workers. Both pools still keep a minimum of one worker // so tiny/cgroup-limited systems remain functional. + // + // Operators can override the rayon worker count with `--rayon-threads` + // (#899). The automatic split is conservative — it deliberately leaves + // half of the post-system-thread budget to the Zig pool because + // verification and gossip work also enter rayon. On a CPU-rich + // aggregator that bottleneck is the produce path instead, so giving + // rayon more cores measurably shortens the per-pass build time. + // // Must be called before setupProver/setupVerifier since rayon’s global // pool is initialized lazily on first use. - const rayon_threads = @max(@as(usize, 1), desired_workers -| worker_count); + const rayon_threads = if (options.rayon_threads) |override| + @max(@as(usize, 1), @as(usize, override)) + else + @max(@as(usize, 1), desired_workers -| worker_count); + self.logger.info( + "thread pools: cpu_count={d} zig_workers={d} rayon_threads={d}{s}", + .{ + cpu_count, + worker_count, + rayon_threads, + if (options.rayon_threads != null) " (rayon override via --rayon-threads)" else "", + }, + ); + // Operator-typo guard for --rayon-threads (review feedback on #903). + // Rayon tolerates over-subscription, but values like `--rayon-threads 160` + // on a 4-vCPU box silently degrade throughput. Warn (don't reject) so the + // operator notices in startup logs without blocking deliberate edge cases + // (e.g. fractional cgroup quotas where `getCpuCount` reports more CPUs + // than the container can actually use). + if (options.rayon_threads) |override| { + if (@as(usize, override) > cpu_count) { + self.logger.warn( + "--rayon-threads {d} exceeds detected cpu_count={d}; rayon over-subscription typically reduces throughput. Verify this is intentional.", + .{ override, cpu_count }, + ); + } + } xmss.setRayonThreads(rayon_threads); // Pre-warm the XMSS verifier on the main thread before any worker can diff --git a/rust/Cargo.lock b/rust/Cargo.lock index a87f4f950..dc922c763 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -181,7 +181,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -192,7 +192,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -713,7 +713,7 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backend" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "mt-air", "mt-fiat-shamir", @@ -1802,7 +1802,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -2017,7 +2017,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2664,7 +2664,7 @@ name = "hashsig-glue" version = "0.1.0" dependencies = [ "ethereum_ssz", - "leansig", + "leansig 0.1.0 (git+https://github.com/leanEthereum/leanSig?branch=devnet4)", "rand 0.10.1", "sha2 0.9.9", "thiserror 2.0.18", @@ -3330,7 +3330,7 @@ dependencies = [ [[package]] name = "lean_compiler" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "backend", "lean_vm", @@ -3345,7 +3345,7 @@ dependencies = [ [[package]] name = "lean_prover" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "backend", "itertools 0.14.0", @@ -3362,7 +3362,7 @@ dependencies = [ [[package]] name = "lean_vm" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "backend", "itertools 0.14.0", @@ -3378,7 +3378,27 @@ dependencies = [ [[package]] name = "leansig" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanSig?branch=devnet4#5cc7e37480362f94e86695428a9ceb9a96b66b97" +source = "git+https://github.com/leanEthereum/leanSig?branch=devnet4#15cbdd43ec8525aa43fea2f42cafc5ed366084ae" +dependencies = [ + "dashmap", + "ethereum_ssz", + "num-bigint 0.4.6", + "num-traits", + "p3-baby-bear 0.5.1", + "p3-field 0.5.1", + "p3-koala-bear 0.5.1", + "p3-symmetric 0.5.1", + "rand 0.10.1", + "rayon", + "serde", + "sha3 0.10.8", + "thiserror 2.0.18", +] + +[[package]] +name = "leansig" +version = "0.1.0" +source = "git+https://github.com/leanEthereum/leanSig#c08a3bae74b0d85379cab72dcbefa4091546ecbb" dependencies = [ "dashmap", "ethereum_ssz", @@ -3398,7 +3418,7 @@ dependencies = [ [[package]] name = "leansig_fast_keygen" version = "0.1.0" -source = "git+https://github.com/TomWambsgans/leanSig?branch=devnet4-fast-keygen#5b86867a4d3c1d4a8add840f70fa047ea1506188" +source = "git+https://github.com/TomWambsgans/leanSig?branch=devnet4-fast-keygen#0fa9e19b8946ef50a34f3d50d82918b98bcfa4a5" dependencies = [ "dashmap", "ethereum_ssz", @@ -3418,11 +3438,11 @@ dependencies = [ [[package]] name = "leansig_wrapper" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "backend", "ethereum_ssz", - "leansig", + "leansig 0.1.0 (git+https://github.com/leanEthereum/leanSig)", "leansig_fast_keygen", "p3-field 0.5.1", "rand 0.10.1", @@ -4109,7 +4129,7 @@ dependencies = [ [[package]] name = "mt-air" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "mt-field", "mt-poly", @@ -4118,7 +4138,7 @@ dependencies = [ [[package]] name = "mt-fiat-shamir" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "mt-field", "mt-koala-bear", @@ -4131,7 +4151,7 @@ dependencies = [ [[package]] name = "mt-field" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "itertools 0.14.0", "mt-utils", @@ -4146,7 +4166,7 @@ dependencies = [ [[package]] name = "mt-koala-bear" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "itertools 0.14.0", "mt-field", @@ -4162,7 +4182,7 @@ dependencies = [ [[package]] name = "mt-poly" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "itertools 0.14.0", "mt-field", @@ -4175,7 +4195,7 @@ dependencies = [ [[package]] name = "mt-sumcheck" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "mt-air", "mt-fiat-shamir", @@ -4188,7 +4208,7 @@ dependencies = [ [[package]] name = "mt-symetric" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "mt-field", "mt-koala-bear", @@ -4198,7 +4218,7 @@ dependencies = [ [[package]] name = "mt-utils" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "serde", ] @@ -4206,7 +4226,7 @@ dependencies = [ [[package]] name = "mt-whir" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "itertools 0.14.0", "mt-fiat-shamir", @@ -4383,7 +4403,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -5498,7 +5518,7 @@ dependencies = [ [[package]] name = "p3-baby-bear" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "p3-challenger 0.5.1", "p3-field 0.5.1", @@ -5550,7 +5570,7 @@ dependencies = [ [[package]] name = "p3-challenger" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "p3-field 0.5.1", "p3-maybe-rayon 0.5.1", @@ -5590,14 +5610,14 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "itertools 0.14.0", "p3-field 0.5.1", "p3-matrix 0.5.1", "p3-maybe-rayon 0.5.1", "p3-util 0.5.1", - "spin 0.10.0", + "spin 0.11.0", "tracing", ] @@ -5621,7 +5641,7 @@ dependencies = [ [[package]] name = "p3-field" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "itertools 0.14.0", "num-bigint 0.4.6", @@ -5723,7 +5743,7 @@ dependencies = [ [[package]] name = "p3-koala-bear" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "p3-challenger 0.5.1", "p3-field 0.5.1", @@ -5753,7 +5773,7 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "itertools 0.14.0", "p3-field 0.5.1", @@ -5775,7 +5795,7 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" [[package]] name = "p3-mds" @@ -5794,7 +5814,7 @@ dependencies = [ [[package]] name = "p3-mds" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "p3-dft 0.5.1", "p3-field 0.5.1", @@ -5844,7 +5864,7 @@ dependencies = [ [[package]] name = "p3-monty-31" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "itertools 0.14.0", "num-bigint 0.4.6", @@ -5860,7 +5880,7 @@ dependencies = [ "paste", "rand 0.10.1", "serde", - "spin 0.10.0", + "spin 0.11.0", "tracing", ] @@ -5878,9 +5898,10 @@ dependencies = [ [[package]] name = "p3-poseidon1" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "p3-field 0.5.1", + "p3-mds 0.5.1", "p3-symmetric 0.5.1", "rand 0.10.1", ] @@ -5900,7 +5921,7 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "p3-field 0.5.1", "p3-mds 0.5.1", @@ -5938,7 +5959,7 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "itertools 0.14.0", "p3-field 0.5.1", @@ -5975,7 +5996,7 @@ dependencies = [ [[package]] name = "p3-util" version = "0.5.1" -source = "git+https://github.com/Plonky3/Plonky3.git#c7bacaeb4c870e3d6f9b7c23064c05e555c80bc8" +source = "git+https://github.com/Plonky3/Plonky3.git#82cfad73cd734d37a0d51953094f970c531817ec" dependencies = [ "serde", "transpose", @@ -6711,7 +6732,7 @@ dependencies = [ [[package]] name = "rec_aggregation" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "backend", "lean_compiler", @@ -7240,7 +7261,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -7674,7 +7695,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -7688,9 +7709,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "783f3f6f6b01e295a669edfc402133a5f2553d1f0e81284b3ba4594e80bdd4a2" dependencies = [ "lock_api", ] @@ -7785,7 +7806,7 @@ dependencies = [ [[package]] name = "sub_protocols" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "backend", "lean_vm", @@ -7884,7 +7905,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -8440,7 +8461,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "utils" version = "0.1.0" -source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=2eb4b9d983171139af36749f127dd9890c9109e6#2eb4b9d983171139af36749f127dd9890c9109e6" +source = "git+https://github.com/leanEthereum/leanMultisig.git?rev=5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa#5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" dependencies = [ "backend", "tracing", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 6ceb72ce9..22a60805d 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -18,6 +18,24 @@ lto = false # Set to true for single-prover builds to reduce binary size from 1 strip = "symbols" codegen-units = 16 # Multiple units keep risc0 and openvm code separate +# Optimized profile for the multisig-only (dummy prover) build. This is the +# image used by production aggregators on the devnet; the leanMultisig prover +# is the per-slot hot path and benefits noticeably from cross-crate inlining +# (ThinLTO) and single-codegen-unit compilation. Because this build excludes +# both risc0 and openvm via `--no-default-features --features +# libp2p,hashsig,multisig`, there are no `sys_alloc_aligned`-style symbol +# collisions to worry about — the constraint that forces `lto = false, +# codegen-units = 16` on the shared `[profile.release]` does not apply. +# +# Keep opt-level at the inherited `3`. Do NOT switch to `opt-level = "z"` +# (or `"s"`) here: combined with `codegen-units = 1` they miscompile +# leanMultisig's prover on x86_64 Linux (rustc >= 1.95) — see the comment on +# `[profile.openvm-release]` and zeam#734 / leanEthereum/leanMultisig#198. +[profile.multisig-release] +inherits = "release" +lto = "thin" +codegen-units = 1 + # Optimized profile for OpenVM-only builds (size reduction, but see opt-level note). [profile.openvm-release] inherits = "release" diff --git a/rust/hashsig-glue/src/lib.rs b/rust/hashsig-glue/src/lib.rs index 7f128c99c..c2f0bfe98 100644 --- a/rust/hashsig-glue/src/lib.rs +++ b/rust/hashsig-glue/src/lib.rs @@ -1,9 +1,13 @@ -// Production config (default) +// Production config (default). +// +// Upstream renamed `Scheme...` → `SIG...` in `lifetime_2_to_the_32` only +// (leanSig main, pulled in via leanMultisig `5eba3b1`). The `lifetime_2_to_the_8` +// test module below is unchanged and still exports `Scheme...`. #[cfg(not(feature = "test-config"))] mod config { pub use leansig::signature::generalized_xmss::instantiations_aborting::lifetime_2_to_the_32::{ PubKeyAbortingTargetSumLifetime32Dim46Base8 as XmssPublicKey, - SchemeAbortingTargetSumLifetime32Dim46Base8 as XmssScheme, + SIGAbortingTargetSumLifetime32Dim46Base8 as XmssScheme, SecretKeyAbortingTargetSumLifetime32Dim46Base8 as XmssSecretKey, SigAbortingTargetSumLifetime32Dim46Base8 as XmssSignature, }; diff --git a/rust/multisig-glue/Cargo.toml b/rust/multisig-glue/Cargo.toml index 2584843aa..019028ccb 100644 --- a/rust/multisig-glue/Cargo.toml +++ b/rust/multisig-glue/Cargo.toml @@ -4,9 +4,22 @@ version = "0.1.0" edition = "2021" [dependencies] -rec_aggregation = { git = "https://github.com/leanEthereum/leanMultisig.git", rev = "2eb4b9d983171139af36749f127dd9890c9109e6" } -leansig_wrapper = { git = "https://github.com/leanEthereum/leanMultisig.git", rev = "2eb4b9d983171139af36749f127dd9890c9109e6" } -backend = { git = "https://github.com/leanEthereum/leanMultisig.git", rev = "2eb4b9d983171139af36749f127dd9890c9109e6" } +# leanMultisig devnet4 head (2026-05-12). Includes: +# - 7a71c0f: eq_mle base-case correctness fix +# (was using packing_width instead of log_packing_width) +# - 939a767: removed superfluous `#[inline]` in eq_mle — measured +10% +# on AVX-512 (Hetzner AX42-U), neutral on NEON. This is the +# same hardware class as the devnet aggregator hosts. +# - 5fbd5bf: Plonky3 PR #1600 NEON dot-product regression coverage +# - e5c2183: leanSig dep flipped to `main` (devnet4 merged into main) +# - 5eba3b1: rec_aggregation BenchmarkReport (API-additive, source of +# the per-node breakdown that lean-bench / op tooling read) +# Devnet operators reported ~16 sig/s on 2eb4b9d (Apr 17) vs ~37 sig/s on +# leanMultisig benchmarks against 5eba3b1 — the 939a767 inline removal is +# the dominant contributor on the prod hardware. +rec_aggregation = { git = "https://github.com/leanEthereum/leanMultisig.git", rev = "5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" } +leansig_wrapper = { git = "https://github.com/leanEthereum/leanMultisig.git", rev = "5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" } +backend = { git = "https://github.com/leanEthereum/leanMultisig.git", rev = "5eba3b141455349d7cdbf0f5d3ccfb2e640b02aa" } rayon = "1" [lib]