From 2ff7307e3a9822ebba7985ec2c015e2086a0f818 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Tue, 23 Apr 2024 09:42:26 +0300 Subject: [PATCH 1/6] docs(config, world/upgrade): add proxy support --- docs/pages/world/_meta.js | 1 + docs/pages/world/upgrade.mdx | 95 ++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 docs/pages/world/upgrade.mdx diff --git a/docs/pages/world/_meta.js b/docs/pages/world/_meta.js index 655c9a21d5..506ec2a1df 100644 --- a/docs/pages/world/_meta.js +++ b/docs/pages/world/_meta.js @@ -9,6 +9,7 @@ export default { balance: "Balance", "account-delegation": "Account Delegation", "batch-calls": "Batch Calls", + "upgrade": "Upgrading", modules: "Modules", reference: "Reference", }; diff --git a/docs/pages/world/upgrade.mdx b/docs/pages/world/upgrade.mdx new file mode 100644 index 0000000000..025fe09601 --- /dev/null +++ b/docs/pages/world/upgrade.mdx @@ -0,0 +1,95 @@ +import { CollapseCode } from "../../components/CollapseCode"; +import { Callout } from "nextra/components"; + +# Upgrading worlds + +The [tables](./tables) and [`System`s](./systems) can be upgraded without changing the underlying `World` code. +However, if the `World` was deployed [behind a proxy](/config#useProxy) it is also possible to upgrade the `World` itself. +This will be useful in the future as we further develop MUD, adding features and fixing bugs. + +## Are upgrades possible? + +As per [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967#logic-contract-address), the storage slot `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` stores the address of the actual `World` contract in a proxy. +So to identify if a `World` is deployed behind a proxy run these commands: + +```sh copy +WORLD_ADDRESS=0xbe6b85dc88f969e45d8d8ae128c5a9c9744d6464 +cast implementation $WORLD_ADDRESS +``` + +If the answer is anything other than zero, the `World` is behind a proxy and can be upgraded. + +## The actual upgrade + +To upgrade the `World` use these steps in a `package/contracts` directory: + +1. Edit `.env` to add `WORLD_ADDRESS` with the address displayed by MUD Dev Tools. + For example, you might want to use this file: + + + + ```sh filename=".env" showLineNumbers copy {12} + # This .env file is for demonstration purposes only. + # + # This should usually be excluded via .gitignore and the env vars attached to + # your deployment environment, but we're including this here for ease of local + # development. Please do not commit changes to this file! + # + # Enable debug logs for MUD CLI + DEBUG=mud:* + # + # Anvil default private key: + PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + WORLD_ADDRESS=0xbe6b85dc88f969e45d8d8ae128c5a9c9744d6464 + ``` + + + +1. Create this script in `scripts/UpgradeWorld.s.sol`. + + + + ```solidity filename="UpgradeWorld.s.sol" copy showLineNumbers {18,23} + // SPDX-License-Identifier: MIT + pragma solidity >=0.8.24; + + import { Script } from "forge-std/Script.sol"; + import { console } from "forge-std/console.sol"; + + import { World } from "@latticexyz/world/src/World.sol"; + import { WorldProxy } from "@latticexyz/world/src/WorldProxy.sol"; + + contract SetImplementation is Script { + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(deployerPrivateKey); + + address proxyAddress = vm.envAddress("WORLD_ADDRESS"); + + // Deploy new world implementation + World newWorld = new World(); + + console.log("proxy:", proxyAddress); + console.log("new World:", address(newWorld)); + + WorldProxy(payable(proxyAddress)).setImplementation(address(newWorld)); + + vm.stopBroadcast(); + } + } + ``` + + + +1. Run the script. + + ```sh copy + forge script script/UpgradeWorld.s.sol --rpc-url http://localhost:8545 --broadcast + ``` + +1. See the new address. + + ```sh copy + source .env + cast implementation $WORLD_ADDRESS + ``` From 08df67315dba73a2fc05e702d93aeb4bd87c75de Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Tue, 23 Apr 2024 15:31:53 +0300 Subject: [PATCH 2/6] WIP --- docs/pages/config.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/pages/config.mdx b/docs/pages/config.mdx index e87a499fa9..cacac77cd8 100644 --- a/docs/pages/config.mdx +++ b/docs/pages/config.mdx @@ -121,3 +121,7 @@ The global configuration keys are all optional. - **`worldsFile`** a `string`: JSON file for the chain to `World` deploy address mapping. The default is `./worlds.json`. + + - + **`useProxy`** a `bool`: Whether the `World` is to be deployed behind a proxy to [enable upgrades](/world/upgrade). The + default is `false`. From d2608cf7ab3dc3c38c409d1776c3cedb72490963 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Thu, 25 Apr 2024 17:56:41 -0500 Subject: [PATCH 3/6] Changed option name to `upgradeableWorldImplementation` --- docs/pages/config.mdx | 6 +++--- docs/pages/world/upgrade.mdx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/pages/config.mdx b/docs/pages/config.mdx index cacac77cd8..d903e8399d 100644 --- a/docs/pages/config.mdx +++ b/docs/pages/config.mdx @@ -122,6 +122,6 @@ The global configuration keys are all optional. - **`worldsFile`** a `string`: JSON file for the chain to `World` deploy address mapping. The default is `./worlds.json`. - - - **`useProxy`** a `bool`: Whether the `World` is to be deployed behind a proxy to [enable upgrades](/world/upgrade). The - default is `false`. + - + **`upgradeableWorldImplementation`** a `bool`: Whether the `World` is to be deployed behind a proxy to [enable upgrades](/world/upgrade). + The default is `false`. diff --git a/docs/pages/world/upgrade.mdx b/docs/pages/world/upgrade.mdx index 025fe09601..3b717c6b5b 100644 --- a/docs/pages/world/upgrade.mdx +++ b/docs/pages/world/upgrade.mdx @@ -4,7 +4,7 @@ import { Callout } from "nextra/components"; # Upgrading worlds The [tables](./tables) and [`System`s](./systems) can be upgraded without changing the underlying `World` code. -However, if the `World` was deployed [behind a proxy](/config#useProxy) it is also possible to upgrade the `World` itself. +However, if the `World` was deployed [behind a proxy](/config#upgradeableWorldImplementation) it is also possible to upgrade the `World` itself. This will be useful in the future as we further develop MUD, adding features and fixing bugs. ## Are upgrades possible? From 04944ddcf3d863e81be370d25b7f8bf563353f13 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Thu, 25 Apr 2024 19:06:32 -0500 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: alvarius Co-authored-by: Kevin Ingersoll --- docs/pages/config.mdx | 2 +- docs/pages/world/upgrade.mdx | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/pages/config.mdx b/docs/pages/config.mdx index d903e8399d..61029cdf6d 100644 --- a/docs/pages/config.mdx +++ b/docs/pages/config.mdx @@ -123,5 +123,5 @@ The global configuration keys are all optional. The default is `./worlds.json`. - - **`upgradeableWorldImplementation`** a `bool`: Whether the `World` is to be deployed behind a proxy to [enable upgrades](/world/upgrade). + **`upgradeableWorldImplementation`** a `bool`: Whether the `World` is to be deployed behind a proxy to [enable upgrades of the core World implementation](/world/upgrade). The default is `false`. diff --git a/docs/pages/world/upgrade.mdx b/docs/pages/world/upgrade.mdx index 3b717c6b5b..a37e21e7ed 100644 --- a/docs/pages/world/upgrade.mdx +++ b/docs/pages/world/upgrade.mdx @@ -3,13 +3,13 @@ import { Callout } from "nextra/components"; # Upgrading worlds -The [tables](./tables) and [`System`s](./systems) can be upgraded without changing the underlying `World` code. +The [`System`s](./systems) can be upgraded without changing the underlying `World` code. However, if the `World` was deployed [behind a proxy](/config#upgradeableWorldImplementation) it is also possible to upgrade the `World` itself. -This will be useful in the future as we further develop MUD, adding features and fixing bugs. +This allows you to upgrade to a future version if MUD, but adds some gas overhead for all calls (due to one more level of indirection). ## Are upgrades possible? -As per [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967#logic-contract-address), the storage slot `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` stores the address of the actual `World` contract in a proxy. +As per [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967#logic-contract-address), the storage slot `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` stores the address of the `World` implementation in a proxy. So to identify if a `World` is deployed behind a proxy run these commands: ```sh copy @@ -19,7 +19,7 @@ cast implementation $WORLD_ADDRESS If the answer is anything other than zero, the `World` is behind a proxy and can be upgraded. -## The actual upgrade +## Performing an upgrade To upgrade the `World` use these steps in a `package/contracts` directory: From cb1b5200e3dd462508998d4c743ea311b49e5550 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Thu, 25 Apr 2024 19:13:13 -0500 Subject: [PATCH 5/6] prettier --- docs/pages/config.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/config.mdx b/docs/pages/config.mdx index 61029cdf6d..d251fd99ad 100644 --- a/docs/pages/config.mdx +++ b/docs/pages/config.mdx @@ -123,5 +123,5 @@ The global configuration keys are all optional. The default is `./worlds.json`. - - **`upgradeableWorldImplementation`** a `bool`: Whether the `World` is to be deployed behind a proxy to [enable upgrades of the core World implementation](/world/upgrade). - The default is `false`. + **`upgradeableWorldImplementation`** a `bool`: Whether the `World` is to be deployed behind a proxy to [enable upgrades + of the core World implementation](/world/upgrade). The default is `false`. From 3d2563825bc1a95f1ed660f4e12064cb6186ee9d Mon Sep 17 00:00:00 2001 From: yonada Date: Fri, 26 Apr 2024 18:12:53 +0100 Subject: [PATCH 6/6] docs: tweak spelling --- docs/pages/world/upgrade.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/world/upgrade.mdx b/docs/pages/world/upgrade.mdx index a37e21e7ed..fc3ea7597d 100644 --- a/docs/pages/world/upgrade.mdx +++ b/docs/pages/world/upgrade.mdx @@ -5,7 +5,7 @@ import { Callout } from "nextra/components"; The [`System`s](./systems) can be upgraded without changing the underlying `World` code. However, if the `World` was deployed [behind a proxy](/config#upgradeableWorldImplementation) it is also possible to upgrade the `World` itself. -This allows you to upgrade to a future version if MUD, but adds some gas overhead for all calls (due to one more level of indirection). +This allows you to upgrade to a future version of MUD, but adds some gas overhead for all calls (due to one more level of indirection). ## Are upgrades possible?