Skip to content

feat(rust/catalyst-types): change RoleIndex to enum #283

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

Open
wants to merge 28 commits into
base: main
Choose a base branch
from

Conversation

vlopes11
Copy link
Contributor

Description

This commit introduces RoleIndex as enum for a better static control over the logical variants of the type.

Related Issue(s)

closes #277

Description of Changes

  • Change RoleIndex from RoleIndex(u16) to enum

Breaking Changes

  • Change RoleIndex from RoleIndex(u16) to enum

Screenshots

N/A

Related Pull Requests

N/A

Please confirm the following checks

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream module

@vlopes11 vlopes11 changed the title refactor: change RoleIndex to enum feat(catalyst-types): change RoleIndex to enum Apr 15, 2025
@Mr-Leshiy Mr-Leshiy self-requested a review April 15, 2025 10:06
This commit introduces RoleIndex as enum for a better static control
over the logical variants of the type.

closes #277
@vlopes11 vlopes11 force-pushed the feat/refactor-role-index branch from d1f4130 to d47d69e Compare April 15, 2025 10:56
@vlopes11 vlopes11 changed the title feat(catalyst-types): change RoleIndex to enum feat(rust/catalyst-types): change RoleIndex to enum Apr 15, 2025
@vlopes11 vlopes11 force-pushed the feat/refactor-role-index branch from d57100e to 2166c44 Compare April 15, 2025 12:03
Copy link
Contributor

github-actions bot commented Apr 15, 2025

Test Report | ${\color{lightgreen}Pass: 318/318}$ | ${\color{red}Fail: 0/318}$ |

@Mr-Leshiy Mr-Leshiy added the do not merge yet PR is not ready to merge yet label Apr 16, 2025
Copy link
Contributor

@Mr-Leshiy Mr-Leshiy left a comment

Choose a reason for hiding this comment

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

Missing this part from the issue Replace the usage of the RoleNumber type with the new RoleId..
RoleNumber structure is defined inside the rbac-registration crate. And this type facilitates exactly the same purpose, so it's redundant to have two types for the same entity.

So you will need replace the RoleNumber with the RoleId inside the rbac-registration crate and remove RoleNumber at all.

@vlopes11 vlopes11 requested a review from Mr-Leshiy April 17, 2025 11:44
Copy link
Contributor

@Mr-Leshiy Mr-Leshiy left a comment

Choose a reason for hiding this comment

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

Despite one comment LGTM.
Only one more thing before we will merge this PR into main.
Pls create a PR with the updating and applying this branch to the cat-gateway first, and if everything would be fine on the cat-gateway side will merge this PR.

The role numbers are now statically defined so an invalid one cannot exist.
@vlopes11 vlopes11 requested a review from Mr-Leshiy April 24, 2025 09:02
Copy link
Collaborator

@stevenj stevenj left a comment

Choose a reason for hiding this comment

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

When working with enums in rust, this crate:
https://docs.rs/strum_macros/0.27.1/strum_macros/derive.EnumDiscriminants.html
which we already use can save a lot of boilerplate and maintenance keeping everything in-sync.

Suggest looking to see if anything other than the two place I highlight could be simplified using these derived macros.

@Mr-Leshiy Mr-Leshiy added the review me PR is ready for review label Apr 25, 2025
@vlopes11 vlopes11 requested a review from stevenj April 28, 2025 13:02
Copy link
Contributor

@bkioshn bkioshn left a comment

Choose a reason for hiding this comment

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

Make sure that comment related to "Role Index" and "Role number" are changed

eg. This should change to Role ID

/// Role Index is not encoded correctly
    InvalidRoleId(#[from] RoleIdError),

@vlopes11 vlopes11 requested a review from bkioshn May 1, 2025 09:13
VoterDelegation = 2,
/// Proposer that enabling creation, collaboration, and submission of proposals.
Proposer = 3,
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I feel like this enum should have a method that returns True if the RoleId is a known variant, and false otherwise.
Which could be used by the currently removed validate_role_numbers function below to determine if any particular role number is known without worrying about what exact role number it is.

You could use: https://docs.rs/strum/latest/strum/derive.EnumIter.html
or https://docs.rs/strum/latest/strum/derive.VariantArray.html
to achieve this without having to update the method when we add new variants.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The initial rationale was that the static list of known roles were valid. Is the valid list a subset? The previous implementation of validate_role_numbers contemplated only roles 0 and 3; do we have a documented list somewhere of what is a valid role? For me to link here for future reference

Copy link
Contributor

Choose a reason for hiding this comment

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

/// Delegated representative (dRep) that vote on behalf of delegators.
DelegatedRepresentative = 1,
/// Voter role that delegates voting power to a chosen representative (dRep).
VoterDelegation = 2,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove VoterDelegation we are not going to use this role at this number.
So the known members are 0,1 and 3 only so far.


/// Returns `true` if the role belongs to the canonical set of known roles.
#[must_use]
pub const fn is_known(self) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Better replace this with using this derive macro https://docs.rs/strum/latest/strum/derive.EnumIs.html

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since this is a group matching, and EnumIs matches individually, I wonder if that would be an improvement. We can hardly beat the performance and simplicity of matches.

With matches, the macro will expand to a single pattern matching. With EnumIs, we would have to do something like self.is_role0() || self.is_delegated_representative() || self.is_proposer(), which would be 3 matching + ors. The compiler might be able to optimize this, but it would be more verbose.

Copy link
Contributor

Choose a reason for hiding this comment

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

No no, I've meant to not have an explicit is_known method defined by ourselves at all.
rather to use EnumIs so it will define for us something like is_unknown which would be more than enough to call !is_unknown in any other place.


/// Returns `true` if the role belongs to the canonical set of known roles.
#[must_use]
pub const fn is_known(self) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

No no, I've meant to not have an explicit is_known method defined by ourselves at all.
rather to use EnumIs so it will define for us something like is_unknown which would be more than enough to call !is_unknown in any other place.


use super::*;

proptest! {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
proptest! {

#[cfg(test)]
mod tests {
use minicbor::{Decoder, Encoder};
use proptest::prelude::*;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
use proptest::prelude::*;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do not merge yet PR is not ready to merge yet review me PR is ready for review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor RoleIndex/ RoleNumber type.
4 participants