cadence icon indicating copy to clipboard operation
cadence copied to clipboard

Detect invalidated references statically

Open SupunS opened this issue 3 years ago • 5 comments

Working towards the FLIP: https://github.com/onflow/flow/pull/1043

Description

Statically check for invalidated references, whenever possible.

All invalidations may not be caught by the static checker. Hence the runtime validation is also added in: https://github.com/onflow/cadence/pull/1999


  • [ ] 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

SupunS avatar Oct 06 '22 00:10 SupunS

Codecov Report

Merging #2037 (c24f027) into feature/stable-cadence (abc0b07) will decrease coverage by 0.02%. The diff coverage is 98.40%.

@@                    Coverage Diff                     @@
##           feature/stable-cadence    #2037      +/-   ##
==========================================================
- Coverage                   77.70%   77.67%   -0.03%     
==========================================================
  Files                         304      304              
  Lines                       63125    63252     +127     
==========================================================
+ Hits                        49050    49133      +83     
- Misses                      12364    12411      +47     
+ Partials                     1711     1708       -3     
Flag Coverage Δ
unittests 77.67% <98.40%> (-0.03%) :arrow_down:

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

Impacted Files Coverage Δ
runtime/sema/checker.go 92.04% <ø> (ø)
runtime/sema/check_variable_declaration.go 97.55% <98.13%> (+0.34%) :arrow_up:
runtime/sema/check_assignment.go 97.26% <100.00%> (+0.01%) :arrow_up:
runtime/sema/check_expression.go 100.00% <100.00%> (ø)
runtime/sema/errors.go 73.52% <100.00%> (+0.04%) :arrow_up:
runtime/interpreter/storage.go 69.04% <0.00%> (-1.59%) :arrow_down:
runtime/interpreter/errors.go 55.94% <0.00%> (-0.89%) :arrow_down:
runtime/interpreter/value.go 71.49% <0.00%> (-0.32%) :arrow_down:
runtime/interpreter/interpreter.go 88.89% <0.00%> (-0.11%) :arrow_down:
runtime/parser/statement.go 82.97% <0.00%> (+0.05%) :arrow_up:
... and 1 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

codecov[bot] avatar Oct 06 '22 00:10 codecov[bot]

Cadence Benchstat comparison

This branch with compared with the base branch onflow:feature/stable-cadence commit 72b3292fff3a22bc8e7982842feb155a45c36937 The command for i in {1..N}; do go test ./... -run=XXX -bench=. -benchmem -shuffle=on; done was used. Bench tests were run a total of 7 times on each branch.

Collapsed results for better readability

old.txtnew.txt
time/opdelta
CheckContractInterfaceFungibleTokenConformance-2167µs ± 4%159µs ± 3%−4.32%(p=0.038 n=7+7)
ContractInterfaceFungibleToken-249.5µs ± 4%50.4µs ± 9%~(p=0.805 n=7+7)
InterpretRecursionFib-23.18ms ± 9%2.93ms ± 3%−7.95%(p=0.001 n=7+6)
NewInterpreter/new_interpreter-21.51µs ± 9%1.42µs ± 3%−5.89%(p=0.001 n=7+7)
NewInterpreter/new_sub-interpreter-2808ns ± 6%806ns ± 6%~(p=0.836 n=6+7)
ParseArray-29.71ms ± 3%9.92ms ± 9%~(p=0.902 n=7+7)
ParseDeploy/byte_array-215.0ms ± 4%14.6ms ± 3%~(p=0.165 n=7+7)
ParseDeploy/decode_hex-21.44ms ± 7%1.42ms ± 3%~(p=0.366 n=7+6)
ParseFungibleToken/With_memory_metering-2229µs ± 3%231µs ± 6%~(p=0.731 n=6+7)
ParseFungibleToken/Without_memory_metering-2184µs ± 3%184µs ± 2%~(p=1.000 n=7+7)
ParseInfix-28.45µs ± 4%8.10µs ± 0%−4.23%(p=0.003 n=7+5)
QualifiedIdentifierCreation/One_level-22.73ns ± 4%2.73ns ± 4%~(p=1.000 n=7+7)
QualifiedIdentifierCreation/Three_levels-2162ns ± 5%164ns ± 4%~(p=0.535 n=7+7)
RuntimeFungibleTokenTransfer-2766µs ±21%748µs ±20%~(p=0.535 n=7+7)
RuntimeResourceDictionaryValues-26.06ms ± 3%6.06ms ± 2%~(p=0.937 n=6+6)
RuntimeScriptNoop-220.8µs ±41%28.6µs ± 7%+37.26%(p=0.035 n=7+6)
ValueIsSubtypeOfSemaType-2109ns ± 4%108ns ± 5%~(p=0.776 n=7+7)
 
alloc/opdelta
CheckContractInterfaceFungibleTokenConformance-261.4kB ± 0%62.8kB ± 0%+2.19%(p=0.001 n=7+7)
ContractInterfaceFungibleToken-224.1kB ± 0%24.8kB ± 0%+2.79%(p=0.001 n=6+7)
InterpretRecursionFib-21.23MB ± 0%1.23MB ± 0%~(p=0.592 n=7+7)
NewInterpreter/new_interpreter-2848B ± 0%848B ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-2264B ± 0%264B ± 0%~(all equal)
ParseArray-22.76MB ± 4%2.74MB ± 4%~(p=0.535 n=7+7)
ParseDeploy/byte_array-24.23MB ± 3%4.17MB ± 4%~(p=0.364 n=7+7)
ParseDeploy/decode_hex-2214kB ± 0%214kB ± 0%~(p=0.707 n=7+7)
ParseFungibleToken/With_memory_metering-229.8kB ± 0%29.8kB ± 0%~(p=0.592 n=7+7)
ParseFungibleToken/Without_memory_metering-229.8kB ± 0%29.8kB ± 0%~(p=0.185 n=7+7)
ParseInfix-21.93kB ± 0%1.93kB ± 0%+0.08%(p=0.041 n=6+7)
QualifiedIdentifierCreation/One_level-20.00B 0.00B ~(all equal)
QualifiedIdentifierCreation/Three_levels-264.0B ± 0%64.0B ± 0%~(all equal)
RuntimeFungibleTokenTransfer-2108kB ± 1%108kB ± 1%~(p=0.535 n=7+7)
RuntimeResourceDictionaryValues-22.27MB ± 0%2.28MB ± 0%~(p=0.445 n=6+7)
RuntimeScriptNoop-28.87kB ± 1%8.86kB ± 0%~(p=0.731 n=7+6)
ValueIsSubtypeOfSemaType-248.0B ± 0%48.0B ± 0%~(all equal)
 
allocs/opdelta
CheckContractInterfaceFungibleTokenConformance-21.03k ± 0%1.03k ± 0%+0.29%(p=0.001 n=7+7)
ContractInterfaceFungibleToken-2431 ± 0%431 ± 0%~(all equal)
InterpretRecursionFib-222.5k ± 0%22.5k ± 0%~(all equal)
NewInterpreter/new_interpreter-214.0 ± 0%14.0 ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-25.00 ± 0%5.00 ± 0%~(all equal)
ParseArray-269.6k ± 0%69.6k ± 0%~(p=0.385 n=7+6)
ParseDeploy/byte_array-2104k ± 0%104k ± 0%~(p=0.538 n=7+6)
ParseDeploy/decode_hex-275.0 ± 0%75.0 ± 0%~(all equal)
ParseFungibleToken/With_memory_metering-21.01k ± 0%1.01k ± 0%~(all equal)
ParseFungibleToken/Without_memory_metering-21.01k ± 0%1.01k ± 0%~(all equal)
ParseInfix-260.0 ± 0%60.0 ± 0%~(all equal)
QualifiedIdentifierCreation/One_level-20.00 0.00 ~(all equal)
QualifiedIdentifierCreation/Three_levels-22.00 ± 0%2.00 ± 0%~(all equal)
RuntimeFungibleTokenTransfer-22.16k ± 0%2.16k ± 0%~(p=0.462 n=7+7)
RuntimeResourceDictionaryValues-236.9k ± 0%36.9k ± 0%~(p=0.878 n=7+7)
RuntimeScriptNoop-2145 ± 0%145 ± 0%~(all equal)
ValueIsSubtypeOfSemaType-21.00 ± 0%1.00 ± 0%~(all equal)
 

github-actions[bot] avatar Oct 06 '22 00:10 github-actions[bot]

I had the same thought initially. But after seeing how many contracts/obvious-cases can be detected statically, I actually changed that stance, and feels like it would be a sin not to catch them statically and enforce them to fix it (vs waiting for the run-time check to catch them on the act.)

The known scenario we don't catch right now is: Taking storage references and changing the storage. e.g: https://github.com/onflow/cadence/blob/91cf4a2ce69d72ade9fd852177732d60535767fc/runtime/tests/checker/reference_test.go#L1573-L1585 Change of this FLIP only targets ephemeral references, so it could argue that no change is done for storage references.

On the other hand, there are similar places where the best-effort analysis is done; for eg: certain invalid casting operations can be caught statically. And then there are also ones that cannot be, and those are caught dynamically at run-time.

SupunS avatar Oct 06 '22 16:10 SupunS

I see! If the only case we can't detect statically is the storage change, then it makes sense to add this check, especially since as you pointed out this whole FLIP only proposed to change ephemeral references anyways. We should document this limitation explicitly though, so people are aware of what the boundaries of the analysis are.

On that point, the documentation boxes on this PR (and the underlying PR) are checked but I don't see any changes to the documentation in them. Are we planning to add a section to the reference documentation about this invalidation?

dsainati1 avatar Oct 06 '22 17:10 dsainati1

Actually, realized one more case: reference-typed fields are not possible to track. Added a test-case: https://github.com/onflow/cadence/pull/2037/commits/df5bd3899c7c95ffa7569677dcb3091c964e8f2d

SupunS avatar Oct 06 '22 19:10 SupunS