diff --git a/contrib/localnet/README.md b/contrib/localnet/README.md index 17a2ae3d03..5181b40828 100644 --- a/contrib/localnet/README.md +++ b/contrib/localnet/README.md @@ -67,3 +67,194 @@ The following are required to run the localnet: - [Git](https://git-scm.com/downloads) - [Go](https://golang.org/doc/install) - [jq](https://stedolan.github.io/jq/download/) + + +### OP Integration + +1 - Run localnet from `docker-compose-optimism.yml`. +>Adjust the exposed ports as necessary to avoid conflicts. + +2 - Run localnet from OP documentation : [Optimism Dev Node](https://docs.optimism.io/chain/testing/dev-node) + +3 - Make sure OP components are running alongside with Zeta localnet with existing EVM, BTC, and Zetachain nodes. + +4 - Deploy OP smart contracts from [Optimism Smart Contract Deployment Guide](https://docs.optimism.io/builders/chain-operators/deploy/smart-contracts) + +After running all scripts, you may encounter issues depending on your local environment, such as: + +* Variables not being declared correctly. For instance, in my case, I had to modify `Config.sol` to deploy the contract. Some functions required static variables because this is just a local dev network. + +>before: +```solidity + function deployConfigPath() internal view returns (string memory _env) { + if (vm.isContext(VmSafe.ForgeContext.TestGroup)) { + _env = string.concat(vm.projectRoot(), "/deploy-config/hardhat.json"); + } else { + _env = vm.envOr("DEPLOY_CONFIG_PATH", string("")); + require(bytes(_env).length > 0, "Config: must set DEPLOY_CONFIG_PATH to filesystem path of deploy config"); + } + } + ``` + + >after: + ```solidity + function deployConfigPath() internal pure returns (string memory _env) { + _env = "deploy-config/devnetL1.json"; + } + ``` + +* Error message like `(called 'Option::unwrap()' on a 'None' value)` which do indicates a problem inside the Foundry's forge tool, specifically within the `revm` library. + +To resolve this, I added debugging steps in my `deploy.sh` to ensure environment variables are set correctly. + +````bash +echo "> Deploying contracts" +echo "RPC URL: $DEPLOY_ETH_RPC_URL" +echo "Private Key: $DEPLOY_PRIVATE_KEY" +echo "Config Path: $DEPLOY_CONFIG_PATH" +```` + +Ensure that Foundry and Forge are updated to the latest versions using `foundryup`. + +Compile a minimal Forge smart contract , such as `SimpleDeploy.s.sol`and execute it: + +````solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract SimpleDeploy { + function run() external { + // Minimal deployment logic + } +} +```` + +```sh +forge script -vvv scripts/deploy/SimpleDeploy.s.sol:SimpleDeploy --rpc-url 127.0.0.1:18545 --broadcast --private-key xxxxxxxxxxxxxxxxxxx +``` + +If execution is correct, try redepoying the set of contracts using `deploy.sh`. + +- Deployment may proceed, but you might face issues with the `CREATE2` Deployer contract if it is not present in your local network: : + + +```log +== Logs == + Writing artifact to /Users/aminechakrellah/Desktop/Projects/ZetaChain/optimism/packages/contracts-bedrock/deployments/1337-deploy.json + Connected to network with chainid 1337 + Commit hash: 39bd919d8063ad57003eb2ac457743a241aa6df9 + DeployConfig: reading file deploy-config/devnetL1.json + Deploying a fresh OP Stack including SuperchainConfig + start of L1 Deploy! + Deploying safe: SystemOwnerSafe with salt 0x47555c7c5eb40250af82c9713b290d445cad0893c01b18ae084f70d0b7b0d67d + Saving SafeProxyFactory: 0x5FbDB2315678afecb367f032d93F642f64180aa3 + Saving SafeSingleton: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 + Saving SystemOwnerSafe: 0xE97C3206DB3e054Ef065FF121BE168063721BA19 + New safe: SystemOwnerSafe deployed at 0xE97C3206DB3e054Ef065FF121BE168063721BA19 + Note that this safe is owned by the deployer key + deployed Safe! + Setting up Superchain + Deploying AddressManager + Saving AddressManager: 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 + AddressManager deployed at 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 + Deploying ProxyAdmin + Saving ProxyAdmin: 0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9 + ProxyAdmin deployed at 0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9 + ProxyAdmin ownership transferred to Safe at: 0xE97C3206DB3e054Ef065FF121BE168063721BA19 + Deploying ERC1967 proxy for SuperchainConfigProxy + Saving SuperchainConfigProxy: 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 + at 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 +Error: +script failed: missing CREATE2 deployer +``` +Follow up with the [Optimism Documentation on how to deploy CREATE2 factory](https://docs.optimism.io/builders/chain-operators/tutorials/create-l2-rollup#deploy-the-create2-factory-optional). + + +- Add `rpc.allow-unprotected-txs` to geth if you cannot post transactions while deploying CREATE2. +- Use MetaMask to connect to your localnet to send transactions and fund smart contract addresses easily. +- Deploy the factory +```bash +cast publish --rpc-url http://0.0.0.0:18545 0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222 +``` + +>output +```json +{ + "status":"0x1", + "cumulativeGasUsed":"0x10a23", + "logs":[], + "logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type":"0x0", + "transactionHash":"0xeddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26", + "transactionIndex":"0x0", + "blockHash":"0xa11e0bb5e8d2d6be633f16a46070fb1e2d8104778d84d1bb08fc997a3e754c26", + "blockNumber":"0x2e2", + "gasUsed":"0x10a23", + "effectiveGasPrice":"0x174876e800", + "from":"0x3fab184622dc19b6109349b94811493bf2a45362", + "to":null, + "contractAddress":"0x4e59b44847b379578588920ca78fbf26c0b4956c" +} +``` + +- Check Tx is mined : + +```json +{ + "jsonrpc":"2.0", + "method":"eth_getTransactionReceipt", + "params":["0xeddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26"], + "id":1 +} +``` + +- Verify the factory is deployed : +```sh +cast codesize 0x4e59b44847b379578588920cA78FbF26c0B4956C --rpc-url http://0.0.0.0:18545 +#output +69 +``` + +At this stage you can redploy the L1 contracts : + +```sh +npm run deploy +``` + +```log +========================== + +ONCHAIN EXECUTION COMPLETE & SUCCESSFUL. + +Transactions saved to: /Users/aminechakrellah/Desktop/Projects/ZetaChain/optimism/packages/contracts-bedrock/broadcast/Deploy.s.sol/1337/run-latest.json + +Sensitive values saved to: /Users/aminechakrellah/Desktop/Projects/ZetaChain/optimism/packages/contracts-bedrock/cache/Deploy.s.sol/1337/run-latest.json +``` + +- Create genesis file : + +```sh +go run cmd/main.go genesis l2 \ + --deploy-config ../packages/contracts-bedrock/deploy-config/devnetL1.json \ + --l1-deployments ../packages/contracts-bedrock/deployments/devnetL1/.deploy \ + --outfile.l2 genesis.json \ + --outfile.rollup rollup.json \ + --l1-rpc 0.0.0.0:18545 +``` + + + + + + + + + + + + + + + + + diff --git a/contrib/localnet/docker-compose-optimism.yml b/contrib/localnet/docker-compose-optimism.yml new file mode 100644 index 0000000000..8f2d404c88 --- /dev/null +++ b/contrib/localnet/docker-compose-optimism.yml @@ -0,0 +1,282 @@ +# This docker-compose file configures the localnet environment +# it contains the following services: +# - ZetaChain with 2 nodes (zetacore0, zetacore1). When profile set to stress, 4 nodes will be created. +# - A observer set with 2 clients (zetaclient0, zetaclient1). When profile set to stress, 4 clients will be created. +# - An Ethereum node (eth) +# - A secondary optional Ethereum node (eth2) enabled when profile is set to eth2 +# - A Bitcoin node (bitcoin) +# - A Rosetta API (rosetta) +# - An orchestrator to manage interaction with the localnet (orchestrator) +# - An upgrade host to serve binaries for the upgrade tests (upgrade-host). Only enabled when profile is set to upgrade. +# - An upgrade orchestrator to send the upgrade governance proposal (upgrade-orchestrator). Only enabled when profile is set to upgrade. + +networks: + mynetwork: + ipam: + config: + - subnet: 172.20.0.0/24 + +services: + rosetta: + image: zetanode:latest + container_name: rosetta + hostname: rosetta + depends_on: + zetacore0: + condition: service_healthy + ports: + - "18080:8080" + networks: + mynetwork: + ipv4_address: 172.20.0.200 + entrypoint: ["zetacored", "rosetta", "--tendermint", "zetacore0:26657", "--grpc", "zetacore0:9090", "--network", "athens_101-1", "--blockchain", "zetacore"] + volumes: + - ssh:/root/.ssh + + zetacore0: + image: zetanode:latest + container_name: zetacore0 + hostname: zetacore0 + ports: + - "1317:1317" + - "28545:8545" + - "9546:8546" + - "26657:26657" + - "6063:6060" + - "9090:9090" + healthcheck: + # use the zevm endpoint for the healthcheck as it is the slowest to come up + test: ["CMD", "curl", "-f", "-X", "POST", "--data", '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}', "-H", "Content-Type: application/json", "http://localhost:8545"] + interval: 30s + timeout: 10s + retries: 3 + start_period: ${ZETACORED_START_PERIOD-30s} + start_interval: 1s + networks: + mynetwork: + ipv4_address: 172.20.0.11 + entrypoint: ["/root/start-zetacored.sh"] + environment: + - HOTKEY_BACKEND=file + - HOTKEY_PASSWORD=password # test purposes only + - ZETACORED_IMPORT_GENESIS_DATA=${ZETACORED_IMPORT_GENESIS_DATA-} + volumes: + - ssh:/root/.ssh + - ~/.zetacored/genesis_data:/root/genesis_data + + zetacore1: + image: zetanode:latest + container_name: zetacore1 + hostname: zetacore1 + networks: + mynetwork: + ipv4_address: 172.20.0.12 + entrypoint: ["/root/start-zetacored.sh"] + environment: + - HOTKEY_BACKEND=file + - HOTKEY_PASSWORD=password # test purposes only + volumes: + - ssh:/root/.ssh + + zetacore2: + image: zetanode:latest + container_name: zetacore2 + hostname: zetacore2 + profiles: + - stress + - all + networks: + mynetwork: + ipv4_address: 172.20.0.13 + entrypoint: [ "/root/start-zetacored.sh", "4" ] + environment: + - HOTKEY_BACKEND=file + - HOTKEY_PASSWORD=password # test purposes only + volumes: + - ssh:/root/.ssh + + zetacore3: + image: zetanode:latest + container_name: zetacore3 + hostname: zetacore3 + profiles: + - stress + - all + networks: + mynetwork: + ipv4_address: 172.20.0.14 + entrypoint: [ "/root/start-zetacored.sh", "4" ] + environment: + - HOTKEY_BACKEND=file + - HOTKEY_PASSWORD=password # test purposes only + volumes: + - ssh:/root/.ssh + + zetaclient0: + image: zetanode:latest + container_name: zetaclient0 + hostname: zetaclient0 + networks: + mynetwork: + ipv4_address: 172.20.0.21 + entrypoint: /root/start-zetaclientd.sh + environment: + - ETHDEV_ENDPOINT=http://eth:18545 + - HOTKEY_BACKEND=file + - HOTKEY_PASSWORD=password # test purposes only + volumes: + - ssh:/root/.ssh + - preparams:/root/preparams + + zetaclient1: + image: zetanode:latest + container_name: zetaclient1 + hostname: zetaclient1 + networks: + mynetwork: + ipv4_address: 172.20.0.22 + entrypoint: /root/start-zetaclientd.sh + environment: + - ETHDEV_ENDPOINT=http://eth:18545 + - HOTKEY_BACKEND=file + - HOTKEY_PASSWORD=password # test purposes only + volumes: + - ssh:/root/.ssh + - preparams:/root/preparams + + zetaclient2: + image: zetanode:latest + container_name: zetaclient2 + hostname: zetaclient2 + profiles: + - stress + - all + networks: + mynetwork: + ipv4_address: 172.20.0.23 + entrypoint: /root/start-zetaclientd.sh + environment: + - HOTKEY_BACKEND=file + - HOTKEY_PASSWORD=password # test purposes only + volumes: + - ssh:/root/.ssh + - preparams:/root/preparams + + zetaclient3: + image: zetanode:latest + container_name: zetaclient3 + hostname: zetaclient3 + profiles: + - stress + - all + networks: + mynetwork: + ipv4_address: 172.20.0.24 + entrypoint: /root/start-zetaclientd.sh + environment: + - HOTKEY_BACKEND=file + - HOTKEY_PASSWORD=password # test purposes only + volumes: + - ssh:/root/.ssh + - preparams:/root/preparams + + eth: + image: ethereum/client-go:v1.10.26 + container_name: eth + hostname: eth + ports: + - "18545:8545" + networks: + mynetwork: + ipv4_address: 172.20.0.100 + entrypoint: ["geth", "--dev", "--http", "--http.addr", "172.20.0.100", "--http.vhosts", "*", "--http.api", "eth,web3,net", "--http.corsdomain", "https://remix.ethereum.org", "--dev.period", "2", --rpc.allow-unprotected-txs] + + eth2: + build: + context: ./anvil + container_name: eth2 + hostname: eth2 + profiles: + - eth2 + - all + platform: linux/amd64 + ports: + - "38545:8545" + networks: + mynetwork: + ipv4_address: 172.20.0.102 + + bitcoin: + image: ruimarinho/bitcoin-core:22 # version 23 is not working with btcd 0.22.0 due to change in createwallet rpc + container_name: bitcoin + hostname: bitcoin + networks: + mynetwork: + ipv4_address: 172.20.0.101 + ports: + - "18443:18443" + command: + -printtoconsole + -regtest=1 + -rpcallowip=0.0.0.0/0 + -rpcbind=0.0.0.0 + -rpcauth=smoketest:63acf9b8dccecce914d85ff8c044b78b$$5892f9bbc84f4364e79f0970039f88bdd823f168d4acc76099ab97b14a766a99 + -txindex=1 + + orchestrator: + image: orchestrator:latest + tty: true + container_name: orchestrator + depends_on: + zetacore0: + condition: service_healthy + eth: + condition: service_started + hostname: orchestrator + networks: + mynetwork: + ipv4_address: 172.20.0.2 + entrypoint: ["/work/start-zetae2e.sh", "local"] + environment: + - LOCALNET_MODE=${LOCALNET_MODE-} + - E2E_ARGS=${E2E_ARGS-} + - UPGRADE_HEIGHT=${UPGRADE_HEIGHT-} + volumes: + - ssh:/root/.ssh + + upgrade-host: + image: zetanode:latest + container_name: upgrade-host + hostname: upgrade-host + profiles: + - upgrade + - all + entrypoint: ["/root/start-upgrade-host.sh"] + networks: + mynetwork: + ipv4_address: 172.20.0.250 + volumes: + - ssh:/root/.ssh + + upgrade-orchestrator: + # must run from old node for api compatibility + image: zetanode:old + container_name: upgrade-orchestrator + hostname: upgrade-orchestrator + profiles: + - upgrade + - all + entrypoint: ["/root/start-upgrade-orchestrator.sh"] + networks: + mynetwork: + ipv4_address: 172.20.0.251 + depends_on: + - zetacore0 + - upgrade-host + environment: + - UPGRADE_HEIGHT=${UPGRADE_HEIGHT-} + volumes: + - ssh:/root/.ssh +volumes: + ssh: + preparams: