Skip to content

Commit

Permalink
++ removeMember test
Browse files Browse the repository at this point in the history
  • Loading branch information
soloseng committed Feb 16, 2024
1 parent acd18ca commit 901be75
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 91 deletions.
114 changes: 114 additions & 0 deletions packages/protocol/test-sol/governance/validators/Validators.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1881,3 +1881,117 @@ contract ValidatorsTest_AddMember is ValidatorsTest {
validators.addMember(validator);
}
}

contract ValidatorsTest_RemoveMember is ValidatorsTest {
function setUp() public {
super.setUp();
_registerValidatorGroupWithMembers(group, 1);
}

function _registerValidatorGroupWithMembers(address _group, uint256 _numMembers) public {
_registerValidatorGroupHelper(_group, _numMembers);

for (uint256 i = 0; i < _numMembers; i++) {
if (i == 0) {
_registerValidatorHelper(validator, validatorPk);

vm.prank(validator);
validators.affiliate(group);

vm.prank(group);
validators.addFirstMember(validator, address(0), address(0));
} else {
uint256 _validator1Pk = i;
address _validator1 = vm.addr(_validator1Pk);

vm.prank(_validator1);
accounts.createAccount();
_registerValidatorHelper(_validator1, _validator1Pk);
vm.prank(validator);
validators.affiliate(group);
vm.prank(group);
validators.addMember(_validator1);
}
}
}

function test_ShouldRemoveMemberFromListOfMembers() public {
address[] memory expectedMembersList = new address[](0);

vm.prank(group);
validators.removeMember(validator);

(address[] memory members, , , , , , ) = validators.getValidatorGroup(group);

assertEq(members, expectedMembersList);
assertEq(members.length, expectedMembersList.length);
}

uint256 _registrationEpoch;
uint256 _additionEpoch;

function test_ShouldUpdateMemberMembershipHistory() public {
vm.prank(group);
validators.removeMember(validator);
uint256 _expectedEpoch = validators.getEpochNumber();

(uint256[] memory _epochs, address[] memory _membershipGroups, uint256 _historyLastRemovedTimestamp, uint256 _historyTail) = validators
.getMembershipHistory(validator);

assertEq(_epochs.length, 1);
assertEq(_membershipGroups.length, 1);

assertEq(_epochs[0], _expectedEpoch);

assertEq(_membershipGroups[0], address(0));
assertEq(_historyLastRemovedTimestamp, uint256(block.timestamp));
}

function test_ShouldUpdateGroupSizeHistory() public {
vm.prank(group);
validators.removeMember(validator);

(, , , , uint256[] memory _sizeHistory, , ) = validators.getValidatorGroup(group);

assertEq(_sizeHistory.length, 2);
assertEq(_sizeHistory[1], uint256(block.timestamp));
}

function test_Emits_ValidatorGroupMemberRemovedEvent() public {
vm.expectEmit(true, true, true, true);
emit ValidatorGroupMemberRemoved(group, validator);

vm.prank(group);
validators.removeMember(validator);
}

// When vlidator ins only member of the group

function test_ShouldMarkGroupIneligible_WhenValidatorIsOnlyMemberOfTheGroup() public {
vm.prank(group);
validators.removeMember(validator);

assertTrue(election.isIneligible(group));
}

function test_Reverts_WhenAccountIsNotRegisteredValidatorGroup() public {
vm.expectRevert("is not group and validator");
vm.prank(nonValidator);
validators.removeMember(validator);
}

function test_Reverts_WhenMemberNotRegisteredValidatorGroup() public {
vm.expectRevert("is not group and validator");
vm.prank(group);
validators.removeMember(nonValidator);
}

function test_Reverts_WhenValidatorNotMemberOfValidatorGroup() public {
vm.prank(validator);
validators.deaffiliate();

vm.expectRevert("Not affiliated to group");
vm.prank(group);
validators.removeMember(validator);
}
}
92 changes: 1 addition & 91 deletions packages/protocol/test/governance/validators/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
assertEqualBNArray,
assertEqualDpBN,
assertRevert,
assertSameAddress,
assertTransactionRevertWithReason,
currentEpochNumber,
mineBlocks,
Expand Down Expand Up @@ -207,96 +206,7 @@ contract('Validators', (accounts: string[]) => {

// describe('#addMember', () => {})

describe('#removeMember', () => {
const group = accounts[0]
const validator = accounts[1]
beforeEach(async () => {
await registerValidatorGroupWithMembers(group, [validator])
})

it('should remove the member from the list of members', async () => {
await validators.removeMember(validator)
const parsedGroup = parseValidatorGroupParams(await validators.getValidatorGroup(group))
assert.deepEqual(parsedGroup.members, [])
})

it("should update the member's membership history", async () => {
await validators.removeMember(validator)
const membershipHistory = parseMembershipHistory(
await validators.getMembershipHistory(validator)
)
const expectedEpoch = await currentEpochNumber(web3)

// Depending on test timing, we may or may not span an epoch boundary between registration
// and removal.
const numEntries = membershipHistory.epochs.length
assert.isTrue(numEntries === 1 || numEntries === 2)
assert.equal(membershipHistory.groups.length, numEntries)
if (numEntries === 1) {
assertEqualBN(membershipHistory.epochs[0], expectedEpoch)
assertSameAddress(membershipHistory.groups[0], NULL_ADDRESS)
} else {
assertEqualBN(membershipHistory.epochs[1], expectedEpoch)
assertSameAddress(membershipHistory.groups[1], NULL_ADDRESS)
}
const latestBlock = await web3.eth.getBlock('latest')
assert.equal(membershipHistory.lastRemovedFromGroupTimestamp, latestBlock.timestamp)
})

it("should update the group's size history", async () => {
await validators.removeMember(validator)
const parsedGroup = parseValidatorGroupParams(await validators.getValidatorGroup(group))
assert.equal(parsedGroup.sizeHistory.length, 2)
assertEqualBN(parsedGroup.sizeHistory[1], (await web3.eth.getBlock('latest')).timestamp)
})

it('should emit the ValidatorGroupMemberRemoved event', async () => {
const resp = await validators.removeMember(validator)
assert.equal(resp.logs.length, 1)
const log = resp.logs[0]
assertContainSubset(log, {
event: 'ValidatorGroupMemberRemoved',
args: {
group,
validator,
},
})
})

describe('when the validator is the only member of the group', () => {
it('should mark the group ineligible', async () => {
await validators.removeMember(validator)
assert.isTrue(await mockElection.isIneligible(group))
})
})

it('should revert when the account is not a registered validator group', async () => {
await assertTransactionRevertWithReason(
validators.removeMember(validator, { from: accounts[2] }),
'is not group and validator'
)
})

it('should revert when the member is not a registered validator', async () => {
await assertTransactionRevertWithReason(
validators.removeMember(accounts[2]),
'is not group and validator'
)
})

describe('when the validator is not a member of the validator group', () => {
beforeEach(async () => {
await validators.deaffiliate({ from: validator })
})

it('should revert', async () => {
await assertTransactionRevertWithReason(
validators.removeMember(validator),
'Not affiliated to group'
)
})
})
})
// describe('#removeMember', () => {})

describe('#reorderMember', () => {
const group = accounts[0]
Expand Down

0 comments on commit 901be75

Please sign in to comment.