cadence icon indicating copy to clipboard operation
cadence copied to clipboard

add `forceSave` function to save and overwrite stored data

Open dsainati1 opened this issue 3 years ago • 12 comments

Closes #1244

Description

Adds the following method to AuthAccount objects:

fun forceSave<T>(_ value: T, to path: Path): Bool

This will save a value to the specified path, overwriting any data present (and destroying it if it is a resource). Returns whether or not any data was overwritten.


  • [X] Targeted PR against master branch
  • [X] Linked to Github issue with discussion and accepted design OR link to spec that describes this work
  • [X] Code follows the standards mentioned here
  • [X] Updated relevant documentation
  • [X] Re-reviewed Files changed in the Github PR explorer
  • [X] Added appropriate labels

dsainati1 avatar Nov 17 '21 20:11 dsainati1

Cadence Benchstat comparison

This branch with compared with the base branch onflow:master commit 81c63bfef73cd4874d05b6274dbd2402a0a0b788 The command go test ./... -run=XXX -bench=. -shuffle=on -count N was used. Bench tests were run a total of 7 times on each branch.

Results

old.txtnew.txt
time/opdelta
ParseInfix-227.2µs ± 3%28.0µs ± 3%+2.66%(p=0.038 n=7+7)
InterpretRecursionFib-22.92ms ± 1%2.99ms ± 4%+2.45%(p=0.035 n=6+7)
RuntimeFungibleTokenTransfer-21.44ms ±32%1.33ms ± 5%~(p=1.000 n=7+7)
RuntimeResourceDictionaryValues-217.9ms ± 4%17.5ms ± 3%~(p=0.073 n=7+7)
RuntimeStorageWriteCached-2153µs ± 4%186µs ±35%~(p=0.620 n=7+7)
ParseArray-225.4ms ± 2%26.2ms ± 4%~(p=0.073 n=7+7)
ParseFungibleToken-2527µs ± 2%526µs ± 3%~(p=0.805 n=7+7)
ParseDeploy/decode_hex-21.61ms ± 1%1.58ms ± 3%~(p=0.053 n=7+7)
QualifiedIdentifierCreation/One_level-23.54ns ± 1%3.63ns ± 4%~(p=0.051 n=6+7)
CheckContractInterfaceFungibleTokenConformance-2182µs ± 5%181µs ± 2%~(p=0.628 n=7+6)
ContractInterfaceFungibleToken-251.2µs ± 1%51.8µs ± 4%~(p=0.534 n=6+7)
NewInterpreter/new_interpreter-21.26µs ± 3%1.26µs ± 1%~(p=1.000 n=7+6)
NewInterpreter/new_sub-interpreter-22.28µs ± 1%2.30µs ± 4%~(p=0.639 n=5+7)
ParseDeploy/byte_array-239.1ms ± 1%38.4ms ± 1%−1.71%(p=0.002 n=6+6)
QualifiedIdentifierCreation/Three_levels-2178ns ± 2%175ns ± 3%−1.77%(p=0.026 n=7+7)
 
alloc/opdelta
RuntimeFungibleTokenTransfer-2233kB ± 0%234kB ± 0%+0.40%(p=0.001 n=7+7)
RuntimeResourceDictionaryValues-24.34MB ± 0%4.34MB ± 0%+0.02%(p=0.001 n=7+7)
RuntimeStorageWriteCached-283.7kB ± 0%83.7kB ± 0%~(p=1.000 n=6+6)
QualifiedIdentifierCreation/One_level-20.00B 0.00B ~(all equal)
QualifiedIdentifierCreation/Three_levels-264.0B ± 0%64.0B ± 0%~(all equal)
CheckContractInterfaceFungibleTokenConformance-266.4kB ± 0%66.4kB ± 0%~(p=0.462 n=7+7)
ContractInterfaceFungibleToken-226.7kB ± 0%26.7kB ± 0%~(all equal)
InterpretRecursionFib-21.21MB ± 0%1.21MB ± 0%~(p=1.000 n=7+6)
NewInterpreter/new_interpreter-2680B ± 0%680B ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-21.06kB ± 0%1.06kB ± 0%~(all equal)
 
allocs/opdelta
RuntimeFungibleTokenTransfer-24.42k ± 0%4.43k ± 0%+0.05%(p=0.001 n=7+6)
RuntimeResourceDictionaryValues-2108k ± 0%108k ± 0%+0.00%(p=0.004 n=7+7)
RuntimeStorageWriteCached-21.42k ± 0%1.42k ± 0%~(all equal)
QualifiedIdentifierCreation/One_level-20.00 0.00 ~(all equal)
QualifiedIdentifierCreation/Three_levels-22.00 ± 0%2.00 ± 0%~(all equal)
CheckContractInterfaceFungibleTokenConformance-21.07k ± 0%1.07k ± 0%~(all equal)
ContractInterfaceFungibleToken-2458 ± 0%458 ± 0%~(all equal)
InterpretRecursionFib-225.0k ± 0%25.0k ± 0%~(all equal)
NewInterpreter/new_interpreter-211.0 ± 0%11.0 ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-231.0 ± 0%31.0 ± 0%~(all equal)
 

github-actions[bot] avatar Nov 17 '21 20:11 github-actions[bot]

Codecov Report

Merging #1252 (b8b1d5b) into master (81c63bf) will increase coverage by 0.03%. The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1252      +/-   ##
==========================================
+ Coverage   77.60%   77.63%   +0.03%     
==========================================
  Files         274      274              
  Lines       35233    35281      +48     
==========================================
+ Hits        27341    27389      +48     
  Misses       6805     6805              
  Partials     1087     1087              
Flag Coverage Δ
unittests 77.63% <100.00%> (+0.03%) :arrow_up:

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
runtime/interpreter/account.go 93.16% <100.00%> (+0.17%) :arrow_up:
runtime/interpreter/interpreter.go 89.23% <100.00%> (+0.09%) :arrow_up:
runtime/sema/authaccount_type.go 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 81c63bf...b8b1d5b. Read the comment docs.

codecov-commenter avatar Nov 17 '21 21:11 codecov-commenter

Is it safe to add stuff like this and the clear method? It might encourage people to use bad practices for handling resources

joshuahannan avatar Nov 17 '21 21:11 joshuahannan

forceSave and clear are both safe with respect to resources because they will destroy any resources that are potentially saved at the destination. Neither method really adds any new functionality to the language; they only make certain patterns easier.

account.clear(/storage/x)

is equivalent to

let r <- account.load<@R>(/storage/x)
destroy r

while

account.forceSave(<-r, /storage/x)

is equivalent to

account.clear(/storage/x)
account.save(<-r, /storage/x)

dsainati1 avatar Nov 17 '21 21:11 dsainati1

I understand that they are just simpler patters for things that already exist, but I feel like this kind of blurs the line on the rule "resources cannot be lost, they have to be explicitly destroyed". To me, this is not explicit destruction and kind of breaks that rule, and I could see some people reverting to using these by default instead of the more explicit versions that we currently use, which could cause unintended loss of resources in some circumstances.

I would support adding these for non-resource types, but it makes me nervous to add them for resource types

joshuahannan avatar Nov 17 '21 23:11 joshuahannan

I agree with @joshuahannan, when you give developer hammer, everything seems like nail to them, for example: when setting up FUSD Vault imagine developer accidentally override.

I think storage system ( cadence part ) needs a rethinking, instead of adding features. Those changes are not solving any serious problem, like storage sandboxing etc...

I was expecting after storage improvements, there would be some work on this area. IMO at least we need:

  • sandboxing ( dapp isolation )
  • capability revoke
  • loading types which does not exist anymore

If it was up to me, I would even get rid of Paths totally.

bluesign avatar Nov 18 '21 10:11 bluesign

@dete Any thoughts here?

turbolent avatar Nov 19 '21 21:11 turbolent

@bluesign Fair enough on the feedback on this PR in particular, but this PR isn't the right place to vent your expectations about the roadmap. Please keep the conversation productive and focused on this PR in particular. Thanks

turbolent avatar Nov 20 '21 00:11 turbolent

@bluesign Fair enough on the feedback on this PR in particular, but this PR isn't the right place to vent your expectations about the roadmap. Please keep the conversation productive and focused on this PR in particular. Thanks

sorry about that, I went off topic a bit. :(

bluesign avatar Nov 20 '21 07:11 bluesign

@dsainati1 Should we maybe consider this change for Stable Cadence?

turbolent avatar Oct 04 '22 23:10 turbolent

@dsainati1 Should we maybe consider this change for Stable Cadence?

See comment on https://github.com/onflow/cadence/pull/1253

dsainati1 avatar Oct 05 '22 14:10 dsainati1

Put on-hold for now, see https://github.com/onflow/cadence/blob/master/meetings/2022-10-11.md#additional-storage-api-functions

turbolent avatar Oct 12 '22 18:10 turbolent

Seems like this feature is not wanted; closing.

dsainati1 avatar Jan 13 '23 18:01 dsainati1