Add getRoleMembers method to return all accounts that have role (#4546)
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com> Co-authored-by: Ernesto García <ernestognw@gmail.com>
This commit is contained in:
5
.changeset/violet-moons-tell.md
Normal file
5
.changeset/violet-moons-tell.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'openzeppelin-solidity': minor
|
||||
---
|
||||
|
||||
`AccessControlEnumerable`: Add a `getRoleMembers` method to return all accounts that have `role`.
|
||||
@ -46,6 +46,18 @@ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessCon
|
||||
return _roleMembers[role].length();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return all accounts that have `role`
|
||||
*
|
||||
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
|
||||
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
|
||||
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
|
||||
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
|
||||
*/
|
||||
function getRoleMembers(bytes32 role) public view virtual returns (address[] memory) {
|
||||
return _roleMembers[role].values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overload {AccessControl-_grantRole} to track enumerable memberships
|
||||
*/
|
||||
|
||||
@ -239,15 +239,17 @@ function shouldBehaveLikeAccessControlEnumerable() {
|
||||
await this.mock.connect(this.defaultAdmin).grantRole(ROLE, this.otherAuthorized);
|
||||
await this.mock.connect(this.defaultAdmin).revokeRole(ROLE, this.other);
|
||||
|
||||
const memberCount = await this.mock.getRoleMemberCount(ROLE);
|
||||
expect(memberCount).to.equal(2);
|
||||
const expectedMembers = [this.authorized.address, this.otherAuthorized.address];
|
||||
|
||||
const bearers = [];
|
||||
const memberCount = await this.mock.getRoleMemberCount(ROLE);
|
||||
const members = [];
|
||||
for (let i = 0; i < memberCount; ++i) {
|
||||
bearers.push(await this.mock.getRoleMember(ROLE, i));
|
||||
members.push(await this.mock.getRoleMember(ROLE, i));
|
||||
}
|
||||
|
||||
expect(bearers).to.have.members([this.authorized.address, this.otherAuthorized.address]);
|
||||
expect(memberCount).to.equal(expectedMembers.length);
|
||||
expect(members).to.deep.equal(expectedMembers);
|
||||
expect(await this.mock.getRoleMembers(ROLE)).to.deep.equal(expectedMembers);
|
||||
});
|
||||
|
||||
it('role enumeration should be in sync after renounceRole call', async function () {
|
||||
|
||||
Reference in New Issue
Block a user