-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Enumberable set cleanup #12885
Enumberable set cleanup #12885
Conversation
I see you updated files related to
|
I see you updated files related to |
e766fd6
to
9ed54b9
Compare
9ed54b9
to
1c111e2
Compare
for (uint256 idx = 0; idx < s_registrars.length(); idx++) { | ||
s_registrars.remove(s_registrars.at(idx)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is potentially buggy because remove()
will adjust the index of items in the set on each delete. I think we need to count backwards instead, like this:
for (int256 idx = int256(s_registrars.length()); idx > -1; idx--) {
s_registrars.remove(s_registrars.at(idx));
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wow, good catch!
I just tested in remix, and indeed, using the above code couldnt remove all, it will have leftover. The right way is to cleanup using reverse order, as you recommended.
I added a foundry test to cover this scenario. If you see this commit , it fails bc of registrar length doesnt match.
with the latest commit, s_registrars is cleaned up properly.
for (uint256 idx = 0; idx < s_deactivatedTransmitters.length(); idx++) { | ||
s_deactivatedTransmitters.remove(s_deactivatedTransmitters.at(idx)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since s_deactivatedTransmitters is not exposed, i couldnt unit test this guy. I hope the above registrar test can also verify the logic.
1c111e2
to
af2190b
Compare
af2190b
to
03a7880
Compare
( | ||
, | ||
IAutomationV21PlusCommon.OnchainConfigLegacy memory onchainConfig2, | ||
address[] memory signers, | ||
address[] memory transmitters, | ||
uint8 f | ||
) = registry.getState(); | ||
|
||
assertEq(onchainConfig2.registrars.length, 3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we test the values of the new registrars, instead of just the length? Also, I think this bug is only exposed when decreasing registrars. Could we extend this test so that we decrease from say 3 to 0 and test that all have been removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we test the values of the new registrars, instead of just the length?
sure, will do.
I think this bug is only exposed when decreasing registrars. Could we extend this test so that we decrease from say 3 to 0 and test that all have been removed?
This should be already covered. When we setConfig, we remove all existing registrars and set new ones. If you check out this particular commit, and run the foundry test, you should see the test failure. I left it there in a separate commit to showcase this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome - sorry I missed that
function _getRegistrars() private pure returns (address[] memory) { | ||
address[] memory registrars = new address[](2); | ||
registrars[0] = address(uint160(uint256(keccak256("registrar1")))); | ||
registrars[1] = address(uint160(uint256(keccak256("registrar2")))); | ||
return registrars; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick - but since the function is only used once, it might be neater to just inline it? not a strong opinion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason of having this function is that we cant initiate and add elements to the registrars array outside of a function. If you see the original code, the registrars were under contracts.
03a7880
to
af3b5db
Compare
Quality Gate passedIssues Measures |
No description provided.