-
Notifications
You must be signed in to change notification settings - Fork 0
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
Add action contracts for migrating live orbit chains to espresso #1
Conversation
function perform() external { | ||
ArbOwner arbOwner = ArbOwner(0x0000000000000000000000000000000000000070); | ||
arbOwner.scheduleArbOSUpgrade({ | ||
newVersion: newArbOSVersion, |
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.
Shouldnt the new version and timestamp be function arguments instead of constructor arguments? Then we can use the same script for multiple upgrade IMO
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.
This is what I originally thought. However, per the governance action contract guidelines this seems to be the proper format to write these contracts for an eventual proposal to the Arbitrum DAO.
In theory this also allows us to create more specific proposals by writing more wrapper contracts like the EspressoArbOSUpgrade that utilizes the general
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; | ||
import "@openzeppelin/contracts/utils/Address.sol"; | ||
|
||
error IncorrectWasmModuleRoot(bytes32 incorrectAddr); |
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 errors should be a part of the contract, so I think you should add them inside the contract object
revert IncorrectWasmModuleRoot(currentWasmModuleRoot); | ||
} | ||
|
||
if(Address.isContract(newOspEntry) == false){ |
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.
nit: can we do if(!Address.isContract(newOspEntry))
revert AddressIsNotContract(newOspEntry); | ||
} | ||
|
||
if(Address.isContract(currentOspEntry) == false){ |
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 here
@@ -0,0 +1,6 @@ | |||
export NEW_OSP_ENTRY="0x7B5F0B437EE68A22992DdD629AA22525Fc5dfa9A" |
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.
Nit: I dont think you need export
in front of the environment variables ( example 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.
This might just be from my lack of familiarity with forge and foundry. I couldn't get the env vars to be visible to the tests unless I exported them. Sourcing the file without exporting them doesn't propagate the vars to any child processes, e.g. forge test
.
If there is a different way I'm supposed to supply forge with the env vars I would love to know about it!
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 the file is called .env exactly it is special and automatically picked up by foundry and many other tools. Unfortunately it has to be exactly .env in the case of foundry.
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.
you can do source .env-espresso-osp-migration && forge test <>
to be able to have a foundry script pick up env variables that's not in the expected .env
file.
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.
That's true but then breaks the ability of being able to override with env vars. So this can get messy when used in scripts if one expects environment variable that are already set to take precedence.
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.
that's true. we aren't using the .env file for secrets anymore but only for config (since that's how it's been set up historically). So should this go into the .env file?
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.
It seems to be how existing orbit upgrades are configured in the orbit-actions repo. I think it's a good idea to stick to how things are done in that repo unless it really gets in our way.
@@ -0,0 +1 @@ | |||
export UPGRADE_TIMESTAMP = "1723664126" |
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 here
|
||
|
||
/* solhint-disable func-name-mixedcase */ | ||
//create items needed for a rollup and deploy it. This code is lovingly borrowed from the rollupcreator.t.sol foundry test. |
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.
nice!
Hey @zacshowa, can you also add a readme that explains these code additions and how to run the scripts |
contract EspressoArbOSUpgrade is UpgradeArbOSVersionAtTimestampAction, Script { | ||
constructor() | ||
UpgradeArbOSVersionAtTimestampAction( | ||
35, |
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.
when is this called? curious about this hardcoded arbOsVersion
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.
This will be called a decent amount of time before the network upgrade is supposed to take place. This will schedule a particular function inside the nodes of an orbit network to run at the given Unix timestamp.
The hardcoded 35 comes from a discussion I had with Mathis when we were first pursuing designating this as an ArbOS upgrade.
Basically, the way ArbOS upgrades are performed is via a switch statement that has some pre-defined gaps in version numbers left open for orbit chains. We chose 35 as it leaves some room for previous upgrades, as well as room for future upgrades in the most recent gap.
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.
ahh interesting - let's add that in the comments then, and maybe leave instructions in the readme if it ever has to change
} | ||
|
||
function perform() external { | ||
ArbOwner arbOwner = ArbOwner(0x0000000000000000000000000000000000000070); |
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.
why is this address used?
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.
This magic value is just the location of the ArbOwner precompile that lives on all arbitrum orbit chains at a specific address.
I'll leave a comment explaining it in the code.
uint64 public immutable newArbOSVersion; | ||
uint64 public immutable upgradeTimestamp; | ||
|
||
constructor(uint64 _newArbOSVersion, uint64 _upgradeTimestamp) { |
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.
do we need uint64 for the arbOSVersion?
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 would argue that most of the way this is done doesn't "need" to happen this way, but I wrote these contracts to broadly conform with the guidance in the arbitrum governance repo here
For the sake of time we aren't using address registries and are instead using env variables for the generic and proposal specific version of the contracts. I'm just doing it this way to minimize the amount of future work to convert this to a reasonable proposal for the Arbitrum DAO
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.
ok great!
uint64 public immutable upgradeTimestamp; | ||
|
||
constructor(uint64 _newArbOSVersion, uint64 _upgradeTimestamp) { | ||
newArbOSVersion = _newArbOSVersion; |
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.
consider adding error checking to ensure that the values passed here are valid
@@ -0,0 +1,34 @@ | |||
// SPDX-License-Identifier: Apache-2.0 |
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 sure which license we'd want to use but we normally default to UNLICENSED
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.
Ill go ahead and add UNLICENSED to all of the files that require it.
@@ -0,0 +1,107 @@ | |||
pragma solidity ^0.8.9; |
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.
add the SPDX license identifier
); | ||
address postUpgradeChalManAddr = ProxyAdmin(proxyAdmin).getProxyImplementation(challengeManager); | ||
|
||
if(postUpgradeChalManAddr != chalManImpl){ |
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 like this check!
address _rollup, | ||
address _proxyAdmin | ||
){ | ||
newOspEntry = _newOspEntry; |
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.
perhaps add some error checking for these variables in the constructor
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 add the checks in the perform function to the constructor we can, in theory, remove them from the perform function to avoid using extra gas correct?
|
||
address migration = address(new EspressoOspMigrationAction()); | ||
|
||
vm.prank(rollupOwner); |
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.
consider adding more tests that check for negative scenarios e.g. expecting a revert of a non-rollup owner tries to execute the upgrade
…OSUpgradeAtTimestampAction contract instead of duplicating it.
migration-test
migration-test
contracts/parent-chain/contract-upgrades/DeployEspressoOsp.s.sol
Outdated
Show resolved
Hide resolved
contracts/parent-chain/contract-upgrades/DeployEspressoOsp.s.sol
Outdated
Show resolved
Hide resolved
This allows us to set all the config from the test script
|
||
#### A note on Upgrade Executors | ||
|
||
This migration presumes there to be upgrade executor contracts that are chain/rollup owners on both the parent chain, as well as the child chain. If you do not have an upgrade executor on the child chain, the contract execution commands at the end of this guide will not work. |
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.
👍
migration/README.md
Outdated
The parent chain is where most of the contract deployments will happen for the migration to espresso. There are two forge scripts that you need to deploy on the parent chain. These scripts are located in the following directories: | ||
|
||
``` | ||
orbit-actions/contracts/parent-chain/espresso-migration/DeployEspressoOsp.s.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.
You can use markdown links relative to files in this repo.
https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#links
1. DeployEspressoOsp.s.sol | ||
2. DeployEspressoOspMigrationAction.s.sol | ||
|
||
In between these deployments you need to record the address of the newly deployed OneStepProverEntry contract and export it in the env var `NEW_OSP_ENTRY` |
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.
Is this obvious from the output? Or should we add a jq
command 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.
I think the output of that command would be obvious if you're running the same verbosity level on the forge script. But I think it also makes sense to add the command anyways. as we know exactly how forge will output the broadcast file.
Co-authored-by: Mathis <[email protected]>
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.
contracts/parent-chain/espresso-migration/EspressoOspMigrationAction.sol
Outdated
Show resolved
Hide resolved
…-actions into espresso-migration
This PR:
This PR adds action upgrade contracts to the orbit-action repo to upgrade orbit chains to be compatible with the espresso sequencing marketplace.
This PR does not:
Include scripts to deploy and perform these action upgrades. Set the chain config in the arbOS upgrade.
Key places to review:
EspressoOspMigrationAction.sol and EspressoMigrationAction.t.sol.
forge test in the repo's top level
EspressoOspMigrationAction.sol