Skip to content

Enable ability to upgrade code and storage of L2 contracts #498

@karlfloersch

Description

@karlfloersch

Is your feature request related to a problem? Please describe.
We currently do not have any way (other than regenesis) to upgrade our L2 contracts! This is no good as regenesis wipes historical transactions & requires coordination with everyone running nodes. Instead we need a way to cleanly upgrade our contracts that enables minimal downtime, multi-party coordination, and max simplicity.

Describe the solution you'd like
Implement automated OVM self upgrades. See a larger exploration of this topic here: https://www.notion.so/optimismpbc/Project-OVM-Upgradability-a0f2298a5aba469ea5749d6feb1aae3e

A simplified example flow for L2 upgrades here look like this:

  1. Make change to our predeploys in monorepo
  2. Run the deployer (aka chugsplash). This will..
  • Generate a deployment script with all code & state that we want in the deployment based on the deployment config
  • Generate a commitment to the deployment
  • Everyone signs a multi-sig which approves the deployment based on the generated commitment
  • The commitment is deposited into L2 from L1
  • Pause transaction ingestion in L2Geth
  • On L2 the upgrader contract calls setCode and setStorage based on the information in the commitment.
  • Resume transaction ingestion in L2Geth / in the ExecutionManager now that the upgrade has completed.
  1. Celebrate because our upgrades are automated!

TODO:

  • Add an L2 predeploy Upgrader which is authenticated to call setCode and setStorage
  • Update L2Geth to support setCode
  • Write UpgradeExecutor contract for L2 that calls the Upgrader contract based on the deployment commitment that was deposited.
  • Implement deployer (aka chugsplash)
    • Add deployment script generator which generates a deployment script based on the deploy config
    • Add L1 UpgradeExecutor which will just execute an enqueue which initiates the L2 deployment (which will be executed through the L2 UpgradeExecutor)
    • Add L1 / L2 deployment executor JS code which, based on a deployment script, executes the deployment if the deployment has been authorized / initiated.
    • Perform an L2 upgrade using this full system!
  • Update infra & l2geth to ensure upgrades are fully automated & no transactions are sent during an upgrade.
    • Should update that status page to UPGRADE IN PROGRESS or something like that.
  • Ensure it is possible to add env vars which set the environment specific variables like FRUAD_PROOF_WINDOW & SEQUENCER_ADDRESS.

Note on status quo deployment configuration

Our current deployment system splits out deployments into 2 configurations:

  1. Deployment configuration -- deploy files which define the default deployment one would perform. ADDITIONALLY these files make use of environment variables passed in through process.env
  2. Environment configuration -- When we update the contracts or the deployment script, we tag a new release which results in a final infrastructure config which looks similar to this: kovan.json - { image: 'v0.2.0', env: { 'FRUAD_PROOF_WINDOW': 100, ... }} (note I used json because it's easy to write a single line example)

Metadata

Metadata

Labels

C-featureCategory: features

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions