Node.js运行snarkjs执行zkey new时触发std::bad_alloc异常求助
snarkjs zkey new处理大规模约束时触发std::bad_alloc异常
问题背景
在256GB内存的Linux x64机器上,使用Node.js运行snarkjs处理一个约28M约束的zk-SNARK电路。执行snarkjs zkey new生成zkey文件时,总是在处理第10-11M条约束时抛出std::bad_alloc异常,进程崩溃。
已尝试的排查措施
- 调整Node.js堆内存:添加
--max-old-space-size=204800参数将JS堆内存设为200GB,无效 - 内存占用排查:崩溃时进程仅占用约40GB内存,排除系统内存不足问题
- 连续内存块排查:确认snarkjs在约束数超过1^20时会采用向量的向量结构避免大连续内存分配,排除该问题
- 版本测试:试过Node.js 18.17.0、snarkjs 0.7.0及其他版本,问题未解决
输出日志
node --max-old-space-size=204800 node_modules/.bin/snarkjs zkey new build/my_step.r1cs resources/powersOfTau28_hez_final_25.ptau build/my_step_p1.zkey [INFO] snarkJS: Reading r1cs [INFO] snarkJS: Reading tauG1 [INFO] snarkJS: Reading tauG2 [INFO] snarkJS: Reading alphatauG1 [INFO] snarkJS: Reading betatauG1 processing constraints: 0/28173676 processing constraints: 500000/28173676 processing constraints: 1000000/28173676 processing constraints: 1500000/28173676 processing constraints: 2000000/28173676 processing constraints: 2500000/28173676 processing constraints: 3000000/28173676 processing constraints: 3500000/28173676 processing constraints: 4000000/28173676 processing constraints: 4500000/28173676 processing constraints: 5000000/28173676 processing constraints: 5500000/28173676 processing constraints: 6000000/28173676 processing constraints: 6500000/28173676 processing constraints: 7000000/28173676 processing constraints: 7500000/28173676 processing constraints: 8000000/28173676 processing constraints: 8500000/28173676 processing constraints: 9000000/28173676 processing constraints: 9500000/28173676 processing constraints: 10000000/28173676 processing constraints: 10500000/28173676 terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc Aborted (core dumped)
电路信息
使用的电路为beacon-relay项目中的step.circom
复现步骤
- 编译电路:
circom my_step.circom --O1 --r1cs - 生成zkey文件:
node --max-old-space-size=204800 node_modules/.bin/snarkjs zkey new my_step.r1cs powersOfTau28_hez_final_25.ptau my_step.zkey
解决方案
1. 切换至snarkjs的Rust实现
snarkjs的JS版本依赖C++绑定,在超大规模约束场景下内存管理易出问题。Rust实现的snarkjs针对大规模电路做了优化,内存处理更高效:
# 安装snarkjs Rust版 cargo install snarkjs # 执行zkey生成命令 snarkjs zkey new my_step.r1cs powersOfTau28_hez_final_25.ptau my_step.zkey
2. 提升电路编译优化级别
当前用--O1编译,尝试--O2或--O3优化,circom会进一步精简约束数量,降低处理压力:
circom my_step.circom --O3 --r1cs
3. 检查系统环境配置
- 确认虚拟内存(swap)空间足够,C++底层可能需要临时swap应对内存峰值
- 检查
ulimit限制,确保进程可打开足够文件描述符:
ulimit -n 65536
- 避免
NODE_OPTIONS中存在冲突参数,确保仅设置必要的内存调整选项
4. 分阶段处理zkey生成
若上述方法无效,可尝试拆分zkey生成流程,分块处理约束后合并,需熟悉snarkjs工作流程或使用支持分阶段处理的工具。
内容的提问来源于stack exchange,提问作者Leonardo Vona
相关产品推荐
相关产品推荐

