o1-labs / o1js

TypeScript framework for zk-SNARKs and zkApps
https://docs.minaprotocol.com/en/zkapps/how-to-write-a-zkapp
Apache License 2.0
475 stars 105 forks source link

Add ZkProgram.Optimistic to allow for deferred recursive proof calculations #1637

Closed dfstio closed 1 month ago

dfstio commented 1 month ago

When calculating recursive proofs, there is a significant probability that the user's transactions are malformed or contain the data that will cause asserts in ZkProgram to throw. Therefore, in the case of calculating recursive proof for 100 txs, which is expensive, it makes sense first to check all txs to make sure that the proof can be created.

Now, it is possible to do this in two ways: 1) Add TypeScript code that repeats the logic of ZkProgram and checks the txs. This method is error-prone, but it can give a 90% probability of checks being correct. 2) Define Struct, which contains all the logic, and in the ZkProgram, just call Struct functions. All txs can be checked by calling Struct's functions. There is a 99% probability of checks being correct, but it is still not 100%

The better way would be to define the new ZkProgram.Optimistic that just calculates the state without long proof calculations:

    class MyOptimisticZkProgram extends ZkProgram.Optimistic(MyZkProgram) {}
    try { 
      for( let i=0; i<100; i++) {
        // only do state calculations and check assertions, do not produce proofs
        await MyOptimisticZkProgram.check(txs[i]);
      }
      // All txs are valid, now produce proofs
      for( let i=0; i<100; i++) {
        proofs.push(await MyZkProgram.check(txs[i]));
      }
    } catch (e) {
      console.error(`Txs are invalid`, e);
    }

The second use case is quickly producing the final state of the ZkProgram to get it signed by the user. This decreases the user's wait time and guarantees that we can later produce valid proof of the signed state.

ZkProgram.Optimistic has nothing to do with "proofs off" debugging and is intended for use in production environments with proofs on.

mitschabaude commented 1 month ago

@dfstio are you aware of program.rawMethods which contains the raw program methods that you could run on your inputs directly?

dfstio commented 1 month ago

@dfstio are you aware of program.rawMethods which contains the raw program methods that you could run on your inputs directly?

Thank you! This way, it works: await MyZkProgram.rawMethods.check(txs[i]);