Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deterministic tests #345

Closed
wants to merge 12 commits into from
Closed

Deterministic tests #345

wants to merge 12 commits into from

Conversation

adria0
Copy link
Member

@adria0 adria0 commented May 31, 2024

Make tests deterministic

  • Create new crate halo2_debug with some utilities, it can be reused for Adding debugging & testing utils #343
  • Instead using OsRng, use a test_rng() fo random and a one_rng() for deterministic randomness.
  • Only use rand_chacha for seeded randomness.
  • Remove integrated dhat profiling, it is activated in cargo test in M3 as also in coverage, creating crashes (since it's already activated). Also remove the associated heap-profining feature (that is activated with --all-features)

@codecov-commenter
Copy link

codecov-commenter commented Jun 3, 2024

Codecov Report

Attention: Patch coverage is 80.00000% with 12 lines in your changes missing coverage. Please review.

Project coverage is 82.08%. Comparing base (80e69b9) to head (a309ab1).
Report is 1 commits behind head on main.

Files Patch % Lines
halo2_debug/src/lib.rs 65.21% 8 Missing ⚠️
halo2_backend/src/poly/ipa/commitment.rs 77.77% 2 Missing ⚠️
halo2_backend/src/poly/kzg/commitment.rs 71.42% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #345      +/-   ##
==========================================
+ Coverage   81.90%   82.08%   +0.18%     
==========================================
  Files          82       83       +1     
  Lines       17019    17218     +199     
==========================================
+ Hits        13939    14133     +194     
- Misses       3080     3085       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@adria0 adria0 marked this pull request as ready for review June 3, 2024 08:30
@ed255
Copy link
Member

ed255 commented Jun 3, 2024

15,756 lines diff is a lot of lines to review!
Maybe you can remove halo2_proofs/dhat-heap.json :P

@adria0
Copy link
Member Author

adria0 commented Jun 3, 2024

15,756 lines diff is a lot of lines to review! Maybe you can remove halo2_proofs/dhat-heap.json :P

image

what a fancy PR! let's me remove it.

update: removed in ed4c33b

Copy link
Member

@ed255 ed255 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken a first look, left some comments and questions :)

halo2_debug/src/lib.rs Show resolved Hide resolved
halo2_proofs/tests/frontend_backend_split.rs Outdated Show resolved Hide resolved
halo2_debug/src/lib.rs Outdated Show resolved Hide resolved
// Check the a test proof against a known hash
// Note that this function is only called in CI in "cargo test --all-fetaures"
pub fn assert_test_proof<D: AsRef<[u8]>>(hex: &str, data: D) {
if cfg!(all(feature = "thread-safe-region", not(coverage))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two questions about this:

  1. The halo2_debug crate doesn't have any feature, which makes me think this is never activated
  2. What's the rationale behind using thread-safe-region for this? When this feature is not enabled in the frontend, a region is not thread safe, and thus parallel witness generation is not supported; but it this feature shouldn't affect the determinism of the proof generation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cause I'm getting different proofs if I activate test_mycircuit_full_legacy with thread-safe-region!

Copy link
Member

@ed255 ed255 Jun 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cause I'm getting different proofs if I activate test_mycircuit_full_legacy with thread-safe-region!

I see, we should investigate why this is happening.

Also please take a look at my point 1 :) Let me know if I'm missing something, but I tried running the tests with --all-features and the assertion was not triggered.

halo2_proofs/tests/frontend_backend_split.rs Outdated Show resolved Hide resolved
use rand_core::OsRng;
use tiny_keccak::Hasher;

// One number generator, that can be used as a deterministic Rng, outputing fixed values.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, the comments you added could be done with /// and then they become documentation.

Copy link

@davidnevadoc davidnevadoc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a doubt about the scope of the PR.
This PR intend makes the tests deterministic, but does it intend to make the proof generation deterministic too? 🤔
I like the idea of having the random input of tests determined by a fixed seed, so that the tests can be easily reproduced. However, having the same mechanism for the random values of the protocol, like the blinders, may be a security issue. What is the idea for this type of randomness? @adria0 @ed255

fn new(k: u32) -> Self {
Self::setup(k, OsRng)
fn new(k: u32, rng: impl RngCore) -> Self {
Self::setup(k, rng)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put the new rng here directly (in setup()) instead of having it in new()?.
We just want randomness in the setup of mock KZG parameters, but we don't need it in IPA so IMO it's better not to modify the common interface of ParamsProver.

use crate::poly::EvaluationDomain;
use halo2curves::bn256::{Bn256, Fr};

let engine = H2cEngine::new();
let params = ParamsKZG::<Bn256>::new(K);
let params = ParamsKZG::<Bn256>::new(K, test_rng());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This randomness is used to generate mock params for testing, so test_rng() is fine here.

@@ -477,7 +476,7 @@ mod test {

let b = domain.lagrange_to_coeff(a.clone());

let alpha = Blind(Fr::random(OsRng));
let alpha = Blind(Fr::random(test_rng()));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this randomness is part of the real protocol, here we need some security guarantees so we probably want to use a different randomness source rather than test_rng(). I think keeping OsRng here is fine.

@@ -256,7 +256,7 @@ mod test {

let mut transcript = T::init(vec![]);

let blind = Blind::new(&mut OsRng);
let blind = Blind::new(&mut test_rng());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous comment, this randomness is not part of the testing.

@@ -297,7 +297,7 @@ mod test {

let prover = P::new(params);
prover
.create_proof(&mut OsRng, &mut transcript, queries)
.create_proof(&mut test_rng(), &mut transcript, queries)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% on this one, but I'd say its not part of testing either.

@@ -35,7 +35,7 @@ rayon = "1.8"
ark-std = { version = "0.3" }
proptest = "1"
group = "0.13"
rand_xorshift = "0.3.0"
rand_chacha = "0.3.0"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is chacha used instead of xorshift?
I believe we are using xorshift in halo2curves. Should we make the switch there too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly just having one seed randomness generator for the whole halo2 package. Makes any sense to use more than one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to use the same seed random generator in the whole halo2 package. I do not see the point to use two if not is really needed.

@adria0
Copy link
Member Author

adria0 commented Jun 5, 2024

I have a doubt about the scope of the PR. This PR intend makes the tests deterministic, but does it intend to make the proof generation deterministic too? 🤔 I like the idea of having the random input of tests determined by a fixed seed, so that the tests can be easily reproduced. However, having the same mechanism for the random values of the protocol, like the blinders, may be a security issue. What is the idea for this type of randomness? @adria0 @ed255

Also, this is not related to determinitic tests, so I remove it, rethink, and make a future PR, if needed.

@adria0
Copy link
Member Author

adria0 commented Jun 5, 2024

@ed255 @davidnevadoc I'll be rolling back some changes and I prefer to replace this PR to keep clean history again.

@adria0 adria0 closed this Jun 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants