fix: change initial memory size parameter from 32767 to 0 in witness_calculator
#110
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The current behavior of the witness calculator builder code is that when initializing a witness calculator wasm module, it specifies an initial memory size equal to
32767 * 64kb ~= 2gb
(theinitial
argument is interpreted as 'quantity of pages', and each 'page' in wasm is specified to be64kb
). If allocating that quantity of memory fails, the code performs an exponential backoff with a factor of2
- i.e. it then attempts to allocate1gb
, then512mb
, then256mb
, until allocation succeeds or fails at0
pages.This memory allocation strategy poses a problem for us at zupass. Our app is built primarily for phones, where memory is much more limited than on desktop environments. Thus, in practice, we have found that our website crashes with an OOM after ~2 proofs on older devices, which results in a poor user experience for a non-negligible portion of our users.
After identifying the section of code modified in this PR as being the culprit behind the OOM crashes, I forked and modified the
circom_runtime
andsnarkjs
libraries with the same change that I am proposing in this pull request. These forks are now included in the zupass repo here. I verified that this change worked properly by making sure that my forkedsnarkjs
depended on my forkedcircom_runtime
, and that the tests defined in my forkedsnarkjs
package indeed passed.logs from running `yarn test` in my fork of snarkjs
Another change I performed on the
zupass
end is that I used the npmpatch-package
package to manually patch these two lines of code during package installation of our dependencies. You can see how I did that here. I tested that proving and verifying our zk proofs worked properly by running the proving and verification code via some UI interactions that zupass supports.It is my understanding that memory can be allocated dynamically by the wasm runtime. From perusing this package, it seems that the wasm builder code is a c++ program, which uses
malloc
, which I understand to be possible in wasm due to the existence of thememory.grow
instruction. From my current perspective, it seems that specifying an initial memory size is not strictly necessary for the proper functioning of a wasm module. Perhaps this implementation was designed to be the way that it is to increase the performance of a single-proof use-case? I could see it being possible that the current behavior results in faster proving due to not having to allocate wasm memory multiple times.Anyways, I do not have a full understanding of how the code I am proposing to modify ended up in the state that it is now, and would appreciate some guidance/explanation if possible. Additionally, perhaps there are some technical limitations to changing the initial memory size to be
0
that I am not aware of due to a lack of context.To conclude: I believe this proposed change to be a strict improvement over the current implementation (holding some space for uncertainty), as it enables a larger quantity of proofs to be generated in memory-constrained environments, which are the environments we are targeting with zupass.
Please let me know if there is any other information needed to get this merged, or how we might arrive to more certainty regarding the correctness of this change.