Skip to content

Add method for getting value of all set flags in Flag #4799

@fubuloubu

Description

@fubuloubu

Simple Summary

Add a function like all (or repurpose max_value) that when applied to a Flag type produces the value of Flag with all members set

Motivation

If using a Flag type for designing a role system, it is typically suggested to have unique flag per system-level capability. However, when used correctly, it is still slightly annoying to specify the "admin" or "all capabilities" value of the flag in practice, involving something like (Flag.A | Flag.B | ... | Flag.Z).

Because this requires manually updating the expression which uses all values, it can lead to human error when adding a new flag member as you might forget to update such an expression. We should make it easy and natural to describe the "all flag members set" semantic for a Flag type, such that when adding a new flag member, that expression does not have to change.

Specification

Either add a new function (perhaps all, which could have future semantics when applied to comprehensions that involve boolean expressions), or repurpose an existing one with similar semantics (perhaps max_value, which typically means "whatever the largest in-memory value for this type should be") so that we can easily write this type of expression and not have to change it when new members are added.

Here is an example using it in practice:

flag Capability:
    MODIFY_ACCESS
    MODIFY_CONFIG
    # Add a flag member per unique system capability
    ...

role: public(HashMap[address, Capability])

def add_capabilities(user: address, capabilities: Capability = all(Capability))  # or `max_value(Capability)`):
    # NOTE: Defaults to add "full admin" capabilities if none specified
    assert Capability.MODIFY_ACCESS in self.role[msg.sender]
    self.role[user] |= capabilities

def remove_capabilities(user: address, capabilities: Capability = all(Capability))  # or `max_value(Capability)`):
    # NOTE: Defaults to removing all capabilities if none specified
    assert Capability.MODIFY_ACCESS in self.role[msg.sender]
    self.role[user] &= ~capabilities

# Check for capability as needed
def change_config(...):
    assert Capability.MODIFY_CONFIG in self.role[msg.sender]
    ...

...

Backwards Compatibility

n/a

Dependencies

n/a (unless there's a VIP for all)

References

n/a

Copyright

Copyright and related rights waived via CC0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions