-
Notifications
You must be signed in to change notification settings - Fork 139
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
Add check for storage of nonstorable values #3397
Conversation
Cadence Benchstat comparisonThis branch with compared with the base branch onflow:master commit 81170a2 Collapsed results for better readability
|
@@ -2952,6 +2973,10 @@ func (v *ArrayValue) Storable( | |||
return v.array.Storable(storage, address, maxInlineSize) | |||
} | |||
|
|||
func (*ArrayValue) IsStorable() bool { | |||
return true |
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 should probably recursively check the elements
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.
Is this necessary? For some reason (I don't fully get why) the test I added for this case that tries to store an array of references already fails even when this is true
. Are the individual elements of the array already being checked for storability when they are being put into the atree array perhaps?
@@ -19682,6 +19743,10 @@ func (v *DictionaryValue) Storable( | |||
return v.dictionary.Storable(storage, address, maxInlineSize) | |||
} | |||
|
|||
func (*DictionaryValue) IsStorable() bool { | |||
return true |
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.
Same as above for arrays
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.
Same question as above
@@ -142,6 +142,7 @@ type Value interface { | |||
// NOTE: memory metering is unnecessary for Clone methods | |||
Clone(interpreter *Interpreter) Value | |||
IsImportable(interpreter *Interpreter, locationRange LocationRange) bool | |||
IsStorable() bool |
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.
Please add some interpreter tests for this new function
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.
CompositeValue
already has a IsStorable
function, but it needs to be adjusted to also recursively check fields.
Until now, CompositeValue.IsStorable
was called during encoding, in the phase converting from interpreter.Value
to atree.Storable
, in CompositeValue.Storable()
. The existing function was sufficient, because atree calls Storable()
recursively, so indirectly checking for storability (some Storable()
implementations return an error when the value is non-storable).
This recursive checking, which is also needed for other containers (see below), is potentially expensive.
Co-authored-by: Bastian Müller <[email protected]>
Part of https://github.com/dapperlabs/cadence-internal/issues/235
Prevents sticking nonstorable things in storage by casting them through
AnyStruct
Thanks @bluesign for the report
master
branchFiles changed
in the Github PR explorer