-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[Perf] A revival of 1955 & 2145 #3127
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
base: staging
Are you sure you want to change the base?
Conversation
Signed-off-by: ljedrz <[email protected]>
… execution Signed-off-by: ljedrz <[email protected]>
Signed-off-by: ljedrz <[email protected]>
…patible Signed-off-by: ljedrz <[email protected]>
Signed-off-by: ljedrz <[email protected]>
iamalwaysuncomfortable
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vicsn made several comments.
Probably the most important is that for wasm we'll also need to build some tooling to adjust the parameters ahead of time. This requires some thought how to do correctly.
I'd like to proceed with this, would you suggest that Konstantin and I take on the role of carrying this to the finish line or do you recommend someone in protocol do it. Either way, I think we can get this in.
|
|
||
| /// The key used to commit to polynomials in Lagrange basis. | ||
| pub lagrange_bases_at_beta_g: BTreeMap<usize, Vec<E::G1Affine>>, | ||
| /// This is `None` if `self` does not support lagrange bases |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /// This is `None` if `self` does not support lagrange bases | |
| /// This is `None` if `self` does not support lagrange bases. |
| /// to the new degree_bounds The `powers_of_beta_times_gamma_g` is only | ||
| /// dependent on the `hiding_bound` so doesn't change This only works if | ||
| /// the SRS max_degree is fixed across specializations Note that this | ||
| /// implementation is not atomic. If specialize fails halfway through, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment should be completed.
| pub fn update(&mut self, srs: &UniversalParams<E>, degree_info: &DegreeInfo) -> Result<()> { | ||
| let trim_time = start_timer!(|| "Trimming public parameters"); | ||
|
|
||
| // The maximum degree required by the circuit polynomials |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot please add a commit that adds periods to all doc comments.
|
|
||
| use std::collections::BTreeSet; | ||
|
|
||
| #[derive(Clone, Debug, Default)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| #[derive(Clone, Debug, Default)] | |
| /// Degree info specifies information needed to determine which powers to use to build the CommitterKey from the SRS. | |
| #[derive(Clone, Debug, Default)] |
| let degree_diff = highest_degree_bound - new_highest_degree_bound; | ||
| shifted_powers_of_beta_g = shifted_powers_of_beta_g.drain(degree_diff - 1..).collect_vec(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may want to disable this in wasm and/or making trimming a manual call as we'll want to keep the SRS in place up to the max degree of the function in storage.
| 2 * self.num_constraints, // zerocheck poly degree | ||
| 2 * self.num_public_and_private_variables, // lineval sumcheck poly degree | ||
| 2 * self.num_non_zero_a, // matrix sumcheck poly degree | ||
| 2 * self.num_non_zero_b, // matrix sumcheck poly degree | ||
| 2 * self.num_non_zero_c, // matrix sumcheck poly degree |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vicsn this I think was possibly done before the changes in Arithmetization? Are these still valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I should double check this, thx for the ping
| Ordering::Greater => { | ||
| let lowest_shift_degree = max_degree - new_highest_degree_bound; | ||
| let highest_shift_degree = max_degree + 1 - highest_degree_bound; | ||
| let mut new_powers = srs.powers_of_beta_g(lowest_shift_degree, highest_shift_degree)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although this PR helps a ton by reducing key sizes, this becomes the new pain in the butt for those without filesystems because at the very best, it invokes synchronous XmlHttpRequest and that works (browsers are ending support for it) but it may block the app during the i/o. At worst, this fails and there's no access to the parameters.
There are three options to fix this:
- Cache the pieces of the SRS fetched into memory somewhere and modify this logic slightly to fetch from cache.
- Provide an
externfunction is implementable by outside callers which allows custom fetching logic, but validates param integrity with a checksum. - Find some way to do this asynchronously at an earlier point. The SDK is a custom executor, so it could potentially call parameter updates from degree bounds stated within pk/vks so that the SRS is properly trimmed by this point.
We'll have to do some current testing to ensure that XmlHttpRequest is still working in most browsers, otherwise we lose the ability to do local Proving if we DO have proving keys.
| for (((circuit_specific_state, batch_combiner), assignments_i), matrix_transposes_i) in state | ||
| .circuit_specific_states | ||
| .iter_mut() | ||
| .values_mut() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ljedrz is this safe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what aspect of safety do you have in mind? mutating values of a BTreeMap is perfectly fine, only the keys may not be modified
| let circuit_verifying_key = CanonicalDeserialize::deserialize_compressed(&mut reader)?; | ||
| let circuit = CanonicalDeserialize::deserialize_compressed(&mut reader)?; | ||
| let committer_key = Arc::new(FromBytes::read_le(&mut reader)?); | ||
| let committer_key = match bool::read_le(&mut reader) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This serialization isn't strictly backwards compatible, this will break for old proving keys because there's no flag supporting it in the original version. A serialization helper needs to be developed to handle legacy proving keys and thus this needs a bit more work to be fully backwards compatible.
@vicsn @ljedrz what's the bandwidth in protocol for this? Should start working on addressing our own comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx for the ping. Lukasz can make it backwards compatible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually already had it, just needed to push; it's in 8083480.
| let degree_info = degree_info.unwrap(); | ||
|
|
||
| let ck = CommitterUnionKey::union(std::iter::once(&committer_key)); | ||
| universal_prover.update(srs, degree_info)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a piece in wasm that we may have to call externally, which will necessarily mean we need the vks easily to crossreference all this info.
Could degree info potentially be gleaned from an authorization similarly to how the execution cost was? If so that'd give us a natural stopping point in the case where a wallet doesn't have all proving keys loaded (highly possible).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The degree info / CircuitInfo is in the synthesized ProvingKey/VerifyingKey. I think there's no way to quickly get it otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay that implies clients will need to collect the pk/vks, that's acceptable.
|
@iamalwaysuncomfortable I've opened a new pull request, #3134, to work on those changes. Once the pull request is ready, I'll request review from you. |
@iamalwaysuncomfortable @kpandl sounds good, we'll await your instructions for next steps, as you have context on the SDK side of things. |
iamalwaysuncomfortable
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iamalwaysuncomfortable @kpandl sounds good, we'll await your instructions for next steps, as you have context on the SDK side of things.
Next week I'll ensure we address two separate concerns that preclude usage of this PR by the wallet.
Issue 1: Power Downloads
- No caching or external storage available without file systems: No external storage exists in
wasmand certain other systems like secure enclaves. This means both that the SRS can only be stored in memory currently and the only way to do this is with an internet connection (which is not always available). This means for EVERY Aleo web app, it must download hundreds of MB potentially for each usage of the web app. - Deprecrated Synchronous XmlHttpDownloads Required: Currently all parameter downloads are through this deprecated function (which is at potential risk of being unsupported entirely in future browsers) 2X the size of any downloads to be allocated due to the need to first change to a text-based encoding of the bytes first.
Issue 2: CommitterKey Population
Because this PR shifts the concern of SRS updates to the update function instead of importing SRS pieces from the Proving key. Any offline transactions on the web or environments where Sync XmlHttpRequests fail to work will lose the ability to prove.
Potential solutions:
I see the following solutions solve the above two problems, we'll make these PRs hopefully over the next two weeks.
- Power Download Estimation (+ Optional Download): Functions that take in a group of proving key and verifying keys that specify the powers which must be inserted into the SRS and whether they currently exist in the SRS. These should optionally download the parameters asynchronously for clients who desire it.
- External parameter insertion: Functions that allow parameters to be inserted externally so that after estimation, the executor can download the parameters (or fetch them from local storage) and insert them. This will ensure the wallet does not have continually download powers. These should be verified by checksums when inserted.
- Constraint Estimation for Functions in Development: In the case where a function that has NOT yet been synthesized (i.e. developers making new functions) and no vk is available, a function that builds the circuit once and gets the circuit info as a first step should be developed.
Once we have these in place, we can carry this PR the rest of the way.
|
A secondary note on what the result of the above proposal + this PR for the wallet. Once this is in, wallets will be able to do the following:
Currently most wallets synthesize keys every time and the synthesis + download i/o is a significant portion of the time. This PR will significantly boost the local proving story. |
This PR is a fresh implementation of #1955 combined with #2145, which built on it. Both were contained in a single commit each, and a few adjustments were necessary in order to work with the current codebase, but nothing too complex.
The affected benchmarks are:
Filing as a draft, as backward compatibility (at least some serialization) still needs to be resolved.
CC @niklaslong