-
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
Holocene: contracts part for separating dynamic&static l1 attributes #11600
Holocene: contracts part for separating dynamic&static l1 attributes #11600
Conversation
The remaining test failure is here. It seems the testcase itself is not sound:
|
if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor(); | ||
|
||
if (_type == ConfigType.SET_GAS_PAYING_TOKEN) { | ||
_setGasPayingToken(_value); | ||
} else if (_type == ConfigType.ADD_DEPENDENCY) { | ||
_addDependency(_value); | ||
} else if (_type == ConfigType.REMOVE_DEPENDENCY) { | ||
_removeDependency(_value); |
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.
not a solidity expert can/should you call "super.setConfig(_type, _value)" instead of duplicating this code here?
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.
Note: L1BlockHolocene
will be shipped before L1BlockInterop
, and L1BlockInterop.setConfig
is external
instead of public
, so not callable from inherited functions.
REMOVE_DEPENDENCY | ||
REMOVE_DEPENDENCY, | ||
SET_BATCHER_HASH, | ||
SET_GAS_CONFIG_ECOTONE, |
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 replace this with two new config type events for each of the two values we hacked into the gas config with Ecotone? E.g.
SET_BASE_FEE_SCALAR
SET_BLOB_BASE_FEE_SCALAR
...allowing each to be updated independently.
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 am on board with this if you think that it results in less operational overhead, this just means a multicall is necessary to set both
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.
Alternatively just have a SET_FEE_SCALARS for both ... Important thing is to get away from the Ecotone hack that combined both fee scalars into the single "scalar" L1 attribute.
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.
Personally I don't think it's worth having two ways to do the same thing. Probably it's best to follow Mark's advice of starting with a specification where we can argue over these API details before turning it into code?
@@ -387,7 +387,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { | |||
/// @notice Internal function for updating the fee scalars as of the Ecotone upgrade. | |||
/// @param _basefeeScalar New basefeeScalar value. | |||
/// @param _blobbasefeeScalar New blobbasefeeScalar value. | |||
function _setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) internal { | |||
function _setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) internal virtual { |
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.
If we separate out the gasconfig into two update types like I suggested, we can deprecate setGasConfigEcotone entirely. (Of course we have make sure this one works if someone calls it, so we'll still have to override this implementation in SystemConfigHolocene.)
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.
Oh and you'll also want to change "_setGasConfig" to virtual so we can override it to make it do the right thing. Though since setGasConfig() has been deprecated since Ecotone, you might also just remove _setGasConfig() entirely, then make setGasConfig() revert, with the error indicating to use set(Blob)BasefeeScalar() instead.
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.
Correction to my statement above, setGasConfig() was actually not deprecated until after Ecotone (Ecotone didn't involve any changes to L1 contracts, which is why we had to hack in the new behavior using the old API). The setGasConfigEcotone() was added in a later update of the L1 contracts. IMO it should have been named setFeeScalars() -- I don't think hardfork names should be in public APIs if not entirely necessary. Regardless, since setGasConfig() wasn't deprecated until later, probably we want to keep it working for a bit longer rather than removing it entirely or just making it revert. Its implementation of course can just be made to call the new contract function(s) after appropriately parsing out the values.
/// @notice Internal function for updating the fee scalars as of the Ecotone upgrade. | ||
/// @param _basefeeScalar New basefeeScalar value. | ||
/// @param _blobbasefeeScalar New blobbasefeeScalar value. | ||
function _setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) internal override { |
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.
Implementation here could just be:
_setBasefeeScalar(_basefeeScalar);
_setBlobBasefeeScalar(_blobBasefeeScalar);
|
||
/// @notice Internal method to set new gas config. | ||
/// @param _value The encoded value with which to set the new batcher hash. | ||
function _setGasConfigEcotone(bytes calldata _value) internal { |
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.
drop, replace with _setBasefeeScalar() and _setBlobBasefeeScalar()
event BatcherHashSet(bytes32 indexed batcherHash); | ||
|
||
/// @notice Event emitted when a new ecotone gas config is set. | ||
event GasConfigEcotoneSet(uint32 indexed blobBaseFeeScalar, uint32 indexed baseFeeScalar); |
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.
replace w/ BasefeeScalarSet and BlobBasefeeScalarSet.
(nit: Note that "Basefee" and "basefee" are the idiomatic casings, whereas "BaseFee" and "baseFee" are not.)
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 changed the naming convention to the idiomatic casings for the new code, but didn't change the existing naming convention in the old code, e.g.,
uint32 public blobBaseFeeScalar; |
uint32 public baseFeeScalar; |
Summarizing most of my comments above: I think we should use this change as an opportunity to undo the ugly Ecotone gas config hack where we smash basefeeScalar and blobBasefeeScalar into a single value. For SystemConfigHolocene.sol, suggest adding: setBasefeeSalar() For SystemConfig.sol, deprecate: setGasConfig (make it revert, or make it virtual so we can override it to make it do the right thing if it still gets called. |
/// @custom:predeploy 0x4200000000000000000000000000000000000015 | ||
/// @title L1BlockHolocene | ||
/// @notice Interop extenstions of L1Block. | ||
contract L1BlockHolocene is L1BlockInterop { |
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.
We don't want to target L1BlockInterop
here since this will go to production before interop. I think naming this L1BlockHolocene
for now is safer, even though I think this could technically go right into the L1Block
contract itself. By not putting this logic into L1Block
now, it reduces risk that somebody deploys with it before its ready end to end, we will need to pull it into the regular L1Block
contract in the future.
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.
Mark, should we also be modifying SystemConfig.sol directly rather than introducing a SystemConfigHolocene.sol?
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.
Good catch, fixed in 4618303 .
/// 4. _basefee L1 base fee. | ||
/// 5. _blobBaseFee L1 blob base fee. | ||
/// 6. _hash L1 blockhash. | ||
function setL1BlockValuesHolocene() external { |
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.
We will want to implement the following comment as setL1BlockValuesHolocene
: ethereum-optimism/specs#122 (comment)
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.
Done in 4618303
This is great work so far, ultimately we will want a more formal spec before we can merge this to ensure that multi client implementations go easily and also its good for auditors to catch bugs. You can find an example of a similar sort of change here where the L1 attributes was modified for the ecotone hardfork You can see an example of the |
@blockchaindevsh I shared the above API discussion & background in the #hf-holocene discord to see if others have strong preferences. |
@tynes @roberto-bayardo The latest commit still keeps changes in the |
Usually we have this level of conversation at the specs level rather than the implementation so that code review is more checking specs against code. We would want to get weigh in from other people like @roberto-bayardo @protolambda @sebastianst @geoknee |
|
||
/// @notice Internal method to decode blobBaseFeeScalar and baseFeeScalar. | ||
/// @return Decoded blobBaseFeeScalar and baseFeeScalar. | ||
function _decodeScalar(uint256 _scalar) internal pure returns (uint32, uint32) { |
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 we will want encode/decode logic in a library so it can be a single source of truth and then imported everywhere that it is required so we only implement the logic once and we can unit test roundtrip
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.
Good point, the packing/unpacking logic is now moved into the library as packScalar
/unpackScalar
in this commit: e876fe4 . StaticConfig.encodeXXX
returns bytes, while we need to maintain the scalar variable as uint256. This is the primary reason it was not encapsulated within the StaticConfig library.
This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 5 days. |
This PR serves as a first step for "Separate Dynamic and Static L1 Attributes Values", it migrates existing
SystemConfig
updates to follow the pattern designed in ethereum-optimism/specs#122 .