omgnetwork / research

43 stars 2 forks source link

Smart contract upgradeability design #49

Closed boolafish closed 5 years ago

boolafish commented 5 years ago

Note

As a plasma user, I want the contract to be able to upgrade smoothly, So that I don't need to go through the hassle of exit and re-join for every plasma contract upgrade.

As an engineer, I want the contract to be able to upgrade smoothly, So that I can continuously deliver changes when needed.

As an engineer, I want to have a guideline on contract upgrade. So that I can make the decision when designing and roll out a new feature or patching bug fixes.

Successful Criteria

Out of scope

boolafish commented 5 years ago

Sort of work in progress already, would try to set up a meeting for the doc review. https://omisego.atlassian.net/wiki/spaces/RES/pages/21233681/Upgrade+Mechanism+Design?atlOrigin=eyJpIjoiYmNjZTVmNTk1YTIxNDdiOGEyYzc1ZDY5NTIwYzY0OTgiLCJwIjoiYyJ9

pik694 commented 5 years ago

Testing upgraded contract by forking the mainnet

Overview

The document describes a possible solution to enabling users to test the upgraded contract before the newer code becomes valid. The proposed solution is based on creating a local, private fork of the mainnet when an upgrade of the contract starts.

Background

Having the possibility of upgrading the contract, we would also like to enable the users to test the newer version of the contract on production data before the upgraded code becomes the valid one.

Requirements

  1. Tests can be done on mainnet data. This is valuable because of the difficulty of creating a good test data and also because of a quirk of delegatecall based update mechanism - data layout in the storage of the proxy contract is implicit and can be corrupted by an updated library.
  2. There is full isolation between mainnet and the testnet. This means replay protection - different network id for the forked chain.

Possible solution - forking

We propose a solution that bases on forking the mainnet shortly after the next version of the contract is loaded, a long time before it becomes active. We would like to switch our, till now normally working, node into dev mode, so it's able to forward the time to the moment when the contract switches. Creating a fork means that the state of the mainnet is copied into the testnet, therefore the first requirement is met.

Accordingly to the second requirement, the switch into dev mode would mean that the node would also have to change its chain id.

The fork should also produce blocks much quicker than it happens on the mainnet, so all contract flows would take less time than on the mainnet. As long as the fork works quicker than the normal world, users can quite quickly go through the upgraded flows and decide whether they should/want to exit while still previous code is valid.

boolafish commented 5 years ago

@pik694 I like that idea of forking. Just curious does anyone know how easy/hard it is to do so? If possible, can we also document some high level steps to do that? I am assuming we first spin a client node and sync to main-net. After up-to-date, we remove all connection with other nodes. But how do we switch to mode that provide faster block?

InoMurko commented 5 years ago

Commenting from Mana's codebase:

Things that would need to change or be finished on Mana:

boolafish commented 5 years ago

wow actually Ganache have the --fork option: https://truffleframework.com/tutorials/chain-forking-exploiting-the-dao

EDIT: Tried ganache forking rinkeby using infura ganache-cli --fork https://rinkeby.infura.io/v3/[:api_key] would work! And can start using localhost:8545 as web3 provider.

boolafish commented 5 years ago

Copy the above Forking mechanism to a OmiseGO wiki for future reference: here

boolafish commented 5 years ago

I think there is enough design here, close this design story.

Summarizing the main docs:

There's a follow up POC implementation story: https://github.com/omisego/research/issues/78.