risc0 / risc0-foundry-template

Template for integrating RISC Zero and Ethereum using Foundry
https://risczero.com
107 stars 60 forks source link

`forge test` yields capacity overflow" guest error #108

Closed mikirov closed 4 months ago

mikirov commented 6 months ago

Hello. I am trying to figure out a "capacity overflow" guest error and what is causing it. Suggestions are appreciated 🙏🏻 . This is a PoC i am just getting started on. The statement we want to prove is "is this Merkle inclusion proof using sha384 nodes valid and is the BLS signature over the merkle root valid" Reproduction steps:

  1. Repo with code can be found here: https://github.com/LimeChain/hedera-zk-poc
  2. rename .env.example to .env, fill it with the bonsai url and api key and source .env
  3. cargo build
  4. cargo test (unit test succeeds)
  5. forge test -vvv(fails with guest error "capacity overflow")

I highly suspect since the cycle count is quite high (currently 216889043 for me), the Bonsai service is internally hitting some limits and throwing an error on my request. I tried local STARK to SNARK conversion, however it is taking way too long on a bulky gcloud 128GB RAM machine (n2-standard-32). The relevant code i used inside the unit test is as follows:

        let private_inputs = PrivateInputs::new(merkle_root, leaf, bls_pubkey, bls_signature, serialized_path);
        //println!("{:?}", private_inputs);

        let env = ExecutorEnv::builder()
            .write(&private_inputs).unwrap()
            .build().unwrap();

        // NOTE: Use the executor to run tests without proving.
        // let session_info = default_executor().execute(env, super::MAIN_ELF).unwrap();
        tracing::info!("Executing");
        let mut exec = ExecutorImpl::from_elf(env, super::MAIN_ELF).unwrap();
        let session = exec.run().unwrap();

        tracing::info!("prove");
        let opts = ProverOpts::default();
        let ctx = VerifierContext::default();
        let prover = get_prover_server(&opts).unwrap();
        // let receipt = prover.prove_session(&ctx, &session).unwrap().receipt;
        // available fields are: `inner`, `journal`
        let receipt: Receipt = prover.prove_session(&ctx, &session).unwrap();
        let claim = receipt.get_claim().unwrap();
        let composite_receipt = receipt.inner.composite().unwrap();
        let succinct_receipt = prover.compress(composite_receipt).unwrap();
        let journal = session.journal.unwrap().bytes;

        tracing::info!("identity_p254");
        let ident_receipt = identity_p254(&succinct_receipt).unwrap();
        let seal_bytes = ident_receipt.get_seal_bytes();

        tracing::info!("stark-to-snark");
        let seal = stark_to_snark(&seal_bytes).unwrap().to_vec();

        tracing::info!("receipt");
        let receipt = Receipt::new(
            InnerReceipt::Compact(CompactReceipt { seal, claim }),
            journal,
        );

This is taken from and modified for the risc0_groth16 library: https://github.com/risc0/risc0/tree/main/risc0/groth16

Profiling the cycle counts:

R0VM[333966] cycle count after reading private inputs: 298040
R0VM[5991956] cycle count after merkle root: 5954977
R0VM[216656130] cycle count after BLS signature verification: 216609314
R0VM[216671486] total cycle count: 216647678

My local groth16 issue may be related to this issue. I am running on M1 Macbook Pro, white stark2snark is only supported on x86: https://github.com/risc0/risc0/issues/1786

nategraf commented 5 months ago

Sorry for a slow response here. Can you provide some more context on the "capacity overflow" error? This is not an error string I immediately recognize. And it seems you are able to execute the guest (e.g. by running with RISC0_DEV_MODE=true but are failing to prove it?

Bonsai regularly runs proofs of this size (~216M cycles), so the size should not be an issue, although if you submit this proof multiple times you may be running out of quota. As for proving locally, a machine with GPU (e.g. the g4dn.xlarge or g6.xlarge) instance on AWS will have the best performance. You'll need to build risc0 with the --features cuda flag to make use of it. (Note those that while the RISC Zero STARK prover doesn't need exceptional CPU specs, the rapidsnark Groth16 prover does use the CPU and memory more heavily, so you'll want to experiment with the right machine for that)

nategraf commented 5 months ago

@mikirov, do you have any additional context to provide here?

nategraf commented 4 months ago

@mikirov, I'm going to close this since we don't have enough information to address the issue. Please re-open if you have some additional information to share with us.