diff --git a/.circleci/config.yml b/.circleci/config.yml index e91cc7fe1..7700560ac 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,11 +68,6 @@ commands: apt-get update apt-get -yq install curl git mercurial make binutils bison gcc build-essential bsdmainutils bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer) - install-nvm: - description: "Installs nvm" - steps: - - run: - command: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash validate-genesis: description: "Runs genesis validation checks" steps: @@ -132,7 +127,11 @@ jobs: - checkout - install-foundry - install-gvm - - install-nvm + - run: + name: Install NVM + command: | + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash + nvm --version - validate-genesis # TODO this should also be filtered on modified chains golang-validate-modified: shell: /bin/bash -eo pipefail diff --git a/bindings/rust-bindings/etc/chainList.toml b/bindings/rust-bindings/etc/chainList.toml index b347e0b11..3b1c0bc92 100644 --- a/bindings/rust-bindings/etc/chainList.toml +++ b/bindings/rust-bindings/etc/chainList.toml @@ -95,6 +95,18 @@ type = "L2" chain = "mainnet" +[[chains]] + name = "World Chain" + identifier = "mainnet/wc" + chain_id = 480 + rpc = ["https://worldchain-mainnet-sequencer.g.alchemy.com"] + explorers = ["https://worldchain-mainnet-explorer.alchemy.com/"] + superchain_level = 0 + data_availability_type = "eth-da" + [chains.parent] + type = "L2" + chain = "mainnet" + [[chains]] name = "Zora" identifier = "mainnet/zora" @@ -167,6 +179,18 @@ type = "L2" chain = "sepolia" +[[chains]] + name = "World Chain Sepolia Testnet" + identifier = "sepolia/wc" + chain_id = 4801 + rpc = [""] + explorers = ["https://worldchain-sepolia-explorer.alchemy.com/"] + superchain_level = 0 + data_availability_type = "eth-da" + [chains.parent] + type = "L2" + chain = "sepolia" + [[chains]] name = "Zora Sepolia Testnet" identifier = "sepolia/zora" diff --git a/bindings/rust-bindings/etc/configs.toml b/bindings/rust-bindings/etc/configs.toml index a492c4675..905cda484 100644 --- a/bindings/rust-bindings/etc/configs.toml +++ b/bindings/rust-bindings/etc/configs.toml @@ -129,6 +129,62 @@ PreimageOracle = "0x0000000000000000000000000000000000000000" DAChallengeAddress = "0x0000000000000000000000000000000000000000" + [[superchains.chains]] + name = "World Chain" + chain_id = 480 + public_rpc = "https://worldchain-mainnet-sequencer.g.alchemy.com" + sequencer_rpc = "https://worldchain-mainnet-sequencer.g.alchemy.com" + explorer = "https://worldchain-mainnet-explorer.alchemy.com/" + superchain_level = 0 + standard_chain_candidate = true + batch_inbox_addr = "0xff00000000000000000000000000000000000480" + canyon_time = 0 + delta_time = 0 + ecotone_time = 0 + block_time = 2 + seq_window_size = 3600 + max_sequencer_drift = 1800 + data_availability_type = "eth-da" + [superchains.chains.genesis] + l2_time = 1719335639 + [superchains.chains.genesis.l1] + hash = "0x793daed4743301e00143be5533cd1dce0a741519e9e9c96588a9ad7dbb4d8db4" + number = 20170118 + [superchains.chains.genesis.l2] + hash = "0x70d316d2e0973b62332ba2e9768dd7854298d7ffe77f0409ffdb8d859f2d3fa3" + number = 0 + [superchains.chains.genesis.system_config] + batcherAddress = "0xdBBE3D8c2d2b22A2611c5A94A9a12C2fCD49Eb29" + overhead = "0x00000000000000000000000000000000000000000000000000000000000000bc" + scalar = "0x00000000000000000000000000000000000000000000000000000000000a6fe0" + gasLimit = 100000000 + [superchains.chains.addresses] + SystemConfigOwner = "0xB2aa0C2C4fD6BFCBF699d4c787CD6Cc0dC461a9d" + ProxyAdminOwner = "0xA4fB12D15Eb85dc9284a7df0AdBC8B696EdbbF1d" + Guardian = "0xB2aa0C2C4fD6BFCBF699d4c787CD6Cc0dC461a9d" + Challenger = "0xB2aa0C2C4fD6BFCBF699d4c787CD6Cc0dC461a9d" + Proposer = "0x2307278fC8aB0005974A6DeD2FA6d1187333a223" + UnsafeBlockSigner = "0x2270d6eC8E760daA317DD978cFB98C8f144B1f3A" + BatchSubmitter = "0xdBBE3D8c2d2b22A2611c5A94A9a12C2fCD49Eb29" + AddressManager = "0x5891090d5085679714cb0e62f74950a3c19146a8" + L1CrossDomainMessengerProxy = "0xf931a81D18B1766d15695ffc7c1920a62b7e710a" + L1ERC721BridgeProxy = "0x1Df436AfDb2fBB40F1fE8bEd4Fc89A0D0990a8E9" + L1StandardBridgeProxy = "0x470458C91978D2d929704489Ad730DC3E3001113" + L2OutputOracleProxy = "0x19A6d1E9034596196295CF148509796978343c5D" + OptimismMintableERC20FactoryProxy = "0x82Cb528466cF22412d89bdBE9bCF04856790dD0e" + OptimismPortalProxy = "0xd5ec14a83B7d95BE1E2Ac12523e2dEE12Cbeea6C" + SystemConfigProxy = "0x6ab0777fD0e609CE58F939a7F70Fe41F5Aa6300A" + ProxyAdmin = "0xd7405BE7f3e63b094Af6C7C23D5eE33Fd82F872D" + SuperchainConfig = "0xa231f8be37e583f276f93dF516D88a043bfe47E3" + AnchorStateRegistryProxy = "0x1325C4966d17038C5592fb38416AeE85EE73c0cb" + DelayedWETHProxy = "0xF9adF7c9502C5C60352C20a4d22683422DbD061F" + DisputeGameFactoryProxy = "0x0E90dCAFBC242D2C861A20Bb20EC8E7182965a52" + FaultDisputeGame = "0x0000000000000000000000000000000000000000" + MIPS = "0x267b2FFfA613c246Ef995390Ea0a2BaAA16a80Ba" + PermissionedDisputeGame = "0x0000000000000000000000000000000000000000" + PreimageOracle = "0x3941778243E3E80a6a46D149F083825dEdc534BB" + DAChallengeAddress = "0x0000000000000000000000000000000000000000" + [[superchains.chains]] name = "Binary Mainnet" chain_id = 624 @@ -660,6 +716,62 @@ PreimageOracle = "0x0000000000000000000000000000000000000000" DAChallengeAddress = "0x0000000000000000000000000000000000000000" + [[superchains.chains]] + name = "World Chain Sepolia Testnet" + chain_id = 4801 + public_rpc = "" + sequencer_rpc = "https://worldchain-sepolia-sequencer.g.alchemy.com" + explorer = "https://worldchain-sepolia-explorer.alchemy.com/" + superchain_level = 0 + standard_chain_candidate = true + batch_inbox_addr = "0xFf00000000000000000000000000000000484752" + canyon_time = 0 + delta_time = 0 + ecotone_time = 0 + block_time = 2 + seq_window_size = 3600 + max_sequencer_drift = 1800 + data_availability_type = "eth-da" + [superchains.chains.genesis] + l2_time = 1720547424 + [superchains.chains.genesis.l1] + hash = "0xd220bbdf24df6d1611f4ece1d08c64feae914ce6299ab2806c864e30a5289201" + number = 6278018 + [superchains.chains.genesis.l2] + hash = "0xf1deb67ee953f94d8545d2647918687fa8ba1f30fa6103771f11b7c483984070" + number = 0 + [superchains.chains.genesis.system_config] + batcherAddress = "0x0f3ff4731D7a10B89ED79AD1Fd97844d7F66B96d" + overhead = "0x00000000000000000000000000000000000000000000000000000000000000bc" + scalar = "0x00000000000000000000000000000000000000000000000000000000000a6fe0" + gasLimit = 100000000 + [superchains.chains.addresses] + SystemConfigOwner = "0xe78a0A96C5D6aE6C606418ED4A9Ced378cb030A0" + ProxyAdminOwner = "0x945185C01fb641bA3E63a9bdF66575e35a407837" + Guardian = "0xe78a0A96C5D6aE6C606418ED4A9Ced378cb030A0" + Challenger = "0xe78a0A96C5D6aE6C606418ED4A9Ced378cb030A0" + Proposer = "0x77a95104e4025fC8B88A6a0F5FB7Fae20851E414" + UnsafeBlockSigner = "0x3241A7D28eA74E807A5087BA637fB58D8dDcd078" + BatchSubmitter = "0x0f3ff4731D7a10B89ED79AD1Fd97844d7F66B96d" + AddressManager = "0xc50Ba0767A1c0Ef69Cf1D9cd44De52b08589F691" + L1CrossDomainMessengerProxy = "0x7768c821200554d8F359A8902905Ba9eDe5659a9" + L1ERC721BridgeProxy = "0x3580505c56f8560E3777E92Fb27f70fD20c5B493" + L1StandardBridgeProxy = "0xd7DF54b3989855eb66497301a4aAEc33Dbb3F8DE" + L2OutputOracleProxy = "0xc8886f8BAb6Eaeb215aDB5f1c686BF699248300e" + OptimismMintableERC20FactoryProxy = "0x2D272eF54Ee8EF5c2Ff3523559186580b158cd57" + OptimismPortalProxy = "0xFf6EBa109271fe6d4237EeeD4bAb1dD9A77dD1A4" + SystemConfigProxy = "0x166F9406e79A656f12F05247fb8F5DfA6155bCBF" + ProxyAdmin = "0x3a987FE1cb587B0A1808cf9bB7Cbe0E341838319" + SuperchainConfig = "0x4642C5eD3B1568e0F05d73B10d02e6Fb2595aF9a" + AnchorStateRegistryProxy = "0x1517FDD5A31B35f790eA8a3c6cC2F595B1BD4742" + DelayedWETHProxy = "0x4F4B8Adf1af4b61bb62F68b7aF1c37f8A6311663" + DisputeGameFactoryProxy = "0x8cF97Ee616C986a070F5020d973b456D0120C253" + FaultDisputeGame = "0x0000000000000000000000000000000000000000" + MIPS = "0xCEd5c6ca2f32dE7bf43DB981E1cac398D7A978F2" + PermissionedDisputeGame = "0x0000000000000000000000000000000000000000" + PreimageOracle = "0x954C0Fb8083047f37c8Fe954c114f8138614131C" + DAChallengeAddress = "0x0000000000000000000000000000000000000000" + [[superchains.chains]] name = "RACE Testnet" chain_id = 6806 diff --git a/chainList.json b/chainList.json index 3bd9eff8d..4aa921bb5 100644 --- a/chainList.json +++ b/chainList.json @@ -136,6 +136,23 @@ }, "gasPayingToken": "0x04E9D7e336f79Cdab911b06133D3Ca2Cd0721ce3" }, + { + "name": "World Chain", + "identifier": "mainnet/wc", + "chainId": 480, + "rpc": [ + "https://worldchain-mainnet-sequencer.g.alchemy.com" + ], + "explorers": [ + "https://worldchain-mainnet-explorer.alchemy.com/" + ], + "superchainLevel": 0, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + } + }, { "name": "Zora", "identifier": "mainnet/zora", @@ -238,6 +255,23 @@ "chain": "sepolia" } }, + { + "name": "World Chain Sepolia Testnet", + "identifier": "sepolia/wc", + "chainId": 4801, + "rpc": [ + "" + ], + "explorers": [ + "https://worldchain-sepolia-explorer.alchemy.com/" + ], + "superchainLevel": 0, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + } + }, { "name": "Zora Sepolia Testnet", "identifier": "sepolia/zora", diff --git a/chainList.toml b/chainList.toml index b347e0b11..3b1c0bc92 100644 --- a/chainList.toml +++ b/chainList.toml @@ -95,6 +95,18 @@ type = "L2" chain = "mainnet" +[[chains]] + name = "World Chain" + identifier = "mainnet/wc" + chain_id = 480 + rpc = ["https://worldchain-mainnet-sequencer.g.alchemy.com"] + explorers = ["https://worldchain-mainnet-explorer.alchemy.com/"] + superchain_level = 0 + data_availability_type = "eth-da" + [chains.parent] + type = "L2" + chain = "mainnet" + [[chains]] name = "Zora" identifier = "mainnet/zora" @@ -167,6 +179,18 @@ type = "L2" chain = "sepolia" +[[chains]] + name = "World Chain Sepolia Testnet" + identifier = "sepolia/wc" + chain_id = 4801 + rpc = [""] + explorers = ["https://worldchain-sepolia-explorer.alchemy.com/"] + superchain_level = 0 + data_availability_type = "eth-da" + [chains.parent] + type = "L2" + chain = "sepolia" + [[chains]] name = "Zora Sepolia Testnet" identifier = "sepolia/zora" diff --git a/superchain/extra/addresses/addresses.json b/superchain/extra/addresses/addresses.json index 6904bc5d6..b3fe216b3 100644 --- a/superchain/extra/addresses/addresses.json +++ b/superchain/extra/addresses/addresses.json @@ -159,6 +159,54 @@ "SystemConfigProxy": "0x5e6432F18Bc5d497B1Ab2288a025Fbf9D69E2221", "UnsafeBlockSigner": "0xa7fA9CA4ac88686A542C0f830d7378eAB4A0278F" }, + "480": { + "AddressManager": "0x5891090d5085679714cb0e62f74950a3c19146a8", + "AnchorStateRegistryProxy": "0x1325C4966d17038C5592fb38416AeE85EE73c0cb", + "BatchSubmitter": "0xdBBE3D8c2d2b22A2611c5A94A9a12C2fCD49Eb29", + "Challenger": "0xB2aa0C2C4fD6BFCBF699d4c787CD6Cc0dC461a9d", + "DelayedWETHProxy": "0xF9adF7c9502C5C60352C20a4d22683422DbD061F", + "DisputeGameFactoryProxy": "0x0E90dCAFBC242D2C861A20Bb20EC8E7182965a52", + "Guardian": "0xB2aa0C2C4fD6BFCBF699d4c787CD6Cc0dC461a9d", + "L1CrossDomainMessengerProxy": "0xf931a81D18B1766d15695ffc7c1920a62b7e710a", + "L1ERC721BridgeProxy": "0x1Df436AfDb2fBB40F1fE8bEd4Fc89A0D0990a8E9", + "L1StandardBridgeProxy": "0x470458C91978D2d929704489Ad730DC3E3001113", + "L2OutputOracleProxy": "0x19A6d1E9034596196295CF148509796978343c5D", + "MIPS": "0x267b2FFfA613c246Ef995390Ea0a2BaAA16a80Ba", + "OptimismMintableERC20FactoryProxy": "0x82Cb528466cF22412d89bdBE9bCF04856790dD0e", + "OptimismPortalProxy": "0xd5ec14a83B7d95BE1E2Ac12523e2dEE12Cbeea6C", + "PreimageOracle": "0x3941778243E3E80a6a46D149F083825dEdc534BB", + "Proposer": "0x2307278fC8aB0005974A6DeD2FA6d1187333a223", + "ProxyAdmin": "0xd7405BE7f3e63b094Af6C7C23D5eE33Fd82F872D", + "ProxyAdminOwner": "0xA4fB12D15Eb85dc9284a7df0AdBC8B696EdbbF1d", + "SuperchainConfig": "0xa231f8be37e583f276f93dF516D88a043bfe47E3", + "SystemConfigOwner": "0xB2aa0C2C4fD6BFCBF699d4c787CD6Cc0dC461a9d", + "SystemConfigProxy": "0x6ab0777fD0e609CE58F939a7F70Fe41F5Aa6300A", + "UnsafeBlockSigner": "0x2270d6eC8E760daA317DD978cFB98C8f144B1f3A" + }, + "4801": { + "AddressManager": "0xc50Ba0767A1c0Ef69Cf1D9cd44De52b08589F691", + "AnchorStateRegistryProxy": "0x1517FDD5A31B35f790eA8a3c6cC2F595B1BD4742", + "BatchSubmitter": "0x0f3ff4731D7a10B89ED79AD1Fd97844d7F66B96d", + "Challenger": "0xe78a0A96C5D6aE6C606418ED4A9Ced378cb030A0", + "DelayedWETHProxy": "0x4F4B8Adf1af4b61bb62F68b7aF1c37f8A6311663", + "DisputeGameFactoryProxy": "0x8cF97Ee616C986a070F5020d973b456D0120C253", + "Guardian": "0xe78a0A96C5D6aE6C606418ED4A9Ced378cb030A0", + "L1CrossDomainMessengerProxy": "0x7768c821200554d8F359A8902905Ba9eDe5659a9", + "L1ERC721BridgeProxy": "0x3580505c56f8560E3777E92Fb27f70fD20c5B493", + "L1StandardBridgeProxy": "0xd7DF54b3989855eb66497301a4aAEc33Dbb3F8DE", + "L2OutputOracleProxy": "0xc8886f8BAb6Eaeb215aDB5f1c686BF699248300e", + "MIPS": "0xCEd5c6ca2f32dE7bf43DB981E1cac398D7A978F2", + "OptimismMintableERC20FactoryProxy": "0x2D272eF54Ee8EF5c2Ff3523559186580b158cd57", + "OptimismPortalProxy": "0xFf6EBa109271fe6d4237EeeD4bAb1dD9A77dD1A4", + "PreimageOracle": "0x954C0Fb8083047f37c8Fe954c114f8138614131C", + "Proposer": "0x77a95104e4025fC8B88A6a0F5FB7Fae20851E414", + "ProxyAdmin": "0x3a987FE1cb587B0A1808cf9bB7Cbe0E341838319", + "ProxyAdminOwner": "0x945185C01fb641bA3E63a9bdF66575e35a407837", + "SuperchainConfig": "0x4642C5eD3B1568e0F05d73B10d02e6Fb2595aF9a", + "SystemConfigOwner": "0xe78a0A96C5D6aE6C606418ED4A9Ced378cb030A0", + "SystemConfigProxy": "0x166F9406e79A656f12F05247fb8F5DfA6155bCBF", + "UnsafeBlockSigner": "0x3241A7D28eA74E807A5087BA637fB58D8dDcd078" + }, "624": { "AddressManager": "0x8173904703995c6BbA59a42B8bBf8405F978758a", "AnchorStateRegistryProxy": "0x275Abd1eB1FBaAB40Dcef5f3A588e2dF65801edc", diff --git a/validation/genesis/commands.go b/validation/genesis/commands.go new file mode 100644 index 000000000..09d981316 --- /dev/null +++ b/validation/genesis/commands.go @@ -0,0 +1,42 @@ +package genesis + +import ( + "fmt" + "strings" +) + +type GeneratorFn func(uint64, string) string + +var GenesisCreationCommand = map[string]GeneratorFn{ + "opnode1": opnode1, + "opnode2": opnode2, +} + +func opnode1(chainId uint64, l1rpcURL string) string { + return strings.Join([]string{ + "go run op-node/cmd/main.go genesis l2", + fmt.Sprintf(" --deploy-config=./packages/contracts-bedrock/deploy-config/%d.json", chainId), + " --outfile.l2=expected-genesis.json", + " --outfile.rollup=rollup.json", + fmt.Sprintf("--l1-deployments=./packages/contracts-bedrock/deployments/%d/.deploy", chainId), + fmt.Sprintf("--l1-rpc=%s", l1rpcURL), + }, + " ") +} + +func opnode2(chainId uint64, l1rpcURL string) string { + return strings.Join([]string{ + "go run op-node/cmd/main.go genesis l2", + fmt.Sprintf("--deploy-config=./packages/contracts-bedrock/deploy-config/%d.json", chainId), + "--outfile.l2=expected-genesis.json", + "--outfile.rollup=rollup.json", + fmt.Sprintf("--deployment-dir=./packages/contracts-bedrock/deployments/%d", chainId), + fmt.Sprintf("--l1-rpc=%s", l1rpcURL), + }, + " ") +} + +var BuildCommand = map[string]string{ + "pnpm": "pnpm install --no-frozen-lockfile", + "yarn": "yarn install --no-frozen-lockfile", +} diff --git a/validation/genesis/config.patch b/validation/genesis/config.patch new file mode 100644 index 000000000..18c6f3eae --- /dev/null +++ b/validation/genesis/config.patch @@ -0,0 +1,13 @@ +diff --git a/op-chain-ops/genesis/config.go b/op-chain-ops/genesis/config.go +index 4c813acd4..42aa795ed 100644 +--- a/op-chain-ops/genesis/config.go ++++ b/op-chain-ops/genesis/config.go +@@ -588,7 +588,7 @@ func NewDeployConfig(path string) (*DeployConfig, error) { + } + + dec := json.NewDecoder(bytes.NewReader(file)) +- dec.DisallowUnknownFields() ++ // dec.DisallowUnknownFields() + + var config DeployConfig + if err := dec.Decode(&config); err != nil { diff --git a/validation/genesis/genesis-predeploy_test.go b/validation/genesis/genesis-predeploy_test.go index 87153e07b..9eab1223d 100644 --- a/validation/genesis/genesis-predeploy_test.go +++ b/validation/genesis/genesis-predeploy_test.go @@ -8,13 +8,14 @@ import ( "os/exec" "path" "path/filepath" - "reflect" "runtime" "strconv" + "strings" "testing" "github.com/ethereum-optimism/superchain-registry/superchain" . "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/stretchr/testify/require" ) @@ -59,30 +60,23 @@ func testGenesisPredeploys(t *testing.T, chain *ChainConfig) { // reset to appropriate commit, this is preferred to git checkout because it will // blow away any leftover files from the previous run - executeCommandInDir(t, monorepoDir, exec.Command("git", "reset", "--hard", monorepoCommit)) + mustExecuteCommandInDir(t, monorepoDir, exec.Command("git", "reset", "--hard", monorepoCommit)) + mustExecuteCommandInDir(t, monorepoDir, exec.Command("rm", "-rf", "node_modules")) + mustExecuteCommandInDir(t, contractsDir, exec.Command("rm", "-rf", "node_modules")) - executeCommandInDir(t, monorepoDir, exec.Command("rm", "-rf", "node_modules")) - executeCommandInDir(t, contractsDir, exec.Command("rm", "-rf", "node_modules")) - if monorepoCommit == "d80c145e0acf23a49c6a6588524f57e32e33b91" { - // apply a patch to get things working - // then compile the contracts - // TODO not sure why this is needed, it is likely coupled to the specific commit we are looking at - executeCommandInDir(t, thisDir, exec.Command("cp", "foundry-config.patch", contractsDir)) - executeCommandInDir(t, contractsDir, exec.Command("git", "apply", "foundry-config.patch")) - executeCommandInDir(t, contractsDir, exec.Command("forge", "build")) - // revert patch, makes rerunning script locally easier - executeCommandInDir(t, contractsDir, exec.Command("git", "apply", "-R", "foundry-config.patch")) - } + // attempt to apply config.patch + mustExecuteCommandInDir(t, thisDir, exec.Command("cp", "config.patch", monorepoDir)) + _ = executeCommandInDir(t, monorepoDir, exec.Command("git", "apply", "config.patch")) // continue on error // copy genesis input files to monorepo - executeCommandInDir(t, validationInputsDir, + mustExecuteCommandInDir(t, validationInputsDir, exec.Command("cp", "deploy-config.json", path.Join(contractsDir, "deploy-config", chainIdString+".json"))) err := os.MkdirAll(path.Join(contractsDir, "deployments", chainIdString), os.ModePerm) if err != nil { log.Fatalf("Failed to create directory: %v", err) } - if vis.UseLegacyDeploymentsFormat { + if vis.GenesisCreationCommand == "opnode2" { err = writeDeploymentsLegacy(chainId, path.Join(contractsDir, "deployments", chainIdString)) } else { err = writeDeployments(chainId, path.Join(contractsDir, "deployments", chainIdString)) @@ -92,8 +86,13 @@ func testGenesisPredeploys(t *testing.T, chain *ChainConfig) { } // regenerate genesis.json at this monorepo commit. - executeCommandInDir(t, thisDir, exec.Command("cp", "./monorepo-outputs.sh", monorepoDir)) - executeCommandInDir(t, monorepoDir, exec.Command("sh", "./monorepo-outputs.sh", vis.MonorepoBuildCommand, vis.GenesisCreationCommand)) + mustExecuteCommandInDir(t, thisDir, exec.Command("cp", "./monorepo-outputs.sh", monorepoDir)) + buildCommand := BuildCommand[vis.MonorepoBuildCommand] + if vis.NodeVersion == "" { + panic("must set node_version in meta.toml") + } + creationCommand := GenesisCreationCommand[vis.GenesisCreationCommand](chainId, Superchains[chain.Superchain].Config.L1.PublicRPC) + mustExecuteCommandInDir(t, monorepoDir, exec.Command("sh", "./monorepo-outputs.sh", vis.NodeVersion, buildCommand, creationCommand)) expectedData, err := os.ReadFile(path.Join(monorepoDir, "expected-genesis.json")) require.NoError(t, err) @@ -103,13 +102,13 @@ func testGenesisPredeploys(t *testing.T, chain *ChainConfig) { err = json.Unmarshal(expectedData, &gen) require.NoError(t, err) - expectedData, err = json.Marshal(gen.Alloc) + expectedData, err = json.MarshalIndent(gen.Alloc, "", " ") require.NoError(t, err) g, err := core.LoadOPStackGenesis(chainId) require.NoError(t, err) - gotData, err := json.Marshal(g.Alloc) + gotData, err := json.MarshalIndent(g.Alloc, "", " ") require.NoError(t, err) err = os.WriteFile(path.Join(monorepoDir, "want-alloc.json"), expectedData, 0o777) @@ -144,41 +143,85 @@ func writeDeployments(chainId uint64, directory string) error { } func writeDeploymentsLegacy(chainId uint64, directory string) error { + // Prepare a HardHat Deployment type, we need this whole structure to make things + // work, although it is only the Address field which ends up getting used. + type StorageLayoutEntry struct { + AstId uint `json:"astId"` + Contract string `json:"contract"` + Label string `json:"label"` + Offset uint `json:"offset"` + Slot uint `json:"slot,string"` + Type string `json:"type"` + } + type StorageLayoutType struct { + Encoding string `json:"encoding"` + Label string `json:"label"` + NumberOfBytes uint `json:"numberOfBytes,string"` + Key string `json:"key,omitempty"` + Value string `json:"value,omitempty"` + Base string `json:"base,omitempty"` + } + type StorageLayout struct { + Storage []StorageLayoutEntry `json:"storage"` + Types map[string]StorageLayoutType `json:"types"` + } + type Deployment struct { + Name string + Abi []string `json:"abi"` + Address string `json:"address"` + Args []any `json:"args"` + Bytecode string `json:"bytecode"` + DeployedBytecode string `json:"deployedBytecode"` + Devdoc json.RawMessage `json:"devdoc"` + Metadata string `json:"metadata"` + Receipt json.RawMessage `json:"receipt"` + SolcInputHash string `json:"solcInputHash"` + StorageLayout StorageLayout `json:"storageLayout"` + TransactionHash common.Hash `json:"transactionHash"` + Userdoc json.RawMessage `json:"userdoc"` + } + // Initialize your struct with some data data := Addresses[chainId] - // Get the reflection value object - val := reflect.ValueOf(*data) - typ := reflect.TypeOf(*data) + type AddressList2 AddressList // use another type to prevent infinite recursion later on + b := AddressList2(*data) - // Iterate over the struct fields - for i := 0; i < val.NumField(); i++ { - fieldName := typ.Field(i).Name // Get the field name - fieldValue := val.Field(i).String() // Get the field value (assuming it's a string) + o, err := json.Marshal(b) + if err != nil { + return err + } + + out := make(map[string]Address) + err = json.Unmarshal(o, &out) + if err != nil { + return err + } - // Define the JSON object - jsonData := map[string]string{ - "address": fieldValue, + for k, v := range out { + text, err := v.MarshalText() + if err != nil || !strings.HasPrefix(string(text), "0x") { + continue } + // Define the Deployment object, filling in only what we need + jsonData := Deployment{Address: v.String(), Name: k} - // Convert the map to JSON - fileContent, err := json.MarshalIndent(jsonData, "", " ") + raw, err := json.MarshalIndent(jsonData, "", " ") if err != nil { - return fmt.Errorf("Failed to marshal JSON for field %s: %w", fieldName, err) + return err } - // Create a file named after the field name - fileName := fmt.Sprintf("%s.json", fieldName) + fileName := fmt.Sprintf("%s.json", k) file, err := os.Create(path.Join(directory, fileName)) if err != nil { - return fmt.Errorf("Failed to create file for field %s: %w", fieldName, err) + return fmt.Errorf("Failed to create file for field %s: %w", k, err) } defer file.Close() // Write the JSON content to the file - _, err = file.Write(fileContent) + _, err = file.Write(raw) if err != nil { - return fmt.Errorf("Failed to write JSON to file for field %s: %w", fieldName, err) + return fmt.Errorf("Failed to write JSON to file for field %s: %w", k, err) } fmt.Printf("Created file: %s\n", fileName) diff --git a/validation/genesis/genesis.go b/validation/genesis/genesis.go index 611f9b2d6..6e70f7327 100644 --- a/validation/genesis/genesis.go +++ b/validation/genesis/genesis.go @@ -51,8 +51,8 @@ func init() { } type ValidationMetadata struct { - GenesisCreationCommit string `toml:"genesis_creation_commit"` // in https://github.com/ethereum-optimism/optimism/ - UseLegacyDeploymentsFormat bool `toml:"use_legacy_deployments_format"` - MonorepoBuildCommand string `toml:"monorepo_build_command"` - GenesisCreationCommand string `toml:"genesis_creation_command"` + GenesisCreationCommit string `toml:"genesis_creation_commit"` // in https://github.com/ethereum-optimism/optimism/ + NodeVersion string `toml:"node_version"` + MonorepoBuildCommand string `toml:"monorepo_build_command"` + GenesisCreationCommand string `toml:"genesis_creation_command"` } diff --git a/validation/genesis/monorepo-outputs.sh b/validation/genesis/monorepo-outputs.sh index f745a15d8..7cfb66db1 100755 --- a/validation/genesis/monorepo-outputs.sh +++ b/validation/genesis/monorepo-outputs.sh @@ -3,10 +3,10 @@ set -e echo "Inferring and selecting correct Node version" export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm -nvm use +nvm use $1 echo "Running install command" -eval $1 +eval $2 echo "Inferring and selecting correct go version" @@ -22,4 +22,4 @@ set -e echo "Running op-node genesis l2 command" -eval "$2" +eval "$3" diff --git a/validation/genesis/utils.go b/validation/genesis/utils.go index add0de08a..ebdce95a2 100644 --- a/validation/genesis/utils.go +++ b/validation/genesis/utils.go @@ -8,7 +8,7 @@ import ( "testing" ) -func executeCommandInDir(t *testing.T, dir string, cmd *exec.Cmd) { +func executeCommandInDir(t *testing.T, dir string, cmd *exec.Cmd) error { t.Logf("executing %s", cmd.String()) cmd.Dir = dir var outErr bytes.Buffer @@ -18,6 +18,13 @@ func executeCommandInDir(t *testing.T, dir string, cmd *exec.Cmd) { if err != nil { // error case : status code of command is different from 0 fmt.Println(outErr.String()) + } + return err +} + +func mustExecuteCommandInDir(t *testing.T, dir string, cmd *exec.Cmd) { + err := executeCommandInDir(t, dir, cmd) + if err != nil { t.Fatal(err) } } diff --git a/validation/genesis/validation-inputs/10/meta.toml b/validation/genesis/validation-inputs/10/meta.toml deleted file mode 100644 index 7f871dd7a..000000000 --- a/validation/genesis/validation-inputs/10/meta.toml +++ /dev/null @@ -1,13 +0,0 @@ -genesis_creation_commit = "b29868e89246274afa17062f9d91df19a3b7ef24" -genesis_creation_command = """ - go - run - op-node/cmd/main.go - genesis - l2 - --deploy-config=./packages/contracts-bedrock/deploy-config/mainnet.json - --outfile.l2=expected-genesis.json - --outfile.rollup=rollup.json - --l1-deployments=./packages/contracts-bedrock/deployments/mainnet - --l1-rpc=https://ethereum.publicnode.com/ -""" diff --git a/validation/genesis/validation-inputs/1750/deploy-config.json b/validation/genesis/validation-inputs/1750/deploy-config.json new file mode 100644 index 000000000..2b8347e78 --- /dev/null +++ b/validation/genesis/validation-inputs/1750/deploy-config.json @@ -0,0 +1,56 @@ +{ + "l1StartingBlockTag": "0x2493565ce8472656b7c22377c8d4d8ef5d17f78392c799ca5f2429b01e2c159c", + "l1ChainID": 1, + "l2ChainID": 1750, + "l2BlockTime": 2, + "l1BlockTime": 12, + "finalizationPeriodSeconds": 604800, + "systemConfigOwner": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "finalSystemOwner": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "controller": "0x87A1157dFCc065684DDE31fE202E50238A17Fc44", + "baseFeeVaultRecipient": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "l1FeeVaultRecipient": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "sequencerFeeVaultRecipient": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "governanceTokenOwner": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0x4a65F5da5e80DEFfEA844eAa15CE130e80605dc5", + "optimismL2FeeRecipient": "0x3A2F5F909d7D3fb62E7Db3193df26078ec563795", + "batchInboxAddress": "0xc83f7D9F2D4A76E81145849381ABA02602373723", + "batchSenderAddress": "0xC94C243f8fb37223F3EB2f7961F7072602A51B8B", + "l2GenesisRegolithTimeOffset": "0x0", + "portalGuardian": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "l2OutputOracleSubmissionInterval": 21600, + "l2OutputOracleStartingTimestamp": -1, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleProposer": "0xC8187d40AD440328104A52BBed2D8Efc5ab1F1F6", + "l2OutputOracleOwner": "0x8768b38625c73FefC6036b4aAEA84483a23abE5D", + "sequencerFeeVaultWithdrawalNetwork": 0, + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l2GenesisBlockGasLimit": "0x1c9c380", + "fundDevAccounts": false, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "eip1559Denominator": 50, + "eip1559Elasticity": 6, + "superchainConfigGuardian": "0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A", + "l2GenesisCanyonTimeOffset": "0x0", + "l2GenesisDeltaTimeOffset": "0x0", + "l2GenesisEcotoneTimeOffset": "0x0", + "eip1559DenominatorCanyon": 250, + "proxyAdmin": "0x72d29FD7601083E95e501Cc0DA7c9A9E073600a4", + "proxyAdminOwner": "0xefCf0c8faFB425997870f845e26fC6cA6EE6dD5C", + "optimismBaseFeeRecipient": "0x26F00eac2a7B0DE5D07109A10a284126F4667735", + "optimismL1FeeRecipient": "0x9c8c9743fD2632E0c22E309375D9c8e8A6d38c55", + "l2CrossDomainMessengerOwner": "0xcCf7200E0D99718C8efB9cD5fd4f95F67cf5E854", + "gasPriceOracleOwner": "0x155e6fb8e0f590a15F31a622D85a4cB42b9aB46E", + "l2OutputOracleChallenger": "0x4a4962275df8c60a80d3a25faec5aa7de116a746" +} diff --git a/validation/genesis/validation-inputs/1750/meta.toml b/validation/genesis/validation-inputs/1750/meta.toml new file mode 100644 index 000000000..b642a13b0 --- /dev/null +++ b/validation/genesis/validation-inputs/1750/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "416cdccd2a93f83fe713dea3b0d86889c430dce3" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode1" diff --git a/validation/genesis/validation-inputs/34443/meta.toml b/validation/genesis/validation-inputs/34443/meta.toml index 07ce9fbe6..1e666dad5 100644 --- a/validation/genesis/validation-inputs/34443/meta.toml +++ b/validation/genesis/validation-inputs/34443/meta.toml @@ -1,14 +1,4 @@ -genesis_creation_commit = "3eda4cd594ba6409584eb6ef95c341d98419e392" -monorepo_build_command = "yarn install --no-frozen-lockfile" -genesis_creation_command = """\ - go \ - run \ - op-node/cmd/main.go \ - genesis \ - l2 \ - --deploy-config=./packages/contracts-bedrock/deploy-config/34443.json \ - --outfile.l2=expected-genesis.json \ - --outfile.rollup=rollup.json \ - --deployment-dir=./packages/contracts-bedrock/deployments/34443 \ - --l1-rpc=https://ethereum.publicnode.com/ \ -""" +genesis_creation_commit = "d80c145e0acf23a49c6a6588524f57e32e33b91" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode2" diff --git a/validation/genesis/validation-inputs/480/meta.toml b/validation/genesis/validation-inputs/480/meta.toml index 3c0918d9c..aabfd29bf 100644 --- a/validation/genesis/validation-inputs/480/meta.toml +++ b/validation/genesis/validation-inputs/480/meta.toml @@ -1,14 +1,4 @@ genesis_creation_commit = "4a3d3fb444f50bed6a6991785ea5634e0efa07a4" -monorepo_build_command = "pnpm install --no-frozen-lockfile" -genesis_creation_command = """\ - go \ - run \ - op-node/cmd/main.go \ - genesis \ - l2 \ - --deploy-config=./packages/contracts-bedrock/deploy-config/480.json \ - --outfile.l2=expected-genesis.json \ - --outfile.rollup=rollup.json \ - --l1-deployments=./packages/contracts-bedrock/deployments/480/.deploy \ - --l1-rpc=https://ethereum.publicnode.com/ \ -""" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode1" diff --git a/validation/genesis/validation-inputs/4801/meta.toml b/validation/genesis/validation-inputs/4801/meta.toml index dabea6b6e..aabfd29bf 100644 --- a/validation/genesis/validation-inputs/4801/meta.toml +++ b/validation/genesis/validation-inputs/4801/meta.toml @@ -1,14 +1,4 @@ genesis_creation_commit = "4a3d3fb444f50bed6a6991785ea5634e0efa07a4" -monorepo_build_command = "pnpm install --no-frozen-lockfile" -genesis_creation_command = """\ - go \ - run \ - op-node/cmd/main.go \ - genesis \ - l2 \ - --deploy-config=./packages/contracts-bedrock/deploy-config/4801.json \ - --outfile.l2=expected-genesis.json \ - --outfile.rollup=rollup.json \ - --l1-deployments=./packages/contracts-bedrock/deployments/4801/.deploy \ - --l1-rpc=https://ethereum-sepolia.publicnode.com/ \ -""" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode1" diff --git a/validation/genesis/validation-inputs/7777777/deploy-config.json b/validation/genesis/validation-inputs/7777777/deploy-config.json new file mode 100644 index 000000000..7b670c6a8 --- /dev/null +++ b/validation/genesis/validation-inputs/7777777/deploy-config.json @@ -0,0 +1,43 @@ +{ + "l1StartingBlockTag": "0x10aa183", + "l1ChainID": 1, + "l2ChainID": 7777777, + "l2BlockTime": 2, + "finalizationPeriodSeconds": 604800, + "systemConfigOwner": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", + "finalSystemOwner": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", + "controller": "0xEe729F57F0111FD0F660867d0F522f983202a5aF", + "baseFeeVaultRecipient": "0xe900b3Edc1BA0430CFa9a204A1027B90825ac951", + "l1FeeVaultRecipient": "0xe900b3Edc1BA0430CFa9a204A1027B90825ac951", + "sequencerFeeVaultRecipient": "0xe900b3Edc1BA0430CFa9a204A1027B90825ac951", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "governanceTokenOwner": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0x3Dc8Dfd0709C835cAd15a6A27e089FF4cF4C9228", + "optimismL2FeeRecipient": "0x63AA492609175d1824dD668BDadF0042E74b0fC8", + "batchInboxAddress": "0x6F54Ca6F6EdE96662024Ffd61BFd18f3f4e34DFf", + "batchSenderAddress": "0x625726c858dBF78c0125436C943Bf4b4bE9d9033", + "l2GenesisRegolithTimeOffset": "0x0", + "portalGuardian": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", + "l2OutputOracleSubmissionInterval": 180, + "l2OutputOracleStartingTimestamp": -1, + "l2OutputOracleProposer": "0x48247032092e7b0ecf5dEF611ad89eaf3fC888Dd", + "l2OutputOracleOwner": "0xDA1F62857EA7f10444725c6c435235243D623540", + "l2GenesisBlockGasLimit": "0x1c9c380", + "fundDevAccounts": false, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "eip1559Denominator": 50, + "eip1559Elasticity": 6, + "proxyAdmin": "0x027860cA56cF779371461C14c3a483c94e1aA8a0", + "proxyAdminOwner": "0xb0cCdbD6fe09D2199171BE19450aF249250518A0", + "optimismBaseFeeRecipient": "0xea4591A6e5a31CF0b822A4f563163CeeBeEe4eb1", + "optimismL1FeeRecipient": "0xdD7aCF916c3E3Fb959CA3bB29beFffcAD2e90be6", + "l2CrossDomainMessengerOwner": "0xA53EF9bBec25fdA4b6Da7EF5617565794369A2A5", + "gasPriceOracleOwner": "0x9c3651E0B3CE47A0b17d775077E3d9B712582be0", + "l2OutputOracleChallenger": "0xcA4571b1ecBeC86Ea2E660d242c1c29FcB55Dc72" +} diff --git a/validation/genesis/validation-inputs/7777777/meta.toml b/validation/genesis/validation-inputs/7777777/meta.toml new file mode 100644 index 000000000..6f094fdd5 --- /dev/null +++ b/validation/genesis/validation-inputs/7777777/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "65ec61dde94ffa93342728d324fecf474d228e1f" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode2"