-
Notifications
You must be signed in to change notification settings - Fork 618
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
feat: Add precompiled contracts for alt_bn128 curve [rebased] #3971
Conversation
@evgenykuzyakov Depending on when this would be merged, let's coordinate with #3954. |
…o feature/alt_bn128_fork
Here is the param estimator run with 200000/20000 accounts: https://gist.github.com/evgenykuzyakov/5ac71f68da3eab1d37dae33c60c35eda
|
There is an issue with the way these functions accept arguments. Basically, the arguments to all these functions are arrays of fixed-sized structures. The functions take their arguments in Borsh-serialized form: first 4 bytes encode the length, and the remaining bytes are the concatenation of encoded elements. It is easy to notice that the length is redundant: since the size of each element is the same, the number of elements can be easily computed from the length of the input. Also, any code that is going to call these functions (e.g. SDK code) will already have these structures as an array, but without the length prepended. So, it will probably have to copy the entire array just to prepend this value which is useless anyway. Also, this code charges gas per byte, while it would be more correct to charge it per element. So, replacing Borsh deserialization with a trivial one (check that the input length is a multiple of the number of bytes per element, then decode each element) would make the code more efficient both on the contract side and on the runtime side. |
@evgenykuzyakov please take a look at what @abacabadabacaba said |
But all other parameters still has to be serialized with Borsh. You don't just copy them in. So you have to manually serialize every element to save 4 bytes. You still need a copy. |
@evgenykuzyakov Isn't it possible to take the values directly from a slice, without Borsh serialization? Suppose that you have a Rust slice with those structures inside a smart contract, and you pass its address and length (in bytes) to the host function, can't the host function just decode this data? In this case, no Borsh is needed on the smart contract side at least. |
it's possible to do, but the inner structure are still Borsh encoded. The inner structure memory alignment is not guaranteed to match Borsh alignment. While Borsh specific serialization gives such guarantee. |
As far as I understand, the inner structures basically consist of fixed-size integers, and their in-memory representation matches their Borsh representation. So Borsh serialization will mostly just copy data in memory (but in an inefficient way), and that can be avoided just by not using Borsh serialization and instead passing the in-memory data directly. In any case, the alignment of any values in smart contract memory must be deterministic and repeatable (because the execution of smart contracts in general is deterministic and repeatable). |
Just to add into this a little bit, shouldn't we maintain our own |
Merged latest.
Based on #2842 by @snjax
This feature adds to near following precompiled contracts:
Example of usage is at https://github.com/zeropoolnetwork/near-groth16-verifier
TODO:
Test plan: