-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Make ISemver and abstract contract, and define semver in a struct #13748
base: develop
Are you sure you want to change the base?
Conversation
3063274
to
ca01d01
Compare
ca01d01
to
468edad
Compare
Why did you make these changes on L2? We aren't doing a release of the L2 contracts based on this, we should reduce the diff in this PR and not modify any L2 contracts. We can integrate these changes into the standard L2 genesis project. I don't love Inlining the struct makes it nice and human readable. |
This is a case in which enforcing codecov at a very high % for merge will bite us |
We put them in a separate commit so that we could easily handle such a comment. The main challenge will be that the semver check script needed to be refactored for the struct based approach. This will require an L1 and L2 semver check, but we can probably deal with that.
We can come up with a shorter name. The purpose for making it public is to expose the uint64 value which is encoded in the bytecode. We are also adding a public function which will expose the |
The STYLE_GUIDE.md says Is the style changed after this PR? |
This changes how contract level semver values are defined, which unlocks an improvement to how the input
X
toreinitializer(X)
is defined.Context
During Solidity development, developers need a clear way to determine the appropriate argument for the reinitializer modifier,
ie. How should they decide what is the correct value for
X
?The previous plan of defining a new
Releases.sol
as either anabstract contract
orlibrary
had the flaw that changing therelease version would modify the bytecode of all contracts, thus forcing all implementations to be redeployed for each upgrade. This unnecessarily increases the state diff of each upgrade. Our update approach instead leverages the already existing per-contract semver versioning system.
Before outlining this new approach, we first recap the goals:
-beta.n
tag to contract semvers.Solution
Approach
We propose to replace
ISemver
with an abstractSemver
.Details:
will be converted into a reinitializer value. This is done by converting the
major
,minor
andpatch
numbers into a singleuint64
value:Then the
initialize()
andupgrade()
methods of a contract will simply havereinitializer(reinitializerValue())
.We don't want to generate the reinitializer argument by parsing strings, therefore we will store the semver values as integers in a struct rather than as string. Thus instead of each contract defining
string constant version = "1.2.3"
, each contract will need to define aninternal
function:In order to maintain the the existing interface (
function version() external view returns (string memory)
), theversion()
function moves intoSemver
, and converts the struct values to a string:Consequences for releases
upgrade()
function will only be required when new storage values are beingadded. The previous plan had been to remove these functions after the upgrade was completed. However, because we only want to redeploy contracts when their bytecode changes, we will not remove the
upgrade()
functions until some other changenecessitates an increase of the semver value. Automation will be created to identify this situation.
-beta
tags to clarify when a contract is not production ready, the OPCM contract and superchain-registrywill combine to become the source of truth for what is included in a release, by including the addresses of the implementations of released contracts. Importantly, implementations are now deterministically deployed, so that they are not
replaced if their bytecode is unchanged. Taking the
OptimismMintableErc20Factory
as an example, while every OPCM will containan
address optimismMintableErc20FactoryImpl
, that address will only change if its bytecode has been modified.opcm.upgrade()
will not update the value at theProxy.IMPLEMENTATION_SLOT
, thus minimizing the state diff of an upgrade.and ensure that the
reinitializerValue
is set properly.