Skip to content
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

Allow scripts to access authorized accounts #1240

Merged
merged 8 commits into from
Nov 19, 2021
Merged

Allow scripts to access authorized accounts #1240

merged 8 commits into from
Nov 19, 2021

Conversation

dsainati1
Copy link
Contributor

@dsainati1 dsainati1 commented Nov 16, 2021

Closes #539

Description

Because scripts discard their changes upon completion, there is no harm in allowing them to access AuthAccounts. This adds a function:

getAuthAccount(_ address: Address): AuthAccount

That loads an AuthAccount in the same way that getAccount loads a PublicAccount. This is only available in scripts; trying to use this function outside of a script will cause an error in the checker.


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

@dsainati1 dsainati1 self-assigned this Nov 16, 2021
@github-actions
Copy link

github-actions bot commented Nov 16, 2021

Cadence Benchstat comparison

This branch with compared with the base branch onflow:master commit ad6895c
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
NewInterpreter/new_interpreter-21.16µs ± 2%1.21µs ± 5%+4.60%(p=0.001 n=6+7)
ParseDeploy/byte_array-234.5ms ± 2%35.9ms ± 3%+4.06%(p=0.001 n=7+7)
ParseFungibleToken-2474µs ± 3%489µs ± 2%+3.24%(p=0.007 n=7+7)
ParseDeploy/decode_hex-21.44ms ± 2%1.48ms ± 2%+3.11%(p=0.001 n=7+7)
RuntimeStorageWriteCached-2170µs ±39%142µs ± 1%~(p=0.209 n=7+7)
RuntimeResourceDictionaryValues-216.4ms ± 3%16.3ms ± 3%~(p=0.902 n=7+7)
RuntimeFungibleTokenTransfer-21.20ms ± 4%1.23ms ± 4%~(p=0.259 n=7+7)
ParseInfix-225.1µs ± 2%25.1µs ± 2%~(p=0.932 n=7+7)
ParseArray-223.4ms ± 1%23.6ms ± 3%~(p=0.234 n=6+7)
QualifiedIdentifierCreation/One_level-23.26ns ± 3%3.26ns ± 2%~(p=0.902 n=7+7)
QualifiedIdentifierCreation/Three_levels-2163ns ± 2%163ns ± 3%~(p=0.902 n=7+7)
CheckContractInterfaceFungibleTokenConformance-2171µs ± 3%170µs ± 1%~(p=0.937 n=6+6)
ContractInterfaceFungibleToken-247.6µs ± 4%48.1µs ± 3%~(p=0.165 n=7+7)
NewInterpreter/new_sub-interpreter-22.14µs ± 2%2.18µs ± 3%~(p=0.154 n=7+7)
InterpretRecursionFib-22.74ms ± 4%2.73ms ± 2%~(p=1.000 n=7+7)
 
alloc/opdelta
RuntimeFungibleTokenTransfer-2233kB ± 0%233kB ± 0%+0.01%(p=0.025 n=7+7)
RuntimeStorageWriteCached-283.7kB ± 0%83.7kB ± 0%~(p=1.000 n=6+6)
RuntimeResourceDictionaryValues-24.34MB ± 0%4.34MB ± 0%~(p=0.318 n=7+7)
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)
NewInterpreter/new_interpreter-2680B ± 0%680B ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-21.06kB ± 0%1.06kB ± 0%~(all equal)
InterpretRecursionFib-21.21MB ± 0%1.21MB ± 0%~(p=0.462 n=7+7)
 
allocs/opdelta
RuntimeStorageWriteCached-21.42k ± 0%1.42k ± 0%~(all equal)
RuntimeResourceDictionaryValues-2108k ± 0%108k ± 0%~(p=0.264 n=7+7)
RuntimeFungibleTokenTransfer-24.43k ± 0%4.43k ± 0%~(p=1.000 n=7+7)
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)
NewInterpreter/new_interpreter-211.0 ± 0%11.0 ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-231.0 ± 0%31.0 ± 0%~(all equal)
InterpretRecursionFib-225.0k ± 0%25.0k ± 0%~(all equal)
 

Copy link
Member

@joshuahannan joshuahannan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exciting! 🎉 🥳

@codecov-commenter
Copy link

codecov-commenter commented Nov 16, 2021

Codecov Report

Merging #1240 (a05e443) into master (ad6895c) will increase coverage by 0.01%.
The diff coverage is 100.00%.

❗ Current head a05e443 differs from pull request most recent head 452d43e. Consider uploading reports for the commit 452d43e to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1240      +/-   ##
==========================================
+ Coverage   77.59%   77.61%   +0.01%     
==========================================
  Files         274      274              
  Lines       35232    35260      +28     
==========================================
+ Hits        27339    27367      +28     
  Misses       6806     6806              
  Partials     1087     1087              
Flag Coverage Δ
unittests 77.61% <100.00%> (+0.01%) ⬆️

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

Impacted Files Coverage Δ
runtime/runtime.go 86.96% <100.00%> (+0.20%) ⬆️

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 ad6895c...452d43e. Read the comment docs.

Copy link
Member

@turbolent turbolent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@bluesign
Copy link
Contributor

Why not extend PublicAccount with functions from AuthAccount in script context ?

Co-authored-by: Bastian Müller <[email protected]>
@dsainati1
Copy link
Contributor Author

Why not extend PublicAccount with functions from AuthAccount in script context ?

Having the same type mean different things in different contexts is confusing; we don't want to change what a PublicAccount means depending on where a script is being used. Instead, it's a much simpler change to allow people to access AuthAccounts depending on whether they are in a script or a transaction, and this way each of the types mean the same thing everywhere. The only thing changing is whether they are accessible.

@bluesign
Copy link
Contributor

I know it is already merged, but here is my 2 cents.

This is the diff of AuthAccount from PublicAccount:

struct AuthAccount {
    fun addPublicKey(_ publicKey: [UInt8])
    fun removePublicKey(_ index: Int)
    fun save<T>(_ value: T, to: StoragePath)
    fun load<T>(from: StoragePath): T?
    fun copy<T: AnyStruct>(from: StoragePath): T?
    fun borrow<T: &Any>(from: StoragePath): T?
    fun getCapability<T>(_ path: CapabilityPath): Capability<T>
    fun link<T: &Any>(_ newCapabilityPath: CapabilityPath, target: Path): Capability<T>?
    fun unlink(_ path: CapabilityPath)
    struct Contracts {
        fun add(
            name: String,
            code: [UInt8],
            ... contractInitializerArguments
        ): DeployedContract
        fun update__experimental(name: String, code: [UInt8]): DeployedContract
        fun remove(name: String): DeployedContract?
    }
    struct Keys {
        fun add(
            publicKey: PublicKey,
            hashAlgorithm: HashAlgorithm,
            weight: UFix64
        ): AccountKey
        fun revoke(keyIndex: Int): AccountKey?
    }
}

Below is the function that makes sense in script ( read only ): (considering getCapability is useless)

struct AuthAccount {
    fun load<T>(from: StoragePath): T?
    fun copy<T: AnyStruct>(from: StoragePath): T?
    fun borrow<T: &Any>(from: StoragePath): T?
}

technically load and copy are same (in script context) borrow is useless when you have load. So we end up with:

fun load<T>(from: StoragePath): T?

In my opinion exposing 14 functions where in reality 1 is needed outweights the benefit. Also PublicAccount has feeling of read-only vs AuthAccount has feeling of read/write.

instead of getAuthAccount (which is exposed to scripts only), maybe it would be better to have something like:

fun loadFromAccount<T>(Address, path: StoragePath): T?

But I think it would also make sense to just put load to PublicAccount. And just panic with a nice error message when in Transaction context.

@turbolent
Copy link
Member

@bluesign The difference between a transaction context and a script context is that in a transaction context state changes are written, and in the script context the changes are ignored.

It is much simpler for the implementation to behave exactly the same in both contexts and I would assume that it is also the same for developers/users. I don't really think that changing the definitions and APIs (e.g. adding new / removing existing functions) is worth it.

Having the existing definitions behave the same in a scripting context as in a transaction context is also useful for future features like testing, where you might want to perform state-changing actions, but are not interested in the state changes being applied. If the API were reduced to just a "read-only" API it would be limiting for some actions you might want to perform.

@bluesign
Copy link
Contributor

bluesign commented Mar 2, 2022

Having the existing definitions behave the same in a scripting context as in a transaction context is also useful for future features like testing, where you might want to perform state-changing actions, but are not interested in the state changes being applied. If the API were reduced to just a "read-only" API it would be limiting for some actions you might want to perform.

Oh thats exactly the point that I missed, I now see how this can be a powerful feature. Thanks for the clarification.

@bluesign
Copy link
Contributor

Any eta on this to be included in Cadence ?

@dsainati1
Copy link
Contributor Author

This will be out in Secure Cadence I believe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Scripts should have access to authorized accounts
5 participants