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

Relax default entitlement mapping for dictionary/array elements #2953

Open
Tracked by #2642
SupunS opened this issue Nov 27, 2023 · 9 comments
Open
Tracked by #2642

Relax default entitlement mapping for dictionary/array elements #2953

SupunS opened this issue Nov 27, 2023 · 9 comments

Comments

@SupunS
Copy link
Member

SupunS commented Nov 27, 2023

Issue to be solved

Currently, there is no way for dictionaries/arrays to define the entitlement mapping for their children. So the default behavior is to have no entitlements for references when a child is accessed through a reference to the parent.
This 'default behavior' was chosen due to some safety concerns: #2587 (comment).

However, this can be restrictive sometimes, if one gets a mutable reference to a dictionary auth(Mutate) {String: {String: AnyStruct}} and wants to mutate the inner dictionary, then this is a bit of a hassle. In order to mutate the inner one, they would need to either:

  • Get a dereferenced copy of the child, update it, and insert it again.
  • Remove the child, update it, and insert it again.

Both of these are not only expensive but also involve a lot of boilerplate code.

e.g: https://discord.com/channels/613813861610684416/1176642288986894366/1176949623638732912

Suggested Solution

An alternative is to give Identity entitlement mapping for children. So children would get the same entitlement as the parent.

@SupunS
Copy link
Member Author

SupunS commented Nov 27, 2023

This is not a breaking change, since the proposal is to relax an existing restriction.

@SupunS
Copy link
Member Author

SupunS commented Nov 27, 2023

cc: @joshuahannan

@turbolent
Copy link
Member

@SupunS Could you please add the concerns to the description or as a comment?

@turbolent
Copy link
Member

@dsainati1 Can you please add your concerns?

@turbolent
Copy link
Member

Example:

let xs = {"a": {"b": "c"}}
let x: ??? = xs[1]

@dsainati1
Copy link
Contributor

My concerns here are primarily about safety; I don't think it is necessarily the case that the entitlements I have to an outer collection should automatically propagate to the inner collections. E.g. just because I have Mutate permissions to an array of NFTs, allowing me to insert or remove NFTs from the array, does not mean I should necessarily have permissions to modify the NFTs themselves.

@turbolent
Copy link
Member

turbolent commented Dec 1, 2023

Would it would be possible to expose this functionality, getting an entitled reference to an inner container/element of the outer container, through a getter function right?

For example:

resource Collection {
  var nfts: @{UInt64: NFT}

  fun getMutableNFTRef(id: UInt64): auth(Mutate) &NFT {
    return &nfts[id] auth(Mutate) &NFT
  }
}

@dsainati1
Copy link
Contributor

Yeah I think this should be possible. If it isn't currently, that seems like the right way to solve this.

@SupunS
Copy link
Member Author

SupunS commented Dec 1, 2023

For composites, this is already working through entitlement mappings. One doesn't even have to define a getter.

The problem is for the dictionaries and arrays that are within another dictionary/array, where there is no way for a user to define custom getters/setters or entitlement mappings.

@SupunS SupunS changed the title [stable-cadence] Relax default entitlement mapping for dictionary/array elements Relax default entitlement mapping for dictionary/array elements Apr 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants