Skip to content
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

Use Trace208 in Votes to support ERC6372 clocks #4539

Merged
merged 10 commits into from
Aug 30, 2023

Conversation

Amxx
Copy link
Collaborator

@Amxx Amxx commented Aug 25, 2023

ERC-6372 clocks are 48 bits but our Votes contracts use 32 bit keys. This changes the Votes library to match clocks and use 48 bit keys, to avoid fallible conversions.

PR Checklist

  • Tests
  • Documentation
  • Changeset entry (run npx changeset add)

@changeset-bot
Copy link

changeset-bot bot commented Aug 25, 2023

🦋 Changeset detected

Latest commit: 7927100

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openzeppelin-solidity Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@Amxx Amxx changed the title Use trace208 in Checkpoints to support full uint48 keys for ERC6372 compatibility Use trace208 in Votes to support ERC6372 clocks Aug 25, 2023
@frangio frangio changed the title Use trace208 in Votes to support ERC6372 clocks Use Trace208 in Votes to support ERC6372 clocks Aug 25, 2023
*/
function _maxSupply() internal view virtual returns (uint224) {
return type(uint224).max;
function _maxSupply() internal view virtual returns (uint256) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why change this to uint256? Using the smaller type prevents returning a number that is too large for the data structure to support it.

Suggested change
function _maxSupply() internal view virtual returns (uint256) {
function _maxSupply() internal view virtual returns (uint208) {

Copy link
Collaborator Author

@Amxx Amxx Aug 25, 2023

Choose a reason for hiding this comment

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

I'm honestly not sure what it implies/change to use uint208 vs uint256 here (note that it's internal)

Copy link
Contributor

Choose a reason for hiding this comment

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

uint208 makes it a type error to override with a function that returns type(uint256).max, for example, or any literal that is too large to fit uint208.

Copy link
Collaborator Author

@Amxx Amxx Aug 25, 2023

Choose a reason for hiding this comment

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

What if multiple modules implement that function with different values (votes limit to 208, but other modules would limit to 224, 192 or 128 for some other reason) how would we resolve that ?

If the return types are different it's a mess. If they are both uint256 there may be some hope

Copy link
Contributor

Choose a reason for hiding this comment

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

This is not a concrete problem we have currently so I would go with the option that is safer.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If that issue happens during the 5.x cycle, would we be able to change it without a major change ?

I don't think overriding this with a bigger function is something anyone would realistically do.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also the only place we use it, we do an implicit upcast to uint256

Copy link
Contributor

Choose a reason for hiding this comment

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

If something like this happens in a minor release I think we would just add an internal function with a name other than _maxSupply so they wouldn't clash, and ERC20Votes could implement that internal function in terms of the existing one.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you feel strongly about this I can accept it. The risk if >uint208 is returned is simply that some transfers might revert but it's a recoverable situation.

@frangio frangio added the breaking change Changes that break backwards compatibility of the public API. label Aug 25, 2023
@frangio
Copy link
Contributor

frangio commented Aug 25, 2023

In 74b8d26 I added continue-on-error for the storage layout checks if the PR is labelled as "breaking change". But note that this doesn't re-run the checks when the label is applied. To do that we would need to add these lines in checks.yml but I feared they might cause tests to restart too often:

types:
- opened
- synchronize
- labeled
- unlabeled

Also, we may want to use a separate label specific to storage breakage, so we don't accidentally miss storage changes when we're doing a less serious breaking change in a minor release. @Amxx what do you think?

@Amxx
Copy link
Collaborator Author

Amxx commented Aug 25, 2023

In 74b8d26 I added continue-on-error for the storage layout checks if the PR is labelled as "breaking change". But note that this doesn't re-run the checks when the label is applied. To do that we would need to add these lines in checks.yml but I feared they might cause tests to restart too often:

types:
- opened
- synchronize
- labeled
- unlabeled

Also, we may want to use a separate label specific to storage breakage, so we don't accidentally miss storage changes when we're doing a less serious breaking change in a minor release. @Amxx what do you think?

A tag is nice, but I think we should also consider the changeset. This could be done in two ways:

  • Forget the tag, and automatically disable the storage check if there is a "major" changeset.
  • Keep the tag, but add a check that if this tag is turned on, then we must have a "major" changeset.

I don't have a strong opinion for the tag name. I'm ok with "breaking change", but if you want to make it more storage specific, then "storage change" would be ok I guess.

The question is, do we want all "breaking change" tags to require a major changeset, or do we accept such tags in patch releases?

@frangio
Copy link
Contributor

frangio commented Aug 25, 2023

Is your idea that the layout check would be disabled if there is any major changeset in the PR branch, or if the current PR is adding a new major changeset?

I went with the label because I thought you meant the second option and it seemed a lot more complicated to implement.

@Amxx
Copy link
Collaborator Author

Amxx commented Aug 28, 2023

if the current PR is adding a new major changeset.

I think is label is good for know.

frangio
frangio previously approved these changes Aug 29, 2023
Copy link
Contributor

@frangio frangio left a comment

Choose a reason for hiding this comment

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

I would prefer to make _maxSupply return uint208 but not a blocker to merge. We should probably document the consequence of returning a number that is larger than type(uint208).max though.

@Amxx
Copy link
Collaborator Author

Amxx commented Aug 30, 2023

I added some documentation.

@Amxx Amxx requested a review from frangio August 30, 2023 08:38
@frangio frangio enabled auto-merge (squash) August 30, 2023 17:01
@frangio frangio merged commit cd67894 into OpenZeppelin:master Aug 30, 2023
14 checks passed
Checkpoints.Checkpoint224 storage latest = _quorumNumeratorHistory._checkpoints[length - 1];
uint32 latestKey = latest._key;
uint224 latestValue = latest._value;
Checkpoints.Checkpoint208 memory latest = _quorumNumeratorHistory._checkpoints[length - 1];
Copy link
Contributor

Choose a reason for hiding this comment

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

Why memory?

Copy link
Contributor

Choose a reason for hiding this comment

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

The merge with master wasn't done correctly. Thanks for raising.

@Amxx Amxx deleted the refactor/checkpoints/use-trace208 branch August 30, 2023 19:48
ernestognw pushed a commit that referenced this pull request Sep 8, 2023
This was referenced Sep 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Changes that break backwards compatibility of the public API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants