Skip to content

ACL: Remove __acl field#84

Merged
mooori merged 9 commits into
masterfrom
remove_acl_field
Mar 2, 2023
Merged

ACL: Remove __acl field#84
mooori merged 9 commits into
masterfrom
remove_acl_field

Conversation

@karim-en
Copy link
Copy Markdown
Collaborator

@karim-en karim-en commented Feb 21, 2023

Currently, the ACL plugins can't be added to already deployed contracts without migration due to the __acl field.
This pull request removes the __acl field and uses the storage key instead.

Added internal/private API:

fn acl_get_storage(&self) -> Option<#acl_type>
fn acl_get_or_init(&mut self) -> #acl_type
fn acl_init_storage_unchecked(&mut self)

@karim-en karim-en added the enhancement New feature or request label Feb 21, 2023
@karim-en karim-en changed the title Remove __acl field ACL: Remove __acl field Feb 21, 2023
Copy link
Copy Markdown

@birchmd birchmd left a comment

Choose a reason for hiding this comment

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

Looks reasonable to me!

Copy link
Copy Markdown
Contributor

@mooori mooori left a comment

Choose a reason for hiding this comment

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

Thanks for this change! Initially the acl plugin used near_sdk::collections types which couldn’t be used with near_sdk::env::storage_{read, write}. Great to see it is possible with near_sdk::store types.


Why is it necessary to explicitly initiate storage with acl_init_storage()? Couldn’t storage be init'ed implicitly if needed? For instance instead of acl_get there could be acl_get_or_init:

fn acl_get_or_init(&mut self) -> #acl_type {
    // Assume `acl_init_storage_unchecked` returns the struct it wrote to storage.
    self.acl_get_storage().unwrap_or_else(|| self.acl_init_storage_unchecked())
}

This is in line with Acl initiating data structures if needed (example, example) and also other plugins don’t require *_init_storage. Moreover, I think it has the following benefits:

No panics

In the current implementation acl_get may panic and it is called in the implementation of almost every AccessControllable trait method. This means we must explain to users when/why Acl may panic due to storage not being init’ed. With acl_get_or_init this wouldn’t be necessary since there is no panic.

No need to explicitly init storage

Which makes the plugin easier to use.

No need for acl_init_storage in the public API

Since it is init’ed internally if needed.

Note

If going with above proposal, methods that don’t take &mut self cannot call acl_get_or_init(&mut self). Instead they can do something like:

fn acl_has_role(&self, role: String, account_id: ::near_sdk::AccountId) -> bool {
    let role: #role_type = ::std::convert::TryFrom::try_from(role.as_str()).unwrap_or_else(|_| ::near_sdk::env::panic_str(#ERR_PARSE_ROLE));
    match self.acl_get_storage() {
        Some(acl) => acl.has_role(role, &account_id),
        None => false
    }
}

Comment thread near-plugins-derive/src/access_controllable.rs
Comment thread .gitignore Outdated
@karim-en
Copy link
Copy Markdown
Collaborator Author

#84 (review)

@mooori @birchmd

Personally, I prefer panic instead of returning default values because normally it shouldn't panic if the contract was implemented correctly, so it indicates there is some bug in the initialization or migration code.

But anyway I've implemented this proposal 35635bc, to be able to merge this pull request asap.

Copy link
Copy Markdown
Contributor

@mooori mooori left a comment

Choose a reason for hiding this comment

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

LGTM, just some functions should mutably borrow self, I think (see below).

This sentence is outdated:

https://github.com/aurora-is-near/near-plugins/blob/35635bc6e6e4c9ec7fcf4383ab9d183034809ff0/near-plugins-derive/tests/contracts/access_controllable/src/lib.rs#L124-L125

Possible replacement:

/// Most of them are implemented for the type that holds the plugin's state,
/// which can be accessed with `self.acl_get_or_init()`.

Comment thread near-plugins-derive/src/access_controllable.rs Outdated
Comment thread .gitignore Outdated
Comment thread near-plugins-derive/src/access_controllable.rs Outdated
Copy link
Copy Markdown

@birchmd birchmd left a comment

Choose a reason for hiding this comment

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

RE: panic or not to panic

Probably the best solution is to have both functions and let developers decide what makes sense for them. This would be analogous to how Near SDK allows your contract to derive PanicOnDefault or not.

Making panicking on missing storage configurable would be a more complex change so I don't think we should do it as part of this PR, but maybe it is something we want to implement in the future.

karim-en and others added 3 commits March 1, 2023 18:18
@karim-en karim-en requested a review from mooori March 1, 2023 18:27
Copy link
Copy Markdown
Contributor

@mooori mooori left a comment

Choose a reason for hiding this comment

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

Thanks!

@mooori mooori merged commit 860ec9d into master Mar 2, 2023
@mooori mooori deleted the remove_acl_field branch March 2, 2023 06:50
@github-actions github-actions Bot mentioned this pull request Mar 27, 2026
This was referenced Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants