Open nventuro opened 3 months ago
This will likely result in ScheduledValueChange
requiring that T
implements the serde traits (instead of to/from field).
Napkin math of saving on the Token::transfer
function with this.
We need to lookup 2 users keys.
One lookup should cost ~17K Currently a lookup of a key is 27K, but we are really doing two lookups of 10k + 6.5K for the case where it is in the address).
The cost should therefore be ~34K.
What is our current cost:
npk
, ovpk
, ivpk
for the sender
npk
, ivpk
for the recipient
Meaning that we have 5 lookups of 27K -> ~135K spent on key rotation.
We should save 101K constraints by having this in.
@iAmMichaelConnor, not sure where you would ideally have some of these numbers 🤷
Can a sharedMutable be hashed into a single field?
I.e. store the following in a single storage slot:
(I forget the naming and mechanics of how sharedMutable has been implemented, but hopefully you get the gist).
If that's all stored in a single slot, for a particular user address, then to read that slot from the archive tree, it's ~80 constraints for poseidon2 of 2 fields * 40 height = 3200 constraints. To unpack all that data listed above, something like a poseidon2 of 10 fields - maybe ~400 constraints. To unpack the signs, a few constraints. To recompute the y-coords: 4 or 5 constraints per point. Although there might need to be a range check, to check the 'negative-ness', in which case all this messing around with signs might be unnecessary and similar in cost to poseidon-hashing the y-coords directly into the slot's hash value. Meh, for an estimate, let's say the coordinates aren't compressed, then instead of ~400 constraints, it's more like a poseidon2 of 16 fields - maybe ~640 constraints. So 3200 + 640 = 4000 constraints to read the keys from the registry for 1 address. 8000 for two addresses. And if we're in the case where the address isn't-yet registered in the registry, we should be re-purposing the poseidon hashes that were used for unpacking above. I.e. we read the registry, find that the value is 0 (or maybe some known hash of 0's if we're reading a hash of some empty shared mutable slot), and then pass the address's preimage data to the existing poseidon hashes. So this case should add approx 0 extra gates.
So I reckon 8000 to read all keys for sender & recipient.
Can a sharedMutable be hashed into a single field?
Yes, that is done as part of #7169. So we have the logic. But you still need the values to be there such that you can actually read them and open (using oracles). This issue is just to fix the latter, but is blocked by noir atm.
https://github.com/AztecProtocol/aztec-packages/pull/5490 introduced a version of
SharedMutable<T>
whereT
is required to implementFromField
, meaning it must fit inside aField
wrapper value. While this is fine for values such asAztecAddress
, we'll eventually want to store multi-field structs, and so this constraint will need to be relaxed.We may implement this by relying solely on
Serialize
andDeserialize
, but are likely going to run into trouble until https://github.com/noir-lang/noir/issues/4633 is fixed, since creating an array out of multiple single-field elements is the core issue there.