|
| 1 | +// SPDX-License-Identifier: UNLICENSED |
| 2 | +pragma solidity =0.8.24; |
| 3 | + |
| 4 | +import {Script} from "forge-std/Script.sol"; |
| 5 | +import {VmSafe} from "forge-std/Vm.sol"; |
| 6 | +import {stdToml} from "forge-std/StdToml.sol"; |
| 7 | + |
| 8 | +import {CONFIG_PATH, CONFIG_CONTRACTS_PATH, CONFIG_CONTRACTS_TEMPLATE_PATH} from "./Constants.sol"; |
| 9 | + |
| 10 | +/// @notice Configuration allows inheriting contracts to read the TOML configuration file. |
| 11 | +abstract contract Configuration is Script { |
| 12 | + using stdToml for string; |
| 13 | + |
| 14 | + /******************* |
| 15 | + * State variables * |
| 16 | + *******************/ |
| 17 | + |
| 18 | + string internal cfg; |
| 19 | + string internal contractsCfg; |
| 20 | + |
| 21 | + /**************************** |
| 22 | + * Configuration parameters * |
| 23 | + ****************************/ |
| 24 | + |
| 25 | + // general |
| 26 | + string internal L1_RPC_ENDPOINT; |
| 27 | + string internal L2_RPC_ENDPOINT; |
| 28 | + |
| 29 | + string internal CHAIN_NAME_L1; |
| 30 | + string internal CHAIN_NAME_L2; |
| 31 | + uint64 internal CHAIN_ID_L1; |
| 32 | + uint64 internal CHAIN_ID_L2; |
| 33 | + |
| 34 | + uint256 internal MAX_TX_IN_CHUNK; |
| 35 | + uint256 internal MAX_BLOCK_IN_CHUNK; |
| 36 | + uint256 internal MAX_BATCH_IN_BUNDLE; |
| 37 | + uint256 internal MAX_L1_MESSAGE_GAS_LIMIT; |
| 38 | + uint256 internal FINALIZE_BATCH_DEADLINE_SEC; |
| 39 | + uint256 internal RELAY_MESSAGE_DEADLINE_SEC; |
| 40 | + |
| 41 | + uint256 internal L1_CONTRACT_DEPLOYMENT_BLOCK; |
| 42 | + |
| 43 | + bool internal TEST_ENV_MOCK_FINALIZE_ENABLED; |
| 44 | + uint256 internal TEST_ENV_MOCK_FINALIZE_TIMEOUT_SEC; |
| 45 | + |
| 46 | + // accounts |
| 47 | + uint256 internal DEPLOYER_PRIVATE_KEY; |
| 48 | + uint256 internal L1_COMMIT_SENDER_PRIVATE_KEY; |
| 49 | + uint256 internal L1_FINALIZE_SENDER_PRIVATE_KEY; |
| 50 | + uint256 internal L1_GAS_ORACLE_SENDER_PRIVATE_KEY; |
| 51 | + uint256 internal L2_GAS_ORACLE_SENDER_PRIVATE_KEY; |
| 52 | + |
| 53 | + address internal DEPLOYER_ADDR; |
| 54 | + address internal L1_COMMIT_SENDER_ADDR; |
| 55 | + address internal L1_FINALIZE_SENDER_ADDR; |
| 56 | + address internal L1_GAS_ORACLE_SENDER_ADDR; |
| 57 | + address internal L2_GAS_ORACLE_SENDER_ADDR; |
| 58 | + |
| 59 | + address internal OWNER_ADDR; |
| 60 | + |
| 61 | + address internal L2GETH_SIGNER_ADDRESS; |
| 62 | + |
| 63 | + // db |
| 64 | + string internal ROLLUP_EXPLORER_BACKEND_DB_CONNECTION_STRING; |
| 65 | + |
| 66 | + // genesis |
| 67 | + uint256 internal L2_MAX_ETH_SUPPLY; |
| 68 | + uint256 internal L2_DEPLOYER_INITIAL_BALANCE; |
| 69 | + uint256 internal L2_SCROLL_MESSENGER_INITIAL_BALANCE; |
| 70 | + |
| 71 | + // contracts |
| 72 | + string internal DEPLOYMENT_SALT; |
| 73 | + |
| 74 | + address internal L1_FEE_VAULT_ADDR; |
| 75 | + |
| 76 | + // coordinator |
| 77 | + string internal CHUNK_COLLECTION_TIME_SEC; |
| 78 | + string internal BATCH_COLLECTION_TIME_SEC; |
| 79 | + string internal BUNDLE_COLLECTION_TIME_SEC; |
| 80 | + string internal COORDINATOR_JWT_SECRET_KEY; |
| 81 | + |
| 82 | + // frontend |
| 83 | + string internal EXTERNAL_RPC_URI_L1; |
| 84 | + string internal EXTERNAL_RPC_URI_L2; |
| 85 | + string internal BRIDGE_API_URI; |
| 86 | + string internal ROLLUPSCAN_API_URI; |
| 87 | + string internal EXTERNAL_EXPLORER_URI_L1; |
| 88 | + string internal EXTERNAL_EXPLORER_URI_L2; |
| 89 | + string internal ADMIN_SYSTEM_DASHBOARD_URI; |
| 90 | + string internal GRAFANA_URI; |
| 91 | + |
| 92 | + /********************** |
| 93 | + * Internal interface * |
| 94 | + **********************/ |
| 95 | + |
| 96 | + function readConfig() internal { |
| 97 | + if (!vm.exists(CONFIG_CONTRACTS_PATH)) { |
| 98 | + string memory template = vm.readFile(CONFIG_CONTRACTS_TEMPLATE_PATH); |
| 99 | + vm.writeFile(CONFIG_CONTRACTS_PATH, template); |
| 100 | + } |
| 101 | + |
| 102 | + cfg = vm.readFile(CONFIG_PATH); |
| 103 | + contractsCfg = vm.readFile(CONFIG_CONTRACTS_PATH); |
| 104 | + |
| 105 | + CHAIN_ID_L1 = uint64(cfg.readUint(".general.CHAIN_ID_L1")); |
| 106 | + CHAIN_ID_L2 = uint64(cfg.readUint(".general.CHAIN_ID_L2")); |
| 107 | + |
| 108 | + MAX_TX_IN_CHUNK = cfg.readUint(".rollup.MAX_TX_IN_CHUNK"); |
| 109 | + MAX_BLOCK_IN_CHUNK = cfg.readUint(".rollup.MAX_BLOCK_IN_CHUNK"); |
| 110 | + MAX_BATCH_IN_BUNDLE = cfg.readUint(".rollup.MAX_BATCH_IN_BUNDLE"); |
| 111 | + MAX_L1_MESSAGE_GAS_LIMIT = cfg.readUint(".rollup.MAX_L1_MESSAGE_GAS_LIMIT"); |
| 112 | + FINALIZE_BATCH_DEADLINE_SEC = cfg.readUint(".rollup.FINALIZE_BATCH_DEADLINE_SEC"); |
| 113 | + RELAY_MESSAGE_DEADLINE_SEC = cfg.readUint(".rollup.RELAY_MESSAGE_DEADLINE_SEC"); |
| 114 | + |
| 115 | + L1_CONTRACT_DEPLOYMENT_BLOCK = cfg.readUint(".general.L1_CONTRACT_DEPLOYMENT_BLOCK"); |
| 116 | + |
| 117 | + TEST_ENV_MOCK_FINALIZE_ENABLED = cfg.readBool(".rollup.TEST_ENV_MOCK_FINALIZE_ENABLED"); |
| 118 | + TEST_ENV_MOCK_FINALIZE_TIMEOUT_SEC = cfg.readUint(".rollup.TEST_ENV_MOCK_FINALIZE_TIMEOUT_SEC"); |
| 119 | + |
| 120 | + DEPLOYER_PRIVATE_KEY = cfg.readUint(".accounts.DEPLOYER_PRIVATE_KEY"); |
| 121 | + L1_COMMIT_SENDER_PRIVATE_KEY = cfg.readUint(".accounts.L1_COMMIT_SENDER_PRIVATE_KEY"); |
| 122 | + L1_FINALIZE_SENDER_PRIVATE_KEY = cfg.readUint(".accounts.L1_FINALIZE_SENDER_PRIVATE_KEY"); |
| 123 | + L1_GAS_ORACLE_SENDER_PRIVATE_KEY = cfg.readUint(".accounts.L1_GAS_ORACLE_SENDER_PRIVATE_KEY"); |
| 124 | + L2_GAS_ORACLE_SENDER_PRIVATE_KEY = cfg.readUint(".accounts.L2_GAS_ORACLE_SENDER_PRIVATE_KEY"); |
| 125 | + |
| 126 | + DEPLOYER_ADDR = cfg.readAddress(".accounts.DEPLOYER_ADDR"); |
| 127 | + L1_COMMIT_SENDER_ADDR = cfg.readAddress(".accounts.L1_COMMIT_SENDER_ADDR"); |
| 128 | + L1_FINALIZE_SENDER_ADDR = cfg.readAddress(".accounts.L1_FINALIZE_SENDER_ADDR"); |
| 129 | + L1_GAS_ORACLE_SENDER_ADDR = cfg.readAddress(".accounts.L1_GAS_ORACLE_SENDER_ADDR"); |
| 130 | + L2_GAS_ORACLE_SENDER_ADDR = cfg.readAddress(".accounts.L2_GAS_ORACLE_SENDER_ADDR"); |
| 131 | + |
| 132 | + OWNER_ADDR = cfg.readAddress(".accounts.OWNER_ADDR"); |
| 133 | + |
| 134 | + L2GETH_SIGNER_ADDRESS = cfg.readAddress(".sequencer.L2GETH_SIGNER_ADDRESS"); |
| 135 | + |
| 136 | + L2_MAX_ETH_SUPPLY = cfg.readUint(".genesis.L2_MAX_ETH_SUPPLY"); |
| 137 | + L2_DEPLOYER_INITIAL_BALANCE = cfg.readUint(".genesis.L2_DEPLOYER_INITIAL_BALANCE"); |
| 138 | + L2_SCROLL_MESSENGER_INITIAL_BALANCE = L2_MAX_ETH_SUPPLY - L2_DEPLOYER_INITIAL_BALANCE; |
| 139 | + |
| 140 | + DEPLOYMENT_SALT = cfg.readString(".contracts.DEPLOYMENT_SALT"); |
| 141 | + |
| 142 | + L1_FEE_VAULT_ADDR = cfg.readAddress(".contracts.L1_FEE_VAULT_ADDR"); |
| 143 | + |
| 144 | + CHUNK_COLLECTION_TIME_SEC = cfg.readString(".coordinator.CHUNK_COLLECTION_TIME_SEC"); |
| 145 | + BATCH_COLLECTION_TIME_SEC = cfg.readString(".coordinator.BATCH_COLLECTION_TIME_SEC"); |
| 146 | + BUNDLE_COLLECTION_TIME_SEC = cfg.readString(".coordinator.BUNDLE_COLLECTION_TIME_SEC"); |
| 147 | + COORDINATOR_JWT_SECRET_KEY = cfg.readString(".coordinator.COORDINATOR_JWT_SECRET_KEY"); |
| 148 | + |
| 149 | + runSanityCheck(); |
| 150 | + } |
| 151 | + |
| 152 | + /// @dev Ensure that `addr` is not the zero address. |
| 153 | + /// This helps catch bugs arising from incorrect deployment order. |
| 154 | + function notnull(address addr) internal pure returns (address) { |
| 155 | + require(addr != address(0), "null address"); |
| 156 | + return addr; |
| 157 | + } |
| 158 | + |
| 159 | + function tryGetOverride(string memory name) internal returns (address) { |
| 160 | + address addr; |
| 161 | + string memory key; |
| 162 | + if (keccak256(abi.encodePacked(name)) == keccak256(abi.encodePacked("L1_GAS_TOKEN"))) { |
| 163 | + key = string(abi.encodePacked(".gas-token.", name)); |
| 164 | + } else { |
| 165 | + key = string(abi.encodePacked(".contracts.overrides.", name)); |
| 166 | + } |
| 167 | + |
| 168 | + if (!vm.keyExistsToml(cfg, key)) { |
| 169 | + return address(0); |
| 170 | + } |
| 171 | + |
| 172 | + addr = cfg.readAddress(key); |
| 173 | + |
| 174 | + if (addr.code.length == 0) { |
| 175 | + (VmSafe.CallerMode callerMode, , ) = vm.readCallers(); |
| 176 | + |
| 177 | + // if we're ready to start broadcasting transactions, then we |
| 178 | + // must ensure that the override contract has been deployed. |
| 179 | + if (callerMode == VmSafe.CallerMode.Broadcast || callerMode == VmSafe.CallerMode.RecurrentBroadcast) { |
| 180 | + revert( |
| 181 | + string( |
| 182 | + abi.encodePacked( |
| 183 | + "[ERROR] override ", |
| 184 | + name, |
| 185 | + " = ", |
| 186 | + vm.toString(addr), |
| 187 | + " not deployed in broadcast mode" |
| 188 | + ) |
| 189 | + ) |
| 190 | + ); |
| 191 | + } |
| 192 | + } |
| 193 | + |
| 194 | + return addr; |
| 195 | + } |
| 196 | + |
| 197 | + /********************* |
| 198 | + * Private functions * |
| 199 | + *********************/ |
| 200 | + |
| 201 | + function runSanityCheck() private view { |
| 202 | + verifyAccount("DEPLOYER", DEPLOYER_PRIVATE_KEY, DEPLOYER_ADDR); |
| 203 | + verifyAccount("L1_COMMIT_SENDER", L1_COMMIT_SENDER_PRIVATE_KEY, L1_COMMIT_SENDER_ADDR); |
| 204 | + verifyAccount("L1_FINALIZE_SENDER", L1_FINALIZE_SENDER_PRIVATE_KEY, L1_FINALIZE_SENDER_ADDR); |
| 205 | + verifyAccount("L1_GAS_ORACLE_SENDER", L1_GAS_ORACLE_SENDER_PRIVATE_KEY, L1_GAS_ORACLE_SENDER_ADDR); |
| 206 | + verifyAccount("L2_GAS_ORACLE_SENDER", L2_GAS_ORACLE_SENDER_PRIVATE_KEY, L2_GAS_ORACLE_SENDER_ADDR); |
| 207 | + } |
| 208 | + |
| 209 | + function verifyAccount( |
| 210 | + string memory name, |
| 211 | + uint256 privateKey, |
| 212 | + address addr |
| 213 | + ) private pure { |
| 214 | + if (vm.addr(privateKey) != addr) { |
| 215 | + revert( |
| 216 | + string( |
| 217 | + abi.encodePacked( |
| 218 | + "[ERROR] ", |
| 219 | + name, |
| 220 | + "_ADDR (", |
| 221 | + vm.toString(addr), |
| 222 | + ") does not match ", |
| 223 | + name, |
| 224 | + "_PRIVATE_KEY" |
| 225 | + ) |
| 226 | + ) |
| 227 | + ); |
| 228 | + } |
| 229 | + } |
| 230 | +} |
0 commit comments