Skip to content

Commit

Permalink
Merge pull request #14031 from MinaProtocol/feature/use-proof-cache
Browse files Browse the repository at this point in the history
[berkeley] Use Proof_cache for Test_zkapp_update tests
  • Loading branch information
mrmr1993 authored Oct 17, 2023
2 parents b193f27 + 4678fec commit 08d678a
Show file tree
Hide file tree
Showing 26 changed files with 206 additions and 7 deletions.
7 changes: 7 additions & 0 deletions src/lib/pickles/proof_cache.ml
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,10 @@ let set_wrap_proof t ~keypair ~public_input proof =
in
let proof_json = Backend.Tock.Proof.to_yojson proof in
set_proof t ~verification_key ~public_input proof_json

let is_env_var_set_requesting_error_for_proofs () =
match Sys.getenv_opt "ERROR_ON_PROOF" with
| Some ("true" | "t" (* insert whatever value is okay here *)) ->
true
| None | Some _ ->
false
2 changes: 2 additions & 0 deletions src/lib/pickles/proof_cache.mli
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ val set_wrap_proof :
-> public_input:Kimchi_bindings.FieldVectors.Fq.t
-> Backend.Tock.Proof.t
-> unit

val is_env_var_set_requesting_error_for_proofs : unit -> bool
4 changes: 4 additions & 0 deletions src/lib/pickles/step.ml
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,10 @@ struct
~public_input:public_inputs
with
| None ->
if
Proof_cache
.is_env_var_set_requesting_error_for_proofs ()
then failwith "Regenerated proof" ;
let%map.Promise proof = create_proof () in
Proof_cache.set_step_proof proof_cache ~keypair:pk
~public_input:public_inputs proof ;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/pickles/wrap.ml
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,10 @@ let wrap
~public_input:public_inputs
with
| None ->
if
Proof_cache.is_env_var_set_requesting_error_for_proofs
()
then failwith "Regenerated proof" ;
let%map.Promise proof = create_proof () in
Proof_cache.set_wrap_proof proof_cache ~keypair:pk
~public_input:public_inputs proof ;
Expand Down
63 changes: 63 additions & 0 deletions src/lib/transaction_snark/test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Tests for the transaction snark

This directory and its subdirectories contain tests for the transaction snark, including consistency checks for the 'in snark' logic with the 'out of snark' version used by block application, and tests for the 'merge' rule for combining transaction snark statements in the scan state.

### Performance considerations

These tests are run on CI for any PR that changes the daemon OCaml code. As such, the tests added here should add value for the time they take, and should not take too long.

#### Caching proofs

The largest performance impact of these tests is the time spent generating proofs; especially for zkApp transactions, where we generate merge proofs as well as the transaction proofs. In order to mitigate this, pickles provides a mode where it will generate the circuit witness, but skips the expensive proving step, using a cache.

The recommended way to enable this cache is:
* add the lines
```ocaml
let proof_cache =
Result.ok_or_failwith @@ Pickles.Proof_cache.of_yojson
@@ Yojson.Safe.from_file "proof_cache.json"
let () = Transaction_snark.For_tests.set_proof_cache proof_cache
```
to the top of the first `%test_module` in the file, to load a proof cache from the `proof_cache.json` file in the directory;
* add the lines
```ocaml
let () =
match Sys.getenv_opt "PROOF_CACHE_OUT" with
| Some path ->
Yojson.Safe.to_file path @@ Pickles.Proof_cache.to_yojson proof_cache
| None ->
()
```
to the bottom of the last `%test_module` in the file, to output the updated proof cache to the path given in the `PROOF_CACHE_OUT` environment variable, when provided;
* update the `dune` file in the test directory to include the libraries
```
ppx_deriving_yojson.runtime
result
```
* update the same `dune` file's `inline_tests` stanza to include `(deps proof_cache.json)`, for example
```diff
- (inline_tests (flags -verbose -show-counts))
+ (inline_tests (flags -verbose -show-counts) (deps proof_cache.json))
```

For a concrete example, see commit [61afcaee844d5966331ddaee11fd8820f6dc1c8a](https://github.com/MinaProtocol/mina/commit/61afcaee844d5966331ddaee11fd8820f6dc1c8a).

Then, to update the cache for a set of tests, we can run the tests to update their contents. For example, to update the tests in `delegate`, `app_state`, `token_symbol`, `permissions`, and `voting_for`, we can run:
```bash
for DIR in ./delegate ./app_state ./token_symbol ./permissions ./voting_for; do
# Initialize the target file
echo [] > $DIR/proof_cache.json;
# Stage the new file for a git commit
git add -N $DIR/proof_cache.json;
# Generate the cache file by running the tests
PROOF_CACHE_OUT=$PWD/$DIR/proof_cache.json dune runtest $DIR;
# Re-run the tests using the cache. Throws an error if the test is
# non-deterministic and caused a cache miss.
ERROR_ON_PROOF=true dune runtest $DIR;
done
```

**In case an error *is* generated, you should not commit the cache before making the test deterministic.**

If none of the updates generated an error, the results can be committed to the repository, and future CI runs will benefit from the speed-up of using the cached proofs.
14 changes: 14 additions & 0 deletions src/lib/transaction_snark/test/app_state/app_state.ml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
open Core_kernel
open Mina_base
open Pickles_types

Expand All @@ -21,5 +22,18 @@ end

let%test_module "Update account app_state" =
( module struct
let proof_cache =
Result.ok_or_failwith @@ Pickles.Proof_cache.of_yojson
@@ Yojson.Safe.from_file "proof_cache.json"

let () = Transaction_snark.For_tests.set_proof_cache proof_cache

include Transaction_snark_tests.Test_zkapp_update.Make (Test_input)

let () =
match Sys.getenv_opt "PROOF_CACHE_OUT" with
| Some path ->
Yojson.Safe.to_file path @@ Pickles.Proof_cache.to_yojson proof_cache
| None ->
()
end )
4 changes: 3 additions & 1 deletion src/lib/transaction_snark/test/app_state/dune
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
base
core_kernel
yojson
ppx_deriving_yojson.runtime
result
;; local libraries
mina_base.import
pickles
Expand All @@ -28,7 +30,7 @@
transaction_snark_tests
)
(library_flags -linkall)
(inline_tests (flags -verbose -show-counts))
(inline_tests (flags -verbose -show-counts) (deps proof_cache.json))
(preprocess
(pps ppx_snarky ppx_version ppx_jane))
(instrumentation (backend bisect_ppx)))
1 change: 1 addition & 0 deletions src/lib/transaction_snark/test/app_state/proof_cache.json

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/lib/transaction_snark/test/delegate/delegate.ml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
open Core_kernel
open Mina_base
module U = Transaction_snark_tests.Util

Expand All @@ -22,5 +23,18 @@ end

let%test_module "Update account delegate" =
( module struct
let proof_cache =
Result.ok_or_failwith @@ Pickles.Proof_cache.of_yojson
@@ Yojson.Safe.from_file "proof_cache.json"

let () = Transaction_snark.For_tests.set_proof_cache proof_cache

include Transaction_snark_tests.Test_zkapp_update.Make (Test_input)

let () =
match Sys.getenv_opt "PROOF_CACHE_OUT" with
| Some path ->
Yojson.Safe.to_file path @@ Pickles.Proof_cache.to_yojson proof_cache
| None ->
()
end )
4 changes: 3 additions & 1 deletion src/lib/transaction_snark/test/delegate/dune
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
base
core_kernel
yojson
ppx_deriving_yojson.runtime
result
;; local libraries
mina_base.import
pickles
Expand All @@ -28,7 +30,7 @@
transaction_snark_tests
)
(library_flags -linkall)
(inline_tests (flags -verbose -show-counts))
(inline_tests (flags -verbose -show-counts) (deps proof_cache.json))
(preprocess
(pps ppx_snarky ppx_version ppx_jane))
(instrumentation (backend bisect_ppx)))
1 change: 1 addition & 0 deletions src/lib/transaction_snark/test/delegate/proof_cache.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/lib/transaction_snark/test/permissions/dune
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
base
core_kernel
yojson
ppx_deriving_yojson.runtime
result
;; local libraries
mina_base.import
pickles
Expand All @@ -28,7 +30,7 @@
transaction_snark_tests
)
(library_flags -linkall)
(inline_tests (flags -verbose -show-counts))
(inline_tests (flags -verbose -show-counts) (deps proof_cache.json))
(preprocess
(pps ppx_snarky ppx_version ppx_jane))
(instrumentation (backend bisect_ppx)))
14 changes: 14 additions & 0 deletions src/lib/transaction_snark/test/permissions/permissions.ml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
open Core_kernel
open Mina_base

module Test_input : Transaction_snark_tests.Test_zkapp_update.Input_intf =
Expand Down Expand Up @@ -25,5 +26,18 @@ end

let%test_module "Update account permissions" =
( module struct
let proof_cache =
Result.ok_or_failwith @@ Pickles.Proof_cache.of_yojson
@@ Yojson.Safe.from_file "proof_cache.json"

let () = Transaction_snark.For_tests.set_proof_cache proof_cache

include Transaction_snark_tests.Test_zkapp_update.Make (Test_input)

let () =
match Sys.getenv_opt "PROOF_CACHE_OUT" with
| Some path ->
Yojson.Safe.to_file path @@ Pickles.Proof_cache.to_yojson proof_cache
| None ->
()
end )

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/lib/transaction_snark/test/token_symbol/dune
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
base
core_kernel
yojson
ppx_deriving_yojson.runtime
result
;; local libraries
mina_base.import
pickles
Expand All @@ -28,7 +30,7 @@
transaction_snark_tests
)
(library_flags -linkall)
(inline_tests (flags -verbose -show-counts))
(inline_tests (flags -verbose -show-counts) (deps proof_cache.json))
(preprocess
(pps ppx_snarky ppx_version ppx_jane))
(instrumentation (backend bisect_ppx)))

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/lib/transaction_snark/test/token_symbol/token_symbol.ml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
open Core_kernel
open Mina_base

module Test_input : Transaction_snark_tests.Test_zkapp_update.Input_intf =
Expand All @@ -18,5 +19,18 @@ end

let%test_module "Update account token symbol" =
( module struct
let proof_cache =
Result.ok_or_failwith @@ Pickles.Proof_cache.of_yojson
@@ Yojson.Safe.from_file "proof_cache.json"

let () = Transaction_snark.For_tests.set_proof_cache proof_cache

include Transaction_snark_tests.Test_zkapp_update.Make (Test_input)

let () =
match Sys.getenv_opt "PROOF_CACHE_OUT" with
| Some path ->
Yojson.Safe.to_file path @@ Pickles.Proof_cache.to_yojson proof_cache
| None ->
()
end )
4 changes: 3 additions & 1 deletion src/lib/transaction_snark/test/verification_key/dune
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
base
core_kernel
yojson
ppx_deriving_yojson.runtime
result
;; local libraries
mina_base.import
pickles.backend
Expand All @@ -33,7 +35,7 @@
random_oracle
)
(library_flags -linkall)
(inline_tests (flags -verbose -show-counts))
(inline_tests (flags -verbose -show-counts) (deps proof_cache.json))
(preprocess
(pps ppx_snarky ppx_version ppx_jane))
(instrumentation (backend bisect_ppx)))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
open Core_kernel
open Mina_base
open Pickles

Expand Down Expand Up @@ -25,5 +26,18 @@ end

let%test_module "Update account verification key" =
( module struct
let proof_cache =
Result.ok_or_failwith @@ Pickles.Proof_cache.of_yojson
@@ Yojson.Safe.from_file "proof_cache.json"

let () = Transaction_snark.For_tests.set_proof_cache proof_cache

include Transaction_snark_tests.Test_zkapp_update.Make (Test_input)

let () =
match Sys.getenv_opt "PROOF_CACHE_OUT" with
| Some path ->
Yojson.Safe.to_file path @@ Pickles.Proof_cache.to_yojson proof_cache
| None ->
()
end )
4 changes: 3 additions & 1 deletion src/lib/transaction_snark/test/voting_for/dune
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
base
core_kernel
yojson
ppx_deriving_yojson.runtime
result
;; local libraries
mina_base.import
pickles.backend
Expand All @@ -33,7 +35,7 @@
random_oracle
)
(library_flags -linkall)
(inline_tests (flags -verbose -show-counts))
(inline_tests (flags -verbose -show-counts) (deps proof_cache.json))
(preprocess
(pps ppx_snarky ppx_version ppx_jane))
(instrumentation (backend bisect_ppx)))
1 change: 1 addition & 0 deletions src/lib/transaction_snark/test/voting_for/proof_cache.json

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/lib/transaction_snark/test/voting_for/voting_for.ml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
open Core_kernel
open Mina_base

module Test_input : Transaction_snark_tests.Test_zkapp_update.Input_intf =
Expand All @@ -20,5 +21,18 @@ end

let%test_module "Update account voting-for" =
( module struct
let proof_cache =
Result.ok_or_failwith @@ Pickles.Proof_cache.of_yojson
@@ Yojson.Safe.from_file "proof_cache.json"

let () = Transaction_snark.For_tests.set_proof_cache proof_cache

include Transaction_snark_tests.Test_zkapp_update.Make (Test_input)

let () =
match Sys.getenv_opt "PROOF_CACHE_OUT" with
| Some path ->
Yojson.Safe.to_file path @@ Pickles.Proof_cache.to_yojson proof_cache
| None ->
()
end )
4 changes: 3 additions & 1 deletion src/lib/transaction_snark/test/zkapp_uri/dune
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
base
core_kernel
yojson
ppx_deriving_yojson.runtime
result
;; local libraries
mina_base.import
pickles
Expand All @@ -28,7 +30,7 @@
transaction_snark_tests
)
(library_flags -linkall)
(inline_tests (flags -verbose -show-counts))
(inline_tests (flags -verbose -show-counts) (deps proof_cache.json))
(preprocess
(pps ppx_snarky ppx_version ppx_jane))
(instrumentation (backend bisect_ppx)))
1 change: 1 addition & 0 deletions src/lib/transaction_snark/test/zkapp_uri/proof_cache.json

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/lib/transaction_snark/test/zkapp_uri/zkapp_uri.ml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
open Core_kernel
open Mina_base

module Test_input : Transaction_snark_tests.Test_zkapp_update.Input_intf =
Expand All @@ -18,5 +19,18 @@ end

let%test_module "Update account snapp URI" =
( module struct
let proof_cache =
Result.ok_or_failwith @@ Pickles.Proof_cache.of_yojson
@@ Yojson.Safe.from_file "proof_cache.json"

let () = Transaction_snark.For_tests.set_proof_cache proof_cache

include Transaction_snark_tests.Test_zkapp_update.Make (Test_input)

let () =
match Sys.getenv_opt "PROOF_CACHE_OUT" with
| Some path ->
Yojson.Safe.to_file path @@ Pickles.Proof_cache.to_yojson proof_cache
| None ->
()
end )

0 comments on commit 08d678a

Please sign in to comment.