fuel-specs
fuel-specs copied to clipboard
Storage tree differentiate between default and non-default
In light of the most recent exploit on Nomad (https://twitter.com/samczsun/status/1554260106107179010), there's a need to differentiate between default and non-default leaves when querying the contract storage tree.
Current Design
The default value of a leaf in the SMT is empty (i.e. zero bytes). However, when reading from storage, 0 is returned if the leaf is empty. This is lossy since it's discarding information.
https://github.com/FuelLabs/fuel-specs/blob/d19cd0ef6fbac7619d5d04b1f00e869ea78593fc/specs/vm/instruction_set.md?plain=1#L1444
Moreover, there's no way to reset a storage slot; writing 0 is not the same thing as writing an empty value.
Proposed Changes
- Add a new instruction, to clear a storage slot. The instruction resets the given storage slot to the default value (i.e. zero bytes).
- Add an additional register parameter to
SRWandSRWQ, that will be set to a Boolean for whether the given storage slot was empty or not.
Add an additional register parameter to SRW and SRWQ, that will hold a flag for whether the given storage slot was empty or not.
Does "empty" here mean zeroed out? Because that is also lossy. Or will the VM keep track of initialized (occupied) vs uninitialized (cleared) slots in a separate bitfield?
The SMT already differentiates between "empty, i.e. zero bytes" and "32 bytes of zeroes," and therefore so does the VM implicitly. The proposed changes simply expose this in the instruction set.
this is quite poggers if i say so myself
Add an additional register parameter to SRW and SRWQ, that will hold a flag for whether the given storage slot was empty or not.
Not familiar with what SRW and SRWQ are, I thought of a flag type system before to solve this problem (like the sign on a signed int) but then I realized that would tack on a 1 bit cost to every single slot used, might add up quickly? Im assuming thats how SRW works aswell, do you not see this as a potential problem?
There's actually no need for any changes to the SMT because the SMT actually already differentiates between a default leaf and a zero-value non-default leaf. The extra register parameter to SRW and SRWQ would simply be set to zero or one depending on whether the slot was default or non-default.
If we already have this differentiation we should absolutely surface it in SRW and SRWQ. It's free money.
@adlerjohn should we close this issue now? The spec changes are in and the impl is done (pending sequential storage slot access).
Yep!