From 19f579ba4a2854c23ff804c1a50e21fe4701eb3d Mon Sep 17 00:00:00 2001 From: "jason.huang" <20609724+doutv@users.noreply.github.com> Date: Tue, 21 Oct 2025 11:27:47 +0800 Subject: [PATCH 01/26] Add SystemConfigV4 contract and upgrade script - Introduced the SystemConfigV4 contract to manage configuration for the Optimism network, including various update types and storage slots for critical addresses. - Created UpgradeSystemConfigToV4 script to facilitate the upgrade process, including deploying a new DepositedOKBAdapter and setting it as the gas paying token. - Implemented configuration validation and logging for better traceability during the upgrade process. --- .../scripts/SystemConfigV4.sol | 631 ++++++++++++++++++ .../scripts/UpgradeSystemConfigToV4.s.sol | 249 +++++++ 2 files changed, 880 insertions(+) create mode 100644 packages/contracts-bedrock/scripts/SystemConfigV4.sol create mode 100644 packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol diff --git a/packages/contracts-bedrock/scripts/SystemConfigV4.sol b/packages/contracts-bedrock/scripts/SystemConfigV4.sol new file mode 100644 index 0000000000000..e38a5fe45bfe6 --- /dev/null +++ b/packages/contracts-bedrock/scripts/SystemConfigV4.sol @@ -0,0 +1,631 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Contracts +import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import { ReinitializableBase } from "src/universal/ReinitializableBase.sol"; +import { ProxyAdminOwnedBase } from "src/L1/ProxyAdminOwnedBase.sol"; + +// Libraries +import { Storage } from "src/libraries/Storage.sol"; +import { Features } from "src/libraries/Features.sol"; +import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; +import { Constants } from "src/libraries/Constants.sol"; +// Interfaces +import { ISemver } from "interfaces/universal/ISemver.sol"; +import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; +import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; +import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; +import { IGasToken } from "src/libraries/GasPayingToken.sol"; + +/// @custom:proxied true +/// @title SystemConfigV4 +/// @notice The SystemConfigV4 contract is used to manage configuration of an Optimism network. +/// All configuration is stored on L1 and picked up by L2 as part of the derviation of +/// the L2 chain. +contract SystemConfigV4 is ProxyAdminOwnedBase, OwnableUpgradeable, ReinitializableBase, ISemver, IGasToken { + /// @notice Enum representing different types of updates. + /// @custom:value BATCHER Represents an update to the batcher hash. + /// @custom:value FEE_SCALARS Represents an update to l1 data fee scalars. + /// @custom:value GAS_LIMIT Represents an update to gas limit on L2. + /// @custom:value UNSAFE_BLOCK_SIGNER Represents an update to the signer key for unsafe + /// block distrubution. + /// @custom:value EIP_1559_PARAMS Represents an update to EIP-1559 parameters. + /// @custom:value OPERATOR_FEE_PARAMS Represents an update to operator fee parameters. + /// @custom:value MIN_BASE_FEE Represents an update to the minimum base fee. + enum UpdateType { + BATCHER, + FEE_SCALARS, + GAS_LIMIT, + UNSAFE_BLOCK_SIGNER, + EIP_1559_PARAMS, + OPERATOR_FEE_PARAMS, + MIN_BASE_FEE + } + + /// @notice Struct representing the addresses of L1 system contracts. These should be the + /// contracts that users interact with (not implementations for proxied contracts) + /// and are network specific. + struct Addresses { + address l1CrossDomainMessenger; + address l1ERC721Bridge; + address l1StandardBridge; + address optimismPortal; + address optimismMintableERC20Factory; + } + + /// @notice Version identifier, used for upgrades. + uint256 public constant VERSION = 0; + + /// @notice Storage slot that the unsafe block signer is stored at. + /// Storing it at this deterministic storage slot allows for decoupling the storage + /// layout from the way that `solc` lays out storage. The `op-node` uses a storage + /// proof to fetch this value. + /// @dev NOTE: this value will be migrated to another storage slot in a future version. + /// User input should not be placed in storage in this contract until this migration + /// happens. It is unlikely that keccak second preimage resistance will be broken, + /// but it is better to be safe than sorry. + bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256("systemconfig.unsafeblocksigner"); + + /// @notice Storage slot that the L1CrossDomainMessenger address is stored at. + bytes32 public constant L1_CROSS_DOMAIN_MESSENGER_SLOT = + bytes32(uint256(keccak256("systemconfig.l1crossdomainmessenger")) - 1); + + /// @notice Storage slot that the L1ERC721Bridge address is stored at. + bytes32 public constant L1_ERC_721_BRIDGE_SLOT = bytes32(uint256(keccak256("systemconfig.l1erc721bridge")) - 1); + + /// @notice Storage slot that the L1StandardBridge address is stored at. + bytes32 public constant L1_STANDARD_BRIDGE_SLOT = bytes32(uint256(keccak256("systemconfig.l1standardbridge")) - 1); + + /// @notice Storage slot that the OptimismPortal address is stored at. + bytes32 public constant OPTIMISM_PORTAL_SLOT = bytes32(uint256(keccak256("systemconfig.optimismportal")) - 1); + + /// @notice Storage slot that the OptimismMintableERC20Factory address is stored at. + bytes32 public constant OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT = + bytes32(uint256(keccak256("systemconfig.optimismmintableerc20factory")) - 1); + + /// @notice Storage slot that the batch inbox address is stored at. + bytes32 public constant BATCH_INBOX_SLOT = bytes32(uint256(keccak256("systemconfig.batchinbox")) - 1); + + /// @notice Storage slot for block at which the op-node can start searching for logs from. + bytes32 public constant START_BLOCK_SLOT = bytes32(uint256(keccak256("systemconfig.startBlock")) - 1); + + /// @notice The maximum gas limit that can be set for L2 blocks. This limit is used to enforce that the blocks + /// on L2 are not too large to process and prove. Over time, this value can be increased as various + /// optimizations and improvements are made to the system at large. + uint64 internal constant MAX_GAS_LIMIT = 500_000_000; + + /// @notice Fixed L2 gas overhead. Used as part of the L2 fee calculation. + /// Deprecated since the Ecotone network upgrade + uint256 public overhead; + + /// @notice Dynamic L2 gas overhead. Used as part of the L2 fee calculation. + /// The most significant byte is used to determine the version since the + /// Ecotone network upgrade. + uint256 public scalar; + + /// @notice Identifier for the batcher. + /// For version 1 of this configuration, this is represented as an address left-padded + /// with zeros to 32 bytes. + bytes32 public batcherHash; + + /// @notice L2 block gas limit. + uint64 public gasLimit; + + /// @notice Basefee scalar value. Part of the L2 fee calculation since the Ecotone network upgrade. + uint32 public basefeeScalar; + + /// @notice Blobbasefee scalar value. Part of the L2 fee calculation since the Ecotone network upgrade. + uint32 public blobbasefeeScalar; + + /// @notice The configuration for the deposit fee market. + /// Used by the OptimismPortal to meter the cost of buying L2 gas on L1. + /// Set as internal with a getter so that the struct is returned instead of a tuple. + IResourceMetering.ResourceConfig internal _resourceConfig; + + /// @notice The EIP-1559 base fee max change denominator. + uint32 public eip1559Denominator; + + /// @notice The EIP-1559 elasticity multiplier. + uint32 public eip1559Elasticity; + + /// @notice The operator fee scalar. + uint32 public operatorFeeScalar; + + /// @notice The operator fee constant. + uint64 public operatorFeeConstant; + + /// @notice The L2 chain ID that this SystemConfig configures. + uint256 public l2ChainId; + + /// @notice The SuperchainConfig contract that manages the pause state. + ISuperchainConfig public superchainConfig; + + /// @notice The minimum base fee, in wei. + uint64 public minBaseFee; + + /// @notice Bytes32 feature flag name to boolean enabled value. + mapping(bytes32 => bool) public isFeatureEnabled; + + /// @notice Emitted when configuration is updated. + /// @param version SystemConfig version. + /// @param updateType Type of update. + /// @param data Encoded update data. + event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); + + /// @notice Emitted when a feature is set. + /// @param feature Feature that was set. + /// @param enabled Whether the feature is enabled. + event FeatureSet(bytes32 indexed feature, bool indexed enabled); + + /// @notice Thrown when attempting to enable/disable a feature when already enabled/disabled, + /// respectively. + error SystemConfig_InvalidFeatureState(); + + /// @notice Thrown when attempting to set a value that has already been set + error SystemConfig_ValueAlreadySet(); + + /// @notice Semantic version. + /// @custom:semver 3.12.0 + function version() public pure virtual returns (string memory) { + return "3.12.0"; + } + + /// @notice Constructs the SystemConfig contract. + /// @dev START_BLOCK_SLOT is set to type(uint256).max here so that it will be a dead value + /// in the singleton. + constructor() ReinitializableBase(4) { + Storage.setUint(START_BLOCK_SLOT, type(uint256).max); + _disableInitializers(); + } + + /// @notice Initializer. + /// The resource config must be set before the require check. + /// @param _owner Initial owner of the contract. + /// @param _basefeeScalar Initial basefee scalar value. + /// @param _blobbasefeeScalar Initial blobbasefee scalar value. + /// @param _batcherHash Initial batcher hash. + /// @param _gasLimit Initial gas limit. + /// @param _unsafeBlockSigner Initial unsafe block signer address. + /// @param _config Initial ResourceConfig. + /// @param _batchInbox Batch inbox address. An identifier for the op-node to find + /// canonical data. + /// @param _addresses Set of L1 contract addresses. These should be the proxies. + /// @param _l2ChainId The L2 chain ID that this SystemConfig configures. + /// @param _superchainConfig The SuperchainConfig contract address. + function initialize( + address _owner, + uint32 _basefeeScalar, + uint32 _blobbasefeeScalar, + bytes32 _batcherHash, + uint64 _gasLimit, + address _unsafeBlockSigner, + IResourceMetering.ResourceConfig memory _config, + address _batchInbox, + SystemConfigV4.Addresses memory _addresses, + uint256 _l2ChainId, + ISuperchainConfig _superchainConfig + ) + public + reinitializer(initVersion()) + { + // Initialization transactions must come from the ProxyAdmin or its owner. + _assertOnlyProxyAdminOrProxyAdminOwner(); + + // Now perform initialization logic. + __Ownable_init(); + transferOwnership(_owner); + + // These are set in ascending order of their UpdateTypes. + _setBatcherHash(_batcherHash); + _setGasConfigEcotone({ _basefeeScalar: _basefeeScalar, _blobbasefeeScalar: _blobbasefeeScalar }); + _setGasLimit(_gasLimit); + + Storage.setAddress(UNSAFE_BLOCK_SIGNER_SLOT, _unsafeBlockSigner); + Storage.setAddress(BATCH_INBOX_SLOT, _batchInbox); + Storage.setAddress(L1_CROSS_DOMAIN_MESSENGER_SLOT, _addresses.l1CrossDomainMessenger); + Storage.setAddress(L1_ERC_721_BRIDGE_SLOT, _addresses.l1ERC721Bridge); + Storage.setAddress(L1_STANDARD_BRIDGE_SLOT, _addresses.l1StandardBridge); + Storage.setAddress(OPTIMISM_PORTAL_SLOT, _addresses.optimismPortal); + Storage.setAddress(OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT, _addresses.optimismMintableERC20Factory); + + _setStartBlock(); + + _setResourceConfig(_config); + + l2ChainId = _l2ChainId; + superchainConfig = _superchainConfig; + } + + /// @notice Returns the minimum L2 gas limit that can be safely set for the system to + /// operate. The L2 gas limit must be larger than or equal to the amount of + /// gas that is allocated for deposits per block plus the amount of gas that + /// is allocated for the system transaction. + /// This function is used to determine if changes to parameters are safe. + /// @return uint64 Minimum gas limit. + function minimumGasLimit() public view returns (uint64) { + return uint64(_resourceConfig.maxResourceLimit) + uint64(_resourceConfig.systemTxMaxGas); + } + + /// @notice Returns the maximum L2 gas limit that can be safely set for the system to + /// operate. This bound is used to prevent the gas limit from being set too high + /// and causing the system to be unable to process and/or prove L2 blocks. + /// @return uint64 Maximum gas limit. + function maximumGasLimit() public pure returns (uint64) { + return MAX_GAS_LIMIT; + } + + /// @notice High level getter for the unsafe block signer address. + /// Unsafe blocks can be propagated across the p2p network if they are signed by the + /// key corresponding to this address. + /// @return addr_ Address of the unsafe block signer. + function unsafeBlockSigner() public view returns (address addr_) { + addr_ = Storage.getAddress(UNSAFE_BLOCK_SIGNER_SLOT); + } + + /// @notice Getter for the L1CrossDomainMessenger address. + function l1CrossDomainMessenger() public view returns (address addr_) { + addr_ = Storage.getAddress(L1_CROSS_DOMAIN_MESSENGER_SLOT); + } + + /// @notice Getter for the L1ERC721Bridge address. + function l1ERC721Bridge() public view returns (address addr_) { + addr_ = Storage.getAddress(L1_ERC_721_BRIDGE_SLOT); + } + + /// @notice Getter for the L1StandardBridge address. + function l1StandardBridge() public view returns (address addr_) { + addr_ = Storage.getAddress(L1_STANDARD_BRIDGE_SLOT); + } + + /// @notice Getter for the DisputeGameFactory address. + function disputeGameFactory() public view returns (address addr_) { + IOptimismPortal2 portal = IOptimismPortal2(payable(optimismPortal())); + addr_ = address(portal.disputeGameFactory()); + } + + /// @notice Getter for the OptimismPortal address. + function optimismPortal() public view returns (address addr_) { + addr_ = Storage.getAddress(OPTIMISM_PORTAL_SLOT); + } + + /// @notice Getter for the OptimismMintableERC20Factory address. + function optimismMintableERC20Factory() public view returns (address addr_) { + addr_ = Storage.getAddress(OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT); + } + + /// @notice Consolidated getter for the Addresses struct. + function getAddresses() external view returns (Addresses memory) { + return Addresses({ + l1CrossDomainMessenger: l1CrossDomainMessenger(), + l1ERC721Bridge: l1ERC721Bridge(), + l1StandardBridge: l1StandardBridge(), + optimismPortal: optimismPortal(), + optimismMintableERC20Factory: optimismMintableERC20Factory() + }); + } + + /// @notice Getter for the BatchInbox address. + function batchInbox() external view returns (address addr_) { + addr_ = Storage.getAddress(BATCH_INBOX_SLOT); + } + + /// @notice Getter for the StartBlock number. + function startBlock() external view returns (uint256 startBlock_) { + startBlock_ = Storage.getUint(START_BLOCK_SLOT); + } + + /// @notice Updates the unsafe block signer address. Can only be called by the owner. + /// @param _unsafeBlockSigner New unsafe block signer address. + function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner { + _setUnsafeBlockSigner(_unsafeBlockSigner); + } + + /// @notice Updates the unsafe block signer address. + /// @param _unsafeBlockSigner New unsafe block signer address. + function _setUnsafeBlockSigner(address _unsafeBlockSigner) internal { + Storage.setAddress(UNSAFE_BLOCK_SIGNER_SLOT, _unsafeBlockSigner); + + bytes memory data = abi.encode(_unsafeBlockSigner); + emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data); + } + + /// @notice Updates the batcher hash. Can only be called by the owner. + /// @param _batcherHash New batcher hash. + function setBatcherHash(bytes32 _batcherHash) external onlyOwner { + _setBatcherHash(_batcherHash); + } + + /// @notice Internal function for updating the batcher hash. + /// @param _batcherHash New batcher hash. + function _setBatcherHash(bytes32 _batcherHash) internal { + batcherHash = _batcherHash; + + bytes memory data = abi.encode(_batcherHash); + emit ConfigUpdate(VERSION, UpdateType.BATCHER, data); + } + + /// @notice Updates gas config. Can only be called by the owner. + /// Deprecated in favor of setGasConfigEcotone since the Ecotone upgrade. + /// @param _overhead New overhead value. + /// @param _scalar New scalar value. + function setGasConfig(uint256 _overhead, uint256 _scalar) external onlyOwner { + _setGasConfig(_overhead, _scalar); + } + + /// @notice Internal function for updating the gas config. + /// @param _overhead New overhead value. + /// @param _scalar New scalar value. + function _setGasConfig(uint256 _overhead, uint256 _scalar) internal { + require((uint256(0xff) << 248) & _scalar == 0, "SystemConfig: scalar exceeds max."); + + overhead = _overhead; + scalar = _scalar; + + bytes memory data = abi.encode(_overhead, _scalar); + emit ConfigUpdate(VERSION, UpdateType.FEE_SCALARS, data); + } + + /// @notice Updates gas config as of the Ecotone upgrade. Can only be called by the owner. + /// @param _basefeeScalar New basefeeScalar value. + /// @param _blobbasefeeScalar New blobbasefeeScalar value. + function setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) external onlyOwner { + _setGasConfigEcotone(_basefeeScalar, _blobbasefeeScalar); + } + + /// @notice Internal function for updating the fee scalars as of the Ecotone upgrade. + /// @param _basefeeScalar New basefeeScalar value. + /// @param _blobbasefeeScalar New blobbasefeeScalar value. + function _setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) internal { + basefeeScalar = _basefeeScalar; + blobbasefeeScalar = _blobbasefeeScalar; + + scalar = (uint256(0x01) << 248) | (uint256(_blobbasefeeScalar) << 32) | _basefeeScalar; + + bytes memory data = abi.encode(overhead, scalar); + emit ConfigUpdate(VERSION, UpdateType.FEE_SCALARS, data); + } + + /// @notice Updates the L2 gas limit. Can only be called by the owner. + /// @param _gasLimit New gas limit. + function setGasLimit(uint64 _gasLimit) external onlyOwner { + _setGasLimit(_gasLimit); + } + + /// @notice Internal function for updating the L2 gas limit. + /// @param _gasLimit New gas limit. + function _setGasLimit(uint64 _gasLimit) internal { + require(_gasLimit >= minimumGasLimit(), "SystemConfig: gas limit too low"); + require(_gasLimit <= maximumGasLimit(), "SystemConfig: gas limit too high"); + gasLimit = _gasLimit; + + bytes memory data = abi.encode(_gasLimit); + emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data); + } + + /// @notice Updates the EIP-1559 parameters of the chain. Can only be called by the owner. + /// @param _denominator EIP-1559 base fee max change denominator. + /// @param _elasticity EIP-1559 elasticity multiplier. + function setEIP1559Params(uint32 _denominator, uint32 _elasticity) external onlyOwner { + _setEIP1559Params(_denominator, _elasticity); + } + + /// @notice Internal function for updating the EIP-1559 parameters. + function _setEIP1559Params(uint32 _denominator, uint32 _elasticity) internal { + // require the parameters have sane values: + require(_denominator >= 1, "SystemConfig: denominator must be >= 1"); + require(_elasticity >= 1, "SystemConfig: elasticity must be >= 1"); + eip1559Denominator = _denominator; + eip1559Elasticity = _elasticity; + + bytes memory data = abi.encode(uint256(_denominator) << 32 | uint64(_elasticity)); + emit ConfigUpdate(VERSION, UpdateType.EIP_1559_PARAMS, data); + } + + /// @notice Updates the minimum base fee. Can only be called by the owner. + /// Setting this value to 0 is equivalent to disabling the min base fee feature + /// @param _minBaseFee New minimum base fee. + function setMinBaseFee(uint64 _minBaseFee) external onlyOwner { + _setMinBaseFee(_minBaseFee); + } + + /// @notice Internal function for updating the minimum base fee. + function _setMinBaseFee(uint64 _minBaseFee) internal { + minBaseFee = _minBaseFee; + + bytes memory data = abi.encode(_minBaseFee); + emit ConfigUpdate(VERSION, UpdateType.MIN_BASE_FEE, data); + } + + /// @notice Updates the operator fee parameters. Can only be called by the owner. + /// @param _operatorFeeScalar operator fee scalar. + /// @param _operatorFeeConstant operator fee constant. + function setOperatorFeeScalars(uint32 _operatorFeeScalar, uint64 _operatorFeeConstant) external onlyOwner { + _setOperatorFeeScalars(_operatorFeeScalar, _operatorFeeConstant); + } + + /// @notice Internal function for updating the operator fee parameters. + function _setOperatorFeeScalars(uint32 _operatorFeeScalar, uint64 _operatorFeeConstant) internal { + operatorFeeScalar = _operatorFeeScalar; + operatorFeeConstant = _operatorFeeConstant; + + bytes memory data = abi.encode(uint256(_operatorFeeScalar) << 64 | _operatorFeeConstant); + emit ConfigUpdate(VERSION, UpdateType.OPERATOR_FEE_PARAMS, data); + } + + /// @notice Sets the start block in a backwards compatible way. Proxies + /// that were initialized before the startBlock existed in storage + /// can have their start block set by a user provided override. + /// A start block of 0 indicates that there is no override and the + /// start block will be set by `block.number`. + /// @dev This logic is used to patch legacy deployments with new storage values. + /// Use the override if it is provided as a non zero value and the value + /// has not already been set in storage. Use `block.number` if the value + /// has already been set in storage + function _setStartBlock() internal { + if (Storage.getUint(START_BLOCK_SLOT) == 0) { + Storage.setUint(START_BLOCK_SLOT, block.number); + } + } + + /// @notice A getter for the resource config. + /// Ensures that the struct is returned instead of a tuple. + /// @return ResourceConfig + function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory) { + return _resourceConfig; + } + + /// @notice An internal setter for the resource config. + /// Ensures that the config is sane before storing it by checking for invariants. + /// In the future, this method may emit an event that the `op-node` picks up + /// for when the resource config is changed. + /// @param _config The new resource config. + function _setResourceConfig(IResourceMetering.ResourceConfig memory _config) internal { + // Min base fee must be less than or equal to max base fee. + require( + _config.minimumBaseFee <= _config.maximumBaseFee, "SystemConfig: min base fee must be less than max base" + ); + // Base fee change denominator must be greater than 1. + require(_config.baseFeeMaxChangeDenominator > 1, "SystemConfig: denominator must be larger than 1"); + // Max resource limit plus system tx gas must be less than or equal to the L2 gas limit. + // The gas limit must be increased before these values can be increased. + require(_config.maxResourceLimit + _config.systemTxMaxGas <= gasLimit, "SystemConfig: gas limit too low"); + // Elasticity multiplier must be greater than 0. + require(_config.elasticityMultiplier > 0, "SystemConfig: elasticity multiplier cannot be 0"); + // No precision loss when computing target resource limit. + require( + ((_config.maxResourceLimit / _config.elasticityMultiplier) * _config.elasticityMultiplier) + == _config.maxResourceLimit, + "SystemConfig: precision loss with target resource limit" + ); + + _resourceConfig = _config; + } + + /// @notice Sets a feature flag enabled or disabled. Can only be called by the ProxyAdmin or + /// its owner. + /// @param _feature Feature to set. + /// @param _enabled Whether the feature should be enabled or disabled. + function setFeature(bytes32 _feature, bool _enabled) external { + // Features can only be set by the ProxyAdmin or its owner. + _assertOnlyProxyAdminOrProxyAdminOwner(); + + // As a sanity check, prevent users from enabling the feature if already enabled or + // disabling the feature if already disabled. This helps to prevent accidental misuse. + if (_enabled == isFeatureEnabled[_feature]) { + revert SystemConfig_InvalidFeatureState(); + } + + // Handle feature-specific safety logic here. + if (_feature == Features.ETH_LOCKBOX) { + // It would probably better to check that the ETHLockbox contract is set inside the + // OptimismPortal2 contract before you're allowed to enable the feature here, but the + // portal checks that the feature is set before allowing you to set the lockbox, so + // these checks are good enough. + + // Lockbox shouldn't be unset if the ethLockbox address is still configured in the + // OptimismPortal2 contract. Doing so would cause the system to start keeping ETH in + // the portal. This check means there's no way to stop using ETHLockbox at the moment + // after it's been configured (which is expected). + if ( + isFeatureEnabled[_feature] && !_enabled + && address(IOptimismPortal2(payable(optimismPortal())).ethLockbox()) != address(0) + ) { + revert SystemConfig_InvalidFeatureState(); + } + + // Lockbox can't be set or unset if the system is currently paused because it would + // change the pause identifier which would potentially cause the system to become + // unpaused unexpectedly. + if (paused()) { + revert SystemConfig_InvalidFeatureState(); + } + } + + // Set the feature. + isFeatureEnabled[_feature] = _enabled; + + // Emit an event. + emit FeatureSet(_feature, _enabled); + } + + /// @notice Returns the current pause state for this network. If the network is using + /// ETHLockbox, the system is paused if either the global pause is active or the pause + /// is active where the ETHLockbox address is used as the identifier. If the network is + /// not using ETHLockbox, the system is paused if either the global pause is active or + /// the pause is active where the OptimismPortal address is used as the identifier. + /// @return bool True if the system is paused, false otherwise. + function paused() public view returns (bool) { + // Determine the appropriate chain identifier based on the feature flags. + address identifier = isFeatureEnabled[Features.ETH_LOCKBOX] + ? address(IOptimismPortal2(payable(optimismPortal())).ethLockbox()) + : address(optimismPortal()); + + // Check if either global or local pause is active. + return superchainConfig.paused(address(0)) || superchainConfig.paused(identifier); + } + + /// @notice Returns the guardian address of the SuperchainConfig. + /// @return address The guardian address. + function guardian() public view returns (address) { + return superchainConfig.guardian(); + } + + /// @custom:legacy + /// @notice Returns whether the custom gas token feature is enabled. + /// @return bool True if the custom gas token feature is enabled, false otherwise. + function isCustomGasToken() public view returns (bool) { + return isFeatureEnabled[Features.CUSTOM_GAS_TOKEN]; + } + + /// @notice Getter for the ERC20 token address that is used to pay for gas and its decimals. + /// @return address_ Address of the gas paying token. + /// @return decimals_ Decimals of the gas paying token. + function gasPayingToken() public view returns (address address_, uint8 decimals_) { + (address_, decimals_) = GasPayingToken.getToken(); + } + + /// @notice Returns the gas token name. + /// @return name_ Name of the gas paying token. + function gasPayingTokenName() public view returns (string memory name_) { + name_ = GasPayingToken.getName(); + } + + /// @notice Returns the gas token symbol. + /// @return symbol_ Symbol of the gas paying token. + function gasPayingTokenSymbol() public view returns (string memory symbol_) { + symbol_ = GasPayingToken.getSymbol(); + } + + /// @notice Sets the gas paying token and its metadata. Can only be called by the owner. + /// @param _token The address of the gas paying token. + /// @param _decimals The decimals of the gas paying token. + /// @param _name The name of the gas paying token as a bytes32. + /// @param _symbol The symbol of the gas paying token as a bytes32. + function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external onlyOwner { + (address gasToken,) = gasPayingToken(); + if (gasToken != Constants.ETHER) { + revert SystemConfig_ValueAlreadySet(); + } + _setGasPayingToken(_token, _decimals, _name, _symbol); + } + + /// @notice Internal function for setting the gas paying token. + /// @param _token The address of the gas paying token. + /// @param _decimals The decimals of the gas paying token. + /// @param _name The name of the gas paying token as a bytes32. + /// @param _symbol The symbol of the gas paying token as a bytes32. + function _setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) internal { + GasPayingToken.set(_token, _decimals, _name, _symbol); + } + + /// @notice Upgrade function that resets the gas paying token to allow setting it once more. + /// This preserves the existing "set once" logic while allowing a fresh start. + /// @dev This function can only be called during the upgrade process via reinitializer(4). + function upgradeAndSetGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external reinitializer(initVersion()) { + // Must be called by ProxyAdmin or its owner + _assertOnlyProxyAdminOrProxyAdminOwner(); + + _setGasPayingToken(_token, _decimals, _name, _symbol); + } +} diff --git a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol new file mode 100644 index 0000000000000..52b08da4a313c --- /dev/null +++ b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { Script } from "forge-std/Script.sol"; +import { console } from "forge-std/console.sol"; +import { SystemConfig } from "src/L1/SystemConfig.sol"; +import { SystemConfigV4 } from "scripts/SystemConfigV4.sol"; +import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; +import { IOKB } from "interfaces/L1/IOKB.sol"; +import { DepositedOKBAdapter } from "src/L1/DepositedOKBAdapter.sol"; + +/// @title UpgradeSystemConfigToV4 +/// @notice Custom script to upgrade SystemConfig to V4 and set OKB adapter as gas paying token +/// @dev This script: +/// 1. Reads OKB token address from environment variable +/// 2. Deploys DepositedOKBAdapter that handles OKB burning internally +/// 3. Adds deployer address to whitelist for deposits +/// 4. Upgrades SystemConfig to V4 +/// 5. Sets OKB adapter as gas paying token in SystemConfig storage +/// 6. Verifies all configurations on L1 +contract UpgradeSystemConfigToV4 is Script { + + // Environment variable names + string constant SYSTEM_CONFIG_PROXY = "SYSTEM_CONFIG_PROXY_ADDRESS"; + string constant PROXY_ADMIN = "PROXY_ADMIN"; + string constant OKB_TOKEN_ADDRESS = "OKB_TOKEN_ADDRESS"; + string constant OPTIMISM_PORTAL_PROXY = "OPTIMISM_PORTAL_PROXY_ADDRESS"; + + // State variables for configuration + address systemConfigProxy; + address proxyAdmin; + address okbTokenAddress; + address optimismPortalProxy; + address deployerAddress; + + // Deployed contracts + IOKB okbToken; + DepositedOKBAdapter adapter; + + /// @notice Main upgrade function + function run() external { + _loadConfiguration(); + _validateConfiguration(); + _performUpgrade(); + } + + /// @notice Load configuration from environment variables + function _loadConfiguration() internal { + // Get deployer address from msg.sender (set by forge script --private-key) + deployerAddress = msg.sender; + + // Load addresses from environment + systemConfigProxy = vm.envAddress(SYSTEM_CONFIG_PROXY); + proxyAdmin = vm.envAddress(PROXY_ADMIN); + okbTokenAddress = vm.envAddress(OKB_TOKEN_ADDRESS); + optimismPortalProxy = vm.envAddress(OPTIMISM_PORTAL_PROXY); + + console.log("=== Upgrade Configuration ==="); + console.log("Deployer address:", deployerAddress); + console.log("SystemConfig Proxy:", systemConfigProxy); + console.log("ProxyAdmin:", proxyAdmin); + console.log("OKB Token Address:", okbTokenAddress); + console.log("OptimismPortal Proxy:", optimismPortalProxy); + + // Initialize OKB token interface + okbToken = IOKB(okbTokenAddress); + } + + /// @notice Validate the configuration before proceeding + function _validateConfiguration() internal view { + require(systemConfigProxy != address(0), "SystemConfig proxy address cannot be zero"); + require(proxyAdmin != address(0), "ProxyAdmin address cannot be zero"); + require(okbTokenAddress != address(0), "OKB token address cannot be zero"); + require(optimismPortalProxy != address(0), "OptimismPortal proxy address cannot be zero"); + require(deployerAddress != address(0), "Deployer address cannot be zero"); + + // Verify contracts have code + require( + systemConfigProxy.code.length > 0, + "SystemConfig proxy must have code (not an EOA)" + ); + require( + proxyAdmin.code.length > 0, + "ProxyAdmin must have code (not an EOA)" + ); + require( + okbTokenAddress.code.length > 0, + "OKB token must have code (not an EOA)" + ); + require( + optimismPortalProxy.code.length > 0, + "OptimismPortal proxy must have code (not an EOA)" + ); + } + + /// @notice Deploy DepositedOKBAdapter + function _deployAdapter() internal { + console.log("\n--- Deploying DepositedOKBAdapter ---"); + adapter = new DepositedOKBAdapter(okbTokenAddress, payable(optimismPortalProxy), deployerAddress); + console.log("DepositedOKBAdapter deployed at:", address(adapter)); + } + + /// @notice Set up whitelist for authorized depositors + function _setupWhitelist() internal { + console.log("\n--- Setting up Whitelist ---"); + console.log("Adding deployer to whitelist..."); + address[] memory addresses = new address[](1); + addresses[0] = deployerAddress; + adapter.addToWhitelistBatch(addresses); + console.log("Deployer whitelisted successfully:", deployerAddress); + } + + /// @notice Perform the complete upgrade process + function _performUpgrade() internal { + console.log("\n=== Starting SystemConfig V4 Upgrade ==="); + + // Step 1: Check current state + _logCurrentState(); + + // Step 2: Deploy new SystemConfigV4 implementation + console.log("\n--- Deploying SystemConfigV4 Implementation ---"); + SystemConfigV4 newImplementation = new SystemConfigV4(); + console.log("SystemConfigV4 deployed at:", address(newImplementation)); + console.log("New implementation version:", newImplementation.version()); + console.log("New init version:", newImplementation.initVersion()); + + vm.startBroadcast(); + + // Step 3: Deploy DepositedOKBAdapter + _deployAdapter(); + + // Step 4: Setup whitelist for deployer + _setupWhitelist(); + + // Step 5: Upgrade the proxy to point to new implementation + console.log("\n--- Upgrading Proxy Implementation ---"); + IProxyAdmin admin = IProxyAdmin(proxyAdmin); + admin.upgrade(payable(systemConfigProxy), address(newImplementation)); + console.log("Proxy upgraded successfully"); + + // Step 6: Call the upgrade function to set OKB adapter as gas paying token + console.log("\n--- Setting OKB Adapter as Gas Paying Token ---"); + SystemConfigV4 upgradedSystemConfig = SystemConfigV4(systemConfigProxy); + + // Convert string to bytes32 for SystemConfig function + bytes32 nameBytes32 = bytes32(bytes(okbToken.name())); + bytes32 symbolBytes32 = bytes32(bytes(okbToken.symbol())); + + try upgradedSystemConfig.upgradeAndSetGasPayingToken(address(adapter), okbToken.decimals(), nameBytes32, symbolBytes32) { + console.log("upgradeAndSetGasPayingToken() called successfully"); + } catch Error(string memory reason) { + console.log("upgradeAndSetGasPayingToken() failed:", reason); + revert("Failed to call upgradeAndSetGasPayingToken"); + } + + // Step 7: Verify the upgrade + _verifyUpgrade(upgradedSystemConfig); + + vm.stopBroadcast(); + + console.log("\n=== SystemConfig V4 Upgrade Completed Successfully ==="); + } + + /// @notice Log the current state before upgrade + function _logCurrentState() internal view { + SystemConfig currentSystemConfig = SystemConfig(systemConfigProxy); + + console.log("\n--- Current SystemConfig State ---"); + console.log("Current version:", currentSystemConfig.version()); + console.log("Current init version:", currentSystemConfig.initVersion()); + + (address currentGasToken, uint8 currentDecimals) = currentSystemConfig.gasPayingToken(); + console.log("Current gas token:", currentGasToken); + console.log("Current gas token decimals:", currentDecimals); + + string memory tokenName = currentSystemConfig.gasPayingTokenName(); + string memory tokenSymbol = currentSystemConfig.gasPayingTokenSymbol(); + console.log("Current gas token name:", tokenName); + console.log("Current gas token symbol:", tokenSymbol); + + bool isCustomGasToken = currentSystemConfig.isCustomGasToken(); + console.log("Is custom gas token:", isCustomGasToken); + } + + /// @notice Verify the upgrade was successful + function _verifyUpgrade(SystemConfigV4 upgradedSystemConfig) internal view { + console.log("\n--- Verifying Upgrade Results ---"); + + // Check version updated + string memory newVersion = upgradedSystemConfig.version(); + require( + keccak256(bytes(newVersion)) == keccak256(bytes("3.12.0")), + "Version not updated correctly" + ); + + // Check init version updated + uint8 newInitVersion = upgradedSystemConfig.initVersion(); + require(newInitVersion == 4, "Init version not updated correctly"); + + // Check gas paying token is set to adapter + (address newGasToken, uint8 newDecimals) = upgradedSystemConfig.gasPayingToken(); + console.log("New gas token:", newGasToken); + console.log("New gas token decimals:", newDecimals); + require(newGasToken == address(adapter), "FAILED: Token address should be adapter"); + require(newDecimals == okbToken.decimals(), "FAILED: Token decimals mismatch"); + + // Check token metadata matches OKB + string memory newTokenName = upgradedSystemConfig.gasPayingTokenName(); + string memory newTokenSymbol = upgradedSystemConfig.gasPayingTokenSymbol(); + console.log("New gas token name:", newTokenName); + console.log("New gas token symbol:", newTokenSymbol); + require( + keccak256(abi.encodePacked(newTokenName)) == keccak256(abi.encodePacked(okbToken.name())), + "FAILED: Token name mismatch" + ); + require( + keccak256(abi.encodePacked(newTokenSymbol)) == keccak256(abi.encodePacked(okbToken.symbol())), + "FAILED: Token symbol mismatch" + ); + + // Verify custom gas token flag is true + bool isCustomGasToken = upgradedSystemConfig.isCustomGasToken(); + require(isCustomGasToken, "Custom gas token flag should be true"); + + // Check DepositedOKBAdapter configuration + require(address(adapter.OKB()) == okbTokenAddress, "FAILED: Adapter OKB mismatch"); + require(address(adapter.PORTAL()) == optimismPortalProxy, "FAILED: Adapter portal mismatch"); + require(adapter.owner() == deployerAddress, "FAILED: Adapter owner mismatch"); + + // Check adapter has preminted total supply + uint256 adapterBalance = adapter.balanceOf(address(adapter)); + uint256 expectedBalance = okbToken.totalSupply(); + console.log("Adapter balance:", adapterBalance); + console.log("Expected balance (OKB total supply):", expectedBalance); + require(adapterBalance == expectedBalance, "FAILED: Adapter balance should equal OKB total supply"); + + // Check whitelist configuration + console.log("Verifying deployer whitelist..."); + require(adapter.whitelist(deployerAddress), "FAILED: Deployer address not whitelisted"); + console.log("Deployer whitelist verified:", deployerAddress); + + // Check Adapter approval to portal (should be zero initially) + uint256 allowance = adapter.allowance(address(adapter), optimismPortalProxy); + console.log("Adapter approval to Portal:", allowance); + require(allowance == 0, "FAILED: Adapter should not pre-approve portal"); + + console.log("All upgrade verifications passed!"); + } +} From 31f6c912e20c5030754afda3b127dd2551100e53 Mon Sep 17 00:00:00 2001 From: "jason.huang" <20609724+doutv@users.noreply.github.com> Date: Tue, 21 Oct 2025 14:21:03 +0800 Subject: [PATCH 02/26] Upgrade okb adapter success - Updated the UpgradeSystemConfigToV4 script to include the Transactor for atomic upgrades and initialization of the SystemConfig to V4. - Added validation for the ownership chain to ensure the Transactor owns the ProxyAdmin before proceeding with the upgrade. - Enhanced configuration validation to include checks for the Transactor address and improved logging for better traceability. - Introduced a new shell script for upgrading the SystemConfig and deploying the DepositedOKBAdapter, streamlining the upgrade process. --- .../scripts/UpgradeSystemConfigToV4.s.sol | 169 +++++++++++++++--- test/upgrade-contracts/upgrade-okb-adapter.sh | 24 +++ 2 files changed, 165 insertions(+), 28 deletions(-) create mode 100755 test/upgrade-contracts/upgrade-okb-adapter.sh diff --git a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol index 52b08da4a313c..21718f3c8799c 100644 --- a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol +++ b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol @@ -3,32 +3,36 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; -import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfigV4 } from "scripts/SystemConfigV4.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IOKB } from "interfaces/L1/IOKB.sol"; import { DepositedOKBAdapter } from "src/L1/DepositedOKBAdapter.sol"; +import { Transactor } from "src/periphery/Transactor.sol"; +import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; /// @title UpgradeSystemConfigToV4 -/// @notice Custom script to upgrade SystemConfig to V4 and set OKB adapter as gas paying token +/// @notice Custom script to upgrade SystemConfig to V4 and set OKB adapter as gas paying token via Transactor /// @dev This script: -/// 1. Reads OKB token address from environment variable -/// 2. Deploys DepositedOKBAdapter that handles OKB burning internally -/// 3. Adds deployer address to whitelist for deposits -/// 4. Upgrades SystemConfig to V4 -/// 5. Sets OKB adapter as gas paying token in SystemConfig storage +/// 1. Reads OKB token address and Transactor address from environment variables +/// 2. Validates ownership chain (Transactor owns ProxyAdmin, ProxyAdmin controls SystemConfig) +/// 3. Deploys DepositedOKBAdapter that handles OKB burning internally +/// 4. Adds deployer address to whitelist for deposits +/// 5. Atomically upgrades SystemConfig to V4 and sets OKB adapter via ProxyAdmin.upgradeAndCall() /// 6. Verifies all configurations on L1 +/// 7. Verifies reinitializer protection prevents multiple calls to upgradeAndSetGasPayingToken() contract UpgradeSystemConfigToV4 is Script { // Environment variable names string constant SYSTEM_CONFIG_PROXY = "SYSTEM_CONFIG_PROXY_ADDRESS"; - string constant PROXY_ADMIN = "PROXY_ADMIN"; + string constant PROXY_ADMIN = "OP_PROXY_ADMIN"; + string constant TRANSACTOR = "TRANSACTOR"; string constant OKB_TOKEN_ADDRESS = "OKB_TOKEN_ADDRESS"; string constant OPTIMISM_PORTAL_PROXY = "OPTIMISM_PORTAL_PROXY_ADDRESS"; // State variables for configuration address systemConfigProxy; address proxyAdmin; + address transactorAddress; address okbTokenAddress; address optimismPortalProxy; address deployerAddress; @@ -36,6 +40,7 @@ contract UpgradeSystemConfigToV4 is Script { // Deployed contracts IOKB okbToken; DepositedOKBAdapter adapter; + Transactor transactor; /// @notice Main upgrade function function run() external { @@ -52,6 +57,7 @@ contract UpgradeSystemConfigToV4 is Script { // Load addresses from environment systemConfigProxy = vm.envAddress(SYSTEM_CONFIG_PROXY); proxyAdmin = vm.envAddress(PROXY_ADMIN); + transactorAddress = vm.envAddress(TRANSACTOR); okbTokenAddress = vm.envAddress(OKB_TOKEN_ADDRESS); optimismPortalProxy = vm.envAddress(OPTIMISM_PORTAL_PROXY); @@ -59,17 +65,20 @@ contract UpgradeSystemConfigToV4 is Script { console.log("Deployer address:", deployerAddress); console.log("SystemConfig Proxy:", systemConfigProxy); console.log("ProxyAdmin:", proxyAdmin); + console.log("Transactor:", transactorAddress); console.log("OKB Token Address:", okbTokenAddress); console.log("OptimismPortal Proxy:", optimismPortalProxy); - // Initialize OKB token interface + // Initialize contract interfaces okbToken = IOKB(okbTokenAddress); + transactor = Transactor(transactorAddress); } /// @notice Validate the configuration before proceeding function _validateConfiguration() internal view { require(systemConfigProxy != address(0), "SystemConfig proxy address cannot be zero"); require(proxyAdmin != address(0), "ProxyAdmin address cannot be zero"); + require(transactorAddress != address(0), "Transactor address cannot be zero"); require(okbTokenAddress != address(0), "OKB token address cannot be zero"); require(optimismPortalProxy != address(0), "OptimismPortal proxy address cannot be zero"); require(deployerAddress != address(0), "Deployer address cannot be zero"); @@ -83,6 +92,10 @@ contract UpgradeSystemConfigToV4 is Script { proxyAdmin.code.length > 0, "ProxyAdmin must have code (not an EOA)" ); + require( + transactorAddress.code.length > 0, + "Transactor must have code (not an EOA)" + ); require( okbTokenAddress.code.length > 0, "OKB token must have code (not an EOA)" @@ -91,6 +104,40 @@ contract UpgradeSystemConfigToV4 is Script { optimismPortalProxy.code.length > 0, "OptimismPortal proxy must have code (not an EOA)" ); + + // Verify ownership chain for upgrade permissions + _validateOwnershipChain(); + } + + /// @notice Validate the ownership chain for upgrade permissions + function _validateOwnershipChain() internal view { + console.log("\n--- Validating Ownership Chain ---"); + + // Check ProxyAdmin owner + IProxyAdmin admin = IProxyAdmin(proxyAdmin); + address proxyAdminOwner = admin.owner(); + console.log("ProxyAdmin owner:", proxyAdminOwner); + console.log("Transactor address:", transactorAddress); + + // Verify Transactor owns ProxyAdmin + require( + proxyAdminOwner == transactorAddress, + "Transactor must be the owner of ProxyAdmin" + ); + + // Check SystemConfig proxy admin + ISystemConfig systemConfigContract = ISystemConfig(systemConfigProxy); + address systemConfigAdmin = address(systemConfigContract.proxyAdmin()); + console.log("SystemConfig proxy admin:", systemConfigAdmin); + console.log("Expected ProxyAdmin:", proxyAdmin); + + // Verify ProxyAdmin controls SystemConfig proxy + require( + systemConfigAdmin == proxyAdmin, + "ProxyAdmin must be the admin of SystemConfig proxy" + ); + + console.log("Ownership chain validated successfully"); } /// @notice Deploy DepositedOKBAdapter @@ -132,28 +179,45 @@ contract UpgradeSystemConfigToV4 is Script { // Step 4: Setup whitelist for deployer _setupWhitelist(); - // Step 5: Upgrade the proxy to point to new implementation - console.log("\n--- Upgrading Proxy Implementation ---"); - IProxyAdmin admin = IProxyAdmin(proxyAdmin); - admin.upgrade(payable(systemConfigProxy), address(newImplementation)); - console.log("Proxy upgraded successfully"); - - // Step 6: Call the upgrade function to set OKB adapter as gas paying token - console.log("\n--- Setting OKB Adapter as Gas Paying Token ---"); - SystemConfigV4 upgradedSystemConfig = SystemConfigV4(systemConfigProxy); + // Step 5: Upgrade proxy and call upgradeAndSetGasPayingToken atomically + console.log("\n--- Upgrading and Initializing SystemConfig V4 via Transactor ---"); // Convert string to bytes32 for SystemConfig function bytes32 nameBytes32 = bytes32(bytes(okbToken.name())); bytes32 symbolBytes32 = bytes32(bytes(okbToken.symbol())); - try upgradedSystemConfig.upgradeAndSetGasPayingToken(address(adapter), okbToken.decimals(), nameBytes32, symbolBytes32) { - console.log("upgradeAndSetGasPayingToken() called successfully"); - } catch Error(string memory reason) { - console.log("upgradeAndSetGasPayingToken() failed:", reason); - revert("Failed to call upgradeAndSetGasPayingToken"); - } + // Encode the upgradeAndSetGasPayingToken() call data + bytes memory initCalldata = abi.encodeWithSelector( + SystemConfigV4.upgradeAndSetGasPayingToken.selector, + address(adapter), + okbToken.decimals(), + nameBytes32, + symbolBytes32 + ); - // Step 7: Verify the upgrade + // Encode the ProxyAdmin.upgradeAndCall() call + bytes memory upgradeAndCallData = abi.encodeWithSelector( + IProxyAdmin.upgradeAndCall.selector, + payable(systemConfigProxy), + address(newImplementation), + initCalldata + ); + + console.log("Calling ProxyAdmin.upgradeAndCall() via Transactor.CALL()"); + console.log("This atomically upgrades and initializes the SystemConfig"); + + // Call ProxyAdmin.upgradeAndCall() through Transactor.CALL() + (bool success,) = transactor.CALL( + proxyAdmin, + upgradeAndCallData, + 0 // no ETH value + ); + require(success, "Transactor CALL to ProxyAdmin.upgradeAndCall failed"); + console.log("Atomic upgrade and initialization completed successfully"); + + SystemConfigV4 upgradedSystemConfig = SystemConfigV4(systemConfigProxy); + + // Step 6: Verify the upgrade _verifyUpgrade(upgradedSystemConfig); vm.stopBroadcast(); @@ -163,14 +227,14 @@ contract UpgradeSystemConfigToV4 is Script { /// @notice Log the current state before upgrade function _logCurrentState() internal view { - SystemConfig currentSystemConfig = SystemConfig(systemConfigProxy); + ISystemConfig currentSystemConfig = ISystemConfig(systemConfigProxy); console.log("\n--- Current SystemConfig State ---"); console.log("Current version:", currentSystemConfig.version()); console.log("Current init version:", currentSystemConfig.initVersion()); (address currentGasToken, uint8 currentDecimals) = currentSystemConfig.gasPayingToken(); - console.log("Current gas token:", currentGasToken); + console.log("Current gas token (DepositedOKBAdapter):", currentGasToken); console.log("Current gas token decimals:", currentDecimals); string memory tokenName = currentSystemConfig.gasPayingTokenName(); @@ -183,7 +247,7 @@ contract UpgradeSystemConfigToV4 is Script { } /// @notice Verify the upgrade was successful - function _verifyUpgrade(SystemConfigV4 upgradedSystemConfig) internal view { + function _verifyUpgrade(SystemConfigV4 upgradedSystemConfig) internal { console.log("\n--- Verifying Upgrade Results ---"); // Check version updated @@ -244,6 +308,55 @@ contract UpgradeSystemConfigToV4 is Script { console.log("Adapter approval to Portal:", allowance); require(allowance == 0, "FAILED: Adapter should not pre-approve portal"); + // Verify reinitializer protection - upgradeAndSetGasPayingToken should not be callable again + _verifyReinitializerProtection(upgradedSystemConfig); + console.log("All upgrade verifications passed!"); } + + /// @notice Verify that upgradeAndSetGasPayingToken cannot be called again due to reinitializer protection + function _verifyReinitializerProtection(SystemConfigV4 _systemConfig) internal { + console.log("\n--- Verifying Reinitializer Protection ---"); + + // Try to call upgradeAndSetGasPayingToken again - this should fail + console.log("Testing reinitializer protection..."); + + // Encode another call to upgradeAndSetGasPayingToken with different parameters + bytes memory secondCalldata = abi.encodeWithSelector( + SystemConfigV4.upgradeAndSetGasPayingToken.selector, + address(0x1234), // dummy address + 18, // dummy decimals + bytes32("Test"), // dummy name + bytes32("TST") // dummy symbol + ); + + console.log("Attempting second call to upgradeAndSetGasPayingToken via Transactor..."); + + // This call should fail due to reinitializer protection + try transactor.CALL(address(_systemConfig), secondCalldata, 0) returns (bool success, bytes memory) { + require(!success, "FAILED: Second call to upgradeAndSetGasPayingToken should have failed but succeeded"); + console.log("Reinitializer protection verified: Second call failed as expected"); + } catch { + console.log("Reinitializer protection verified: Second call reverted as expected"); + } + + // Also try calling it directly (this should also fail) + console.log("Attempting direct call to upgradeAndSetGasPayingToken..."); + + try _systemConfig.upgradeAndSetGasPayingToken( + address(0x1234), + 18, + bytes32("Test"), + bytes32("TST") + ) { + revert("FAILED: Direct call to upgradeAndSetGasPayingToken should have failed but succeeded"); + } catch Error(string memory reason) { + console.log("Direct call failed as expected with reason:"); + console.log(" ", reason); + } catch { + console.log("Direct call reverted as expected (low-level revert)"); + } + + console.log("Reinitializer protection verification completed"); + } } diff --git a/test/upgrade-contracts/upgrade-okb-adapter.sh b/test/upgrade-contracts/upgrade-okb-adapter.sh new file mode 100755 index 0000000000000..107d00bc8146f --- /dev/null +++ b/test/upgrade-contracts/upgrade-okb-adapter.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +ROOT_DIR=$(git rev-parse --show-toplevel) + +cd $ROOT_DIR + +STATE_JSON="$ROOT_DIR/test/config-op/state.json" +OP_PROXY_ADMIN=$(jq -r '.opChainDeployments[0].OpChainProxyAdminImpl' "$STATE_JSON") + +source test/.env + +echo "🔧 Upgrading SystemConfig, deploying new DepositedOKBAdapter, and updating SystemConfig to use it as gas paying token..." +cd $ROOT_DIR/packages/contracts-bedrock +export SYSTEM_CONFIG_PROXY_ADDRESS=$SYSTEM_CONFIG_PROXY_ADDRESS +export OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS +export OKB_TOKEN_ADDRESS=$OKB_TOKEN_ADDRESS +export OP_PROXY_ADMIN=$OP_PROXY_ADMIN +export TRANSACTOR=$TRANSACTOR + +forge script scripts/UpgradeSystemConfigToV4.s.sol:UpgradeSystemConfigToV4 \ + --rpc-url $L1_RPC_URL \ + --private-key $DEPLOYER_PRIVATE_KEY \ + --broadcast From f482c9e36a1fc9e4027b4884c818d94c28f8e8aa Mon Sep 17 00:00:00 2001 From: "jason.huang" <20609724+doutv@users.noreply.github.com> Date: Thu, 23 Oct 2025 10:57:00 +0800 Subject: [PATCH 03/26] Refactor UpgradeSystemConfigToV4 script to streamline deployment process and update upgrade-okb-adapter.sh to source environment variables correctly. --- .../contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol | 4 ++-- test/upgrade-contracts/upgrade-okb-adapter.sh | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol index 21718f3c8799c..f33b142cf3052 100644 --- a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol +++ b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol @@ -165,14 +165,14 @@ contract UpgradeSystemConfigToV4 is Script { _logCurrentState(); // Step 2: Deploy new SystemConfigV4 implementation + vm.startBroadcast(); + console.log("\n--- Deploying SystemConfigV4 Implementation ---"); SystemConfigV4 newImplementation = new SystemConfigV4(); console.log("SystemConfigV4 deployed at:", address(newImplementation)); console.log("New implementation version:", newImplementation.version()); console.log("New init version:", newImplementation.initVersion()); - vm.startBroadcast(); - // Step 3: Deploy DepositedOKBAdapter _deployAdapter(); diff --git a/test/upgrade-contracts/upgrade-okb-adapter.sh b/test/upgrade-contracts/upgrade-okb-adapter.sh index 107d00bc8146f..517062286e3ae 100755 --- a/test/upgrade-contracts/upgrade-okb-adapter.sh +++ b/test/upgrade-contracts/upgrade-okb-adapter.sh @@ -5,10 +5,12 @@ ROOT_DIR=$(git rev-parse --show-toplevel) cd $ROOT_DIR +source test/.env + STATE_JSON="$ROOT_DIR/test/config-op/state.json" OP_PROXY_ADMIN=$(jq -r '.opChainDeployments[0].OpChainProxyAdminImpl' "$STATE_JSON") - -source test/.env +SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].SystemConfigProxy' "$STATE_JSON") +OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy' "$STATE_JSON") echo "🔧 Upgrading SystemConfig, deploying new DepositedOKBAdapter, and updating SystemConfig to use it as gas paying token..." cd $ROOT_DIR/packages/contracts-bedrock From c7369e16a4782cc995a1466ea3251f40e584e115 Mon Sep 17 00:00:00 2001 From: "jason.huang" <20609724+doutv@users.noreply.github.com> Date: Thu, 23 Oct 2025 17:33:28 +0800 Subject: [PATCH 04/26] Refactor UpgradeSystemConfigToV4 script by removing whitelist setup for deployer and adjusting upgrade steps. Streamlined upgrade process to focus on atomic upgrade and verification of SystemConfig V4 without whitelist checks. --- .../scripts/UpgradeSystemConfigToV4.s.sol | 29 ++++--------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol index f33b142cf3052..f2154f6f4ddac 100644 --- a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol +++ b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol @@ -16,10 +16,9 @@ import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; /// 1. Reads OKB token address and Transactor address from environment variables /// 2. Validates ownership chain (Transactor owns ProxyAdmin, ProxyAdmin controls SystemConfig) /// 3. Deploys DepositedOKBAdapter that handles OKB burning internally -/// 4. Adds deployer address to whitelist for deposits -/// 5. Atomically upgrades SystemConfig to V4 and sets OKB adapter via ProxyAdmin.upgradeAndCall() -/// 6. Verifies all configurations on L1 -/// 7. Verifies reinitializer protection prevents multiple calls to upgradeAndSetGasPayingToken() +/// 4. Atomically upgrades SystemConfig to V4 and sets OKB adapter via ProxyAdmin.upgradeAndCall() +/// 5. Verifies all configurations on L1 +/// 6. Verifies reinitializer protection prevents multiple calls to upgradeAndSetGasPayingToken() contract UpgradeSystemConfigToV4 is Script { // Environment variable names @@ -147,16 +146,6 @@ contract UpgradeSystemConfigToV4 is Script { console.log("DepositedOKBAdapter deployed at:", address(adapter)); } - /// @notice Set up whitelist for authorized depositors - function _setupWhitelist() internal { - console.log("\n--- Setting up Whitelist ---"); - console.log("Adding deployer to whitelist..."); - address[] memory addresses = new address[](1); - addresses[0] = deployerAddress; - adapter.addToWhitelistBatch(addresses); - console.log("Deployer whitelisted successfully:", deployerAddress); - } - /// @notice Perform the complete upgrade process function _performUpgrade() internal { console.log("\n=== Starting SystemConfig V4 Upgrade ==="); @@ -176,10 +165,7 @@ contract UpgradeSystemConfigToV4 is Script { // Step 3: Deploy DepositedOKBAdapter _deployAdapter(); - // Step 4: Setup whitelist for deployer - _setupWhitelist(); - - // Step 5: Upgrade proxy and call upgradeAndSetGasPayingToken atomically + // Step 4: Upgrade proxy and call upgradeAndSetGasPayingToken atomically console.log("\n--- Upgrading and Initializing SystemConfig V4 via Transactor ---"); // Convert string to bytes32 for SystemConfig function @@ -217,7 +203,7 @@ contract UpgradeSystemConfigToV4 is Script { SystemConfigV4 upgradedSystemConfig = SystemConfigV4(systemConfigProxy); - // Step 6: Verify the upgrade + // Step 5: Verify the upgrade _verifyUpgrade(upgradedSystemConfig); vm.stopBroadcast(); @@ -298,11 +284,6 @@ contract UpgradeSystemConfigToV4 is Script { console.log("Expected balance (OKB total supply):", expectedBalance); require(adapterBalance == expectedBalance, "FAILED: Adapter balance should equal OKB total supply"); - // Check whitelist configuration - console.log("Verifying deployer whitelist..."); - require(adapter.whitelist(deployerAddress), "FAILED: Deployer address not whitelisted"); - console.log("Deployer whitelist verified:", deployerAddress); - // Check Adapter approval to portal (should be zero initially) uint256 allowance = adapter.allowance(address(adapter), optimismPortalProxy); console.log("Adapter approval to Portal:", allowance); From 86f76e01e0b5e9f1eb3b05c28f0c26dacc2c554c Mon Sep 17 00:00:00 2001 From: "jason.huang" <20609724+doutv@users.noreply.github.com> Date: Thu, 23 Oct 2025 18:49:28 +0800 Subject: [PATCH 05/26] Update SystemConfigV4 constructor version and modify gas paying token function access control. The constructor now initializes with version 3, and the `setGasPayingToken` function can be called by the ProxyAdmin or its owner instead of just the contract owner. Additionally, removed the deprecated `upgradeAndSetGasPayingToken` function and updated the UpgradeSystemConfigToV4 script to reflect these changes, including adjustments to environment variable handling for the adapter owner address. --- .../scripts/SystemConfigV4.sol | 21 ++----- .../scripts/UpgradeSystemConfigToV4.s.sol | 62 +++---------------- test/upgrade-contracts/upgrade-okb-adapter.sh | 1 + 3 files changed, 15 insertions(+), 69 deletions(-) diff --git a/packages/contracts-bedrock/scripts/SystemConfigV4.sol b/packages/contracts-bedrock/scripts/SystemConfigV4.sol index e38a5fe45bfe6..a539af4ec68fd 100644 --- a/packages/contracts-bedrock/scripts/SystemConfigV4.sol +++ b/packages/contracts-bedrock/scripts/SystemConfigV4.sol @@ -174,7 +174,7 @@ contract SystemConfigV4 is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitializa /// @notice Constructs the SystemConfig contract. /// @dev START_BLOCK_SLOT is set to type(uint256).max here so that it will be a dead value /// in the singleton. - constructor() ReinitializableBase(4) { + constructor() ReinitializableBase(3) { Storage.setUint(START_BLOCK_SLOT, type(uint256).max); _disableInitializers(); } @@ -597,16 +597,14 @@ contract SystemConfigV4 is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitializa symbol_ = GasPayingToken.getSymbol(); } - /// @notice Sets the gas paying token and its metadata. Can only be called by the owner. + /// @notice Sets the gas paying token and its metadata. Can only be called by the ProxyAdmin or its owner. /// @param _token The address of the gas paying token. /// @param _decimals The decimals of the gas paying token. /// @param _name The name of the gas paying token as a bytes32. /// @param _symbol The symbol of the gas paying token as a bytes32. - function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external onlyOwner { - (address gasToken,) = gasPayingToken(); - if (gasToken != Constants.ETHER) { - revert SystemConfig_ValueAlreadySet(); - } + function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external { + _assertOnlyProxyAdminOrProxyAdminOwner(); + _setGasPayingToken(_token, _decimals, _name, _symbol); } @@ -619,13 +617,4 @@ contract SystemConfigV4 is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitializa GasPayingToken.set(_token, _decimals, _name, _symbol); } - /// @notice Upgrade function that resets the gas paying token to allow setting it once more. - /// This preserves the existing "set once" logic while allowing a fresh start. - /// @dev This function can only be called during the upgrade process via reinitializer(4). - function upgradeAndSetGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external reinitializer(initVersion()) { - // Must be called by ProxyAdmin or its owner - _assertOnlyProxyAdminOrProxyAdminOwner(); - - _setGasPayingToken(_token, _decimals, _name, _symbol); - } } diff --git a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol index f2154f6f4ddac..5dac3a9c63f3b 100644 --- a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol +++ b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol @@ -18,7 +18,7 @@ import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; /// 3. Deploys DepositedOKBAdapter that handles OKB burning internally /// 4. Atomically upgrades SystemConfig to V4 and sets OKB adapter via ProxyAdmin.upgradeAndCall() /// 5. Verifies all configurations on L1 -/// 6. Verifies reinitializer protection prevents multiple calls to upgradeAndSetGasPayingToken() +/// 6. Verifies reinitializer protection contract UpgradeSystemConfigToV4 is Script { // Environment variable names @@ -27,6 +27,7 @@ contract UpgradeSystemConfigToV4 is Script { string constant TRANSACTOR = "TRANSACTOR"; string constant OKB_TOKEN_ADDRESS = "OKB_TOKEN_ADDRESS"; string constant OPTIMISM_PORTAL_PROXY = "OPTIMISM_PORTAL_PROXY_ADDRESS"; + string constant OKB_ADAPTER_OWNER_ADDRESS = "OKB_ADAPTER_OWNER_ADDRESS"; // State variables for configuration address systemConfigProxy; @@ -35,6 +36,7 @@ contract UpgradeSystemConfigToV4 is Script { address okbTokenAddress; address optimismPortalProxy; address deployerAddress; + address adatperOwnerAddress; // Deployed contracts IOKB okbToken; @@ -59,6 +61,7 @@ contract UpgradeSystemConfigToV4 is Script { transactorAddress = vm.envAddress(TRANSACTOR); okbTokenAddress = vm.envAddress(OKB_TOKEN_ADDRESS); optimismPortalProxy = vm.envAddress(OPTIMISM_PORTAL_PROXY); + adatperOwnerAddress = vm.envAddress(OKB_ADAPTER_OWNER_ADDRESS); console.log("=== Upgrade Configuration ==="); console.log("Deployer address:", deployerAddress); @@ -67,6 +70,7 @@ contract UpgradeSystemConfigToV4 is Script { console.log("Transactor:", transactorAddress); console.log("OKB Token Address:", okbTokenAddress); console.log("OptimismPortal Proxy:", optimismPortalProxy); + console.log("OKB Adapter Owner Address:", adatperOwnerAddress); // Initialize contract interfaces okbToken = IOKB(okbTokenAddress); @@ -81,6 +85,7 @@ contract UpgradeSystemConfigToV4 is Script { require(okbTokenAddress != address(0), "OKB token address cannot be zero"); require(optimismPortalProxy != address(0), "OptimismPortal proxy address cannot be zero"); require(deployerAddress != address(0), "Deployer address cannot be zero"); + require(adatperOwnerAddress != address(0), "OKB Adapter owner address cannot be zero"); // Verify contracts have code require( @@ -142,7 +147,7 @@ contract UpgradeSystemConfigToV4 is Script { /// @notice Deploy DepositedOKBAdapter function _deployAdapter() internal { console.log("\n--- Deploying DepositedOKBAdapter ---"); - adapter = new DepositedOKBAdapter(okbTokenAddress, payable(optimismPortalProxy), deployerAddress); + adapter = new DepositedOKBAdapter(okbTokenAddress, payable(optimismPortalProxy), adatperOwnerAddress); console.log("DepositedOKBAdapter deployed at:", address(adapter)); } @@ -174,7 +179,7 @@ contract UpgradeSystemConfigToV4 is Script { // Encode the upgradeAndSetGasPayingToken() call data bytes memory initCalldata = abi.encodeWithSelector( - SystemConfigV4.upgradeAndSetGasPayingToken.selector, + SystemConfigV4.setGasPayingToken.selector, address(adapter), okbToken.decimals(), nameBytes32, @@ -245,7 +250,7 @@ contract UpgradeSystemConfigToV4 is Script { // Check init version updated uint8 newInitVersion = upgradedSystemConfig.initVersion(); - require(newInitVersion == 4, "Init version not updated correctly"); + require(newInitVersion == 3, "Init version not updated correctly"); // Check gas paying token is set to adapter (address newGasToken, uint8 newDecimals) = upgradedSystemConfig.gasPayingToken(); @@ -289,55 +294,6 @@ contract UpgradeSystemConfigToV4 is Script { console.log("Adapter approval to Portal:", allowance); require(allowance == 0, "FAILED: Adapter should not pre-approve portal"); - // Verify reinitializer protection - upgradeAndSetGasPayingToken should not be callable again - _verifyReinitializerProtection(upgradedSystemConfig); - console.log("All upgrade verifications passed!"); } - - /// @notice Verify that upgradeAndSetGasPayingToken cannot be called again due to reinitializer protection - function _verifyReinitializerProtection(SystemConfigV4 _systemConfig) internal { - console.log("\n--- Verifying Reinitializer Protection ---"); - - // Try to call upgradeAndSetGasPayingToken again - this should fail - console.log("Testing reinitializer protection..."); - - // Encode another call to upgradeAndSetGasPayingToken with different parameters - bytes memory secondCalldata = abi.encodeWithSelector( - SystemConfigV4.upgradeAndSetGasPayingToken.selector, - address(0x1234), // dummy address - 18, // dummy decimals - bytes32("Test"), // dummy name - bytes32("TST") // dummy symbol - ); - - console.log("Attempting second call to upgradeAndSetGasPayingToken via Transactor..."); - - // This call should fail due to reinitializer protection - try transactor.CALL(address(_systemConfig), secondCalldata, 0) returns (bool success, bytes memory) { - require(!success, "FAILED: Second call to upgradeAndSetGasPayingToken should have failed but succeeded"); - console.log("Reinitializer protection verified: Second call failed as expected"); - } catch { - console.log("Reinitializer protection verified: Second call reverted as expected"); - } - - // Also try calling it directly (this should also fail) - console.log("Attempting direct call to upgradeAndSetGasPayingToken..."); - - try _systemConfig.upgradeAndSetGasPayingToken( - address(0x1234), - 18, - bytes32("Test"), - bytes32("TST") - ) { - revert("FAILED: Direct call to upgradeAndSetGasPayingToken should have failed but succeeded"); - } catch Error(string memory reason) { - console.log("Direct call failed as expected with reason:"); - console.log(" ", reason); - } catch { - console.log("Direct call reverted as expected (low-level revert)"); - } - - console.log("Reinitializer protection verification completed"); - } } diff --git a/test/upgrade-contracts/upgrade-okb-adapter.sh b/test/upgrade-contracts/upgrade-okb-adapter.sh index 517062286e3ae..ce2097e85eca5 100755 --- a/test/upgrade-contracts/upgrade-okb-adapter.sh +++ b/test/upgrade-contracts/upgrade-okb-adapter.sh @@ -19,6 +19,7 @@ export OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS export OKB_TOKEN_ADDRESS=$OKB_TOKEN_ADDRESS export OP_PROXY_ADMIN=$OP_PROXY_ADMIN export TRANSACTOR=$TRANSACTOR +export OKB_ADAPTER_OWNER_ADDRESS=$OKB_ADAPTER_OWNER_ADDRESS forge script scripts/UpgradeSystemConfigToV4.s.sol:UpgradeSystemConfigToV4 \ --rpc-url $L1_RPC_URL \ From 9b62d34b5b72c9b9c062819d5f2ce0de6a290b85 Mon Sep 17 00:00:00 2001 From: "jason.huang" <20609724+doutv@users.noreply.github.com> Date: Fri, 24 Oct 2025 11:50:18 +0800 Subject: [PATCH 06/26] Add SystemConfigV312 contract and upgrade script for OKB adapter integration - Introduced SystemConfigV312 contract to manage Optimism network configurations. - Implemented UpgradeSystemConfig script to upgrade to SystemConfigV312 and set the OKB adapter as the gas paying token. - Enhanced upgrade process with validation checks and logging for better traceability. - Updated upgrade script to handle environment variables for configuration and ownership validation. - Modified upgrade-okb-adapter.sh to query adapter address and OKB token address dynamically. --- ...ystemConfigV4.sol => SystemConfigV312.sol} | 9 +++--- ....s.sol => UpgradeSystemConfigToV312.s.sol} | 32 +++++++++---------- test/upgrade-contracts/upgrade-okb-adapter.sh | 15 +++++++++ 3 files changed, 36 insertions(+), 20 deletions(-) rename packages/contracts-bedrock/scripts/{SystemConfigV4.sol => SystemConfigV312.sol} (98%) rename packages/contracts-bedrock/scripts/{UpgradeSystemConfigToV4.s.sol => UpgradeSystemConfigToV312.s.sol} (91%) diff --git a/packages/contracts-bedrock/scripts/SystemConfigV4.sol b/packages/contracts-bedrock/scripts/SystemConfigV312.sol similarity index 98% rename from packages/contracts-bedrock/scripts/SystemConfigV4.sol rename to packages/contracts-bedrock/scripts/SystemConfigV312.sol index a539af4ec68fd..138d1d4525ea3 100644 --- a/packages/contracts-bedrock/scripts/SystemConfigV4.sol +++ b/packages/contracts-bedrock/scripts/SystemConfigV312.sol @@ -19,11 +19,12 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IGasToken } from "src/libraries/GasPayingToken.sol"; /// @custom:proxied true -/// @title SystemConfigV4 -/// @notice The SystemConfigV4 contract is used to manage configuration of an Optimism network. +/// @title SystemConfigV312 +/// @notice The SystemConfigV312 contract is used to manage configuration of an Optimism network. /// All configuration is stored on L1 and picked up by L2 as part of the derviation of /// the L2 chain. -contract SystemConfigV4 is ProxyAdminOwnedBase, OwnableUpgradeable, ReinitializableBase, ISemver, IGasToken { +/// @dev Purpuse: upgrade DevNet OKB adapter +contract SystemConfigV312 is ProxyAdminOwnedBase, OwnableUpgradeable, ReinitializableBase, ISemver, IGasToken { /// @notice Enum representing different types of updates. /// @custom:value BATCHER Represents an update to the batcher hash. /// @custom:value FEE_SCALARS Represents an update to l1 data fee scalars. @@ -202,7 +203,7 @@ contract SystemConfigV4 is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitializa address _unsafeBlockSigner, IResourceMetering.ResourceConfig memory _config, address _batchInbox, - SystemConfigV4.Addresses memory _addresses, + SystemConfigV312.Addresses memory _addresses, uint256 _l2ChainId, ISuperchainConfig _superchainConfig ) diff --git a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV312.s.sol similarity index 91% rename from packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol rename to packages/contracts-bedrock/scripts/UpgradeSystemConfigToV312.s.sol index 5dac3a9c63f3b..a22936c9910aa 100644 --- a/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV4.s.sol +++ b/packages/contracts-bedrock/scripts/UpgradeSystemConfigToV312.s.sol @@ -3,23 +3,23 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; -import { SystemConfigV4 } from "scripts/SystemConfigV4.sol"; +import { SystemConfigV312 } from "scripts/SystemConfigV312.sol"; import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IOKB } from "interfaces/L1/IOKB.sol"; import { DepositedOKBAdapter } from "src/L1/DepositedOKBAdapter.sol"; import { Transactor } from "src/periphery/Transactor.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -/// @title UpgradeSystemConfigToV4 -/// @notice Custom script to upgrade SystemConfig to V4 and set OKB adapter as gas paying token via Transactor +/// @title UpgradeSystemConfig +/// @notice Custom script to upgrade SystemConfig to V3.12 and set OKB adapter as gas paying token via Transactor /// @dev This script: /// 1. Reads OKB token address and Transactor address from environment variables /// 2. Validates ownership chain (Transactor owns ProxyAdmin, ProxyAdmin controls SystemConfig) /// 3. Deploys DepositedOKBAdapter that handles OKB burning internally -/// 4. Atomically upgrades SystemConfig to V4 and sets OKB adapter via ProxyAdmin.upgradeAndCall() +/// 4. Atomically upgrades SystemConfig to V3.12 and sets OKB adapter via ProxyAdmin.upgradeAndCall() /// 5. Verifies all configurations on L1 /// 6. Verifies reinitializer protection -contract UpgradeSystemConfigToV4 is Script { +contract UpgradeSystemConfig is Script { // Environment variable names string constant SYSTEM_CONFIG_PROXY = "SYSTEM_CONFIG_PROXY_ADDRESS"; @@ -153,17 +153,17 @@ contract UpgradeSystemConfigToV4 is Script { /// @notice Perform the complete upgrade process function _performUpgrade() internal { - console.log("\n=== Starting SystemConfig V4 Upgrade ==="); + console.log("\n=== Starting SystemConfig V3.12 Upgrade ==="); // Step 1: Check current state _logCurrentState(); - // Step 2: Deploy new SystemConfigV4 implementation + // Step 2: Deploy new SystemConfigV312 implementation vm.startBroadcast(); - console.log("\n--- Deploying SystemConfigV4 Implementation ---"); - SystemConfigV4 newImplementation = new SystemConfigV4(); - console.log("SystemConfigV4 deployed at:", address(newImplementation)); + console.log("\n--- Deploying SystemConfigV312 Implementation ---"); + SystemConfigV312 newImplementation = new SystemConfigV312(); + console.log("SystemConfigV312 deployed at:", address(newImplementation)); console.log("New implementation version:", newImplementation.version()); console.log("New init version:", newImplementation.initVersion()); @@ -171,7 +171,7 @@ contract UpgradeSystemConfigToV4 is Script { _deployAdapter(); // Step 4: Upgrade proxy and call upgradeAndSetGasPayingToken atomically - console.log("\n--- Upgrading and Initializing SystemConfig V4 via Transactor ---"); + console.log("\n--- Upgrading and Initializing SystemConfig V3.12 via Transactor ---"); // Convert string to bytes32 for SystemConfig function bytes32 nameBytes32 = bytes32(bytes(okbToken.name())); @@ -179,7 +179,7 @@ contract UpgradeSystemConfigToV4 is Script { // Encode the upgradeAndSetGasPayingToken() call data bytes memory initCalldata = abi.encodeWithSelector( - SystemConfigV4.setGasPayingToken.selector, + SystemConfigV312.setGasPayingToken.selector, address(adapter), okbToken.decimals(), nameBytes32, @@ -206,14 +206,14 @@ contract UpgradeSystemConfigToV4 is Script { require(success, "Transactor CALL to ProxyAdmin.upgradeAndCall failed"); console.log("Atomic upgrade and initialization completed successfully"); - SystemConfigV4 upgradedSystemConfig = SystemConfigV4(systemConfigProxy); + SystemConfigV312 upgradedSystemConfig = SystemConfigV312(systemConfigProxy); // Step 5: Verify the upgrade _verifyUpgrade(upgradedSystemConfig); vm.stopBroadcast(); - console.log("\n=== SystemConfig V4 Upgrade Completed Successfully ==="); + console.log("\n=== SystemConfig V3.12 Upgrade Completed Successfully ==="); } /// @notice Log the current state before upgrade @@ -238,7 +238,7 @@ contract UpgradeSystemConfigToV4 is Script { } /// @notice Verify the upgrade was successful - function _verifyUpgrade(SystemConfigV4 upgradedSystemConfig) internal { + function _verifyUpgrade(SystemConfigV312 upgradedSystemConfig) internal { console.log("\n--- Verifying Upgrade Results ---"); // Check version updated @@ -248,7 +248,7 @@ contract UpgradeSystemConfigToV4 is Script { "Version not updated correctly" ); - // Check init version updated + // Check init version uint8 newInitVersion = upgradedSystemConfig.initVersion(); require(newInitVersion == 3, "Init version not updated correctly"); diff --git a/test/upgrade-contracts/upgrade-okb-adapter.sh b/test/upgrade-contracts/upgrade-okb-adapter.sh index ce2097e85eca5..731572d79d5c8 100755 --- a/test/upgrade-contracts/upgrade-okb-adapter.sh +++ b/test/upgrade-contracts/upgrade-okb-adapter.sh @@ -11,6 +11,21 @@ STATE_JSON="$ROOT_DIR/test/config-op/state.json" OP_PROXY_ADMIN=$(jq -r '.opChainDeployments[0].OpChainProxyAdminImpl' "$STATE_JSON") SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].SystemConfigProxy' "$STATE_JSON") OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy' "$STATE_JSON") +# Query ADAPTER_ADDRESS from SystemConfig.gasPayingToken() +ADAPTER_ADDRESS=$(cast call "$SYSTEM_CONFIG_PROXY_ADDRESS" "gasPayingToken()(address,uint8)" --rpc-url "$L1_RPC_URL" | head -n1) +if [ -z "$ADAPTER_ADDRESS" ] || [ "$ADAPTER_ADDRESS" = "0x0000000000000000000000000000000000000000" ]; then + echo "❌ ERROR: Could not query ADAPTER_ADDRESS from SystemConfig or CGT not configured" + echo " SystemConfig address: $SYSTEM_CONFIG_PROXY_ADDRESS" + exit 1 +fi + +# Query OKB_TOKEN_ADDRESS from the adapter +OKB_TOKEN_ADDRESS=$(cast call "$ADAPTER_ADDRESS" "OKB()(address)" --rpc-url "$L1_RPC_URL") +if [ -z "$OKB_TOKEN_ADDRESS" ] || [ "$OKB_TOKEN_ADDRESS" = "0x0000000000000000000000000000000000000000" ]; then + echo "❌ ERROR: Could not query OKB_TOKEN_ADDRESS from adapter" + echo " Adapter address: $ADAPTER_ADDRESS" + exit 1 +fi echo "🔧 Upgrading SystemConfig, deploying new DepositedOKBAdapter, and updating SystemConfig to use it as gas paying token..." cd $ROOT_DIR/packages/contracts-bedrock From 634c57b1a99ec07c3cba50c3d27d350543fd49e9 Mon Sep 17 00:00:00 2001 From: "jason.huang" <20609724+doutv@users.noreply.github.com> Date: Fri, 24 Oct 2025 11:53:08 +0800 Subject: [PATCH 07/26] fix script --- test/upgrade-contracts/upgrade-okb-adapter.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/upgrade-contracts/upgrade-okb-adapter.sh b/test/upgrade-contracts/upgrade-okb-adapter.sh index 731572d79d5c8..4a61f6ab691ae 100755 --- a/test/upgrade-contracts/upgrade-okb-adapter.sh +++ b/test/upgrade-contracts/upgrade-okb-adapter.sh @@ -36,7 +36,7 @@ export OP_PROXY_ADMIN=$OP_PROXY_ADMIN export TRANSACTOR=$TRANSACTOR export OKB_ADAPTER_OWNER_ADDRESS=$OKB_ADAPTER_OWNER_ADDRESS -forge script scripts/UpgradeSystemConfigToV4.s.sol:UpgradeSystemConfigToV4 \ +forge script scripts/UpgradeSystemConfigToV312.s.sol:UpgradeSystemConfig \ --rpc-url $L1_RPC_URL \ --private-key $DEPLOYER_PRIVATE_KEY \ --broadcast From 6b776e416f63bc0030ab3b4ff9209cfaea0937da Mon Sep 17 00:00:00 2001 From: "jason.huang" <20609724+doutv@users.noreply.github.com> Date: Fri, 24 Oct 2025 11:53:16 +0800 Subject: [PATCH 08/26] Update SystemConfigV312 contract to allow ProxyAdmin to set gas paying token multiple times --- packages/contracts-bedrock/scripts/SystemConfigV312.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/scripts/SystemConfigV312.sol b/packages/contracts-bedrock/scripts/SystemConfigV312.sol index 138d1d4525ea3..015fe91e3402a 100644 --- a/packages/contracts-bedrock/scripts/SystemConfigV312.sol +++ b/packages/contracts-bedrock/scripts/SystemConfigV312.sol @@ -23,7 +23,7 @@ import { IGasToken } from "src/libraries/GasPayingToken.sol"; /// @notice The SystemConfigV312 contract is used to manage configuration of an Optimism network. /// All configuration is stored on L1 and picked up by L2 as part of the derviation of /// the L2 chain. -/// @dev Purpuse: upgrade DevNet OKB adapter +/// @dev Key changes: allow ProxyAdmin to set gas paying token multiple times contract SystemConfigV312 is ProxyAdminOwnedBase, OwnableUpgradeable, ReinitializableBase, ISemver, IGasToken { /// @notice Enum representing different types of updates. /// @custom:value BATCHER Represents an update to the batcher hash. @@ -617,5 +617,4 @@ contract SystemConfigV312 is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitiali function _setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) internal { GasPayingToken.set(_token, _decimals, _name, _symbol); } - } From 716e456ad26b5b97daccadfe8868c250b9800604 Mon Sep 17 00:00:00 2001 From: Louis Liu <35095310+louisliu2048@users.noreply.github.com> Date: Sun, 26 Oct 2025 20:09:28 +0800 Subject: [PATCH 09/26] Pre release (#105) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(cgt): custom gas token Signed-off-by: Hex <165055168+hexshire@users.noreply.github.com> Co-authored-by: niha <205694301+0xniha@users.noreply.github.com> Co-authored-by: Ashitaka <96790496+ashitakah@users.noreply.github.com> Co-authored-by: AgusDuha <81362284+agusduha@users.noreply.github.com> * feat: add gasPayingTokenName and gasPayingTokenSymbol on json config files * fix: contracts semver * fix: remove system config bool * test: add OptimismPortal2CGT tests * chore(cgt): set cgt flag l1block & fixes * fix(linter): resolve goimports formatting issue * feat: add separate l2 contracts for cgt (#530) * feat: add L1BlockCGT * feat: add L2ToL1MessagePasserCGT * chore: remove test exclution in test validation * test(cgt): fix failing tests (#529) * test(cgt): fix failing tests * test(cgt): fix portal version * test(cgt): skip tests on forked mode * fix: predeploys test cgt mismatch * test(cgt): minor fixes --------- Co-authored-by: niha <205694301+0xniha@users.noreply.github.com> * fix(cgt): revert weth * cgt: feature flag integration Updates the implementation to use the new feature flagging system * config: make backwards compatible Use the legacy config name so that less needs to change for legacy CGT chains * fix: build issue Remove leftover merge conflict * fix: better backwards compatibility * build: fix * lint: fix * snapshots: update * op-deployer: apply test with CGT Add a specific test for CGT in the intent * contracts-bedrock: fix versioning * lint: fix * deployer: remove standard values * contracts: semver lock * contracts-bedrock: fix semver + abis * cgt: solidity test cleanup * solidity: fmt * tests: remove dead imports * tests: fixup * cgt: configurable liquidity amount * feat: configurable native asset liquidity balance Fix the build for this feature * cleanup: merge L1Block logic so that we inherit Keeps it simple because development on Jovian is happening and we will inherit any Jovian modifications automatically * snapshots: update * cgt: inherit logic for L2ToL1MessagePasser Generally simplifies the code * semver-lock: update * lint: fix * lint: fixup * interfaces: fix * fixes: smol * deploy-config: sane default * lint: fix * linting: fix * lint: fix * semgrep: fix * lint: fix * tests: fix * tests: fix fuzz * fix: custom gas token rebase (#17484) * fix: import in OptimismPortal2CGT test and pre-pr * fix(cgt): add missing native asset amount (#543) * fix: upgrade contract name * feat: add nativeAssetLiquidityAmount to config json files * fix: add correct nativeAssetLiquidityAmount in op-deployer * fix: add correct nativeAssetLiquidityAmount in op-e2e and fix withCustomGasToken argument on op-devstack * fix: restore OptimismPortal2CGT * fix: all comments * fix: comments * fix: governace * fix: remove aux * fix: remove aux * fix: deploy cgt * fix: revert cgt deploy config * fix: deploy config * chore: run linter * fix: remove unnecessary GetNativeAssetLiquidityAmount --------- Co-authored-by: Ashitaka Co-authored-by: agusduha Co-authored-by: hexshire * fix: l2 genesis pipeline (#554) * fix: add nativeAssetLiquidityAmount in e2e apply test (#555) * fix: failing test --------- Co-authored-by: niha <205694301+0xniha@users.noreply.github.com> Co-authored-by: Ashitaka Co-authored-by: hexshire Co-authored-by: Hex <165055168+hexshire@users.noreply.github.com> * fix: semver lock * fix: CGT review fixes (#17534) * fix: json default zero * feat(cgt): add native asset liquidity amount test & omitempty on cgt struct * test: check native asset liquidity amount is correctly configured * feat: add omitempty to name and symbol on cgt intent struct * fix: check value in cgt * feat(cgt): add cgt dev feature * feat: add cgt dev feature * refactor: set custom gas token (#563) * feat: add cgt devFeatures and remove useCustomGasToken from DeployOPChainInput --------- Co-authored-by: Hex <165055168+hexshire@users.noreply.github.com> * fix: ir informational * fix: informational * fix: legacy tag * feat(cgt): add setNativeAssetLiquidityAmount & L2Genesis max amount check * feat: add setNativeAssetLiquidityAmount & L2Genesis max amount check * test: fix bound param in liquidity controller * fix: remove unused import * refactor: move max amount check inside setNativeAssetLiquidity * refactor: make chainIntent.CustomGasToken a non-pointer (#574) * refactor: make chainIntent.CustomGasToken a non-pointer * test: fix custom gas token text (#576) --------- Co-authored-by: Hex <165055168+hexshire@users.noreply.github.com> * fix: undo tests Co-authored-by: hexshire * fix: cgt portal (#577) * fix: semver * fix: cgt tests coverage (#582) * fix: l2genesis expectRevert amount test * test: improve l1block coverage * test: improve l1blockcgt coverage * test: add isCustomGasToken tests on SystemConfig * test: improve L2ToL1MessagePasserCGT coverage * test: improve L2ToL1MessagePasser coverage * fix: naming pre-pr * fix(cgt): change L2ToL1MessagePasser & OPContractsManager semver (#584) * fix: change L2ToL1MessagePasser semver * fix: change L2ToL1MessagePasser & OPContractsManager semver * fix: cgt feature tests (#585) * fix: cgt feature tests * fix: deposits with amount 0 when cgt enabled * Revert "fix: deposits with amount 0 when cgt enabled" This reverts commit 8bee464d45cf7d4040c4dd1459ffc78de2508024. * fix: cgt portal (#587) * fix: ci fixes (#588) --------- Co-authored-by: Ashitaka <96790496+ashitakah@users.noreply.github.com> Co-authored-by: niha <205694301+0xniha@users.noreply.github.com> Co-authored-by: Hex <165055168+hexshire@users.noreply.github.com> Co-authored-by: hexshire * fix: semver * fix: opcm version * fix: tests * feat(op-acceptance-tests): add acceptance tests for native CGT across L1/L2 (#17451) - Gate suite via L1Block.isCustomGasToken(); assert name/symbol non-empty - L2: value transfer pays CGT token (typed amounts via op-service/eth) - L2: XDM rejects callvalue; L2StandardBridge legacy withdraw reverts - L1: Portal receive/deposit rejects ETH; introspect SystemConfig addr - L1: assert SystemConfig.isCustomGasToken() is true * fix: custom gas token rebase review comments (#17577) * chore: use w3 library * fix: msg error * refactor(cgt): rename amount & add geq 0 check (#600) * feat: add NativeAssetLiquidityAmount sign check * refactor: rename NativeAssetLiquidityAmount to InitialLiquidity * refactor(cgt): rename json nativeAssetLiquidityAmount to initialLiquidity (#601) * refactor: rename json nativeAssetLiquidityAmount to initialLiquidity * fix: only add initialLiquidity to cgt intent struct --------- Co-authored-by: Hex <165055168+hexshire@users.noreply.github.com> Co-authored-by: Ashitaka <96790496+ashitakah@users.noreply.github.com> Co-authored-by: niha <205694301+0xniha@users.noreply.github.com> * fix: cgt review (#17612) * refactor: replace enableCustomGasToken with cgt devfeature * feat: remove fund in NativeAssetLiquidity (#605) * fix(cgt): remove OptimismPortal2 test from exclusions (#606) * fix: remove OptimismPortal2 test from exclusions * fix: remove virtual and restore constructor in portal test * refactor: use low level call to receive test * refactor(cgt): migrate L1Block and L2ToL1MessagePasser cgt tests (#608) * refactor: migrate L1Block cgt tests * refactor: migrate L2ToL1MessagePasser cgt tests * fix: comments (#607) * fix: comments * fix: custom error * fix: errors and tests * fix: errors and tests * fix: cgt tests (#610) * fix: comments * fix: custom error * fix: errors and tests * fix: errors and tests * fix: tests * fix: tests * fix: weth * fix: cgt tests (#611) * fix: comments * fix: custom error * fix: errors and tests * fix: errors and tests * fix: tests * fix: tests * fix: weth * fix: remove types * fix: coverage tests (#612) * fix: separate setUp function tests (#613) --------- Co-authored-by: niha <205694301+0xniha@users.noreply.github.com> Co-authored-by: Ashitaka <96790496+ashitakah@users.noreply.github.com> * test: custom gas token invariants (#17489) * test(inv): setup and total sup inv * test(inv): accounting invariants * chore: doc * fix: import in OptimismPortal2CGT test and pre-pr * fix(cgt): add missing native asset amount (#543) * fix: upgrade contract name * feat: add nativeAssetLiquidityAmount to config json files * fix: add correct nativeAssetLiquidityAmount in op-deployer * fix: add correct nativeAssetLiquidityAmount in op-e2e and fix withCustomGasToken argument on op-devstack * fix: restore OptimismPortal2CGT * fix: all comments * fix: comments * fix: governace * fix: remove aux * fix: remove aux * fix: deploy cgt * fix: revert cgt deploy config * fix: deploy config * chore: run linter * fix: remove unnecessary GetNativeAssetLiquidityAmount --------- Co-authored-by: Ashitaka Co-authored-by: agusduha Co-authored-by: hexshire * fix: l2 genesis pipeline (#554) * fix: add nativeAssetLiquidityAmount in e2e apply test (#555) * fix: failing test * chore: doc Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> * chore: remove unused imports * chore: fix semgrep * chore: change error name --------- Co-authored-by: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Co-authored-by: niha <205694301+0xniha@users.noreply.github.com> Co-authored-by: Ashitaka Co-authored-by: agusduha Co-authored-by: hexshire Co-authored-by: AgusDuha <81362284+agusduha@users.noreply.github.com> Co-authored-by: Hex <165055168+hexshire@users.noreply.github.com> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> * refactor: use skipIfDevFeatureDisabled for cgt predeploys test (#614) (#17621) Co-authored-by: niha <205694301+0xniha@users.noreply.github.com> * fix: tests * fix: auth minter helper & bound _mint in depositTransaction tests (#17642) * refactor: auth minter helper tests (#618) * fix: bound _mint correctly in depositTransaction test function (#619) * fix contract reference error * block bridge function (#49) * update image tag info * revert the change name of var DeployV2DisputeGamesDevFlag * rm unused code * Add CGT (#52) * Add architecture diagrams and developer guide for Custom Gas Token implementation - Introduced `ARCHITECTURE_DIAGRAM.md` detailing the system architecture, deposit flow, contract interaction, storage layout, and feature flag flow for the Custom Gas Token (CGT). - Added `DEVELOPER_GUIDE.md` providing practical examples, usage patterns, and troubleshooting tips for developers and users interacting with the CGT. - Completed `IMPLEMENTATION_COMPLETE.md` summarizing the implementation status and design requirements met. - Created `IMPLEMENTATION_SUMMARY.md` outlining the changes made across various contracts and interfaces related to the CGT. * Implement restrictions in CrossDomainMessenger by adding require statements to prevent message sending. This change enforces a "not allowed" condition for the sendMessage function, enhancing contract security. * Add gasPayingToken function to OptimismPortal2 for retrieving gas token address and decimals - Introduced a new public view function `gasPayingToken` that returns the gas paying token address and its decimals, ensuring it adheres to the 18-decimal requirement for Custom Gas Tokens (CGT). - Updated the deposit function to utilize the new `gasPayingToken` method for improved clarity and maintainability. * Add gas paying token functionality to SystemConfig and OptimismPortal2 - Enhanced the ISystemConfig interface with new functions for managing gas paying token details, including retrieval of the token address, name, and symbol, as well as a setter function for updating these parameters. - Updated the OptimismPortal2 contract to utilize the new gasPayingToken method from SystemConfig, improving clarity in gas token management during deposit operations. - Introduced internal mechanisms for setting and emitting updates related to the gas paying token configuration. * fix error * Add SetupCustomGasToken script and MockOKB contract for custom gas token configuration - Introduced a new Foundry script `SetupCustomGasToken.s.sol` to deploy a mock OKB token, enable the CUSTOM_GAS_TOKEN feature in SystemConfig, and set the gas paying token. - Created `MockOKB` contract to simulate the OKB token with a fixed supply for testing purposes. - Updated `DepositedOKBAdapter` to include additional documentation and constants for improved clarity. - Added a shell script for setting up and verifying the custom gas token configuration, including test deposit functionality. - Updated example environment file to include L2 RPC URL and Optimism portal proxy address for configuration. * Updated the script to extract and handle the OptimismPortalProxy address from the STATE_JSON file. * fix Transactor error * fix: error crit: failed to update L1 sysCfg with receipts from block 0x50d239f28f64c684383e88b9a6cb31b529bf4dd693a41317ec6cdacc465ef134:381: 1 error occurred:\n\t* malformatted L1 system sysCfg log in receipt 2, log 0: unrecognized L1 sysCfg update type: 0x0000000000000000000000000000000000000000000000000000000000000006\n\n * revert changes * Update custom gas token setup script - Introduced a new shell script `cgt-only-contract.sh` for setting up and verifying the Custom Gas Token (CGT) configuration. - The script automates the deployment of the mock OKB token and the associated adapter, verifies L2 configuration, and performs a test deposit. - Enhanced user feedback with detailed output during each step of the setup process, including success and warning messages for better troubleshooting. * Add OKB token interface and implement burner functionality - Introduced the `IOKB` interface for the OKB token, defining the `triggerBridge` function. - Enhanced the `MockOKB` contract to implement the `ERC20Burnable` interface and added the `triggerBridge` function to burn all tokens held by the sender. - Created the `OKBBurner` contract for burning OKB tokens via a minimal proxy pattern, ensuring each clone self-destructs after burning. - Updated the `DepositedOKBAdapter` to integrate the new burner functionality, allowing for the creation of unique burner contracts for each deposit transaction. - Improved documentation and error handling throughout the contracts for better clarity and maintainability. * fix compiler * Enhance CGT setup script with OKB total supply checks - Added functionality to query and display the initial and final total supply of the OKB token during the deposit process. - Included detailed output for burned tokens, improving visibility into token supply changes after deposits. - Implemented final total supply checks at the end of the script for comprehensive reporting. * Refactor OKBBurner contract and setup script - Removed the adapter address from the OKBBurner constructor and related logic, simplifying the contract's design. - Updated the SetupCustomGasToken script to reflect the changes in the OKBBurner implementation, removing references to the adapter address in the deployment and configuration checks. - Enhanced clarity in the deployment process by focusing on the OKB token address. * Update cgt-only-contract.sh to improve OKB supply reporting and balance checks - Removed formatted output for initial and final OKB total supply to simplify display. - Added a check for the deployer's OKB balance before proceeding with the deposit. - Updated the deposit function call to include additional parameters for better transaction handling. - Enhanced clarity in the output regarding token supply changes and burned tokens. * refine logic * add Libraries * Revert "Implement restrictions in CrossDomainMessenger by adding require statements to prevent message sending. This change enforces a "not allowed" condition for the sendMessage function, enhancing contract security." This reverts commit d29ffd4409a122d5e5795a410056f7f90f7ed104. * revert L1BlockCGT, fix CGT metadata on L2 * remove doc * Remove unused OptimismPortal reference and related checks from SetupCustomGasToken script to streamline gas token configuration process. * feat: add log of update gas paying token * feat: enable custom gas token feature in deployment script - Added the --dev-feature-bitmap flag to the deployment command to support custom gas token functionality. * Refactor cgt-only-contract.sh to simplify OKB supply reporting - Removed the calculation and output for burned tokens to streamline the reporting process. - Enhanced clarity in the final status output regarding OKB total supply. --------- Co-authored-by: weixie.cui Co-authored-by: albbm <43458858@qq.com> * feat: add custom gas token configuration for OKB (#55) - Introduced custom gas token settings in the intent.toml.bak file. - Enabled the custom gas token feature with name "OKB", symbol "OKB", and initial liquidity set to "0x0". * consolidate test scripts * refactor * resolve conflicts * fix build op contracts * fix op_stack image build * use dev for op-geth * fix setGasToken * remove SystemConfig UpdateType GAS_PAYING_TOKEN event * refactoring * fix typo * fix sysconfig * refactoring * Update MockOKB contract to mint a total supply of 660,000 (#60) * add patch * fix: build image sequence * feat: add cdk image env * feat: set ARCH to default value using docker cmd * update testnet genesisGasParameters and readme * use gopath for install go bin * Optimize dockerfile build time (#63) * Update Dockerfile and .dockerignore for improved build process - Modified .dockerignore to include necessary directories and exclude generated files, enhancing build efficiency. - Updated Dockerfile to skip test files during the forge build process, streamlining the build and reducing unnecessary overhead. * Optimize opstack Dockerfile build time - Modified Dockerfile to use a new target `build-go-no-submodules`, allowing for builds without submodules, improving flexibility. - Updated .dockerignore to include the Makefile, ensuring it is not ignored during the Docker build process. * Update .dockerignore to exclude .env file from Docker builds * update op-geth to the latest * add cgt_enable (#66) * add cgt_enable * update contracts dockerfile * skip test forge build * simplify contract * Update testnet readme steps * put migration into separate file * merge with pre-release * refactor * sync op-geth * fix(test): add --legacy flag to Safe contract deployment * update testnet readme for regenesis * consolidate test scripts (#59) * consolidate test scripts * refactor * resolve conflicts * fix build op contracts * fix op_stack image build * use dev for op-geth * fix setGasToken * remove SystemConfig UpdateType GAS_PAYING_TOKEN event * refactoring * fix typo * fix sysconfig * refactoring * add patch * fix: build image sequence * feat: add cdk image env * feat: set ARCH to default value using docker cmd * update testnet genesisGasParameters and readme * use gopath for install go bin * add cgt_enable (#66) * add cgt_enable * update contracts dockerfile * skip test forge build * simplify contract * Update testnet readme steps * put migration into separate file * merge with pre-release * refactor * sync op-geth * update testnet readme for regenesis --------- Co-authored-by: jason.huang <20609724+doutv@users.noreply.github.com> Co-authored-by: weixie.cui Co-authored-by: Vui-Chee * support gnosis safe and fix configs * refactor geth_cmd * no verify for redeploy testnet, temparay * custom dockerfile to build op-geth-migrate * Update testnet migration readme * add pp proxy * rm testnet.env * rm testnetenv * change address * update parameters * change fee receipt address * update op-geth * support parallel build images (#80) Co-authored-by: louis.liu * Update CGT Contracts (#79) * Update MockOKB contract to mint a total supply of 660,000 * Separate MockOKB and setupCGT into 2 scripts - Updated the IOKB interface to inherit from IERC20Metadata, adding metadata functionality. - Created a new MockOKB contract for testing purposes, implementing ERC20 and ERC20Burnable. - The MockOKB contract includes a triggerBridge function to burn all tokens held by the sender. - Added a deployment script for the MockOKB token to facilitate testing of custom gas token configurations. * Enhance cgt-only-contract.sh for improved OKB token handling - Added logic to check for an existing OKB token address in the environment and verify its validity before deployment. - Implemented deployment of a MockOKB token if no address is found, with error handling for deployment failures. - Updated the script to export necessary environment variables and streamline the setup process for the Custom Gas Token (CGT). - Enhanced user feedback with detailed messages during each step, including success and error notifications. * Add require statement for gas token address validation in SetupCustomGasToken script - Introduced a require statement to ensure that the token address is set to the predefined constant for ETHER, enhancing validation during the setup process. - This change improves error handling by preventing incorrect configurations of the gas paying token. * Update example.env to include OKB token address configuration - Added a new environment variable `OKB_TOKEN_ADDRESS` to specify the OKB token address on L1. If not set, a new MockOKB will be deployed, enhancing flexibility in token management. * Refactor Custom Gas Token setup and verification scripts - Integrated the setup of the Custom Gas Token (CGT) into the `2-deploy-op-contracts.sh` script, enhancing the deployment process. - Created a new script `setup-cgt-function.sh` to encapsulate the CGT setup logic, improving modularity and maintainability. - Added a new test script `test-cgt.sh` for verifying CGT configuration and performing test deposits, ensuring comprehensive testing of the setup. - Removed the obsolete `cgt-only-contract.sh` script to streamline the codebase and eliminate redundancy. * Remove SystemConfig UpdateType GAS_PAYING_TOKEN event. gasPayingToken only set once, no need update event. * Update Dockerfile and .dockerignore for improved build process - Modified .dockerignore to include necessary directories and exclude generated files, enhancing build efficiency. - Updated Dockerfile to skip test files during the forge build process, streamlining the build and reducing unnecessary overhead. * refine okbAdapter contract * Optimize opstack Dockerfile build time - Modified Dockerfile to use a new target `build-go-no-submodules`, allowing for builds without submodules, improving flexibility. - Updated .dockerignore to include the Makefile, ensuring it is not ignored during the Docker build process. * Refactor output handling in setup_cgt function - Updated the `setup_cgt` function in `setup-cgt-function.sh` to pipe the output of the forge script commands to `tee`, allowing for real-time logging to the terminal. - Removed redundant echo statements for the output, streamlining the script and improving readability. * Update console log output in SetupCustomGasToken script - Changed the console log message for gasPayingToken to improve clarity, ensuring it reflects the function call format for better readability during execution. * Update environment configuration in test script - Backed up the existing .env file and replaced it with example.env to ensure the correct environment settings are used during testing. - Ensured the test script continues to execute the preparation of tests without interruption. * Remove duplicate balanceOf function from IOKB interface * fix script * Revert "Merge branch 'dev' into pre-release" This reverts commit b0c412edbfb0fa978265818bfffdf088cda9b59d, reversing changes made to 97a978d46afc3d6864cd5ba16815386ad6994aee. * forge fmt * Optimize dockerfile build time (#63) * Update Dockerfile and .dockerignore for improved build process - Modified .dockerignore to include necessary directories and exclude generated files, enhancing build efficiency. - Updated Dockerfile to skip test files during the forge build process, streamlining the build and reducing unnecessary overhead. * Optimize opstack Dockerfile build time - Modified Dockerfile to use a new target `build-go-no-submodules`, allowing for builds without submodules, improving flexibility. - Updated .dockerignore to include the Makefile, ensuring it is not ignored during the Docker build process. * Update .dockerignore to exclude .env file from Docker builds * Add read access for test configuration directory in foundry.toml Add L1 And L2 bridge test * Refactor DepositedOKBAdapter and introduce ERC20Rescuer contract - Removed the OKBBurner implementation and its related functionality from DepositedOKBAdapter, simplifying the contract. - Added a new ERC20Rescuer contract to handle the rescue of ERC20 tokens, enhancing token management. - Updated DepositedOKBAdapter to utilize the new rescuer address for transferring any mistakenly sent OKB tokens. - Cleaned up unnecessary events and errors related to the burner functionality, improving code clarity and maintainability. * Add new error for invalid gas token in IOptimismPortal2 interface * Enhance DepositedOKBAdapter with Whitelist Functionality and Owner Control - Introduced Ownable inheritance to manage ownership and access control. - Added a whitelist mechanism allowing only approved addresses to deposit OKB. - Implemented batch functions for adding and removing addresses from the whitelist. - Updated deposit logic to enforce whitelisting and added error handling for zero addresses. - Removed the ERC20Rescuer contract, consolidating rescue functionality within DepositedOKBAdapter. - Cleaned up unnecessary errors and improved overall contract clarity and maintainability. * Enhance DepositedOKBAdapter with Transfer Failure Handling - Introduced a new error for transfer failures to improve error handling. - Updated the constructor to transfer ownership to the specified owner after minting. - Modified transfer functions to check for successful token transfers, reverting on failure. - Improved overall contract robustness and clarity by handling potential transfer issues. * Refactor transfer error handling in DepositedOKBAdapter - Simplified the TransferNotAllowed error by removing parameters, enhancing clarity. - Updated transfer functions to always revert with the new error format, ensuring consistent error handling. - Improved code maintainability by reducing complexity in transfer logic. * Add comprehensive tests for DepositedOKBAdapter functionality - Introduced a new test suite for DepositedOKBAdapter, covering constructor validation, whitelist management, deposit functionality, transfer restrictions, and ERC20 rescue operations. - Implemented mock contracts for testing, including MockOKB and MockOptimismPortal2, to simulate interactions and validate behavior. - Enhanced test coverage to ensure robust error handling and correct functionality across various scenarios, including deposits by whitelisted users and handling of edge cases. - Improved overall test structure for better maintainability and clarity. * Update Dockerfile to use latest op-contracts image * Refactor SetupCustomGasToken script to remove OKBBurner implementation - Eliminated the OKBBurner contract from the SetupCustomGasToken script, simplifying the deployment process. - Updated the DepositedOKBAdapter deployment to handle OKB burning internally and added the deployer address to the whitelist. - Enhanced configuration checks to verify adapter ownership and whitelist status, ensuring robust contract setup. * Add tests for depositERC20Transaction in OptimismPortal2 - Introduced a new test contract to validate the depositERC20Transaction function. - Implemented various test cases to ensure correct behavior when using a custom gas token, including scenarios for invalid tokens, insufficient gas limits, and contract creation deposits. - Verified token transfers and ensured proper reverts for edge cases, enhancing overall test coverage for the OptimismPortal2 functionality. * forge fmt * add OKB mainnet address * Refactor DepositedOKBAdapter to clarify token minting and transfer restrictions - Updated comments to specify that deposit tokens are referred to as dOKB. - Enhanced transferFrom function to ensure only the portal can pull tokens from the adapter. - Added tests to verify that unauthorized transfer attempts from the portal revert correctly. * fix lint --------- Co-authored-by: albbm <43458858@qq.com> * update op-geth to the latest version * Pre release for mainnet (#83) * update * update * update * update * update * Update m1 script * Fix conditional check for .env file * Update deploy contracts script `OKB_TOKEN_ADDRESS` * Push m1 updates * Update M2 to follow M1 * Step 3 updates * update * update * Change tarfile name in m1 and m2 scripts * Update m3 script * update * update * update * update * update * update * update * Reorder image vars * Omit .env as m2 runs in host * Changes to m3 * Update m1 to load m2 and m3 scripts * Update m2 * Drop m2 script * Push new m2 * update * update * update * update * Update README with new m1/m2 scripts * Omit date suffix from backup dir name * update * Update mount path for run container * update * update * To check block need to specify block number before * update * increase retry * refactor * increase timeout * update * update * Drop sleeps * update --------- Co-authored-by: Vui-Chee Co-authored-by: cliff.yang * Allow CGT feature to be enabled on Mainnet by commenting out the production check in OPContractsManager.sol (#97) * Update CGT config for mainnet (#98) * set deployer as systemConfigOwner first, after setup cgt finish, transfer ownership * Add OKB adapter owner address to SetupCustomGasToken script - Introduced `okbAdapterOwnerAddress` to the SetupCustomGasToken contract. - Updated deployment logic to use `okbAdapterOwnerAddress` instead of `deployerAddress`. - Modified environment configuration to include `OKB_ADAPTER_OWNER_ADDRESS` in local.env. * Enhance SetupCustomGasToken script to transfer adapter ownership - Updated the deployment logic to set the deployer as the initial owner of the DepositedOKBAdapter. - Added a new function to transfer adapter ownership to a designated owner address after deployment. - Modified the environment configuration to include `OKB_ADAPTER_OWNER_ADDRESS` for deployment. * Simplified Ownership Pattern: Deploying the adapter directly with the final owner (okbAdapterOwnerAddress) instead of deploying with deployer and then transferring - more efficient and cleaner deployment pattern. (#106) No whitelist * pre-release-v3 (#95) * update * update * update * update * update * Update m1 script * Fix conditional check for .env file * Update deploy contracts script `OKB_TOKEN_ADDRESS` * Push m1 updates * Update M2 to follow M1 * Step 3 updates * update * update * Change tarfile name in m1 and m2 scripts * Update m3 script * update * update * update * update * update * update * update * Reorder image vars * Omit .env as m2 runs in host * Changes to m3 * Update m1 to load m2 and m3 scripts * Update m2 * Drop m2 script * Push new m2 * update * update * update * update * Update README with new m1/m2 scripts * Omit date suffix from backup dir name * update * Update mount path for run container * update * update * To check block need to specify block number before * update * increase retry * refactor * increase timeout * update * update * Drop sleeps * update * before/after configs check * Set `EXPECTED_L1_CHAIN_ID` for fakemainnet * Fix print configuration issues * Fix timestamp not showing * update * recover * set deployer as systemConfigOwner first, after setup cgt finish, transfer ownership * Add OKB adapter owner address to SetupCustomGasToken script - Introduced `okbAdapterOwnerAddress` to the SetupCustomGasToken contract. - Updated deployment logic to use `okbAdapterOwnerAddress` instead of `deployerAddress`. - Modified environment configuration to include `OKB_ADAPTER_OWNER_ADDRESS` in local.env. * update * Enhance SetupCustomGasToken script to transfer adapter ownership - Updated the deployment logic to set the deployer as the initial owner of the DepositedOKBAdapter. - Added a new function to transfer adapter ownership to a designated owner address after deployment. - Modified the environment configuration to include `OKB_ADAPTER_OWNER_ADDRESS` for deployment. * update * Update `l2GenesisBlockBaseFeePerGas` in fakemainnet intent * Fix duplicate eip1559Denominator values * updates to m2 * Remove logs for these fields * Drop previous builds before building image * prompt delete backup dir if exists * Print sth if delete * Print `SystemConfigProxy` after regenesis * update * Match rollup.json `eip1559DenominatorCanyon` after migration... * Report removal of upload dir * Reduce verbosity and log upload filename * Tidy last log at shutdown --------- Co-authored-by: Vui-Chee Co-authored-by: cliff.yang Co-authored-by: Vui-Chee <46051576+Vui-Chee@users.noreply.github.com> Co-authored-by: jason.huang <20609724+doutv@users.noreply.github.com> * update op-geth version * Pre release v4 (#107) * update * Drop debug * Restore L2 num + hash after migrate * Revert to allow deploy contracts to succeed * Omit debug from build script * Pull out game factory adress from .env * update * update --------- Co-authored-by: Vui-Chee * Update test cgt cross chain script (#109) * Simplified Ownership Pattern: Deploying the adapter directly with the final owner (okbAdapterOwnerAddress) instead of deploying with deployer and then transferring - more efficient and cleaner deployment pattern. No whitelist * Add OKB adapter owner address to environment and update CGT setup script - Introduced `DEPLOYER_ADDRESS` and `OKB_ADAPTER_OWNER_ADDRESS` in `example.env` for better configuration. - Updated `setup-cgt-function.sh` to export the new adapter owner address. - Enhanced `test-cgt.sh` to verify the deployer as the adapter owner and streamline the setup process. * Updated comments to reflect the new order of operations in the script. * Enhance test-cgt.sh to dynamically set L2 recipient and display deposit details - Added retrieval of SYSTEM_CONFIG_PROXY_ADDRESS from state.json. - Updated deposit logic to use DEPLOYER_ADDRESS as the L2 recipient. - Included initial balance display for the L2 recipient before deposit. * Remove deprecated `cgt-only-contract.sh` script as it is no longer needed for the Custom Gas Token setup process. * Real script: test-pp-op/test-cgt.sh (the canonical version) Symlink: test/test-cgt.sh → ../test-pp-op/test-cgt.sh * move test-cgt to test/ * update op-geth version * Remove deprecated L2_RPC_URL from example.env to streamline configuration. (#114) * update seq window size (#118) * add more error info in Transactor.sol (#121) * Pre-release v6 (#122) * Copy migrate log * Execute verification from working dir * Copy verify script for upload * Last check to verify checksum of copied data * Use SOURCE_PATH and report success * indent * Add set_init_bond.sh * Add set initBond logic * use env params * fix set-init-bond wrong path * Use `diff` over `md5sum` * update * Simplify diff check * save mainnet intent toml * Adjust proposer and challenger addresses * Update intent mainnet * update systemConfigOwner * update --------- Co-authored-by: JimmyShi22 <417711026@qq.com> Co-authored-by: Barry --------- Signed-off-by: Hex <165055168+hexshire@users.noreply.github.com> Co-authored-by: Hex <165055168+hexshire@users.noreply.github.com> Co-authored-by: niha <205694301+0xniha@users.noreply.github.com> Co-authored-by: Ashitaka <96790496+ashitakah@users.noreply.github.com> Co-authored-by: AgusDuha <81362284+agusduha@users.noreply.github.com> Co-authored-by: Mark Tyneway Co-authored-by: Ashitaka Co-authored-by: hexshire Co-authored-by: agusduha Co-authored-by: Stefano Charissis Co-authored-by: Simon Something /DrGoNoGo <83670532+simon-something@users.noreply.github.com> Co-authored-by: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> Co-authored-by: louis.liu Co-authored-by: 怪兽 <32981645+albbm@users.noreply.github.com> Co-authored-by: Backdoor <20609724+doutv@users.noreply.github.com> Co-authored-by: weixie.cui Co-authored-by: albbm <43458858@qq.com> Co-authored-by: cliff.yang Co-authored-by: cliff.li Co-authored-by: Vui-Chee Co-authored-by: KyrinCode Co-authored-by: Barry Co-authored-by: Vui-Chee <46051576+Vui-Chee@users.noreply.github.com> Co-authored-by: jimmyshi <417711026@qq.com> --- .circleci/config.yml | 6 +- .gitignore | 4 + Dockerfile-contracts | 2 +- op-acceptance-tests/acceptance-tests.yaml | 6 + op-acceptance-tests/justfile | 3 + .../cgt_introspection_test.go | 25 + .../cgt_l1_portal_introspection_test.go | 53 + .../cgt_native_payment_test.go | 48 + .../cgt_portal_reverts_test.go | 34 + .../custom_gas_token/cgt_reverts_test.go | 68 ++ .../custom_gas_token/cgt_systemconfig_test.go | 107 ++ .../tests/custom_gas_token/helpers.go | 70 ++ .../tests/custom_gas_token/init_test.go | 22 + op-chain-ops/genesis/config.go | 21 +- .../testdata/test-deploy-config-full.json | 4 +- op-chain-ops/interopgen/deploy.go | 4 + op-chain-ops/interopgen/recipe.go | 5 +- op-deployer/pkg/deployer/devfeatures.go | 3 + .../deployer/integration_test/apply_test.go | 56 ++ .../integration_test/shared/shared.go | 5 + .../pkg/deployer/manage/testdata/state.json | 7 +- op-deployer/pkg/deployer/opcm/l2genesis.go | 4 + .../pkg/deployer/pipeline/l2genesis.go | 28 + .../pkg/deployer/pipeline/l2genesis_test.go | 86 +- .../pkg/deployer/state/chain_intent.go | 33 +- .../pkg/deployer/state/deploy_config.go | 19 +- .../pkg/deployer/state/deploy_config_test.go | 7 + op-deployer/pkg/deployer/state/intent.go | 15 + op-deployer/pkg/deployer/state/intent_test.go | 53 + op-devstack/sysgo/deployer.go | 8 + op-e2e/config/init.go | 6 + op-e2e/e2eutils/intentbuilder/builder.go | 11 + op-e2e/e2eutils/intentbuilder/builder_test.go | 8 + .../deploy-config/hardhat.json | 6 +- .../deploy-config/internal-devnet.json | 6 +- .../deploy-config/mainnet.json | 6 +- .../deploy-config/sepolia-devnet-0.json | 6 +- .../deploy-config/sepolia.json | 6 +- packages/contracts-bedrock/foundry.toml | 1 + .../interfaces/L1/IL1CrossDomainMessenger.sol | 7 +- .../interfaces/L1/IL1StandardBridge.sol | 7 +- .../contracts-bedrock/interfaces/L1/IOKB.sol | 9 + .../interfaces/L1/IOptimismPortal2.sol | 18 +- .../interfaces/L1/ISystemConfig.sol | 5 + .../interfaces/L2/IL1BlockCGT.sol | 40 + .../interfaces/L2/IL2ToL1MessagePasserCGT.sol | 28 + .../interfaces/L2/ILiquidityController.sol | 26 + .../interfaces/L2/INativeAssetLiquidity.sol | 15 + .../scripts/DeployMockOKB.s.sol | 74 ++ .../contracts-bedrock/scripts/L2Genesis.s.sol | 104 +- .../scripts/SetupCustomGasToken.s.sol | 150 +++ .../checks/test-validation/exclusions.toml | 3 +- .../scripts/deploy/DeployConfig.s.sol | 45 + .../scripts/deploy/DeployOPChain.s.sol | 2 + .../scripts/libraries/Config.sol | 5 + .../snapshots/abi/L1Block.json | 6 +- .../snapshots/abi/L1BlockCGT.json | 323 ++++++ .../snapshots/abi/L2ToL1MessagePasser.json | 2 +- .../snapshots/abi/L2ToL1MessagePasserCGT.json | 161 +++ .../snapshots/abi/LiquidityController.json | 222 +++++ .../snapshots/abi/NativeAssetLiquidity.json | 83 ++ .../snapshots/abi/OptimismPortal2.json | 5 + .../snapshots/abi/SystemConfig.json | 13 + .../snapshots/semver-lock.json | 38 +- .../snapshots/storageLayout/L1BlockCGT.json | 93 ++ .../storageLayout/L2ToL1MessagePasserCGT.json | 16 + .../storageLayout/LiquidityController.json | 37 + .../storageLayout/NativeAssetLiquidity.json | 1 + .../src/L1/DepositedOKBAdapter.sol | 230 +++++ .../src/L1/L1ERC721Bridge.sol | 2 + .../src/L1/L1StandardBridge.sol | 8 + .../src/L1/OPContractsManager.sol | 32 +- .../src/L1/OptimismPortal2.sol | 115 ++- .../contracts-bedrock/src/L1/SystemConfig.sol | 61 +- packages/contracts-bedrock/src/L2/L1Block.sol | 12 +- .../contracts-bedrock/src/L2/L1BlockCGT.sol | 72 ++ .../src/L2/L2ERC721Bridge.sol | 2 + .../src/L2/L2StandardBridge.sol | 3 + .../src/L2/L2ToL1MessagePasser.sol | 10 +- .../src/L2/L2ToL1MessagePasserCGT.sol | 36 + .../src/L2/LiquidityController.sol | 105 ++ .../src/L2/NativeAssetLiquidity.sol | 51 + .../src/libraries/DevFeatures.sol | 5 + .../src/libraries/Features.sol | 5 + .../src/libraries/Predeploys.sol | 15 +- .../src/periphery/Transactor.sol | 4 +- .../src/universal/ERC721Bridge.sol | 2 + .../src/universal/StandardBridge.sol | 8 + .../test/L1/DepositedOKBAdapter.t.sol | 717 ++++++++++++++ .../test/L1/L1StandardBridge.t.sol | 13 +- .../test/L1/OptimismPortal2.t.sol | 545 ++++++++++- .../test/L1/SystemConfig.t.sol | 17 + .../test/L2/BaseFeeVault.t.sol | 7 +- .../contracts-bedrock/test/L2/L1Block.t.sol | 100 +- .../test/L2/L1FeeVault.t.sol | 7 +- .../test/L2/L2StandardBridge.t.sol | 5 + .../test/L2/L2ToL1MessagePasser.t.sol | 39 + .../test/L2/LiquidityController.t.sol | 279 ++++++ .../test/L2/NativeAssetLiquidity.t.sol | 151 +++ .../test/L2/SequencerFeeVault.t.sol | 13 +- packages/contracts-bedrock/test/L2/WETH.t.sol | 4 +- .../test/bridgeRevert/L1Bridge.t.sol | 170 ++++ .../test/bridgeRevert/L2Bridge.t.sol | 129 +++ .../test/invariants/CustomGasToken.t.sol | 258 +++++ .../test/invariants/OptimismPortal2.t.sol | 12 + .../test/libraries/Predeploys.t.sol | 27 +- .../test/scripts/L2Genesis.t.sol | 105 +- .../test/setup/CommonTest.sol | 12 + .../test/setup/FeatureFlags.sol | 4 + .../contracts-bedrock/test/setup/Setup.sol | 12 +- test-pp-op/0-all-local.sh | 13 + test-pp-op/1-start-erigon.sh | 60 ++ test-pp-op/2-deploy-op-contracts.sh | 455 +++++++++ test-pp-op/3-stop-erigon.sh | 27 + test-pp-op/4-migrate-op.sh | 209 ++++ test-pp-op/5-start-op.sh | 168 ++++ test-pp-op/6-build-op-program.sh | 174 ++++ test-pp-op/7-setup-fraud-proof.sh | 505 ++++++++++ test-pp-op/8-prepare-tests.sh | 57 ++ test-pp-op/Makefile | 204 ++++ test-pp-op/README.md | 393 ++++++++ test-pp-op/build_images.sh | 300 ++++++ .../config-op/intent.fakemainnet.toml.bak | 35 + test-pp-op/config-op/intent.local.toml.bak | 36 + test-pp-op/config-op/intent.mainnet.toml.bak | 36 + test-pp-op/config-op/intent.testnet.toml.bak | 35 + test-pp-op/config-op/intent.toml.bak | 35 + test-pp-op/config-op/jwt.txt | 1 + test-pp-op/config-op/state.json.bak | 13 + test-pp-op/config-op/test.rpc.config.toml | 38 + test-pp-op/config-op/test.seq.config.toml | 46 + test-pp-op/config/aggkit.toml | 129 +++ test-pp-op/config/agglayer-config.toml | 91 ++ test-pp-op/config/agglayer-prover-config.toml | 25 + test-pp-op/config/cdk.config.toml | 296 ++++++ .../config/dynamic-mynetwork-allocs.json | 100 ++ .../config/dynamic-mynetwork-chainspec.json | 25 + test-pp-op/config/dynamic-mynetwork-conf.json | 6 + test-pp-op/config/first-batch-config.json | 9 + .../config/local/local.erigon.rpc.config.yaml | 114 +++ .../config/local/local.erigon.seq.config.yaml | 109 +++ test-pp-op/config/test.bridge.config.toml | 132 +++ test-pp-op/config/test.erigon.rpc.config.yaml | 86 ++ test-pp-op/config/test.erigon.seq.config.yaml | 114 +++ test-pp-op/config/test.genesis.config.json | 109 +++ test-pp-op/config/test.node.config.toml | 6 + test-pp-op/config/test.poolmanager.toml | 37 + .../config/xlayerconfig-mainnet-rpc.yaml | 29 + test-pp-op/config/xlayerconfig-mainnet.yaml | 87 ++ test-pp-op/contracts/OKBToken.sol | 97 ++ test-pp-op/contracts/Transactor.sol | 51 + test-pp-op/contracts/foundry.toml | 9 + test-pp-op/docker-compose-local.yml | 925 ++++++++++++++++++ test-pp-op/docker-compose.yml | 663 +++++++++++++ test-pp-op/dockerfile/Dockerfile-cdk-erigon | 87 ++ test-pp-op/dockerfile/Dockerfile.migrate | 27 + test-pp-op/dockerfile/Dockerfile.repro | 60 ++ .../dockerfile/Dockerfile.repro-builder | 19 + test-pp-op/init-erigon.sh | 213 ++++ test-pp-op/l1-geth/consensus/config.yml | 34 + test-pp-op/l1-geth/execution/genesis-raw.json | 119 +++ .../l1-geth/execution/geth_password.txt | 0 test-pp-op/l1-geth/execution/jwtsecret | 1 + ...--123463a4b065722e99115d6c222f267d9cabb524 | 1 + test-pp-op/l1-geth/execution/sk.json | 1 + test-pp-op/local.env | 132 +++ test-pp-op/m1-deploy-and-upload.sh | 80 ++ test-pp-op/m2-migrate.sh | 630 ++++++++++++ test-pp-op/m3-verify.sh | 43 + test-pp-op/notes.txt | 28 + ...pport-load-genesis-at-a-given-number.patch | 187 ++++ .../optimism-0001-decompress-genesis.patch | 65 ++ ...1-support-regenesis-op-geth-prestate.patch | 82 ++ ...upport-sync-L2-block-at-given-number.patch | 70 ++ ...002-skip-reorg-check-after-regenesis.patch | 30 + ...skip-syncing-blocks-before-regenesis.patch | 31 + test-pp-op/scripts/active-sequencer.sh | 91 ++ test-pp-op/scripts/add-game-type.sh | 192 ++++ test-pp-op/scripts/deposit-from-banker.sh | 17 + test-pp-op/scripts/deposit-from-l1.sh | 48 + test-pp-op/scripts/docker-install-start.sh | 31 + test-pp-op/scripts/gray-upgrade-simulation.sh | 309 ++++++ test-pp-op/scripts/replace-genesis.sh | 29 + test-pp-op/scripts/set-init-bond.sh | 152 +++ test-pp-op/scripts/show-dev-accounts.sh | 17 + test-pp-op/scripts/stop-leader-sequencer.sh | 47 + test-pp-op/scripts/transfer-leader.sh | 59 ++ test-pp-op/tools.sh | 32 + test-pp-op/utils.sh | 15 + test/2-deploy-op-contracts.sh | 14 +- test/3-op-init.sh | 11 + test/config-op/intent.toml.bak | 5 + test/example.env | 7 + test/init-parallel.sh | 271 +++++ test/setup-cgt-function.sh | 133 +++ test/test-cgt.sh | 227 +++++ 196 files changed, 15310 insertions(+), 230 deletions(-) create mode 100644 op-acceptance-tests/tests/custom_gas_token/cgt_introspection_test.go create mode 100644 op-acceptance-tests/tests/custom_gas_token/cgt_l1_portal_introspection_test.go create mode 100644 op-acceptance-tests/tests/custom_gas_token/cgt_native_payment_test.go create mode 100644 op-acceptance-tests/tests/custom_gas_token/cgt_portal_reverts_test.go create mode 100644 op-acceptance-tests/tests/custom_gas_token/cgt_reverts_test.go create mode 100644 op-acceptance-tests/tests/custom_gas_token/cgt_systemconfig_test.go create mode 100644 op-acceptance-tests/tests/custom_gas_token/helpers.go create mode 100644 op-acceptance-tests/tests/custom_gas_token/init_test.go create mode 100644 packages/contracts-bedrock/interfaces/L1/IOKB.sol create mode 100644 packages/contracts-bedrock/interfaces/L2/IL1BlockCGT.sol create mode 100644 packages/contracts-bedrock/interfaces/L2/IL2ToL1MessagePasserCGT.sol create mode 100644 packages/contracts-bedrock/interfaces/L2/ILiquidityController.sol create mode 100644 packages/contracts-bedrock/interfaces/L2/INativeAssetLiquidity.sol create mode 100644 packages/contracts-bedrock/scripts/DeployMockOKB.s.sol create mode 100644 packages/contracts-bedrock/scripts/SetupCustomGasToken.s.sol create mode 100644 packages/contracts-bedrock/snapshots/abi/L1BlockCGT.json create mode 100644 packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasserCGT.json create mode 100644 packages/contracts-bedrock/snapshots/abi/LiquidityController.json create mode 100644 packages/contracts-bedrock/snapshots/abi/NativeAssetLiquidity.json create mode 100644 packages/contracts-bedrock/snapshots/storageLayout/L1BlockCGT.json create mode 100644 packages/contracts-bedrock/snapshots/storageLayout/L2ToL1MessagePasserCGT.json create mode 100644 packages/contracts-bedrock/snapshots/storageLayout/LiquidityController.json create mode 100644 packages/contracts-bedrock/snapshots/storageLayout/NativeAssetLiquidity.json create mode 100644 packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol create mode 100644 packages/contracts-bedrock/src/L2/L1BlockCGT.sol create mode 100644 packages/contracts-bedrock/src/L2/L2ToL1MessagePasserCGT.sol create mode 100644 packages/contracts-bedrock/src/L2/LiquidityController.sol create mode 100644 packages/contracts-bedrock/src/L2/NativeAssetLiquidity.sol create mode 100644 packages/contracts-bedrock/test/L1/DepositedOKBAdapter.t.sol create mode 100644 packages/contracts-bedrock/test/L2/LiquidityController.t.sol create mode 100644 packages/contracts-bedrock/test/L2/NativeAssetLiquidity.t.sol create mode 100644 packages/contracts-bedrock/test/bridgeRevert/L1Bridge.t.sol create mode 100644 packages/contracts-bedrock/test/bridgeRevert/L2Bridge.t.sol create mode 100644 packages/contracts-bedrock/test/invariants/CustomGasToken.t.sol create mode 100755 test-pp-op/0-all-local.sh create mode 100755 test-pp-op/1-start-erigon.sh create mode 100755 test-pp-op/2-deploy-op-contracts.sh create mode 100755 test-pp-op/3-stop-erigon.sh create mode 100755 test-pp-op/4-migrate-op.sh create mode 100755 test-pp-op/5-start-op.sh create mode 100755 test-pp-op/6-build-op-program.sh create mode 100755 test-pp-op/7-setup-fraud-proof.sh create mode 100755 test-pp-op/8-prepare-tests.sh create mode 100644 test-pp-op/Makefile create mode 100644 test-pp-op/README.md create mode 100755 test-pp-op/build_images.sh create mode 100644 test-pp-op/config-op/intent.fakemainnet.toml.bak create mode 100644 test-pp-op/config-op/intent.local.toml.bak create mode 100644 test-pp-op/config-op/intent.mainnet.toml.bak create mode 100644 test-pp-op/config-op/intent.testnet.toml.bak create mode 100644 test-pp-op/config-op/intent.toml.bak create mode 100644 test-pp-op/config-op/jwt.txt create mode 100755 test-pp-op/config-op/state.json.bak create mode 100644 test-pp-op/config-op/test.rpc.config.toml create mode 100644 test-pp-op/config-op/test.seq.config.toml create mode 100644 test-pp-op/config/aggkit.toml create mode 100644 test-pp-op/config/agglayer-config.toml create mode 100644 test-pp-op/config/agglayer-prover-config.toml create mode 100644 test-pp-op/config/cdk.config.toml create mode 100644 test-pp-op/config/dynamic-mynetwork-allocs.json create mode 100644 test-pp-op/config/dynamic-mynetwork-chainspec.json create mode 100644 test-pp-op/config/dynamic-mynetwork-conf.json create mode 100644 test-pp-op/config/first-batch-config.json create mode 100644 test-pp-op/config/local/local.erigon.rpc.config.yaml create mode 100644 test-pp-op/config/local/local.erigon.seq.config.yaml create mode 100644 test-pp-op/config/test.bridge.config.toml create mode 100644 test-pp-op/config/test.erigon.rpc.config.yaml create mode 100644 test-pp-op/config/test.erigon.seq.config.yaml create mode 100644 test-pp-op/config/test.genesis.config.json create mode 100644 test-pp-op/config/test.node.config.toml create mode 100644 test-pp-op/config/test.poolmanager.toml create mode 100644 test-pp-op/config/xlayerconfig-mainnet-rpc.yaml create mode 100644 test-pp-op/config/xlayerconfig-mainnet.yaml create mode 100644 test-pp-op/contracts/OKBToken.sol create mode 100644 test-pp-op/contracts/Transactor.sol create mode 100644 test-pp-op/contracts/foundry.toml create mode 100644 test-pp-op/docker-compose-local.yml create mode 100644 test-pp-op/docker-compose.yml create mode 100644 test-pp-op/dockerfile/Dockerfile-cdk-erigon create mode 100644 test-pp-op/dockerfile/Dockerfile.migrate create mode 100644 test-pp-op/dockerfile/Dockerfile.repro create mode 100644 test-pp-op/dockerfile/Dockerfile.repro-builder create mode 100755 test-pp-op/init-erigon.sh create mode 100644 test-pp-op/l1-geth/consensus/config.yml create mode 100644 test-pp-op/l1-geth/execution/genesis-raw.json create mode 100644 test-pp-op/l1-geth/execution/geth_password.txt create mode 100755 test-pp-op/l1-geth/execution/jwtsecret create mode 100644 test-pp-op/l1-geth/execution/keystore/UTC--2022-08-19T17-38-31.257380510Z--123463a4b065722e99115d6c222f267d9cabb524 create mode 100644 test-pp-op/l1-geth/execution/sk.json create mode 100644 test-pp-op/local.env create mode 100755 test-pp-op/m1-deploy-and-upload.sh create mode 100755 test-pp-op/m2-migrate.sh create mode 100755 test-pp-op/m3-verify.sh create mode 100644 test-pp-op/notes.txt create mode 100644 test-pp-op/patch/op-geth-0001-support-load-genesis-at-a-given-number.patch create mode 100644 test-pp-op/patch/optimism-0001-decompress-genesis.patch create mode 100644 test-pp-op/patch/optimism-0001-support-regenesis-op-geth-prestate.patch create mode 100644 test-pp-op/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch create mode 100644 test-pp-op/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch create mode 100644 test-pp-op/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch create mode 100755 test-pp-op/scripts/active-sequencer.sh create mode 100755 test-pp-op/scripts/add-game-type.sh create mode 100755 test-pp-op/scripts/deposit-from-banker.sh create mode 100755 test-pp-op/scripts/deposit-from-l1.sh create mode 100755 test-pp-op/scripts/docker-install-start.sh create mode 100755 test-pp-op/scripts/gray-upgrade-simulation.sh create mode 100755 test-pp-op/scripts/replace-genesis.sh create mode 100755 test-pp-op/scripts/set-init-bond.sh create mode 100755 test-pp-op/scripts/show-dev-accounts.sh create mode 100755 test-pp-op/scripts/stop-leader-sequencer.sh create mode 100755 test-pp-op/scripts/transfer-leader.sh create mode 100644 test-pp-op/tools.sh create mode 100644 test-pp-op/utils.sh create mode 100755 test/init-parallel.sh create mode 100755 test/setup-cgt-function.sh create mode 100755 test/test-cgt.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 557385d223ac7..a79a226bf55cf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -565,7 +565,7 @@ jobs: contracts-bedrock-build: docker: - image: <> - resource_class: xlarge + resource_class: 2xlarge parameters: build_args: description: Forge build arguments @@ -865,7 +865,7 @@ jobs: circleci_ip_ranges: true docker: - image: <> - resource_class: xlarge + resource_class: 2xlarge parameters: test_list: description: List of test files to run @@ -2378,7 +2378,7 @@ workflows: dev_features: <> matrix: parameters: - dev_features: ["main", "OPTIMISM_PORTAL_INTEROP","CANNON_KONA","CANNON_KONA,DEPLOY_V2_DISPUTE_GAMES"] + dev_features: ["main", "OPTIMISM_PORTAL_INTEROP","CANNON_KONA","CANNON_KONA,DEPLOY_V2_DISPUTE_GAMES","CUSTOM_GAS_TOKEN"] # need this requires to ensure that all FFI JSONs exist requires: - contracts-bedrock-build diff --git a/.gitignore b/.gitignore index b95853b53f8fb..405751e77201a 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,7 @@ test/tmp test-apollo/l1-geth test-apollo/config-op test-apollo/data + +test-pp-op/testnet.env +test-pp-op/mainnet.env +test-pp-op/fakemainnet.env diff --git a/Dockerfile-contracts b/Dockerfile-contracts index 457efb953d146..7fae591865bb3 100644 --- a/Dockerfile-contracts +++ b/Dockerfile-contracts @@ -29,7 +29,7 @@ RUN --mount=type=cache,target=/root/.cache \ # Create final contracts image with artifacts, foundry tools, and op-deployer FROM debian:bookworm-slim WORKDIR /app -# RUN apt-get update && apt-get install -y ca-certificates && update-ca-certificates +RUN apt-get update && apt-get install -y ca-certificates && update-ca-certificates # Set environment variables for Go ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt diff --git a/op-acceptance-tests/acceptance-tests.yaml b/op-acceptance-tests/acceptance-tests.yaml index 97d0f0788583a..cf6463614c52d 100644 --- a/op-acceptance-tests/acceptance-tests.yaml +++ b/op-acceptance-tests/acceptance-tests.yaml @@ -132,3 +132,9 @@ gates: tests: - package: github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/jovian timeout: 10m + + - id: cgt + description: "Custom Gas Token (CGT) network tests." + tests: + - package: github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/custom_gas_token + timeout: 10m diff --git a/op-acceptance-tests/justfile b/op-acceptance-tests/justfile index afdf3d4bafd86..79331168e7c30 100644 --- a/op-acceptance-tests/justfile +++ b/op-acceptance-tests/justfile @@ -14,6 +14,9 @@ jovian: interop: @just acceptance-test "" interop +cgt: + @just acceptance-test "" cgt + # Run acceptance tests with mise-managed binary # Usage: just acceptance-test [devnet] [gate] diff --git a/op-acceptance-tests/tests/custom_gas_token/cgt_introspection_test.go b/op-acceptance-tests/tests/custom_gas_token/cgt_introspection_test.go new file mode 100644 index 0000000000000..06a77a3878d8b --- /dev/null +++ b/op-acceptance-tests/tests/custom_gas_token/cgt_introspection_test.go @@ -0,0 +1,25 @@ +package custom_gas_token + +import ( + "testing" + + "github.com/ethereum-optimism/optimism/op-devstack/devtest" + "github.com/ethereum-optimism/optimism/op-devstack/presets" +) + +// TestCGT_IntrospectionViaL1Block verifies that the L2 L1Block predeploy reports +// that CGT mode is enabled and exposes non-empty token metadata (name, symbol). +func TestCGT_IntrospectionViaL1Block(gt *testing.T) { + t := devtest.SerialT(gt) + sys := presets.NewMinimal(t) + + name, symbol := ensureCGTOrSkip(t, sys) + + // Metadata should be non-empty. + if name == "" { + t.Require().Fail("gasPayingTokenName() returned empty string") + } + if symbol == "" { + t.Require().Fail("gasPayingTokenSymbol() returned empty string") + } +} diff --git a/op-acceptance-tests/tests/custom_gas_token/cgt_l1_portal_introspection_test.go b/op-acceptance-tests/tests/custom_gas_token/cgt_l1_portal_introspection_test.go new file mode 100644 index 0000000000000..173476ca3eafb --- /dev/null +++ b/op-acceptance-tests/tests/custom_gas_token/cgt_l1_portal_introspection_test.go @@ -0,0 +1,53 @@ +package custom_gas_token + +import ( + "context" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-devstack/devtest" + "github.com/ethereum-optimism/optimism/op-devstack/presets" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" + "github.com/lmittmann/w3" +) + +// TestCGT_L1PortalIntrospection checks that the L1 OptimismPortal exposes +// a valid SystemConfig address via its systemConfig() view. +func TestCGT_L1PortalIntrospection(gt *testing.T) { + t := devtest.SerialT(gt) + sys := presets.NewMinimal(t) + + // Skip if this devnet is not CGT-enabled (uses your existing gate). + ensureCGTOrSkip(t, sys) + + l1c := sys.L1EL.EthClient() + portal := sys.L2Chain.DepositContractAddr() + + ctx, cancel := context.WithTimeout(t.Ctx(), 20*time.Second) + defer cancel() + + // Portal exposes systemConfig() -> address + systemConfigFunc := w3.MustNewFunc("systemConfig()", "address") + + data, err := systemConfigFunc.EncodeArgs() + if err != nil { + t.Require().Fail("encode systemConfig() args: %v", err) + } + + out, err := l1c.Call(ctx, ethereum.CallMsg{To: &portal, Data: data}, rpc.LatestBlockNumber) + if err != nil { + t.Require().Fail("portal.systemConfig() call failed: %v", err) + } + + var sysCfg common.Address + if err := systemConfigFunc.DecodeReturns(out, &sysCfg); err != nil { + t.Require().Fail("decode portal.systemConfig() returns: %v", err) + } + + if sysCfg == (common.Address{}) { + t.Require().Fail("portal.systemConfig() returned zero address") + } +} diff --git a/op-acceptance-tests/tests/custom_gas_token/cgt_native_payment_test.go b/op-acceptance-tests/tests/custom_gas_token/cgt_native_payment_test.go new file mode 100644 index 0000000000000..2d6ab79b5a61c --- /dev/null +++ b/op-acceptance-tests/tests/custom_gas_token/cgt_native_payment_test.go @@ -0,0 +1,48 @@ +package custom_gas_token + +import ( + "testing" + + "github.com/ethereum-optimism/optimism/op-devstack/devtest" + "github.com/ethereum-optimism/optimism/op-devstack/presets" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +// TestCGT_ValueTransferPaysGasInToken verifies that on CGT chains a simple L2 +// value transfer charges gas in the native ERC-20, and balances reflect +// recipient +amount and sender > amount decrease (amount + gas). +func TestCGT_ValueTransferPaysGasInToken(gt *testing.T) { + t := devtest.SerialT(gt) + sys := presets.NewMinimal(t) + + ensureCGTOrSkip(t, sys) + + sender := sys.FunderL2.NewFundedEOA(eth.OneTenthEther) + recipient := sys.Wallet.NewEOA(sys.L2EL) + + amount := eth.OneHundredthEther + beforeS := sender.GetBalance() + beforeR := recipient.GetBalance() + + // This sends L2 native (CGT) value. + sender.Transfer(recipient.Address(), amount) + + // Wait until recipient reflects the transfer. + // We don't wait on sender balance; it includes gas and is non-deterministic. + recipient.WaitForBalance(beforeR.Add(amount)) + + afterS := sender.GetBalance() + afterR := recipient.GetBalance() + + // Recipient increased by amount + wantR := beforeR.Add(amount) + if afterR != wantR { + t.Require().Fail("recipient balance mismatch: got %s, want %s", afterR, wantR) + } + + // Sender decreased by at least amount (amount + gas). Strict inequality: + if !(beforeS.Sub(afterS)).Gt(amount) { + t.Require().Fail("sender delta must exceed transferred amount (gas must be paid): before=%s after=%s amount=%s", + beforeS, afterS, amount) + } +} diff --git a/op-acceptance-tests/tests/custom_gas_token/cgt_portal_reverts_test.go b/op-acceptance-tests/tests/custom_gas_token/cgt_portal_reverts_test.go new file mode 100644 index 0000000000000..fa1b3a982554b --- /dev/null +++ b/op-acceptance-tests/tests/custom_gas_token/cgt_portal_reverts_test.go @@ -0,0 +1,34 @@ +package custom_gas_token + +import ( + "context" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-devstack/devtest" + "github.com/ethereum-optimism/optimism/op-devstack/presets" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" +) + +// TestCGT_PortalReceiveReverts asserts that sending ETH to the L1 OptimismPortal +// (receive() -> depositTransaction) reverts under CGT, preventing ETH from getting stuck. +func TestCGT_PortalReceiveReverts(gt *testing.T) { + t := devtest.SerialT(gt) + sys := presets.NewMinimal(t) + ensureCGTOrSkip(t, sys) + + l1c := sys.L1EL.EthClient() + portal := sys.L2Chain.DepositContractAddr() + + // Try to send 1 wei to the Portal (receive() -> depositTransaction); should revert in CGT mode. + ctx, cancel := context.WithTimeout(t.Ctx(), 20*time.Second) + defer cancel() + _, err := l1c.EstimateGas(ctx, ethereum.CallMsg{ + To: &portal, + Value: common.Big1, + }) + if err == nil { + t.Require().Fail("expected L1 Portal to revert on direct ETH send in CGT mode, but estimator returned no error") + } +} diff --git a/op-acceptance-tests/tests/custom_gas_token/cgt_reverts_test.go b/op-acceptance-tests/tests/custom_gas_token/cgt_reverts_test.go new file mode 100644 index 0000000000000..30a2277ffafcc --- /dev/null +++ b/op-acceptance-tests/tests/custom_gas_token/cgt_reverts_test.go @@ -0,0 +1,68 @@ +package custom_gas_token + +import ( + "context" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-devstack/devtest" + "github.com/ethereum-optimism/optimism/op-devstack/presets" + "github.com/ethereum-optimism/optimism/op-service/eth" + + "math/big" + + "github.com/ethereum/go-ethereum" + "github.com/lmittmann/w3" +) + +// TestCGT_MessengerRejectsValue ensures that sending native value to the +// L2CrossDomainMessenger reverts under CGT (non-payable path). +func TestCGT_MessengerRejectsValue(gt *testing.T) { + t := devtest.SerialT(gt) + sys := presets.NewMinimal(t) + ensureCGTOrSkip(t, sys) + + ctx, cancel := context.WithTimeout(t.Ctx(), 30*time.Second) + defer cancel() + + from := sys.FunderL2.NewFundedEOA(eth.OneHundredthEther).Address() + _, err := sys.L2EL.Escape().L2EthClient().EstimateGas(ctx, ethereum.CallMsg{ + From: from, + To: &l2XDMAddr, + Value: big.NewInt(1), // 1 wei native + Data: nil, + }) + if err == nil { + t.Require().Fail("expected estimation error when sending value to L2CrossDomainMessenger in CGT mode") + } +} + +// TestCGT_L2StandardBridge_LegacyWithdrawReverts verifies that the legacy +// ETH-specific withdraw path on L2StandardBridge reverts under CGT. +func TestCGT_L2StandardBridge_LegacyWithdrawReverts(gt *testing.T) { + t := devtest.SerialT(gt) + sys := presets.NewMinimal(t) + ensureCGTOrSkip(t, sys) + + ctx, cancel := context.WithTimeout(t.Ctx(), 30*time.Second) + defer cancel() + + withdrawFunc := w3.MustNewFunc("withdraw(address,uint256,uint32,bytes)", "") + + // Any address is fine; the ETH-specific legacy path should be disabled under CGT. + anyAddress := l2XDMAddr + data, err := withdrawFunc.EncodeArgs(anyAddress, big.NewInt(1), uint32(100_000), []byte{}) + if err != nil { + t.Require().Fail("%v", err) + } + + from := sys.FunderL2.NewFundedEOA(eth.OneHundredthEther).Address() + _, err = sys.L2EL.Escape().L2EthClient().EstimateGas(ctx, ethereum.CallMsg{ + From: from, + To: &l2BridgeAddr, + Data: data, + }) + if err == nil { + t.Require().Fail("expected estimation error for L2StandardBridge.withdraw under CGT") + } +} diff --git a/op-acceptance-tests/tests/custom_gas_token/cgt_systemconfig_test.go b/op-acceptance-tests/tests/custom_gas_token/cgt_systemconfig_test.go new file mode 100644 index 0000000000000..a350b8d60f6be --- /dev/null +++ b/op-acceptance-tests/tests/custom_gas_token/cgt_systemconfig_test.go @@ -0,0 +1,107 @@ +package custom_gas_token + +import ( + "context" + "testing" + "time" + + "github.com/ethereum-optimism/optimism/op-devstack/devtest" + "github.com/ethereum-optimism/optimism/op-devstack/presets" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" + "github.com/lmittmann/w3" +) + +// TestCGT_SystemConfigFlagOnL1 checks that the L1 SystemConfig contract reports +// CGT=true via isCustomGasToken(). Skips if the devnet does not wire this flag. +func TestCGT_SystemConfigFlagOnL1(gt *testing.T) { + t := devtest.SerialT(gt) + sys := presets.NewMinimal(t) + ensureCGTOrSkip(t, sys) + + l1c := sys.L1EL.EthClient() + portal := sys.L2Chain.DepositContractAddr() + + systemConfigFunc := w3.MustNewFunc("systemConfig()", "address") + isCustomGasTokenFunc := w3.MustNewFunc("isCustomGasToken()", "bool") + + ctx, cancel := context.WithTimeout(t.Ctx(), 20*time.Second) + defer cancel() + + // Resolve SystemConfig via Portal.systemConfig() + data, _ := systemConfigFunc.EncodeArgs() + out, err := l1c.Call(ctx, ethereum.CallMsg{To: &portal, Data: data}, rpc.LatestBlockNumber) + if err != nil { + t.Require().Fail("portal.systemConfig() call failed: %v", err) + } + var sysCfg common.Address + if err := systemConfigFunc.DecodeReturns(out, &sysCfg); err != nil { + t.Require().Fail("unpack portal.systemConfig() failed: %v", err) + } + if (sysCfg == common.Address{}) { + t.Require().Fail("portal.systemConfig() returned zero address") + } + + // Ask SystemConfig whether CGT is enabled. + data, _ = isCustomGasTokenFunc.EncodeArgs() + out, err = l1c.Call(ctx, ethereum.CallMsg{To: &sysCfg, Data: data}, rpc.LatestBlockNumber) + if err != nil { + t.Require().Fail("SystemConfig.isCustomGasToken() call failed: %v", err) + } + var isCustom bool + if err := isCustomGasTokenFunc.DecodeReturns(out, &isCustom); err != nil { + t.Require().Fail("unpack isCustomGasToken failed: %v", err) + } + if !isCustom { + t.Skip("SystemConfig.isCustomGasToken() = false on this devnet; skipping") + } +} + +// TestCGT_SystemConfigFeatureFlag re-validates the CGT flag on SystemConfig, +// using locally encoded calls (mirrors the previous test structure). Skips on devnets without the flag. +func TestCGT_SystemConfigFeatureFlag(gt *testing.T) { + t := devtest.SerialT(gt) + sys := presets.NewMinimal(t) + + // Skip if not in CGT mode (uses L2 L1Block.isCustomGasToken()). + ensureCGTOrSkip(t, sys) + + l1c := sys.L1EL.EthClient() + portal := sys.L2Chain.DepositContractAddr() + + ctx, cancel := context.WithTimeout(t.Ctx(), 20*time.Second) + defer cancel() + + // Resolve SystemConfig via Portal.systemConfig() + systemConfigFunc := w3.MustNewFunc("systemConfig()", "address") + isCustomGasTokenFunc := w3.MustNewFunc("isCustomGasToken()", "bool") + + data, _ := systemConfigFunc.EncodeArgs() + out, err := l1c.Call(ctx, ethereum.CallMsg{To: &portal, Data: data}, rpc.LatestBlockNumber) + if err != nil { + t.Require().Fail("portal.systemConfig() call failed: %v", err) + } + var sysCfg common.Address + if err := systemConfigFunc.DecodeReturns(out, &sysCfg); err != nil { + t.Require().Fail("unpack portal.systemConfig() failed: %v", err) + } + + // Query the CGT flag on SystemConfig via IGasToken.isCustomGasToken(). + data, _ = isCustomGasTokenFunc.EncodeArgs() + out, err = l1c.Call(ctx, ethereum.CallMsg{ + To: &sysCfg, + Data: data, + }, rpc.LatestBlockNumber) + if err != nil { + t.Require().Fail("SystemConfig.isCustomGasToken() call failed: %v", err) + } + var flag bool + if err := isCustomGasTokenFunc.DecodeReturns(out, &flag); err != nil { + t.Require().Fail("unpack isCustomGasToken failed: %v", err) + } + if !flag { + t.Skip("SystemConfig.isCustomGasToken() = false on this devnet; skipping") + } +} diff --git a/op-acceptance-tests/tests/custom_gas_token/helpers.go b/op-acceptance-tests/tests/custom_gas_token/helpers.go new file mode 100644 index 0000000000000..f76228df3a682 --- /dev/null +++ b/op-acceptance-tests/tests/custom_gas_token/helpers.go @@ -0,0 +1,70 @@ +// op-acceptance-tests/tests/custom_gas_token/helpers.go +package custom_gas_token + +import ( + "context" + "time" + + "github.com/ethereum-optimism/optimism/op-devstack/devtest" + "github.com/ethereum-optimism/optimism/op-devstack/presets" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" + "github.com/lmittmann/w3" +) + +var ( + // L2 predeploy: L1Block (address is stable across OP Stack chains) + l1BlockAddr = common.HexToAddress("0x4200000000000000000000000000000000000015") + + // L2 predeploy: L2CrossDomainMessenger & L2StandardBridge (for revert checks) + l2XDMAddr = common.HexToAddress("0x4200000000000000000000000000000000000007") + l2BridgeAddr = common.HexToAddress("0x4200000000000000000000000000000000000010") +) + +// ensureCGTOrSkip probes L2 L1Block for CGT mode. If not enabled, the test is skipped. +// Returns (name, symbol). +func ensureCGTOrSkip(t devtest.T, sys *presets.Minimal) (string, string) { + l2 := sys.L2EL.Escape().L2EthClient() + + isCustomGasTokenFunc := w3.MustNewFunc("isCustomGasToken()", "bool") + gasPayingTokenNameFunc := w3.MustNewFunc("gasPayingTokenName()", "string") + gasPayingTokenSymbolFunc := w3.MustNewFunc("gasPayingTokenSymbol()", "string") + + ctx, cancel := context.WithTimeout(t.Ctx(), 20*time.Second) + defer cancel() + + // isCustomGasToken() + data, _ := isCustomGasTokenFunc.EncodeArgs() + out, err := l2.Call(ctx, ethereum.CallMsg{To: &l1BlockAddr, Data: data}, rpc.LatestBlockNumber) + if err != nil { + t.Skipf("CGT not enabled (isCustomGasToken() call failed): %v", err) + } + var isCustom bool + if err := isCustomGasTokenFunc.DecodeReturns(out, &isCustom); err != nil { + t.Require().NoError(err) + } + if !isCustom { + t.Skip("CGT disabled on this devnet (native ETH mode detected)") + } + + // Read metadata (name/symbol) + data, _ = gasPayingTokenNameFunc.EncodeArgs() + out, err = l2.Call(ctx, ethereum.CallMsg{To: &l1BlockAddr, Data: data}, rpc.LatestBlockNumber) + t.Require().NoError(err) + var name string + if err := gasPayingTokenNameFunc.DecodeReturns(out, &name); err != nil { + t.Require().NoError(err) + } + + data, _ = gasPayingTokenSymbolFunc.EncodeArgs() + out, err = l2.Call(ctx, ethereum.CallMsg{To: &l1BlockAddr, Data: data}, rpc.LatestBlockNumber) + t.Require().NoError(err) + var symbol string + if err := gasPayingTokenSymbolFunc.DecodeReturns(out, &symbol); err != nil { + t.Require().NoError(err) + } + + return name, symbol +} diff --git a/op-acceptance-tests/tests/custom_gas_token/init_test.go b/op-acceptance-tests/tests/custom_gas_token/init_test.go new file mode 100644 index 0000000000000..e3aa47385cbf8 --- /dev/null +++ b/op-acceptance-tests/tests/custom_gas_token/init_test.go @@ -0,0 +1,22 @@ +package custom_gas_token + +import ( + "math/big" + "testing" + + "github.com/ethereum-optimism/optimism/op-devstack/presets" + "github.com/ethereum-optimism/optimism/op-devstack/stack" + "github.com/ethereum-optimism/optimism/op-devstack/sysgo" +) + +func TestMain(m *testing.M) { + // Create a CGT-enabled devnet with 1M tokens of liquidity + liq := new(big.Int).Mul(big.NewInt(1_000_000), big.NewInt(1e18)) // 1M tokens * 18 decimals + + presets.DoMain(m, + presets.WithMinimal(), + stack.MakeCommon(sysgo.WithDeployerOptions( + sysgo.WithCustomGasToken(true, "Custom Gas Token", "CGT", liq), + )), + ) +} diff --git a/op-chain-ops/genesis/config.go b/op-chain-ops/genesis/config.go index c4acf5d16d201..12319135f535f 100644 --- a/op-chain-ops/genesis/config.go +++ b/op-chain-ops/genesis/config.go @@ -275,18 +275,29 @@ func (d *GasPriceOracleDeployConfig) OperatorFeeParams() [32]byte { type GasTokenDeployConfig struct { // UseCustomGasToken is a flag to indicate that a custom gas token should be used UseCustomGasToken bool `json:"useCustomGasToken"` - // CustomGasTokenAddress is the address of the ERC20 token to be used to pay for gas on L2. - CustomGasTokenAddress common.Address `json:"customGasTokenAddress"` + // GasPayingTokenName represents the custom gas token name. + GasPayingTokenName string `json:"gasPayingTokenName"` + // GasPayingTokenSymbol represents the custom gas token symbol. + GasPayingTokenSymbol string `json:"gasPayingTokenSymbol"` + // NativeAssetLiquidityAmount represents the amount of liquidity to pre-fund the NativeAssetLiquidity contract with. + NativeAssetLiquidityAmount *hexutil.Big `json:"nativeAssetLiquidityAmount"` } var _ ConfigChecker = (*GasTokenDeployConfig)(nil) func (d *GasTokenDeployConfig) Check(log log.Logger) error { if d.UseCustomGasToken { - if d.CustomGasTokenAddress == (common.Address{}) { - return fmt.Errorf("%w: CustomGasTokenAddress cannot be address(0)", ErrInvalidDeployConfig) + if d.GasPayingTokenName == "" { + return fmt.Errorf("%w: GasPayingTokenName cannot be empty", ErrInvalidDeployConfig) } - log.Info("Using custom gas token", "address", d.CustomGasTokenAddress) + if d.GasPayingTokenSymbol == "" { + return fmt.Errorf("%w: GasPayingTokenSymbol cannot be empty", ErrInvalidDeployConfig) + } + if d.NativeAssetLiquidityAmount == nil || d.NativeAssetLiquidityAmount.ToInt().Sign() < 0 { + return fmt.Errorf("%w: NativeAssetLiquidityAmount cannot be nil or negative", ErrInvalidDeployConfig) + } + + log.Info("Using custom gas token", "name", d.GasPayingTokenName, "symbol", d.GasPayingTokenSymbol, "nativeAssetLiquidityAmount", d.NativeAssetLiquidityAmount.ToInt()) } return nil } diff --git a/op-chain-ops/genesis/testdata/test-deploy-config-full.json b/op-chain-ops/genesis/testdata/test-deploy-config-full.json index 0f332842204f9..71ac6fae51b9b 100644 --- a/op-chain-ops/genesis/testdata/test-deploy-config-full.json +++ b/op-chain-ops/genesis/testdata/test-deploy-config-full.json @@ -6,7 +6,6 @@ "maxSequencerDrift": 20, "sequencerWindowSize": 100, "channelTimeout": 30, - "customGasTokenAddress": "0x0000000000000000000000000000000000000000", "p2pSequencerAddress": "0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc", "batchInboxAddress": "0x42000000000000000000000000000000000000ff", "batchSenderAddress": "0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc", @@ -85,6 +84,9 @@ "disputeGameFinalityDelaySeconds": 6, "respectedGameType": 0, "useCustomGasToken": false, + "gasPayingTokenName": "", + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null, "useFaultProofs": false, "useAltDA": false, "daBondSize": 0, diff --git a/op-chain-ops/interopgen/deploy.go b/op-chain-ops/interopgen/deploy.go index 987e6683ae3b4..de3ec36007fe0 100644 --- a/op-chain-ops/interopgen/deploy.go +++ b/op-chain-ops/interopgen/deploy.go @@ -335,6 +335,10 @@ func GenesisL2(l2Host *script.Host, cfg *L2Config, deployment *L2Deployment, mul DeployCrossL2Inbox: multichainDepSet, EnableGovernance: cfg.EnableGovernance, FundDevAccounts: cfg.FundDevAccounts, + UseCustomGasToken: cfg.UseCustomGasToken, + GasPayingTokenName: cfg.GasPayingTokenName, + GasPayingTokenSymbol: cfg.GasPayingTokenSymbol, + NativeAssetLiquidityAmount: cfg.NativeAssetLiquidityAmount.ToInt(), }); err != nil { return fmt.Errorf("failed L2 genesis: %w", err) } diff --git a/op-chain-ops/interopgen/recipe.go b/op-chain-ops/interopgen/recipe.go index 2d40c4451c94d..f780f83f35a13 100644 --- a/op-chain-ops/interopgen/recipe.go +++ b/op-chain-ops/interopgen/recipe.go @@ -243,7 +243,10 @@ func (r *InteropDevL2Recipe) build(l1ChainID uint64, addrs devkeys.Addresses) (* GasPriceOracleBlobBaseFeeScalar: 810949, }, GasTokenDeployConfig: genesis.GasTokenDeployConfig{ - UseCustomGasToken: false, + UseCustomGasToken: false, + GasPayingTokenName: "", + GasPayingTokenSymbol: "", + NativeAssetLiquidityAmount: (*hexutil.Big)(big.NewInt(0)), }, OperatorDeployConfig: genesis.OperatorDeployConfig{ P2PSequencerAddress: sequencerP2P, diff --git a/op-deployer/pkg/deployer/devfeatures.go b/op-deployer/pkg/deployer/devfeatures.go index 8e62bb1a42fd4..241c9a52d28b2 100644 --- a/op-deployer/pkg/deployer/devfeatures.go +++ b/op-deployer/pkg/deployer/devfeatures.go @@ -17,6 +17,9 @@ var ( // DeployV2DisputeGamesDevFlag enables deployment of V2 dispute game contracts. DeployV2DisputeGamesDevFlag = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000100") + + // CustomGasToken enables the custom gas token. + CustomGasToken = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000001000") ) // IsDevFeatureEnabled checks if a specific development feature is enabled in a feature bitmap. diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index 390c37de14492..b3f70e0f6229e 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -13,6 +13,8 @@ import ( "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/bootstrap" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/inspect" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/integration_test/shared" + + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/params" "github.com/ethereum-optimism/optimism/op-service/testutils" @@ -34,6 +36,7 @@ import ( op_e2e "github.com/ethereum-optimism/optimism/op-e2e" "github.com/holiman/uint256" + "github.com/lmittmann/w3" "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis" @@ -226,6 +229,59 @@ func TestEndToEndApply(t *testing.T) { require.NoError(t, err) } }) + + t.Run("with custom gas token", func(t *testing.T) { + intent, st := shared.NewIntent(t, l1ChainID, dk, l2ChainID1, loc, loc, testCustomGasLimit) + + // CGT config for L2 genesis + amount := new(big.Int) + amount.SetString("1000000000000000000000", 10) + intent.Chains[0].CustomGasToken = state.CustomGasToken{ + Enabled: true, + Name: "Custom Gas Token", + Symbol: "CGT", + InitialLiquidity: (*hexutil.Big)(amount), + } + // CGT config for OPCM + intent.GlobalDeployOverrides = map[string]interface{}{ + "devFeatureBitmap": deployer.CustomGasToken, + } + + require.NoError(t, deployer.ApplyPipeline(ctx, deployer.ApplyPipelineOpts{ + DeploymentTarget: deployer.DeploymentTargetLive, + L1RPCUrl: l1RPC, + DeployerPrivateKey: pk, + Intent: intent, + State: st, + Logger: lgr, + StateWriter: pipeline.NoopStateWriter(), + CacheDir: testCacheDir, + })) + + systemConfig := st.Chains[0].SystemConfigProxy + fn := w3.MustNewFunc("isFeatureEnabled(bytes32)", "bool") + // bytes32("CUSTOM_GAS_TOKEN") + data, err := fn.EncodeArgs(w3.H("0x435553544f4d5f4741535f544f4b454e00000000000000000000000000000000")) + require.NoError(t, err) + + res, err := l1Client.CallContract(ctx, ethereum.CallMsg{ + To: &systemConfig, + Data: data, + }, nil) + require.NoError(t, err) + + var response bool + err = fn.DecodeReturns(res, &response) + require.NoError(t, err) + require.Equal(t, true, response) + + // Check that the native asset liquidity predeploy has the configured amount in L2 genesis + nativeAssetLiquidityAddr := common.HexToAddress("0x4200000000000000000000000000000000000029") + l2Genesis := st.Chains[0].Allocs.Data.Accounts + account, exists := l2Genesis[nativeAssetLiquidityAddr] + require.True(t, exists, "Native asset liquidity predeploy should exist in L2 genesis") + require.Equal(t, amount, account.Balance, "Native asset liquidity predeploy should have the configured balance") + }) } func TestGlobalOverrides(t *testing.T) { diff --git a/op-deployer/pkg/deployer/integration_test/shared/shared.go b/op-deployer/pkg/deployer/integration_test/shared/shared.go index 296d56104a717..702e7a7fe4aeb 100644 --- a/op-deployer/pkg/deployer/integration_test/shared/shared.go +++ b/op-deployer/pkg/deployer/integration_test/shared/shared.go @@ -42,6 +42,11 @@ func NewChainIntent(t *testing.T, dk *devkeys.MnemonicDevKeys, l1ChainID *big.In Proposer: AddrFor(t, dk, devkeys.ProposerRole.Key(l1ChainID)), Challenger: AddrFor(t, dk, devkeys.ChallengerRole.Key(l1ChainID)), }, + CustomGasToken: state.CustomGasToken{ + Enabled: false, + Name: "", + Symbol: "", + }, } } diff --git a/op-deployer/pkg/deployer/manage/testdata/state.json b/op-deployer/pkg/deployer/manage/testdata/state.json index c99554e1e9731..d8e562c51dd83 100755 --- a/op-deployer/pkg/deployer/manage/testdata/state.json +++ b/op-deployer/pkg/deployer/manage/testdata/state.json @@ -31,6 +31,12 @@ "batcher": "0x0000000000000000000000000000000000000006", "proposer": "0x0000000000000000000000000000000000000007", "challenger": "0xfd1d2e729ae8eee2e146c033bf4400fe75284301" + }, + "customGasToken": { + "enabled": false, + "name": "", + "symbol": "", + "initialLiquidity": null } } ], @@ -57,4 +63,3 @@ "l1StateDump": null, "DeploymentCalldata": null } - diff --git a/op-deployer/pkg/deployer/opcm/l2genesis.go b/op-deployer/pkg/deployer/opcm/l2genesis.go index 3f91196cc85fc..92e39307678a1 100644 --- a/op-deployer/pkg/deployer/opcm/l2genesis.go +++ b/op-deployer/pkg/deployer/opcm/l2genesis.go @@ -28,6 +28,10 @@ type L2GenesisInput struct { DeployCrossL2Inbox bool EnableGovernance bool FundDevAccounts bool + UseCustomGasToken bool + GasPayingTokenName string + GasPayingTokenSymbol string + NativeAssetLiquidityAmount *big.Int } type L2GenesisScript script.DeployScriptWithoutOutput[L2GenesisInput] diff --git a/op-deployer/pkg/deployer/pipeline/l2genesis.go b/op-deployer/pkg/deployer/pipeline/l2genesis.go index bb3f514358bce..a9b9a77b5993c 100644 --- a/op-deployer/pkg/deployer/pipeline/l2genesis.go +++ b/op-deployer/pkg/deployer/pipeline/l2genesis.go @@ -22,6 +22,13 @@ import ( ) type l2GenesisOverrides struct { + // ===== CUSTOM GAS TOKEN (CGT) CONFIGURATION ===== + UseCustomGasToken bool `json:"useCustomGasToken"` // CGT: Enable custom gas token mode + GasPayingTokenName string `json:"gasPayingTokenName"` // CGT: Name of the custom gas token + GasPayingTokenSymbol string `json:"gasPayingTokenSymbol"` // CGT: Symbol of the custom gas token + NativeAssetLiquidityAmount *hexutil.Big `json:"nativeAssetLiquidityAmount"` // CGT: Liquidity amount for NativeAssetLiquidity contract + + // ===== GENERAL L2 CONFIGURATION (NON-CGT) ===== FundDevAccounts bool `json:"fundDevAccounts"` BaseFeeVaultMinimumWithdrawalAmount *hexutil.Big `json:"baseFeeVaultMinimumWithdrawalAmount"` L1FeeVaultMinimumWithdrawalAmount *hexutil.Big `json:"l1FeeVaultMinimumWithdrawalAmount"` @@ -94,6 +101,11 @@ func GenerateL2Genesis(pEnv *Env, intent *state.Intent, bundle ArtifactsBundle, DeployCrossL2Inbox: len(intent.Chains) > 1, EnableGovernance: overrides.EnableGovernance, FundDevAccounts: overrides.FundDevAccounts, + // Custom Gas Token (CGT) configuration passed to L2Genesis script + UseCustomGasToken: thisIntent.CustomGasToken.Enabled, // CGT: Enable/disable custom gas token + GasPayingTokenName: thisIntent.CustomGasToken.Name, // CGT: Token name (e.g., "Custom Gas Token") + GasPayingTokenSymbol: thisIntent.CustomGasToken.Symbol, // CGT: Token symbol (e.g., "CGT") + NativeAssetLiquidityAmount: thisIntent.GetInitialLiquidity(), // CGT: Liquidity amount for NativeAssetLiquidity contract }); err != nil { return fmt.Errorf("failed to call L2Genesis script: %w", err) } @@ -142,6 +154,16 @@ func calculateL2GenesisOverrides(intent *state.Intent, thisIntent *state.ChainIn } } + // If CustomGasToken is not enabled, update it with override values + if !thisIntent.CustomGasToken.Enabled { + thisIntent.CustomGasToken = state.CustomGasToken{ + Enabled: overrides.UseCustomGasToken, + Name: overrides.GasPayingTokenName, + Symbol: overrides.GasPayingTokenSymbol, + InitialLiquidity: overrides.NativeAssetLiquidityAmount, + } + } + return overrides, schedule, nil } @@ -156,6 +178,7 @@ func wdNetworkToBig(wd genesis.WithdrawalNetwork) *big.Int { func defaultOverrides() l2GenesisOverrides { return l2GenesisOverrides{ + // ===== GENERAL L2 DEFAULTS ===== FundDevAccounts: false, BaseFeeVaultMinimumWithdrawalAmount: standard.VaultMinWithdrawalAmount, L1FeeVaultMinimumWithdrawalAmount: standard.VaultMinWithdrawalAmount, @@ -165,5 +188,10 @@ func defaultOverrides() l2GenesisOverrides { SequencerFeeVaultWithdrawalNetwork: "local", EnableGovernance: false, GovernanceTokenOwner: standard.GovernanceTokenOwner, + // ===== CGT DEFAULTS ===== + UseCustomGasToken: false, // CGT disabled by default + GasPayingTokenName: "", // Empty when CGT disabled + GasPayingTokenSymbol: "", // Empty when CGT disabled + NativeAssetLiquidityAmount: (*hexutil.Big)(big.NewInt(0)), // Default to 0 when CGT disabled (consistent with "" and false) } } diff --git a/op-deployer/pkg/deployer/pipeline/l2genesis_test.go b/op-deployer/pkg/deployer/pipeline/l2genesis_test.go index aed2a1e782390..65bcf4860cb65 100644 --- a/op-deployer/pkg/deployer/pipeline/l2genesis_test.go +++ b/op-deployer/pkg/deployer/pipeline/l2genesis_test.go @@ -43,17 +43,11 @@ func TestCalculateL2GenesisOverrides(t *testing.T) { }, chainIntent: &state.ChainIntent{}, expectError: false, - expectedOverrides: l2GenesisOverrides{ - FundDevAccounts: true, - BaseFeeVaultMinimumWithdrawalAmount: standard.VaultMinWithdrawalAmount, - L1FeeVaultMinimumWithdrawalAmount: standard.VaultMinWithdrawalAmount, - SequencerFeeVaultMinimumWithdrawalAmount: standard.VaultMinWithdrawalAmount, - BaseFeeVaultWithdrawalNetwork: "local", - L1FeeVaultWithdrawalNetwork: "local", - SequencerFeeVaultWithdrawalNetwork: "local", - EnableGovernance: false, - GovernanceTokenOwner: standard.GovernanceTokenOwner, - }, + expectedOverrides: func() l2GenesisOverrides { + defaults := defaultOverrides() + defaults.FundDevAccounts = true + return defaults + }(), expectedSchedule: func() *genesis.UpgradeScheduleDeployConfig { return standard.DefaultHardforkScheduleForTag("") }, @@ -73,21 +67,28 @@ func TestCalculateL2GenesisOverrides(t *testing.T) { "enableGovernance": true, "governanceTokenOwner": "0x1111111111111111111111111111111111111111", "l2GenesisInteropTimeOffset": "0x1234", + "useCustomGasToken": false, + "gasPayingTokenName": "", + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": "0x0", }, }, chainIntent: &state.ChainIntent{}, expectError: false, - expectedOverrides: l2GenesisOverrides{ - FundDevAccounts: true, - BaseFeeVaultMinimumWithdrawalAmount: (*hexutil.Big)(hexutil.MustDecodeBig("0x1234")), - L1FeeVaultMinimumWithdrawalAmount: (*hexutil.Big)(hexutil.MustDecodeBig("0x2345")), - SequencerFeeVaultMinimumWithdrawalAmount: (*hexutil.Big)(hexutil.MustDecodeBig("0x3456")), - BaseFeeVaultWithdrawalNetwork: "remote", - L1FeeVaultWithdrawalNetwork: "remote", - SequencerFeeVaultWithdrawalNetwork: "remote", - EnableGovernance: true, - GovernanceTokenOwner: common.HexToAddress("0x1111111111111111111111111111111111111111"), - }, + expectedOverrides: func() l2GenesisOverrides { + defaults := defaultOverrides() + defaults.FundDevAccounts = true + defaults.BaseFeeVaultMinimumWithdrawalAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x1234")) + defaults.L1FeeVaultMinimumWithdrawalAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x2345")) + defaults.SequencerFeeVaultMinimumWithdrawalAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x3456")) + defaults.BaseFeeVaultWithdrawalNetwork = "remote" + defaults.L1FeeVaultWithdrawalNetwork = "remote" + defaults.SequencerFeeVaultWithdrawalNetwork = "remote" + defaults.EnableGovernance = true + defaults.GovernanceTokenOwner = common.HexToAddress("0x1111111111111111111111111111111111111111") + defaults.NativeAssetLiquidityAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x0")) + return defaults + }(), expectedSchedule: func() *genesis.UpgradeScheduleDeployConfig { sched := standard.DefaultHardforkScheduleForTag("") sched.L2GenesisInteropTimeOffset = op_service.U64UtilPtr(0x1234) @@ -114,20 +115,27 @@ func TestCalculateL2GenesisOverrides(t *testing.T) { "enableGovernance": true, "governanceTokenOwner": "0x1111111111111111111111111111111111111111", "l2GenesisInteropTimeOffset": "0x1234", + "useCustomGasToken": false, + "gasPayingTokenName": "", + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": "0x0", }, }, expectError: false, - expectedOverrides: l2GenesisOverrides{ - FundDevAccounts: true, - BaseFeeVaultMinimumWithdrawalAmount: (*hexutil.Big)(hexutil.MustDecodeBig("0x1234")), - L1FeeVaultMinimumWithdrawalAmount: (*hexutil.Big)(hexutil.MustDecodeBig("0x2345")), - SequencerFeeVaultMinimumWithdrawalAmount: (*hexutil.Big)(hexutil.MustDecodeBig("0x3456")), - BaseFeeVaultWithdrawalNetwork: "remote", - L1FeeVaultWithdrawalNetwork: "remote", - SequencerFeeVaultWithdrawalNetwork: "remote", - EnableGovernance: true, - GovernanceTokenOwner: common.HexToAddress("0x1111111111111111111111111111111111111111"), - }, + expectedOverrides: func() l2GenesisOverrides { + defaults := defaultOverrides() + defaults.FundDevAccounts = true + defaults.BaseFeeVaultMinimumWithdrawalAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x1234")) + defaults.L1FeeVaultMinimumWithdrawalAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x2345")) + defaults.SequencerFeeVaultMinimumWithdrawalAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x3456")) + defaults.BaseFeeVaultWithdrawalNetwork = "remote" + defaults.L1FeeVaultWithdrawalNetwork = "remote" + defaults.SequencerFeeVaultWithdrawalNetwork = "remote" + defaults.EnableGovernance = true + defaults.GovernanceTokenOwner = common.HexToAddress("0x1111111111111111111111111111111111111111") + defaults.NativeAssetLiquidityAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x0")) + return defaults + }(), expectedSchedule: func() *genesis.UpgradeScheduleDeployConfig { sched := standard.DefaultHardforkScheduleForTag("") sched.L2GenesisInteropTimeOffset = op_service.U64UtilPtr(0x1234) @@ -140,11 +148,17 @@ func TestCalculateL2GenesisOverrides(t *testing.T) { L1ContractsLocator: &artifacts.Locator{}, GlobalDeployOverrides: map[string]any{ "l2GenesisInteropTimeOffset": "0x0", + "nativeAssetLiquidityAmount": "0x0", }, }, - chainIntent: &state.ChainIntent{}, - expectError: false, - expectedOverrides: defaultOverrides(), + chainIntent: &state.ChainIntent{}, + expectError: false, + expectedOverrides: func() l2GenesisOverrides { + defaults := defaultOverrides() + // Override with the same value that comes from JSON merge to match internal representation + defaults.NativeAssetLiquidityAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x0")) + return defaults + }(), expectedSchedule: func() *genesis.UpgradeScheduleDeployConfig { schedule := standard.DefaultHardforkScheduleForTag("") schedule.L2GenesisInteropTimeOffset = op_service.U64UtilPtr(0) diff --git a/op-deployer/pkg/deployer/state/chain_intent.go b/op-deployer/pkg/deployer/state/chain_intent.go index 819bc9e3f1f9f..0686e3f3e3c8e 100644 --- a/op-deployer/pkg/deployer/state/chain_intent.go +++ b/op-deployer/pkg/deployer/state/chain_intent.go @@ -2,6 +2,7 @@ package state import ( "fmt" + "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -56,6 +57,13 @@ type L2DevGenesisParams struct { Prefund map[common.Address]*hexutil.U256 `json:"prefund" toml:"prefund"` } +type CustomGasToken struct { + Enabled bool `json:"enabled" toml:"enabled"` + Name string `json:"name,omitempty" toml:"name,omitempty"` + Symbol string `json:"symbol,omitempty" toml:"symbol,omitempty"` + InitialLiquidity *hexutil.Big `json:"initialLiquidity,omitempty" toml:"initialLiquidity,omitempty"` +} + type ChainIntent struct { ID common.Hash `json:"id" toml:"id"` BaseFeeVaultRecipient common.Address `json:"baseFeeVaultRecipient" toml:"baseFeeVaultRecipient"` @@ -73,7 +81,7 @@ type ChainIntent struct { OperatorFeeConstant uint64 `json:"operatorFeeConstant,omitempty" toml:"operatorFeeConstant,omitempty"` L1StartBlockHash *common.Hash `json:"l1StartBlockHash,omitempty" toml:"l1StartBlockHash,omitempty"` MinBaseFee uint64 `json:"minBaseFee,omitempty" toml:"minBaseFee,omitempty"` - + CustomGasToken CustomGasToken `json:"customGasToken" toml:"customGasToken"` // Optional. For development purposes only. Only enabled if the operation mode targets a genesis-file output. L2DevGenesisParams *L2DevGenesisParams `json:"l2DevGenesisParams,omitempty" toml:"l2DevGenesisParams,omitempty"` } @@ -119,9 +127,32 @@ func (c *ChainIntent) Check() error { return fmt.Errorf("%w: chainId=%s", ErrFeeVaultZeroAddress, c.ID) } + if c.CustomGasToken.Enabled { + if c.CustomGasToken.Name == "" { + return fmt.Errorf("%w: CustomGasToken.Name cannot be empty when enabled, chainId=%s", ErrIncompatibleValue, c.ID) + } + if c.CustomGasToken.Symbol == "" { + return fmt.Errorf("%w: CustomGasToken.Symbol cannot be empty when enabled, chainId=%s", ErrIncompatibleValue, c.ID) + } + + if c.CustomGasToken.InitialLiquidity == nil || c.CustomGasToken.InitialLiquidity.ToInt().Sign() < 0 { + return fmt.Errorf("%w: CustomGasToken.InitialLiquidity must be set and non-negative when custom gas token is enabled, chainId=%s", ErrIncompatibleValue, c.ID) + } + } + if c.DangerousAltDAConfig.UseAltDA { return c.DangerousAltDAConfig.Check(nil) } return nil } + +// GetInitialLiquidity returns the native asset liquidity amount for the chain. +// If not set, returns the default value of zero. +func (c *ChainIntent) GetInitialLiquidity() *big.Int { + if c.CustomGasToken.InitialLiquidity != nil { + return c.CustomGasToken.InitialLiquidity.ToInt() + } + + return (*hexutil.Big)(big.NewInt(0)).ToInt() +} diff --git a/op-deployer/pkg/deployer/state/deploy_config.go b/op-deployer/pkg/deployer/state/deploy_config.go index 5e3cde1f1b3d7..0a801be8c0005 100644 --- a/op-deployer/pkg/deployer/state/deploy_config.go +++ b/op-deployer/pkg/deployer/state/deploy_config.go @@ -71,6 +71,13 @@ func CombineDeployConfig(intent *Intent, chainIntent *ChainIntent, state *State, EIP1559Elasticity: chainIntent.Eip1559Elasticity, }, + GasTokenDeployConfig: genesis.GasTokenDeployConfig{ + UseCustomGasToken: chainIntent.CustomGasToken.Enabled, + GasPayingTokenName: chainIntent.CustomGasToken.Name, + GasPayingTokenSymbol: chainIntent.CustomGasToken.Symbol, + NativeAssetLiquidityAmount: chainIntent.CustomGasToken.InitialLiquidity, + }, + // STOP! This struct sets the _default_ upgrade schedule for all chains. // Any upgrades you enable here will be enabled for all new deployments. // In-development hardforks should never be activated here. Instead, they @@ -108,15 +115,11 @@ func CombineDeployConfig(intent *Intent, chainIntent *ChainIntent, state *State, if chainState.StartBlock == nil { // These are dummy variables - see below for rationale. - num := rpc.LatestBlockNumber - cfg.L1StartingBlockTag = &genesis.MarshalableRPCBlockNumberOrHash{ - BlockNumber: &num, - } + blockNumOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) + cfg.L1StartingBlockTag = (*genesis.MarshalableRPCBlockNumberOrHash)(&blockNumOrHash) } else { - startHash := chainState.StartBlock.Hash - cfg.L1StartingBlockTag = &genesis.MarshalableRPCBlockNumberOrHash{ - BlockHash: &startHash, - } + blockNumOrHash := rpc.BlockNumberOrHashWithHash(chainState.StartBlock.Hash, false) + cfg.L1StartingBlockTag = (*genesis.MarshalableRPCBlockNumberOrHash)(&blockNumOrHash) } if chainIntent.DangerousAltDAConfig.UseAltDA { diff --git a/op-deployer/pkg/deployer/state/deploy_config_test.go b/op-deployer/pkg/deployer/state/deploy_config_test.go index a91a90a8cbcb8..48c69a19dfdd9 100644 --- a/op-deployer/pkg/deployer/state/deploy_config_test.go +++ b/op-deployer/pkg/deployer/state/deploy_config_test.go @@ -1,6 +1,7 @@ package state import ( + "math/big" "testing" "github.com/ethereum-optimism/optimism/op-chain-ops/addresses" @@ -33,6 +34,12 @@ func TestCombineDeployConfig(t *testing.T) { UnsafeBlockSigner: common.HexToAddress("0xabc"), Batcher: common.HexToAddress("0xdef"), }, + CustomGasToken: CustomGasToken{ + Enabled: false, + Name: "", + Symbol: "", + InitialLiquidity: (*hexutil.Big)(big.NewInt(0)), + }, } state := State{ SuperchainDeployment: &addresses.SuperchainContracts{ProtocolVersionsProxy: common.HexToAddress("0x123")}, diff --git a/op-deployer/pkg/deployer/state/intent.go b/op-deployer/pkg/deployer/state/intent.go index 8c331e9f64296..b645cf55b906e 100644 --- a/op-deployer/pkg/deployer/state/intent.go +++ b/op-deployer/pkg/deployer/state/intent.go @@ -169,6 +169,9 @@ func (c *Intent) validateStandardValues() error { if len(chain.AdditionalDisputeGames) > 0 { return fmt.Errorf("%w: chainId=%s additionalDisputeGames must be nil", ErrNonStandardValue, chain.ID) } + if chain.CustomGasToken.Enabled { + return fmt.Errorf("%w: chainId=%s custom gas token must be disabled for standard chains", ErrNonStandardValue, chain.ID) + } } challenger, _ := standard.ChallengerAddressFor(c.L1ChainID) @@ -310,6 +313,12 @@ func NewIntentCustom(l1ChainId uint64, l2ChainIds []common.Hash) (Intent, error) intent.Chains = append(intent.Chains, &ChainIntent{ ID: l2ChainID, GasLimit: standard.GasLimit, + CustomGasToken: CustomGasToken{ + Enabled: false, + Name: "", + Symbol: "", + InitialLiquidity: (*hexutil.Big)(big.NewInt(0)), + }, }) } return intent, nil @@ -354,6 +363,12 @@ func NewIntentStandard(l1ChainId uint64, l2ChainIds []common.Hash) (Intent, erro L1ProxyAdminOwner: l1ProxyAdminOwner, L2ProxyAdminOwner: l2ProxyAdminOwner, }, + CustomGasToken: CustomGasToken{ + Enabled: false, + Name: "", + Symbol: "", + InitialLiquidity: (*hexutil.Big)(big.NewInt(0)), + }, }) } return intent, nil diff --git a/op-deployer/pkg/deployer/state/intent_test.go b/op-deployer/pkg/deployer/state/intent_test.go index 8ffb0060db3c5..1a0f1c5feb676 100644 --- a/op-deployer/pkg/deployer/state/intent_test.go +++ b/op-deployer/pkg/deployer/state/intent_test.go @@ -1,10 +1,12 @@ package state import ( + "math/big" "testing" "github.com/ethereum-optimism/optimism/op-chain-ops/addresses" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" ) @@ -62,6 +64,18 @@ func TestValidateStandardValues(t *testing.T) { }, ErrNonStandardValue, }, + { + "CustomGasToken", + func(intent *Intent) { + intent.Chains[0].CustomGasToken = CustomGasToken{ + Enabled: true, + Name: "Custom Gas Token", + Symbol: "CGT", + InitialLiquidity: (*hexutil.Big)(big.NewInt(1000)), + } + }, + ErrNonStandardValue, + }, { "SuperchainConfigProxy", func(intent *Intent) { @@ -131,6 +145,10 @@ func TestValidateCustomValues(t *testing.T) { err = intent.Check() require.NoError(t, err) + setCustomGasToken(&intent) + err = intent.Check() + require.NoError(t, err) + tests := []struct { name string mutator func(intent *Intent) @@ -155,6 +173,28 @@ func TestValidateCustomValues(t *testing.T) { }, ErrIncompatibleValue, }, + { + "empty custom gas token name when enabled", + func(intent *Intent) { + intent.Chains[0].CustomGasToken = CustomGasToken{ + Enabled: true, + Name: "", + Symbol: "CGT", + } + }, + ErrIncompatibleValue, + }, + { + "empty custom gas token symbol when enabled", + func(intent *Intent) { + intent.Chains[0].CustomGasToken = CustomGasToken{ + Enabled: true, + Name: "Custom Gas Token", + Symbol: "", + } + }, + ErrIncompatibleValue, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -211,3 +251,16 @@ func setFeeAddresses(intent *Intent) { intent.Chains[0].L1FeeVaultRecipient = common.HexToAddress("0x09") intent.Chains[0].SequencerFeeVaultRecipient = common.HexToAddress("0x0A") } + +func setCustomGasToken(intent *Intent) { + // 1000 ETH in wei (1000 * 10^18) + amount := new(big.Int) + amount.SetString("1000000000000000000000", 10) + + intent.Chains[0].CustomGasToken = CustomGasToken{ + Enabled: true, + Name: "Custom Gas Token", + Symbol: "CGT", + InitialLiquidity: (*hexutil.Big)(amount), + } +} diff --git a/op-devstack/sysgo/deployer.go b/op-devstack/sysgo/deployer.go index 4c204d5b9bea6..f95b3132ef6e0 100644 --- a/op-devstack/sysgo/deployer.go +++ b/op-devstack/sysgo/deployer.go @@ -339,6 +339,14 @@ func WithDisputeGameFinalityDelaySeconds(seconds uint64) DeployerOption { } } +func WithCustomGasToken(enabled bool, name, symbol string, initialLiquidity *big.Int) DeployerOption { + return func(p devtest.P, keys devkeys.Keys, builder intentbuilder.Builder) { + for _, l2Cfg := range builder.L2s() { + l2Cfg.WithCustomGasToken(enabled, name, symbol, initialLiquidity) + } + } +} + func (wb *worldBuilder) buildL1Genesis() { wb.require.NotNil(wb.output.L1DevGenesis, "must have L1 genesis outer config") wb.require.NotNil(wb.output.L1StateDump, "must have L1 genesis alloc") diff --git a/op-e2e/config/init.go b/op-e2e/config/init.go index c2b4c8b508685..a29d56977efe5 100644 --- a/op-e2e/config/init.go +++ b/op-e2e/config/init.go @@ -400,6 +400,12 @@ func defaultIntent(root string, loc *artifacts.Locator, deployer common.Address, Proposer: addrs.Proposer, Challenger: common.HexToAddress("0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65"), }, + CustomGasToken: state.CustomGasToken{ + Enabled: false, + Name: "", + Symbol: "", + InitialLiquidity: (*hexutil.Big)(big.NewInt(0)), + }, AdditionalDisputeGames: []state.AdditionalDisputeGame{ { ChainProofParams: state.ChainProofParams{ diff --git a/op-e2e/e2eutils/intentbuilder/builder.go b/op-e2e/e2eutils/intentbuilder/builder.go index be8d4d8c8eae2..2a193e77a3912 100644 --- a/op-e2e/e2eutils/intentbuilder/builder.go +++ b/op-e2e/e2eutils/intentbuilder/builder.go @@ -2,6 +2,7 @@ package intentbuilder import ( "fmt" + "math/big" "github.com/holiman/uint256" "github.com/stretchr/testify/require" @@ -52,6 +53,7 @@ type L2Configurator interface { WithL1StartBlockHash(hash common.Hash) WithAdditionalDisputeGames(games []state.AdditionalDisputeGame) WithFinalizationPeriodSeconds(value uint64) + WithCustomGasToken(enabled bool, name string, symbol string, initialLiquidity *big.Int) ContractsConfigurator L2VaultsConfigurator L2RolesConfigurator @@ -409,6 +411,15 @@ func (c *l2Configurator) WithEIP1559Denominator(value uint64) { c.builder.intent.Chains[c.chainIndex].Eip1559Denominator = value } +func (c *l2Configurator) WithCustomGasToken(enabled bool, name, symbol string, initialLiquidity *big.Int) { + c.builder.intent.Chains[c.chainIndex].CustomGasToken = state.CustomGasToken{ + Enabled: enabled, + Name: name, + Symbol: symbol, + InitialLiquidity: (*hexutil.Big)(initialLiquidity), + } +} + func (c *l2Configurator) WithEIP1559Elasticity(value uint64) { c.builder.intent.Chains[c.chainIndex].Eip1559Elasticity = value } diff --git a/op-e2e/e2eutils/intentbuilder/builder_test.go b/op-e2e/e2eutils/intentbuilder/builder_test.go index d98eec5ce387f..17a1c57e48327 100644 --- a/op-e2e/e2eutils/intentbuilder/builder_test.go +++ b/op-e2e/e2eutils/intentbuilder/builder_test.go @@ -2,6 +2,7 @@ package intentbuilder import ( "encoding/json" + "math/big" "net/url" "testing" @@ -75,6 +76,7 @@ func TestBuilder(t *testing.T) { require.Equal(t, eth.ChainIDFromUInt64(420), l2Config.ChainID()) l2Config.WithBlockTime(2) l2Config.WithL1StartBlockHash(common.HexToHash("0x5678")) + l2Config.WithCustomGasToken(false, "", "", (*big.Int)(big.NewInt(0))) // Test ContractsConfigurator methods l2Config.WithL1ContractsLocator("http://l1.example.com") @@ -167,6 +169,12 @@ func TestBuilder(t *testing.T) { GasLimit: standard.GasLimit, OperatorFeeScalar: 100, OperatorFeeConstant: 200, + CustomGasToken: state.CustomGasToken{ + Enabled: false, + Name: "", + Symbol: "", + InitialLiquidity: (*hexutil.Big)(big.NewInt(0)), + }, DeployOverrides: map[string]any{ "l2BlockTime": uint64(2), "l2GenesisRegolithTimeOffset": hexutil.Uint64(0), diff --git a/packages/contracts-bedrock/deploy-config/hardhat.json b/packages/contracts-bedrock/deploy-config/hardhat.json index 736991c93ba26..d330d1345955f 100644 --- a/packages/contracts-bedrock/deploy-config/hardhat.json +++ b/packages/contracts-bedrock/deploy-config/hardhat.json @@ -62,5 +62,9 @@ "daChallengeWindow": 100, "daResolveWindow": 100, "daBondSize": 1000, - "daResolverRefundPercentage": 50 + "daResolverRefundPercentage": 50, + "useCustomGasToken": false, + "gasPayingTokenName": "", + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/deploy-config/internal-devnet.json b/packages/contracts-bedrock/deploy-config/internal-devnet.json index 643c507dc86d5..e74050bb76c70 100644 --- a/packages/contracts-bedrock/deploy-config/internal-devnet.json +++ b/packages/contracts-bedrock/deploy-config/internal-devnet.json @@ -38,5 +38,9 @@ "eip1559Elasticity": 10, "systemConfigStartBlock": 8364212, "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", - "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "useCustomGasToken": false, + "gasPayingTokenName": "", + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/deploy-config/mainnet.json b/packages/contracts-bedrock/deploy-config/mainnet.json index cd217ba111538..ae9b04ec3a464 100644 --- a/packages/contracts-bedrock/deploy-config/mainnet.json +++ b/packages/contracts-bedrock/deploy-config/mainnet.json @@ -55,5 +55,9 @@ "proofMaturityDelaySeconds": 604800, "disputeGameFinalityDelaySeconds": 302400, "respectedGameType": 0, - "useFaultProofs": true + "useFaultProofs": true, + "useCustomGasToken": false, + "gasPayingTokenName": "", + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json b/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json index 2392dcb9281a5..78575879084bf 100644 --- a/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json +++ b/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json @@ -79,5 +79,9 @@ "useFaultProofs": true, "fundDevAccounts": false, "requiredProtocolVersion": "0x0000000000000000000000000000000000000005000000000000000000000000", - "recommendedProtocolVersion": "0x0000000000000000000000000000000000000005000000000000000000000000" + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000005000000000000000000000000", + "useCustomGasToken": false, + "gasPayingTokenName": "", + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/deploy-config/sepolia.json b/packages/contracts-bedrock/deploy-config/sepolia.json index 12a1cc392c803..22ad35b14806b 100644 --- a/packages/contracts-bedrock/deploy-config/sepolia.json +++ b/packages/contracts-bedrock/deploy-config/sepolia.json @@ -54,5 +54,9 @@ "proofMaturityDelaySeconds": 604800, "disputeGameFinalityDelaySeconds": 302400, "respectedGameType": 0, - "useFaultProofs": true + "useFaultProofs": true, + "useCustomGasToken": false, + "gasPayingTokenName": "", + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml index 12d9cb5f206ad..9068e96e130ba 100644 --- a/packages/contracts-bedrock/foundry.toml +++ b/packages/contracts-bedrock/foundry.toml @@ -63,6 +63,7 @@ fs_permissions = [ { access='read-write', path='./.testdata/' }, { access='read', path='./kout-deployment' }, { access='read', path='./test/fixtures' }, + { access='read', path='../../test/config-op/' }, { access='read', path='./lib/superchain-registry/superchain/configs/' }, { access='read', path='./lib/superchain-registry/validation/standard/' }, ] diff --git a/packages/contracts-bedrock/interfaces/L1/IL1CrossDomainMessenger.sol b/packages/contracts-bedrock/interfaces/L1/IL1CrossDomainMessenger.sol index 75d61233ae242..adb75a42b7cbd 100644 --- a/packages/contracts-bedrock/interfaces/L1/IL1CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/interfaces/L1/IL1CrossDomainMessenger.sol @@ -8,15 +8,10 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IProxyAdminOwnedBase } from "interfaces/L1/IProxyAdminOwnedBase.sol"; interface IL1CrossDomainMessenger is ICrossDomainMessenger, IProxyAdminOwnedBase { - error ReinitializableBase_ZeroInitVersion(); function PORTAL() external view returns (IOptimismPortal); - function initialize( - ISystemConfig _systemConfig, - IOptimismPortal _portal - ) - external; + function initialize(ISystemConfig _systemConfig, IOptimismPortal _portal) external; function initVersion() external view returns (uint8); function portal() external view returns (IOptimismPortal); function systemConfig() external view returns (ISystemConfig); diff --git a/packages/contracts-bedrock/interfaces/L1/IL1StandardBridge.sol b/packages/contracts-bedrock/interfaces/L1/IL1StandardBridge.sol index 0e22bb9b9c45c..bca0a79f56287 100644 --- a/packages/contracts-bedrock/interfaces/L1/IL1StandardBridge.sol +++ b/packages/contracts-bedrock/interfaces/L1/IL1StandardBridge.sol @@ -8,7 +8,6 @@ import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IProxyAdminOwnedBase } from "interfaces/L1/IProxyAdminOwnedBase.sol"; interface IL1StandardBridge is IStandardBridge, IProxyAdminOwnedBase { - error ReinitializableBase_ZeroInitVersion(); event ERC20DepositInitiated( @@ -67,11 +66,7 @@ interface IL1StandardBridge is IStandardBridge, IProxyAdminOwnedBase { ) external payable; - function initialize( - ICrossDomainMessenger _messenger, - ISystemConfig _systemConfig - ) - external; + function initialize(ICrossDomainMessenger _messenger, ISystemConfig _systemConfig) external; function l2TokenBridge() external view returns (address); function systemConfig() external view returns (ISystemConfig); function version() external view returns (string memory); diff --git a/packages/contracts-bedrock/interfaces/L1/IOKB.sol b/packages/contracts-bedrock/interfaces/L1/IOKB.sol new file mode 100644 index 0000000000000..ab545c22411d7 --- /dev/null +++ b/packages/contracts-bedrock/interfaces/L1/IOKB.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; + +interface IOKB is IERC20, IERC20Metadata { + function triggerBridge() external; +} diff --git a/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol b/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol index 987450481d6b6..45fcf739ebd65 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol @@ -21,6 +21,7 @@ interface IOptimismPortal2 is IProxyAdminOwnedBase { error OptimismPortal_BadTarget(); error OptimismPortal_CallPaused(); error OptimismPortal_CalldataTooLarge(); + error OptimismPortal_NotAllowedOnCGTMode(); error OptimismPortal_GasEstimation(); error OptimismPortal_GasLimitTooLow(); error OptimismPortal_ImproperDisputeGame(); @@ -33,6 +34,8 @@ interface IOptimismPortal2 is IProxyAdminOwnedBase { error OptimismPortal_ProofNotOldEnough(); error OptimismPortal_Unproven(); error OptimismPortal_InvalidLockboxState(); + error OptimismPortal_OnlyCustomGasToken(); + error OptimismPortal_InvalidGasToken(); error OutOfGas(); error UnexpectedList(); error UnexpectedString(); @@ -48,6 +51,15 @@ interface IOptimismPortal2 is IProxyAdminOwnedBase { function anchorStateRegistry() external view returns (IAnchorStateRegistry); function ethLockbox() external view returns (IETHLockbox); function checkWithdrawal(bytes32 _withdrawalHash, address _proofSubmitter) external view; + function depositERC20Transaction( + address _to, + uint256 _mint, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + external; function depositTransaction( address _to, uint256 _value, @@ -70,11 +82,7 @@ interface IOptimismPortal2 is IProxyAdminOwnedBase { external; function finalizedWithdrawals(bytes32) external view returns (bool); function guardian() external view returns (address); - function initialize( - ISystemConfig _systemConfig, - IAnchorStateRegistry _anchorStateRegistry - ) - external; + function initialize(ISystemConfig _systemConfig, IAnchorStateRegistry _anchorStateRegistry) external; function initVersion() external view returns (uint8); function l2Sender() external view returns (address); function minimumGasLimit(uint64 _byteCount) external pure returns (uint64); diff --git a/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol b/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol index 4abb69a1c1ab1..132586ffdb3eb 100644 --- a/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol +++ b/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol @@ -98,6 +98,11 @@ interface ISystemConfig is IProxyAdminOwnedBase { function guardian() external view returns (address); function setFeature(bytes32 _feature, bool _enabled) external; function isFeatureEnabled(bytes32) external view returns (bool); + function isCustomGasToken() external view returns (bool); + function gasPayingToken() external view returns (address address_, uint8 decimals_); + function gasPayingTokenName() external view returns (string memory name_); + function gasPayingTokenSymbol() external view returns (string memory symbol_); + function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; function __constructor__() external; } diff --git a/packages/contracts-bedrock/interfaces/L2/IL1BlockCGT.sol b/packages/contracts-bedrock/interfaces/L2/IL1BlockCGT.sol new file mode 100644 index 0000000000000..1501b74fc3cd8 --- /dev/null +++ b/packages/contracts-bedrock/interfaces/L2/IL1BlockCGT.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IL1BlockCGT { + function DEPOSITOR_ACCOUNT() external pure returns (address addr_); + function number() external view returns (uint64); + function timestamp() external view returns (uint64); + function basefee() external view returns (uint256); + function hash() external view returns (bytes32); + function sequenceNumber() external view returns (uint64); + function blobBaseFeeScalar() external view returns (uint32); + function baseFeeScalar() external view returns (uint32); + function batcherHash() external view returns (bytes32); + function l1FeeOverhead() external view returns (uint256); + function l1FeeScalar() external view returns (uint256); + function blobBaseFee() external view returns (uint256); + function operatorFeeConstant() external view returns (uint64); + function operatorFeeScalar() external view returns (uint32); + function version() external pure returns (string memory); + function isCustomGasToken() external view returns (bool isCustom_); + function gasPayingTokenName() external view returns (string memory name_); + function gasPayingTokenSymbol() external view returns (string memory symbol_); + function setL1BlockValues( + uint64 _number, + uint64 _timestamp, + uint256 _basefee, + bytes32 _hash, + uint64 _sequenceNumber, + bytes32 _batcherHash, + uint256 _l1FeeOverhead, + uint256 _l1FeeScalar + ) + external; + function setL1BlockValuesEcotone() external; + function setL1BlockValuesIsthmus() external; + function setCustomGasToken() external; + function gasPayingToken() external view returns (address, uint8); + + function __constructor__() external; +} diff --git a/packages/contracts-bedrock/interfaces/L2/IL2ToL1MessagePasserCGT.sol b/packages/contracts-bedrock/interfaces/L2/IL2ToL1MessagePasserCGT.sol new file mode 100644 index 0000000000000..cdb94f21d478b --- /dev/null +++ b/packages/contracts-bedrock/interfaces/L2/IL2ToL1MessagePasserCGT.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IL2ToL1MessagePasserCGT { + error L2ToL1MessagePasserCGT_NotAllowedOnCGTMode(); + + event MessagePassed( + uint256 indexed nonce, + address indexed sender, + address indexed target, + uint256 value, + uint256 gasLimit, + bytes data, + bytes32 withdrawalHash + ); + event WithdrawerBalanceBurnt(uint256 indexed amount); + + receive() external payable; + + function MESSAGE_VERSION() external view returns (uint16); + function burn() external; + function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) external payable; + function messageNonce() external view returns (uint256); + function sentMessages(bytes32) external view returns (bool); + function version() external view returns (string memory); + + function __constructor__() external; +} diff --git a/packages/contracts-bedrock/interfaces/L2/ILiquidityController.sol b/packages/contracts-bedrock/interfaces/L2/ILiquidityController.sol new file mode 100644 index 0000000000000..2039de56a67d7 --- /dev/null +++ b/packages/contracts-bedrock/interfaces/L2/ILiquidityController.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ISemver } from "interfaces/universal/ISemver.sol"; + +interface ILiquidityController is ISemver { + error LiquidityController_Unauthorized(); + + event Initialized(uint8 version); + + event MinterAuthorized(address indexed minter); + event MinterDeauthorized(address indexed minter); + event LiquidityMinted(address indexed minter, address indexed to, uint256 amount); + event LiquidityBurned(address indexed minter, uint256 amount); + + function authorizeMinter(address _minter) external; + function deauthorizeMinter(address _minter) external; + function mint(address _to, uint256 _amount) external; + function burn() external payable; + function minters(address) external view returns (bool); + function gasPayingTokenName() external view returns (string memory); + function gasPayingTokenSymbol() external view returns (string memory); + function initialize(string memory _gasPayingTokenName, string memory _gasPayingTokenSymbol) external; + + function __constructor__() external; +} diff --git a/packages/contracts-bedrock/interfaces/L2/INativeAssetLiquidity.sol b/packages/contracts-bedrock/interfaces/L2/INativeAssetLiquidity.sol new file mode 100644 index 0000000000000..fc343f4cba1e6 --- /dev/null +++ b/packages/contracts-bedrock/interfaces/L2/INativeAssetLiquidity.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { ISemver } from "interfaces/universal/ISemver.sol"; + +interface INativeAssetLiquidity is ISemver { + error NativeAssetLiquidity_Unauthorized(); + error NativeAssetLiquidity_InsufficientBalance(); + + event LiquidityDeposited(address indexed caller, uint256 value); + event LiquidityWithdrawn(address indexed caller, uint256 value); + + function deposit() external payable; + function withdraw(uint256 _amount) external; +} diff --git a/packages/contracts-bedrock/scripts/DeployMockOKB.s.sol b/packages/contracts-bedrock/scripts/DeployMockOKB.s.sol new file mode 100644 index 0000000000000..8a5613844005a --- /dev/null +++ b/packages/contracts-bedrock/scripts/DeployMockOKB.s.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Script } from "forge-std/Script.sol"; +import { console2 as console } from "forge-std/console2.sol"; + +// Contracts +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { ERC20Burnable } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; + +/// @title MockOKB +/// @notice Mock OKB token for testing custom gas token setup +contract MockOKB is ERC20, ERC20Burnable { + constructor() ERC20("Mock OKB", "OKB") { + _mint(msg.sender, 660000 * 10 ** decimals()); + } + + function decimals() public pure override returns (uint8) { + return 18; + } + + /// @notice Burn all tokens of msg.sender + function triggerBridge() external { + _burn(msg.sender, balanceOf(msg.sender)); + } +} + +/// @title DeployMockOKB +/// @notice Foundry script to deploy MockOKB token for testing +/// @dev This script deploys a mock OKB token with 660,000 initial supply +contract DeployMockOKB is Script { + // Deployed contract + MockOKB okbToken; + address deployerAddress; + + function setUp() public { + // Get deployer address from msg.sender (set by forge script --private-key) + deployerAddress = msg.sender; + console.log("Deployer address:", deployerAddress); + } + + function run() public { + console.log("\n=== Deploying Mock OKB Token ===\n"); + + vm.startBroadcast(msg.sender); + + // Deploy Mock OKB Token + deployMockOKB(); + + vm.stopBroadcast(); + + // Print deployment summary + printDeploymentSummary(); + } + + /// @notice Deploy mock OKB token with 660,000 supply + function deployMockOKB() internal { + okbToken = new MockOKB(); + console.log("MockOKB deployed at:", address(okbToken)); + } + + /// @notice Print deployment summary with token details + function printDeploymentSummary() internal view { + console.log("\n=== Deployment Summary ==="); + console.log("MockOKB Address:", address(okbToken)); + console.log("Token name:", okbToken.name()); + console.log("Token symbol:", okbToken.symbol()); + console.log("Token decimals:", okbToken.decimals()); + console.log("Total supply:", okbToken.totalSupply() / 1e18, "OKB"); + console.log("Deployer balance:", okbToken.balanceOf(deployerAddress) / 1e18, "OKB"); + console.log("\nEnvironment variable to set:"); + console.log("export OKB_TOKEN_ADDRESS=", address(okbToken)); + } +} diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index de75c6b99cf1e..244cdc4c409fc 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -30,6 +30,8 @@ import { ICrossDomainMessenger } from "interfaces/universal/ICrossDomainMessenge import { IL2CrossDomainMessenger } from "interfaces/L2/IL2CrossDomainMessenger.sol"; import { IGasPriceOracle } from "interfaces/L2/IGasPriceOracle.sol"; import { IL1Block } from "interfaces/L2/IL1Block.sol"; +import { ILiquidityController } from "interfaces/L2/ILiquidityController.sol"; +import { IL1BlockCGT } from "interfaces/L2/IL1BlockCGT.sol"; /// @title L2Genesis /// @notice Generates the genesis state for the L2 network. @@ -60,6 +62,10 @@ contract L2Genesis is Script { bool deployCrossL2Inbox; bool enableGovernance; bool fundDevAccounts; + bool useCustomGasToken; + string gasPayingTokenName; + string gasPayingTokenSymbol; + uint256 nativeAssetLiquidityAmount; } using ForkUtils for Fork; @@ -118,6 +124,7 @@ contract L2Genesis is Script { if (_input.fundDevAccounts) { fundDevAccounts(); } + vm.stopPrank(); vm.deal(deployer, 0); vm.resetNonce(deployer); @@ -195,7 +202,8 @@ contract L2Genesis is Script { vm.etch(addr, code); EIP1967Helper.setAdmin(addr, Predeploys.PROXY_ADMIN); - if (Predeploys.isSupportedPredeploy(addr, _input.fork, _input.deployCrossL2Inbox)) { + if (Predeploys.isSupportedPredeploy(addr, _input.fork, _input.deployCrossL2Inbox, _input.useCustomGasToken)) + { address implementation = Predeploys.predeployToCodeNamespace(addr); EIP1967Helper.setImplementation(addr, implementation); } @@ -219,8 +227,8 @@ contract L2Genesis is Script { setOptimismMintableERC20Factory(); // 12 setL1BlockNumber(); // 13 setL2ERC721Bridge(_input.l1ERC721BridgeProxy); // 14 - setL1Block(); // 15 - setL2ToL1MessagePasser(); // 16 + setL1Block(_input.useCustomGasToken); // 15 + setL2ToL1MessagePasser(_input.useCustomGasToken); // 16 setOptimismMintableERC721Factory(_input); // 17 setProxyAdmin(_input); // 18 setBaseFeeVault(_input); // 19 @@ -236,6 +244,10 @@ contract L2Genesis is Script { } setL2ToL2CrossDomainMessenger(); // 23 } + if (_input.useCustomGasToken) { + setLiquidityController(_input); // 29 + setNativeAssetLiquidity(_input); // 2A + } } function setInteropPredeployProxies() internal { } @@ -252,8 +264,14 @@ contract L2Genesis is Script { vm.store(impl, _ownerSlot, bytes32(uint256(uint160(_input.opChainProxyAdminOwner)))); } - function setL2ToL1MessagePasser() internal { - _setImplementationCode(Predeploys.L2_TO_L1_MESSAGE_PASSER); + function setL2ToL1MessagePasser(bool _useCustomGasToken) internal { + if (_useCustomGasToken) { + string memory cname = "L2ToL1MessagePasserCGT"; + address impl = Predeploys.predeployToCodeNamespace(Predeploys.L2_TO_L1_MESSAGE_PASSER); + vm.etch(impl, vm.getDeployedCode(string.concat(cname, ".sol:", cname))); + } else { + _setImplementationCode(Predeploys.L2_TO_L1_MESSAGE_PASSER); + } } /// @notice This predeploy is following the safety invariant #1. @@ -289,6 +307,12 @@ contract L2Genesis is Script { /// @notice This predeploy is following the safety invariant #2, function setSequencerFeeVault(Input memory _input) internal { + Types.WithdrawalNetwork withdrawalNetwork = Types.WithdrawalNetwork(_input.sequencerFeeVaultWithdrawalNetwork); + + if (_input.useCustomGasToken && withdrawalNetwork == Types.WithdrawalNetwork.L1) { + revert("SequencerFeeVault: withdrawalNetwork type cannot be L1 when custom gas token is enabled"); + } + ISequencerFeeVault vault = ISequencerFeeVault( DeployUtils.create1({ _name: "SequencerFeeVault", @@ -298,7 +322,7 @@ contract L2Genesis is Script { ( _input.sequencerFeeVaultRecipient, _input.sequencerFeeVaultMinimumWithdrawalAmount, - Types.WithdrawalNetwork(_input.sequencerFeeVaultWithdrawalNetwork) + withdrawalNetwork ) ) ) @@ -346,10 +370,20 @@ contract L2Genesis is Script { } /// @notice This predeploy is following the safety invariant #1. - function setL1Block() internal { - // Note: L1 block attributes are set to 0. - // Before the first user-tx the state is overwritten with actual L1 attributes. - _setImplementationCode(Predeploys.L1_BLOCK_ATTRIBUTES); + function setL1Block(bool _useCustomGasToken) internal { + if (_useCustomGasToken) { + // Set the implementation code for L1BlockCGT + string memory cname = "L1BlockCGT"; + address impl = Predeploys.predeployToCodeNamespace(Predeploys.L1_BLOCK_ATTRIBUTES); + vm.etch(impl, vm.getDeployedCode(string.concat(cname, ".sol:", cname))); + + // Set the custom gas token flag + vm.startPrank(IL1BlockCGT(Predeploys.L1_BLOCK_ATTRIBUTES).DEPOSITOR_ACCOUNT()); + IL1BlockCGT(Predeploys.L1_BLOCK_ATTRIBUTES).setCustomGasToken(); + vm.stopPrank(); + } else { + _setImplementationCode(Predeploys.L1_BLOCK_ATTRIBUTES); + } } /// @notice This predeploy is following the safety invariant #1. @@ -381,17 +415,19 @@ contract L2Genesis is Script { /// @notice This predeploy is following the safety invariant #2. function setBaseFeeVault(Input memory _input) internal { + Types.WithdrawalNetwork withdrawalNetwork = Types.WithdrawalNetwork(_input.baseFeeVaultWithdrawalNetwork); + + if (_input.useCustomGasToken && withdrawalNetwork == Types.WithdrawalNetwork.L1) { + revert("BaseFeeVault: withdrawalNetwork type cannot be L1 when custom gas token is enabled"); + } + IBaseFeeVault vault = IBaseFeeVault( DeployUtils.create1({ _name: "BaseFeeVault", _args: DeployUtils.encodeConstructor( abi.encodeCall( IBaseFeeVault.__constructor__, - ( - _input.baseFeeVaultRecipient, - _input.baseFeeVaultMinimumWithdrawalAmount, - Types.WithdrawalNetwork(_input.baseFeeVaultWithdrawalNetwork) - ) + (_input.baseFeeVaultRecipient, _input.baseFeeVaultMinimumWithdrawalAmount, withdrawalNetwork) ) ) }) @@ -407,17 +443,19 @@ contract L2Genesis is Script { /// @notice This predeploy is following the safety invariant #2. function setL1FeeVault(Input memory _input) internal { + Types.WithdrawalNetwork withdrawalNetwork = Types.WithdrawalNetwork(_input.l1FeeVaultWithdrawalNetwork); + + if (_input.useCustomGasToken && withdrawalNetwork == Types.WithdrawalNetwork.L1) { + revert("L1FeeVault: withdrawalNetwork type cannot be L1 when custom gas token is enabled"); + } + IL1FeeVault vault = IL1FeeVault( DeployUtils.create1({ _name: "L1FeeVault", _args: DeployUtils.encodeConstructor( abi.encodeCall( IL1FeeVault.__constructor__, - ( - _input.l1FeeVaultRecipient, - _input.l1FeeVaultMinimumWithdrawalAmount, - Types.WithdrawalNetwork(_input.l1FeeVaultWithdrawalNetwork) - ) + (_input.l1FeeVaultRecipient, _input.l1FeeVaultMinimumWithdrawalAmount, withdrawalNetwork) ) ) }) @@ -546,6 +584,32 @@ contract L2Genesis is Script { _setImplementationCode(Predeploys.SUPERCHAIN_TOKEN_BRIDGE); } + /// @notice This predeploy is following the safety invariant #1. + function setLiquidityController(Input memory _input) internal { + address impl = _setImplementationCode(Predeploys.LIQUIDITY_CONTROLLER); + + ILiquidityController(impl).initialize({ _gasPayingTokenName: "", _gasPayingTokenSymbol: "" }); + + ILiquidityController(Predeploys.LIQUIDITY_CONTROLLER).initialize({ + _gasPayingTokenName: _input.gasPayingTokenName, + _gasPayingTokenSymbol: _input.gasPayingTokenSymbol + }); + } + + /// @notice This predeploy is following the safety invariant #1. + /// This contract has no initializer. + function setNativeAssetLiquidity(Input memory _input) internal { + _setImplementationCode(Predeploys.NATIVE_ASSET_LIQUIDITY); + + require( + _input.nativeAssetLiquidityAmount <= type(uint248).max, + "L2Genesis: native asset liquidity amount must be less than or equal to type(uint248).max" + ); + + // Pre-fund the liquidity contract with the specified amount + vm.deal(Predeploys.NATIVE_ASSET_LIQUIDITY, _input.nativeAssetLiquidityAmount); + } + /// @notice Sets all the preinstalls. function setPreinstalls() internal { address tmpSetPreinstalls = address(uint160(uint256(keccak256("SetPreinstalls")))); diff --git a/packages/contracts-bedrock/scripts/SetupCustomGasToken.s.sol b/packages/contracts-bedrock/scripts/SetupCustomGasToken.s.sol new file mode 100644 index 0000000000000..4306bc75f1c26 --- /dev/null +++ b/packages/contracts-bedrock/scripts/SetupCustomGasToken.s.sol @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Script } from "forge-std/Script.sol"; +import { console2 as console } from "forge-std/console2.sol"; + +// Contracts +import { DepositedOKBAdapter } from "src/L1/DepositedOKBAdapter.sol"; + +// Interfaces +import { IOKB } from "interfaces/L1/IOKB.sol"; +import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; + +// Libraries +import { Constants } from "src/libraries/Constants.sol"; + +/// @title SetupCustomGasToken +/// @notice Foundry script to set up and verify custom gas token configuration +/// @dev This script: +/// 1. Pre-checks L1 configuration +/// 2. Deploys DepositedOKBAdapter with designated owner +/// 3. Sets gas paying token in SystemConfig storage +/// 4. Post-checks configuration +contract SetupCustomGasToken is Script { + // Addresses to be loaded from deployment artifacts + address systemConfigProxy; + address optimismPortalProxy; + address deployerAddress; + address okbTokenAddress; + address okbAdapterOwnerAddress; + + // Deployed contracts + IOKB okbToken; + DepositedOKBAdapter adapter; + + function setUp() public { + // Get deployer address from msg.sender (set by forge script --private-key) + deployerAddress = msg.sender; + console.log("Deployer address:", deployerAddress); + + // Parse addresses from environment variables + systemConfigProxy = vm.envAddress("SYSTEM_CONFIG_PROXY_ADDRESS"); + optimismPortalProxy = vm.envAddress("OPTIMISM_PORTAL_PROXY_ADDRESS"); + okbTokenAddress = vm.envAddress("OKB_TOKEN_ADDRESS"); + okbAdapterOwnerAddress = vm.envAddress("OKB_ADAPTER_OWNER_ADDRESS"); + + console.log("SystemConfig Proxy:", systemConfigProxy); + console.log("OptimismPortal Proxy:", optimismPortalProxy); + console.log("OKB Token Address:", okbTokenAddress); + console.log("OKB Adapter Owner Address:", okbAdapterOwnerAddress); + + // Initialize OKB token interface + okbToken = IOKB(okbTokenAddress); + } + + function run() public { + console.log("\n=== Starting Custom Gas Token Setup ===\n"); + + preCheck(); + + vm.startBroadcast(msg.sender); + + deployAdapter(); + + setGasPayingToken(); + + vm.stopBroadcast(); + + postCheck(); + } + + /// @notice Pre-check L1 Configuration + function preCheck() internal view { + console.log("Pre-check L1 Configuration...\n"); + ISystemConfig systemConfig = ISystemConfig(systemConfigProxy); + bool isCustomGasToken = systemConfig.isCustomGasToken(); + require(isCustomGasToken, "FAILED: SystemConfig custom gas token not enabled"); + + (address tokenAddr, uint8 decimals) = systemConfig.gasPayingToken(); + string memory name = systemConfig.gasPayingTokenName(); + string memory symbol = systemConfig.gasPayingTokenSymbol(); + console.log("SystemConfig.gasPayingToken():"); + console.log(" Address:", tokenAddr); + console.log(" Decimals:", decimals); + console.log(" Name:", name); + console.log(" Symbol:", symbol); + require(tokenAddr == Constants.ETHER, "FAILED: GasPayingToken already set"); + } + + /// @notice Deploy DepositedOKBAdapter + function deployAdapter() internal { + adapter = new DepositedOKBAdapter(okbTokenAddress, payable(optimismPortalProxy), okbAdapterOwnerAddress); + console.log(" DepositedOKBAdapter deployed at:", address(adapter)); + console.log(" Adapter owner:", okbAdapterOwnerAddress); + } + + /// @notice Set gas paying token in SystemConfig storage + /// @dev This writes to the GasPayingToken storage slots directly + function setGasPayingToken() internal { + ISystemConfig systemConfig = ISystemConfig(systemConfigProxy); + // adapter is the gas paying token + // Convert string to bytes32 for SystemConfig function + bytes32 nameBytes32 = bytes32(bytes(okbToken.name())); + bytes32 symbolBytes32 = bytes32(bytes(okbToken.symbol())); + systemConfig.setGasPayingToken(address(adapter), okbToken.decimals(), nameBytes32, symbolBytes32); + } + + /// @notice Post-check L1 configuration + function postCheck() internal view { + console.log("\nPost-check L1 Configuration...\n"); + + ISystemConfig systemConfig = ISystemConfig(systemConfigProxy); + // Check SystemConfig gasPayingToken + (address tokenAddr, uint8 decimals) = systemConfig.gasPayingToken(); + string memory name = systemConfig.gasPayingTokenName(); + string memory symbol = systemConfig.gasPayingTokenSymbol(); + console.log("SystemConfig.gasPayingToken():"); + console.log(" Address:", tokenAddr); + console.log(" Decimals:", decimals); + console.log(" Name:", name); + console.log(" Symbol:", symbol); + require(tokenAddr == address(adapter), "FAILED: Token address mismatch"); + require(decimals == okbToken.decimals(), "FAILED: Token decimals mismatch"); + require( + keccak256(abi.encodePacked(name)) == keccak256(abi.encodePacked(okbToken.name())), + "FAILED: Token name mismatch" + ); + require( + keccak256(abi.encodePacked(symbol)) == keccak256(abi.encodePacked(okbToken.symbol())), + "FAILED: Token symbol mismatch" + ); + + // Check DepositedOKBAdapter configuration + require(address(adapter.OKB()) == okbTokenAddress, "FAILED: Adapter OKB mismatch"); + require(address(adapter.PORTAL()) == optimismPortalProxy, "FAILED: Adapter portal mismatch"); + require(adapter.owner() == okbAdapterOwnerAddress, "FAILED: Adapter owner mismatch"); + + // Check adapter has preminted total supply + uint256 adapterBalance = adapter.balanceOf(address(adapter)); + uint256 expectedBalance = okbToken.totalSupply(); + console.log(" [CHECK] Adapter balance:", adapterBalance); + console.log(" [CHECK] Expected balance (OKB total supply):", expectedBalance); + require(adapterBalance == expectedBalance, "FAILED: Adapter balance should equal OKB total supply"); + + // Check Adapter approval to portal (should be zero initially) + uint256 allowance = adapter.allowance(address(adapter), optimismPortalProxy); + console.log(" [CHECK] Adapter approval to Portal:", allowance); + require(allowance == 0, "FAILED: Adapter should not pre-approve portal"); + } +} diff --git a/packages/contracts-bedrock/scripts/checks/test-validation/exclusions.toml b/packages/contracts-bedrock/scripts/checks/test-validation/exclusions.toml index 6c332b4e8a321..41f5b340eacdd 100644 --- a/packages/contracts-bedrock/scripts/checks/test-validation/exclusions.toml +++ b/packages/contracts-bedrock/scripts/checks/test-validation/exclusions.toml @@ -1,4 +1,4 @@ - # Test validation exclusions configuration +# Test validation exclusions configuration # This file contains lists of paths and test names that should be excluded # from various validation checks in the test validation script. @@ -94,4 +94,5 @@ contracts = [ "OptimismPortal2_UpgradeInterop_Test", # Interop tests hosted in the OptimismPortal2 test file "TransactionBuilder", # Transaction builder helper library in TimelockGuard test file "Constants_Test", # Invalid naming pattern - doesn't specify function or Uncategorized + "L1Block_SetCustomGasToken_Test", # Custom gas token tests hosted in the L1Block test file ] diff --git a/packages/contracts-bedrock/scripts/deploy/DeployConfig.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployConfig.s.sol index 928faad8129bc..6a5808b91f56b 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployConfig.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployConfig.s.sol @@ -76,6 +76,12 @@ contract DeployConfig is Script { uint256 public daBondSize; uint256 public daResolverRefundPercentage; + // Custom Gas Token Configuration + bool public useCustomGasToken; + string public gasPayingTokenName; + string public gasPayingTokenSymbol; + uint256 public nativeAssetLiquidityAmount; + // V2 Dispute Game Configuration uint256 public faultGameV2MaxGameDepth; uint256 public faultGameV2SplitDepth; @@ -128,6 +134,10 @@ contract DeployConfig is Script { l2GenesisBlockGasLimit = stdJson.readUint(_json, "$.l2GenesisBlockGasLimit"); basefeeScalar = uint32(_readOr(_json, "$.gasPriceOracleBaseFeeScalar", 1368)); blobbasefeeScalar = uint32(_readOr(_json, "$.gasPriceOracleBlobBaseFeeScalar", 810949)); + useCustomGasToken = _readOr(_json, "$.useCustomGasToken", false); + gasPayingTokenName = _readOr(_json, "$.gasPayingTokenName", ""); + gasPayingTokenSymbol = _readOr(_json, "$.gasPayingTokenSymbol", ""); + nativeAssetLiquidityAmount = _readOr(_json, "$.nativeAssetLiquidityAmount", 0); enableGovernance = _readOr(_json, "$.enableGovernance", false); systemConfigStartBlock = stdJson.readUint(_json, "$.systemConfigStartBlock"); @@ -236,6 +246,41 @@ contract DeployConfig is Script { useUpgradedFork = _useUpgradedFork; } + /// @notice Allow the `useCustomGasToken` config to be overridden in testing environments + function setUseCustomGasToken(bool _useCustomGasToken) public { + useCustomGasToken = _useCustomGasToken; + } + + /// @notice Allow the `gasPayingTokenName` config to be overridden in testing environments + function setGasPayingTokenName(string memory _gasPayingTokenName) public { + gasPayingTokenName = _gasPayingTokenName; + } + + /// @notice Allow the `gasPayingTokenSymbol` config to be overridden in testing environments + function setGasPayingTokenSymbol(string memory _gasPayingTokenSymbol) public { + gasPayingTokenSymbol = _gasPayingTokenSymbol; + } + + /// @notice Allow the `nativeAssetLiquidityAmount` config to be overridden in testing environments + function setNativeAssetLiquidityAmount(uint256 _nativeAssetLiquidityAmount) public { + nativeAssetLiquidityAmount = _nativeAssetLiquidityAmount; + } + + /// @notice Allow the `baseFeeVaultWithdrawalNetwork` config to be overridden in testing environments + function setBaseFeeVaultWithdrawalNetwork(uint256 _baseFeeVaultWithdrawalNetwork) public { + baseFeeVaultWithdrawalNetwork = _baseFeeVaultWithdrawalNetwork; + } + + /// @notice Allow the `l1FeeVaultWithdrawalNetwork` config to be overridden in testing environments + function setL1FeeVaultWithdrawalNetwork(uint256 _l1FeeVaultWithdrawalNetwork) public { + l1FeeVaultWithdrawalNetwork = _l1FeeVaultWithdrawalNetwork; + } + + /// @notice Allow the `sequencerFeeVaultWithdrawalNetwork` config to be overridden in testing environments + function setSequencerFeeVaultWithdrawalNetwork(uint256 _sequencerFeeVaultWithdrawalNetwork) public { + sequencerFeeVaultWithdrawalNetwork = _sequencerFeeVaultWithdrawalNetwork; + } + function latestGenesisFork() internal view returns (Fork) { if (l2GenesisJovianTimeOffset == 0) { return Fork.JOVIAN; diff --git a/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol index 77a3d3d4351f8..6220c7542c817 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol @@ -5,6 +5,7 @@ import { Script } from "forge-std/Script.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { Solarray } from "scripts/libraries/Solarray.sol"; + import { ChainAssertions } from "scripts/deploy/ChainAssertions.sol"; import { Constants as ScriptConstants } from "scripts/libraries/Constants.sol"; import { Types } from "scripts/libraries/Types.sol"; @@ -17,6 +18,7 @@ import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol" import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol"; + import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPortal2.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol"; diff --git a/packages/contracts-bedrock/scripts/libraries/Config.sol b/packages/contracts-bedrock/scripts/libraries/Config.sol index 739fe88e6fbfa..d01788e5b9f14 100644 --- a/packages/contracts-bedrock/scripts/libraries/Config.sol +++ b/packages/contracts-bedrock/scripts/libraries/Config.sol @@ -250,4 +250,9 @@ library Config { function devFeatureDeployV2DisputeGames() internal view returns (bool) { return vm.envOr("DEV_FEATURE__DEPLOY_V2_DISPUTE_GAMES", false); } + + /// @notice Returns true if the development feature custom gas token is enabled. + function devFeatureCustomGasToken() internal view returns (bool) { + return vm.envOr("DEV_FEATURE__CUSTOM_GAS_TOKEN", false); + } } diff --git a/packages/contracts-bedrock/snapshots/abi/L1Block.json b/packages/contracts-bedrock/snapshots/abi/L1Block.json index 153d2676cf5bb..cf5e9a890de69 100644 --- a/packages/contracts-bedrock/snapshots/abi/L1Block.json +++ b/packages/contracts-bedrock/snapshots/abi/L1Block.json @@ -105,7 +105,7 @@ "type": "string" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { @@ -118,7 +118,7 @@ "type": "string" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { @@ -144,7 +144,7 @@ "type": "bool" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { diff --git a/packages/contracts-bedrock/snapshots/abi/L1BlockCGT.json b/packages/contracts-bedrock/snapshots/abi/L1BlockCGT.json new file mode 100644 index 0000000000000..1ece2bf86189b --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L1BlockCGT.json @@ -0,0 +1,323 @@ +[ + { + "inputs": [], + "name": "DEPOSITOR_ACCOUNT", + "outputs": [ + { + "internalType": "address", + "name": "addr_", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "baseFeeScalar", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "basefee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "batcherHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blobBaseFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blobBaseFeeScalar", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasPayingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "gasPayingTokenName", + "outputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasPayingTokenSymbol", + "outputs": [ + { + "internalType": "string", + "name": "symbol_", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isCustomGasToken", + "outputs": [ + { + "internalType": "bool", + "name": "isCustom_", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1FeeOverhead", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1FeeScalar", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "number", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operatorFeeConstant", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "operatorFeeScalar", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sequenceNumber", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "setCustomGasToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "_number", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "_timestamp", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "_basefee", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "_sequenceNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "_batcherHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l1FeeOverhead", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l1FeeScalar", + "type": "uint256" + } + ], + "name": "setL1BlockValues", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "setL1BlockValuesEcotone", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "setL1BlockValuesIsthmus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "timestamp", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json b/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json index 77e1cf7596b35..3638283520aab 100644 --- a/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json +++ b/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasser.json @@ -88,7 +88,7 @@ "type": "string" } ], - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { diff --git a/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasserCGT.json b/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasserCGT.json new file mode 100644 index 0000000000000..a8a57bea938ed --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L2ToL1MessagePasserCGT.json @@ -0,0 +1,161 @@ +[ + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "MESSAGE_VERSION", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_gasLimit", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "initiateWithdrawal", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "messageNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "sentMessages", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "withdrawalHash", + "type": "bytes32" + } + ], + "name": "MessagePassed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawerBalanceBurnt", + "type": "event" + }, + { + "inputs": [], + "name": "L2ToL1MessagePasserCGT_NotAllowedOnCGTMode", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/LiquidityController.json b/packages/contracts-bedrock/snapshots/abi/LiquidityController.json new file mode 100644 index 0000000000000..3a61fc231c183 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/LiquidityController.json @@ -0,0 +1,222 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "authorizeMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "burn", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_minter", + "type": "address" + } + ], + "name": "deauthorizeMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "gasPayingTokenName", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasPayingTokenSymbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_gasPayingTokenName", + "type": "string" + }, + { + "internalType": "string", + "name": "_gasPayingTokenSymbol", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "minters", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LiquidityBurned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LiquidityMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MinterAuthorized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MinterDeauthorized", + "type": "event" + }, + { + "inputs": [], + "name": "LiquidityController_Unauthorized", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/NativeAssetLiquidity.json b/packages/contracts-bedrock/snapshots/abi/NativeAssetLiquidity.json new file mode 100644 index 0000000000000..156ece4cc1361 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/NativeAssetLiquidity.json @@ -0,0 +1,83 @@ +[ + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "LiquidityDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "LiquidityWithdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "NativeAssetLiquidity_InsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "NativeAssetLiquidity_Unauthorized", + "type": "error" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json index 49ae551310b01..9d19d18dbe5db 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json @@ -824,6 +824,11 @@ "name": "OptimismPortal_NoReentrancy", "type": "error" }, + { + "inputs": [], + "name": "OptimismPortal_NotAllowedOnCGTMode", + "type": "error" + }, { "inputs": [], "name": "OptimismPortal_ProofNotOldEnough", diff --git a/packages/contracts-bedrock/snapshots/abi/SystemConfig.json b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json index 10a956622f8f5..fcb9fc5921918 100644 --- a/packages/contracts-bedrock/snapshots/abi/SystemConfig.json +++ b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json @@ -413,6 +413,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "isCustomGasToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index 366cbca9da7c8..f2acb41fd3460 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -20,16 +20,16 @@ "sourceCodeHash": "0xfca613b5d055ffc4c3cbccb0773ddb9030abedc1aa6508c9e2e7727cc0cd617b" }, "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0x9f9a3738b05cae6597ea9a5c5747f7dbd3a5328b05a319955054fbd8b1aaa791", - "sourceCodeHash": "0x154c764083f353e2a56337c0dd5cbcd6f2e12c21966cd0580c7a0f96c4e147dd" + "initCodeHash": "0x6dfe2a337e7690287b571c360dc972101fb2c93ab17b2bcd2cb1ef5e6b858e59", + "sourceCodeHash": "0x4e2237a9a11581b3ea9800fe636e201f99d9e4166f026824dfd79fc8f2c1de11" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { "initCodeHash": "0x57d6a6729d887ead009d518e8f17fa0d26bfc97b8efe1494ab4ef8dbb000d109", "sourceCodeHash": "0x1d58891954cf782d2fe4f112b0c7fd25be991c2b8873f10d8545c653b517cac9" }, "src/L1/OptimismPortal2.sol:OptimismPortal2": { - "initCodeHash": "0x5bf576ea7f566e402a997204988471fc9b971410aa9dff8fe810b10baf6b7456", - "sourceCodeHash": "0xcde7f2a838d13bf3bd2140a686d0c31472b637ab84d18ee46963977f036f80eb" + "initCodeHash": "0x2c01bc6c0a55a1a27263224e05c1b28703ff85c61075bae7ab384b3043820ed2", + "sourceCodeHash": "0x16fb96f4d29a10d03b3b9c70edf56df51e97c2a1a3f0ba36aae79469b446ad5c" }, "src/L1/OptimismPortalInterop.sol:OptimismPortalInterop": { "initCodeHash": "0x087281cd2a48e882648c09fa90bfcca7487d222e16300f9372deba6b2b8ccfad", @@ -44,8 +44,8 @@ "sourceCodeHash": "0xbf344c4369b8cb00ec7a3108f72795747f3bc59ab5b37ac18cf21e72e2979dbf" }, "src/L1/SystemConfig.sol:SystemConfig": { - "initCodeHash": "0x6e1e3cf76f08916bf6a3aed2b68772bd5ade935db4f0f876e682dc7a586334fb", - "sourceCodeHash": "0x006e3560f8b2e17133eb10a116916798ddc4345a7b006f8504dab69e810adb1c" + "initCodeHash": "0x7c560a18cde0e6139c263d61fec2e8be53dc171ccd7f791b56e100bcd90237f8", + "sourceCodeHash": "0x04ef4b7b4248fb06b098370f3e12434aa16723c23efcef73b77bf07e3475c124" }, "src/L2/BaseFeeVault.sol:BaseFeeVault": { "initCodeHash": "0x9b664e3d84ad510091337b4aacaa494b142512e2f6f7fbcdb6210ed62ca9b885", @@ -64,8 +64,12 @@ "sourceCodeHash": "0x4351fe2ac1106c8c220b8cfe7839bc107c24d8084deb21259ac954f5a362725d" }, "src/L2/L1Block.sol:L1Block": { - "initCodeHash": "0xc35734387887a95f611888f3944546c6bcf82fd4c05dcdaa1e019779b628ad68", - "sourceCodeHash": "0x6e5349fd781d5f0127ff29ccea4d86a80240550cfa322364183a0f629abcb43e" + "initCodeHash": "0x03285c88bf59fd17004489269134abf740d8111b9cb55a6c542a5dc27121d988", + "sourceCodeHash": "0x2cad0fa9b950c9306eb7a77622486ebc9aa2c2530a4c167c460819dba4dbaf9a" + }, + "src/L2/L1BlockCGT.sol:L1BlockCGT": { + "initCodeHash": "0x4a12ae06f475c342268b0cd2c1fb8fe5f49210813eb6349b1cd6cd10ec9748c1", + "sourceCodeHash": "0x97b84b125df97ca4ad6fb1bd5c05998115970f37e71d7bccb5b902144fb8f8de" }, "src/L2/L1FeeVault.sol:L1FeeVault": { "initCodeHash": "0x9b664e3d84ad510091337b4aacaa494b142512e2f6f7fbcdb6210ed62ca9b885", @@ -88,13 +92,25 @@ "sourceCodeHash": "0xde724da82ecf3c96b330c2876a7285b6e2b933ac599241eaa3174c443ebbe33a" }, "src/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser": { - "initCodeHash": "0x88f7b25f956eceeab9ad84c17e66cded6a1acbb933054ac2c8b336641f70f875", - "sourceCodeHash": "0x83396cbd12a0c5c02e09a4d99c4b62ab4e9d9eb762745e63283e2e818a78a39c" + "initCodeHash": "0xe30675ea6623cd7390dd2cd1e9a523c92c66956dfab86d06e318eb410cd1989b", + "sourceCodeHash": "0xdc7bd63134eeab163a635950f2afd16b59f40f9cf1306f2ed33ad661cc7b4962" + }, + "src/L2/L2ToL1MessagePasserCGT.sol:L2ToL1MessagePasserCGT": { + "initCodeHash": "0xf36eab44c41249b4d8ea95a21b70f1eae55b1a555384870c2f4ca306fa9121b6", + "sourceCodeHash": "0xec1736e67134e22ad9ceb0b8b6c116fd169637aa6729c05d9f0f4b02547aaac0" }, "src/L2/L2ToL2CrossDomainMessenger.sol:L2ToL2CrossDomainMessenger": { "initCodeHash": "0x975fd33a3a386310d54dbb01b56f3a6a8350f55a3b6bd7781e5ccc2166ddf2e6", "sourceCodeHash": "0xbea4229c5c6988243dbc7cf5a086ddd412fe1f2903b8e20d56699fec8de0c2c9" }, + "src/L2/LiquidityController.sol:LiquidityController": { + "initCodeHash": "0x19ce7a691d1f8631bfce9fea002c385c418fc69c2e9a9aa5d44ee0cf348c1026", + "sourceCodeHash": "0x87351013f5bcca917dfdd916b06b8ece6bd447acae146f004a33d88f59ce2487" + }, + "src/L2/NativeAssetLiquidity.sol:NativeAssetLiquidity": { + "initCodeHash": "0x04b176e5d484e54173a5644c833117c5fd9f055dce8678be9ec4cf07c0f01f00", + "sourceCodeHash": "0x79289174e875ead5a6290df9af1951d6c0ff0dc6809601e1c7a80110ceb8e945" + }, "src/L2/OperatorFeeVault.sol:OperatorFeeVault": { "initCodeHash": "0x3d8c0d7736e8767f2f797da1c20c5fe30bd7f48a4cf75f376290481ad7c0f91f", "sourceCodeHash": "0x2022fdb4e32769eb9446dab4aed4b8abb5261fd866f381cccfa7869df1a2adff" @@ -239,4 +255,4 @@ "initCodeHash": "0x2bfce526f82622288333d53ca3f43a0a94306ba1bab99241daa845f8f4b18bd4", "sourceCodeHash": "0xf49d7b0187912a6bb67926a3222ae51121e9239495213c975b3b4b217ee57a1b" } -} \ No newline at end of file +} diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L1BlockCGT.json b/packages/contracts-bedrock/snapshots/storageLayout/L1BlockCGT.json new file mode 100644 index 0000000000000..2c23f06367859 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L1BlockCGT.json @@ -0,0 +1,93 @@ +[ + { + "bytes": "8", + "label": "number", + "offset": 0, + "slot": "0", + "type": "uint64" + }, + { + "bytes": "8", + "label": "timestamp", + "offset": 8, + "slot": "0", + "type": "uint64" + }, + { + "bytes": "32", + "label": "basefee", + "offset": 0, + "slot": "1", + "type": "uint256" + }, + { + "bytes": "32", + "label": "hash", + "offset": 0, + "slot": "2", + "type": "bytes32" + }, + { + "bytes": "8", + "label": "sequenceNumber", + "offset": 0, + "slot": "3", + "type": "uint64" + }, + { + "bytes": "4", + "label": "blobBaseFeeScalar", + "offset": 8, + "slot": "3", + "type": "uint32" + }, + { + "bytes": "4", + "label": "baseFeeScalar", + "offset": 12, + "slot": "3", + "type": "uint32" + }, + { + "bytes": "32", + "label": "batcherHash", + "offset": 0, + "slot": "4", + "type": "bytes32" + }, + { + "bytes": "32", + "label": "l1FeeOverhead", + "offset": 0, + "slot": "5", + "type": "uint256" + }, + { + "bytes": "32", + "label": "l1FeeScalar", + "offset": 0, + "slot": "6", + "type": "uint256" + }, + { + "bytes": "32", + "label": "blobBaseFee", + "offset": 0, + "slot": "7", + "type": "uint256" + }, + { + "bytes": "8", + "label": "operatorFeeConstant", + "offset": 0, + "slot": "8", + "type": "uint64" + }, + { + "bytes": "4", + "label": "operatorFeeScalar", + "offset": 8, + "slot": "8", + "type": "uint32" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2ToL1MessagePasserCGT.json b/packages/contracts-bedrock/snapshots/storageLayout/L2ToL1MessagePasserCGT.json new file mode 100644 index 0000000000000..09cc3b5440136 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2ToL1MessagePasserCGT.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "32", + "label": "sentMessages", + "offset": 0, + "slot": "0", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "30", + "label": "msgNonce", + "offset": 0, + "slot": "1", + "type": "uint240" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/LiquidityController.json b/packages/contracts-bedrock/snapshots/storageLayout/LiquidityController.json new file mode 100644 index 0000000000000..d817ac7953d16 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/LiquidityController.json @@ -0,0 +1,37 @@ +[ + { + "bytes": "1", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "uint8" + }, + { + "bytes": "1", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "bool" + }, + { + "bytes": "32", + "label": "minters", + "offset": 0, + "slot": "1", + "type": "mapping(address => bool)" + }, + { + "bytes": "32", + "label": "gasPayingTokenName", + "offset": 0, + "slot": "2", + "type": "string" + }, + { + "bytes": "32", + "label": "gasPayingTokenSymbol", + "offset": 0, + "slot": "3", + "type": "string" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/NativeAssetLiquidity.json b/packages/contracts-bedrock/snapshots/storageLayout/NativeAssetLiquidity.json new file mode 100644 index 0000000000000..0637a088a01e8 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/NativeAssetLiquidity.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol b/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol new file mode 100644 index 0000000000000..f3a30ad98120f --- /dev/null +++ b/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Contracts +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +// Interfaces +import { IOKB } from "interfaces/L1/IOKB.sol"; +import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; + +/// @title DepositedOKBAdapter +/// @notice This contract is an ERC20 adapter that allows for burning OKB tokens on L1 +/// and depositing them into L2. It enforces the strict 21 million supply cap +/// by burning OKB tokens and minting equivalent deposit tokens (dOKB) that can only +/// be used with the OptimismPortal2 for deposits to L2. +/// +/// Key features: +/// - Burns OKB from user's wallet upon deposit +/// - Mints deposit tokens (dOKB) that are locked to this contract +/// - Only this contract and the OptimismPortal2 have balances of dOKB. +/// - Automatically initiates L2 deposit transaction +/// +/// @dev This token is set as the gasPayingToken on SystemConfig. +contract DepositedOKBAdapter is ERC20, Ownable { + /// @notice Address of the OptimismPortal2 contract that this adapter works with. + IOptimismPortal2 public immutable PORTAL; + + /// @notice Address of the OKB token contract. + IOKB public immutable OKB; + + /// @notice Default gas limit for L2 deposit transactions. + uint64 public constant DEFAULT_GAS_LIMIT = 100_000; + + /// @notice Mapping of whitelisted addresses allowed to deposit. + mapping(address => bool) public whitelist; + + /// @notice Emitted when a user deposits OKB and initiates an L2 transaction. + /// @param from Address that deposited the OKB. + /// @param to Target address on L2. + /// @param amount Amount of OKB burned and deposited. + event Deposited(address indexed from, address indexed to, uint256 amount); + + /// @notice Emitted when an address is added to the whitelist. + /// @param account Address that was added to the whitelist. + event WhitelistAdded(address indexed account); + + /// @notice Emitted when an address is removed from the whitelist. + /// @param account Address that was removed from the whitelist. + event WhitelistRemoved(address indexed account); + + /// @notice Thrown when transfer is attempted outside of portal operations. + error TransferNotAllowed(); + + /// @notice Thrown when amount is zero. + error AmountMustBeGreaterThanZero(); + + /// @notice Thrown when balance is insufficient. + error InsufficientBalance(); + + /// @notice Thrown when transfer fails. + error TransferFailed(); + + /// @notice Thrown when transfer OKB from user fails. + error TransferFromUserFailed(); + + /// @notice Thrown when OKB balance is not equal to the amount deposited. + error OKBBalanceMismatch(); + + /// @notice Thrown when caller is not whitelisted. + error NotWhitelisted(); + + /// @notice Thrown when address is zero. + error AddressCannotBeZero(); + + /// @notice Thrown when OKB balance is not zero. + error OKBBalanceNotZeroAfterBurn(); + + /// @notice Constructor sets up the adapter with references to OKB, OptimismPortal, rescuer, + /// and premints the maximum supply to the owner. + /// @param _okb Address of the OKB token contract. + /// @param _portal Address of the OptimismPortal2 contract. + /// @param _owner Address of the contract owner. + constructor(address _okb, address payable _portal, address _owner) ERC20("Deposited OKB", "dOKB") { + if (_okb == address(0)) { + revert AddressCannotBeZero(); + } + if (_portal == address(0)) { + revert AddressCannotBeZero(); + } + OKB = IOKB(_okb); + PORTAL = IOptimismPortal2(_portal); + + // Premint total supply of OKB to this contract to enforce hard cap + _mint(address(this), OKB.totalSupply()); + + // Transfer ownership to the owner + transferOwnership(_owner); + } + + /// @notice Adds multiple addresses to the whitelist in a single transaction. + /// @param _accounts Array of addresses to add to the whitelist. + function addToWhitelistBatch(address[] calldata _accounts) external onlyOwner { + for (uint256 i = 0; i < _accounts.length; i++) { + if (_accounts[i] == address(0)) { + revert AddressCannotBeZero(); + } + whitelist[_accounts[i]] = true; + emit WhitelistAdded(_accounts[i]); + } + } + + /// @notice Removes multiple addresses from the whitelist in a single transaction. + /// @param _accounts Array of addresses to remove from the whitelist. + function removeFromWhitelistBatch(address[] calldata _accounts) external onlyOwner { + for (uint256 i = 0; i < _accounts.length; i++) { + if (_accounts[i] == address(0)) { + revert AddressCannotBeZero(); + } + whitelist[_accounts[i]] = false; + emit WhitelistRemoved(_accounts[i]); + } + } + + /// @notice Allows whitelisted users to burn OKB and deposit into L2. + /// This function: + /// 1. Checks if caller is whitelisted + /// 2. Transfers OKB from the user to this contract + /// 3. Creates a minimal proxy burner contract + /// 4. Transfers the exact amount of OKB to the burner + /// 5. Burns the OKB via the burner (which self-destructs) + /// 6. Mints deposit tokens to this contract + /// 7. Initiates an L2 deposit transaction via the portal + /// @param _to Target address on L2 to receive the tokens. + /// @param _amount Amount of OKB to burn and deposit. + function deposit(address _to, uint256 _amount) external { + if (!whitelist[msg.sender]) { + revert NotWhitelisted(); + } + if (_amount == 0) { + revert AmountMustBeGreaterThanZero(); + } + if (OKB.balanceOf(msg.sender) < _amount) { + revert InsufficientBalance(); + } + + // Transfer any remaining OKB to rescuer. + // If someone mistakenly directly transfer OKB to this contract, transfer it to the owner. + if (OKB.balanceOf(address(this)) > 0) { + bool transferSuccess = OKB.transfer(owner(), OKB.balanceOf(address(this))); + if (!transferSuccess) { + revert TransferFailed(); + } + } + + // Transfer OKB from user to this contract first + bool transferFromUserSuccess = OKB.transferFrom(msg.sender, address(this), _amount); + if (!transferFromUserSuccess) { + revert TransferFromUserFailed(); + } + + // Check invariant: the amount of OKB in this contract should be equal to the amount deposited. + if (OKB.balanceOf(address(this)) != _amount) { + revert OKBBalanceMismatch(); + } + + // Burn all OKB from this contract + OKB.triggerBridge(); + + // Check invariant: the amount of OKB in this contract should be zero after burning. + if (OKB.balanceOf(address(this)) > 0) { + revert OKBBalanceNotZeroAfterBurn(); + } + + // Approve the portal to pull the deposit tokens + _approve(address(this), address(PORTAL), _amount); + + // Portal will call transferFrom to pull the deposit tokens + PORTAL.depositERC20Transaction(_to, _amount, _amount, DEFAULT_GAS_LIMIT, false, ""); + + emit Deposited(msg.sender, _to, _amount); + } + + /// @notice Override transfer to disable transfers + /// This ensures that deposit tokens can only be used by the portal + /// and cannot be transferred or traded elsewhere. + /// @return bool Always reverts. + function transfer(address, /* _to */ uint256 /* _amount */ ) public virtual override returns (bool) { + // Do not allow any transfers + revert TransferNotAllowed(); + } + + /// @notice Override transferFrom to disable transfers + /// This ensures that deposit tokens can only be used by the portal + /// and cannot be transferred or traded elsewhere. + /// @param from Sender address. + /// @param to Recipient address. + /// @param amount Amount to transfer. + /// @return bool True if transfer succeeds. + function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { + // Ensure only the portal can pull from this contract, and only to the portal. + if (msg.sender == address(PORTAL) && to == address(PORTAL) && from == address(this)) { + return super.transferFrom(from, to, amount); + } + + revert TransferNotAllowed(); + } + + /// @notice Allows owner to rescue ERC20 tokens sent to this contract. + /// @param _token Address of the ERC20 token to rescue. + /// @param _to Address to send the tokens to. + /// @param _amount Amount of tokens to rescue. + function rescueERC20(address _token, address _to, uint256 _amount) external onlyOwner { + if (_token == address(0)) { + revert AddressCannotBeZero(); + } + if (_to == address(0)) { + revert AddressCannotBeZero(); + } + if (_amount == 0) { + revert AmountMustBeGreaterThanZero(); + } + + bool transferSuccess = IERC20(_token).transfer(_to, _amount); + if (!transferSuccess) { + revert TransferFailed(); + } + } +} diff --git a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol index 98c557a603c37..cceb56ac55b84 100644 --- a/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L1/L1ERC721Bridge.sol @@ -94,6 +94,7 @@ contract L1ERC721Bridge is ERC721Bridge, ProxyAdminOwnedBase, ReinitializableBas external onlyOtherBridge { + revert("not allow bridge"); require(paused() == false, "L1ERC721Bridge: paused"); require(_localToken != address(this), "L1ERC721Bridge: local token cannot be self"); @@ -128,6 +129,7 @@ contract L1ERC721Bridge is ERC721Bridge, ProxyAdminOwnedBase, ReinitializableBas internal override { + revert("not allow bridge"); require(_remoteToken != address(0), "L1ERC721Bridge: remote token cannot be address(0)"); // Construct calldata for _l2Token.finalizeBridgeERC721(_to, _tokenId) diff --git a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol index 465ec7f7ed5eb..3e0d6c68cb1ed 100644 --- a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol +++ b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol @@ -142,6 +142,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl /// Data supplied here will not be used to execute any code on L2 and is /// only emitted as extra data for the convenience of off-chain tooling. function depositETH(uint32 _minGasLimit, bytes calldata _extraData) external payable onlyEOA { + revert("not allow bridge"); _initiateETHDeposit(msg.sender, msg.sender, _minGasLimit, _extraData); } @@ -157,6 +158,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl /// Data supplied here will not be used to execute any code on L2 and is /// only emitted as extra data for the convenience of off-chain tooling. function depositETHTo(address _to, uint32 _minGasLimit, bytes calldata _extraData) external payable { + revert("not allow bridge"); _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData); } @@ -180,6 +182,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl virtual onlyEOA { + revert("not allow bridge"); _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData); } @@ -204,6 +207,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl external virtual { + revert("not allow bridge"); _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData); } @@ -222,6 +226,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl external payable { + revert("not allow bridge"); finalizeBridgeETH(_from, _to, _amount, _extraData); } @@ -243,6 +248,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl ) external { + revert("not allow bridge"); finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData); } @@ -259,6 +265,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl /// @param _minGasLimit Minimum gas limit for the deposit message on L2. /// @param _extraData Optional data to forward to L2. function _initiateETHDeposit(address _from, address _to, uint32 _minGasLimit, bytes memory _extraData) internal { + revert("not allow bridge"); _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData); } @@ -281,6 +288,7 @@ contract L1StandardBridge is StandardBridge, ProxyAdminOwnedBase, Reinitializabl ) internal { + revert("not allow bridge"); _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData); } diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index 142fa67ea358f..d49d82342ff58 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -68,10 +68,11 @@ contract OPContractsManagerContractsContainer { implementation = _implementations; devFeatureBitmap = _devFeatureBitmap; + // Allow CGT feature to be enabled on Mainnet. // Development features MUST NOT be enabled on Mainnet. - if (block.chainid == 1 && !_isTestingEnvironment() && uint256(_devFeatureBitmap) != 0) { - revert OPContractsManagerContractsContainer_DevFeatureInProd(); - } + // if (block.chainid == 1 && !_isTestingEnvironment() && uint256(_devFeatureBitmap) != 0) { + // revert OPContractsManagerContractsContainer_DevFeatureInProd(); + // } } function blueprints() public view returns (OPContractsManager.Blueprints memory) { @@ -1106,6 +1107,12 @@ contract OPContractsManagerDeployer is OPContractsManagerBase { output.opChainProxyAdmin, address(output.systemConfigProxy), implementation.systemConfigImpl, data ); + // If the custom gas token feature was requested, enable the custom gas token feature in the SystemConfig + // contract. + if (isDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN)) { + output.systemConfigProxy.setFeature(Features.CUSTOM_GAS_TOKEN, true); + } + // If the interop feature was requested, enable the ETHLockbox feature in the SystemConfig // contract. Only other way to get the ETHLockbox feature as of u16a is to have already had // the ETHLockbox in U16 and then upgrade to U16a. @@ -1318,6 +1325,21 @@ contract OPContractsManagerDeployer is OPContractsManagerBase { (IResourceMetering.ResourceConfig memory referenceResourceConfig, ISystemConfig.Addresses memory opChainAddrs) = defaultSystemConfigParams(_input, _output); + return systemConfigInitializerData(_input, _superchainConfig, referenceResourceConfig, opChainAddrs); + } + + /// @notice Helper method for encoding the call data for the SystemConfig initializer. + function systemConfigInitializerData( + OPContractsManager.DeployInput memory _input, + ISuperchainConfig _superchainConfig, + IResourceMetering.ResourceConfig memory _referenceResourceConfig, + ISystemConfig.Addresses memory _opChainAddrs + ) + internal + view + virtual + returns (bytes memory) + { return abi.encodeCall( ISystemConfig.initialize, ( @@ -1327,9 +1349,9 @@ contract OPContractsManagerDeployer is OPContractsManagerBase { bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash _input.gasLimit, _input.roles.unsafeBlockSigner, - referenceResourceConfig, + _referenceResourceConfig, chainIdToBatchInboxAddress(_input.l2ChainId), - opChainAddrs, + _opChainAddrs, _input.l2ChainId, _superchainConfig ) diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index 071bf55a88922..a16c064e8724c 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -17,6 +17,7 @@ import { SecureMerkleTrie } from "src/libraries/trie/SecureMerkleTrie.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { GameStatus, GameType } from "src/dispute/lib/Types.sol"; import { Features } from "src/libraries/Features.sol"; +import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; // Interfaces import { ISemver } from "interfaces/universal/ISemver.sol"; @@ -27,6 +28,7 @@ import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /// @custom:proxied true /// @title OptimismPortal2 @@ -168,6 +170,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase /// @notice Thrown when the portal is paused. error OptimismPortal_CallPaused(); + /// @notice Thrown when a CGT withdrawal is not allowed. + error OptimismPortal_NotAllowedOnCGTMode(); + /// @notice Thrown when a gas estimation transaction is being executed. error OptimismPortal_GasEstimation(); @@ -204,10 +209,16 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase /// @notice Thrown when ETHLockbox is set/unset incorrectly depending on the feature flag. error OptimismPortal_InvalidLockboxState(); + /// @notice Thrown when trying to use depositERC20Transaction on a non-CGT chain. + error OptimismPortal_OnlyCustomGasToken(); + + /// @notice Thrown when trying to use depositERC20Transaction but gas token not set. + error OptimismPortal_InvalidGasToken(); + /// @notice Semantic version. - /// @custom:semver 5.1.1 + /// @custom:semver 5.2.0 function version() public pure virtual returns (string memory) { - return "5.1.1"; + return "5.2.0"; } /// @param _proofMaturityDelaySeconds The proof maturity delay in seconds. @@ -342,14 +353,19 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase // Cannot prove withdrawal transactions while the system is paused. _assertNotPaused(); - // Fetch the dispute game proxy from the `DisputeGameFactory` contract. - (,, IDisputeGame disputeGameProxy) = disputeGameFactory().gameAtIndex(_disputeGameIndex); - // Make sure that the target address is safe. if (_isUnsafeTarget(_tx.target)) { revert OptimismPortal_BadTarget(); } + // Cannot prove withdrawal with value when custom gas token mode is enabled. + if (_isUsingCustomGasToken()) { + if (_tx.value > 0) revert OptimismPortal_NotAllowedOnCGTMode(); + } + + // Fetch the dispute game proxy from the `DisputeGameFactory` contract. + (,, IDisputeGame disputeGameProxy) = disputeGameFactory().gameAtIndex(_disputeGameIndex); + // Game must be a Proper Game. if (!anchorStateRegistry.isGameProper(disputeGameProxy)) { revert OptimismPortal_ImproperDisputeGame(); @@ -438,6 +454,11 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase // Cannot finalize withdrawal transactions while the system is paused. _assertNotPaused(); + // Cannot finalize withdrawal with value when custom gas token mode is enabled. + if (_isUsingCustomGasToken()) { + if (_tx.value > 0) revert OptimismPortal_NotAllowedOnCGTMode(); + } + // Make sure that the l2Sender has not yet been set. The l2Sender is set to a value other // than the default value when a withdrawal transaction is being finalized. This check is // a defacto reentrancy guard. @@ -538,6 +559,78 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase } } + /// @notice Accepts deposits of ERC20 (custom gas token) and data, and emits a TransactionDeposited + /// event for use in deriving deposit transactions. This function is specifically for depositing + /// the custom gas token on CGT-enabled chains. Users must approve this contract to spend their + /// tokens before calling this function. + /// @param _to Target address on L2. + /// @param _mint Amount of custom gas token to mint on L2 (transferred from msg.sender). + /// @param _value Amount of custom gas token to send to the recipient on L2. + /// @param _gasLimit Amount of L2 gas to purchase by burning gas on L1. + /// @param _isCreation Whether or not the transaction is a contract creation. + /// @param _data Data to trigger the recipient with. + function depositERC20Transaction( + address _to, + uint256 _mint, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + public + metered(_gasLimit) + { + // Only allow ERC20 deposits if custom gas token mode is enabled + if (!_isUsingCustomGasToken()) { + revert OptimismPortal_OnlyCustomGasToken(); + } + + // Transfer the custom gas token from the caller to this contract + (address token,) = systemConfig.gasPayingToken(); + if (token == Constants.ETHER) { + revert OptimismPortal_InvalidGasToken(); + } + + if (_mint > 0) { + IERC20(token).transferFrom(msg.sender, address(this), _mint); + } + + // Just to be safe, make sure that people specify address(0) as the target when doing + // contract creations. + if (_isCreation && _to != address(0)) { + revert OptimismPortal_BadTarget(); + } + + // Prevent depositing transactions that have too small of a gas limit. Users should pay + // more for more resource usage. + if (_gasLimit < minimumGasLimit(uint64(_data.length))) { + revert OptimismPortal_GasLimitTooLow(); + } + + // Prevent the creation of deposit transactions that have too much calldata. This gives an + // upper limit on the size of unsafe blocks over the p2p network. 120kb is chosen to ensure + // that the transaction can fit into the p2p network policy of 128kb even though deposit + // transactions are not gossipped over the p2p network. + if (_data.length > 120_000) { + revert OptimismPortal_CalldataTooLarge(); + } + + // Transform the from-address to its alias if the caller is a contract. + address from = msg.sender; + if (!EOA.isSenderEOA()) { + from = AddressAliasHelper.applyL1ToL2Alias(msg.sender); + } + + // Compute the opaque data that will be emitted as part of the TransactionDeposited event. + // We use opaque data so that we can update the TransactionDeposited event in the future + // without breaking the current interface. + bytes memory opaqueData = abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data); + + // Emit a TransactionDeposited event so that the rollup node can derive a deposit + // transaction for this deposit. + emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData); + } + /// @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in /// deriving deposit transactions. Note that if a deposit is made by a contract, its /// address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider @@ -560,6 +653,10 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase payable metered(_gasLimit) { + if (_isUsingCustomGasToken()) { + if (msg.value > 0) revert OptimismPortal_NotAllowedOnCGTMode(); + } + // If using ETHLockbox, lock the ETH in the ETHLockbox. if (_isUsingLockbox()) { if (msg.value > 0) ethLockbox.lockETH{ value: msg.value }(); @@ -614,6 +711,14 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase return systemConfig.isFeatureEnabled(Features.ETH_LOCKBOX) && address(ethLockbox) != address(0); } + /// @notice Checks if the Custom Gas Token feature is enabled. + /// @return bool True if the Custom Gas Token feature is enabled. + function _isUsingCustomGasToken() internal view returns (bool) { + // NOTE: Chains are not supposed to enable Custom Gas Token (CGT) mode after initial deployment. + // Enabling CGT post-deployment is strongly discouraged and may lead to unexpected behavior. + return systemConfig.isFeatureEnabled(Features.CUSTOM_GAS_TOKEN); + } + /// @notice Asserts that the contract is not paused. function _assertNotPaused() internal view { if (paused()) { diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index 68b5dba6ef81c..0ed197114ecd5 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -9,19 +9,21 @@ import { ProxyAdminOwnedBase } from "src/L1/ProxyAdminOwnedBase.sol"; // Libraries import { Storage } from "src/libraries/Storage.sol"; import { Features } from "src/libraries/Features.sol"; - +import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; +import { Constants } from "src/libraries/Constants.sol"; // Interfaces import { ISemver } from "interfaces/universal/ISemver.sol"; import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; +import { IGasToken } from "src/libraries/GasPayingToken.sol"; /// @custom:proxied true /// @title SystemConfig /// @notice The SystemConfig contract is used to manage configuration of an Optimism network. /// All configuration is stored on L1 and picked up by L2 as part of the derviation of /// the L2 chain. -contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, ReinitializableBase, ISemver { +contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, ReinitializableBase, ISemver, IGasToken { /// @notice Enum representing different types of updates. /// @custom:value BATCHER Represents an update to the batcher hash. /// @custom:value FEE_SCALARS Represents an update to l1 data fee scalars. @@ -160,10 +162,13 @@ contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitializabl /// respectively. error SystemConfig_InvalidFeatureState(); + /// @notice Thrown when attempting to set a value that has already been set + error SystemConfig_ValueAlreadySet(); + /// @notice Semantic version. - /// @custom:semver 3.10.0 + /// @custom:semver 3.11.0 function version() public pure virtual returns (string memory) { - return "3.10.0"; + return "3.11.0"; } /// @notice Constructs the SystemConfig contract. @@ -565,4 +570,52 @@ contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitializabl function guardian() public view returns (address) { return superchainConfig.guardian(); } + + /// @custom:legacy + /// @notice Returns whether the custom gas token feature is enabled. + /// @return bool True if the custom gas token feature is enabled, false otherwise. + function isCustomGasToken() public view returns (bool) { + return isFeatureEnabled[Features.CUSTOM_GAS_TOKEN]; + } + + /// @notice Getter for the ERC20 token address that is used to pay for gas and its decimals. + /// @return address_ Address of the gas paying token. + /// @return decimals_ Decimals of the gas paying token. + function gasPayingToken() public view returns (address address_, uint8 decimals_) { + (address_, decimals_) = GasPayingToken.getToken(); + } + + /// @notice Returns the gas token name. + /// @return name_ Name of the gas paying token. + function gasPayingTokenName() public view returns (string memory name_) { + name_ = GasPayingToken.getName(); + } + + /// @notice Returns the gas token symbol. + /// @return symbol_ Symbol of the gas paying token. + function gasPayingTokenSymbol() public view returns (string memory symbol_) { + symbol_ = GasPayingToken.getSymbol(); + } + + /// @notice Sets the gas paying token and its metadata. Can only be called by the owner. + /// @param _token The address of the gas paying token. + /// @param _decimals The decimals of the gas paying token. + /// @param _name The name of the gas paying token as a bytes32. + /// @param _symbol The symbol of the gas paying token as a bytes32. + function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external onlyOwner { + (address gasToken,) = gasPayingToken(); + if (gasToken != Constants.ETHER) { + revert SystemConfig_ValueAlreadySet(); + } + _setGasPayingToken(_token, _decimals, _name, _symbol); + } + + /// @notice Internal function for setting the gas paying token. + /// @param _token The address of the gas paying token. + /// @param _decimals The decimals of the gas paying token. + /// @param _name The name of the gas paying token as a bytes32. + /// @param _symbol The symbol of the gas paying token as a bytes32. + function _setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) internal { + GasPayingToken.set(_token, _decimals, _name, _symbol); + } } diff --git a/packages/contracts-bedrock/src/L2/L1Block.sol b/packages/contracts-bedrock/src/L2/L1Block.sol index 31935dfab7eac..5cba32efcc410 100644 --- a/packages/contracts-bedrock/src/L2/L1Block.sol +++ b/packages/contracts-bedrock/src/L2/L1Block.sol @@ -61,13 +61,13 @@ contract L1Block is ISemver { /// @notice The scalar value applied to the operator fee. uint32 public operatorFeeScalar; - /// @custom:semver 1.6.1 + /// @custom:semver 1.6.2 function version() public pure virtual returns (string memory) { - return "1.6.1"; + return "1.6.2"; } /// @notice Returns the gas paying token, its decimals, name and symbol. - function gasPayingToken() public pure returns (address addr_, uint8 decimals_) { + function gasPayingToken() public pure virtual returns (address addr_, uint8 decimals_) { addr_ = Constants.ETHER; decimals_ = 18; } @@ -75,20 +75,20 @@ contract L1Block is ISemver { /// @notice Returns the gas paying token name. /// If nothing is set in state, then it means ether is used. /// This function cannot be removed because WETH depends on it. - function gasPayingTokenName() public pure returns (string memory name_) { + function gasPayingTokenName() public view virtual returns (string memory name_) { name_ = "Ether"; } /// @notice Returns the gas paying token symbol. /// If nothing is set in state, then it means ether is used. /// This function cannot be removed because WETH depends on it. - function gasPayingTokenSymbol() public pure returns (string memory symbol_) { + function gasPayingTokenSymbol() public view virtual returns (string memory symbol_) { symbol_ = "ETH"; } /// @notice Getter for custom gas token paying networks. Returns true if the /// network uses a custom gas token. - function isCustomGasToken() public pure returns (bool is_) { + function isCustomGasToken() public view virtual returns (bool is_) { is_ = false; } diff --git a/packages/contracts-bedrock/src/L2/L1BlockCGT.sol b/packages/contracts-bedrock/src/L2/L1BlockCGT.sol new file mode 100644 index 0000000000000..aac68b7915814 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/L1BlockCGT.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Libraries +import { Constants } from "src/libraries/Constants.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { L1Block } from "src/L2/L1Block.sol"; + +// Interfaces +import { ILiquidityController } from "interfaces/L2/ILiquidityController.sol"; + +/// @custom:proxied true +/// @custom:predeploy 0x4200000000000000000000000000000000000015 +/// @title L1BlockCGT +/// @notice The L1BlockCGT predeploy gives users access to information about the last known L1 block. +/// Values within this contract are updated once per epoch (every L1 block) and can only be +/// set by the "depositor" account, a special system address. Depositor account transactions +/// are created by the protocol whenever we move to a new epoch. +contract L1BlockCGT is L1Block { + /// @notice Storage slot for the isCustomGasToken flag + /// @dev bytes32(uint256(keccak256("l1block.isCustomGasToken")) - 1) + bytes32 private constant IS_CUSTOM_GAS_TOKEN_SLOT = + 0xd2ff82c9b477ff6a09f530b1c627ffb4b0b81e2ae2ba427f824162e8dad020aa; + + /// @custom:semver +custom-gas-token + function version() public pure override returns (string memory) { + return string.concat(super.version(), "+custom-gas-token"); + } + + /// @notice Returns whether the gas paying token is custom. + function isCustomGasToken() public view override returns (bool isCustom_) { + bytes32 slot = IS_CUSTOM_GAS_TOKEN_SLOT; + assembly { + isCustom_ := sload(slot) + } + } + + /// @notice Returns the gas paying token, its decimals, name and symbol. + function gasPayingToken() public pure override returns (address, uint8) { + revert("L1BlockCGT: deprecated"); + } + + /// @notice Returns the gas paying token name. + /// If nothing is set in state, then it means ether is used. + /// This function cannot be removed because WETH depends on it. + function gasPayingTokenName() public view override returns (string memory name_) { + name_ = + isCustomGasToken() ? ILiquidityController(Predeploys.LIQUIDITY_CONTROLLER).gasPayingTokenName() : "Ether"; + } + + /// @notice Returns the gas paying token symbol. + /// If nothing is set in state, then it means ether is used. + /// This function cannot be removed because WETH depends on it. + function gasPayingTokenSymbol() public view override returns (string memory symbol_) { + symbol_ = + isCustomGasToken() ? ILiquidityController(Predeploys.LIQUIDITY_CONTROLLER).gasPayingTokenSymbol() : "ETH"; + } + + /// @notice Set chain to use custom gas token (callable by depositor account) + function setCustomGasToken() external { + require( + msg.sender == Constants.DEPOSITOR_ACCOUNT, + "L1Block: only the depositor account can set isCustomGasToken flag" + ); + require(isCustomGasToken() == false, "L1Block: CustomGasToken already active"); + + bytes32 slot = IS_CUSTOM_GAS_TOKEN_SLOT; + assembly { + sstore(slot, 1) + } + } +} diff --git a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol index e080f694751f9..68f2a235e8f25 100644 --- a/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/L2/L2ERC721Bridge.sol @@ -62,6 +62,7 @@ contract L2ERC721Bridge is ERC721Bridge, ISemver { external onlyOtherBridge { + revert("not allow bridge"); require(_localToken != address(this), "L2ERC721Bridge: local token cannot be self"); // Note that supportsInterface makes a callback to the _localToken address which is user @@ -97,6 +98,7 @@ contract L2ERC721Bridge is ERC721Bridge, ISemver { internal override { + revert("not allow bridge"); require(_remoteToken != address(0), "L2ERC721Bridge: remote token cannot be address(0)"); // Check that the withdrawal is being initiated by the NFT owner diff --git a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol index 1e9c2ac15f315..1df6a0d5f91dc 100644 --- a/packages/contracts-bedrock/src/L2/L2StandardBridge.sol +++ b/packages/contracts-bedrock/src/L2/L2StandardBridge.sol @@ -103,6 +103,7 @@ contract L2StandardBridge is StandardBridge, ISemver { virtual onlyEOA { + revert("not allow bridge"); _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData); } @@ -131,6 +132,7 @@ contract L2StandardBridge is StandardBridge, ISemver { payable virtual { + revert("not allow bridge"); _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData); } @@ -159,6 +161,7 @@ contract L2StandardBridge is StandardBridge, ISemver { ) internal { + revert("not allow bridge"); if (_l2Token == Predeploys.LEGACY_ERC20_ETH) { _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData); } else { diff --git a/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol b/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol index b25a2a1248bc5..682b5ac1b2ccb 100644 --- a/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol +++ b/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol @@ -48,11 +48,13 @@ contract L2ToL1MessagePasser is ISemver { ); /// @notice Emitted when the balance of this contract is burned. - /// @param amount Amount of ETh that was burned. + /// @param amount Amount of ETH that was burned. event WithdrawerBalanceBurnt(uint256 indexed amount); - /// @custom:semver 1.1.2 - string public constant version = "1.1.2"; + /// @custom:semver 1.2.0 + function version() public pure virtual returns (string memory) { + return "1.2.0"; + } /// @notice Allows users to withdraw ETH by sending directly to this contract. receive() external payable { @@ -73,7 +75,7 @@ contract L2ToL1MessagePasser is ISemver { /// @param _target Address to call on L1 execution. /// @param _gasLimit Minimum gas limit for executing the message on L1. /// @param _data Data to forward to L1 target. - function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) public payable { + function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) public payable virtual { bytes32 withdrawalHash = Hashing.hashWithdrawal( Types.WithdrawalTransaction({ nonce: messageNonce(), diff --git a/packages/contracts-bedrock/src/L2/L2ToL1MessagePasserCGT.sol b/packages/contracts-bedrock/src/L2/L2ToL1MessagePasserCGT.sol new file mode 100644 index 0000000000000..efd00314559c2 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/L2ToL1MessagePasserCGT.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; + +// Interfaces +import { IL1Block } from "interfaces/L2/IL1Block.sol"; + +/// @custom:proxied true +/// @custom:predeploy 0x4200000000000000000000000000000000000016 +/// @title L2ToL1MessagePasserCGT +/// @notice The L2ToL1MessagePasserCGT is a dedicated contract where messages that are being sent from +/// L2 to L1 can be stored. The storage root of this contract is pulled up to the top level +/// of the L2 output to reduce the cost of proving the existence of sent messages. +contract L2ToL1MessagePasserCGT is L2ToL1MessagePasser { + /// @notice The error thrown when a withdrawal is initiated with value and custom gas token is used. + error L2ToL1MessagePasserCGT_NotAllowedOnCGTMode(); + + /// @custom:semver +custom-gas-token + function version() public pure override returns (string memory) { + return string.concat(super.version(), "+custom-gas-token"); + } + + /// @notice Sends a message from L2 to L1. + /// @param _target Address to call on L1 execution. + /// @param _gasLimit Minimum gas limit for executing the message on L1. + /// @param _data Data to forward to L1 target. + function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) public payable override { + if (IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).isCustomGasToken() && msg.value > 0) { + revert L2ToL1MessagePasserCGT_NotAllowedOnCGTMode(); + } + super.initiateWithdrawal(_target, _gasLimit, _data); + } +} diff --git a/packages/contracts-bedrock/src/L2/LiquidityController.sol b/packages/contracts-bedrock/src/L2/LiquidityController.sol new file mode 100644 index 0000000000000..571932d477a52 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/LiquidityController.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Contracts +import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; +import { SafeSend } from "src/universal/SafeSend.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces +import { INativeAssetLiquidity } from "interfaces/L2/INativeAssetLiquidity.sol"; +import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; +import { ISemver } from "interfaces/universal/ISemver.sol"; + +/// @custom:proxied true +/// @custom:predeploy 0x420000000000000000000000000000000000002A +/// @title LiquidityController +/// @notice The LiquidityController contract is responsible for controlling the liquidity of the native asset on the L2 +/// chain. +contract LiquidityController is ISemver, Initializable { + /// @notice Emitted when an address is authorized to mint/burn liquidity + /// @param minter The address that was authorized + event MinterAuthorized(address indexed minter); + + /// @notice Emitted when an address is deauthorized to mint/burn liquidity + /// @param minter The address that was deauthorized + event MinterDeauthorized(address indexed minter); + + /// @notice Emitted when liquidity is minted + /// @param minter The address that minted the liquidity + /// @param to The address that received the minted liquidity + /// @param amount The amount of liquidity that was minted + event LiquidityMinted(address indexed minter, address indexed to, uint256 amount); + + /// @notice Emitted when liquidity is burned + /// @param minter The address that burned the liquidity + /// @param amount The amount of liquidity that was burned + event LiquidityBurned(address indexed minter, uint256 amount); + + /// @notice Error for when an address is unauthorized to perform liquidity control operations + error LiquidityController_Unauthorized(); + + /// @notice Semantic version. + /// @custom:semver 1.0.0 + string public constant version = "1.0.0"; + + /// @notice Mapping of addresses authorized to control liquidity operations + mapping(address => bool) public minters; + + /// @notice The name of the native asset + string public gasPayingTokenName; + + /// @notice The symbol of the native asset + string public gasPayingTokenSymbol; + + constructor() { + _disableInitializers(); + } + + /// @notice Initializer. + /// @param _gasPayingTokenName The name of the native asset + /// @param _gasPayingTokenSymbol The symbol of the native asset + function initialize(string memory _gasPayingTokenName, string memory _gasPayingTokenSymbol) external initializer { + gasPayingTokenName = _gasPayingTokenName; + gasPayingTokenSymbol = _gasPayingTokenSymbol; + } + + /// @notice Authorizes an address to perform liquidity control operations + /// @param _minter The address to authorize as a minter + function authorizeMinter(address _minter) external { + if (msg.sender != IProxyAdmin(Predeploys.PROXY_ADMIN).owner()) revert LiquidityController_Unauthorized(); + minters[_minter] = true; + emit MinterAuthorized(_minter); + } + + /// @notice Deauthorizes an address from performing liquidity control operations + /// @param _minter The address to deauthorize as a minter + function deauthorizeMinter(address _minter) external { + if (msg.sender != IProxyAdmin(Predeploys.PROXY_ADMIN).owner()) revert LiquidityController_Unauthorized(); + delete minters[_minter]; + emit MinterDeauthorized(_minter); + } + + /// @notice Mints native asset liquidity and sends it to a specified address + /// @param _to The address to receive the minted native asset + /// @param _amount The amount of native asset to mint and send + function mint(address _to, uint256 _amount) external { + if (!minters[msg.sender]) revert LiquidityController_Unauthorized(); + INativeAssetLiquidity(Predeploys.NATIVE_ASSET_LIQUIDITY).withdraw(_amount); + + // This is a forced ETH send to the recipient, the recipient should NOT expect to be called + new SafeSend{ value: _amount }(payable(_to)); + + emit LiquidityMinted(msg.sender, _to, _amount); + } + + /// @notice Burns native asset liquidity by sending ETH to the contract + function burn() external payable { + if (!minters[msg.sender]) revert LiquidityController_Unauthorized(); + INativeAssetLiquidity(Predeploys.NATIVE_ASSET_LIQUIDITY).deposit{ value: msg.value }(); + + emit LiquidityBurned(msg.sender, msg.value); + } +} diff --git a/packages/contracts-bedrock/src/L2/NativeAssetLiquidity.sol b/packages/contracts-bedrock/src/L2/NativeAssetLiquidity.sol new file mode 100644 index 0000000000000..f0ab2bbba95b9 --- /dev/null +++ b/packages/contracts-bedrock/src/L2/NativeAssetLiquidity.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Contracts +import { SafeSend } from "src/universal/SafeSend.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Interfaces +import { ISemver } from "interfaces/universal/ISemver.sol"; + +/// @custom:predeploy 0x4200000000000000000000000000000000000029 +/// @title NativeAssetLiquidity +/// @notice The NativeAssetLiquidity contract allows other contracts to access native asset liquidity +contract NativeAssetLiquidity is ISemver { + /// @notice Emitted when an address withdraws native asset liquidity. + event LiquidityWithdrawn(address indexed caller, uint256 value); + + /// @notice Emitted when an address deposits native asset liquidity. + event LiquidityDeposited(address indexed caller, uint256 value); + + /// @notice Error for when the contract has insufficient balance. + error NativeAssetLiquidity_InsufficientBalance(); + + /// @notice Error for when an address is unauthorized to perform native asset liquidity operations + error NativeAssetLiquidity_Unauthorized(); + + /// @notice Semantic version. + /// @custom:semver 1.0.0 + string public constant version = "1.0.0"; + + /// @notice Allows an address to lock native asset liquidity into this contract. + function deposit() external payable { + if (msg.sender != Predeploys.LIQUIDITY_CONTROLLER) revert NativeAssetLiquidity_Unauthorized(); + + emit LiquidityDeposited(msg.sender, msg.value); + } + + /// @notice Allows an address to unlock native asset liquidity from this contract. + /// @param _amount The amount of liquidity to unlock. + function withdraw(uint256 _amount) external { + if (msg.sender != Predeploys.LIQUIDITY_CONTROLLER) revert NativeAssetLiquidity_Unauthorized(); + + if (_amount > address(this).balance) revert NativeAssetLiquidity_InsufficientBalance(); + + new SafeSend{ value: _amount }(payable(msg.sender)); + + emit LiquidityWithdrawn(msg.sender, _amount); + } +} diff --git a/packages/contracts-bedrock/src/libraries/DevFeatures.sol b/packages/contracts-bedrock/src/libraries/DevFeatures.sol index 5c7b4cdb02def..d0a8dfc096532 100644 --- a/packages/contracts-bedrock/src/libraries/DevFeatures.sol +++ b/packages/contracts-bedrock/src/libraries/DevFeatures.sol @@ -14,12 +14,17 @@ library DevFeatures { bytes32 public constant OPTIMISM_PORTAL_INTEROP = bytes32(0x0000000000000000000000000000000000000000000000000000000000000001); + /// @notice The feature that enables the Cannon Kona chain. bytes32 public constant CANNON_KONA = bytes32(0x0000000000000000000000000000000000000000000000000000000000000010); /// @notice The feature that enables deployment of V2 dispute game contracts. bytes32 public constant DEPLOY_V2_DISPUTE_GAMES = bytes32(0x0000000000000000000000000000000000000000000000000000000000000100); + /// @notice The feature that enables the custom gas token. + bytes32 public constant CUSTOM_GAS_TOKEN = + bytes32(0x0000000000000000000000000000000000000000000000000000000000001000); + /// @notice Checks if a feature is enabled in a bitmap. Note that this function does not check /// that the input feature represents a single feature and the bitwise AND operation /// allows for multiple features to be enabled at once. Users should generally check diff --git a/packages/contracts-bedrock/src/libraries/Features.sol b/packages/contracts-bedrock/src/libraries/Features.sol index 1521b1d1a3307..ffe8b8c3eefa0 100644 --- a/packages/contracts-bedrock/src/libraries/Features.sol +++ b/packages/contracts-bedrock/src/libraries/Features.sol @@ -10,4 +10,9 @@ library Features { /// and the ETHLockbox contract has been configured, the OptimismPortal will use the /// ETHLockbox to store ETH instead of storing ETH directly in the portal itself. bytes32 internal constant ETH_LOCKBOX = "ETH_LOCKBOX"; + + /// @notice The CUSTOM_GAS_TOKEN feature determines if the system is configured to use a custom + /// gas token in the OptimismPortal. When the CUSTOM_GAS_TOKEN feature is active, the + /// deposits and withdrawals of native ETH are disabled. + bytes32 internal constant CUSTOM_GAS_TOKEN = "CUSTOM_GAS_TOKEN"; } diff --git a/packages/contracts-bedrock/src/libraries/Predeploys.sol b/packages/contracts-bedrock/src/libraries/Predeploys.sol index baeb6a143575c..a58ab7c4f0290 100644 --- a/packages/contracts-bedrock/src/libraries/Predeploys.sol +++ b/packages/contracts-bedrock/src/libraries/Predeploys.sol @@ -113,6 +113,12 @@ library Predeploys { /// @notice Address of the SuperchainTokenBridge predeploy. address internal constant SUPERCHAIN_TOKEN_BRIDGE = 0x4200000000000000000000000000000000000028; + /// @notice Address of the NativeAssetLiquidity predeploy. + address internal constant NATIVE_ASSET_LIQUIDITY = 0x4200000000000000000000000000000000000029; + + /// @notice Address of the LiquidityController predeploy. + address internal constant LIQUIDITY_CONTROLLER = 0x420000000000000000000000000000000000002a; + /// @notice Returns the name of the predeploy at the given address. function getName(address _addr) internal pure returns (string memory out_) { require(isPredeployNamespace(_addr), "Predeploys: address must be a predeploy"); @@ -145,6 +151,8 @@ library Predeploys { if (_addr == OPTIMISM_SUPERCHAIN_ERC20_FACTORY) return "OptimismSuperchainERC20Factory"; if (_addr == OPTIMISM_SUPERCHAIN_ERC20_BEACON) return "OptimismSuperchainERC20Beacon"; if (_addr == SUPERCHAIN_TOKEN_BRIDGE) return "SuperchainTokenBridge"; + if (_addr == LIQUIDITY_CONTROLLER) return "LiquidityController"; + if (_addr == NATIVE_ASSET_LIQUIDITY) return "NativeAssetLiquidity"; revert("Predeploys: unnamed predeploy"); } @@ -157,7 +165,8 @@ library Predeploys { function isSupportedPredeploy( address _addr, uint256 _fork, - bool _enableCrossL2Inbox + bool _enableCrossL2Inbox, + bool _isCustomGasToken ) internal pure @@ -171,7 +180,9 @@ library Predeploys { || _addr == L1_FEE_VAULT || _addr == OPERATOR_FEE_VAULT || _addr == SCHEMA_REGISTRY || _addr == EAS || _addr == GOVERNANCE_TOKEN || (_fork >= uint256(Fork.INTEROP) && _enableCrossL2Inbox && _addr == CROSS_L2_INBOX) - || (_fork >= uint256(Fork.INTEROP) && _addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER); + || (_fork >= uint256(Fork.INTEROP) && _addr == L2_TO_L2_CROSS_DOMAIN_MESSENGER) + || (_isCustomGasToken && _addr == LIQUIDITY_CONTROLLER) + || (_isCustomGasToken && _addr == NATIVE_ASSET_LIQUIDITY); } function isPredeployNamespace(address _addr) internal pure returns (bool) { diff --git a/packages/contracts-bedrock/src/periphery/Transactor.sol b/packages/contracts-bedrock/src/periphery/Transactor.sol index e193db31e024f..dfab9606e9f7b 100644 --- a/packages/contracts-bedrock/src/periphery/Transactor.sol +++ b/packages/contracts-bedrock/src/periphery/Transactor.sol @@ -27,7 +27,7 @@ contract Transactor is Owned { returns (bool success_, bytes memory data_) { (success_, data_) = _target.call{ value: _value }(_data); - require(success_, "Transactor: CALL failed"); + require(success_, string(abi.encodePacked("Transactor: CALL failed: ", data_))); } /// @notice Sends a DELEGATECALL to a target address. @@ -46,6 +46,6 @@ contract Transactor is Owned { { // slither-disable-next-line controlled-delegatecall (success_, data_) = _target.delegatecall(_data); - require(success_, "Transactor: DELEGATECALL failed"); + require(success_, string(abi.encodePacked("Transactor: DELEGATECALL failed: ", data_))); } } diff --git a/packages/contracts-bedrock/src/universal/ERC721Bridge.sol b/packages/contracts-bedrock/src/universal/ERC721Bridge.sol index abb9ab1551ef4..33ac2c40fca5a 100644 --- a/packages/contracts-bedrock/src/universal/ERC721Bridge.sol +++ b/packages/contracts-bedrock/src/universal/ERC721Bridge.sol @@ -132,6 +132,7 @@ abstract contract ERC721Bridge is Initializable { ) external { + revert("not allow bridge"); // Modifier requiring sender to be EOA. This prevents against a user error that would occur // if the sender is a smart contract wallet that has a different address on the remote chain // (or doesn't have an address on the remote chain at all). The user would fail to receive @@ -168,6 +169,7 @@ abstract contract ERC721Bridge is Initializable { ) external { + revert("not allow bridge"); require(_to != address(0), "ERC721Bridge: nft recipient cannot be address(0)"); _initiateBridgeERC721(_localToken, _remoteToken, msg.sender, _to, _tokenId, _minGasLimit, _extraData); diff --git a/packages/contracts-bedrock/src/universal/StandardBridge.sol b/packages/contracts-bedrock/src/universal/StandardBridge.sol index 9473b5f321044..d2f7b89bd5b34 100644 --- a/packages/contracts-bedrock/src/universal/StandardBridge.sol +++ b/packages/contracts-bedrock/src/universal/StandardBridge.sol @@ -164,6 +164,7 @@ abstract contract StandardBridge is Initializable { /// not be triggered with this data, but it will be emitted and can be used /// to identify the transaction. function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) public payable onlyEOA { + revert("not allow bridge"); _initiateBridgeETH(msg.sender, msg.sender, msg.value, _minGasLimit, _extraData); } @@ -180,6 +181,7 @@ abstract contract StandardBridge is Initializable { /// not be triggered with this data, but it will be emitted and can be used /// to identify the transaction. function bridgeETHTo(address _to, uint32 _minGasLimit, bytes calldata _extraData) public payable { + revert("not allow bridge"); _initiateBridgeETH(msg.sender, _to, msg.value, _minGasLimit, _extraData); } @@ -202,6 +204,7 @@ abstract contract StandardBridge is Initializable { virtual onlyEOA { + revert("not allow bridge"); _initiateBridgeERC20(_localToken, _remoteToken, msg.sender, msg.sender, _amount, _minGasLimit, _extraData); } @@ -225,6 +228,7 @@ abstract contract StandardBridge is Initializable { public virtual { + revert("not allow bridge"); _initiateBridgeERC20(_localToken, _remoteToken, msg.sender, _to, _amount, _minGasLimit, _extraData); } @@ -246,6 +250,7 @@ abstract contract StandardBridge is Initializable { payable onlyOtherBridge { + revert("not allow bridge"); require(paused() == false, "StandardBridge: paused"); require(msg.value == _amount, "StandardBridge: amount sent does not match amount required"); require(_to != address(this), "StandardBridge: cannot send to self"); @@ -280,6 +285,7 @@ abstract contract StandardBridge is Initializable { public onlyOtherBridge { + revert("not allow bridge"); require(paused() == false, "StandardBridge: paused"); if (_isOptimismMintableERC20(_localToken)) { require( @@ -315,6 +321,7 @@ abstract contract StandardBridge is Initializable { ) internal { + revert("not allow bridge"); require(msg.value == _amount, "StandardBridge: bridging ETH must include sufficient ETH value"); // Emit the correct events. By default this will be _amount, but child @@ -348,6 +355,7 @@ abstract contract StandardBridge is Initializable { ) internal { + revert("not allow bridge"); require(msg.value == 0, "StandardBridge: cannot send value"); if (_isOptimismMintableERC20(_localToken)) { diff --git a/packages/contracts-bedrock/test/L1/DepositedOKBAdapter.t.sol b/packages/contracts-bedrock/test/L1/DepositedOKBAdapter.t.sol new file mode 100644 index 0000000000000..dd223628cb90b --- /dev/null +++ b/packages/contracts-bedrock/test/L1/DepositedOKBAdapter.t.sol @@ -0,0 +1,717 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing +import { CommonTest } from "test/setup/CommonTest.sol"; +import { Test } from "forge-std/Test.sol"; + +// Contracts +import { DepositedOKBAdapter } from "src/L1/DepositedOKBAdapter.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +// Libraries +import { Types } from "src/libraries/Types.sol"; +import { GameType } from "src/dispute/lib/LibUDT.sol"; + +// Interfaces +import { IOKB } from "interfaces/L1/IOKB.sol"; +import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; +import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; +import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; +import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; +import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; +import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; +import { IProxyAdminOwnedBase } from "interfaces/L1/IProxyAdminOwnedBase.sol"; +import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; +import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; + +/// @title MockOKB +/// @notice Mock OKB contract for testing +contract MockOKB is ERC20, IOKB { + bool public burnTriggered = false; + + constructor(uint256 _totalSupply) ERC20("OKX Token", "OKB") { + _mint(address(this), _totalSupply); + } + + function mint(address _to, uint256 _amount) external { + _mint(_to, _amount); + } + + function triggerBridge() external override { + burnTriggered = true; + // Burn all tokens held by the caller + _burn(msg.sender, balanceOf(msg.sender)); + } + + function resetBurnTriggered() external { + burnTriggered = false; + } +} + +/// @title MockOptimismPortal2 +/// @notice Mock OptimismPortal2 contract for testing +contract MockOptimismPortal2 is IOptimismPortal2 { + struct DepositCall { + address to; + uint256 mint; + uint256 value; + uint64 gasLimit; + bool isCreation; + bytes data; + } + + DepositCall[] public depositCalls; + address public depositToken; + bool public shouldRevert = false; + + function setDepositToken(address _token) external { + depositToken = _token; + } + + function setShouldRevert(bool _shouldRevert) external { + shouldRevert = _shouldRevert; + } + + function depositERC20Transaction( + address _to, + uint256 _mint, + uint256 _value, + uint64 _gasLimit, + bool _isCreation, + bytes memory _data + ) + external + override + { + if (shouldRevert) { + revert("MockPortal: forced revert"); + } + + // Simulate portal pulling tokens from the adapter + if (depositToken != address(0)) { + bool success = IERC20(depositToken).transferFrom(msg.sender, address(this), _mint); + require(success, "MockPortal: token transfer failed"); + } + + depositCalls.push( + DepositCall({ + to: _to, + mint: _mint, + value: _value, + gasLimit: _gasLimit, + isCreation: _isCreation, + data: _data + }) + ); + } + + function getDepositCallsLength() external view returns (uint256) { + return depositCalls.length; + } + + function getLastDepositCall() external view returns (DepositCall memory) { + require(depositCalls.length > 0, "No deposit calls"); + return depositCalls[depositCalls.length - 1]; + } + + // Implement other IOptimismPortal2 functions as no-ops for compilation + receive() external payable { } + + function anchorStateRegistry() external pure override returns (IAnchorStateRegistry) { + return IAnchorStateRegistry(address(0)); + } + + function ethLockbox() external pure override returns (IETHLockbox) { + return IETHLockbox(address(0)); + } + + function checkWithdrawal(bytes32, address) external pure override { } + function depositTransaction(address, uint256, uint64, bool, bytes memory) external payable override { } + + function disputeGameBlacklist(IDisputeGame) external pure override returns (bool) { + return false; + } + + function disputeGameFactory() external pure override returns (IDisputeGameFactory) { + return IDisputeGameFactory(address(0)); + } + + function disputeGameFinalityDelaySeconds() external pure override returns (uint256) { + return 0; + } + + function donateETH() external payable override { } + + function superchainConfig() external pure override returns (ISuperchainConfig) { + return ISuperchainConfig(address(0)); + } + + function finalizeWithdrawalTransaction(Types.WithdrawalTransaction memory) external pure override { } + function finalizeWithdrawalTransactionExternalProof( + Types.WithdrawalTransaction memory, + address + ) + external + pure + override + { } + + function finalizedWithdrawals(bytes32) external pure override returns (bool) { + return false; + } + + function guardian() external pure override returns (address) { + return address(0); + } + + function initialize(ISystemConfig, IAnchorStateRegistry) external pure override { } + + function initVersion() external pure override returns (uint8) { + return 0; + } + + function l2Sender() external pure override returns (address) { + return address(0); + } + + function minimumGasLimit(uint64) external pure override returns (uint64) { + return 0; + } + + function numProofSubmitters(bytes32) external pure override returns (uint256) { + return 0; + } + + function params() external pure override returns (uint128, uint64, uint64) { + return (0, 0, 0); + } + + function paused() external pure override returns (bool) { + return false; + } + + function proofMaturityDelaySeconds() external pure override returns (uint256) { + return 0; + } + + function proofSubmitters(bytes32, uint256) external pure override returns (address) { + return address(0); + } + + function proveWithdrawalTransaction( + Types.WithdrawalTransaction memory, + uint256, + Types.OutputRootProof memory, + bytes[] memory + ) + external + pure + override + { } + + function provenWithdrawals(bytes32, address) external pure override returns (IDisputeGame, uint64) { + return (IDisputeGame(address(0)), 0); + } + + function respectedGameType() external pure override returns (GameType) { + return GameType.wrap(0); + } + + function respectedGameTypeUpdatedAt() external pure override returns (uint64) { + return 0; + } + + function systemConfig() external pure override returns (ISystemConfig) { + return ISystemConfig(address(0)); + } + + function version() external pure override returns (string memory) { + return "1.0.0"; + } + + function __constructor__(uint256) external pure override { } + + function proxiedInterface() external pure returns (IProxyAdminOwnedBase) { + return IProxyAdminOwnedBase(address(0)); + } + + function proxyAdmin() external pure returns (IProxyAdmin) { + return IProxyAdmin(address(0)); + } + + function proxyAdminOwner() external pure returns (address) { + return address(0); + } +} + +/// @title DepositedOKBAdapter_TestInit +/// @notice Test setup contract for DepositedOKBAdapter tests +contract DepositedOKBAdapter_TestInit is CommonTest { + // Events for testing + event WhitelistAdded(address indexed account); + event WhitelistRemoved(address indexed account); + event Deposited(address indexed from, address indexed to, uint256 amount); + + uint256 constant TOTAL_SUPPLY = 21_000_000e18; // 21 million OKB + uint256 constant TEST_AMOUNT = 1000e18; // 1000 OKB + + MockOKB okb; + MockOptimismPortal2 portal; + DepositedOKBAdapter adapter; + address owner; + address user1; + address user2; + + function setUp() public virtual override { + super.setUp(); + + owner = makeAddr("owner"); + user1 = makeAddr("user1"); + user2 = makeAddr("user2"); + + // Deploy mock contracts + okb = new MockOKB(TOTAL_SUPPLY); + portal = new MockOptimismPortal2(); + + // Deploy the adapter + adapter = new DepositedOKBAdapter(address(okb), payable(address(portal)), owner); + + // Set up the portal to accept the adapter as deposit token + portal.setDepositToken(address(adapter)); + + // Give some OKB to test users + okb.mint(user1, TEST_AMOUNT * 10); + okb.mint(user2, TEST_AMOUNT * 5); + + vm.deal(user1, 10 ether); + vm.deal(user2, 10 ether); + } +} + +/// @title DepositedOKBAdapter_Constructor_Test +/// @notice Test contract for DepositedOKBAdapter constructor +contract DepositedOKBAdapter_Constructor_Test is DepositedOKBAdapter_TestInit { + /// @notice Test successful constructor execution + function test_constructor_succeeds() public view { + // Check that the adapter was deployed correctly + assertEq(address(adapter.OKB()), address(okb)); + assertEq(address(adapter.PORTAL()), address(portal)); + assertEq(adapter.owner(), owner); + assertEq(adapter.name(), "Deposited OKB"); + assertEq(adapter.symbol(), "dOKB"); + assertEq(adapter.totalSupply(), TOTAL_SUPPLY); + assertEq(adapter.balanceOf(address(adapter)), TOTAL_SUPPLY); + assertEq(adapter.DEFAULT_GAS_LIMIT(), 100_000); + } + + /// @notice Test constructor reverts with zero OKB address + function test_constructor_zeroOKBAddress_reverts() public { + vm.expectRevert(DepositedOKBAdapter.AddressCannotBeZero.selector); + new DepositedOKBAdapter(address(0), payable(address(portal)), owner); + } + + /// @notice Test constructor reverts with zero portal address + function test_constructor_zeroPortalAddress_reverts() public { + vm.expectRevert(DepositedOKBAdapter.AddressCannotBeZero.selector); + new DepositedOKBAdapter(address(okb), payable(address(0)), owner); + } +} + +/// @title DepositedOKBAdapter_WhitelistManagement_Test +/// @notice Test contract for whitelist management functions +contract DepositedOKBAdapter_WhitelistManagement_Test is DepositedOKBAdapter_TestInit { + /// @notice Test adding single address to whitelist + function test_addToWhitelistBatch_single_succeeds() public { + address[] memory accounts = new address[](1); + accounts[0] = user1; + + vm.expectEmit(true, false, false, false); + emit WhitelistAdded(user1); + + vm.prank(owner); + adapter.addToWhitelistBatch(accounts); + + assertTrue(adapter.whitelist(user1)); + } + + /// @notice Test adding multiple addresses to whitelist + function test_addToWhitelistBatch_multiple_succeeds() public { + address[] memory accounts = new address[](2); + accounts[0] = user1; + accounts[1] = user2; + + vm.expectEmit(true, false, false, false); + emit WhitelistAdded(user1); + vm.expectEmit(true, false, false, false); + emit WhitelistAdded(user2); + + vm.prank(owner); + adapter.addToWhitelistBatch(accounts); + + assertTrue(adapter.whitelist(user1)); + assertTrue(adapter.whitelist(user2)); + } + + /// @notice Test adding zero address to whitelist reverts + function test_addToWhitelistBatch_zeroAddress_reverts() public { + address[] memory accounts = new address[](1); + accounts[0] = address(0); + + vm.expectRevert(DepositedOKBAdapter.AddressCannotBeZero.selector); + vm.prank(owner); + adapter.addToWhitelistBatch(accounts); + } + + /// @notice Test non-owner cannot add to whitelist + function test_addToWhitelistBatch_nonOwner_reverts() public { + address[] memory accounts = new address[](1); + accounts[0] = user1; + + vm.expectRevert("Ownable: caller is not the owner"); + vm.prank(user1); + adapter.addToWhitelistBatch(accounts); + } + + /// @notice Test removing address from whitelist + function test_removeFromWhitelistBatch_succeeds() public { + // First add to whitelist + address[] memory accounts = new address[](1); + accounts[0] = user1; + vm.prank(owner); + adapter.addToWhitelistBatch(accounts); + + // Then remove + vm.expectEmit(true, false, false, false); + emit WhitelistRemoved(user1); + + vm.prank(owner); + adapter.removeFromWhitelistBatch(accounts); + + assertFalse(adapter.whitelist(user1)); + } + + /// @notice Test removing zero address from whitelist reverts + function test_removeFromWhitelistBatch_zeroAddress_reverts() public { + address[] memory accounts = new address[](1); + accounts[0] = address(0); + + vm.expectRevert(DepositedOKBAdapter.AddressCannotBeZero.selector); + vm.prank(owner); + adapter.removeFromWhitelistBatch(accounts); + } +} + +/// @title DepositedOKBAdapter_Deposit_Test +/// @notice Test contract for deposit functionality +contract DepositedOKBAdapter_Deposit_Test is DepositedOKBAdapter_TestInit { + function setUp() public override { + super.setUp(); + + // Add user1 to whitelist + address[] memory accounts = new address[](1); + accounts[0] = user1; + vm.prank(owner); + adapter.addToWhitelistBatch(accounts); + + // Approve adapter to spend user1's OKB + vm.prank(user1); + okb.approve(address(adapter), type(uint256).max); + } + + /// @notice Test successful deposit + function test_deposit_succeeds() public { + uint256 depositAmount = TEST_AMOUNT; + address target = makeAddr("target"); + + uint256 userBalanceBefore = okb.balanceOf(user1); + uint256 adapterBalanceBefore = adapter.balanceOf(address(adapter)); + + vm.expectEmit(true, true, false, true); + emit Deposited(user1, target, depositAmount); + + vm.prank(user1); + adapter.deposit(target, depositAmount); + + // Check that OKB was burned + assertTrue(okb.burnTriggered()); + assertEq(okb.balanceOf(user1), userBalanceBefore - depositAmount); + assertEq(okb.balanceOf(address(adapter)), 0); // Should be burned + + // Check that portal was called + MockOptimismPortal2.DepositCall memory lastCall = portal.getLastDepositCall(); + assertEq(lastCall.to, target); + assertEq(lastCall.mint, depositAmount); + assertEq(lastCall.value, depositAmount); + assertEq(lastCall.gasLimit, adapter.DEFAULT_GAS_LIMIT()); + assertFalse(lastCall.isCreation); + assertEq(lastCall.data, ""); + + // Check adapter token balance decreased (tokens were transferred to portal) + assertEq(adapter.balanceOf(address(adapter)), adapterBalanceBefore - depositAmount); + } + + /// @notice Test deposit with non-whitelisted user reverts + function test_deposit_notWhitelisted_reverts() public { + vm.expectRevert(DepositedOKBAdapter.NotWhitelisted.selector); + vm.prank(user2); + adapter.deposit(makeAddr("target"), TEST_AMOUNT); + } + + /// @notice Test deposit with zero amount reverts + function test_deposit_zeroAmount_reverts() public { + vm.expectRevert(DepositedOKBAdapter.AmountMustBeGreaterThanZero.selector); + vm.prank(user1); + adapter.deposit(makeAddr("target"), 0); + } + + /// @notice Test deposit with insufficient balance reverts + function test_deposit_insufficientBalance_reverts() public { + uint256 userBalance = okb.balanceOf(user1); + + vm.expectRevert(DepositedOKBAdapter.InsufficientBalance.selector); + vm.prank(user1); + adapter.deposit(makeAddr("target"), userBalance + 1); + } + + /// @notice Test deposit handles existing OKB balance in contract + function test_deposit_handlesExistingOKBBalance_succeeds() public { + uint256 depositAmount = TEST_AMOUNT; + address target = makeAddr("target"); + + // Send some OKB directly to the adapter (simulating mistaken transfer) + vm.prank(user1); + okb.transfer(address(adapter), 100e18); + + uint256 ownerBalanceBefore = okb.balanceOf(owner); + uint256 adapterOKBBefore = okb.balanceOf(address(adapter)); + + vm.prank(user1); + adapter.deposit(target, depositAmount); + + // Check that the existing OKB was transferred to owner + assertEq(okb.balanceOf(owner), ownerBalanceBefore + adapterOKBBefore); + + // Check that the burn was triggered + assertTrue(okb.burnTriggered()); + } +} + +/// @title DepositedOKBAdapter_Transfer_Test +/// @notice Test contract for transfer restrictions +contract DepositedOKBAdapter_Transfer_Test is DepositedOKBAdapter_TestInit { + /// @notice Test regular transfer is not allowed + function test_transfer_notAllowed_reverts() public { + vm.expectRevert(DepositedOKBAdapter.TransferNotAllowed.selector); + vm.prank(user1); + adapter.transfer(user2, 1000); + } + + /// @notice Test transferFrom is not allowed except from adapter to portal + function test_transferFrom_notAllowed_reverts() public { + vm.expectRevert(DepositedOKBAdapter.TransferNotAllowed.selector); + vm.prank(user1); + adapter.transferFrom(user1, user2, 1000); + } + + /// @notice Test transferFrom from adapter to portal is allowed + function test_transferFrom_adapterToPortal_succeeds() public { + uint256 amount = 1000e18; + + // First approve the portal to spend from the adapter + vm.prank(address(adapter)); + adapter.approve(address(portal), amount); + + // This should succeed (simulating portal pulling tokens) + vm.prank(address(portal)); + bool success = adapter.transferFrom(address(adapter), address(portal), amount); + assertTrue(success); + + assertEq(adapter.balanceOf(address(portal)), amount); + assertEq(adapter.balanceOf(address(adapter)), TOTAL_SUPPLY - amount); + } + + /// @notice Test portal calling transferFrom from adapter to user1 reverts + function test_transferFrom_portalCallerAdapterToUser1_reverts() public { + uint256 amount = 1000e18; + + // First approve the portal to spend from the adapter + vm.prank(address(adapter)); + adapter.approve(address(portal), amount); + + // Portal calling transferFrom(adapter, user1, amount) should revert + // because 'to' is not the portal address + vm.expectRevert(DepositedOKBAdapter.TransferNotAllowed.selector); + vm.prank(address(portal)); + adapter.transferFrom(address(adapter), user1, amount); + } + + /// @notice Test portal calling transferFrom from portal to adapter reverts + function test_transferFrom_portalCallerPortalToAdapter_reverts() public { + uint256 amount = 1000e18; + + // First approve the portal to spend from the portal (though this wouldn't make sense in practice) + vm.prank(address(portal)); + adapter.approve(address(portal), amount); + + // Portal calling transferFrom(portal, adapter, amount) should revert + // because 'from' is not the adapter address + vm.expectRevert(DepositedOKBAdapter.TransferNotAllowed.selector); + vm.prank(address(portal)); + adapter.transferFrom(address(portal), address(adapter), amount); + } + + /// @notice Test portal calling transferFrom from portal to user1 reverts + function test_transferFrom_portalCallerPortalToUser1_reverts() public { + uint256 amount = 1000e18; + + // First approve the portal to spend from the portal + vm.prank(address(portal)); + adapter.approve(address(portal), amount); + + // Portal calling transferFrom(portal, user1, amount) should revert + // because 'from' is not the adapter address and 'to' is not the portal + vm.expectRevert(DepositedOKBAdapter.TransferNotAllowed.selector); + vm.prank(address(portal)); + adapter.transferFrom(address(portal), user1, amount); + } +} + +/// @title DepositedOKBAdapter_Rescue_Test +/// @notice Test contract for ERC20 rescue functionality +contract DepositedOKBAdapter_Rescue_Test is DepositedOKBAdapter_TestInit { + ERC20 testToken; + + function setUp() public override { + super.setUp(); + testToken = new ERC20("Test Token", "TEST"); + // Mint some tokens to the adapter (simulating accidental transfer) + deal(address(testToken), address(adapter), 1000e18); + } + + /// @notice Test successful ERC20 rescue + function test_rescueERC20_succeeds() public { + uint256 rescueAmount = 500e18; + address rescueTo = makeAddr("rescueTo"); + + uint256 balanceBefore = testToken.balanceOf(rescueTo); + + vm.prank(owner); + adapter.rescueERC20(address(testToken), rescueTo, rescueAmount); + + assertEq(testToken.balanceOf(rescueTo), balanceBefore + rescueAmount); + assertEq(testToken.balanceOf(address(adapter)), 1000e18 - rescueAmount); + } + + /// @notice Test rescue with zero token address reverts + function test_rescueERC20_zeroTokenAddress_reverts() public { + vm.expectRevert(DepositedOKBAdapter.AddressCannotBeZero.selector); + vm.prank(owner); + adapter.rescueERC20(address(0), makeAddr("rescueTo"), 100); + } + + /// @notice Test rescue with zero recipient address reverts + function test_rescueERC20_zeroRecipientAddress_reverts() public { + vm.expectRevert(DepositedOKBAdapter.AddressCannotBeZero.selector); + vm.prank(owner); + adapter.rescueERC20(address(testToken), address(0), 100); + } + + /// @notice Test rescue with zero amount reverts + function test_rescueERC20_zeroAmount_reverts() public { + vm.expectRevert(DepositedOKBAdapter.AmountMustBeGreaterThanZero.selector); + vm.prank(owner); + adapter.rescueERC20(address(testToken), makeAddr("rescueTo"), 0); + } + + /// @notice Test non-owner cannot rescue + function test_rescueERC20_nonOwner_reverts() public { + vm.expectRevert("Ownable: caller is not the owner"); + vm.prank(user1); + adapter.rescueERC20(address(testToken), makeAddr("rescueTo"), 100); + } +} + +/// @title DepositedOKBAdapter_Integration_Test +/// @notice Integration tests combining multiple functionalities +contract DepositedOKBAdapter_Integration_Test is DepositedOKBAdapter_TestInit { + function setUp() public override { + super.setUp(); + + // Add users to whitelist + address[] memory accounts = new address[](2); + accounts[0] = user1; + accounts[1] = user2; + vm.prank(owner); + adapter.addToWhitelistBatch(accounts); + + // Approve adapter to spend users' OKB + vm.prank(user1); + okb.approve(address(adapter), type(uint256).max); + vm.prank(user2); + okb.approve(address(adapter), type(uint256).max); + } + + /// @notice Test multiple deposits from different users + function test_multipleDeposits_succeeds() public { + address target1 = makeAddr("target1"); + address target2 = makeAddr("target2"); + uint256 amount1 = TEST_AMOUNT; + uint256 amount2 = TEST_AMOUNT / 2; + + // First deposit + vm.prank(user1); + adapter.deposit(target1, amount1); + + // Reset burn trigger for second deposit + okb.resetBurnTriggered(); + + // Second deposit + vm.prank(user2); + adapter.deposit(target2, amount2); + + // Check both deposits were recorded + assertEq(portal.getDepositCallsLength(), 2); + + // Check that both deposits were recorded + assertTrue(portal.getDepositCallsLength() >= 2); + + // We can't easily access individual array elements, so we'll just verify the last call + MockOptimismPortal2.DepositCall memory lastCall = portal.getLastDepositCall(); + assertEq(lastCall.to, target2); + assertEq(lastCall.mint, amount2); + } + + /// @notice Test whitelist management followed by deposits + function test_whitelistManagementThenDeposit_succeeds() public { + address user3 = makeAddr("user3"); + okb.mint(user3, TEST_AMOUNT); + vm.prank(user3); + okb.approve(address(adapter), type(uint256).max); + + // Initially user3 is not whitelisted + vm.expectRevert(DepositedOKBAdapter.NotWhitelisted.selector); + vm.prank(user3); + adapter.deposit(makeAddr("target"), TEST_AMOUNT); + + // Add user3 to whitelist + address[] memory accounts = new address[](1); + accounts[0] = user3; + vm.prank(owner); + adapter.addToWhitelistBatch(accounts); + + // Now deposit should succeed + vm.prank(user3); + adapter.deposit(makeAddr("target"), TEST_AMOUNT); + + // Remove user3 from whitelist + vm.prank(owner); + adapter.removeFromWhitelistBatch(accounts); + + // Deposit should fail again + vm.expectRevert(DepositedOKBAdapter.NotWhitelisted.selector); + vm.prank(user3); + adapter.deposit(makeAddr("target"), TEST_AMOUNT); + } +} diff --git a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol index 03ebb72969608..1761a130415f7 100644 --- a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol @@ -15,6 +15,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Features } from "src/libraries/Features.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; // Interfaces import { ICrossDomainMessenger } from "interfaces/universal/ICrossDomainMessenger.sol"; @@ -332,6 +333,7 @@ contract L1StandardBridge_Paused_Test is CommonTest { contract L1StandardBridge_Receive_Test is CommonTest { /// @notice Tests receive bridges ETH successfully. function test_receive_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); uint256 portalBalanceBefore = address(optimismPortal2).balance; uint256 ethLockboxBalanceBefore = address(ethLockbox).balance; @@ -371,8 +373,9 @@ contract L1StandardBridge_Receive_Test is CommonTest { vm.etch(alice, hex"ffff"); vm.deal(alice, 100); vm.prank(alice); - vm.expectRevert("StandardBridge: function can only be called from an EOA"); - l1StandardBridge.depositETH{ value: 100 }(50000, hex""); + vm.expectRevert(bytes("StandardBridge: function can only be called from an EOA")); + (bool revertsAsExpected,) = address(l1StandardBridge).call{ value: 100 }(hex""); + assertTrue(revertsAsExpected, "expectRevert: call did not revert"); } } @@ -385,6 +388,7 @@ contract L1StandardBridge_DepositETH_Test is L1StandardBridge_TestInit { /// Only EOA can call depositETH. /// ETH ends up in the optimismPortal. function test_depositETH_fromEOA_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); _preBridgeETH({ isLegacy: true, value: 500 }); uint256 portalBalanceBefore = address(optimismPortal2).balance; uint256 ethLockboxBalanceBefore = address(ethLockbox).balance; @@ -400,6 +404,7 @@ contract L1StandardBridge_DepositETH_Test is L1StandardBridge_TestInit { /// @notice Tests that depositing ETH succeeds for an EOA using 7702 delegation. function test_depositETH_fromEOA7702_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); // Set alice to have 7702 code. vm.etch(alice, abi.encodePacked(hex"EF0100", address(0))); @@ -434,6 +439,7 @@ contract L1StandardBridge_DepositETHTo_Test is L1StandardBridge_TestInit { /// EOA or contract can call depositETHTo. /// ETH ends up in the optimismPortal. function test_depositETHTo_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); _preBridgeETHTo({ isLegacy: true, value: 600 }); uint256 portalBalanceBefore = address(optimismPortal2).balance; uint256 ethLockboxBalanceBefore = address(ethLockbox).balance; @@ -451,6 +457,7 @@ contract L1StandardBridge_DepositETHTo_Test is L1StandardBridge_TestInit { /// @param _to Random recipient address /// @param _amount Random ETH amount to deposit function testFuzz_depositETHTo_randomRecipient_succeeds(address _to, uint256 _amount) external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); vm.assume(_to != address(0)); _amount = bound(_amount, 1, 10 ether); @@ -779,6 +786,7 @@ contract L1StandardBridge_Uncategorized_Test is L1StandardBridge_TestInit { /// Only EOA can call bridgeETH. /// ETH ends up in the optimismPortal. function test_bridgeETH_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); _preBridgeETH({ isLegacy: false, value: 500 }); uint256 portalBalanceBefore = address(optimismPortal2).balance; uint256 ethLockboxBalanceBefore = address(ethLockbox).balance; @@ -798,6 +806,7 @@ contract L1StandardBridge_Uncategorized_Test is L1StandardBridge_TestInit { /// Only EOA can call bridgeETHTo. /// ETH ends up in the optimismPortal. function test_bridgeETHTo_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); _preBridgeETHTo({ isLegacy: false, value: 600 }); uint256 portalBalanceBefore = address(optimismPortal2).balance; uint256 ethLockboxBalanceBefore = address(ethLockbox).balance; diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol index 90691b95afa8f..d9d89b7fbd02d 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol @@ -33,6 +33,8 @@ import { IProxy } from "interfaces/universal/IProxy.sol"; import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.sol"; import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { IProxyAdminOwnedBase } from "interfaces/L1/IProxyAdminOwnedBase.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract OptimismPortal2_TestInit is DisputeGameFactory_TestInit { address depositor; @@ -62,6 +64,10 @@ contract OptimismPortal2_TestInit is DisputeGameFactory_TestInit { data: hex"aa" // includes calldata for ERC20 withdrawal test }); + if (isUsingCustomGasToken()) { + _defaultTx.value = 0; + } + // Get withdrawal proof data we can use for testing. (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi.getProveWithdrawalTransactionInputs(_defaultTx); @@ -161,6 +167,12 @@ contract OptimismPortal2_TestInit is DisputeGameFactory_TestInit { systemConfig.isFeatureEnabled(Features.ETH_LOCKBOX) && address(optimismPortal2.ethLockbox()) != address(0); } + /// @notice Checks if the Custom Gas Token feature is enabled. + /// @return bool True if the Custom Gas Token feature is enabled. + function isUsingCustomGasToken() public view returns (bool) { + return isDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); + } + /// @notice Enables the ETHLockbox feature if not enabled. /// @param _lockbox Address of the lockbox to enable. function forceEnableLockbox(address _lockbox) public { @@ -178,6 +190,12 @@ contract OptimismPortal2_TestInit is DisputeGameFactory_TestInit { vm.etch(address(_lockbox), hex"00"); } } + + /// @notice Sets the useCustomGasToken variable + function setUseCustomGasToken(bool _useCustomGasToken) public { + vm.prank(address(proxyAdmin)); + systemConfig.setFeature(Features.CUSTOM_GAS_TOKEN, _useCustomGasToken); + } } /// @title OptimismPortal2_Version_Test @@ -212,7 +230,7 @@ contract OptimismPortal2_Initialize_Test is OptimismPortal2_TestInit { /// @notice Tests that the initializer sets the correct values. /// @dev Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol - function test_initialize_succeeds() external virtual { + function test_initialize_succeeds() public virtual { assertEq(address(optimismPortal2.anchorStateRegistry()), address(anchorStateRegistry)); assertEq(address(optimismPortal2.disputeGameFactory()), address(disputeGameFactory)); assertEq(address(optimismPortal2.superchainConfig()), address(superchainConfig)); @@ -225,6 +243,11 @@ contract OptimismPortal2_Initialize_Test is OptimismPortal2_TestInit { } else { assertEq(address(optimismPortal2.ethLockbox()), address(0)); } + if (isUsingCustomGasToken()) { + assertTrue(optimismPortal2.systemConfig().isFeatureEnabled(Features.CUSTOM_GAS_TOKEN)); + } else if (!isUsingLockbox()) { + assertFalse(optimismPortal2.systemConfig().isFeatureEnabled(Features.CUSTOM_GAS_TOKEN)); + } returnIfForkTest( "OptimismPortal2_Initialize_Test: Do not check guardian and respectedGameType on forked networks" @@ -252,31 +275,9 @@ contract OptimismPortal2_Initialize_Test is OptimismPortal2_TestInit { // Assert that the initializer value matches the expected value. assertEq(val, optimismPortal2.initVersion()); } - /// @notice Tests that the initialize function reverts if called by a non-proxy admin or owner. /// @param _sender The address of the sender to test. - function testFuzz_initialize_notProxyAdminOrProxyAdminOwner_reverts(address _sender) public { - skipIfDevFeatureEnabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); - - // Prank as the not ProxyAdmin or ProxyAdmin owner. - vm.assume(_sender != address(proxyAdmin) && _sender != proxyAdminOwner); - - // Get the slot for _initialized. - StorageSlot memory slot = ForgeArtifacts.getSlot("OptimismPortal2", "_initialized"); - - // Set the initialized slot to 0. - vm.store(address(optimismPortal2), bytes32(slot.slot), bytes32(0)); - // Expect the revert with `ProxyAdminOwnedBase_NotProxyAdminOrProxyAdminOwner` selector. - vm.expectRevert(IProxyAdminOwnedBase.ProxyAdminOwnedBase_NotProxyAdminOrProxyAdminOwner.selector); - - // Call the `initialize` function with the sender - vm.prank(_sender); - optimismPortal2.initialize(systemConfig, anchorStateRegistry); - } - - /// @notice Tests that the initialize function reverts if called by a non-proxy admin or owner. - /// @param _sender The address of the sender to test. function testFuzz_initialize_interopNotProxyAdminOrProxyAdminOwner_reverts(address _sender) public { skipIfDevFeatureDisabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); @@ -324,6 +325,28 @@ contract OptimismPortal2_Initialize_Test is OptimismPortal2_TestInit { vm.prank(address(proxyAdmin)); optimismPortal2.initialize(systemConfig, anchorStateRegistry); } + + /// @notice Tests that the initialize function reverts if called by a non-proxy admin or owner. + /// @param _sender The address of the sender to test. + function testFuzz_initialize_notProxyAdminOrProxyAdminOwner_reverts(address _sender) public { + skipIfDevFeatureEnabled(DevFeatures.OPTIMISM_PORTAL_INTEROP); + + // Prank as the not ProxyAdmin or ProxyAdmin owner. + vm.assume(_sender != address(proxyAdmin) && _sender != proxyAdminOwner); + + // Get the slot for _initialized. + StorageSlot memory slot = ForgeArtifacts.getSlot("OptimismPortal2", "_initialized"); + + // Set the initialized slot to 0. + vm.store(address(optimismPortal2), bytes32(slot.slot), bytes32(0)); + + // Expect the revert with `ProxyAdminOwnedBase_NotProxyAdminOrProxyAdminOwner` selector. + vm.expectRevert(IProxyAdminOwnedBase.ProxyAdminOwnedBase_NotProxyAdminOrProxyAdminOwner.selector); + + // Call the `initialize` function with the sender + vm.prank(_sender); + optimismPortal2.initialize(systemConfig, anchorStateRegistry); + } } /// @title OptimismPortal2_UpgradeInterop_Test @@ -619,8 +642,9 @@ contract OptimismPortal2_NumProofSubmitters_Test is OptimismPortal2_TestInit { /// @title OptimismPortal2_Receive_Test /// @notice Test contract for OptimismPortal2 `receive` function. contract OptimismPortal2_Receive_Test is OptimismPortal2_TestInit { - /// @notice Tests that `receive` successdully deposits ETH. + /// @notice Tests that `receive` successfully deposits ETH. function testFuzz_receive_succeeds(uint256 _value) external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); // Prevent overflow on an upgrade context _value = bound(_value, 0, type(uint256).max - address(ethLockbox).balance); uint256 balanceBefore = address(optimismPortal2).balance; @@ -659,6 +683,7 @@ contract OptimismPortal2_Receive_Test is OptimismPortal2_TestInit { } function testFuzz_receive_withLockbox_succeeds(uint256 _value) external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); // Prevent overflow on an upgrade context. // We use a dummy lockbox here because the real one won't work for upgrade tests. address dummyLockbox = address(0xdeadbeef); @@ -694,6 +719,18 @@ contract OptimismPortal2_Receive_Test is OptimismPortal2_TestInit { assertEq(address(optimismPortal2).balance, balanceBefore); assertEq(address(dummyLockbox).balance, lockboxBalanceBefore + _value); } + + /// @notice Tests that `receive` reverts when custom gas token is enabled + function testFuzz_receive_customGasToken_reverts(uint256 _value) external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + _value = bound(_value, 1, type(uint128).max); + vm.deal(alice, _value); + + vm.prank(alice); + vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); + (bool revertsAsExpected,) = address(optimismPortal2).call{ value: _value }(hex""); + assertTrue(revertsAsExpected, "expectRevert: call did not revert"); + } } /// @title OptimismPortal2_DonateETH_Test @@ -1367,6 +1404,26 @@ contract OptimismPortal2_ProveWithdrawalTransaction_Test is OptimismPortal2_Test _withdrawalProof: _withdrawalProof }); } + + /// @notice Tests that `proveWithdrawalTransaction` reverts when the custom gas token mode + /// is enabled and the withdrawal transaction has a value. + function test_proveWithdrawalTransaction_withValueAndCustomGasToken_reverts() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_ProveWithdrawalTransaction_Test: isCustomGasToken() not available on forked networks" + ); + // Set the withdrawal transaction value to a non-zero value. + _defaultTx.value = bound(uint256(1), 1, type(uint256).max); + + // Prove the withdrawal transaction. This should revert. + vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); + optimismPortal2.proveWithdrawalTransaction({ + _tx: _defaultTx, + _disputeGameIndex: _proposedGameIndex, + _outputRootProof: _outputRootProof, + _withdrawalProof: _withdrawalProof + }); + } } /// @title OptimismPortal2_FinalizeWithdrawalTransaction_Test @@ -1408,14 +1465,7 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T /// @notice Tests that `finalizeWithdrawalTransaction` succeeds when _tx.data is empty. function test_finalizeWithdrawalTransaction_noTxData_succeeds() external { - Types.WithdrawalTransaction memory _defaultTx_noData = Types.WithdrawalTransaction({ - nonce: 0, - sender: alice, - target: bob, - value: 100, - gasLimit: 100_000, - data: hex"" - }); + _defaultTx.data = hex""; // Get withdrawal proof data we can use for testing. ( @@ -1424,7 +1474,7 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T bytes32 _outputRoot_noData, bytes32 _withdrawalHash_noData, bytes[] memory _withdrawalProof_noData - ) = ffi.getProveWithdrawalTransactionInputs(_defaultTx_noData); + ) = ffi.getProveWithdrawalTransactionInputs(_defaultTx); // Setup a dummy output root proof for reuse. Types.OutputRootProof memory _outputRootProof_noData = Types.OutputRootProof({ @@ -1463,7 +1513,7 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T vm.expectEmit(address(optimismPortal2)); emit WithdrawalProvenExtension1(_withdrawalHash_noData, address(this)); optimismPortal2.proveWithdrawalTransaction({ - _tx: _defaultTx_noData, + _tx: _defaultTx, _disputeGameIndex: _proposedGameIndex_noData, _outputRootProof: _outputRootProof_noData, _withdrawalProof: _withdrawalProof_noData @@ -1476,9 +1526,9 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T vm.expectEmit(true, true, false, true); emit WithdrawalFinalized(_withdrawalHash_noData, true); - optimismPortal2.finalizeWithdrawalTransaction(_defaultTx_noData); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); - assert(bob.balance == bobBalanceBefore + 100); + assert(bob.balance == bobBalanceBefore + _defaultTx.value); } /// @notice Tests that `finalizeWithdrawalTransaction` succeeds. @@ -1505,7 +1555,7 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T emit WithdrawalFinalized(_withdrawalHash, true); optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); - assert(address(bob).balance == bobBalanceBefore + 100); + assert(address(bob).balance == bobBalanceBefore + _defaultTx.value); } /// @notice Tests that `finalizeWithdrawalTransaction` succeeds using a different proof than an @@ -1566,7 +1616,7 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T emit WithdrawalFinalized(_withdrawalHash, true); optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); - assert(address(bob).balance == bobBalanceBefore + 100); + assert(address(bob).balance == bobBalanceBefore + _defaultTx.value); } /// @notice Tests that `finalizeWithdrawalTransaction` reverts if the contract is paused. @@ -1778,19 +1828,12 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T /// does not have enough gas to execute. function test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() external { // This number was identified through trial and error. - uint256 gasLimit = 150_000; - Types.WithdrawalTransaction memory insufficientGasTx = Types.WithdrawalTransaction({ - nonce: 0, - sender: alice, - target: bob, - value: 100, - gasLimit: gasLimit, - data: hex"" - }); + _defaultTx.gasLimit = 150_000; + _defaultTx.data = hex""; // Get updated proof inputs. (bytes32 stateRoot, bytes32 storageRoot,,, bytes[] memory withdrawalProof) = - ffi.getProveWithdrawalTransactionInputs(insufficientGasTx); + ffi.getProveWithdrawalTransactionInputs(_defaultTx); Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ version: bytes32(0), stateRoot: stateRoot, @@ -1803,7 +1846,7 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T ); optimismPortal2.proveWithdrawalTransaction({ - _tx: insufficientGasTx, + _tx: _defaultTx, _disputeGameIndex: _proposedGameIndex, _outputRootProof: outputRootProof, _withdrawalProof: withdrawalProof @@ -1815,7 +1858,7 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); vm.expectRevert("SafeCall: Not enough gas"); - optimismPortal2.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx); + optimismPortal2.finalizeWithdrawalTransaction{ gas: _defaultTx.gasLimit }(_defaultTx); } /// @notice Tests that `finalizeWithdrawalTransaction` reverts if a sub-call attempts to @@ -1867,6 +1910,21 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T assert(address(bob).balance == bobBalanceBefore); } + /// @notice Tests that `finalizeWithdrawalTransaction` reverts when the custom gas token mode + /// is enabled and the withdrawal transaction has a value. + function test_finalizeWithdrawalTransaction_withValueAndCustomGasToken_reverts() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_FinalizeWithdrawalTransaction_Test: isCustomGasToken() not available on forked networks" + ); + // Set the withdrawal transaction value to a non-zero value. + _defaultTx.value = bound(uint256(1), 1, type(uint256).max); + + // Finalize the withdrawal transaction. This should revert. + vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + } + /// @notice Tests that `finalizeWithdrawalTransaction` succeeds. function testDiff_finalizeWithdrawalTransaction_succeeds( address _sender, @@ -1878,6 +1936,9 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T external { skipIfForkTest("Skipping on forked tests because of the L2ToL1MessageParser call below"); + if (isUsingCustomGasToken()) { + _value = 0; + } vm.assume( _target != address(optimismPortal2) // Cannot call the optimism portal or a contract @@ -1959,6 +2020,9 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T external { skipIfForkTest("Skipping on forked tests because of the L2ToL1MessageParser call below"); + if (isUsingCustomGasToken()) { + _value = 0; + } vm.assume( _target != address(optimismPortal2) // Cannot call the optimism portal or a contract @@ -2278,7 +2342,7 @@ contract OptimismPortal2_FinalizeWithdrawalTransactionExternalProof_Test is Opti vm.expectRevert(IOptimismPortal.OptimismPortal_AlreadyFinalized.selector); optimismPortal2.finalizeWithdrawalTransactionExternalProof(_defaultTx, address(this)); - assert(address(bob).balance == bobBalanceBefore + 100); + assert(address(bob).balance == bobBalanceBefore + _defaultTx.value); } } @@ -2452,6 +2516,28 @@ contract OptimismPortal2_DepositTransaction_Test is OptimismPortal2_TestInit { optimismPortal2.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" }); } + /// @notice Tests that `depositTransaction` reverts when the value is greater than 0 and the + /// custom gas token is active. + function test_depositTransaction_withCustomGasTokenAndValue_reverts(bytes memory _data, uint256 _value) external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest("OptimismPortal2_DepositTransaction_Test: isCustomGasToken() not available on forked networks"); + + // Prevent overflow on an upgrade context + _value = bound(_value, 1, type(uint256).max - address(optimismPortal2).balance); + uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(_data.length)); + + vm.deal(alice, _value); + vm.prank(alice); + vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); + optimismPortal2.depositTransaction{ value: _value }({ + _to: address(0x40), + _value: _value, + _gasLimit: gasLimit, + _isCreation: false, + _data: _data + }); + } + /// @notice Tests that `depositTransaction` succeeds for small, but sufficient, gas limits. function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external { uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(_data.length)); @@ -2481,7 +2567,17 @@ contract OptimismPortal2_DepositTransaction_Test is OptimismPortal2_TestInit { external { // Prevent overflow on an upgrade context - _mint = bound(_mint, 0, type(uint256).max - address(ethLockbox).balance); + // Since the value always goes through the portal + _mint = bound(_mint, 0, type(uint256).max - address(optimismPortal2).balance); + + if (isUsingLockbox() && address(optimismPortal2).balance > address(ethLockbox).balance) { + _mint = bound(_mint, 0, type(uint256).max - address(ethLockbox).balance); + } + + if (isUsingCustomGasToken()) { + _mint = 0; + } + _gasLimit = uint64( bound( _gasLimit, @@ -2493,7 +2589,6 @@ contract OptimismPortal2_DepositTransaction_Test is OptimismPortal2_TestInit { uint256 balanceBefore = address(optimismPortal2).balance; uint256 lockboxBalanceBefore = address(ethLockbox).balance; - _mint = bound(_mint, 0, type(uint256).max - balanceBefore); // EOA emulation vm.expectEmit(address(optimismPortal2)); @@ -2547,6 +2642,10 @@ contract OptimismPortal2_DepositTransaction_Test is OptimismPortal2_TestInit { // Prevent overflow on an upgrade context _mint = bound(_mint, 0, type(uint256).max - address(ethLockbox).balance); + if (isUsingCustomGasToken()) { + _mint = 0; + } + _gasLimit = uint64( bound( _gasLimit, @@ -2606,6 +2705,9 @@ contract OptimismPortal2_DepositTransaction_Test is OptimismPortal2_TestInit { { // Prevent overflow on an upgrade context _mint = bound(_mint, 0, type(uint256).max - address(ethLockbox).balance); + if (isUsingCustomGasToken()) { + _mint = 0; + } _gasLimit = uint64( bound( _gasLimit, @@ -2654,6 +2756,343 @@ contract OptimismPortal2_DepositTransaction_Test is OptimismPortal2_TestInit { } } +/// @title OptimismPortal2_DepositERC20Transaction_Test +/// @notice Test contract for OptimismPortal2 `depositERC20Transaction` function. +contract OptimismPortal2_DepositERC20Transaction_Test is CommonTest { + address depositor; + ERC20 customGasToken; + + function setUp() public override { + super.setUp(); + depositor = makeAddr("depositor"); + + // Set up custom gas token if the feature is enabled + if (isDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN)) { + // Deploy a mock ERC20 token to use as custom gas token + customGasToken = new ERC20("Custom Gas Token", "CGT"); + + // Set the custom gas token in SystemConfig + // Convert strings to bytes32 for SystemConfig function + bytes32 nameBytes32 = bytes32(bytes("Custom Gas Token")); + bytes32 symbolBytes32 = bytes32(bytes("CGT")); + + vm.prank(systemConfig.owner()); + systemConfig.setGasPayingToken(address(customGasToken), 18, nameBytes32, symbolBytes32); + } + } + /// @notice Tests that `depositERC20Transaction` reverts when custom gas token is not enabled. + + function test_depositERC20Transaction_notCustomGasToken_reverts() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); + + vm.expectRevert(IOptimismPortal.OptimismPortal_OnlyCustomGasToken.selector); + optimismPortal2.depositERC20Transaction({ + _to: address(0x40), + _mint: 100, + _value: 100, + _gasLimit: 21000, + _isCreation: false, + _data: hex"" + }); + } + + /// @notice Tests that `depositERC20Transaction` reverts when gas token is invalid (ETH). + function test_depositERC20Transaction_invalidGasToken_reverts() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_DepositERC20Transaction_Test: custom gas token not available on forked networks" + ); + + // Mock the gasPayingToken to return Constants.ETHER to test the invalid token error + // We can't actually call setGasPayingToken again since it can only be set once + vm.mockCall( + address(systemConfig), + abi.encodeCall(systemConfig.gasPayingToken, ()), + abi.encode(Constants.ETHER, uint8(18)) + ); + + vm.expectRevert(IOptimismPortal.OptimismPortal_InvalidGasToken.selector); + optimismPortal2.depositERC20Transaction({ + _to: address(0x40), + _mint: 100, + _value: 100, + _gasLimit: 21000, + _isCreation: false, + _data: hex"" + }); + + // Clear the mock for other tests + vm.clearMockedCalls(); + } + + /// @notice Tests that `depositERC20Transaction` reverts when destination address is non-zero + /// for a contract creation deposit. + function test_depositERC20Transaction_contractCreation_reverts() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_DepositERC20Transaction_Test: custom gas token not available on forked networks" + ); + + // Set up tokens and approval so we don't fail on ERC20 transfer first + uint256 mintAmount = 100; + deal(address(customGasToken), address(this), mintAmount); + customGasToken.approve(address(optimismPortal2), mintAmount); + + vm.expectRevert(IOptimismPortal.OptimismPortal_BadTarget.selector); + optimismPortal2.depositERC20Transaction({ + _to: address(1), + _mint: mintAmount, + _value: 100, + _gasLimit: 21000, + _isCreation: true, + _data: hex"" + }); + } + + /// @notice Tests that `depositERC20Transaction` reverts when the gas limit is too small. + function test_depositERC20Transaction_smallGasLimit_reverts() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_DepositERC20Transaction_Test: custom gas token not available on forked networks" + ); + + // Set up tokens and approval so we don't fail on ERC20 transfer first + uint256 mintAmount = 100; + deal(address(customGasToken), address(this), mintAmount); + customGasToken.approve(address(optimismPortal2), mintAmount); + + vm.expectRevert(IOptimismPortal.OptimismPortal_GasLimitTooLow.selector); + optimismPortal2.depositERC20Transaction({ + _to: address(0x40), + _mint: mintAmount, + _value: 100, + _gasLimit: 0, + _isCreation: false, + _data: hex"" + }); + } + + /// @notice Tests that `depositERC20Transaction` reverts when the data is too large. + function test_depositERC20Transaction_largeData_reverts() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_DepositERC20Transaction_Test: custom gas token not available on forked networks" + ); + + uint256 size = 120_001; + uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(size)); + + // Set up tokens and approval so we don't fail on ERC20 transfer first + uint256 mintAmount = 100; + deal(address(customGasToken), address(this), mintAmount); + customGasToken.approve(address(optimismPortal2), mintAmount); + + vm.expectRevert(IOptimismPortal.OptimismPortal_CalldataTooLarge.selector); + optimismPortal2.depositERC20Transaction({ + _to: address(0x40), + _mint: mintAmount, + _value: 100, + _gasLimit: gasLimit, + _isCreation: false, + _data: new bytes(size) + }); + } + + /// @notice Tests that `depositERC20Transaction` succeeds for small, but sufficient, gas limits. + function testFuzz_depositERC20Transaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_DepositERC20Transaction_Test: custom gas token not available on forked networks" + ); + + uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(_data.length)); + if (_shouldFail) { + gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1)); + vm.expectRevert(IOptimismPortal.OptimismPortal_GasLimitTooLow.selector); + } + + // No ERC20 transfer needed since _mint is 0 + vm.prank(depositor); + optimismPortal2.depositERC20Transaction({ + _to: address(0x40), + _mint: 0, + _value: 0, + _gasLimit: gasLimit, + _isCreation: false, + _data: _data + }); + } + + /// @notice Tests that `depositERC20Transaction` succeeds for an EOA. + function testFuzz_depositERC20Transaction_eoa_succeeds( + address _to, + uint64 _gasLimit, + uint256 _mint, + uint256 _value, + bool _isCreation, + bytes memory _data + ) + external + { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_DepositERC20Transaction_Test: custom gas token not available on forked networks" + ); + + _gasLimit = uint64( + bound( + _gasLimit, + optimismPortal2.minimumGasLimit(uint64(_data.length)), + systemConfig.resourceConfig().maxResourceLimit + ) + ); + if (_isCreation) _to = address(0); + + // Set up ERC20 token balance and approval for real transfers + if (_mint > 0) { + // Give the depositor some tokens and approve the portal + deal(address(customGasToken), depositor, _mint); + vm.prank(depositor); + customGasToken.approve(address(optimismPortal2), _mint); + } + + // EOA emulation + vm.expectEmit(address(optimismPortal2)); + emitTransactionDeposited({ + _from: depositor, + _to: _to, + _value: _value, + _mint: _mint, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + + vm.prank(depositor, depositor); + optimismPortal2.depositERC20Transaction({ + _to: _to, + _mint: _mint, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + } + + /// @notice Tests that `depositERC20Transaction` succeeds for a contract. + function testFuzz_depositERC20Transaction_contract_succeeds( + address _to, + uint64 _gasLimit, + uint256 _mint, + uint256 _value, + bool _isCreation, + bytes memory _data + ) + external + { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_DepositERC20Transaction_Test: custom gas token not available on forked networks" + ); + + _gasLimit = uint64( + bound( + _gasLimit, + optimismPortal2.minimumGasLimit(uint64(_data.length)), + systemConfig.resourceConfig().maxResourceLimit + ) + ); + if (_isCreation) _to = address(0); + + // Set up ERC20 token balance and approval for real transfers + if (_mint > 0) { + // Give the test contract some tokens and approve the portal + deal(address(customGasToken), address(this), _mint); + customGasToken.approve(address(optimismPortal2), _mint); + } + + vm.expectEmit(address(optimismPortal2)); + emitTransactionDeposited({ + _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), + _to: _to, + _value: _value, + _mint: _mint, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + + vm.prank(address(this)); + optimismPortal2.depositERC20Transaction({ + _to: _to, + _mint: _mint, + _value: _value, + _gasLimit: _gasLimit, + _isCreation: _isCreation, + _data: _data + }); + } + + /// @notice Tests that `depositERC20Transaction` correctly transfers tokens when mint is non-zero. + function test_depositERC20Transaction_transfersTokens_succeeds() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_DepositERC20Transaction_Test: custom gas token not available on forked networks" + ); + + uint256 mintAmount = 1000; + + // Set up the depositor with tokens and approval + deal(address(customGasToken), depositor, mintAmount); + vm.prank(depositor); + customGasToken.approve(address(optimismPortal2), mintAmount); + + // Check initial balances + uint256 depositorBalanceBefore = customGasToken.balanceOf(depositor); + uint256 portalBalanceBefore = customGasToken.balanceOf(address(optimismPortal2)); + + vm.prank(depositor, depositor); + optimismPortal2.depositERC20Transaction({ + _to: address(0x40), + _mint: mintAmount, + _value: mintAmount, + _gasLimit: 50000, + _isCreation: false, + _data: hex"" + }); + + // Verify the tokens were transferred + assertEq(customGasToken.balanceOf(depositor), depositorBalanceBefore - mintAmount); + assertEq(customGasToken.balanceOf(address(optimismPortal2)), portalBalanceBefore + mintAmount); + } + + /// @notice Tests that `depositERC20Transaction` does not transfer tokens when mint is zero. + function test_depositERC20Transaction_zeroMint_succeeds() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_DepositERC20Transaction_Test: custom gas token not available on forked networks" + ); + + // Check initial balances - should remain unchanged + uint256 depositorBalanceBefore = customGasToken.balanceOf(depositor); + uint256 portalBalanceBefore = customGasToken.balanceOf(address(optimismPortal2)); + + vm.prank(depositor, depositor); + optimismPortal2.depositERC20Transaction({ + _to: address(0x40), + _mint: 0, + _value: 100, + _gasLimit: 50000, + _isCreation: false, + _data: hex"" + }); + + // Verify no tokens were transferred when mint is 0 + assertEq(customGasToken.balanceOf(depositor), depositorBalanceBefore); + assertEq(customGasToken.balanceOf(address(optimismPortal2)), portalBalanceBefore); + } +} + /// @title OptimismPortal2_Params_Test /// @notice Test various values of the resource metering config to ensure that deposits cannot be /// broken by changing the config. diff --git a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol index cfa090517b154..fd3426638b65e 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol @@ -11,6 +11,7 @@ import { ForgeArtifacts, StorageSlot } from "scripts/libraries/ForgeArtifacts.so import { Constants } from "src/libraries/Constants.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Features } from "src/libraries/Features.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; // Interfaces import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; @@ -907,3 +908,19 @@ contract SystemConfig_SetMinBaseFee_Test is SystemConfig_TestInit { assertEq(systemConfig.minBaseFee(), newMinBaseFee); } } + +/// @title SystemConfig_IsCustomGasToken_Test +/// @notice Test contract for SystemConfig `isCustomGasToken` function. +contract SystemConfig_IsCustomGasToken_Test is SystemConfig_TestInit { + /// @notice Tests that `isCustomGasToken` returns the correct value. + function test_isCustomGasToken_enabled_succeeds() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + assertTrue(systemConfig.isCustomGasToken()); + } + + /// @notice Tests that `isCustomGasToken` returns the correct value. + function test_isCustomGasToken_disabled_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); + assertFalse(systemConfig.isCustomGasToken()); + } +} diff --git a/packages/contracts-bedrock/test/L2/BaseFeeVault.t.sol b/packages/contracts-bedrock/test/L2/BaseFeeVault.t.sol index ce1a0fe77d35b..1a2019cf061ff 100644 --- a/packages/contracts-bedrock/test/L2/BaseFeeVault.t.sol +++ b/packages/contracts-bedrock/test/L2/BaseFeeVault.t.sol @@ -4,9 +4,6 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/setup/CommonTest.sol"; -// Libraries -import { Types } from "src/libraries/Types.sol"; - /// @title BaseFeeVault_Constructor_Test /// @notice Tests the `constructor` of the `BaseFeeVault` contract. contract BaseFeeVault_Constructor_Test is CommonTest { @@ -16,7 +13,7 @@ contract BaseFeeVault_Constructor_Test is CommonTest { assertEq(baseFeeVault.recipient(), deploy.cfg().baseFeeVaultRecipient()); assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().baseFeeVaultMinimumWithdrawalAmount()); assertEq(baseFeeVault.minWithdrawalAmount(), deploy.cfg().baseFeeVaultMinimumWithdrawalAmount()); - assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), uint8(Types.WithdrawalNetwork.L1)); - assertEq(uint8(baseFeeVault.withdrawalNetwork()), uint8(Types.WithdrawalNetwork.L1)); + assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), deploy.cfg().baseFeeVaultWithdrawalNetwork()); + assertEq(uint8(baseFeeVault.withdrawalNetwork()), deploy.cfg().baseFeeVaultWithdrawalNetwork()); } } diff --git a/packages/contracts-bedrock/test/L2/L1Block.t.sol b/packages/contracts-bedrock/test/L2/L1Block.t.sol index 7a276b94df5d6..b46df4bae4d8d 100644 --- a/packages/contracts-bedrock/test/L2/L1Block.t.sol +++ b/packages/contracts-bedrock/test/L2/L1Block.t.sol @@ -3,11 +3,16 @@ pragma solidity 0.8.15; // Testing import { CommonTest } from "test/setup/CommonTest.sol"; +import { stdStorage, StdStorage } from "forge-std/Test.sol"; // Libraries import { Encoding } from "src/libraries/Encoding.sol"; import { Constants } from "src/libraries/Constants.sol"; import "src/libraries/L1BlockErrors.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; + +// Interfaces +import { IL1BlockCGT } from "interfaces/L2/IL1BlockCGT.sol"; /// @title L1Block_ TestInit /// @notice Reusable test initialization for `L1Block` tests. @@ -21,34 +26,68 @@ contract L1Block_TestInit is CommonTest { } } +/// @title L1Block_Version_Test +/// @notice Test contract for L1Block `version` function. +contract L1Block_Version_Test is L1Block_TestInit { + /// @notice Tests that the version function returns a valid string. We avoid testing the + /// specific value of the string as it changes frequently. + function test_version_succeeds() external view { + assert(bytes(l1Block.version()).length > 0); + } +} + /// @title L1Block_GasPayingToken_Test /// @notice Tests the `gasPayingToken` function of the `L1Block` contract. contract L1Block_GasPayingToken_Test is L1Block_TestInit { /// @notice Tests that the `gasPayingToken` function returns the correct token address and /// decimals. - function test_gasPayingToken_succeeds() external view { + function test_gasPayingToken_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); (address token, uint8 decimals) = l1Block.gasPayingToken(); assertEq(token, Constants.ETHER); assertEq(uint256(decimals), uint256(18)); } + + /// @notice Tests that the `gasPayingToken` function reverts when custom gas token is enabled. + function test_gasPayingToken_customGasToken_reverts() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + vm.expectRevert("L1BlockCGT: deprecated"); + l1Block.gasPayingToken(); + } } /// @title L1Block_GasPayingTokenName_Test /// @notice Tests the `gasPayingTokenName` function of the `L1Block` contract. contract L1Block_GasPayingTokenName_Test is L1Block_TestInit { /// @notice Tests that the `gasPayingTokenName` function returns the correct token name. - function test_gasPayingTokenName_succeeds() external view { + function test_gasPayingTokenName_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); assertEq("Ether", l1Block.gasPayingTokenName()); } + + /// @notice Tests that the `gasPayingTokenName` function returns the correct token name when custom gas token is + /// enabled. + function test_gasPayingTokenName_customGasToken_succeeds() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + assertEq(liquidityController.gasPayingTokenName(), l1Block.gasPayingTokenName()); + } } /// @title L1Block_GasPayingTokenSymbol_Test /// @notice Tests the `gasPayingTokenSymbol` function of the `L1Block` contract. contract L1Block_GasPayingTokenSymbol_Test is L1Block_TestInit { /// @notice Tests that the `gasPayingTokenSymbol` function returns the correct token symbol. - function test_gasPayingTokenSymbol_succeeds() external view { + function test_gasPayingTokenSymbol_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); assertEq("ETH", l1Block.gasPayingTokenSymbol()); } + + /// @notice Tests that the `gasPayingTokenSymbol` function returns the correct token symbol when custom gas token is + /// enabled. + function test_gasPayingTokenSymbol_customGasToken_succeeds() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + assertEq(liquidityController.gasPayingTokenSymbol(), l1Block.gasPayingTokenSymbol()); + } } /// @title L1Block_IsCustomGasToken_Test @@ -56,9 +95,17 @@ contract L1Block_GasPayingTokenSymbol_Test is L1Block_TestInit { contract L1Block_IsCustomGasToken_Test is L1Block_TestInit { /// @notice Tests that the `isCustomGasToken` function returns false when no custom gas token /// is used. - function test_isCustomGasToken_succeeds() external view { + function test_isCustomGasToken_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); assertFalse(l1Block.isCustomGasToken()); } + + /// @notice Tests that the `isCustomGasToken` function returns true when custom gas token + /// is used. + function test_isCustomGasToken_customGasToken_succeeds() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + assertTrue(l1Block.isCustomGasToken()); + } } /// @title L1Block_SetL1BlockValues_Test @@ -315,3 +362,48 @@ contract L1Block_SetL1BlockValuesIsthmus_Test is L1Block_TestInit { assertEq(data, expReturn); } } + +/// @title L1Block_SetCustomGasToken_Test +/// @notice Tests the `setCustomGasToken` function of the `L1Block` contract. +contract L1Block_SetCustomGasToken_Test is L1Block_TestInit { + using stdStorage for StdStorage; + + IL1BlockCGT l1BlockCGT; + + function setUp() public override { + super.setUp(); + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + l1BlockCGT = IL1BlockCGT(address(l1Block)); + } + + /// @notice Tests that `setCustomGasToken` reverts if called twice. + function test_setCustomGasToken_alreadyActive_reverts() external { + // This test uses the setUp that already activates custom gas token + assertTrue(l1BlockCGT.isCustomGasToken()); + + vm.expectRevert("L1Block: CustomGasToken already active"); + vm.prank(depositor); + IL1BlockCGT(address(l1BlockCGT)).setCustomGasToken(); + } + + /// @notice Tests that `setCustomGasToken` updates the flag correctly when called by depositor. + function test_setCustomGasToken_succeeds() external { + stdstore.target(address(l1BlockCGT)).sig("isCustomGasToken()").checked_write(false); + // This test uses the setUp that already activates custom gas token + assertFalse(l1BlockCGT.isCustomGasToken()); + + vm.prank(depositor); + l1BlockCGT.setCustomGasToken(); + + assertTrue(l1BlockCGT.isCustomGasToken()); + } + + /// @notice Tests that `setCustomGasToken` reverts if sender address is not the depositor. + function test_setCustomGasToken_notDepositor_reverts(address nonDepositor) external { + stdstore.target(address(l1BlockCGT)).sig("isCustomGasToken()").checked_write(false); + vm.assume(nonDepositor != depositor); + vm.expectRevert("L1Block: only the depositor account can set isCustomGasToken flag"); + vm.prank(nonDepositor); + l1BlockCGT.setCustomGasToken(); + } +} diff --git a/packages/contracts-bedrock/test/L2/L1FeeVault.t.sol b/packages/contracts-bedrock/test/L2/L1FeeVault.t.sol index f61eb99927db7..b98774339d615 100644 --- a/packages/contracts-bedrock/test/L2/L1FeeVault.t.sol +++ b/packages/contracts-bedrock/test/L2/L1FeeVault.t.sol @@ -4,9 +4,6 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/setup/CommonTest.sol"; -// Libraries -import { Types } from "src/libraries/Types.sol"; - /// @title L1FeeVault_Constructor_Test /// @notice Tests the `constructor` of the `L1FeeVault` contract. contract L1FeeVault_Constructor_Test is CommonTest { @@ -16,7 +13,7 @@ contract L1FeeVault_Constructor_Test is CommonTest { assertEq(l1FeeVault.recipient(), deploy.cfg().l1FeeVaultRecipient()); assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().l1FeeVaultMinimumWithdrawalAmount()); assertEq(l1FeeVault.minWithdrawalAmount(), deploy.cfg().l1FeeVaultMinimumWithdrawalAmount()); - assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(Types.WithdrawalNetwork.L1)); - assertEq(uint8(l1FeeVault.withdrawalNetwork()), uint8(Types.WithdrawalNetwork.L1)); + assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), deploy.cfg().l1FeeVaultWithdrawalNetwork()); + assertEq(uint8(l1FeeVault.withdrawalNetwork()), deploy.cfg().l1FeeVaultWithdrawalNetwork()); } } diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol index a3f7297426ba1..c79d9995be469 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol @@ -14,6 +14,7 @@ import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { Types } from "src/libraries/Types.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; // Interfaces import { ICrossDomainMessenger } from "interfaces/universal/ICrossDomainMessenger.sol"; @@ -231,6 +232,7 @@ contract L2StandardBridge_Initialize_Test is L2StandardBridge_TestInit { contract L2StandardBridge_Receive_Test is L2StandardBridge_TestInit { /// @notice Tests that the bridge receives ETH and successfully initiates a withdrawal. function test_receive_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); assertEq(address(l2ToL1MessagePasser).balance, 0); uint256 nonce = l2CrossDomainMessenger.messageNonce(); @@ -323,6 +325,7 @@ contract L2StandardBridge_Withdraw_Test is L2StandardBridge_TestInit { /// @notice Tests that the legacy `withdraw` interface on the L2StandardBridge sucessfully /// initiates a withdrawal. function test_withdraw_ether_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); assertTrue(alice.balance >= 100); assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0); @@ -465,6 +468,7 @@ contract L2StandardBridge_Uncategorized_Test is L2StandardBridge_TestInit { /// @notice Tests that bridging ETH succeeds. function testFuzz_bridgeETH_succeeds(uint256 _value, uint32 _minGasLimit, bytes calldata _extraData) external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); uint256 nonce = l2CrossDomainMessenger.messageNonce(); bytes memory message = abi.encodeCall(IStandardBridge.finalizeBridgeETH, (alice, alice, _value, _extraData)); @@ -498,6 +502,7 @@ contract L2StandardBridge_Uncategorized_Test is L2StandardBridge_TestInit { /// @notice Tests that bridging ETH to a different address succeeds. function testFuzz_bridgeETHTo_succeeds(uint256 _value, uint32 _minGasLimit, bytes calldata _extraData) external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); uint256 nonce = l2CrossDomainMessenger.messageNonce(); vm.expectCall( diff --git a/packages/contracts-bedrock/test/L2/L2ToL1MessagePasser.t.sol b/packages/contracts-bedrock/test/L2/L2ToL1MessagePasser.t.sol index 8ce02b6aad74b..c4c911a4937b3 100644 --- a/packages/contracts-bedrock/test/L2/L2ToL1MessagePasser.t.sol +++ b/packages/contracts-bedrock/test/L2/L2ToL1MessagePasser.t.sol @@ -7,6 +7,20 @@ import { CommonTest } from "test/setup/CommonTest.sol"; // Libraries import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; + +// Interfaces +import { IL2ToL1MessagePasserCGT } from "interfaces/L2/IL2ToL1MessagePasserCGT.sol"; + +/// @title L2ToL1MessagePasser_Version_Test +/// @notice Tests the `version` function of the `L2ToL1MessagePasser` contract. +contract L2ToL1MessagePasser_Version_Test is CommonTest { + /// @notice Tests that the `version` function returns the correct string. We avoid testing the + /// specific value of the string as it changes frequently. + function test_version_succeeds() external view { + assert(bytes(l2ToL1MessagePasser.version()).length > 0); + } +} /// @title L2ToL1MessagePasser_InitiateWithdrawal_Test /// @notice Tests the `initiateWithdrawal` function of the `L2ToL1MessagePasser` contract. @@ -22,6 +36,9 @@ contract L2ToL1MessagePasser_InitiateWithdrawal_Test is CommonTest { ) external { + if (isDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN)) { + _value = 0; + } uint256 nonce = l2ToL1MessagePasser.messageNonce(); bytes32 withdrawalHash = Hashing.hashWithdrawal( @@ -59,6 +76,7 @@ contract L2ToL1MessagePasser_InitiateWithdrawal_Test is CommonTest { ) external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); bytes32 withdrawalHash = Hashing.hashWithdrawal( Types.WithdrawalTransaction({ nonce: l2ToL1MessagePasser.messageNonce(), @@ -89,6 +107,7 @@ contract L2ToL1MessagePasser_InitiateWithdrawal_Test is CommonTest { ) external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); uint256 nonce = l2ToL1MessagePasser.messageNonce(); // EOA emulation @@ -107,6 +126,25 @@ contract L2ToL1MessagePasser_InitiateWithdrawal_Test is CommonTest { // the nonce increments assertEq(nonce + 1, l2ToL1MessagePasser.messageNonce()); } + + /// @notice Tests that `initiateWithdrawal` fails when called with value and custom gas token + /// is enabled. + function testFuzz_initiateWithdrawal_withValueAndCustomGasToken_fails( + address _randomAddress, + uint256 _value + ) + external + { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + // Set initial state + _value = bound(_value, 1, type(uint256).max); + vm.deal(_randomAddress, _value); + + // Expect revert with NotAllowedOnCGTMode + vm.prank(_randomAddress); + vm.expectRevert(IL2ToL1MessagePasserCGT.L2ToL1MessagePasserCGT_NotAllowedOnCGTMode.selector); + l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: address(0), _gasLimit: 1, _data: "" }); + } } /// @title L2ToL1MessagePasser_Burn_Test @@ -114,6 +152,7 @@ contract L2ToL1MessagePasser_InitiateWithdrawal_Test is CommonTest { contract L2ToL1MessagePasser_Burn_Test is CommonTest { /// @notice Tests that `burn` succeeds and destroys the ETH held in the contract. function testFuzz_burn_succeeds(uint256 _value, address _target, uint256 _gasLimit, bytes memory _data) external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); vm.deal(address(this), _value); l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); diff --git a/packages/contracts-bedrock/test/L2/LiquidityController.t.sol b/packages/contracts-bedrock/test/L2/LiquidityController.t.sol new file mode 100644 index 0000000000000..c43d3e3ee6eda --- /dev/null +++ b/packages/contracts-bedrock/test/L2/LiquidityController.t.sol @@ -0,0 +1,279 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; +import { stdStorage, StdStorage } from "forge-std/Test.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; + +// Contracts +import { LiquidityController } from "src/L2/LiquidityController.sol"; +import { NativeAssetLiquidity } from "src/L2/NativeAssetLiquidity.sol"; + +// Interfaces +import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; + +/// @title LiquidityController_TestInit +/// @notice Reusable test initialization for `LiquidityController` tests. +contract LiquidityController_TestInit is CommonTest { + using stdStorage for StdStorage; + + /// @notice Emitted when an address withdraws native asset liquidity. + event LiquidityWithdrawn(address indexed caller, uint256 value); + + /// @notice Emitted when an address deposits native asset liquidity. + event LiquidityDeposited(address indexed caller, uint256 value); + + /// @notice Emitted when an address is deauthorized to mint/burn liquidity + event MinterDeauthorized(address indexed minter); + + /// @notice Emitted when an address is authorized to mint/burn liquidity + event MinterAuthorized(address indexed minter); + + /// @notice Emitted when liquidity is minted + event LiquidityMinted(address indexed minter, address indexed to, uint256 amount); + + /// @notice Emitted when liquidity is burned + event LiquidityBurned(address indexed minter, uint256 amount); + + /// @notice Test setup. + function setUp() public virtual override { + super.setUp(); + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + } + + /// @notice Helper function to authorize a minter. + function _authorizeMinter(address _minter) internal { + assumeNotForgeAddress(_minter); + assumeNotZeroAddress(_minter); + // Authorize the minter + stdstore.target(address(liquidityController)).sig(liquidityController.minters.selector).with_key(_minter) + .checked_write(true); + } +} + +/// @title LiquidityController_Version_Test +/// @notice Tests the `version` function of the `LiquidityController` contract. +contract LiquidityController_Version_Test is LiquidityController_TestInit { + /// @notice Tests that the version function returns a valid string. + function test_version_succeeds() public view { + assert(bytes(liquidityController.version()).length > 0); + } +} + +/// @title LiquidityController_GasPayingTokenName_Test +/// @notice Tests the `gasPayingTokenName` function of the `LiquidityController` contract. +contract LiquidityController_GasPayingTokenName_Test is LiquidityController_TestInit { + /// @notice Tests that the `version` function returns the correct string. We avoid testing the + /// specific value of the string as it changes frequently. + function test_gasPayingTokenName_succeeds() public view { + assertTrue(bytes(liquidityController.gasPayingTokenName()).length > 0); + } +} + +/// @title LiquidityController_GasPayingTokenSymbol_Test +/// @notice Tests the `gasPayingTokenSymbol` function of the `LiquidityController` contract. +contract LiquidityController_GasPayingTokenSymbol_Test is LiquidityController_TestInit { + /// @notice Tests that the gasPayingTokenSymbol function returns a valid string. + function test_gasPayingTokenSymbol_succeeds() public view { + assertTrue(bytes(liquidityController.gasPayingTokenSymbol()).length > 0); + } +} + +/// @title LiquidityController_AuthorizeMinter_Test +/// @notice Tests the `authorizeMinter` function of the `LiquidityController` contract. +contract LiquidityController_AuthorizeMinter_Test is LiquidityController_TestInit { + /// @notice Tests that the authorizeMinter function can be called by the owner. + function testFuzz_authorizeMinter_fromOwner_succeeds(address _minter) public { + // Expect emit MinterAuthorized event + vm.expectEmit(address(liquidityController)); + emit MinterAuthorized(_minter); + // Call the authorizeMinter function with owner as the caller + vm.prank(IProxyAdmin(Predeploys.PROXY_ADMIN).owner()); + liquidityController.authorizeMinter(_minter); + + // Assert minter is authorized + assertTrue(liquidityController.minters(_minter)); + } + + /// @notice Tests that the authorizeMinter function reverts when called by non-owner. + function testFuzz_authorizeMinter_fromNonOwner_fails(address _caller, address _minter) public { + vm.assume(_caller != IProxyAdmin(Predeploys.PROXY_ADMIN).owner()); + + // Call the authorizeMinter function with non-owner as the caller + vm.prank(_caller); + vm.expectRevert(LiquidityController.LiquidityController_Unauthorized.selector); + liquidityController.authorizeMinter(_minter); + + // Assert minter is not authorized + assertFalse(liquidityController.minters(_minter)); + } +} + +/// @title LiquidityController_DeauthorizeMinter_Test +/// @notice Tests the `deauthorizeMinter` function of the `LiquidityController` contract. +contract LiquidityController_DeauthorizeMinter_Test is LiquidityController_TestInit { + /// @notice Tests that the deauthorizeMinter function can be called by the owner. + function testFuzz_deauthorizeMinter_fromOwner_succeeds(address _minter) public { + // Set minter to authorized + _authorizeMinter(_minter); + + // Expect emit MinterDeauthorized event + vm.expectEmit(address(liquidityController)); + emit MinterDeauthorized(_minter); + // Call the deauthorizeMinter function with owner as the caller + vm.prank(IProxyAdmin(Predeploys.PROXY_ADMIN).owner()); + liquidityController.deauthorizeMinter(_minter); + + // Assert minter is deauthorized + assertFalse(liquidityController.minters(_minter)); + } + + /// @notice Tests that the deauthorizeMinter function reverts when called by non-owner. + function testFuzz_deauthorizeMinter_fromNonOwner_fails(address _caller, address _minter) public { + vm.assume(_caller != IProxyAdmin(Predeploys.PROXY_ADMIN).owner()); + + // Set minter to authorized + _authorizeMinter(_minter); + + // Call the deauthorizeMinter function with non-owner as the caller + vm.prank(_caller); + vm.expectRevert(LiquidityController.LiquidityController_Unauthorized.selector); + liquidityController.deauthorizeMinter(_minter); + + // Assert minter is still authorized + assertTrue(liquidityController.minters(_minter)); + } +} + +/// @title LiquidityController_Mint_Test +/// @notice Tests the `mint` function of the `LiquidityController` contract. +contract LiquidityController_Mint_Test is LiquidityController_TestInit { + /// @notice Tests that the mint function can be called by an authorized minter. + function testFuzz_mint_fromAuthorizedMinter_succeeds(address _to, uint256 _amount, address _minter) public { + _authorizeMinter(_minter); + vm.assume(_to != address(nativeAssetLiquidity)); + _amount = bound(_amount, 1, address(nativeAssetLiquidity).balance); + + // Record initial balances + uint256 nativeAssetBalanceBefore = address(nativeAssetLiquidity).balance; + uint256 toBalanceBefore = _to.balance; + + // Expect emit LiquidityWithdrawn event and call the mint function + vm.expectEmit(address(nativeAssetLiquidity)); + emit LiquidityWithdrawn(address(liquidityController), _amount); + // Expect emit LiquidityMinted event + vm.expectEmit(address(liquidityController)); + emit LiquidityMinted(_minter, _to, _amount); + vm.prank(_minter); + liquidityController.mint(_to, _amount); + + // Assert recipient and NativeAssetLiquidity balances are updated correctly + assertEq(_to.balance, toBalanceBefore + _amount); + assertEq(address(nativeAssetLiquidity).balance, nativeAssetBalanceBefore - _amount); + } + + /// @notice Tests that the mint function reverts when called by unauthorized address. + function testFuzz_mint_fromUnauthorizedCaller_fails(address _caller, address _to, uint256 _amount) public { + _amount = bound(_amount, 1, address(nativeAssetLiquidity).balance); + + uint256 nativeAssetBalanceBefore = address(nativeAssetLiquidity).balance; + uint256 toBalanceBefore = _to.balance; + + // Call the mint function with unauthorized caller + vm.prank(_caller); + vm.expectRevert(LiquidityController.LiquidityController_Unauthorized.selector); + liquidityController.mint(_to, _amount); + + // Assert recipient and NativeAssetLiquidity balances remain unchanged + assertEq(_to.balance, toBalanceBefore); + assertEq(address(nativeAssetLiquidity).balance, nativeAssetBalanceBefore); + } + + /// @notice Tests that the mint function reverts when contract has insufficient balance. + function test_mint_insufficientBalance_fails(address _minter) public { + _authorizeMinter(_minter); + // Try to mint more than available balance + uint256 contractBalance = address(nativeAssetLiquidity).balance; + uint256 amount = bound(contractBalance, contractBalance + 1, type(uint256).max); + address to = makeAddr("recipient"); + + // Call the mint function with insufficient balance + vm.prank(_minter); + // Should revert due to insufficient balance in NativeAssetLiquidity + vm.expectRevert(NativeAssetLiquidity.NativeAssetLiquidity_InsufficientBalance.selector); + + liquidityController.mint(to, amount); + + // Assert recipient and NativeAssetLiquidity balances remain unchanged + assertEq(to.balance, 0); + assertEq(address(nativeAssetLiquidity).balance, contractBalance); + } +} + +/// @title LiquidityController_Burn_Test +/// @notice Tests the `burn` function of the `LiquidityController` contract. +contract LiquidityController_Burn_Test is LiquidityController_TestInit { + /// @notice Tests that the burn function can be called by an authorized minter. + function testFuzz_burn_fromAuthorizedMinter_succeeds(uint256 _amount, address _minter) public { + _authorizeMinter(_minter); + _amount = bound(_amount, 0, address(nativeAssetLiquidity).balance); + + // Deal the authorized minter with the amount to burn + vm.deal(_minter, _amount); + uint256 nativeAssetBalanceBefore = address(nativeAssetLiquidity).balance; + uint256 minterBalanceBefore = _minter.balance; + + // Expect emit LiquidityDeposited event and call the burn function + vm.expectEmit(address(nativeAssetLiquidity)); + emit LiquidityDeposited(address(liquidityController), _amount); + // Expect emit LiquidityBurned event + vm.expectEmit(address(liquidityController)); + emit LiquidityBurned(_minter, _amount); + vm.prank(_minter); + liquidityController.burn{ value: _amount }(); + + // Assert minter and NativeAssetLiquidity balances are updated correctly + assertEq(_minter.balance, minterBalanceBefore - _amount); + assertEq(address(nativeAssetLiquidity).balance, nativeAssetBalanceBefore + _amount); + } + + /// @notice Tests that the burn function reverts when called by unauthorized address. + function testFuzz_burn_fromUnauthorizedCaller_fails(address _caller, uint256 _amount, address _minter) public { + _authorizeMinter(_minter); + vm.assume(_caller != _minter); + _amount = bound(_amount, 0, address(nativeAssetLiquidity).balance); + + // Deal the unauthorized caller with the amount to burn + vm.deal(_caller, _amount); + uint256 nativeAssetBalanceBefore = address(nativeAssetLiquidity).balance; + uint256 callerBalanceBefore = _caller.balance; + + // Call the burn function with unauthorized caller + vm.prank(_caller); + vm.expectRevert(LiquidityController.LiquidityController_Unauthorized.selector); + liquidityController.burn{ value: _amount }(); + + // Assert caller and NativeAssetLiquidity balances remain unchanged + assertEq(_caller.balance, callerBalanceBefore); + assertEq(address(nativeAssetLiquidity).balance, nativeAssetBalanceBefore); + } +} + +/// @title LiquidityController_Initialize_Test +/// @notice Tests the `initialize` function of the `LiquidityController` contract. +contract LiquidityController_Initialize_Test is LiquidityController_TestInit { + /// @notice Tests that calling initialize on the implementation contract reverts. + function test_initialize_implementation_reverts() public { + // Deploy a new implementation contract directly (not through proxy) + LiquidityController implementation = new LiquidityController(); + + // Try to initialize the implementation contract directly + // This should revert because _disableInitializers() was called in the constructor + vm.expectRevert("Initializable: contract is already initialized"); + implementation.initialize("Test Token", "TEST"); + } +} diff --git a/packages/contracts-bedrock/test/L2/NativeAssetLiquidity.t.sol b/packages/contracts-bedrock/test/L2/NativeAssetLiquidity.t.sol new file mode 100644 index 0000000000000..2b5869b556596 --- /dev/null +++ b/packages/contracts-bedrock/test/L2/NativeAssetLiquidity.t.sol @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; + +// Libraries +import { DevFeatures } from "src/libraries/DevFeatures.sol"; +import { NativeAssetLiquidity } from "src/L2/NativeAssetLiquidity.sol"; + +/// @title NativeAssetLiquidity_TestInit +/// @notice Reusable test initialization for `NativeAssetLiquidity` tests. +contract NativeAssetLiquidity_TestInit is CommonTest { + /// @notice Emitted when an address withdraws native asset liquidity. + event LiquidityWithdrawn(address indexed caller, uint256 value); + + /// @notice Emitted when an address deposits native asset liquidity. + event LiquidityDeposited(address indexed caller, uint256 value); + + /// @notice Emitted when an address funds the contract. + event LiquidityFunded(address indexed funder, uint256 value); + + /// @notice Test setup. + function setUp() public virtual override { + super.setUp(); + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + } +} + +/// @title NativeAssetLiquidity_Version_Test +/// @notice Tests the `version` function of the `NativeAssetLiquidity` contract. +contract NativeAssetLiquidity_Version_Test is NativeAssetLiquidity_TestInit { + /// @notice Tests that the `version` function returns the correct string. We avoid testing the + /// specific value of the string as it changes frequently. + function test_version_succeeds() public view { + assert(bytes(nativeAssetLiquidity.version()).length > 0); + } +} + +/// @title NativeAssetLiquidity_Deposit_Test +/// @notice Tests the `deposit` function of the `NativeAssetLiquidity` contract. +contract NativeAssetLiquidity_Deposit_Test is NativeAssetLiquidity_TestInit { + /// @notice Tests that the deposit function can be called by the authorized caller. + /// @param _amount Amount of native asset (in wei) to call the deposit function with. + function testFuzz_deposit_fromAuthorizedCaller_succeeds(uint256 _amount) public { + _amount = bound(_amount, 0, type(uint248).max); + + // Deal the LiquidityController with the amount to deposit + vm.deal(address(liquidityController), _amount); + uint256 nativeAssetBalanceBefore = address(nativeAssetLiquidity).balance; + + // Expect emit LiquidityDeposited event + vm.expectEmit(address(nativeAssetLiquidity)); + emit LiquidityDeposited(address(liquidityController), _amount); + + // Call the deposit function with LiquidityController as the caller + vm.prank(address(liquidityController)); + nativeAssetLiquidity.deposit{ value: _amount }(); + + // Assert LiquidityController and NativeAssetLiquidity balances are updated correctly + assertEq(address(liquidityController).balance, 0); + assertEq(address(nativeAssetLiquidity).balance, nativeAssetBalanceBefore + _amount); + } + + /// @notice Tests that the deposit function always reverts when called by an unauthorized caller. + /// @param _amount Amount of native asset (in wei) to call the deposit function with. + /// @param _caller Address of the caller to call the deposit function with. + function testFuzz_deposit_fromUnauthorizedCaller_fails(uint256 _amount, address _caller) public { + vm.assume(_caller != address(liquidityController)); + _amount = bound(_amount, 0, type(uint248).max); + + // Deal the unauthorized caller with the amount to deposit + vm.deal(_caller, _amount); + uint256 nativeAssetBalanceBefore = address(nativeAssetLiquidity).balance; + + // Call the deposit function with unauthorized caller + vm.prank(_caller); + // Expect revert with Unauthorized + vm.expectRevert(NativeAssetLiquidity.NativeAssetLiquidity_Unauthorized.selector); + nativeAssetLiquidity.deposit{ value: _amount }(); + + // Assert caller and NativeAssetLiquidity balances remain unchanged + assertEq(_caller.balance, _amount); + assertEq(address(nativeAssetLiquidity).balance, nativeAssetBalanceBefore); + } +} + +/// @title NativeAssetLiquidity_Withdraw_Test +/// @notice Tests the `withdraw` function of the `NativeAssetLiquidity` contract. +contract NativeAssetLiquidity_Withdraw_Test is NativeAssetLiquidity_TestInit { + /// @notice Tests that the withdraw function can be called by the authorized caller. + /// @param _amount Amount of native asset (in wei) to call the withdraw function with. + function testFuzz_withdraw_fromAuthorizedCaller_succeeds(uint256 _amount) public { + _amount = bound(_amount, 1, type(uint248).max); + + // Deal NativeAssetLiquidity with the amount to withdraw + vm.deal(address(nativeAssetLiquidity), _amount); + uint256 nativeAssetBalanceBefore = address(nativeAssetLiquidity).balance; + uint256 controllerBalanceBefore = address(liquidityController).balance; + + // Expect emit LiquidityWithdrawn event + vm.expectEmit(address(nativeAssetLiquidity)); + emit LiquidityWithdrawn(address(liquidityController), _amount); + vm.prank(address(liquidityController)); + nativeAssetLiquidity.withdraw(_amount); + + // Assert LiquidityController and NativeAssetLiquidity balances are updated correctly + assertEq(address(liquidityController).balance, controllerBalanceBefore + _amount); + assertEq(address(nativeAssetLiquidity).balance, nativeAssetBalanceBefore - _amount); + } + + /// @notice Tests that the withdraw function always reverts when called by an unauthorized caller. + /// @param _amount Amount of native asset (in wei) to call the withdraw function with. + /// @param _caller Address of the caller to call the withdraw function with. + function testFuzz_withdraw_fromUnauthorizedCaller_fails(uint256 _amount, address _caller) public { + vm.assume(_caller != address(liquidityController)); + _amount = bound(_amount, 1, type(uint248).max); + + // Deal NativeAssetLiquidity with the amount to withdraw + vm.deal(address(nativeAssetLiquidity), _amount); + uint256 nativeAssetBalanceBefore = address(nativeAssetLiquidity).balance; + uint256 callerBalanceBefore = _caller.balance; + + // Call the withdraw function with unauthorized caller + vm.prank(_caller); + // Expect revert with Unauthorized + vm.expectRevert(NativeAssetLiquidity.NativeAssetLiquidity_Unauthorized.selector); + nativeAssetLiquidity.withdraw(_amount); + + // Assert caller and NativeAssetLiquidity balances remain unchanged + assertEq(_caller.balance, callerBalanceBefore); + assertEq(address(nativeAssetLiquidity).balance, nativeAssetBalanceBefore); + } + + /// @notice Tests that the withdraw function reverts when contract has insufficient balance. + function test_withdraw_insufficientBalance_fails() public { + // Try to withdraw more than available balance + uint256 contractBalance = address(nativeAssetLiquidity).balance; + uint256 amount = bound(contractBalance, contractBalance + 1, type(uint256).max); + + // Call the withdraw function with insufficient balance + vm.prank(address(liquidityController)); + // Expect revert with NativeAssetLiquidity_InsufficientBalance + vm.expectRevert(NativeAssetLiquidity.NativeAssetLiquidity_InsufficientBalance.selector); + nativeAssetLiquidity.withdraw(amount); + + // Assert contract and controller balances remain unchanged + assertEq(address(nativeAssetLiquidity).balance, contractBalance); + assertEq(address(liquidityController).balance, 0); + } +} diff --git a/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol index 55c5a7eb72991..ab808f1bac122 100644 --- a/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol +++ b/packages/contracts-bedrock/test/L2/SequencerFeeVault.t.sol @@ -14,6 +14,7 @@ import { Hashing } from "src/libraries/Hashing.sol"; import { Types } from "src/libraries/Types.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; /// @title SequencerFeeVault_TestInit /// @notice Reusable test initialization for `SequencerFeeVault` tests. @@ -37,8 +38,8 @@ contract SequencerFeeVault_Constructor_Test is SequencerFeeVault_TestInit { assertEq(sequencerFeeVault.recipient(), recipient); assertEq(sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount()); assertEq(sequencerFeeVault.minWithdrawalAmount(), deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount()); - assertEq(uint8(sequencerFeeVault.WITHDRAWAL_NETWORK()), uint8(Types.WithdrawalNetwork.L1)); - assertEq(uint8(sequencerFeeVault.withdrawalNetwork()), uint8(Types.WithdrawalNetwork.L1)); + assertEq(uint8(sequencerFeeVault.WITHDRAWAL_NETWORK()), deploy.cfg().sequencerFeeVaultWithdrawalNetwork()); + assertEq(uint8(sequencerFeeVault.withdrawalNetwork()), deploy.cfg().sequencerFeeVaultWithdrawalNetwork()); } } @@ -96,6 +97,7 @@ contract SequencerFeeVault_Withdraw_Test is SequencerFeeVault_TestInit { /// @notice Tests that `withdraw` successfully initiates a withdrawal to L1. function test_withdraw_toL1_succeeds() external { + skipIfDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN); uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT() + 1; vm.deal(address(sequencerFeeVault), amount); @@ -105,7 +107,12 @@ contract SequencerFeeVault_Withdraw_Test is SequencerFeeVault_TestInit { vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET)); emit Withdrawal(address(sequencerFeeVault).balance, recipient, address(this)); vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET)); - emit Withdrawal(address(sequencerFeeVault).balance, recipient, address(this), Types.WithdrawalNetwork.L1); + emit Withdrawal( + address(sequencerFeeVault).balance, + recipient, + address(this), + Types.WithdrawalNetwork(deploy.cfg().sequencerFeeVaultWithdrawalNetwork()) + ); // The entire vault's balance is withdrawn vm.expectCall(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(sequencerFeeVault).balance, hex""); diff --git a/packages/contracts-bedrock/test/L2/WETH.t.sol b/packages/contracts-bedrock/test/L2/WETH.t.sol index 4b1cfa1751d13..694183115e0a0 100644 --- a/packages/contracts-bedrock/test/L2/WETH.t.sol +++ b/packages/contracts-bedrock/test/L2/WETH.t.sol @@ -16,7 +16,7 @@ contract WETH_Name_Test is CommonTest { /// @notice Tests that the `name` function returns 'Wrapped Ether' by default. function test_name_ether_succeeds() external view { - assertEq("Wrapped Ether", weth.name()); + assertEq(string.concat("Wrapped ", l1Block.gasPayingTokenName()), weth.name()); } } @@ -34,6 +34,6 @@ contract WETH_Symbol_Test is CommonTest { /// @notice Tests that the `symbol` function returns 'WETH' by default. function test_symbol_ether_succeeds() external view { - assertEq("WETH", weth.symbol()); + assertEq(string.concat("W", l1Block.gasPayingTokenSymbol()), weth.symbol()); } } diff --git a/packages/contracts-bedrock/test/bridgeRevert/L1Bridge.t.sol b/packages/contracts-bedrock/test/bridgeRevert/L1Bridge.t.sol new file mode 100644 index 0000000000000..1be83be74551c --- /dev/null +++ b/packages/contracts-bedrock/test/bridgeRevert/L1Bridge.t.sol @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import { IL1CrossDomainMessenger } from "../../interfaces/L1/IL1CrossDomainMessenger.sol"; +import { IL1StandardBridge } from "../../interfaces/L1/IL1StandardBridge.sol"; +import { CommonBase } from "../../lib/forge-std/src/Base.sol"; +import { StdAssertions } from "../../lib/forge-std/src/StdAssertions.sol"; +import { StdChains } from "../../lib/forge-std/src/StdChains.sol"; +import { StdCheats, StdCheatsSafe } from "../../lib/forge-std/src/StdCheats.sol"; +import { StdUtils } from "../../lib/forge-std/src/StdUtils.sol"; +import { Test } from "../../lib/forge-std/src/Test.sol"; +import { TestERC20 } from "../mocks/TestERC20.sol"; +import { TestERC721 } from "../mocks/TestERC721.sol"; +import { IL1ERC721Bridge } from "../../interfaces/L1/IL1ERC721Bridge.sol"; + +contract L1Bridge_Test is Test { + TestERC20 token; + TestERC721 token721; + uint256 l1Fork; + address testAlice; + address testBob; + IL1StandardBridge internal l1StandardBridge; + IL1CrossDomainMessenger internal l1CrossDomainMessenger; + IL1ERC721Bridge internal l1ERC721Bridge; + + function setUp() public { + testAlice = makeAddr("testAlice"); + testBob = makeAddr("testBob"); + l1Fork = vm.createSelectFork("http://localhost:8545"); + token = new TestERC20(); + token721 = new TestERC721(); + token.mint(testAlice, 1000); + token721.mint(testAlice, 1); + vm.deal(testAlice, 1000 ether); + vm.deal(testBob, 1000 ether); + vm.label(testAlice, "testAlice"); + vm.label(testBob, "testBob"); + string memory stateJson = vm.readFile("../../test/config-op/state.json"); + + address l1StandardBridgeProxy = vm.parseJsonAddress(stateJson, ".opChainDeployments[0].L1StandardBridgeProxy"); + address l1CrossDomainMessengerProxy = + vm.parseJsonAddress(stateJson, ".opChainDeployments[0].L1CrossDomainMessengerProxy"); + address l1ERC721BridgeProxy = vm.parseJsonAddress(stateJson, ".opChainDeployments[0].L1Erc721BridgeProxy"); + l1StandardBridge = IL1StandardBridge(payable(l1StandardBridgeProxy)); + l1CrossDomainMessenger = IL1CrossDomainMessenger(l1CrossDomainMessengerProxy); + l1ERC721Bridge = IL1ERC721Bridge(l1ERC721BridgeProxy); + } + + function test_sendETH_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + address(l1StandardBridge).call{ value: 1 ether }(""); + } + + function test_depositETH_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1StandardBridge.depositETH(100000, hex""); + } + + function test_depositETHTo_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1StandardBridge.depositETHTo(testBob, 100000, hex""); + } + + function test_depositERC20_reverts() public { + vm.prank(testAlice, testAlice); + token.approve(address(l1StandardBridge), 1); + + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1StandardBridge.depositERC20(address(token), address(token), 1000, 100000, hex""); + } + + function test_depositERC20To_reverts() public { + // Approve bridge to spend tokens + vm.prank(testAlice, testAlice); + token.approve(address(l1StandardBridge), 1); + + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1StandardBridge.depositERC20To( + address(token), + address(token), + testBob, + 1, + 200000, // minGasLimit + "" // extraData + ); + } + + function test_finalizeETHWithdrawal_reverts() public { + vm.expectRevert("not allow bridge"); + l1StandardBridge.finalizeETHWithdrawal{ value: 1 ether }(testAlice, testBob, 1 ether, ""); + } + + function test_finalizeERC20Withdrawal_reverts() public { + vm.expectRevert("not allow bridge"); + l1StandardBridge.finalizeERC20Withdrawal(address(token), address(token), testAlice, testBob, 1, ""); + } + + function test_bridgeETH_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1StandardBridge.bridgeETH{ value: 1 ether }( + 200000, // minGasLimit + "" // extraData + ); + } + + function test_bridgeETHTo_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1StandardBridge.bridgeETHTo(testBob, 100000, hex""); + } + + function test_bridgeERC20_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1StandardBridge.bridgeERC20(address(token), address(token), 1, 200000, hex""); + } + + function test_bridgeERC20To_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1StandardBridge.bridgeERC20To(address(token), address(token), testBob, 1, 200000, hex""); + } + + function test_bridgeERC721_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1ERC721Bridge.bridgeERC721(address(token721), address(token721), 1, 200000, hex""); + } + + function test_bridgeERC721To_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l1ERC721Bridge.bridgeERC721To(address(token721), address(token721), testBob, 1, 200000, hex""); + } + + function test_finalizeBridgeERC20_reverts() public { + address messenger = address(l1StandardBridge.messenger()); + + // Mock + vm.mockCall( + messenger, + abi.encodeCall(l1CrossDomainMessenger.xDomainMessageSender, ()), + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) + ); + vm.expectRevert("not allow bridge"); + vm.prank(messenger, messenger); + l1StandardBridge.finalizeBridgeERC20(address(token), address(token), testAlice, testBob, 1, hex""); + } + + function test_finalizeBridgeETH_reverts() public { + address messenger = address(l1StandardBridge.messenger()); + + vm.mockCall( + messenger, + abi.encodeCall(l1CrossDomainMessenger.xDomainMessageSender, ()), + abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) + ); + + vm.startPrank(messenger); + vm.expectRevert("not allow bridge"); + l1StandardBridge.finalizeBridgeETH(testAlice, testBob, 1 ether, hex""); + vm.stopPrank(); + } +} diff --git a/packages/contracts-bedrock/test/bridgeRevert/L2Bridge.t.sol b/packages/contracts-bedrock/test/bridgeRevert/L2Bridge.t.sol new file mode 100644 index 0000000000000..68e691d86a65d --- /dev/null +++ b/packages/contracts-bedrock/test/bridgeRevert/L2Bridge.t.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.10; + +import { CommonBase } from "../../lib/forge-std/src/Base.sol"; +import { StdAssertions } from "../../lib/forge-std/src/StdAssertions.sol"; +import { StdChains } from "../../lib/forge-std/src/StdChains.sol"; +import { StdCheats, StdCheatsSafe } from "../../lib/forge-std/src/StdCheats.sol"; +import { StdUtils } from "../../lib/forge-std/src/StdUtils.sol"; +import { Test } from "../../lib/forge-std/src/Test.sol"; +import { TestERC20 } from "../mocks/TestERC20.sol"; +import { TestERC721 } from "../mocks/TestERC721.sol"; +import { IL2ERC721Bridge } from "../../interfaces/L2/IL2ERC721Bridge.sol"; +import { IL2StandardBridge } from "../../interfaces/L2/IL2StandardBridge.sol"; +import { IL2CrossDomainMessenger } from "../../interfaces/L2/IL2CrossDomainMessenger.sol"; + +contract L2Bridge_Test is Test { + TestERC20 token; + TestERC721 token721; + uint256 l2Fork; + address testAlice; + address testBob; + IL2StandardBridge internal l2StandardBridge; + IL2ERC721Bridge internal l2ERC721Bridge; + IL2CrossDomainMessenger internal l2CrossDomainMessenger; + + function setUp() public { + testAlice = makeAddr("testAlice"); + testBob = makeAddr("testBob"); + l2Fork = vm.createSelectFork("http://localhost:8123"); + token = new TestERC20(); + token721 = new TestERC721(); + token.mint(testAlice, 1000); + token721.mint(testAlice, 1); + vm.deal(testAlice, 1000 ether); + vm.deal(testBob, 1000 ether); + vm.label(testAlice, "testAlice"); + vm.label(testBob, "testBob"); + + address l2StandardBridgeProxy = 0x4200000000000000000000000000000000000010; + address l2CrossDomainMessengerProxy = 0x4200000000000000000000000000000000000007; + address l2ERC721BridgeProxy = 0x4200000000000000000000000000000000000014; + l2StandardBridge = IL2StandardBridge(payable(l2StandardBridgeProxy)); + l2CrossDomainMessenger = IL2CrossDomainMessenger(l2CrossDomainMessengerProxy); + l2ERC721Bridge = IL2ERC721Bridge(l2ERC721BridgeProxy); + } + + function test_sendETH_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + address(l2StandardBridge).call{ value: 1 ether }(""); + } + + function test_withdraw_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l2StandardBridge.withdraw(address(token), 1, 100000, hex""); + } + + function test_withdrawTo_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l2StandardBridge.withdrawTo(address(token), testBob, 1, 100000, hex""); + } + + function test_bridgeETH_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l2StandardBridge.bridgeETH{ value: 1 ether }(100000, hex""); + } + + function test_bridgeETHTo_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l2StandardBridge.bridgeETHTo(testBob, 100000, hex""); + } + + function test_bridgeERC20_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l2StandardBridge.bridgeERC20(address(token), address(token), 1, 100000, hex""); + } + + function test_bridgeERC20To_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l2StandardBridge.bridgeERC20To(address(token), address(token), testBob, 1, 100000, hex""); + } + + function test_bridgeERC721_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l2ERC721Bridge.bridgeERC721(address(token721), address(token721), 1, 100000, hex""); + } + + function test_bridgeERC721To_reverts() public { + vm.prank(testAlice, testAlice); + vm.expectRevert("not allow bridge"); + l2ERC721Bridge.bridgeERC721To(address(token721), address(token721), testBob, 1, 100000, hex""); + } + + function test_finalizeBridgeERC20_reverts() public { + address messenger = address(l2StandardBridge.messenger()); + + // Mock + vm.mockCall( + messenger, + abi.encodeCall(l2CrossDomainMessenger.xDomainMessageSender, ()), + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) + ); + vm.expectRevert("not allow bridge"); + vm.prank(messenger, messenger); + l2StandardBridge.finalizeBridgeERC20(address(token), address(token), testAlice, testBob, 1, hex""); + } + + function test_finalizeBridgeETH_reverts() public { + address messenger = address(l2StandardBridge.messenger()); + + vm.mockCall( + messenger, + abi.encodeCall(l2CrossDomainMessenger.xDomainMessageSender, ()), + abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) + ); + + vm.startPrank(messenger); + vm.expectRevert("not allow bridge"); + l2StandardBridge.finalizeBridgeETH(testAlice, testBob, 1 ether, hex""); + vm.stopPrank(); + } +} diff --git a/packages/contracts-bedrock/test/invariants/CustomGasToken.t.sol b/packages/contracts-bedrock/test/invariants/CustomGasToken.t.sol new file mode 100644 index 0000000000000..fe96f009e3023 --- /dev/null +++ b/packages/contracts-bedrock/test/invariants/CustomGasToken.t.sol @@ -0,0 +1,258 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing +import { StdUtils } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; +import { CommonTest } from "test/setup/CommonTest.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; + +// Contracts +import { ILiquidityController } from "interfaces/L2/ILiquidityController.sol"; +import { INativeAssetLiquidity } from "interfaces/L2/INativeAssetLiquidity.sol"; +import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; + +/// @title CGT_Minter +/// @notice An actor with the minter role (can mint and burn) +contract LiquidityController_Minter is StdUtils { + /// @notice The Vm contract. + Vm internal vm; + + /// @notice The LiquidityController contract. + ILiquidityController internal liquidityController; + + /// @notice The RandomActor contract. + RandomActor internal randomActor; + + /// @notice Ghost accounting + uint256 public totalAmountMinted; + uint256 public totalAmountBurned; + bool public deltaBalanceAndMint; // NativeAssetLiquidity balance change != amount minted? + bool public deltaBalanceAndBurn; // NativeAssetLiquidity balance change != amount burned? + + /// @param _vm The Vm contract. + /// @param _liquidityController The LiquidityController contract. + /// @param _randomActor The RandomActor contract. + constructor(Vm _vm, ILiquidityController _liquidityController, RandomActor _randomActor) { + vm = _vm; + liquidityController = _liquidityController; + randomActor = _randomActor; + } + + /// @notice Mint custom gas token to the random actor. + /// @param _amount The amount of CGT to mint. + /// @dev Accounting invariants are leveraging the balance difference between pre and post-condition + function mint(uint256 _amount) public { + // precondition: nil - update ghost variables + uint256 _preBalance = payable(Predeploys.NATIVE_ASSET_LIQUIDITY).balance; + + // action: mint to the random actor + liquidityController.mint(address(randomActor), _amount); + + // postcondition: is the NativeAssetLiquidity contract's balance changed by an amount different than minted? + deltaBalanceAndMint = _amount != (_preBalance - uint256(payable(Predeploys.NATIVE_ASSET_LIQUIDITY).balance)); + totalAmountMinted += _amount; + } + + /// @notice Burn custom gas token. + /// @param _amount The amount of CGT to burn, which is bounded to the actor's balance (avoid trivial revert) + /// @dev Accounting invariant are leveraging the balance difference between pre and post-condition + function burn(uint256 _amount) public { + // precondition: amount to burn has an upper bound (this contract's balance) + _amount = bound(_amount, 0, address(this).balance); + uint256 _preBalance = payable(Predeploys.NATIVE_ASSET_LIQUIDITY).balance; + + // action: burn _amount + liquidityController.burn{ value: _amount }(); + + // postcondition: update ghost variables by tracking an accounting difference + deltaBalanceAndBurn = _preBalance + _amount != uint256(payable(Predeploys.NATIVE_ASSET_LIQUIDITY).balance); + totalAmountBurned += _amount; + } + + /// @dev Receive needed to receive CGT from the random actor + receive() external payable { } +} + +/// @notice An actor which funds the NativeAssetLiquidity contract +/// @dev There is no underlying access control to this +contract NativeAssetLiquidity_Fundooor is StdUtils { + /// @notice The Vm contract. + Vm internal vm; + + /// @notice The NativeAssetLiquidity contract. + INativeAssetLiquidity internal nativeAssetLiquidity; + + /// @notice Ghost accounting + uint256 public totalAmountFunded; + + /// @param _vm The Vm contract. + constructor(Vm _vm) { + vm = _vm; + nativeAssetLiquidity = INativeAssetLiquidity(Predeploys.NATIVE_ASSET_LIQUIDITY); + } + + /// @notice Wrap fund() calls on the NativeAssetLiquidity contract. + /// @param _amount The amount of CGT to fund. + /// @dev The amount is bounded to the actor's balance (avoid trivial revert) + function fund(uint256 _amount) public { + // precondition: amount to fund has an upper bound (this contract's balance) + ghost accounting + _amount = bound(_amount, 0, address(this).balance); + + // action: fund _amount + vm.deal(address(nativeAssetLiquidity), _amount); + + // postcondition: nil here (in the invariant tests) + // update ghost variables + totalAmountFunded += _amount; + } + + receive() external payable { } +} + +/// @notice actor which receives fund and send them to either the minter or the funder actor, +/// keeping a closed loop (no vm.deal). It receive() function always revert, to insure mint()/safeSend is +/// always successfully sending the CGT. +contract RandomActor is StdUtils { + address internal liquidityController_Minter; + address internal nativeAssetLiquidity_Fundooor; + + /// @notice Flag to indicate if the actor has been called via receive() + bool public hasBeenCalled = false; + + /// @notice Error thrown when sending CGT to minter fails. + error RandomActor_SendCGTToMinterFailed(); + + /// @notice Error thrown when sending CGT to funder fails. + error RandomActor_SendCGTtoFunderFailed(); + + /// @notice Initialize the addresses of the minter and funder actors. + /// @param _liquidityController_Minter The address of the minter actor. + /// @param _nativeAssetLiquidity_Fundooor The address of the funder actor. + /// @dev This function selector is excluded from the invariant tests + function initAddresses(address _liquidityController_Minter, address _nativeAssetLiquidity_Fundooor) public { + liquidityController_Minter = _liquidityController_Minter; + nativeAssetLiquidity_Fundooor = _nativeAssetLiquidity_Fundooor; + } + + /// @notice Send CGT to the minter actor. + /// @param _amount The amount of CGT to send. + /// @dev The amount is bounded to the actor's balance (avoid trivial revert) + function sendCGTtoMinter(uint256 _amount) public { + // precondition: amount to send has an upper bound (this contract's balance) + uint256 _amountToSend = bound(_amount, 0, address(this).balance); + + // action: send _amountToSend to the minter actor + (bool success,) = payable(address(liquidityController_Minter)).call{ value: _amountToSend }(""); + + // postcondition: the call must succeed (test suite sanity check) + if (!success) revert RandomActor_SendCGTToMinterFailed(); + } + + /// @notice Send CGT to the funder actor. + /// @param _amount The amount of CGT to send. + /// @dev The amount is bounded to the actor's balance (avoid trivial revert) + function sendCGTtoFunder(uint256 _amount) public { + // precondition: amount to send has an upper bound (this contract's balance) + uint256 _amountToSend = bound(_amount, 0, address(this).balance); + + // action: send _amountToSend to the funder actor + (bool success,) = payable(address(nativeAssetLiquidity_Fundooor)).call{ value: _amountToSend }(""); + + // postcondition: the call must succeed (test suite sanity check) + if (!success) revert RandomActor_SendCGTtoFunderFailed(); + } + + /// @dev We track if the SafeSend triggers a logic on the receiver via a ghost variable + receive() external payable { + hasBeenCalled = true; + } + + fallback() external payable { + hasBeenCalled = true; + } +} + +/// @title ETHLiquidity_MintBurn_Invariant +/// @notice Invariant that checks that the NativeAssetLiquidity contract's balance is always equal +/// to the sum of the initial supply, the deposits, the funds, and minus the withdrawals. +/// NAL Balance = Initial Supply + Deposits + Funds - Withdrawals +contract CustomGasToken_Invariants_Test is CommonTest { + /// @notice Starting balance of the contract - arbitrary value (cf Config change) + uint256 internal constant STARTING_BALANCE = type(uint248).max / 5; + + LiquidityController_Minter internal actor_minter; + NativeAssetLiquidity_Fundooor internal actor_funder; + RandomActor internal randomActor; + + /// @notice Test setup. + function setUp() public override { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + super.setUp(); + + randomActor = new RandomActor(); + actor_funder = new NativeAssetLiquidity_Fundooor(vm); + actor_minter = new LiquidityController_Minter(vm, liquidityController, randomActor); + + // Initialize the addresses of the minter and funder actors + randomActor.initAddresses(address(actor_minter), address(actor_funder)); + + // Authorize the minter actor (simple access control in unit tests) + vm.prank(IProxyAdmin(Predeploys.PROXY_ADMIN).owner()); + liquidityController.authorizeMinter(address(actor_minter)); + + // Create the initial supply + vm.deal(address(nativeAssetLiquidity), STARTING_BALANCE); + + // Set the target contract. + targetContract(address(actor_minter)); + targetContract(address(actor_funder)); + + // Set the target selectors (exclude the initAddresses function) + bytes4[] memory selectors = new bytes4[](2); + selectors[0] = RandomActor.sendCGTtoMinter.selector; + selectors[1] = RandomActor.sendCGTtoFunder.selector; + FuzzSelector memory selector = FuzzSelector({ addr: address(randomActor), selectors: selectors }); + targetSelector(selector); + } + + /// @notice Invariant that checks that the NativeAssetLiquidity contract's balance is always equal + /// to the sum of the initial supply, the deposits, the funds, and minus the withdrawals. + /// NAL Balance = Initial Supply + Deposits + Funds - Withdrawals + /// @dev liquidityController.burn() calls deposit, liquidityController.mint() calls withdraw + function invariant_supplyConservation() public view { + assertEq( + address(nativeAssetLiquidity).balance, + STARTING_BALANCE + actor_funder.totalAmountFunded() + actor_minter.totalAmountBurned() + - actor_minter.totalAmountMinted(), + "NativeAssetLiquidity balance is not equal to the sum of the initial supply, the deposits, the funds, and minus the withdrawals" + ); + } + + /// @notice Invariant that checks that the minted amount is equal to the withdrawn amount + /// @dev Checks if the amount minted equals the amount transferred *outside* the NativeAssetLiquidity contract + function invariant_mintedEqualsWithdrawn() public view { + assertFalse(actor_minter.deltaBalanceAndMint(), "Minted amount is not equal to the withdrawn amount"); + } + + /// @notice Invariant that checks that the burned amount is equal to the deposited amount + /// @dev Checks if the amount burned equals the amount transferred *to* the NativeAssetLiquidity contract + function invariant_burnedEqualsDeposited() public view { + assertFalse(actor_minter.deltaBalanceAndBurn(), "Burned amount is not equal to the deposited amount"); + } + + /// @notice Invariant that checks that the LiquidityController contract's balance is always 0 + /// @dev Checks if the LiquidityController there is no CGT being trapped in the LiquidityController contract + function invariant_noDustLiquidityController() public view { + assertEq(address(liquidityController).balance, 0, "LiquidityController balance is not 0"); + } + + /// @notice Invariant that checks that the mint function never calls back to the RandomActor contract + /// @dev Checks if the mint function never calls back to the RandomActor contract (test SafeSend) + function invariant_mintNeverCallsBack() public view { + assertFalse(randomActor.hasBeenCalled(), "RandomActor receive() function has been triggered"); + } +} diff --git a/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol index 63d05ad7a4f94..f826e0262914a 100644 --- a/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/invariants/OptimismPortal2.t.sol @@ -14,6 +14,7 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol"; // Libraries import { Constants } from "src/libraries/Constants.sol"; import { Types } from "src/libraries/Types.sol"; +import { Features } from "src/libraries/Features.sol"; import "src/dispute/lib/Types.sol"; // Interfaces @@ -67,6 +68,11 @@ contract OptimismPortal2_Depositor is StdUtils, ResourceMetering { uint256 preDepositBalance = address(this).balance; uint256 value = bound(preDepositvalue, 0, preDepositBalance); + // If custom gas token is enabled, set deposit value to 0 + if (portal.systemConfig().isFeatureEnabled(Features.CUSTOM_GAS_TOKEN)) { + value = 0; + } + (, uint64 cachedPrevBoughtGas,) = ResourceMetering(address(portal)).params(); ResourceMetering.ResourceConfig memory rcfg = resourceConfig(); uint256 maxResourceLimit = uint64(rcfg.maxResourceLimit); @@ -106,6 +112,12 @@ contract OptimismPortal2_Invariant_Harness is DisputeGameFactory_TestInit { gasLimit: 100_000, data: hex"" }); + + // If custom gas token is enabled, set deposit value to 0 + if (systemConfig.isFeatureEnabled(Features.CUSTOM_GAS_TOKEN)) { + _defaultTx.value = 0; + } + // Get withdrawal proof data we can use for testing. (_stateRoot, _storageRoot, _outputRoot, _withdrawalHash, _withdrawalProof) = ffi.getProveWithdrawalTransactionInputs(_defaultTx); diff --git a/packages/contracts-bedrock/test/libraries/Predeploys.t.sol b/packages/contracts-bedrock/test/libraries/Predeploys.t.sol index bbce4e1d7d640..dc14ef4d9755c 100644 --- a/packages/contracts-bedrock/test/libraries/Predeploys.t.sol +++ b/packages/contracts-bedrock/test/libraries/Predeploys.t.sol @@ -9,6 +9,7 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { ForgeArtifacts } from "scripts/libraries/ForgeArtifacts.sol"; import { Fork } from "scripts/libraries/Config.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; /// @title Predeploys_TestInit /// @notice Reusable test initialization for `Predeploys` tests. @@ -23,6 +24,12 @@ contract Predeploys_TestInit is CommonTest { return _addr == Predeploys.L1_BLOCK_ATTRIBUTES || _addr == Predeploys.L2_STANDARD_BRIDGE; } + /// @notice Returns true if the address is a predeploy that has a different code in the + /// custom gas token mode. + function _customGasTokenCodeDiffer(address _addr) internal pure returns (bool) { + return _addr == Predeploys.L1_BLOCK_ATTRIBUTES || _addr == Predeploys.L2_TO_L1_MESSAGE_PASSER; + } + /// @notice Returns true if the account is not meant to be in the L2 genesis anymore. function _isOmitted(address _addr) internal pure returns (bool) { return _addr == Predeploys.L1_MESSAGE_SENDER; @@ -42,7 +49,7 @@ contract Predeploys_TestInit is CommonTest { } /// @notice Internal test function for predeploys validation across different forks. - function _test_predeploys(Fork _fork, bool _enableCrossL2Inbox) internal { + function _test_predeploys(Fork _fork, bool _enableCrossL2Inbox, bool _isCustomGasToken) internal { uint256 count = 2048; uint160 prefix = uint160(0x420) << 148; @@ -57,7 +64,8 @@ contract Predeploys_TestInit is CommonTest { continue; } - bool isPredeploy = Predeploys.isSupportedPredeploy(addr, uint256(_fork), _enableCrossL2Inbox); + bool isPredeploy = + Predeploys.isSupportedPredeploy(addr, uint256(_fork), _enableCrossL2Inbox, _isCustomGasToken); bytes memory code = addr.code; if (isPredeploy) assertTrue(code.length > 0); @@ -93,7 +101,7 @@ contract Predeploys_TestInit is CommonTest { string.concat("Implementation mismatch for ", vm.toString(addr)) ); assertNotEq(implAddr.code.length, 0, "predeploy implementation account must have code"); - if (!_usesImmutables(addr) && !_interopCodeDiffer(addr)) { + if (!_usesImmutables(addr) && !_interopCodeDiffer(addr) && !_customGasTokenCodeDiffer(addr)) { // can't check bytecode if it's modified with immutables in genesis. assertEq(implAddr.code, supposedCode, "proxy implementation contract should match contract source"); } @@ -133,7 +141,14 @@ contract Predeploys_Uncategorized_Test is Predeploys_TestInit { /// @notice Tests that the predeploy addresses are set correctly. They have code /// and the proxied accounts have the correct admin. function test_predeploys_succeeds() external { - _test_predeploys(Fork.ISTHMUS, false); + _test_predeploys(Fork.ISTHMUS, false, false); + } + + /// @notice Tests that the predeploy addresses are set correctly. They have code + /// and the proxied accounts have the correct admin. Using custom gas token. + function test_predeploys_customGasToken_succeeds() external { + skipIfDevFeatureDisabled(DevFeatures.CUSTOM_GAS_TOKEN); + _test_predeploys(Fork.ISTHMUS, false, true); } } @@ -150,12 +165,12 @@ contract Predeploys_UncategorizedInterop_Test is Predeploys_TestInit { /// @notice Tests that the predeploy addresses are set correctly. They have code and the /// proxied accounts have the correct admin. Using interop with inbox. function test_predeploysWithInbox_succeeds() external { - _test_predeploys(Fork.INTEROP, true); + _test_predeploys(Fork.INTEROP, true, false); } /// @notice Tests that the predeploy addresses are set correctly. They have code and the /// proxied accounts have the correct admin. Using interop without inbox. function test_predeploysWithoutInbox_succeeds() external { - _test_predeploys(Fork.INTEROP, false); + _test_predeploys(Fork.INTEROP, false, false); } } diff --git a/packages/contracts-bedrock/test/scripts/L2Genesis.t.sol b/packages/contracts-bedrock/test/scripts/L2Genesis.t.sol index 400f3285bf50b..843706aa3888a 100644 --- a/packages/contracts-bedrock/test/scripts/L2Genesis.t.sol +++ b/packages/contracts-bedrock/test/scripts/L2Genesis.t.sol @@ -15,6 +15,8 @@ import { IOptimismMintableERC721Factory } from "interfaces/L2/IOptimismMintableE import { IProxyAdmin } from "interfaces/universal/IProxyAdmin.sol"; import { IGovernanceToken } from "interfaces/governance/IGovernanceToken.sol"; import { IGasPriceOracle } from "interfaces/L2/IGasPriceOracle.sol"; +import { ILiquidityController } from "interfaces/L2/ILiquidityController.sol"; +import { INativeAssetLiquidity } from "interfaces/L2/INativeAssetLiquidity.sol"; /// @title L2Genesis_TestInit /// @notice Reusable test initialization for `L2Genesis` tests. @@ -23,12 +25,22 @@ contract L2Genesis_TestInit is Test { L2Genesis internal genesis; - function setUp() public { + function setUp() public virtual { genesis = new L2Genesis(); } function testProxyAdmin() internal view { + // Verify owner in the proxy assertEq(input.opChainProxyAdminOwner, IProxyAdmin(Predeploys.PROXY_ADMIN).owner()); + + // Verify owner in the implementation to catch storage shifting issues + // The implementation is stored in the code namespace + address proxyAdminImpl = Predeploys.predeployToCodeNamespace(Predeploys.PROXY_ADMIN); + assertEq( + input.opChainProxyAdminOwner, + IProxyAdmin(proxyAdminImpl).owner(), + "ProxyAdmin implementation owner should match expected" + ); } function testPredeploys() internal view { @@ -47,7 +59,7 @@ contract L2Genesis_TestInit is Test { assertEq(Predeploys.PROXY_ADMIN, EIP1967Helper.getAdmin(addr)); // If it's not a supported predeploy, skip next checks. - if (!Predeploys.isSupportedPredeploy(addr, uint256(LATEST_FORK), true)) { + if (!Predeploys.isSupportedPredeploy(addr, uint256(LATEST_FORK), true, input.useCustomGasToken)) { continue; } @@ -81,7 +93,14 @@ contract L2Genesis_TestInit is Test { function testGovernance() internal view { IGovernanceToken token = IGovernanceToken(payable(Predeploys.GOVERNANCE_TOKEN)); + + // Verify owner (existing check) assertEq(token.owner(), input.governanceTokenOwner); + + // Verify name and symbol to catch storage shifting issues + // These should match the values hardcoded in GovernanceToken constructor + assertEq(token.name(), "Optimism", "GovernanceToken name should be 'Optimism'"); + assertEq(token.symbol(), "OP", "GovernanceToken symbol should be 'OP'"); } function testFactories() internal view { @@ -102,12 +121,29 @@ contract L2Genesis_TestInit is Test { assertEq(gasPriceOracle.isFjord(), true); assertEq(gasPriceOracle.isIsthmus(), true); } + + function testCGT() internal view { + // Test LiquidityController deployment + ILiquidityController controller = ILiquidityController(Predeploys.LIQUIDITY_CONTROLLER); + assertEq(controller.gasPayingTokenName(), input.gasPayingTokenName); + assertEq(controller.gasPayingTokenSymbol(), input.gasPayingTokenSymbol); + + // Test NativeAssetLiquidity deployment and funding + INativeAssetLiquidity liquidity = INativeAssetLiquidity(Predeploys.NATIVE_ASSET_LIQUIDITY); + assertEq(address(liquidity).balance, type(uint248).max); + + // Verify predeploys have code + assertGt(Predeploys.LIQUIDITY_CONTROLLER.code.length, 0); + assertGt(Predeploys.NATIVE_ASSET_LIQUIDITY.code.length, 0); + } } /// @title L2Genesis_Run_Test /// @notice Tests the `run` function of the `L2Genesis` contract. contract L2Genesis_Run_Test is L2Genesis_TestInit { - function test_run_succeeds() external { + function setUp() public override { + super.setUp(); + // Set up default input configuration input = L2Genesis.Input({ l1ChainID: 1, l2ChainID: 2, @@ -128,8 +164,15 @@ contract L2Genesis_Run_Test is L2Genesis_TestInit { fork: uint256(LATEST_FORK), deployCrossL2Inbox: true, enableGovernance: true, - fundDevAccounts: true + fundDevAccounts: true, + useCustomGasToken: false, + gasPayingTokenName: "", + gasPayingTokenSymbol: "", + nativeAssetLiquidityAmount: type(uint248).max }); + } + + function test_run_succeeds() external { genesis.run(input); testProxyAdmin(); @@ -139,4 +182,58 @@ contract L2Genesis_Run_Test is L2Genesis_TestInit { testFactories(); testForks(); } + + /// @notice Helper function to configure input for CGT enabled tests. + function _setInputCGTEnabled() internal { + input.useCustomGasToken = true; + input.gasPayingTokenName = "Custom Gas Token"; + input.gasPayingTokenSymbol = "CGT"; + } + + /// @notice Tests that the run function succeeds when CGT is enabled. + /// @dev Tests that LiquidityController and NativeAssetLiquidity are deployed. + function test_run_cgt_succeeds() external { + _setInputCGTEnabled(); + genesis.run(input); + + testProxyAdmin(); + testPredeploys(); + testVaults(); + testGovernance(); + testFactories(); + testForks(); + testCGT(); + } + + /// @notice Tests that the run function reverts when CGT is enabled and sequencerFeeVault withdrawal network is L1. + function test_cgt_sequencerVault_reverts() external { + _setInputCGTEnabled(); + input.sequencerFeeVaultWithdrawalNetwork = 0; + vm.expectRevert("SequencerFeeVault: withdrawalNetwork type cannot be L1 when custom gas token is enabled"); + genesis.run(input); + } + + /// @notice Tests that the run function reverts when CGT is enabled and baseFeeVault withdrawal network is L1. + function test_cgt_baseFeeVault_reverts() external { + _setInputCGTEnabled(); + input.baseFeeVaultWithdrawalNetwork = 0; + vm.expectRevert("BaseFeeVault: withdrawalNetwork type cannot be L1 when custom gas token is enabled"); + genesis.run(input); + } + + /// @notice Tests that the run function reverts when CGT is enabled and l1FeeVault withdrawal network is L1. + function test_cgt_l1FeeVault_reverts() external { + _setInputCGTEnabled(); + input.l1FeeVaultWithdrawalNetwork = 0; + vm.expectRevert("L1FeeVault: withdrawalNetwork type cannot be L1 when custom gas token is enabled"); + genesis.run(input); + } + + /// @notice Tests that the run function reverts when nativeAssetLiquidityAmount exceeds type(uint248).max. + function test_cgt_liquidityAmount_reverts() external { + _setInputCGTEnabled(); + input.nativeAssetLiquidityAmount = uint256(type(uint248).max) + 1; + vm.expectRevert("L2Genesis: native asset liquidity amount must be less than or equal to type(uint248).max"); + genesis.run(input); + } } diff --git a/packages/contracts-bedrock/test/setup/CommonTest.sol b/packages/contracts-bedrock/test/setup/CommonTest.sol index a117be29a50b1..280a7326d1c25 100644 --- a/packages/contracts-bedrock/test/setup/CommonTest.sol +++ b/packages/contracts-bedrock/test/setup/CommonTest.sol @@ -14,6 +14,7 @@ import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; // Contracts import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { DevFeatures } from "src/libraries/DevFeatures.sol"; // Libraries import { console } from "forge-std/console.sol"; @@ -34,6 +35,7 @@ contract CommonTest is Test, Setup, Events { bool useAltDAOverride; bool useInteropOverride; + bool useCustomGasToken; /// @dev This value is only used in forked tests. During forked tests, the default is to perform the upgrade before /// running the tests. @@ -74,6 +76,16 @@ contract CommonTest is Test, Setup, Events { if (useUpgradedFork) { deploy.cfg().setUseUpgradedFork(true); } + if (isDevFeatureEnabled(DevFeatures.CUSTOM_GAS_TOKEN)) { + console.log("CommonTest: enabling custom gas token"); + deploy.cfg().setUseCustomGasToken(true); + deploy.cfg().setGasPayingTokenName("Custom Gas Token"); + deploy.cfg().setGasPayingTokenSymbol("CGT"); + deploy.cfg().setNativeAssetLiquidityAmount(type(uint248).max); + deploy.cfg().setBaseFeeVaultWithdrawalNetwork(1); + deploy.cfg().setL1FeeVaultWithdrawalNetwork(1); + deploy.cfg().setSequencerFeeVaultWithdrawalNetwork(1); + } if (isForkTest()) { // Skip any test suite which uses a nonstandard configuration. diff --git a/packages/contracts-bedrock/test/setup/FeatureFlags.sol b/packages/contracts-bedrock/test/setup/FeatureFlags.sol index 7ab1e36853909..0a53f92770564 100644 --- a/packages/contracts-bedrock/test/setup/FeatureFlags.sol +++ b/packages/contracts-bedrock/test/setup/FeatureFlags.sol @@ -44,6 +44,10 @@ contract FeatureFlags { console.log("Setup: DEV_FEATURE__DEPLOY_V2_DISPUTE_GAMES is enabled"); devFeatureBitmap |= DevFeatures.DEPLOY_V2_DISPUTE_GAMES; } + if (Config.devFeatureCustomGasToken()) { + console.log("Setup: DEV_FEATURE__CUSTOM_GAS_TOKEN is enabled"); + devFeatureBitmap |= DevFeatures.CUSTOM_GAS_TOKEN; + } } /// @notice Enables a feature. diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 4d6453932799e..b80c45e597e40 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -62,6 +62,8 @@ import { ISuperchainTokenBridge } from "interfaces/L2/ISuperchainTokenBridge.sol import { IPermissionedDisputeGame } from "interfaces/dispute/IPermissionedDisputeGame.sol"; import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; import { ICrossL2Inbox } from "interfaces/L2/ICrossL2Inbox.sol"; +import { ILiquidityController } from "interfaces/L2/ILiquidityController.sol"; +import { INativeAssetLiquidity } from "interfaces/L2/INativeAssetLiquidity.sol"; /// @title Setup /// @dev This contact is responsible for setting up the contracts in state. It currently @@ -146,6 +148,8 @@ contract Setup is FeatureFlags { ISuperchainTokenBridge superchainTokenBridge = ISuperchainTokenBridge(Predeploys.SUPERCHAIN_TOKEN_BRIDGE); IOptimismSuperchainERC20Factory l2OptimismSuperchainERC20Factory = IOptimismSuperchainERC20Factory(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY); + ILiquidityController liquidityController = ILiquidityController(Predeploys.LIQUIDITY_CONTROLLER); + INativeAssetLiquidity nativeAssetLiquidity = INativeAssetLiquidity(Predeploys.NATIVE_ASSET_LIQUIDITY); /// @notice Indicates whether a test is running against a forked production network. function isForkTest() public view returns (bool) { @@ -334,7 +338,11 @@ contract Setup is FeatureFlags { fork: uint256(l2Fork), deployCrossL2Inbox: deploy.cfg().useInterop(), enableGovernance: deploy.cfg().enableGovernance(), - fundDevAccounts: deploy.cfg().fundDevAccounts() + fundDevAccounts: deploy.cfg().fundDevAccounts(), + useCustomGasToken: deploy.cfg().useCustomGasToken(), + gasPayingTokenName: deploy.cfg().gasPayingTokenName(), + gasPayingTokenSymbol: deploy.cfg().gasPayingTokenSymbol(), + nativeAssetLiquidityAmount: deploy.cfg().nativeAssetLiquidityAmount() }) ); @@ -366,6 +374,8 @@ contract Setup is FeatureFlags { labelPredeploy(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY); labelPredeploy(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON); labelPredeploy(Predeploys.SUPERCHAIN_TOKEN_BRIDGE); + labelPredeploy(Predeploys.NATIVE_ASSET_LIQUIDITY); + labelPredeploy(Predeploys.LIQUIDITY_CONTROLLER); // L2 Preinstalls labelPreinstall(Preinstalls.MultiCall3); diff --git a/test-pp-op/0-all-local.sh b/test-pp-op/0-all-local.sh new file mode 100755 index 0000000000000..efa8aad44a6ea --- /dev/null +++ b/test-pp-op/0-all-local.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e + +# ./build_images.sh --all # build all images. add --force if want to force rebuild +make clean +cp local.env .env +./1-start-erigon.sh +./2-deploy-op-contracts.sh +./3-stop-erigon.sh +./4-migrate-op.sh +./5-start-op.sh +./6-build-op-program.sh +./7-setup-fraud-proof.sh diff --git a/test-pp-op/1-start-erigon.sh b/test-pp-op/1-start-erigon.sh new file mode 100755 index 0000000000000..00e95fd74e9b1 --- /dev/null +++ b/test-pp-op/1-start-erigon.sh @@ -0,0 +1,60 @@ +#!/bin/bash +set -e +set -x + +if ! [ -f .env ]; then + echo "need to provide .env file" +fi + +source .env +source tools.sh + +if [ "$ENV" = "local" ]; then + COMPOSE_FILE="docker-compose-local.yml" +else + COMPOSE_FILE="docker-compose.yml" +fi + +DOCKER_COMPOSE=$(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose") +DOCKER_COMPOSE_CMD="${DOCKER_COMPOSE} -f ${COMPOSE_FILE}" +echo ${DOCKER_COMPOSE_CMD} + +# 1. setup l1 +# 2. run & init erigon pp +start_local_xlayer_erigon() { + export ENV=local + make run_erigon + sleep 3 + # Calculate addresses for all actors + OP_BATCHER_ADDR=$(cast wallet a $OP_BATCHER_PRIVATE_KEY) + OP_PROPOSER_ADDR=$(cast wallet a $OP_PROPOSER_PRIVATE_KEY) + OP_CHALLENGER_ADDR=$(cast wallet a $OP_CHALLENGER_PRIVATE_KEY) + + # Wait for L1 node to finish syncing + while [[ "$(cast rpc eth_syncing --rpc-url $L1_RPC_URL)" != "false" ]]; do + echo "Waiting for node to finish syncing..." + sleep 1 + done + + # Fund all actor addresses + for addr in $OP_BATCHER_ADDR $OP_PROPOSER_ADDR $OP_CHALLENGER_ADDR; do + cast send --private-key $RICH_PRIVATE_KEY --value 100ether $addr --legacy --rpc-url $L1_RPC_URL + done +} + +setup_xlayer_erigon() { + if [ "$ENV" = "local" ]; then + echo "Starting local environment setup..." + start_local_xlayer_erigon + elif [ "$ENV" = "testnet" ]; then + echo "Starting ${ENV} environment setup..." + echo "not implemented" + exit 1 + else + echo "Starting ${ENV} environment setup..." + echo "not implemented" + exit 1 + fi +} + +setup_xlayer_erigon diff --git a/test-pp-op/2-deploy-op-contracts.sh b/test-pp-op/2-deploy-op-contracts.sh new file mode 100755 index 0000000000000..1ad0435cb2c9e --- /dev/null +++ b/test-pp-op/2-deploy-op-contracts.sh @@ -0,0 +1,455 @@ +#!/bin/bash +set -e +set -x + +source .env +source tools.sh +source utils.sh + +ROOT_DIR=$(git rev-parse --show-toplevel) + +# Set global OP_CONTRACTS_IMAGE_TAG based on environment +if [ "$ENV" = "local" ]; then + # Use local image tag for local environment + DOCKER_NETWORK_ARG="$DOCKER_NETWORK" +else + # Use cert image tag for non-local environments + DOCKER_NETWORK_ARG="host" +fi + +if [ -z "$CHAIN_ID" ]; then + echo "❌ ERROR: CHAIN_ID is not set. Set it explicitly or derive it from intent.toml before proceeding." + exit 1 +fi +if ! [[ "$CHAIN_ID" =~ ^[0-9]+$ ]]; then + echo "❌ ERROR: CHAIN_ID must be a numeric value, got: '$CHAIN_ID'" + exit 1 +fi + +cd $PWD_DIR + +deploy_safe() { + echo "=== Deploying Gnosis Safe ===" + + # Use deployer as single owner with threshold 1 + echo "Using deployer as single owner with threshold 1" + + # Execute Safe deployment + SAFE_DEPLOY_OUTPUT=$(docker run --rm \ + --network "$DOCKER_NETWORK" \ + -v "$(pwd)/$CONFIG_DIR:/deployments" \ + -e DEPLOYER_PRIVATE_KEY="$DEPLOYER_PRIVATE_KEY" \ + -w /app/packages/contracts-bedrock \ + "${OP_CONTRACTS_IMAGE_TAG}" \ + forge script --json --broadcast \ + --rpc-url $L1_RPC_URL_IN_DOCKER \ + --private-key $DEPLOYER_PRIVATE_KEY \ + scripts/deploy/DeploySimpleSafe.s.sol:DeploySimpleSafe) + + # Extract Safe address + SAFE_ADDRESS=$(echo "$SAFE_DEPLOY_OUTPUT" | jq -r '.logs[] | select(contains("New Safe L1ProxyAdminSafe deployed at:")) | split(": ")[1]' 2>/dev/null | head -1) + + if [ -z "$SAFE_ADDRESS" ] || [ "$SAFE_ADDRESS" = "null" ]; then + echo "❌ Failed to deploy Safe" + exit 1 + fi + + echo "✅ Safe deployed at: $SAFE_ADDRESS" + echo " Owner: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" + echo " Threshold: 1" + + # Update .env file + sed_inplace "s/SAFE_ADDRESS=.*/SAFE_ADDRESS=$SAFE_ADDRESS/" .env + source .env + echo " ✅ Updated SAFE_ADDRESS in .env: $SAFE_ADDRESS" +} + +deploy_transactor() { + # Deploy Transactor contract first + echo "🔧 Deploying Transactor contract..." + + # Debug: Show environment variables + echo "ENV: $ENV" + echo "CHAIN_ID: $CHAIN_ID" + echo "DOCKER_NETWORK: $DOCKER_NETWORK" + echo "L1_RPC_URL_IN_DOCKER: $L1_RPC_URL_IN_DOCKER" + echo "DEPLOYER_PRIVATE_KEY: ${DEPLOYER_PRIVATE_KEY:0:10}..." + echo "DEPLOYER_ADDRESS: $DEPLOYER_ADDRESS" + echo "OP_CONTRACTS_IMAGE_TAG: $OP_CONTRACTS_IMAGE_TAG" + + # Build docker run command with conditional network flag + DOCKER_ARGS=() + DOCKER_ARGS+=("--rm") + DOCKER_ARGS+=("-v" "$(pwd)/$CONFIG_DIR:/deployments") + DOCKER_ARGS+=("-w" "/app/packages/contracts-bedrock") + + if [ "$ENV" = "local" ]; then + DOCKER_ARGS+=("--network" "$DOCKER_NETWORK") + echo "✅ Using Docker network: $DOCKER_NETWORK" + else + DOCKER_ARGS+=("--network" "host") + echo "✅ Skipping Docker network (ENV=$ENV)" + fi + + DOCKER_ARGS+=("$OP_CONTRACTS_IMAGE_TAG") + + # Create the forge create command + FORGE_CMD="forge create --json --broadcast --legacy \ + --rpc-url $L1_RPC_URL_IN_DOCKER \ + --private-key $DEPLOYER_PRIVATE_KEY \ + src/periphery/Transactor.sol:Transactor.0.8.30 \ + --constructor-args $DEPLOYER_ADDRESS" + + echo "🔧 Executing Docker command..." + echo "Command: docker run ${DOCKER_ARGS[*]} $FORGE_CMD" + + TRANSACTOR_DEPLOY_OUTPUT=$(docker run "${DOCKER_ARGS[@]}" $FORGE_CMD) + + echo "Raw deployment output:" + echo "$TRANSACTOR_DEPLOY_OUTPUT" + echo "--- End of raw output ---" + + # Extract contract address from deployment output + TRANSACTOR_ADDRESS=$(echo "$TRANSACTOR_DEPLOY_OUTPUT" | jq -r '.deployedTo // empty' 2>/dev/null || echo "") + if [ -z "$TRANSACTOR_ADDRESS" ] || [ "$TRANSACTOR_ADDRESS" = "null" ]; then + echo "❌ Failed to extract Transactor contract address from deployment output" + echo "Deployment output: $TRANSACTOR_DEPLOY_OUTPUT" + echo "Trying to extract address manually..." + + # Try alternative extraction methods for forge output + TRANSACTOR_ADDRESS=$(echo "$TRANSACTOR_DEPLOY_OUTPUT" | jq -r '.deployedTo' 2>/dev/null || echo "") + if [ -z "$TRANSACTOR_ADDRESS" ]; then + TRANSACTOR_ADDRESS=$(echo "$TRANSACTOR_DEPLOY_OUTPUT" | grep -o '"deployedTo":"[^"]*"' | cut -d'"' -f4 || echo "") + fi + if [ -z "$TRANSACTOR_ADDRESS" ]; then + TRANSACTOR_ADDRESS=$(echo "$TRANSACTOR_DEPLOY_OUTPUT" | grep -o '0x[a-fA-F0-9]\{40\}' | head -1 || echo "") + fi + + if [ -z "$TRANSACTOR_ADDRESS" ]; then + echo "❌ Still failed to extract contract address" + exit 1 + else + echo "✅ Extracted address manually: $TRANSACTOR_ADDRESS" + fi + fi + + echo "✅ Transactor contract deployed at: $TRANSACTOR_ADDRESS" + + # Update .env file with Transactor address + sed_inplace "s/TRANSACTOR=.*/TRANSACTOR=$TRANSACTOR_ADDRESS/" .env + source .env + echo "✅ Updated TRANSACTOR address in .env: $TRANSACTOR_ADDRESS" +} + +# Bootstrapping superchain with op-deployer +# Output: after deploy, it will output `superchain.json` under config-op +# e.g. { +# "protocolVersionsImplAddress": "0x37e15e4d6dffa9e5e320ee1ec036922e563cb76c", +# "protocolVersionsProxyAddress": "0xfb5a7622e23e0f807b97a8ed608d50d56d202688", +# "superchainConfigImplAddress": "0xce28685eb204186b557133766eca00334eb441e4", +# "superchainConfigProxyAddress": "0x8c15b9d397b5bf29e114aebff0663fdd34976756", +# "proxyAdminAddress": "0x210879bec4c74c7e4e6df5e919f9525d75e15183" +# } +deploy_op_stack_bootstrap_superchain() { + source .env + echo "🔧 Bootstrapping superchain with op-deployer..." + + # Build docker run command with conditional network flag + DOCKER_ARGS=() + DOCKER_ARGS+=("-v" "$(pwd)/$CONFIG_DIR:/deployments") + DOCKER_ARGS+=("-w" "/app") + DOCKER_ARGS+=("-e" "CURL_CA_BUNDLE=") + DOCKER_ARGS+=("-e" "GIT_SSL_NO_VERIFY=true") + DOCKER_ARGS+=("-e" "NODE_TLS_REJECT_UNAUTHORIZED=0") + DOCKER_ARGS+=("-e" "GODEBUG=x509ignoreCN=1,x509ignoreUnknownCA=1,x509ignoreSystemRoots=1") + DOCKER_ARGS+=("--network" "$DOCKER_NETWORK_ARG") + + DOCKER_ARGS+=("$OP_CONTRACTS_IMAGE_TAG") + + BASH_CMD="set -e && /app/op-deployer/bin/op-deployer bootstrap superchain --l1-rpc-url $L1_RPC_URL_IN_DOCKER --private-key $DEPLOYER_PRIVATE_KEY --artifacts-locator file:///app/packages/contracts-bedrock/forge-artifacts --superchain-proxy-admin-owner $L1_PROXY_ADMIN_OWNER --protocol-versions-owner $ADMIN_OWNER_ADDRESS --guardian $ADMIN_OWNER_ADDRESS --outfile /deployments/superchain.json" + + docker run "${DOCKER_ARGS[@]}" bash -c "$BASH_CMD" +} + +deploy_op_stack_bootstrap_implementations() { + source .env + echo "🔧 Bootstrapping implementations with op-deployer..." + SUPERCHAIN_JSON="$CONFIG_DIR/superchain.json" + PROTOCOL_VERSIONS_PROXY=$(jq -r '.protocolVersionsProxyAddress' "$SUPERCHAIN_JSON") + SUPERCHAIN_CONFIG_PROXY=$(jq -r '.superchainConfigProxyAddress' "$SUPERCHAIN_JSON") + PROXY_ADMIN=$(jq -r '.proxyAdminAddress' "$SUPERCHAIN_JSON") + # Build docker run command with conditional network flag + DOCKER_ARGS=() + DOCKER_ARGS+=("-v" "$(pwd)/$CONFIG_DIR:/deployments") + DOCKER_ARGS+=("-w" "/app") + DOCKER_ARGS+=("-e" "CURL_CA_BUNDLE=") + DOCKER_ARGS+=("-e" "GIT_SSL_NO_VERIFY=true") + DOCKER_ARGS+=("-e" "NODE_TLS_REJECT_UNAUTHORIZED=0") + DOCKER_ARGS+=("--network" "$DOCKER_NETWORK_ARG") + + DOCKER_ARGS+=("$OP_CONTRACTS_IMAGE_TAG") + + # Build the base command + BASH_CMD="set -e && export CURL_CA_BUNDLE= && export GIT_SSL_NO_VERIFY=true && /app/op-deployer/bin/op-deployer bootstrap implementations --artifacts-locator file:///app/packages/contracts-bedrock/forge-artifacts --l1-rpc-url $L1_RPC_URL_IN_DOCKER --outfile /deployments/implementations.json --mips-version \"7\" --private-key $DEPLOYER_PRIVATE_KEY --protocol-versions-proxy $PROTOCOL_VERSIONS_PROXY --superchain-config-proxy $SUPERCHAIN_CONFIG_PROXY --superchain-proxy-admin $PROXY_ADMIN --upgrade-controller $ADMIN_OWNER_ADDRESS --challenger $CHALLENGER_ADDRESS --challenge-period-seconds $CHALLENGE_PERIOD_SECONDS --withdrawal-delay-seconds $WITHDRAWAL_DELAY_SECONDS --proof-maturity-delay-seconds $PROOF_MATURITY_DELAY_SECONDS --dispute-game-finality-delay-seconds $DISPUTE_GAME_FINALITY_DELAY_SECONDS" + + # Add dev-feature-bitmap only when CGT_ENABLED=true + if [ "$CGT_ENABLED" = "true" ]; then + BASH_CMD="$BASH_CMD --dev-feature-bitmap 0x0000000000000000000000000000000000000000000000000000000000001000" + fi + + docker run "${DOCKER_ARGS[@]}" bash -c "$BASH_CMD" + + # Update intent.toml + sed_inplace "s/l1ProxyAdminOwner = .*/l1ProxyAdminOwner = \"$L1_PROXY_ADMIN_OWNER\"/" "$CONFIG_DIR/intent.toml" + echo " ✅ Updated intent.toml with $OWNER_TYPE owner: $L1_PROXY_ADMIN_OWNER" + + # Read opcmAddress from implementations.json and write it into intent.toml + OPCM_ADDRESS=$(jq -r '.opcmAddress' ./config-op/implementations.json) + if [ -z "$OPCM_ADDRESS" ] || [ "$OPCM_ADDRESS" = "null" ]; then + echo "❌ Failed to read opcmAddress from implementations.json" + exit 1 + fi + + # Replace the opcmAddress field in intent.toml with the new value + sed_inplace "s/^opcmAddress = \".*\"/opcmAddress = \"$OPCM_ADDRESS\"/" ./config-op/intent.toml + echo "✅ Updated opcmAddress ($OPCM_ADDRESS) in intent.toml" +} + +deploy_op_stack_contracts() { + # Deploy contracts, TODO: should we need to modify source code to deploy contracts? + # Build docker run command with conditional network flag + DOCKER_ARGS=() + DOCKER_ARGS+=("-v" "$(pwd)/$CONFIG_DIR:/deployments") + DOCKER_ARGS+=("-w" "/app") + DOCKER_ARGS+=("-e" "CURL_CA_BUNDLE=") + DOCKER_ARGS+=("-e" "GIT_SSL_NO_VERIFY=true") + DOCKER_ARGS+=("-e" "NODE_TLS_REJECT_UNAUTHORIZED=0") + DOCKER_ARGS+=("--network" "$DOCKER_NETWORK_ARG") + + DOCKER_ARGS+=("$OP_CONTRACTS_IMAGE_TAG") + + BASH_CMD="set -e && export CURL_CA_BUNDLE= && export GIT_SSL_NO_VERIFY=true && echo '🔧 Starting contract deployment with op-deployer...' && echo '' && echo 'Deploy using op-deployer, wait for completion before proceeding' && /app/op-deployer/bin/op-deployer apply --workdir /deployments --private-key $DEPLOYER_PRIVATE_KEY --l1-rpc-url $L1_RPC_URL_IN_DOCKER && echo '' && echo '📄 Generating L2 genesis and rollup config...' && echo '' && echo 'Generate L2 genesis using op-deployer' && /app/op-deployer/bin/op-deployer inspect genesis --workdir /deployments $CHAIN_ID > /deployments/genesis.json && echo '' && echo 'Generate L2 rollup using op-node' && /app/op-deployer/bin/op-deployer inspect rollup --workdir /deployments $CHAIN_ID > /deployments/rollup.json && echo '' && echo '✅ Contract deployment completed successfully'" + + docker run "${DOCKER_ARGS[@]}" bash -c "$BASH_CMD" + + echo "genesis.json and rollup.json are generated in deployments folder" + echo "🎉 OP Stack deployment preparation completed!" +} + +deploy_custom_gas_token() { + echo "🔧 Setting up Custom Gas Token (CGT) configuration..." + echo "" + + # Extract parameters from intent.toml BEFORE changing directory + GAS_LIMIT=$(grep -E "^[[:space:]]*gasLimit[[:space:]]*=" "$CONFIG_DIR/intent.toml" | sed -E 's/^[[:space:]]*gasLimit[[:space:]]*=[[:space:]]*([0-9]+).*/\1/') + EIP1559_DENOMINATOR=$(grep -E "^[[:space:]]*eip1559Denominator[[:space:]]*=" "$CONFIG_DIR/intent.toml" | sed -E 's/^[[:space:]]*eip1559Denominator[[:space:]]*=[[:space:]]*([0-9]+).*/\1/') + EIP1559_ELASTICITY=$(grep -E "^[[:space:]]*eip1559Elasticity[[:space:]]*=" "$CONFIG_DIR/intent.toml" | sed -E 's/^[[:space:]]*eip1559Elasticity[[:space:]]*=[[:space:]]*([0-9]+).*/\1/') + + echo "📋 Configuration from intent.toml:" + echo " Gas Limit: $GAS_LIMIT" + echo " EIP1559 Denominator: $EIP1559_DENOMINATOR" + echo " EIP1559 Elasticity: $EIP1559_ELASTICITY" + echo "" + + # Validate extracted parameters + if [ -z "$GAS_LIMIT" ]; then + echo "❌ Failed to extract gasLimit from intent.toml" + exit 1 + fi + if [ -z "$EIP1559_DENOMINATOR" ]; then + echo "❌ Failed to extract eip1559Denominator from intent.toml" + exit 1 + fi + if [ -z "$EIP1559_ELASTICITY" ]; then + echo "❌ Failed to extract eip1559Elasticity from intent.toml" + exit 1 + fi + + SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].SystemConfigProxy' "$CONFIG_DIR/state.json") + OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy' "$CONFIG_DIR/state.json") + + if [ -z "$SYSTEM_CONFIG_PROXY_ADDRESS" ] || [ "$SYSTEM_CONFIG_PROXY_ADDRESS" = "null" ]; then + echo "❌ Failed to read systemConfigProxyAddress from state.json" + exit 1 + fi + if [ -z "$OPTIMISM_PORTAL_PROXY_ADDRESS" ] || [ "$OPTIMISM_PORTAL_PROXY_ADDRESS" = "null" ]; then + echo "❌ Failed to read optimismPortalProxyAddress from state.json" + exit 1 + fi + echo "📝 Running Foundry setup script for Custom Gas Token..." + + cd $ROOT_DIR/packages/contracts-bedrock + export SYSTEM_CONFIG_PROXY_ADDRESS=$SYSTEM_CONFIG_PROXY_ADDRESS + export OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS + export OKB_TOKEN_ADDRESS=$OKB_TOKEN_ADDRESS + export OKB_ADAPTER_OWNER_ADDRESS=$OKB_ADAPTER_OWNER_ADDRESS + + FORGE_OUTPUT=$(forge script scripts/SetupCustomGasToken.s.sol:SetupCustomGasToken \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" \ + --broadcast 2>&1) + + echo "$FORGE_OUTPUT" + + # Extract contract addresses from forge output + ADAPTER_ADDRESS=$(echo "$FORGE_OUTPUT" | grep "DepositedOKBAdapter deployed at:" | awk '{print $NF}') + + # Query initial OKB total supply + INIT_TOTAL_SUPPLY=$(cast call "$OKB_TOKEN_ADDRESS" "totalSupply()(uint256)" --rpc-url "$L1_RPC_URL") + echo "" + echo "📊 Initial OKB Total Supply: $INIT_TOTAL_SUPPLY" + + echo "" + echo "✅ L1 Custom Gas Token setup complete!" + echo "📋 Deployed Contract Addresses:" + echo "" + echo " OKB Token: $OKB_TOKEN_ADDRESS" + echo " Adapter: $ADAPTER_ADDRESS" + echo "" + + # Set gas config to 0 for custom gas token (Ecotone upgrade) + echo "🔧 Setting gas config for Ecotone (Custom Gas Token)..." + cast send "$SYSTEM_CONFIG_PROXY_ADDRESS" \ + "setGasConfigEcotone(uint32,uint32)" \ + 0 \ + 0 \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" + echo "✅ Gas config set to (0, 0) for Custom Gas Token" + echo "" + + # Set gas limit + echo "🔧 Setting gas limit to $GAS_LIMIT..." + cast send "$SYSTEM_CONFIG_PROXY_ADDRESS" \ + "setGasLimit(uint64)" \ + "$GAS_LIMIT" \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" + echo "✅ Gas limit set successfully" + echo "" + + # Set EIP-1559 parameters + echo "🔧 Setting EIP-1559 parameters (denominator: $EIP1559_DENOMINATOR, elasticity: $EIP1559_ELASTICITY)..." + cast send "$SYSTEM_CONFIG_PROXY_ADDRESS" \ + "setEIP1559Params(uint32,uint32)" \ + "$EIP1559_DENOMINATOR" \ + "$EIP1559_ELASTICITY" \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" + echo "✅ EIP-1559 parameters set successfully" + echo "" + + # Transfer SystemConfig ownership + echo "🔧 Transferring SystemConfig ownership..." + echo "" + + # Check current owner + CURRENT_OWNER=$(cast call "$SYSTEM_CONFIG_PROXY_ADDRESS" "owner()(address)" --rpc-url "$L1_RPC_URL") + echo "📋 Current SystemConfig owner: $CURRENT_OWNER" + echo "📋 Target owner: $SYSTEM_CONFIG_OWNER_ADDRESS" + + if [ "$CURRENT_OWNER" != "$SYSTEM_CONFIG_OWNER_ADDRESS" ]; then + echo "🔄 Transferring ownership to $SYSTEM_CONFIG_OWNER_ADDRESS..." + + cast send "$SYSTEM_CONFIG_PROXY_ADDRESS" \ + "transferOwnership(address)" \ + "$SYSTEM_CONFIG_OWNER_ADDRESS" \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" + + # Verify transfer + NEW_OWNER=$(cast call "$SYSTEM_CONFIG_PROXY_ADDRESS" "owner()(address)" --rpc-url "$L1_RPC_URL") + echo "✅ SystemConfig ownership transferred to: $NEW_OWNER" + else + echo "✅ SystemConfig already owned by $SYSTEM_CONFIG_OWNER_ADDRESS" + fi + echo "" + + # Set init bond for game type 1 + set_init_bond + + # Transfer Transactor ownership + echo "🔧 Transferring Transactor ownership..." + echo "" + + # Check current Transactor owner + CURRENT_TRANSACTOR_OWNER=$(cast call "$TRANSACTOR_ADDRESS" "owner()(address)" --rpc-url "$L1_RPC_URL") + echo "📋 Current Transactor owner: $CURRENT_TRANSACTOR_OWNER" + echo "📋 Target owner: $ADMIN_OWNER_ADDRESS" + + if [ "$CURRENT_TRANSACTOR_OWNER" != "$ADMIN_OWNER_ADDRESS" ]; then + echo "🔄 Transferring Transactor ownership to $ADMIN_OWNER_ADDRESS..." + + cast send "$TRANSACTOR_ADDRESS" \ + "setOwner(address)" \ + "$ADMIN_OWNER_ADDRESS" \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" + + # Verify transfer + NEW_TRANSACTOR_OWNER=$(cast call "$TRANSACTOR_ADDRESS" "owner()(address)" --rpc-url "$L1_RPC_URL") + echo "✅ Transactor ownership transferred to: $NEW_TRANSACTOR_OWNER" + else + echo "✅ Transactor already owned by $ADMIN_OWNER_ADDRESS" + fi + echo "" + +} + +set_init_bond() { + echo "🔧 Setting init bond for game type 1..." + echo "" + + # Get DisputeGameFactory address from state.json + DISPUTE_GAME_FACTORY_ADDRESS=$(cat $ROOT_DIR/test-pp-op/config-op/state.json | jq -r '.opChainDeployments[0].DisputeGameFactoryProxy') + echo "📋 DisputeGameFactory Address: $DISPUTE_GAME_FACTORY_ADDRESS" + + # Set init bond using the script + bash $ROOT_DIR/test-pp-op/scripts/set-init-bond.sh \ + --game-type 1 \ + --init-bond $INITIAL_BOND \ + --transactor $TRANSACTOR_ADDRESS \ + --dispute-game-factory $DISPUTE_GAME_FACTORY_ADDRESS \ + --private-key $DEPLOYER_PRIVATE_KEY \ + --rpc-url $L1_RPC_URL + + echo "" +} + +echo "CGT_ENABLED: ${CGT_ENABLED}" + +cp ./config-op/intent.${ENV}.toml.bak ./config-op/intent.toml +cp ./config-op/state.json.bak ./config-op/state.json + +CHAIN_ID_UINT256=$(cast to-uint256 $CHAIN_ID) +sed_inplace 's/id = .*/id = "'"$CHAIN_ID_UINT256"'"/' ./config-op/intent.toml +echo " ✅ Updated chain id in intent.toml: $CHAIN_ID_UINT256" + +# Validate OWNER_TYPE configuration +if [ "$OWNER_TYPE" != "transactor" ] && [ "$OWNER_TYPE" != "safe" ]; then + echo "❌ Error: Invalid OWNER_TYPE '$OWNER_TYPE'. Must be 'transactor' or 'safe'" + exit 1 +fi + +echo "=== Deploying with OWNER_TYPE: $OWNER_TYPE ===" + +# Deploy owner contract based on OWNER_TYPE +if [ "$OWNER_TYPE" = "safe" ]; then + echo "🔧 Deploying Gnosis Safe for l1ProxyAdminOwner..." + deploy_safe + L1_PROXY_ADMIN_OWNER=$SAFE_ADDRESS +elif [ "$OWNER_TYPE" = "transactor" ]; then + echo "🔧 Deploying Transactor for l1ProxyAdminOwner..." + deploy_transactor + L1_PROXY_ADMIN_OWNER=$TRANSACTOR_ADDRESS +fi + +echo "Using $OWNER_TYPE as l1ProxyAdminOwner: $L1_PROXY_ADMIN_OWNER" + +deploy_op_stack_bootstrap_superchain +deploy_op_stack_bootstrap_implementations +deploy_op_stack_contracts + +if [ "$CGT_ENABLED" = "true" ]; then + deploy_custom_gas_token +fi diff --git a/test-pp-op/3-stop-erigon.sh b/test-pp-op/3-stop-erigon.sh new file mode 100755 index 0000000000000..5a6b2845f2b53 --- /dev/null +++ b/test-pp-op/3-stop-erigon.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -x +set -e +source .env +source tools.sh +source utils.sh + +cd $PWD_DIR + +## Stop X Layer services +echo "DOCKER_COMPOSE_CMD: ${DOCKER_COMPOSE_CMD}" +${DOCKER_COMPOSE_CMD} stop xlayer-seq +#${DOCKER_COMPOSE_CMD} stop xlayer-rpc +${DOCKER_COMPOSE_CMD} stop xlayer-bridge-service +${DOCKER_COMPOSE_CMD} stop xlayer-bridge-ui +${DOCKER_COMPOSE_CMD} stop xlayer-agg-sender + +# Get fork block number and parent hash +LOG_OUTPUT=$(docker logs xlayer-seq 2>&1) +FORK_BLOCK=$(echo "$LOG_OUTPUT" | grep "Finish block" | tail -1 | sed -n 's/.*Finish block \([0-9]*\) with.*/\1/p') + +echo "FORK_BLOCK=$FORK_BLOCK" + +sed_inplace "s/FORK_BLOCK=.*/FORK_BLOCK=$((FORK_BLOCK+1))/" .env +PARENT_HASH=$(echo "$LOG_OUTPUT" | grep "RPC Daemon notified of new headers" | tail -1 | sed -n 's/.*hash=\([0-9a-fx]*\) .*/\1/p') +echo "PARENT_HASH=$PARENT_HASH" +sed_inplace "s/PARENT_HASH=.*/PARENT_HASH=$PARENT_HASH/" .env diff --git a/test-pp-op/4-migrate-op.sh b/test-pp-op/4-migrate-op.sh new file mode 100755 index 0000000000000..b34624e272506 --- /dev/null +++ b/test-pp-op/4-migrate-op.sh @@ -0,0 +1,209 @@ +#!/bin/bash +set -e + +# Debug mode - set to true to enable verbose output +DEBUG=${DEBUG:-false} + +if [ "$DEBUG" = "true" ]; then + set -x +fi + +source .env +source tools.sh +source utils.sh + +prepare() { + # Check required files exist + if [ ! -f "./config-op/genesis.json" ]; then + echo "❌ ERROR: ./config-op/genesis.json not found!" + exit 1 + fi + + if [ ! -f "./config-op/rollup.json" ]; then + echo "❌ ERROR: ./config-op/rollup.json not found!" + exit 1 + fi + + cp ./config-op/genesis.json ./config-op/genesis-op-raw.json + cp ./config-op/genesis.json ./config-op/genesis-op-before-number.json + cp ./config-op/genesis.json ./config-op/genesis-op-after-number.json + + # Extract contract addresses from state.json and update .env file + echo "🔧 Extracting contract addresses from state.json..." + STATE_JSON="$PWD_DIR/config-op/state.json" + + if [ -f "$STATE_JSON" ]; then + # Extract contract addresses from state.json + DEPLOYMENTS_TYPE=$(jq -r 'type' "$STATE_JSON") + if [ "$DEPLOYMENTS_TYPE" = "object" ]; then + OPCD_TYPE=$(jq -r '.opChainDeployments | type' "$STATE_JSON" 2>/dev/null) + if [ "$OPCD_TYPE" = "object" ]; then + DISPUTE_GAME_FACTORY_ADDRESS=$(jq -r '.opChainDeployments.DisputeGameFactoryProxy // empty' "$STATE_JSON") + L2OO_ADDRESS=$(jq -r '.opChainDeployments.L2OutputOracleProxy // empty' "$STATE_JSON") + OPCM_IMPL_ADDRESS=$(jq -r '.appliedIntent.opcmAddress // empty' "$STATE_JSON") + SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments.SystemConfigProxy // empty' "$STATE_JSON") + PROXY_ADMIN=$(jq -r '.superchainContracts.SuperchainProxyAdminImpl // empty' "$STATE_JSON") + OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments.OptimismPortalProxy // empty' "$STATE_JSON") + elif [ "$OPCD_TYPE" = "array" ]; then + DISPUTE_GAME_FACTORY_ADDRESS=$(jq -r '.opChainDeployments[0].DisputeGameFactoryProxy // empty' "$STATE_JSON") + L2OO_ADDRESS=$(jq -r '.opChainDeployments[0].L2OutputOracleProxy // empty' "$STATE_JSON") + OPCM_IMPL_ADDRESS=$(jq -r '.appliedIntent.opcmAddress // empty' "$STATE_JSON") + SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].SystemConfigProxy // empty' "$STATE_JSON") + PROXY_ADMIN=$(jq -r '.superchainContracts.SuperchainProxyAdminImpl // empty' "$STATE_JSON") + OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy // empty' "$STATE_JSON") + else + DISPUTE_GAME_FACTORY_ADDRESS="" + L2OO_ADDRESS="" + OPCM_IMPL_ADDRESS="" + SYSTEM_CONFIG_PROXY_ADDRESS="" + PROXY_ADMIN="" + OPTIMISM_PORTAL_PROXY_ADDRESS="" + fi + + # Update .env if found + if [ -n "$DISPUTE_GAME_FACTORY_ADDRESS" ]; then + echo "✅ Found DisputeGameFactoryProxy address: $DISPUTE_GAME_FACTORY_ADDRESS" + sed_inplace "s/DISPUTE_GAME_FACTORY_ADDRESS=.*/DISPUTE_GAME_FACTORY_ADDRESS=$DISPUTE_GAME_FACTORY_ADDRESS/" .env + else + echo "⚠️ DisputeGameFactoryProxy address not found in opChainDeployments" + fi + + if [ -n "$L2OO_ADDRESS" ]; then + echo "✅ Found L2OutputOracleProxy address: $L2OO_ADDRESS" + sed_inplace "s/L2OO_ADDRESS=.*/L2OO_ADDRESS=$L2OO_ADDRESS/" .env + else + echo "⚠️ L2OutputOracleProxy address not found in opChainDeployments" + fi + + if [ -n "$OPCM_IMPL_ADDRESS" ]; then + echo "✅ Found opcmAddress address: $OPCM_IMPL_ADDRESS" + sed_inplace "s/OPCM_IMPL_ADDRESS=.*/OPCM_IMPL_ADDRESS=$OPCM_IMPL_ADDRESS/" .env + else + echo "⚠️ opcmAddress address not found in opChainDeployments" + fi + + if [ -n "$SYSTEM_CONFIG_PROXY_ADDRESS" ]; then + echo "✅ Found SystemConfigProxy address: $SYSTEM_CONFIG_PROXY_ADDRESS" + sed_inplace "s/SYSTEM_CONFIG_PROXY_ADDRESS=.*/SYSTEM_CONFIG_PROXY_ADDRESS=$SYSTEM_CONFIG_PROXY_ADDRESS/" .env + else + echo "⚠️ SystemConfigProxy address not found in opChainDeployments" + fi + + if [ -n "$OPTIMISM_PORTAL_PROXY_ADDRESS" ]; then + echo " ✅ Found OptimismPortalProxy address: $OPTIMISM_PORTAL_PROXY_ADDRESS" + sed_inplace "s/OPTIMISM_PORTAL_PROXY_ADDRESS=.*/OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS/" .env + else + echo " ⚠️ OptimismPortalProxy address not found in opChainDeployments" + fi + + if [ -n "$PROXY_ADMIN" ]; then + echo "✅ Found ProxyAdmin address: $PROXY_ADMIN" + sed_inplace "s/PROXY_ADMIN=.*/PROXY_ADMIN=$PROXY_ADMIN/" .env + else + echo "⚠️ ProxyAdmin address not found in opChainDeployments" + fi + + # Show summary + echo "📄 Contract addresses updated in .env:" + echo " DISPUTE_GAME_FACTORY_ADDRESS=$DISPUTE_GAME_FACTORY_ADDRESS" + echo " L2OO_ADDRESS=$L2OO_ADDRESS" + echo " OPCM_IMPL_ADDRESS=$OPCM_IMPL_ADDRESS" + echo " SYSTEM_CONFIG_PROXY_ADDRESS=$SYSTEM_CONFIG_PROXY_ADDRESS" + echo " OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS" + echo " PROXY_ADMIN=$PROXY_ADMIN" + else + echo "❌ $STATE_JSON is not a valid JSON object" + fi + else + echo "❌ state.json not found at $STATE_JSON" + fi +} + + +migrate() { + export OP_DATA_DIR=./data/op-geth-seq + export OP_GENESIS_PATH=${PWD_DIR}/config-op/genesis-op-after-number.json + + if [ "$ENV" = "local" ]; then + ERIGON_CHAINDATA_DIR=${PWD_DIR}/data/rpc/chaindata/ + ERIGON_SMTDATA_DIR=${PWD_DIR}/data/rpc/smt/ + else + ERIGON_CHAINDATA_DIR=/data/erigon-data/chaindata/ + ERIGON_SMTDATA_DIR=/data/erigon-data/smt/ + fi + + if [[ "$OSTYPE" == "darwin"* ]]; then + export GETH_CMD=$(go env GOPATH)/bin/geth + + if [ ! -f ${GETH_CMD} ]; then + cd ./tmp/op-geth + make geth + sudo cp ./build/bin/geth /usr/local/bin/geth + cd $PWD_DIR + else + echo "✅ geth found at optimism/op-geth/build/bin" + fi + else + export GETH_CMD=geth + echo "✅ Using Linux geth path: $GETH_CMD" + fi + + echo "GETH_CMD: $GETH_CMD" + # Build the base command + MIGRATE_CMD="${GETH_CMD} --datadir=${OP_DATA_DIR} --gcmode=archive migrate --state.scheme=hash --ignore-addresses=0x000000000000000000000000000000005ca1ab1e --chaindata=${ERIGON_CHAINDATA_DIR} --smt-db-path=${ERIGON_SMTDATA_DIR} --output merged.genesis.json" + + # Add --override-proposer if TIMELOCK_OVERRIDE_PROPOSER_ADDRESS is set and non-empty + if [ -n "${TIMELOCK_OVERRIDE_PROPOSER_ADDRESS:-}" ]; then + MIGRATE_CMD="$MIGRATE_CMD --override-proposer=${TIMELOCK_OVERRIDE_PROPOSER_ADDRESS}" + fi + + # Add --override-executor if TIMELOCK_OVERRIDE_EXECUTOR_ADDRESS is set and non-empty + if [ -n "${TIMELOCK_OVERRIDE_EXECUTOR_ADDRESS:-}" ]; then + MIGRATE_CMD="$MIGRATE_CMD --override-executor=${TIMELOCK_OVERRIDE_EXECUTOR_ADDRESS}" + fi + + # Add the genesis path at the end + MIGRATE_CMD="$MIGRATE_CMD ${OP_GENESIS_PATH}" + + # Execute the command + $MIGRATE_CMD 2>&1 | tee migrate.log + + LOG_BLOCK=$(grep -A 5 "Update rollup.json file with the following information l2" migrate.log | tail -n 5) + L2_NUMBER=$(echo "$LOG_BLOCK" | grep '"number"' | sed 's/[^0-9]*\([0-9]*\).*/\1/') + L2_HASH=$(echo "$LOG_BLOCK" | grep '"hash"' | sed 's/.*"\(0x[0-9a-fA-F]*\)".*/\1/') + echo "L2_NUMBER: $L2_NUMBER" + echo "L2_HASH: $L2_HASH" + + jq --argjson num "$L2_NUMBER" --arg hash "$L2_HASH" \ + '.genesis.l2.number = $num | .genesis.l2.hash = $hash' \ + config-op/rollup.json > config-op/rollup.json.tmp && mv config-op/rollup.json.tmp config-op/rollup.json + + # Update eip1559DenominatorCanyon to match eip1559Denominator in rollup.json + echo "🔧 Updating eip1559DenominatorCanyon to match eip1559Denominator..." + + # Extract eip1559Denominator from rollup.json + EIP1559_DENOMINATOR=$(jq -r '.chain_op_config.eip1559Denominator' config-op/rollup.json) + echo "eip1559Denominator value from rollup.json: $EIP1559_DENOMINATOR" + + # Debug: Check current rollup.json structure + echo "🔍 Current rollup.json chain_op_config structure:" + jq '.chain_op_config' config-op/rollup.json + + # Update rollup.json with the eip1559DenominatorCanyon value + echo "🔧 Updating rollup.json chain_op_config..." + jq --argjson denominator "$EIP1559_DENOMINATOR" \ + '.chain_op_config.eip1559DenominatorCanyon = $denominator' \ + config-op/rollup.json > config-op/rollup.json.tmp && mv config-op/rollup.json.tmp config-op/rollup.json + + # Verify the update + echo "🔍 Updated rollup.json chain_op_config structure:" + jq '.chain_op_config' config-op/rollup.json + + echo "✅ Updated eip1559DenominatorCanyon to $EIP1559_DENOMINATOR in rollup.json" + + echo "finished migrate op-geth" +} + +cd $PWD_DIR +prepare +migrate diff --git a/test-pp-op/5-start-op.sh b/test-pp-op/5-start-op.sh new file mode 100755 index 0000000000000..62ff8b6c8c18f --- /dev/null +++ b/test-pp-op/5-start-op.sh @@ -0,0 +1,168 @@ +set -e +set -x +source .env +source utils.sh +source tools.sh + +PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(dirname "$PWD_DIR")" +SCRIPTS_DIR=$ROOT_DIR/test/scripts + +start_sequencer() { + rm -rf "$OP_GETH_DATADIR2" + cp -r "$OP_GETH_DATADIR" "$OP_GETH_DATADIR2" + + rm -rf "$OP_GETH_DATADIR3" + cp -r "$OP_GETH_DATADIR" "$OP_GETH_DATADIR3" + + if [ "$ENV" = "testnet" ];then + L1_RPC_URL="https://fullnode-inner.okg.com/sepolia/fork/okbc/rpc" + L1_BEACON_URL_IN_DOCKER="https://fullnode-inner.okg.com/ethsepoliabeacon/native/layer1/rpc" + sed_inplace "s|L1_RPC_URL=.*|L1_RPC_URL=$L1_RPC_URL|" .env + sed_inplace "s|L1_RPC_URL_IN_DOCKER=.*|L1_RPC_URL_IN_DOCKER=$L1_RPC_URL|" .env + sed_inplace "s|L1_BEACON_URL_IN_DOCKER=.*|L1_BEACON_URL_IN_DOCKER=$L1_BEACON_URL_IN_DOCKER|" .env + fi + + if [ "$CONDUCTOR_ENABLED" = "true" ]; then + ${DOCKER_COMPOSE_CMD} up -d op-conductor + ${DOCKER_COMPOSE_CMD} up -d op-conductor2 + ${DOCKER_COMPOSE_CMD} up -d op-conductor3 + sleep 3 + $SCRIPTS_DIR/active-sequencer.sh + else + ${DOCKER_COMPOSE_CMD} up -d op-seq + fi + + # Check for L2 genesis hash mismatch + LOG_OUTPUT=$(${DOCKER_COMPOSE_CMD} logs op-seq 2>&1 | tail -20) + if echo "$LOG_OUTPUT" | grep -q "expected L2 genesis hash to match L2 block at genesis block number"; then + echo "❌ L2 genesis hash mismatch detected!" + echo "Error details:" + echo "$LOG_OUTPUT" | grep "expected L2 genesis hash to match L2 block at genesis block number" + exit 1 + fi +} + +start_rpc() { + rm -rf "$OP_GETH_RPC_DATADIR" + cp -r "$OP_GETH_DATADIR" "$OP_GETH_RPC_DATADIR" + ${DOCKER_COMPOSE_CMD} up -d op-rpc +} + +connect_static_peers() { + + # Setup P2P static connections between op-geth nodes + echo "🔗 Setting up P2P static connections between op-geth nodes..." + + # Get enodes for all op-geth containers + echo "📡 Getting enode addresses..." + + # Get enodes + OP_GETH_SEQ_ENODE=$(get_enode "op-geth-seq" "8545") + OP_GETH_RPC_ENODE=$(get_enode "op-geth-rpc" "8545") + + if [ "$CONDUCTOR_ENABLED" = "true" ]; then + OP_GETH_SEQ2_ENODE=$(get_enode "op-geth-seq2" "8545") + OP_GETH_SEQ3_ENODE=$(get_enode "op-geth-seq3" "8545") + fi + + # Replace 127.0.0.1 with container names + OP_GETH_SEQ_ENODE=$(replace_enode_ip "$OP_GETH_SEQ_ENODE" "op-geth-seq") + OP_GETH_RPC_ENODE=$(replace_enode_ip "$OP_GETH_RPC_ENODE" "op-geth-rpc") + + if [ "$CONDUCTOR_ENABLED" = "true" ]; then + OP_GETH_SEQ2_ENODE=$(replace_enode_ip "$OP_GETH_SEQ2_ENODE" "op-geth-seq2") + OP_GETH_SEQ3_ENODE=$(replace_enode_ip "$OP_GETH_SEQ3_ENODE" "op-geth-seq3") + fi + + echo "✅ Enode addresses:" + echo " op-geth-seq: $OP_GETH_SEQ_ENODE" + echo " op-geth-rpc: $OP_GETH_RPC_ENODE" + if [ "$CONDUCTOR_ENABLED" = "true" ]; then + echo " op-geth-seq2: $OP_GETH_SEQ2_ENODE" + echo " op-geth-seq3: $OP_GETH_SEQ3_ENODE" + fi + + + # Setup static connections between sequencer nodes + echo "🔗 Setting up static connections between sequencer nodes..." + + # Add peers to op-geth-seq (connect to other sequencers) + echo "🔗 Setting up peers for op-geth-seq..." + if [ "$CONDUCTOR_ENABLED" = "true" ]; then + add_peer "op-geth-seq" "$OP_GETH_SEQ2_ENODE" + add_peer "op-geth-seq" "$OP_GETH_SEQ3_ENODE" + fi + + if [ "$CONDUCTOR_ENABLED" = "true" ]; then + # Add peers to op-geth-seq2 (connect to other sequencers) + echo "🔗 Setting up peers for op-geth-seq2..." + add_peer "op-geth-seq2" "$OP_GETH_SEQ_ENODE" + add_peer "op-geth-seq2" "$OP_GETH_SEQ3_ENODE" + + # Add peers to op-geth-seq3 (connect to other sequencers) + echo "🔗 Setting up peers for op-geth-seq3..." + add_peer "op-geth-seq3" "$OP_GETH_SEQ_ENODE" + add_peer "op-geth-seq3" "$OP_GETH_SEQ2_ENODE" + fi + + # Setup RPC node to connect to all sequencer nodes + echo "🔗 Setting up RPC node to connect to all sequencer nodes..." + add_peer "op-geth-rpc" "$OP_GETH_SEQ_ENODE" + if [ "$CONDUCTOR_ENABLED" = "true" ]; then + add_peer "op-geth-rpc" "$OP_GETH_SEQ2_ENODE" + add_peer "op-geth-rpc" "$OP_GETH_SEQ3_ENODE" + fi + + echo "✅ P2P static connections established:" + echo " - Sequencer nodes (op-geth-seq, op-geth-seq2, op-geth-seq3) are connected to each other" + echo " - RPC node (op-geth-rpc) is connected to all sequencer nodes" + +} + +# Function to get enode from a geth container +get_enode() { + local container_name=$1 + local rpc_port=$2 + local enode=$(docker exec $container_name geth attach --exec "admin.nodeInfo.enode" --datadir /datadir 2>/dev/null | tr -d '"') + echo "$enode" +} + +# Function to replace 127.0.0.1 with container name in enode +replace_enode_ip() { + local enode=$1 + local container_name=$2 + echo "$enode" | sed "s/@127.0.0.1:/@$container_name:/" +} + +# Function to add peer to a geth container +add_peer() { + local container_name=$1 + local peer_enode=$2 + echo "🔗 Adding peer to $container_name: $peer_enode" + docker exec $container_name geth attach --exec "admin.addPeer('$peer_enode')" --datadir /datadir 2>/dev/null +} + +start_batcher() { + # Configure op-batcher endpoints based on conductor mode + if [ "$CONDUCTOR_ENABLED" = "true" ]; then + echo "🔧 Configuring op-batcher for conductor mode with conductor RPC endpoints..." + # Set conductor mode endpoints + export OP_BATCHER_L2_ETH_RPC="http://op-conductor:8547,http://op-conductor2:8547,http://op-conductor3:8547" + export OP_BATCHER_ROLLUP_RPC="http://op-conductor:8547,http://op-conductor2:8547,http://op-conductor3:8547" + echo "✅ op-batcher configured for conductor mode (connecting to conductor RPC endpoints)" + else + echo "🔧 Configuring op-batcher for single sequencer mode..." + # Set single sequencer mode endpoints + export OP_BATCHER_L2_ETH_RPC="http://op-geth-seq:8545" + export OP_BATCHER_ROLLUP_RPC="http://op-seq:9545" + echo "✅ op-batcher configured for single sequencer mode" + fi + + ${DOCKER_COMPOSE_CMD} up -d op-batcher +} + +start_sequencer +start_rpc +connect_static_peers +start_batcher diff --git a/test-pp-op/6-build-op-program.sh b/test-pp-op/6-build-op-program.sh new file mode 100755 index 0000000000000..867ec1be3d168 --- /dev/null +++ b/test-pp-op/6-build-op-program.sh @@ -0,0 +1,174 @@ +#!/bin/bash +set -x +set -e +source .env +source tools.sh + +PWD_DIR=$(pwd) + +if [ -z "$CHAIN_ID" ]; then + echo "❌ ERROR: CHAIN_ID is not set. Set it explicitly or derive it from intent.toml before proceeding." + exit 1 +fi +if ! [[ "$CHAIN_ID" =~ ^[0-9]+$ ]]; then + echo "❌ ERROR: CHAIN_ID must be a numeric value, got: '$CHAIN_ID'" + exit 1 +fi +# Function to show usage +show_usage() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " -a, --arch ARCH Target architecture (x86|arm|amd64|arm64)" + echo " Default: auto-detect from OSTYPE" + echo " -h, --help Show this help message" + echo "" + echo "Architecture mapping:" + echo " x86/amd64 -> linux/amd64" + echo " arm/arm64 -> linux/arm64" + echo "" + echo "Current OSTYPE: $OSTYPE" +} + +# Default architecture detection based on OSTYPE +detect_arch() { + case "$OSTYPE" in + *darwin*) + if [[ $(uname -m) == "arm64" ]]; then + echo "linux/arm64" + else + echo "linux/amd64" + fi + ;; + *linux*) + if [[ $(uname -m) == "aarch64" ]] || [[ $(uname -m) == "arm64" ]]; then + echo "linux/arm64" + else + echo "linux/amd64" + fi + ;; + *) + echo "linux/amd64" # Default fallback + ;; + esac +} + +# Parse command line arguments +DOCKER_PLATFORM="" +while [[ $# -gt 0 ]]; do + case $1 in + -a|--arch) + case "$2" in + x86|amd64) + DOCKER_PLATFORM="linux/amd64" + ;; + arm|arm64) + DOCKER_PLATFORM="linux/arm64" + ;; + *) + echo "Error: Invalid architecture '$2'" + echo "Valid options: x86, amd64, arm, arm64" + exit 1 + ;; + esac + shift 2 + ;; + -h|--help) + show_usage + exit 0 + ;; + *) + echo "Error: Unknown option '$1'" + show_usage + exit 1 + ;; + esac +done + +# Set default platform if not specified +if [ -z "$DOCKER_PLATFORM" ]; then + DOCKER_PLATFORM=$(detect_arch) + echo "Auto-detected platform: $DOCKER_PLATFORM" +else + echo "Using specified platform: $DOCKER_PLATFORM" +fi + +post_migrate() { + # Check if genesis.json exists, panic if it doesn't + if [ ! -f "merged.genesis.json" ]; then + echo "ERROR: merged.genesis.json does not exist!" + echo "Please ensure the genesis.json file is present before running this script." + exit 1 + fi + + $MD5SUM_CMD merged.genesis.json + # genesis.json is too large to embed in go, so we compress it now and decompress it in go code + gzip -c merged.genesis.json > config-op/merged.genesis.gz.json + + # Ensure prestate files exist and devnetL1.json is consistent before deploying contracts + EXPORT_DIR="$PWD_DIR/data/cannon-data" + rm -rf $EXPORT_DIR + mkdir -p $EXPORT_DIR + + # Set network based on ENV + if [ "$ENV" = "local" ]; then + DOCKER_NETWORK_ARG="--network ${DOCKER_NETWORK}" + else + DOCKER_NETWORK_ARG="--network host" + fi + + ROOTLESS_DOCKER=$(docker info -f "{{println .SecurityOptions}}" | grep rootless || true) + + if ! [ -z "$ROOTLESS_DOCKER" ]; then + docker run -it --privileged \ + --platform $DOCKER_PLATFORM \ + -v "$(pwd)/scripts:/scripts" \ + -v "$(pwd)/config-op/rollup.json:/app/op-program/chainconfig/configs/${CHAIN_ID}-rollup.json" \ + -v "$(pwd)/config-op/merged.genesis.gz.json:/app/op-program/chainconfig/configs/${CHAIN_ID}-genesis-l2.json" \ + -v "$(pwd)/l1-geth/execution/genesis.json:/app/op-program/chainconfig/configs/1337-genesis-l1.json" \ + -v "$EXPORT_DIR:/app/op-program/bin" \ + --name op-program \ + -w /app \ + ${DOCKER_NETWORK_ARG} \ + "${OP_STACK_IMAGE_TAG}" \ + bash -c " + echo '📊 Verifying Docker connection:' + /scripts/dind-install-start.sh + docker --version + docker ps --format 'table {{.Names}}\t{{.Status}}' | head -3 + + echo '🚀 Running make reproducible-prestate...' + make reproducible-prestate + + echo '📁 Checking contents of op-program/bin:' + ls -la /app/op-program/bin/ || echo 'Directory is empty or does not exist' + " + else + docker run -it \ + --platform $DOCKER_PLATFORM \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v "$(pwd)/config-op/rollup.json:/app/op-program/chainconfig/configs/${CHAIN_ID}-rollup.json" \ + -v "$(pwd)/config-op/merged.genesis.gz.json:/app/op-program/chainconfig/configs/${CHAIN_ID}-genesis-l2.json" \ + -v "$(pwd)/l1-geth/execution/genesis.json:/app/op-program/chainconfig/configs/1337-genesis-l1.json" \ + -v "$EXPORT_DIR:/app/op-program/bin" \ + --name op-program \ + -w /app \ + ${DOCKER_NETWORK_ARG} \ + -e DOCKER_HOST=unix:///var/run/docker.sock \ + "${OP_STACK_IMAGE_TAG}" \ + bash -c " + echo '📊 Verifying Docker connection:' + apt-get update + apt-get install docker.io -y + docker --version + docker ps --format 'table {{.Names}}\t{{.Status}}' | head -3 + + echo '🚀 Running make reproducible-prestate...' + make reproducible-prestate + + echo '📁 Checking contents of op-program/bin:' + ls -la /app/op-program/bin/ || echo 'Directory is empty or does not exist' + " + fi +} + +post_migrate diff --git a/test-pp-op/7-setup-fraud-proof.sh b/test-pp-op/7-setup-fraud-proof.sh new file mode 100755 index 0000000000000..2dad87ecf5731 --- /dev/null +++ b/test-pp-op/7-setup-fraud-proof.sh @@ -0,0 +1,505 @@ +#!/bin/bash +set -e +set -x + +source .env +source tools.sh + +if [ "$ENV" = "testnet" ];then + shopt -s expand_aliases + alias cast='docker run --rm --network host op-migrate:amd64 cast' +fi + +PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd $PWD_DIR +EXPORT_DIR="$PWD_DIR/data/cannon-data" + +# Get prestate value from prestate-proof-mt64.json +ABSOLUTE_PRESTATE=$(jq -r '.pre' "$EXPORT_DIR/prestate-proof-mt64.json") + +# Validate OWNER_TYPE configuration +if [ "$OWNER_TYPE" != "transactor" ] && [ "$OWNER_TYPE" != "safe" ]; then + echo "❌ Error: Invalid OWNER_TYPE '$OWNER_TYPE'. Must be 'transactor' or 'safe'" + exit 1 +fi + +echo "=== Using OWNER_TYPE: $OWNER_TYPE ===" + +# Function to add game type via Safe +add_game_type_via_safe() { + # Check parameter count + if [ $# -ne 5 ]; then + echo "Error: add_game_type_via_safe requires exactly 5 parameters" + echo "Usage: add_game_type_via_safe " + echo "Example: add_game_type_via_safe 2 true 600 1800 0x..." + return 1 + fi + + local GAME_TYPE=$1 + local IS_PERMISSIONED=$2 + local CLOCK_EXTENSION_VAL=$3 + local MAX_CLOCK_DURATION_VAL=$4 + local ABSOLUTE_PRESTATE_VAL=$5 + + echo "=== Adding Game Type $GAME_TYPE via Safe ===" + echo " Game Type: $GAME_TYPE" + echo " Is Permissioned: $IS_PERMISSIONED" + echo " Clock Extension: $CLOCK_EXTENSION_VAL" + echo " Max Clock Duration: $MAX_CLOCK_DURATION_VAL" + echo "" + + # Get dispute game factory address + DISPUTE_GAME_FACTORY=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'disputeGameFactory()(address)') + + echo "Debug Info:" + echo " State JSON: $STATE_JSON_PATH" + echo " Dispute Game Factory: $DISPUTE_GAME_FACTORY" + echo " System Config: $SYSTEM_CONFIG_PROXY_ADDRESS" + echo " Proxy Admin: $PROXY_ADMIN" + echo " OPCM: $OPCM_IMPL_ADDRESS" + echo " Safe: $SAFE_ADDRESS" + echo " RPC URL: $L1_RPC_URL" + echo " Sender: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" + echo "" + + # Retrieve existing permissioned game implementation for parameters + echo "Retrieving permissioned game parameters..." + PERMISSIONED_GAME=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' 1) + echo "Permissioned Game Implementation: $PERMISSIONED_GAME" + + if [ "$PERMISSIONED_GAME" == "0x0000000000000000000000000000000000000000" ]; then + echo "Error: No permissioned game found. Cannot retrieve parameters." + exit 1 + fi + + # Retrieve parameters from existing permissioned game + ABSOLUTE_PRESTATE="$ABSOLUTE_PRESTATE_VAL" + MAX_GAME_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'maxGameDepth()') + SPLIT_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'splitDepth()') + VM=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'vm()(address)') + + echo "Retrieved parameters:" + echo " Absolute Prestate: $ABSOLUTE_PRESTATE" + echo " Max Game Depth: $MAX_GAME_DEPTH" + echo " Split Depth: $SPLIT_DEPTH" + echo " Clock Extension: $CLOCK_EXTENSION_VAL" + echo " Max Clock Duration: $MAX_CLOCK_DURATION_VAL" + echo " VM: $VM" + echo "" + + # Set constants + INITIAL_BOND='80000000000000000' # 0.08 ETH in wei + SALT_MIXER='123' # Unique salt for game type + + echo "Creating addGameType calldata..." + + # Build game type parameters array (simplified) + GAME_PARAMS="[(\"$SALT_MIXER\",$SYSTEM_CONFIG_PROXY_ADDRESS,$PROXY_ADMIN,0x0000000000000000000000000000000000000000,$GAME_TYPE,$ABSOLUTE_PRESTATE,$MAX_GAME_DEPTH,$SPLIT_DEPTH,$CLOCK_EXTENSION_VAL,$MAX_CLOCK_DURATION_VAL,$INITIAL_BOND,$VM,$IS_PERMISSIONED)]" + + echo "Parameters prepared for addGameType" + + # Execute the transaction through Safe + echo "Executing transaction via Safe..." + echo "Target: $SAFE_ADDRESS" + echo "From: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" + + # Simplified DELEGATECALL - build calldata first, then call + ADDGAMETYPE_CALLDATA=$(cast calldata 'addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[])' "$GAME_PARAMS") + + + # Execute transaction via Safe's execTransaction with proper signature + echo "Executing transaction via Safe with signature..." + DEPLOYER_ADDRESS=$(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY) + + # Use the calldata we built earlier + echo "Using calldata: $ADDGAMETYPE_CALLDATA" + + # Get Safe nonce + SAFE_NONCE=$(cast call --rpc-url $L1_RPC_URL $SAFE_ADDRESS 'nonce()(uint256)') + echo "Safe nonce: $SAFE_NONCE" + + # Build signature exactly like DeployOwnership.s.sol _callViaSafe method + # abi.encodePacked(uint256(uint160(msg.sender)), bytes32(0), uint8(1)) + echo "Building signature like DeployOwnership.s.sol _callViaSafe..." + + # Convert deployer address to uint256(uint160(address)) format + # This is equivalent to: uint256(uint160(msg.sender)) + DEPLOYER_ADDRESS_NO_PREFIX=${DEPLOYER_ADDRESS#0x} + DEPLOYER_ADDRESS_PADDED=$(printf "%064s" $DEPLOYER_ADDRESS_NO_PREFIX) + + # Build signature: uint256(uint160(msg.sender)) + bytes32(0) + uint8(1) + # This is exactly what abi.encodePacked(uint256(uint160(msg.sender)), bytes32(0), uint8(1)) produces + PACKED_SIGNATURE="0x${DEPLOYER_ADDRESS_PADDED}000000000000000000000000000000000000000000000000000000000000000001" + + echo "Deployer address: $DEPLOYER_ADDRESS" + echo "Signature (abi.encodePacked format): $PACKED_SIGNATURE" + echo "Signature length: $((${#PACKED_SIGNATURE} - 2)) hex chars = $(((${#PACKED_SIGNATURE} - 2) / 2)) bytes" + + # Execute transaction via Safe's execTransaction + echo "Executing execTransaction on Safe..." + TX_OUTPUT=$(cast send \ + --json \ + --legacy \ + --rpc-url $L1_RPC_URL \ + --private-key $DEPLOYER_PRIVATE_KEY \ + --from $DEPLOYER_ADDRESS \ + $SAFE_ADDRESS \ + 'execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)' \ + $OPCM_IMPL_ADDRESS \ + 0 \ + $ADDGAMETYPE_CALLDATA \ + 1 \ + 0 \ + 0 \ + 0 \ + 0x0000000000000000000000000000000000000000 \ + 0x0000000000000000000000000000000000000000 \ + $PACKED_SIGNATURE) + + # Extract transaction hash and status + TX_HASH=$(echo "$TX_OUTPUT" | jq -r '.transactionHash // empty') + TX_STATUS=$(echo "$TX_OUTPUT" | jq -r '.status // empty') + + echo "" + echo "Transaction sent, TX_HASH: $TX_HASH" + + # Check if transaction was successful + if [ "$TX_STATUS" = "0x1" ] || [ "$TX_STATUS" = "1" ]; then + echo " ✅ Transaction successful!" + else + echo " ❌ Transaction failed with status: $TX_STATUS" + echo "Full output: $TX_OUTPUT" + exit 1 + fi + echo "" + + # Verify the new game type was added + echo "Verifying new game type was added..." + NEW_GAME_IMPL=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' $GAME_TYPE) + + if [ "$NEW_GAME_IMPL" != "0x0000000000000000000000000000000000000000" ] && [ "$NEW_GAME_IMPL" != "$PERMISSIONED_GAME" ]; then + echo " ✅ Success! New game type $GAME_TYPE added." + echo "Game Type $GAME_TYPE Implementation: $NEW_GAME_IMPL" + else + echo " ❌ Warning: Could not verify game type was added. Check transaction status." + fi + + echo " ✅ AddGameType operations completed successfully" + + # Set the newly added game type as respected + echo "" + set_respected_game_type "$GAME_TYPE" +} + +# Function to add game type via Transactor +add_game_type_via_transactor() { + local GAME_TYPE=$1 + local IS_PERMISSIONED=$2 + local CLOCK_EXTENSION_VAL=$3 + local MAX_CLOCK_DURATION_VAL=$4 + local ABSOLUTE_PRESTATE_VAL=$5 + + echo "=== Adding Game Type $GAME_TYPE via Transactor ===" + echo "Game Type: $GAME_TYPE" + echo "Is Permissioned: $IS_PERMISSIONED" + echo "Clock Extension: $CLOCK_EXTENSION_VAL" + echo "Max Clock Duration: $MAX_CLOCK_DURATION_VAL" + echo "" + + docker run --rm \ + --network "$DOCKER_NETWORK" \ + -v "$(pwd)/$CONFIG_DIR:/deployments" \ + -w /app \ + "${OP_CONTRACTS_IMAGE_TAG}" \ + bash -c " + set -e + + # Get addresses from environment + RPC_URL=$L1_RPC_URL_IN_DOCKER + TRANSACTOR_ADDRESS=$TRANSACTOR + SENDER_ADDRESS=\$(cast wallet address --private-key $ADMIN_OWNER_PRIVATE_KEY) + PRIVATE_KEY=$ADMIN_OWNER_PRIVATE_KEY + + # Get addresses from environment variables + SYSTEM_CONFIG=$SYSTEM_CONFIG_PROXY_ADDRESS + PROXY_ADMIN=$PROXY_ADMIN + OPCM=$OPCM_IMPL_ADDRESS + DISPUTE_GAME_FACTORY=\$(cast call --rpc-url \$RPC_URL \$SYSTEM_CONFIG 'disputeGameFactory()(address)') + + echo 'State JSON Path: '\$STATE_JSON_PATH + echo 'Dispute Game Factory: '\$DISPUTE_GAME_FACTORY + echo 'System Config: '\$SYSTEM_CONFIG + echo 'Proxy Admin: '\$PROXY_ADMIN + echo 'OPCM: '\$OPCM + echo 'Transactor Address: '\$TRANSACTOR_ADDRESS + echo 'RPC URL: '\$RPC_URL + echo 'Sender Address: '\$SENDER_ADDRESS + echo '' + + # Retrieve existing permissioned game implementation for parameters + echo 'Retrieving permissioned game parameters...' + PERMISSIONED_GAME=\$(cast call --rpc-url \$RPC_URL \$DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' 1) + echo 'Permissioned Game Implementation: '\$PERMISSIONED_GAME + + if [ \"\$PERMISSIONED_GAME\" == \"0x0000000000000000000000000000000000000000\" ]; then + echo 'Error: No permissioned game found. Cannot retrieve parameters.' + exit 1 + fi + + # Retrieve parameters from existing permissioned game + ABSOLUTE_PRESTATE='$ABSOLUTE_PRESTATE_VAL' + MAX_GAME_DEPTH=\$(cast call --rpc-url \$RPC_URL \$PERMISSIONED_GAME 'maxGameDepth()') + SPLIT_DEPTH=\$(cast call --rpc-url \$RPC_URL \$PERMISSIONED_GAME 'splitDepth()') + VM=\$(cast call --rpc-url \$RPC_URL \$PERMISSIONED_GAME 'vm()(address)') + + echo 'Retrieved parameters:' + echo ' Absolute Prestate: '\$ABSOLUTE_PRESTATE + echo ' Max Game Depth: '\$MAX_GAME_DEPTH + echo ' Split Depth: '\$SPLIT_DEPTH + echo ' Clock Extension: '$CLOCK_EXTENSION_VAL' + echo ' Max Clock Duration: '$MAX_CLOCK_DURATION_VAL' + echo ' VM: '\$VM + echo '' + + # Set initial bond + INITIAL_BOND='80000000000000000' # 0.08 ETH in wei + + # Create unique salt mixer + SALT_MIXER='123' + + echo 'Creating addGameType calldata...' + + # Create calldata for addGameType function + ADDGAMETYPE_CALLDATA=\$(cast calldata 'addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[])' \ + \"[(\ + \\\"\$SALT_MIXER\\\",\ + \$SYSTEM_CONFIG,\ + \$PROXY_ADMIN,\ + 0x0000000000000000000000000000000000000000,\ + $GAME_TYPE,\ + \$ABSOLUTE_PRESTATE,\ + \$MAX_GAME_DEPTH,\ + \$SPLIT_DEPTH,\ + $CLOCK_EXTENSION_VAL,\ + $MAX_CLOCK_DURATION_VAL,\ + \$INITIAL_BOND,\ + \$VM,\ + $IS_PERMISSIONED\ + )]\") + echo 'AddGameType calldata: '\$ADDGAMETYPE_CALLDATA + echo '' + + # Create calldata for Transactor's DELEGATECALL function + echo 'Creating Transactor DELEGATECALL calldata...' + TRANSACTOR_CALLDATA=\$(cast calldata 'DELEGATECALL(address,bytes)' \$OPCM \$ADDGAMETYPE_CALLDATA) + + echo 'Transactor calldata: '\$TRANSACTOR_CALLDATA + echo '' + + # Execute the transaction through Transactor + echo 'Executing transaction via Transactor...' + echo 'Target: '\$TRANSACTOR_ADDRESS + echo 'RPC_URL: '\$RPC_URL + + cast send \\ + --rpc-url \$RPC_URL \\ + --private-key \$PRIVATE_KEY \\ + --from \$SENDER_ADDRESS \\ + \$TRANSACTOR_ADDRESS \\ + \$TRANSACTOR_CALLDATA + + echo '' + echo 'Transaction sent! Check the transaction hash above for confirmation.' + echo '' + + # Verify the new game type was added + echo 'Verifying new game type was added...' + NEW_GAME_IMPL=\$(cast call --rpc-url \$RPC_URL \$DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' $GAME_TYPE) + + if [ \"\$NEW_GAME_IMPL\" != \"0x0000000000000000000000000000000000000000\" ] && [ \"\$NEW_GAME_IMPL\" != \"\$PERMISSIONED_GAME\" ]; then + echo '✅ Success! New game type $GAME_TYPE added.' + echo 'Game Type $GAME_TYPE Implementation: '\$NEW_GAME_IMPL + else + echo '❌ Warning: Could not verify game type was added. Check transaction status.' + fi + + echo '✅ AddGameType operations completed successfully' + " +} + +add_permissioned_game_type() { + echo "Adding game type to DisputeGameFactory via op-deployer..." + + # Retrieve existing values from chain for reference + # Get permissioned game implementation + PERMISSIONED_GAME_RAW=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameImpls(uint32)" 1) + # Convert 32-byte hex to 20-byte address (last 40 hex chars, with 0x prefix) + PERMISSIONED_GAME="0x${PERMISSIONED_GAME_RAW: -40}" + + MAX_GAME_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "maxGameDepth()") + SPLIT_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "splitDepth()") + VM_RAW=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "vm()") + VM="0x${VM_RAW: -40}" + ANCHOR_STATE_REGISTRY=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "anchorStateRegistry()") + L2_CHAIN_ID=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "l2ChainId()") + + # Call the function to add game type 1 (permissioned) via Transactor + add_game_type_via_transactor 1 true $TEMP_CLOCK_EXTENSION $TEMP_MAX_CLOCK_DURATION $ABSOLUTE_PRESTATE + export GAME_TYPE=1 +} + +wait_op_proposer_create_game() { + + echo "Waiting for op-proposer to create a game..." + ${DOCKER_COMPOSE_CMD} up -d op-proposer + + GAME_CREATED=false + MAX_WAIT_TIME=600 # 10 minutes timeout + WAIT_COUNT=0 + + while [ "$GAME_CREATED" = false ] && [ $WAIT_COUNT -lt $MAX_WAIT_TIME ]; do + # Check if a game was created by op-proposer + GAME_COUNT=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameCount()(uint256)") + if [ "$GAME_COUNT" -gt 0 ]; then + echo "✅ Game created! Game count: $GAME_COUNT" + GAME_CREATED=true + else + echo "⏳ Waiting for game creation... ($WAIT_COUNT/$MAX_WAIT_TIME seconds)" + sleep 1 + WAIT_COUNT=$((WAIT_COUNT + 1)) + fi + done + + if [ "$GAME_CREATED" = false ]; then + echo "❌ Timeout waiting for game creation" + exit 1 + fi + + echo "🛑 Stopping op-proposer..." + ${DOCKER_COMPOSE_CMD} stop op-proposer + +} + +fetch_and_set_latest_game_address() { + echo "get game address" +# echo "🔧 Executing dispute resolution sequence using op-challenger..." + GAME_COUNT=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameCount()(uint256)") + # Get the latest game address + LATEST_GAME_INDEX=$((GAME_COUNT - 1)) + GAME_INFO=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameAtIndex(uint256)(uint256,uint256,address)" $LATEST_GAME_INDEX) + # Extract the third value (address) from the returned tuple - address is the last 40 hex chars + GAME_ADDRESS="0x${GAME_INFO: -40}" + echo "Latest game address: $GAME_ADDRESS" +} + +resolve_claim() { + # Execute the dispute resolution sequence using op-challenger commands + echo "1. Resolving claim (0,0) using op-challenger..." + docker run --rm \ + --network "$DOCKER_NETWORK" \ + -v "$(pwd)/data/cannon-data:/data" \ + -v "$(pwd)/config-op/rollup.json:/rollup.json" \ + -v "$(pwd)/config-op/genesis.json:/l2-genesis.json" \ + "${OP_STACK_IMAGE_TAG}" \ + /app/op-challenger/bin/op-challenger resolve-claim \ + --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} \ + --private-key=${OP_CHALLENGER_PRIVATE_KEY} \ + --game-address=$GAME_ADDRESS \ + --claim=0 +} + +resolve_game() { + echo "2. Resolving game using op-challenger..." + docker run --rm \ + --network "$DOCKER_NETWORK" \ + -v "$(pwd)/data/cannon-data:/data" \ + -v "$(pwd)/config-op/rollup.json:/rollup.json" \ + -v "$(pwd)/config-op/genesis.json:/l2-genesis.json" \ + "${OP_STACK_IMAGE_TAG}" \ + /app/op-challenger/bin/op-challenger resolve \ + --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} \ + --private-key=${OP_CHALLENGER_PRIVATE_KEY} \ + --game-address=$GAME_ADDRESS +} + +claim_credit() { + echo "3. Claiming credit for proposer using cast command..." + docker run --rm \ + --network "$DOCKER_NETWORK" \ + "${OP_STACK_IMAGE_TAG}" \ + cast send \ + --rpc-url ${L1_RPC_URL_IN_DOCKER} \ + --private-key ${OP_CHALLENGER_PRIVATE_KEY} \ + $GAME_ADDRESS \ + "claimCredit(address)" \ + $PROPOSER_ADDRESS + echo "✅ Dispute resolution sequence completed using op-challenger commands!" +} + +set_game_type_permissionless() { + # Retrieve existing values from chain for reference + # Get permissioned game implementation + PERMISSIONED_GAME_RAW=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameImpls(uint32)" 1) + # Convert 32-byte hex to 20-byte address (last 40 hex chars, with 0x prefix) + PERMISSIONED_GAME="0x${PERMISSIONED_GAME_RAW: -40}" + # + ABSOLUTE_PRESTATE=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "absolutePrestate()") + ANCHOR_STATE_REGISTRY=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "anchorStateRegistry()") + + # Call the function to add game type 0 (permissionless) via Transactor or Safe + # Script is being executed directly - choose function based on OWNER_TYPE + if [ "$OWNER_TYPE" = "safe" ]; then + add_game_type_via_safe 0 false $CLOCK_EXTENSION $MAX_CLOCK_DURATION $ABSOLUTE_PRESTATE + elif [ "$OWNER_TYPE" = "transactor" ]; then + add_game_type_via_transactor 0 false $CLOCK_EXTENSION $MAX_CLOCK_DURATION $ABSOLUTE_PRESTATE + else + echo "Error: Invalid OWNER_TYPE '$OWNER_TYPE'" + exit 1 + fi + + docker run --rm \ + --network "$DOCKER_NETWORK" \ + -v "$(pwd)/$CONFIG_DIR:/deployments" \ + -w /app \ + "${OP_CONTRACTS_IMAGE_TAG}" \ + bash -c " + set -e + + echo '📋 Gathering contract addresses and generating calldata...' + DISPUTE_GAME_FACTORY_ADDR=\$(cast call --rpc-url $L1_RPC_URL_IN_DOCKER $SYSTEM_CONFIG_PROXY_ADDRESS 'disputeGameFactory()(address)') + OPTIMISM_PORTAL_ADDR=\$(cast call --rpc-url $L1_RPC_URL_IN_DOCKER $SYSTEM_CONFIG_PROXY_ADDRESS 'optimismPortal()(address)') + echo 'disputeGameFactory: '\$DISPUTE_GAME_FACTORY_ADDR + echo 'optimismPortal: '\$OPTIMISM_PORTAL_ADDR + + # Get anchorStateRegistry address with proper return type specification + ANCHOR_STATE_REGISTRY_ADDR=\$(cast call --rpc-url $L1_RPC_URL_IN_DOCKER \$OPTIMISM_PORTAL_ADDR 'anchorStateRegistry()(address)') + echo 'anchorStateRegistry: '\$ANCHOR_STATE_REGISTRY_ADDR + + GAME_ADDR=\$(cast call --rpc-url $L1_RPC_URL_IN_DOCKER \$DISPUTE_GAME_FACTORY_ADDR 'gameImpls(uint32)(address)' 0) + echo 'gameImpls(0): '\$GAME_ADDR + + cast send \$ANCHOR_STATE_REGISTRY_ADDR 'setRespectedGameType(uint32)' 0 --rpc-url $L1_RPC_URL_IN_DOCKER --private-key $ADMIN_OWNER_PRIVATE_KEY + + echo '✅ setRespectedGameType completed successfully' + " + + export GAME_TYPE=0 +} + +add_permissioned_game_type +wait_op_proposer_create_game +# +#echo "⏰ Sleeping for ($TEMP_MAX_CLOCK_DURATION seconds)..." +#sleep $TEMP_MAX_CLOCK_DURATION +# +#fetch_and_set_latest_game_address +#resolve_claim +#resolve_game +# +#sleep $DISPUTE_GAME_FINALITY_DELAY_SECONDS +#claim_credit +# +#set_game_type_permissionless +# +sleep $TEMP_GAME_WINDOW +${DOCKER_COMPOSE_CMD} up -d op-proposer op-challenger op-dispute-mon diff --git a/test-pp-op/8-prepare-tests.sh b/test-pp-op/8-prepare-tests.sh new file mode 100755 index 0000000000000..8f3dd154bc382 --- /dev/null +++ b/test-pp-op/8-prepare-tests.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +set -e + +source .env + + +echo "=== Preparing test; Funding L1 Admin Address===" +L1_ADMIN_ADDRESS="0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" +L1_ADMIN_PRIVATE_KEY="0x815405dddb0e2a99b12af775fd2929e526704e1d1aea6a0b4e74dc33e2f7fcd2" +cast send --rpc-url $L1_RPC_URL $L1_ADMIN_ADDRESS --private-key $RICH_L1_PRIVATE_KEY --value 1000ether + +echo "=== Bridging ETH from L1 to L2 ===" + +# Bridge contract addresses +OPTIMISM_PORTAL=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'optimismPortal()(address)') +RECIPIENT="0x14dC79964da2C08b23698B3D3cc7Ca32193d9955" # Default Rich Address +PRIVATE_KEY="0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356" # Default Rich Private Key + +echo "OPTIMISM PORTAL Address: $OPTIMISM_PORTAL" +echo "Recipient: $RECIPIENT" +cast balance $RECIPIENT --rpc-url $L2_RPC_URL +echo "Bridging 1 ETH from L1 to L2..." + +# Bridge 1 ETH to L2 +cast send $OPTIMISM_PORTAL \ + --rpc-url $L1_RPC_URL \ + --private-key $PRIVATE_KEY \ + --value 100ether + +cast send $OPTIMISM_PORTAL \ + --rpc-url $L1_RPC_URL \ + --private-key $L1_ADMIN_PRIVATE_KEY \ + --value 100ether + + + +echo -e "\nWaiting for bridging to complete..." + +echo "Checking L2 balance for $RECIPIENT:" +BALANCE=$(cast balance $RECIPIENT --rpc-url $L2_RPC_URL) +ADMIN_BALANCE=$(cast balance $L1_ADMIN_ADDRESS --rpc-url $L2_RPC_URL) + +WAIT_COUNT=0 +while [ $BALANCE == 0 ] || [ $ADMIN_BALANCE == 0 ]; do + WAIT_COUNT=$((WAIT_COUNT + 1)) + echo " ⏳ Waiting for bridge transactions to finalize... (${WAIT_COUNT})" + echo " Current L2 balance: $(cast --to-unit $BALANCE ether) ETH" + echo " Current Admin balance: $(cast --to-unit $ADMIN_BALANCE ether) ETH" + sleep 5 + BALANCE=$(cast balance $RECIPIENT --rpc-url $L2_RPC_URL) + ADMIN_BALANCE=$(cast balance $L1_ADMIN_ADDRESS --rpc-url $L2_RPC_URL) +done + +echo " ✅ Bridging complete!" +echo " Final L2 balance: $(cast --to-unit $BALANCE ether) ETH" +echo " Final Admin balance: $(cast --to-unit $ADMIN_BALANCE ether) ETH" diff --git a/test-pp-op/Makefile b/test-pp-op/Makefile new file mode 100644 index 0000000000000..e3bcf091c2529 --- /dev/null +++ b/test-pp-op/Makefile @@ -0,0 +1,204 @@ +-include .env +export + +ifeq ($(ENV),local) + COMPOSE_FILE := docker-compose-local.yml + include local.env +else + COMPOSE_FILE := docker-compose.yml + include testnet.env +endif + +DOCKER_COMPOSE := $(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose") -f ${COMPOSE_FILE} + +RUN_DOCKER_MOCK_L1_NETWORK := $(DOCKER_COMPOSE) up -d xlayer-mock-l1-network + +PAUSE := $(DOCKER_COMPOSE) down --remove-orphans; \ + sleep 3; \ + rm -Rf ./l1-geth/consensus/beacondata; \ + rm -Rf ./l1-geth/consensus/validatordata; \ + rm -Rf ./l1-geth/consensus/genesis.ssz; \ + rm -Rf ./l1-geth/execution/geth; \ + rm -Rf ./config-op/artifact.json; \ + rm -Rf ./config-op/31337-deploy.json; \ + rm -Rf ./config-op/genesis.json; \ + rm -Rf ./config-op/rollup.json; \ + rm -Rf ./config-op/state_dump.json; \ + rm -Rf ./l1-geth/execution/genesis.json; \ + rm -Rf ./config-op/genesis-op-raw.json; \ + rm -Rf ./config-op/superchain.json; \ + rm -Rf ./config-op/implementations.json; \ + + +DEPLOY_ERC20_L1 := cd contracts && forge create OKBToken.sol:StandardERC20 --private-key $(SEQUENCER_PRIVATE_KEY) --rpc-url $(L1_RPC_URL) --legacy --broadcast --constructor-args "OKBToken" "OKB" 1000000000 +INIT_ACCOUNT_1 := cast send -f $(SEQUENCER_ADDRESS) --private-key $(SEQUENCER_PRIVATE_KEY) --value 1000ether $(DEPLOYER_ADDRESS) --legacy --rpc-url $(L1_RPC_URL) +INIT_ACCOUNT_2 := cast send -f $(SEQUENCER_ADDRESS) --private-key $(SEQUENCER_PRIVATE_KEY) --value 1000ether $(AGGREGATOR_ADDRESS) --legacy --rpc-url $(L1_RPC_URL) +INIT_ACCOUNT_3 := cast send -f $(SEQUENCER_ADDRESS) --private-key $(SEQUENCER_PRIVATE_KEY) --value 1000ether $(RICH_ADDRESS) --legacy --rpc-url $(L1_RPC_URL) +INIT_ACCOUNT_4 := cast send -f $(SEQUENCER_ADDRESS) --private-key $(SEQUENCER_PRIVATE_KEY) --value 1000ether $(CHALLENGER_ADDRESS) --legacy --rpc-url $(L1_RPC_URL) + +INIT_BRIDGE_ACCOUNT := cast send -f $(DEPLOYER_ADDRESS) --private-key $(DEPLOYER_PRIVATE_KEY) --value 0.01ether $(SEQUENCER_ADDRESS) --legacy --rpc-url $(L2_ERIGON_RPC_URL) + +.PHONY: set-env +set-env: + @if [ "$(ENV)" = "local" ]; then \ + if [ -f local.env ]; then \ + cp local.env .env; \ + echo "Using local.env -> .env"; \ + else \ + echo "local.env not found"; \ + exit 1; \ + fi; \ + fi + +.PHONY: show-env +show-env: + @echo "Current ENV: $(ENV)" + @echo "Using compose file: $(COMPOSE_FILE)" + +.PHONY: run_erigon +run_erigon: set-env show-env + @echo "🚀 Starting L1 PoS environment automatic dependency management..." + $(DOCKER_COMPOSE) up -d l1-validator + @echo "🎉 L1 PoS environment started!" + sleep 30 + $(DEPLOY_ERC20_L1) + $(INIT_ACCOUNT_1) + $(INIT_ACCOUNT_2) + $(INIT_ACCOUNT_3) + $(INIT_ACCOUNT_4) + sleep 5 + ./init-erigon.sh + sleep 5 + $(DOCKER_COMPOSE) up -d xlayer-bridge-db + $(DOCKER_COMPOSE) up -d xlayer-pool-db + sleep 5 + $(DOCKER_COMPOSE) up -d xlayer-agglayer-prover + $(DOCKER_COMPOSE) up -d xlayer-agglayer + sleep 5 + + sleep 3 + $(DOCKER_COMPOSE) up -d xlayer-approve + $(DOCKER_COMPOSE) up -d xlayer-seq + $(DOCKER_COMPOSE) up -d xlayer-pool-manager + + sleep 5 + $(DOCKER_COMPOSE) up -d xlayer-rpc + + sleep 10 + $(DOCKER_COMPOSE) up -d xlayer-bridge-service + $(DOCKER_COMPOSE) up -d xlayer-bridge-ui + $(INIT_BRIDGE_ACCOUNT) + + $(DOCKER_COMPOSE) up -d xlayer-agg-sender + +.PHONY: mainnet +mainnet: + @echo "🚀 Starting XLayer Fake Mainnet ..." + $(DOCKER_COMPOSE) up -d l1-validator + sleep 20 + $(INIT_ACCOUNT_1) + $(INIT_ACCOUNT_2) + $(INIT_ACCOUNT_3) + $(INIT_ACCOUNT_4) + $(DOCKER_COMPOSE) up -d xlayer-mainnet-seq + sleep 5 + $(DOCKER_COMPOSE) up -d xlayer-rpc + +.PHONY: build-docker +build-docker: ## build images for all + ./build_images.sh --all + +.PHONY: build-force +build-force: ## Force rebuild all images + ./build_images.sh --all --force + +.PHONY: build-op-geth +build-op-geth: ## Build op-geth image only + ./build_images.sh --op-geth + +.PHONY: build-op-stack +build-op-stack: ## Build op-stack images only + ./build_images.sh --op-stack + +.PHONY: build-cdk-erigon +build-cdk-erigon: + ./build_images.sh --cdk-erigon + +.PHONY: pause +pause: ## Stops all services + $(PAUSE) + +.PHONY: stop +stop: pause + rm -rf data + +.PHONY: clean +clean: stop + rm -rf data + rm -rf config-op/genesis.json + rm -rf config-op/genesis.json.gz + rm -rf config-op/implementations.json + rm -rf config-op/intent.toml + rm -rf config-op/rollup.json + rm -rf config-op/state.json + rm -rf config-op/superchain.json + rm -rf config-op/genesis-op-before-number.json + rm -rf config-op/genesis-op-after-number.json + rm -rf config-op/merged.genesis.gz.json + rm -rf config-op/196-* + rm -rf config-op/195-* + rm -rf config-op/1952-* + rm -rf l1-geth/consensus/beacondata/ + rm -rf l1-geth/consensus/genesis.ssz + rm -rf l1-geth/consensus/validatordata/ + rm -rf l1-geth/execution/genesis.json + rm -rf l1-geth/execution/geth/ + rm -rf merged.genesis.json + rm -rf migrate.log + rm -rf .env + +.PHONY: run +run: stop + @mkdir -p tmp + @echo "OP_GETH_BRANCH: $(OP_GETH_BRANCH)" + @if [ -n "$(OP_GETH_BRANCH)" ]; then \ + echo "Initializing with branch: $(OP_GETH_BRANCH)"; \ + ./init.sh $(OP_GETH_BRANCH); \ + else \ + echo "Initializing with default branch"; \ + ./init.sh; \ + fi + ./0-all.sh + +.PHONY: run-test +run-test: + @echo "OP_GETH_LOCAL_DIRECTORY: $$OP_GETH_LOCAL_DIRECTORY" + @echo "OP_GETH_BRANCH: $(OP_GETH_BRANCH)" + @if [ -n "$$OP_GETH_LOCAL_DIRECTORY" ]; then \ + echo "Using custom local directory: $$OP_GETH_LOCAL_DIRECTORY"; \ + cd "$$OP_GETH_LOCAL_DIRECTORY"; \ + else \ + echo "Using default submodule: ../op-geth"; \ + cd ../op-geth; \ + fi && \ + if [ -n "$(OP_GETH_BRANCH)" ]; then \ + echo "Switching to branch: $(OP_GETH_BRANCH)"; \ + git fetch origin && git checkout "$(OP_GETH_BRANCH)" && git pull origin "$(OP_GETH_BRANCH)"; \ + else \ + echo "Using current branch"; \ + fi && \ + echo "Running E2E tests..."; \ + MallocNanoZone=0 go test -count=1 -failfast -race -v -p 1 -timeout 600s ./test/e2e/... + +.PHONY: test-e2e +test-e2e: stop + @trap 'make stop' EXIT ERR INT TERM; + @echo "OP_GETH_BRANCH: $(OP_GETH_BRANCH)" + if [ -n "$(OP_GETH_BRANCH)" ]; then \ + echo "Running E2E tests with branch: $(OP_GETH_BRANCH)"; \ + make run && sleep 3 && make run-test; \ + else \ + echo "Running E2E tests with default branch"; \ + make run && sleep 3 && make run-test; \ + fi && echo "✅ E2E tests passed ✅" + diff --git a/test-pp-op/README.md b/test-pp-op/README.md new file mode 100644 index 0000000000000..7375b653a7204 --- /dev/null +++ b/test-pp-op/README.md @@ -0,0 +1,393 @@ +# Optimism Test Environment Setup Guide + +## run on local +```bash +# git submodule update --recursive --force +make clean +cp local.env .env +# ./build_images.sh --all # build all images. add --force if want to force rebuild +./1-start-erigon.sh +./2-deploy-op-contracts.sh +./3-stop-erigon.sh +./4-migrate-op.sh +./5-start-op.sh +./6-build-op-program.sh +./7-setup-fraud-proof.sh +``` + +## run on testnet +```bash +make clean + +cp testnet.env .env +./m1-deploy-and-upload.sh + +# Upload with md5 hash +osstool -f upload-to-oss.tar.gz -a upload -ticket ${TICKET_ID} + + +# Download to ECS machine +osstool -a download -ticket ${TICKET_ID} + +# Unzip +tar -xzvf upload-to-oss.tar.gz +cd upload-to-oss + +# On ECS machine, just run and follow prompts. +./m2-migrate.sh +``` + +## Prerequisites + +### System Requirements +- Docker 20.10.0 or higher +- Docker Compose +- At least 32GB RAM +- At least 32GB available disk space + +> **Important**: If you encounter performance issues, increase Docker engine memory limit to over 32GB +> ![issue](./images/stuck.png) +> ![solution](./images/docker.png) + +### Initial Setup (First Time Only) +1. Run `./init.sh` to initialize the environment (only needed once): + - Install all git submodules + - Build required Docker images + - Prepare base environment + +> Important: `init.sh` should only be run once during initial setup. Re-run only if you need to rebuild Docker images after code changes. + +### Code Updates and Image Rebuilding (Optional) +If you've updated the Optimism codebase and need to rebuild Docker images: + +1. **Update image tags** in `example.env`: + ```bash + # Example: increment version numbers + OP_GETH_IMAGE_TAG=op-geth:v1.101512.0-patch + OP_STACK_IMAGE_TAG=op-stack:v1.13.5 + OP_CONTRACTS_IMAGE_TAG=op-contracts:v1.13.5 + ``` + +2. **Apply changes**: + ```bash + ./clean.sh # This will update .env from example.env + ``` + +3. **Rebuild images**: + ```bash + ./init.sh # Rebuilds all Docker images + + # Or rebuild specific images only (optional) + source .env && cd .. && docker build -t ${OP_STACK_IMAGE_TAG} -f Dockerfile-opstack . && cd - + ``` + +### Directory Structure +``` +test/ +├── 0-all.sh # One-click deployment script +├── init.sh # Initialization script +├── clean.sh # Environment cleanup script +├── 1-start-l1.sh # L1 chain startup script +├── 2-deploy-op-contracts.sh # Contract deployment script +├── 3-op-init.sh # Environment initialization script +├── 4-op-start-service.sh # Service startup script +├── scripts/ # Utility scripts +│ ├── transfer_leader.sh # Leader transfer script +│ ├── stop_leader_sequencer.sh # Sequencer stop script +│ ├── active_sequencer.sh # Check active sequencer +│ ├── add_game_type.sh # Add dispute game type +│ ├── deposit-from-l1.sh # L1 to L2 deposit script +│ ├── deposit-from-banker.sh # transfer ETH from banker script +│ └── show-dev-accounts.sh # Display dev accounts info +├── config-op/ # Configuration directory +├── data/ # Data storage directory +├── contracts/ # Smart contracts +├── images/ # Documentation images +├── example.env # Environment template +``` + +## Quick Start + +### One-Click Deployment +Run `./0-all.sh` to automatically: +- Initialize the environment +- Start all required components +- Complete all configurations and deployments + +⚠️ **Important Notes**: + +1. Configuration Management: + - Always make configuration changes in `example.env` + - Never modify `.env` directly as it will be reset by `clean.sh` + - Run `clean.sh` to apply changes from `example.env` + +2. Environment Reset: + - `clean.sh` will stop all containers + - Clean all data directories + - Reset `.env` to values from `example.env` + +> Note: For first-time setup, we recommend following the step-by-step deployment process to better understand each component and troubleshoot any potential issues. + +### Step-by-Step Deployment +For more granular control or troubleshooting, follow the steps below. + +## Deployment Process + +### 1. L1 Environment Setup +Run `./1-start-l1.sh`: +- Starts a complete PoS L1 test chain (EL + CL) +- CL node handles blob data storage +- Automatically funds test accounts: + - Batcher + - Proposer + - Challenger + +### 2. Smart Contract Deployment +Run `./2-deploy-op-contracts.sh`: +- Deploys Transactor contract +- Deploys and initializes all Optimism L1 contracts +- Generates configuration files: + - `rollup.json`: op-node configuration + - `genesis.json`: L2 initial state + +### 3. Environment Initialization +Run `./3-op-init.sh`: +- Initializes op-geth database + - Sequencer node + - RPC node +- Generates dispute game components: + - Compiles op-program + - Generates prestate files + - Creates state proofs + +### 4. Service Startup +Run `./4-op-start-service.sh`: +- Launches core services: + - op-batcher: L2 transaction batch processing + - op-proposer: L2 state submission + - op-node: State sync and validation + - op-geth: L2 execution engine + - op-challenger: State validation + - op-dispute-mon: Dispute monitoring + - op-conductor: Sequencer HA management + +### 5. Conductor Management +The test environment includes a 3-node conductor cluster for sequencer high availability (HA). + +#### Architecture +- **Cluster Type**: 3-node Raft consensus cluster +- **Active Sequencer**: Only runs on leader node +- **Failover**: Automatic when leader becomes unhealthy +- **High Availability**: Ensures continuous L2 block production + +#### Configuration +Enable or disable conductor cluster in `example.env`: +```bash +# Enable HA mode with conductor cluster +CONDUCTOR_ENABLED=true + +# Disable HA, run single sequencer +CONDUCTOR_ENABLED=false +``` + +#### Network Ports +Each conductor node uses three ports: +- **RPC Port**: Management API + - Node 1: 8547 + - Node 2: 8548 + - Node 3: 8549 + +- **Consensus Port**: Raft protocol + - Node 1: 50050 + - Node 2: 50051 + - Node 3: 50052 + +- **Sequencer Port**: L2 execution + - Node 1: 9545 + - Node 2: 9546 + - Node 3: 9547 + +#### Health Monitoring +The conductor cluster monitors each node's: +- Sync status with L1 +- P2P network connectivity +- Block production rate + +When leader becomes unhealthy: +- Automatically transfers leadership +- Deactivates unhealthy sequencer +- Activates sequencer on new leader + +#### Leadership Management +There are two ways to trigger leader transfer: + +1. Using `transfer-leader.sh`: +```bash +# Auto transfer to any healthy node +./scripts/transfer-leader.sh + +# Transfer to specific node (1 or 2 or 3) +./scripts/transfer-leader.sh 2 +``` + +2. Force transfer by stopping leader's sequencer: +```bash +# Stops block production while keeping the container running +# Automatically triggers leader transfer after health check timeout +# Can be run multiple times to test different leadership scenarios +./scripts/stop-leader-sequencer.sh +``` + +This method simulates a sequencer failure scenario, enabling comprehensive testing of automatic failover mechanisms. Each execution stops the current leader's sequencer and triggers a transfer to another node, allowing you to test different leadership scenarios by running the script multiple times. The cluster maintains high availability through dynamic role switching - when a sequencer stops producing blocks, it transitions to follower status while another node assumes leadership. The system remains resilient as any follower can automatically promote to leader if the current leader encounters issues. + +3. Gray upgrade using op-conductor: +```bash +# Emulate the whole gray upgrade process to achieve 0 downtime +./scripts/gray-upgrade-simulation.sh +# Meanwhile, open another terminal window to load test +polycli loadtest --rpc-url http://localhost:8124 \ + --private-key "0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356" \ + --verbosity 700 --requests 50000 -c 1 --rate-limit -1 +``` + +The `scripts/gray-upgrade-simulation.sh` script simulates a rolling upgrade process for the sequencer cluster managed by op-conductor. It upgrades a follower sequencer while keeping the leader running, then transfers leadership to the upgraded node. This approach ensures service continuity and validates the cluster's resilience during upgrades. + +## Utility Scripts + +### L1 to L2 Deposit Script + +The `scripts/deposit-from-l1.sh` script facilitates testing L1 to L2 cross-chain deposits: + +#### Features +- **Automatic Deposit**: Deposits 3000 ETH from L1 to L2 +- **Balance Monitoring**: Monitors L2 balance changes in real-time +- **Wait Time Tracking**: Measures total deposit confirmation time +- **Status Updates**: Provides clear progress feedback + +#### Usage +```bash +# Run the deposit script +./scripts/deposit-from-l1.sh +``` + +#### What it does +1. **Funds Test Account**: Sends ETH to the test account on L1 +2. **Creates Deposit Transaction**: Calls OptimismPortal.depositTransaction() +3. **Monitors L2 Balance**: Continuously checks L2 balance until change detected +4. **Reports Results**: Shows deposit confirmation time and balance changes + +#### Configuration +The script uses these default parameters: +- **Deposit Amount**: 3000 ETH +- **Gas Limit**: 100,000 +- **Target Address**: Same as sender (self-deposit) +- **L2 RPC**: http://127.0.0.1:8123 + +This script is useful for: +- Testing cross-chain deposit functionality +- Measuring deposit confirmation times +- Verifying L1/L2 synchronization +- Validating OptimismPortal contract integration + +### Banker Account Deposit Script + +The `scripts/deposit-from-banker.sh` script enables large-scale testing using a banker account with massive balance: + +#### Features +- **Large Amount Transfers**: Transfers 1,000,000 ETH (1 million ETH) +- **Banker Account**: Uses a pre-funded account with astronomical balance +- **Simple Transfer**: Direct ETH transfer without cross-chain complexity +- **Legacy Transaction**: Uses legacy transaction format for compatibility + +#### Usage +```bash +# Run the banker deposit script +./scripts/deposit-from-banker.sh +``` + +#### What it does +1. **Uses Banker Account**: Leverages account `0x70997970C51812dc3A010C7d01b50e0d17dc79C8` +2. **Large Transfer**: Sends 1,000,000 ETH to target address +3. **Direct Transfer**: Simple ETH transfer on L2 network +4. **Legacy Format**: Uses legacy transaction format + +### Development Accounts Display Script + +The `scripts/show-dev-accounts.sh` script displays all development accounts with their private keys: + +#### Features +- **Account Listing**: Shows all 30 development accounts (paths 0-29) +- **Private Key Display**: Reveals private keys for testing +- **Address Generation**: Shows corresponding addresses +- **Mnemonic Path**: Displays derivation paths + +#### Usage +```bash +# Display all dev accounts +./scripts/show-dev-accounts.sh +``` + +#### What it does +1. **Generates Accounts**: Creates 30 accounts from standard mnemonic (paths 0-29) +2. **Shows Details**: Displays address, private key, and derivation path +3. **Standard Mnemonic**: Uses "test test test test test test test test test test test junk" +4. **Path Format**: Uses `m/44'/60'/0'/0/{i}` derivation paths + +#### Important Notes +- **Balance Status**: Most dev accounts are pre-funded with 10,000 ETH, but some accounts may have zero initial balance + +## Troubleshooting + +### Common Issues + +#### 1. Service Startup Failures +- **Check Docker logs**: `docker compose logs ` +- **Verify port availability**: Ensure ports 8545, 8546, 4000, 3500 are free +- **Validate environment variables**: Check `.env` file matches `example.env` +- **Memory issues**: Increase Docker memory limit to 32GB+ + +#### 2. Contract Deployment Issues +- **Verify L1 node is running**: Check `docker compose ps` +- **Check account balances**: Ensure test accounts have sufficient ETH +- **Validate gas settings**: Check gas limit and price in deployment logs + +#### 3. Synchronization Issues +- **L2 not syncing**: Check op-geth-seq is running and producing blocks +- **RPC node issues**: Verify op-geth-rpc can connect to op-geth-seq +- **Genesis mismatch**: Ensure rollup.json matches actual L2 genesis + +#### 4. Conductor Cluster Issues +- **Leader election problems**: Check Raft consensus logs +- **Sequencer not switching**: Verify health check configuration +- **P2P connectivity**: Check network configuration and firewall + +## Service Ports Overview + +| Service | Port | Description | +|---------|------|-------------| +| **L1 Services** | | | +| l1-geth | 8545 | L1 Ethereum RPC | +| l1-geth | 8546 | L1 Ethereum WebSocket | +| l1-geth | 8551 | L1 Ethereum Engine API | +| l1-beacon-chain | 4000 | L1 Beacon RPC | +| l1-beacon-chain | 3500 | L1 Beacon HTTP | +| l1-beacon-chain | 18080 | L1 Beacon Metrics | +| **L2 Services** | | | +| op-geth-seq | 8123 | L2 Sequencer RPC | +| op-geth-seq | 7546 | L2 Sequencer WebSocket | +| op-geth-seq | 8552 | L2 Sequencer Engine API | +| op-geth-rpc | 9123 | L2 RPC Node RPC | +| op-seq | 9545 | L2 Node RPC | +| op-seq | 7070 | L2 Node P2P | +| op-seq | 9223 | L2 Node P2P (UDP) | +| op-rpc | 9555 | L2 RPC Node RPC | +| **Conductor Cluster** | | | +| op-conductor | 8547 | Conductor 1 RPC | +| op-conductor | 50050 | Conductor 1 Consensus | +| op-conductor2 | 8548 | Conductor 2 RPC | +| op-conductor2 | 50051 | Conductor 2 Consensus | +| op-conductor3 | 8549 | Conductor 3 RPC | +| op-conductor3 | 50052 | Conductor 3 Consensus | +| **Other Services** | | | +| op-batcher | 8548 | Batcher RPC | +| op-proposer | 8560 | Proposer RPC | diff --git a/test-pp-op/build_images.sh b/test-pp-op/build_images.sh new file mode 100755 index 0000000000000..11a598914a708 --- /dev/null +++ b/test-pp-op/build_images.sh @@ -0,0 +1,300 @@ +#!/bin/bash +set -e + +# ============================================================================= +# Build Images Script +# ============================================================================= +# This script builds Docker images for the OP-Geth project with support for +# selective building and force rebuilds. +# +# USAGE: +# ./build_images.sh [OPTIONS] +# +# OPTIONS: +# --op-geth Build op-geth image only +# --op-stack Build op-stack images only (contracts + opstack) +# --op-contract Build op-contracts images only +# --bridge Build bridge service image only +# --aggkit Build aggkit image only +# --all Build all images (default if no options specified) +# --force Force rebuild even if images exist +# -h, --help Show this help message +# +# EXAMPLES: +# ./build_images.sh # Build all images (default) +# ./build_images.sh --op-geth # Build op-geth only +# ./build_images.sh --op-stack # Build op-stack only +# ./build_images.sh --bridge # Build bridge service only +# ./build_images.sh --aggkit # Build aggkit only +# ./build_images.sh --all --force # Force rebuild all images +# ./build_images.sh --op-geth --force # Force rebuild op-geth only +# ./build_images.sh --help # Show help +# +# IMAGES BUILT: +# - OP-Geth: Ethereum client with OP Stack modifications +# - OP-Stack: Core OP Stack components (contracts + opstack) +# - Bridge Service: Patched zkevm-bridge-service +# - AggKit: OKX aggregation toolkit +# ============================================================================= + +source .env + +# Default values +ARCH=$(docker version --format '{{.Server.Os}}/{{.Server.Arch}}') +BUILD_CDK_ERIGON=false +BUILD_OP_GETH=false +BUILD_OP_GETH_MIGRATE=false +BUILD_OP_STACK=false +BUILD_OP_CONTRACT=false +BUILD_BRIDGE=false +BUILD_AGGKIT=false +BUILD_ALL=false +FORCE=false + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + --cdk-erigon) + BUILD_CDK_ERIGON=true + shift + ;; + --op-geth) + BUILD_OP_GETH=true + shift + ;; + --op-geth-migrate) + BUILD_OP_GETH_MIGRATE=true + shift + ;; + --op-stack) + BUILD_OP_STACK=true + shift + ;; + --op-contract) + BUILD_OP_CONTRACT=true + shift + ;; + --bridge) + BUILD_BRIDGE=true + shift + ;; + --aggkit) + BUILD_AGGKIT=true + shift + ;; + --all) + BUILD_ALL=true + shift + ;; + --force) + FORCE=true + shift + ;; + --arch) + echo "ARCH: $2" + ARCH="$2" + shift 2 + ;; + -h|--help) + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --cdk-erigon Build cdk-erigon image only" + echo " --op-geth Build op-geth image only" + echo " --op-geth-migrate Build op-geth-migrate image only" + echo " --op-stack Build op-stack images" + echo " --op-contract Build op contract image" + echo " --bridge Build bridge service image only" + echo " --aggkit Build aggkit image only" + echo " --all Build all images (default if no options specified)" + echo " --force Force rebuild even if images exist" + echo " -h, --help Show this help message" + exit 0 + ;; + *) + echo "Unknown option: $1" + echo "Use --help for usage information" + exit 1 + ;; + esac +done + +# If no specific options provided, build all +if [ "$BUILD_OP_GETH" = false ] && [ "$BUILD_CDK_ERIGON" = false ] && [ "$BUILD_OP_STACK" = false ] && [ "$BUILD_OP_CONTRACT" = false ] && [ "$BUILD_BRIDGE" = false ] && [ "$BUILD_AGGKIT" = false ] && [ "$BUILD_OP_GETH_MIGRATE" = false ] && [ "$BUILD_ALL" = false ]; then + BUILD_ALL=true +fi + +# If --all is specified, set all flags +if [ "$BUILD_ALL" = true ]; then + BUILD_CDK_ERIGON=true + BUILD_OP_GETH=true + BUILD_OP_GETH_MIGRATE=true + BUILD_OP_STACK=true + BUILD_OP_CONTRACT=true + BUILD_BRIDGE=true + BUILD_AGGKIT=true +fi + +build_patched_zkevm_bridge_service_image() { + echo "build patched zkevm bridge service image" + PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + rm -rf $PWD_DIR/tmp/zkevm-bridge-service + mkdir -p $PWD_DIR/tmp + cd $PWD_DIR/tmp/ + git clone -b v0.6.0-RC16 https://github.com/0xPolygon/zkevm-bridge-service.git + # it has docker file + cd zkevm-bridge-service + + # patch zkevm-bridge-service + git apply $PWD_DIR/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch + git apply $PWD_DIR/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch + git apply $PWD_DIR/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch + + docker build --platform $ARCH -t $XLAYER_BRIDGE_SERVICE_IMAGE_TAG . + cd $PWD_DIR +} + +build_aggkit_image() { + echo "build aggkit image" + PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + rm -rf $PWD_DIR/tmp/aggkit + mkdir -p $PWD_DIR/tmp + cd $PWD_DIR/tmp/ + + echo "Cloning contract repository..." + git clone -b feature/0.1.0 https://github.com/okx/aggkit.git + cd ./aggkit + echo "Cleaning and resting contract repository..." + git reset --hard; git checkout feature/0.1.0;git pull + make build-docker + cd $PWD_DIR +} + +build_cdk_erigon_image() { + echo "build cdk_erigon image" + PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + rm -rf $PWD_DIR/tmp/xlayer-erigon + mkdir -p $PWD_DIR/tmp + cd $PWD_DIR/tmp/ + + echo "Cloning cdk-erigon repository..." + git clone -b dev https://github.com/okx/xlayer-erigon.git + cd ./xlayer-erigon + git reset --hard; git checkout dev;git pull + docker build --platform $ARCH -t ${CDK_ERIGON_IMAGE_TAG} -f ./Dockerfile.local . + cd $PWD_DIR +} + +build_op_stack_contract() { + echo "build op stack image" + PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + + # cp Transactor.sol to optimism, which is used for addGameType + cp $PWD_DIR/contracts/Transactor.sol ../packages/contracts-bedrock/src/periphery/Transactor.sol + + cd .. + docker build $( [ "$FORCE" = true ] && echo --no-cache ) --platform $ARCH -t $OP_CONTRACTS_IMAGE_TAG -f Dockerfile-contracts . + + cd $PWD_DIR + +} + +build_op_stack_image() { + echo "build op stack image" + # Check if op_contract image exists + if ! image_exists "$OP_CONTRACTS_IMAGE_TAG"; then + echo "Error: OP contracts image ($OP_CONTRACTS_IMAGE_TAG) does not exist." + echo "Please build the contracts image first using --op-contract or --all" + exit 1 + fi + + PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + + cd .. + docker tag "$OP_CONTRACTS_IMAGE_TAG" "op-contracts:latest" + docker build --platform $ARCH -t $OP_STACK_IMAGE_TAG -f Dockerfile-opstack . + docker tag "op-contracts:latest" "$OP_CONTRACTS_IMAGE_TAG" + + cd $PWD_DIR +} + +build_op_geth_migrate_image() { + echo "build op-geth image" + PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + PROJECT_ROOT="$(git rev-parse --show-toplevel)" + + # If tmp/optimism doesn't exist, clone it + if [ ! -d "$PWD_DIR/tmp/op-geth" ]; then + rm -rf $PWD_DIR/tmp/op-geth + mkdir -p $PWD_DIR/tmp + cd $PWD_DIR/tmp/ + echo "Cloning op-geth repository..." + git clone --recurse-submodules -b dev-op https://github.com/okx/op-geth.git + cd $PWD_DIR + fi + + # Must build at test-pp-op to copy config files (eg. .env) over as well. + docker build --platform $ARCH -t $OP_GETH_MIGRATION_IMAGE_TAG --progress=plain --no-cache -f dockerfile/Dockerfile.migrate . + # cd "$PWD_DIR/tmp/op-geth" + # docker build --platform $ARCH -t $OP_GETH_MIGRATION_IMAGE_TAG . + cd $PWD_DIR +} + +build_op_geth_image() { + echo "build op-geth image" + PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + + cd ../op-geth + docker build $( [ "$FORCE" = true ] && echo --no-cache ) --platform $ARCH -t $OP_GETH_IMAGE_TAG . + cd $PWD_DIR +} + +# Helper function to check if image exists +image_exists() { + local image_tag=$1 + docker image inspect "$image_tag" >/dev/null 2>&1 +} + +# Helper function to build if needed +build_if_needed() { + local image_tag=$1 + local build_function=$2 + local description=$3 + + if [ "$FORCE" = true ] || ! image_exists "$image_tag"; then + echo "Building $description..." + $build_function + else + echo "Image $image_tag already exists (use --force to rebuild)" + fi +} + +# Build images based on selected options +if [ "$BUILD_OP_CONTRACT" = true ]; then + build_if_needed "$OP_CONTRACTS_IMAGE_TAG" "build_op_stack_contract" "OP Stack contracts" +fi + +if [ "$BUILD_OP_STACK" = true ]; then + build_if_needed "$OP_STACK_IMAGE_TAG" "build_op_stack_image" "OP Stack image" +fi + +if [ "$BUILD_OP_GETH" = true ]; then + build_if_needed "$OP_GETH_IMAGE_TAG" "build_op_geth_image" "OP-Geth image" +fi + +if [ "$BUILD_OP_GETH_MIGRATE" = true ]; then + build_if_needed "$OP_GETH_MIGRATION_IMAGE_TAG" "build_op_geth_migrate_image" "OP-Geth migrate image" +fi + +if [ "$BUILD_CDK_ERIGON" = true ]; then + build_if_needed "$CDK_ERIGON_IMAGE_TAG" "build_cdk_erigon_image" "cdk-erigon image" +fi + +if [ "$BUILD_BRIDGE" = true ]; then + build_if_needed "$XLAYER_BRIDGE_SERVICE_IMAGE_TAG" "build_patched_zkevm_bridge_service_image" "patched zkevm bridge service" +fi + +if [ "$BUILD_AGGKIT" = true ]; then + build_if_needed "aggkit:local" "build_aggkit_image" "aggkit" +fi + +echo "Build completed!" diff --git a/test-pp-op/config-op/intent.fakemainnet.toml.bak b/test-pp-op/config-op/intent.fakemainnet.toml.bak new file mode 100644 index 0000000000000..d423adaa5a5e3 --- /dev/null +++ b/test-pp-op/config-op/intent.fakemainnet.toml.bak @@ -0,0 +1,35 @@ +configType = "standard-overrides" +l1ChainID = 11155111 +fundDevAccounts = false +opcmAddress = "0x0000000000000000000000000000000000000000" +l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" +l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" + +[[chains]] + id = "0x00000000000000000000000000000000000000000000000000000000000000C4" + baseFeeVaultRecipient = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" + l1FeeVaultRecipient = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" + sequencerFeeVaultRecipient = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" + eip1559DenominatorCanyon = 100000000 + eip1559Denominator = 100000000 + eip1559Elasticity = 1 + operatorFeeScalar = 0 + operatorFeeConstant = 0 + gasLimit = 50000000 + [chains.deployOverrides] + l2GenesisBlockGasLimit = "0x2faf080" + l2GenesisBlockBaseFeePerGas = "0x5FC01C5" + l2BlockTime = 1 + [chains.customGasToken] + enabled = true + name = "OKB" + symbol = "OKB" + initialLiquidity = "0x0" + [chains.roles] + l1ProxyAdminOwner = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" + l2ProxyAdminOwner = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" + systemConfigOwner = "0x1183f158515091c94188C13Cd16923cee663d4c4" + unsafeBlockSigner = "0xe44FaF74D0EA83D962BB8cE077F69e449c6D8c4a" + batcher = "0x02E0eF87B04FD60E7F2215D1932420a80Cc35c55" + proposer = "0xe43944421681170648e10007f73816e04f74394f" + challenger = "0x736e68af2cbf2ab0e46e4310fe5ae568b3642ff6" diff --git a/test-pp-op/config-op/intent.local.toml.bak b/test-pp-op/config-op/intent.local.toml.bak new file mode 100644 index 0000000000000..3265223ca8fd1 --- /dev/null +++ b/test-pp-op/config-op/intent.local.toml.bak @@ -0,0 +1,36 @@ +configType = "standard-overrides" +l1ChainID = 1337 +fundDevAccounts = true +opcmAddress = "0x0000000000000000000000000000000000000000" +l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" +l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" + +[[chains]] + id = "0x00000000000000000000000000000000000000000000000000000000000000c3" + baseFeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + l1FeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + sequencerFeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + eip1559DenominatorCanyon = 250 + eip1559Denominator = 50 + eip1559Elasticity = 6 + operatorFeeScalar = 0 + operatorFeeConstant = 0 + gasLimit = 30000000 + minBaseFee = 1000000 + [chains.deployOverrides] + l2GenesisBlockGasLimit = "0xbebc200" + l2GenesisBlockBaseFeePerGas = "0x3B9ACA00" + l2BlockTime = 1 + [chains.customGasToken] + enabled = true + name = "OKB" + symbol = "OKB" + initialLiquidity = "0x0" + [chains.roles] + l1ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + l2ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + systemConfigOwner = "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" + unsafeBlockSigner = "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc" + batcher = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" + proposer = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" + challenger = "0x7d18A1B858253b5588f61fb5739d52e4b84e2cdA" diff --git a/test-pp-op/config-op/intent.mainnet.toml.bak b/test-pp-op/config-op/intent.mainnet.toml.bak new file mode 100644 index 0000000000000..8c2059f99af90 --- /dev/null +++ b/test-pp-op/config-op/intent.mainnet.toml.bak @@ -0,0 +1,36 @@ +configType = "standard-overrides" +l1ChainID = 1 +fundDevAccounts = false +opcmAddress = "0x0000000000000000000000000000000000000000" +l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" +l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" + +[[chains]] + id = "0x00000000000000000000000000000000000000000000000000000000000000C4" + baseFeeVaultRecipient = "0x610DE9141a2c51A9A9624278AA97fbE54b27c102" + l1FeeVaultRecipient = "0x610DE9141a2c51A9A9624278AA97fbE54b27c102" + sequencerFeeVaultRecipient = "0x610DE9141a2c51A9A9624278AA97fbE54b27c102" + eip1559DenominatorCanyon = 100000000 + eip1559Denominator = 100000000 + eip1559Elasticity = 1 + operatorFeeScalar = 0 + operatorFeeConstant = 0 + gasLimit = 50000000 + [chains.deployOverrides] + l2GenesisBlockGasLimit = "0x2faf080" + l2GenesisBlockBaseFeePerGas = "0x5FC01C5" + l2BlockTime = 1 + sequencerWindowSize = 7200 + [chains.customGasToken] + enabled = true + name = "OKB" + symbol = "OKB" + initialLiquidity = "0x0" + [chains.roles] + l1ProxyAdminOwner = "0x0000000000000000000000000000000000000000" + l2ProxyAdminOwner = "0xF21637a6d8407aaE4bB0a051986261832dD91DDD" + systemConfigOwner = "0xAd9bCE315bF77C0Ade22097199953381C6Cc72eE" + unsafeBlockSigner = "0x09dA216351B5E3df326220DaDA71cCCEEcD0D2f3" + batcher = "0xdfd6C636Dcb5a013c2431316c4A0762B84e70a5d" + proposer = "0xE43944421681170648E10007f73816e04F74394F" + challenger = "0x736E68Af2CbF2aB0E46E4310fE5Ae568b3642FF6" diff --git a/test-pp-op/config-op/intent.testnet.toml.bak b/test-pp-op/config-op/intent.testnet.toml.bak new file mode 100644 index 0000000000000..44b5ea978ea98 --- /dev/null +++ b/test-pp-op/config-op/intent.testnet.toml.bak @@ -0,0 +1,35 @@ +configType = "standard-overrides" +l1ChainID = 11155111 +fundDevAccounts = false +opcmAddress = "0x0000000000000000000000000000000000000000" +l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" +l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" + +[[chains]] + id = "0x00000000000000000000000000000000000000000000000000000000000007A0" + baseFeeVaultRecipient = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" + l1FeeVaultRecipient = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" + sequencerFeeVaultRecipient = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" + eip1559DenominatorCanyon = 100000000 + eip1559Denominator = 100000000 + eip1559Elasticity = 1 + operatorFeeScalar = 0 + operatorFeeConstant = 0 + gasLimit = 30000000 + [chains.deployOverrides] + l2GenesisBlockGasLimit = "0x1C9C380" + l2GenesisBlockBaseFeePerGas = "0x5FC01C5" + l2BlockTime = 1 + [chains.customGasToken] + enabled = true + name = "OKB" + symbol = "OKB" + initialLiquidity = "0x0" + [chains.roles] + l1ProxyAdminOwner = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" + l2ProxyAdminOwner = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" + systemConfigOwner = "0x1183f158515091c94188C13Cd16923cee663d4c4" + unsafeBlockSigner = "0x8A8926FEbCFEdD0B189886858B32ad1e7F4a5b4B" + batcher = "0x8EDf9B54e1c693b7B0caEa85E6a005C35e229124" + proposer = "0x829D57F38D2A94514a3dbA2297fDD1Bc52bB1938" + challenger = "0x7c3787BF0D78a9e2F802916110e4Ddd6E3eD262C" diff --git a/test-pp-op/config-op/intent.toml.bak b/test-pp-op/config-op/intent.toml.bak new file mode 100644 index 0000000000000..cf04ac0b40e8b --- /dev/null +++ b/test-pp-op/config-op/intent.toml.bak @@ -0,0 +1,35 @@ +configType = "standard-overrides" +l1ChainID = 1337 +fundDevAccounts = true +opcmAddress = "0x0000000000000000000000000000000000000000" +l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" +l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" + +[[chains]] + id = "0x00000000000000000000000000000000000000000000000000000000000000c4" + baseFeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + l1FeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + sequencerFeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + eip1559DenominatorCanyon = 250 + eip1559Denominator = 50 + eip1559Elasticity = 6 + gasLimit = 60000000 + operatorFeeScalar = 0 + operatorFeeConstant = 0 + [chains.deployOverrides] + l2GenesisBlockGasLimit = "0xbebc200" + l2GenesisBlockBaseFeePerGas = "0x3B9ACA00" + l2BlockTime = 1 + [chains.roles] + l1ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + l2ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + systemConfigOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + unsafeBlockSigner = "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc" + batcher = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" + proposer = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" + challenger = "0x7d18A1B858253b5588f61fb5739d52e4b84e2cdA" + [chains.customGasToken] + enabled = true + name = "OKB" + symbol = "OKB" + InitialLiquidity = "0x0" # 0 OKB, no premint diff --git a/test-pp-op/config-op/jwt.txt b/test-pp-op/config-op/jwt.txt new file mode 100644 index 0000000000000..f9be65a53906f --- /dev/null +++ b/test-pp-op/config-op/jwt.txt @@ -0,0 +1 @@ +0c00f14247582fcd3c837311148cda1f56e7c2caa42fb1ba8a3cc7843603846e diff --git a/test-pp-op/config-op/state.json.bak b/test-pp-op/config-op/state.json.bak new file mode 100755 index 0000000000000..466b3f965891e --- /dev/null +++ b/test-pp-op/config-op/state.json.bak @@ -0,0 +1,13 @@ +{ + "version": 1, + "create2Salt": "0x0000000000000000000000000000000000000000000000000000000000000000", + "appliedIntent": null, + "prestateManifest": null, + "superchainContracts": null, + "superchainRoles": null, + "implementationsDeployment": null, + "opChainDeployments": null, + "l1StateDump": null, + "DeploymentCalldata": null +} + diff --git a/test-pp-op/config-op/test.rpc.config.toml b/test-pp-op/config-op/test.rpc.config.toml new file mode 100644 index 0000000000000..d0470fc21f615 --- /dev/null +++ b/test-pp-op/config-op/test.rpc.config.toml @@ -0,0 +1,38 @@ +[Node] +HTTPHost = "0.0.0.0" +HTTPPort = 8545 +HTTPCors = ["*"] +HTTPVirtualHosts = ["*"] +HTTPModules = ["web3", "debug", "eth", "txpool", "net", "engine", "miner", "admin"] +WSHost = "0.0.0.0" +WSPort = 7546 +WSOrigins = ["*"] +WSModules = ["debug", "eth", "txpool", "net", "engine"] +AuthAddr = "0.0.0.0" +AuthPort = 8552 +AuthVirtualHosts = ["*"] +JWTSecret = "/jwt.txt" + +[Node.P2P] +MaxPeers = 30 +DiscoveryV5 = true + +[Eth] +NetworkId = 901 +SyncMode = "full" +EnableInnerTx = true + + +[Eth.GPO] +Blocks = 20 +Percentile = 60 +MaxHeaderHistory = 1024 +MaxBlockHistory = 1024 +MaxPrice = "50000000000" #50GWei +IgnorePrice = "2" +MinSuggestedPriorityFee = 1 + +[Eth.GPO.XLayer] +Type = "default" +UpdatePeriod = 3000000000 # 3s +Default = "100000000" # 0.1 GWei diff --git a/test-pp-op/config-op/test.seq.config.toml b/test-pp-op/config-op/test.seq.config.toml new file mode 100644 index 0000000000000..117652fb59b31 --- /dev/null +++ b/test-pp-op/config-op/test.seq.config.toml @@ -0,0 +1,46 @@ +[Node] +HTTPHost = "0.0.0.0" +HTTPPort = 8545 +HTTPCors = ["*"] +HTTPVirtualHosts = ["*"] +HTTPModules = ["web3", "debug", "eth", "txpool", "net", "engine", "miner", "admin"] +WSHost = "0.0.0.0" +WSPort = 7546 +WSOrigins = ["*"] +WSModules = ["debug", "eth", "txpool", "net", "engine"] +AuthAddr = "0.0.0.0" +AuthPort = 8552 +AuthVirtualHosts = ["*"] +JWTSecret = "/jwt.txt" + +[Node.P2P] +MaxPeers = 30 +DiscoveryV5 = true + +[Eth] +NetworkId = 901 +SyncMode = "full" +EnableInnerTx = true + + + +[Eth.TxPool] +GlobalSlots = 500000 +GlobalQueue = 100000 +AccountSlots = 50000 +AccountQueue = 10000 + + +[Eth.GPO] +Blocks = 20 +Percentile = 60 +MaxHeaderHistory = 1024 +MaxBlockHistory = 1024 +MaxPrice = "50000000000" #50GWei +IgnorePrice = "2" +MinSuggestedPriorityFee = 1 + +[Eth.GPO.XLayer] +Type = "default" +UpdatePeriod = 3000000000 # 3s +Default = "100000000" # 0.1 GWei diff --git a/test-pp-op/config/aggkit.toml b/test-pp-op/config/aggkit.toml new file mode 100644 index 0000000000000..3740349a09bcd --- /dev/null +++ b/test-pp-op/config/aggkit.toml @@ -0,0 +1,129 @@ +PathRWData = "/tmp/" +L1URL="http://l1-geth:8545" + +L2URL="http://xlayer-rpc:8545" + +AggLayerURL="xlayer-agglayer:4443" + +ForkId = 13 +ContractVersions = "banana" +IsValidiumMode = false +NetworkID = 1 + +L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" +SequencerPrivateKeyPath = "/etc/aggkit/sequencer.keystore" +SequencerPrivateKeyPassword = "testonly" + +AggregatorPrivateKeyPath = "/etc/aggkit/aggregator.keystore" +AggregatorPrivateKeyPassword = "testonly" +SenderProofToL1Addr = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" +polygonBridgeAddr = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" + +rollupCreationBlockNumber = "91" +rollupManagerCreationBlockNumber = "100" +genesisBlockNumber = "91" + +[Common] +NetworkID = 1 +IsValidiumMode = false +ContractVersions = "banana" +# TODO, should we config with base +L2RPC = { Mode = "basic", URL = "{{L2URL}}", OpNodeURL = "http://op-rpc:8545" } + +[L1Config] +chainId = "1337" +polygonZkEVMGlobalExitRootAddress = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" +polygonRollupManagerAddress = "0xE96dBF374555C6993618906629988d39184716B3" +polTokenAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3" +polygonZkEVMAddress = "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" + +[L2Config] +GlobalExitRootAddr = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" + +[Log] +Environment = "development" +Level = "debug" +Outputs = ["stderr"] + +[RPC] +Port = 5576 + +[AggSender] +StoragePath = "/tmp/aggsender.sqlite" +AggsenderPrivateKey = {Path = "/etc/aggkit/sequencer.keystore", Password = "testonly"} +CheckStatusCertificateInterval = "1s" +Mode="PessimisticProof" +UseAgglayerTLS = false +MaxCertSize = 0 +MaxL2BlockNumber = 0 +StopOnFinishedSendingAllCertificates = false + +[AggSender.MaxSubmitCertificateRate] +NumRequests = 20 +Interval = "1m" +BlockFinality = "LatestBlock" +SaveCertificatesToFilesPath = "/tmp/certificates" +KeepCertificatesHistory = true +[AggOracle] +BlockFinality = "LatestBlock" +WaitPeriodNextGER = "10s" + +[AggOracle.EVMSender] +GlobalExitRootL2 = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" +WaitPeriodMonitorTx = "10s" + +[AggOracle.EVMSender.EthTxManager] +PrivateKeys = [{Path = "/etc/aggkit/aggoracle.keystore", Password = "testonly"}] +[AggOracle.EVMSender.EthTxManager.Etherman] +L1ChainID = "195" + +[BridgeL1Sync] +BlockFinality = "LatestBlock" + +[BridgeL2Sync] +BridgeAddr = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" + +DBPath = "/tmp/bridgel2sync.sqlite" +BlockFinality = "LatestBlock" + +SyncBlockChunkSize = 1000 + +[ReorgDetectorL1] +DBPath = "/tmp/reorgdetectorl1.sqlite" +LatestBlock="LatestBlock" + +[ReorgDetectorL2] +DBPath = "/tmp/reorgdetectorl2.sqlite" +LatestBlock="LatestBlock" + +[L1InfoTreeSync] +InitialBlock = "36" +BlockFinality = "LatestBlock" + +[LastGERSync] +BlockFinality = "LatestBlock" + +[ClaimSponsor] +DBPath = "/tmp/claimsponsor.sqlite" +Enabled = false + +SenderAddr = "0x5f5dB0D4D58310F53713eF4Df80ba6717868A9f8" + +BridgeAddrL2 = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" + +[ClaimSponsor.EthTxManager] +PrivateKeys = [ + {Path = "/etc/aggkit/claimtxmanager.keystore", Password = ""}, +] + +StoragePath = "" + +[ClaimSponsor.EthTxManager.Etherman] +URL = "" + +L1ChainID = "195" + +[Profiling] +ProfilingHost = "0.0.0.0" + +ProfilingPort = 6060 \ No newline at end of file diff --git a/test-pp-op/config/agglayer-config.toml b/test-pp-op/config/agglayer-config.toml new file mode 100644 index 0000000000000..d070a4ce6aee8 --- /dev/null +++ b/test-pp-op/config/agglayer-config.toml @@ -0,0 +1,91 @@ +prover-entrypoint = "http://xlayer-agglayer-prover:4445" +debug-mode = true + +# Only supported by fork 12+ +mock-verifier = true + +[full-node-rpcs] +# TODO switch this to permissionless +1 = "http://op-geth-rpc:8545" + +[proof-signers] +1 = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" + +[rpc] +grpc-port = 4443 +readrpc-port = 4444 +admin-port = 4446 +host = "0.0.0.0" +request-timeout = 180 +# size is define in bytes e.g. 100 * 1024 * 1024 +# same for `max_response_body_size` +# default value is equal to 10MB +max-request-body-size = 104857600 + +[prover.grpc] +# size is define in bytes e.g. 100 * 1024 * 1024 +# same for `max-encoding-message-size` +# default value is equal to 4MB +max-decoding-message-size = 104857600 + +[outbound.rpc.settle] +max-retries = 3 +retry-interval = 7 +confirmations = 1 +settlement-timeout = 1200 + +[log] +# level = "info" +# we want debug visibility here for now +level = "debug" +outputs = ["stderr"] +format = "json" + +[auth.local] +private-keys = [ + { path = "/etc/zkevm/agglayer.keystore", password = "testonly" }, +] + +[l1] +chain-id = 1337 +node-url = "http://l1-geth:8545" +ws-node-url = "ws://l1-geth:8546" +rollup-manager-contract = "0xE96dBF374555C6993618906629988d39184716B3" +polygon-zkevm-global-exit-root-v2-contract = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" +rpc-timeout = 45 + +[l2] +rpc-timeout = 45 + +[telemetry] +prometheus-addr = "0.0.0.0:9092" + +# https://github.com/orgs/agglayer/discussions/213 + +[rate-limiting] +send-tx = "unlimited" +# [rate-limiting.send-tx] +# max-per-interval = 1 +# time-interval = "15m" + +[rate-limiting.network] + +[epoch.block-clock] +epoch-duration = 6 +genesis-block = 0 + +[shutdown] +runtime-timeout = 5 + +[certificate-orchestrator] +input-backpressure-buffer-size = 1000 + +[certificate-orchestrator.prover.sp1-local] + +[storage] +db-path = "/etc/zkevm/storage" + +[storage.backup] +path = "/etc/zkevm/backups" +state-max-backup-count = 100 +pending-max-backup-count = 100 \ No newline at end of file diff --git a/test-pp-op/config/agglayer-prover-config.toml b/test-pp-op/config/agglayer-prover-config.toml new file mode 100644 index 0000000000000..fb7255e14c7f9 --- /dev/null +++ b/test-pp-op/config/agglayer-prover-config.toml @@ -0,0 +1,25 @@ +grpc-endpoint = "0.0.0.0:4445" +max-concurrency-limit = 100 +max-request-duration = 300 +max-buffered-queries = 100 + +[log] +environment = "production" # "production" or "development" +# level = "info" +level = "debug" +outputs = ["stderr"] +format = "json" + +[telemetry] +prometheus-addr = "0.0.0.0:9093" + + +[primary-prover.mock-prover] + +proving-timeout = 900 + +[grpc] +# size is define in bytes e.g. 100 * 1024 * 1024 +# same for `max-encoding-message-size` +# default value is equal to 4MB +max-decoding-message-size = 104857600 \ No newline at end of file diff --git a/test-pp-op/config/cdk.config.toml b/test-pp-op/config/cdk.config.toml new file mode 100644 index 0000000000000..8500a1af38bfc --- /dev/null +++ b/test-pp-op/config/cdk.config.toml @@ -0,0 +1,296 @@ +ForkUpgradeBatchNumber = 0 +ForkUpgradeNewForkId = 0 + +[Log] +Environment = "development" # "production" or "development" +Level = "info" +Outputs = ["stderr"] + +[NetworkConfig.L1] +L1ChainID = 1337 +PolAddr = "0x5FbDB2315678afecb367f032d93F642f64180aa3" +ZkEVMAddr = "0xeb173087729c88a47568AF87b17C653039377BA6" +RollupManagerAddr = "0x2d42E2899662EFf08b13eeb65b154b904C7a1c8a" +GlobalExitRootManagerAddr = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" + +[Etherman] + URL="http://xlayer-mock-l1-network:8545" + ForkIDChunkSize=100 + [Etherman.EthermanConfig] + URL="http://xlayer-mock-l1-network:8545" + MultiGasProvider=false + L1ChainID=1337 + HTTPHeaders=[] + [Etherman.EthermanConfig.Etherscan] + ApiKey="" + Url="https://api.etherscan.io/api?module=gastracker&action=gasoracle&apikey=" + +[Common] +NetworkID = 1 +IsValidiumMode = true +ContractVersions = "banana" + +[SequenceSender] +WaitPeriodSendSequence = "15s" +LastBatchVirtualizationTimeMaxWaitPeriod = "10s" +L1BlockTimestampMargin = "30s" +MaxTxSizeForL1 = 131072 +L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" +PrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"} +SequencesTxFileName = "sequencesender.json" +GasOffset = 80000 +WaitPeriodPurgeTxFile = "60m" +MaxPendingTx = 1 +MaxBatchesForL1 = 300 +BlockFinality = "FinalizedBlock" +RPCURL = "http://xlayer-rpc:8545" +GetBatchWaitInterval = "10s" + [SequenceSender.EthTxManager] + FrequencyToMonitorTxs = "1s" + WaitTxToBeMined = "2m" + GetReceiptMaxTime = "250ms" + GetReceiptWaitInterval = "1s" + PrivateKeys = [ + {Path = "/pk/sequencer.keystore", Password = "testonly"}, + ] + ForcedGas = 0 + GasPriceMarginFactor = 1 + MaxGasPriceLimit = 0 + StoragePath = "/tmp/cdk/ethtxmanager.sqlite" + ReadPendingL1Txs = false + SafeStatusL1NumberOfBlocks = 0 + FinalizedStatusL1NumberOfBlocks = 0 + [SequenceSender.EthTxManager.Etherman] + URL = "http://xlayer-mock-l1-network:8545" + MultiGasProvider = false + L1ChainID = 1337 +[Aggregator] +# GRPC server host +Host = "0.0.0.0" +# GRPC server port +Port = 50081 +RetryTime = "5s" +VerifyProofInterval = "10s" +ProofStatePollingInterval = "5s" +TxProfitabilityCheckerType = "acceptall" +TxProfitabilityMinReward = "1.1" +IntervalAfterWhichBatchConsolidateAnyway="0s" +BatchProofSanityCheckEnabled = true +# ChainID is L2ChainID. Is populated on runtimme +ChainID = 0 +ForkId = 13 +SenderAddress = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" +CleanupLockedProofsInterval = "2m" +GeneratingProofCleanupThreshold = "10m" +GasOffset = 0 +RPCURL = "http://xlayer-rpc:8545" +WitnessURL = "http://xlayer-rpc:8545" +UseFullWitness = false +SettlementBackend = "l1" +AggLayerTxTimeout = "5m" +AggLayerURL = "" +SyncModeOnlyEnabled = false + [Aggregator.SequencerPrivateKey] + Path = "/pk/sequencer.keystore" + Password = "testonly" + [Aggregator.DB] + Name = "aggregator_db" + User = "aggregator_user" + Password = "aggregator_password" + Host = "xlayer-agg-db-old" + Port = "5432" + EnableLog = false + MaxConns = 200 + [Aggregator.Log] + Environment = "development" # "production" or "development" + Level = "info" + Outputs = ["stderr"] + [Aggregator.EthTxManager] + FrequencyToMonitorTxs = "1s" + WaitTxToBeMined = "2m" + GetReceiptMaxTime = "250ms" + GetReceiptWaitInterval = "1s" + PrivateKeys = [ + {Path = "/pk/aggregator.keystore", Password = "testonly"}, + ] + ForcedGas = 0 + GasPriceMarginFactor = 1 + MaxGasPriceLimit = 0 + StoragePath = "/tmp/cdk/ethtxmanager.sqlite" + ReadPendingL1Txs = false + SafeStatusL1NumberOfBlocks = 0 + FinalizedStatusL1NumberOfBlocks = 0 + [Aggregator.EthTxManager.Etherman] + URL = "http://xlayer-mock-l1-network:8545" + L1ChainID = 1337 + HTTPHeaders = [] + [Aggregator.Synchronizer] + [Aggregator.Synchronizer.Log] + Environment = "development" # "production" or "development" + Level = "info" + Outputs = ["stderr"] + [Aggregator.Synchronizer.SQLDB] + DriverName = "sqlite3" + DataSource = "/tmp/cdk/aggregator_sync_db.sqlite" + [Aggregator.Synchronizer.Synchronizer] + SyncInterval = "10s" + SyncChunkSize = 1000 + GenesisBlockNumber = 123 + SyncUpToBlock = "finalized" + BlockFinality = "finalized" + OverrideStorageCheck = false + [Aggregator.Synchronizer.Etherman] + L1URL = "http://xlayer-mock-l1-network:8545" + ForkIDChunkSize = 100 + L1ChainID = 1337 + PararellBlockRequest = false + [Aggregator.Synchronizer.Etherman.Contracts] + GlobalExitRootManagerAddr = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" + RollupManagerAddr = "0x2d42E2899662EFf08b13eeb65b154b904C7a1c8a" + ZkEVMAddr = "0xeb173087729c88a47568AF87b17C653039377BA6" + [Aggregator.Synchronizer.Etherman.Validium] + Enabled = true + # L2URL, empty ask to contract + TrustedSequencerURL = "" + RetryOnDACErrorInterval = "1m" + DataSourcePriority = ["trusted", "external"] + [Aggregator.Synchronizer.Etherman.Validium.Translator] + FullMatchRules = [] + [Aggregator.Synchronizer.Etherman.Validium.RateLimit] + NumRequests = 1000 + Interval = "1s" +[ReorgDetectorL1] +DBPath = "/tmp/cdk/reorg_detector_l1.sqlite" + +# Only for AGGORACLE, RPC, AGGSENDER +#[ReorgDetectorL2] +#DBPath = "/tmp/cdk/reorg_detector_l2.sqlite" + +[L1InfoTreeSync] +DBPath = "/tmp/cdk/l1_info_tree_sync.sqlite" +GlobalExitRootAddr="0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" +RollupManagerAddr = "0x2d42E2899662EFf08b13eeb65b154b904C7a1c8a" +SyncBlockChunkSize=10 +BlockFinality="LatestBlock" +WaitForNewBlocksPeriod="100ms" +InitialBlock= 123 + +# Only for AGGORACLE, RPC, AGGSENDER +#[AggOracle] +#TargetChainType="EVM" +#URLRPCL1="" +#BlockFinality="FinalizedBlock" +#WaitPeriodNextGER="100ms" +# [AggOracle.EVMSender] +# GlobalExitRootL2="0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" +# URLRPCL2="" +# ChainIDL2=195 +# GasOffset=0 +# WaitPeriodMonitorTx="100ms" +# SenderAddr="0x70997970c51812dc3a010c7d01b50e0d17dc79c8" +# [AggOracle.EVMSender.EthTxManager] +# FrequencyToMonitorTxs = "1s" +# WaitTxToBeMined = "2s" +# GetReceiptMaxTime = "250ms" +# GetReceiptWaitInterval = "1s" +# PrivateKeys = [ +# {Path = "/app/keystore/aggoracle.keystore", Password = "testonly"}, +# ] +# ForcedGas = 0 +# GasPriceMarginFactor = 1 +# MaxGasPriceLimit = 0 +# StoragePath = "/tmp/cdk/ethtxmanager-sequencesender.sqlite" +# ReadPendingL1Txs = false +# SafeStatusL1NumberOfBlocks = 5 +# FinalizedStatusL1NumberOfBlocks = 10 +# [AggOracle.EVMSender.EthTxManager.Etherman] +# URL = "http://xlayer-mock-l1-network:8545" +# MultiGasProvider = false +# L1ChainID = 1337 +# HTTPHeaders = [] + +# Only for RPC +#[RPC] +#Host = "0.0.0.0" +#Port = 5576 +#ReadTimeout = "2s" +#WriteTimeout = "2s" +#MaxRequestsPerIPAndSecond = 10 + +# Only for RPC +#[ClaimSponsor] +#DBPath = "/tmp/cdk/claimsopnsor.sqlite" +#Enabled = true +#SenderAddr = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" +#BridgeAddrL2 = "0x3a277Fa4E78cc1266F32E26c467F99A8eAEfF7c3" +#MaxGas = 200000 +#RetryAfterErrorPeriod = "1s" +#MaxRetryAttemptsAfterError = -1 +#WaitTxToBeMinedPeriod = "3s" +#WaitOnEmptyQueue = "3s" +#GasOffset = 0 +# [ClaimSponsor.EthTxManager] +# FrequencyToMonitorTxs = "1s" +# WaitTxToBeMined = "2s" +# GetReceiptMaxTime = "250ms" +# GetReceiptWaitInterval = "1s" +# PrivateKeys = [ +# {Path = "/app/keystore/claimsopnsor.keystore", Password = "testonly"}, +# ] +# ForcedGas = 0 +# GasPriceMarginFactor = 1 +# MaxGasPriceLimit = 0 +# StoragePath = "/tmp/cdk/ethtxmanager-claimsponsor.sqlite" +# ReadPendingL1Txs = false +# SafeStatusL1NumberOfBlocks = 5 +# FinalizedStatusL1NumberOfBlocks = 10 +# [ClaimSponsor.EthTxManager.Etherman] +# URL = "http://xlayer-mock-l1-network:8545" +# MultiGasProvider = false +# L1ChainID = 1337 +# HTTPHeaders = [] + +# Only for RPC +#[BridgeL1Sync] +#DBPath = "/tmp/cdk/bridgel1sync.sqlite" +#BlockFinality = "LatestBlock" +#InitialBlockNum = 0 +#BridgeAddr = "0x3a277Fa4E78cc1266F32E26c467F99A8eAEfF7c3" +#SyncBlockChunkSize = 100 +#RetryAfterErrorPeriod = "1s" +#MaxRetryAttemptsAfterError = -1 +#WaitForNewBlocksPeriod = "3s" +#OriginNetwork=0 + +# For RPC and aggsender +#[BridgeL2Sync] +#DBPath = "/tmp/cdk/bridgel2sync.sqlite" +#BlockFinality = "LatestBlock" +#InitialBlockNum = 0 +#BridgeAddr = "0x3a277Fa4E78cc1266F32E26c467F99A8eAEfF7c3" +#SyncBlockChunkSize = 100 +#RetryAfterErrorPeriod = "1s" +#MaxRetryAttemptsAfterError = -1 +#WaitForNewBlocksPeriod = "3s" +#OriginNetwork=1 + +# Only for RPC +#[LastGERSync] +## MDBX database path +#DBPath = "/tmp/cdk/lastgersync.sqlite" +#BlockFinality = "LatestBlock" +#InitialBlockNum = 0 +#GlobalExitRootL2Addr = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" +#RetryAfterErrorPeriod = "1s" +#MaxRetryAttemptsAfterError = -1 +#WaitForNewBlocksPeriod = "1s" +#DownloadBufferSize = 100 + +#[AggSender] +#StoragePath = "/tmp/cdk/aggsender.sqlite" +#AggLayerURL = "" +#AggsenderPrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"} +#BlockGetInterval = "2s" +#URLRPCL2="http://xlayer-rpc:8545" +#CheckSettledInterval = "2s" +#SaveCertificatesToFiles = false \ No newline at end of file diff --git a/test-pp-op/config/dynamic-mynetwork-allocs.json b/test-pp-op/config/dynamic-mynetwork-allocs.json new file mode 100644 index 0000000000000..013af5343dd56 --- /dev/null +++ b/test-pp-op/config/dynamic-mynetwork-allocs.json @@ -0,0 +1,100 @@ +{ + "0x1eDa899fE24907035Ed6F5C6472a1f1E627aB359": { + "contractName": "BytecodeStorer", + "balance": "0", + "nonce": "1", + "code": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063c514f24e1461002d575b5f5ffd5b61003561004b565b604051610042919061006a565b60405180910390f35b60405180610f000160405280610ec881526020016100b6610ec8913981565b602081525f82518060208401525f5b818110156100965760208186018101516040868401015201610079565b505f604082850101526040601f19601f8301168401019150509291505056fe60806040819052631d97f74d60e11b81523390633b2fee9a90608490602090600481865afa158015610033573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100579190610433565b604080515f80825260208201909252905061007382825f6100e2565b50506100dd336001600160a01b03166338b8fbbb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100b4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100d89190610433565b61010d565b6104c8565b6100eb8361017a565b5f825111806100f75750805b156101085761010683836101b9565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61014c5f516020610e815f395f51905f52546001600160a01b031690565b604080516001600160a01b03928316815291841660208301520160405180910390a1610177816101e5565b50565b61018381610280565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606101de8383604051806060016040528060278152602001610ea160279139610314565b9392505050565b6001600160a01b03811661024f5760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b805f516020610e815f395f51905f525b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b0381163b6102ed5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610246565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61025f565b60605f5f856001600160a01b031685604051610330919061047b565b5f60405180830381855af49150503d805f8114610368576040519150601f19603f3d011682016040523d82523d5f602084013e61036d565b606091505b50909250905061037f86838387610389565b9695505050505050565b606083156103f75782515f036103f0576001600160a01b0385163b6103f05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610246565b5081610401565b6104018383610409565b949350505050565b8151156104195781518083602001fd5b8060405162461bcd60e51b81526004016102469190610496565b5f60208284031215610443575f5ffd5b81516001600160a01b03811681146101de575f5ffd5b5f5b8381101561047357818101518382015260200161045b565b50505f910152565b5f825161048c818460208701610459565b9190910192915050565b602081525f82518060208401526104b4816040850160208701610459565b601f01601f19169190910160400192915050565b6109ac806104d55f395ff3fe60806040526004361061005d575f3560e01c80635c60da1b116100425780635c60da1b146100a65780638f283970146100e3578063f851a440146101025761006c565b80633659cfe6146100745780634f1ef286146100935761006c565b3661006c5761006a610116565b005b61006a610116565b34801561007f575f5ffd5b5061006a61008e366004610854565b610130565b61006a6100a136600461086d565b610178565b3480156100b1575f5ffd5b506100ba6101eb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee575f5ffd5b5061006a6100fd366004610854565b610228565b34801561010d575f5ffd5b506100ba610255565b61011e610282565b61012e610129610359565b610362565b565b610138610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d8160405180602001604052805f8152505f6103bf565b50565b61016d610116565b610180610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101e3576101de8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250600192506103bf915050565b505050565b6101de610116565b5f6101f4610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610359565b905090565b610225610116565b90565b610230610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d816103e9565b5f61025e610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610380565b61028a610380565b73ffffffffffffffffffffffffffffffffffffffff16330361012e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b5f61021861044a565b365f5f375f5f365f845af43d5f5f3e80801561037c573d5ff35b3d5ffd5b5f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103c883610471565b5f825111806103d45750805b156101de576103e383836104bd565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610412610380565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161016d816104e9565b5f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103a3565b61047a816105f5565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606104e28383604051806060016040528060278152602001610979602791396106c0565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811661058c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610350565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610350565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105af565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff16856040516106e9919061090d565b5f60405180830381855af49150503d805f8114610721576040519150601f19603f3d011682016040523d82523d5f602084013e610726565b606091505b509150915061073786838387610741565b9695505050505050565b606083156107d65782515f036107cf5773ffffffffffffffffffffffffffffffffffffffff85163b6107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610350565b50816107e0565b6107e083836107e8565b949350505050565b8151156107f85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103509190610928565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f575f5ffd5b919050565b5f60208284031215610864575f5ffd5b6104e28261082c565b5f5f5f6040848603121561087f575f5ffd5b6108888461082c565b9250602084013567ffffffffffffffff8111156108a3575f5ffd5b8401601f810186136108b3575f5ffd5b803567ffffffffffffffff8111156108c9575f5ffd5b8660208284010111156108da575f5ffd5b939660209190910195509293505050565b5f5b838110156109055781810151838201526020016108ed565b50505f910152565b5f825161091e8184602087016108eb565b9190910192915050565b602081525f82518060208401526109468160408501602087016108eb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a164736f6c634300081c000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220f9f921f910b22a2a14f9dce017cc4be5206c1f1f3690adcea59699078c36984a64736f6c634300081c0033", + "storage": null + }, + "0xccF2F75629fF55768cAF87F9D2e733dee92373DC": { + "contractName": "TokenWrapped Implementation", + "balance": "0", + "nonce": "1", + "code": "0x608060405234801561000f575f5ffd5b5060043610610106575f3560e01c806370a082311161009e5780639dc29fac1161006e5780639dc29fac1461023c578063a3c573eb1461024f578063a9059cbb14610297578063d505accf146102aa578063dd62ed3e146102bd575f5ffd5b806370a08231146101f35780637ecebe001461020657806384b0196e1461021957806395d89b4114610234575f5ffd5b806323b872dd116100d957806323b872dd14610191578063313ce567146101a45780633644e515146101d857806340c10f19146101e0575f5ffd5b806306fdde031461010a578063095ea7b3146101285780631624f6c61461014b57806318160ddd14610160575b5f5ffd5b610112610314565b60405161011f919061115f565b60405180910390f35b61013b610136366004611193565b6103b9565b604051901515815260200161011f565b61015e61015936600461126a565b6103d2565b005b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace02545b60405190815260200161011f565b61013b61019f3660046112de565b61054a565b7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d005460405160ff909116815260200161011f565b61018361056d565b61015e6101ee366004611193565b61057b565b610183610201366004611318565b6105de565b610183610214366004611318565b61060e565b610221610618565b60405161011f9796959493929190611331565b6101126106ce565b61015e61024a366004611193565b61070c565b7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d005461010090046001600160a01b03166040516001600160a01b03909116815260200161011f565b61013b6102a5366004611193565b61076a565b61015e6102b83660046113c7565b610777565b6101836102cb36600461142d565b6001600160a01b039182165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b60605f5f5160206115c95f395f51905f525b90508060030180546103379061145e565b80601f01602080910402602001604051908101604052809291908181526020018280546103639061145e565b80156103ae5780601f10610385576101008083540402835291602001916103ae565b820191905f5260205f20905b81548152906001019060200180831161039157829003601f168201915b505050505091505090565b5f336103c68185856108cc565b60019150505b92915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f8115801561041c5750825b90505f8267ffffffffffffffff1660011480156104385750303b155b905081158015610446575080155b156104645760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561049857845468ff00000000000000001916680100000000000000001785555b6104a288886108d9565b6104ab886108ef565b7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d00805460ff881674ffffffffffffffffffffffffffffffffffffffffff19909116176101003302179055831561054057845468ff000000000000000019168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f3361055785828561091d565b6105628585856109b7565b506001949350505050565b5f610576610a14565b905090565b5f7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d00805490915061010090046001600160a01b031633146105cf576040516338da3b1560e01b815260040160405180910390fd5b6105d98383610a1d565b505050565b5f805f5160206115c95f395f51905f525b6001600160a01b039093165f9081526020939093525050604090205490565b5f6103cc82610a51565b5f60608082808083815f5160206115e95f395f51905f52805490915015801561064357506001810154155b6106945760405162461bcd60e51b815260206004820152601560248201527f4549503731323a20556e696e697469616c697a6564000000000000000000000060448201526064015b60405180910390fd5b61069c610a5b565b6106a4610a99565b604080515f80825260208201909252600f60f81b9c939b5091995046985030975095509350915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060915f5160206115c95f395f51905f52916103379061145e565b5f7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d00805490915061010090046001600160a01b03163314610760576040516338da3b1560e01b815260040160405180910390fd5b6105d98383610aaf565b5f336103c68185856109b7565b8342111561079b5760405163313c898160e11b81526004810185905260240161068b565b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886108058c6001600160a01b03165f9081527f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090505f61085f82610ae3565b90505f61086e82878787610b0f565b9050896001600160a01b0316816001600160a01b0316146108b5576040516325c0072360e11b81526001600160a01b0380831660048301528b16602482015260440161068b565b6108c08a8a8a6108cc565b50505050505050505050565b6105d98383836001610b3b565b6108e1610c1f565b6108eb8282610c6f565b5050565b6108f7610c1f565b61091a81604051806040016040528060018152602001603160f81b815250610cbf565b50565b6001600160a01b038381165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0160209081526040808320938616835292905220545f1981146109b157818110156109a357604051637dc7a0d960e11b81526001600160a01b0384166004820152602481018290526044810183905260640161068b565b6109b184848484035f610b3b565b50505050565b6001600160a01b0383166109e057604051634b637e8f60e11b81525f600482015260240161068b565b6001600160a01b038216610a095760405163ec442f0560e01b81525f600482015260240161068b565b6105d9838383610d1e565b5f610576610e57565b6001600160a01b038216610a465760405163ec442f0560e01b81525f600482015260240161068b565b6108eb5f8383610d1e565b5f6103cc82610eca565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060915f5160206115e95f395f51905f52916103379061145e565b60605f5f5160206115e95f395f51905f52610326565b6001600160a01b038216610ad857604051634b637e8f60e11b81525f600482015260240161068b565b6108eb825f83610d1e565b5f6103cc610aef610a14565b8360405161190160f01b8152600281019290925260228201526042902090565b5f5f5f5f610b1f88888888610ef2565b925092509250610b2f8282610fba565b50909695505050505050565b5f5160206115c95f395f51905f526001600160a01b038516610b725760405163e602df0560e01b81525f600482015260240161068b565b6001600160a01b038416610b9b57604051634a1406b160e11b81525f600482015260240161068b565b6001600160a01b038086165f90815260018301602090815260408083209388168352929052208390558115610c1857836001600160a01b0316856001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051610c0f91815260200190565b60405180910390a35b5050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16610c6d57604051631afcd79f60e31b815260040160405180910390fd5b565b610c77610c1f565b5f5160206115c95f395f51905f527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace03610cb084826114da565b50600481016109b183826114da565b610cc7610c1f565b5f5160206115e95f395f51905f527fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102610d0084826114da565b5060038101610d0f83826114da565b505f8082556001909101555050565b5f5160206115c95f395f51905f526001600160a01b038416610d585781816002015f828254610d4d9190611595565b90915550610dc89050565b6001600160a01b0384165f9081526020829052604090205482811015610daa5760405163391434e360e21b81526001600160a01b0386166004820152602481018290526044810184905260640161068b565b6001600160a01b0385165f9081526020839052604090209083900390555b6001600160a01b038316610de6576002810180548390039055610e04565b6001600160a01b0383165f9081526020829052604090208054830190555b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e4991815260200190565b60405180910390a350505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f610e81611072565b610e896110da565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f807f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006105ef565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610f2b57505f91506003905082610fb0565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610f7c573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b038116610fa757505f925060019150829050610fb0565b92505f91508190505b9450945094915050565b5f826003811115610fcd57610fcd6115b4565b03610fd6575050565b6001826003811115610fea57610fea6115b4565b036110085760405163f645eedf60e01b815260040160405180910390fd5b600282600381111561101c5761101c6115b4565b0361103d5760405163fce698f760e01b81526004810182905260240161068b565b6003826003811115611051576110516115b4565b036108eb576040516335e2f38360e21b81526004810182905260240161068b565b5f5f5160206115e95f395f51905f528161108a610a5b565b8051909150156110a257805160209091012092915050565b815480156110b1579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b5f5f5160206115e95f395f51905f52816110f2610a99565b80519091501561110a57805160209091012092915050565b600182015480156110b1579392505050565b5f81518084525f5b8181101561114057602081850181015186830182015201611124565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f611171602083018461111c565b9392505050565b80356001600160a01b038116811461118e575f5ffd5b919050565b5f5f604083850312156111a4575f5ffd5b6111ad83611178565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126111de575f5ffd5b813567ffffffffffffffff8111156111f8576111f86111bb565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715611227576112276111bb565b60405281815283820160200185101561123e575f5ffd5b816020850160208301375f918101602001919091529392505050565b803560ff8116811461118e575f5ffd5b5f5f5f6060848603121561127c575f5ffd5b833567ffffffffffffffff811115611292575f5ffd5b61129e868287016111cf565b935050602084013567ffffffffffffffff8111156112ba575f5ffd5b6112c6868287016111cf565b9250506112d56040850161125a565b90509250925092565b5f5f5f606084860312156112f0575f5ffd5b6112f984611178565b925061130760208501611178565b929592945050506040919091013590565b5f60208284031215611328575f5ffd5b61117182611178565b60ff60f81b8816815260e060208201525f61134f60e083018961111c565b8281036040840152611361818961111c565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b818110156113b6578351835260209384019390920191600101611398565b50909b9a5050505050505050505050565b5f5f5f5f5f5f5f60e0888a0312156113dd575f5ffd5b6113e688611178565b96506113f460208901611178565b955060408801359450606088013593506114106080890161125a565b9699959850939692959460a0840135945060c09093013592915050565b5f5f6040838503121561143e575f5ffd5b61144783611178565b915061145560208401611178565b90509250929050565b600181811c9082168061147257607f821691505b60208210810361149057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156105d957805f5260205f20601f840160051c810160208510156114bb5750805b601f840160051c820191505b81811015610c18575f81556001016114c7565b815167ffffffffffffffff8111156114f4576114f46111bb565b61150881611502845461145e565b84611496565b6020601f82116001811461153a575f83156115235750848201515b5f19600385901b1c1916600184901b178455610c18565b5f84815260208120601f198516915b828110156115695787850151825560209485019460019092019101611549565b508482101561158657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b808201808211156103cc57634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52602160045260245ffdfe52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100a2646970667358221220f0e100f498b6f41fbf597025b81d217623a1e4b7d8ee5bf92572b87e86172a6264736f6c634300081c0033", + "storage": null + }, + "0x9C1aBd1fB3569e951DcC3cd5D678a7a618088CFa": { + "contractName": "PolygonZkEVMDeployer", + "balance": "0", + "nonce": "4", + "code": "0x60806040526004361061006e575f3560e01c8063715018a61161004c578063715018a6146100e25780638da5cb5b146100f6578063e11ae6cb1461011f578063f2fde38b14610132575f80fd5b80632b79805a146100725780634a94d487146100875780636d07dbf81461009a575b5f80fd5b610085610080366004610908565b610151565b005b6100856100953660046109a2565b6101c2565b3480156100a5575f80fd5b506100b96100b43660046109f5565b610203565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ed575f80fd5b50610085610215565b348015610101575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff166100b9565b61008561012d366004610a15565b610228565b34801561013d575f80fd5b5061008561014c366004610a61565b61028e565b61015961034a565b5f6101658585856103ca565b90506101718183610527565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101ca61034a565b6101d583838361056a565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b905f90a1505050565b5f61020e8383610598565b9392505050565b61021d61034a565b6102265f6105a4565b565b61023061034a565b5f61023c8484846103ca565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b61029661034a565b73ffffffffffffffffffffffffffffffffffffffff811661033e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610347816105a4565b50565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610335565b5f83471015610435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610335565b81515f0361049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610335565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff811661020e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610335565b606061020e83835f6040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610618565b6060610590848484604051806060016040528060298152602001610b0860299139610618565b949350505050565b5f61020e83833061072d565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610335565b5f808673ffffffffffffffffffffffffffffffffffffffff1685876040516106d29190610a9c565b5f6040518083038185875af1925050503d805f811461070c576040519150601f19603f3d011682016040523d82523d5f602084013e610711565b606091505b509150915061072287838387610756565b979650505050505050565b5f604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156107eb5782515f036107e45773ffffffffffffffffffffffffffffffffffffffff85163b6107e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610335565b5081610590565b61059083838151156108005781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103359190610ab7565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112610870575f80fd5b813567ffffffffffffffff8082111561088b5761088b610834565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108d1576108d1610834565b816040528381528660208588010111156108e9575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f805f806080858703121561091b575f80fd5b8435935060208501359250604085013567ffffffffffffffff80821115610940575f80fd5b61094c88838901610861565b93506060870135915080821115610961575f80fd5b5061096e87828801610861565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff8116811461099d575f80fd5b919050565b5f805f606084860312156109b4575f80fd5b6109bd8461097a565b9250602084013567ffffffffffffffff8111156109d8575f80fd5b6109e486828701610861565b925050604084013590509250925092565b5f8060408385031215610a06575f80fd5b50508035926020909101359150565b5f805f60608486031215610a27575f80fd5b8335925060208401359150604084013567ffffffffffffffff811115610a4b575f80fd5b610a5786828701610861565b9150509250925092565b5f60208284031215610a71575f80fd5b61020e8261097a565b5f5b83811015610a94578181015183820152602001610a7c565b50505f910152565b5f8251610aad818460208701610a7a565b9190910192915050565b602081525f8251806020840152610ad5816040850160208701610a7a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a26469706673582212206c37fb6ca2362734c4736703fbea1e2f5c6060623d61a5acc99beb96437a122364736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008f8e2d6cf621f30e9a11309d6a56a876281fd534" + } + }, + "0xc2c5fb710E85BedC5C18A8a0Fa931D75983F2185": { + "contractName": "ProxyAdmin", + "balance": "0", + "nonce": "1", + "code": "0x608060405260043610610079575f3560e01c80639623609d1161004c5780639623609d1461012357806399a88ec414610136578063f2fde38b14610155578063f3b7dead14610174575f5ffd5b8063204e1c7a1461007d578063715018a6146100c55780637eff275e146100db5780638da5cb5b146100fa575b5f5ffd5b348015610088575f5ffd5b5061009c6100973660046105e8565b610193565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d0575f5ffd5b506100d9610244565b005b3480156100e6575f5ffd5b506100d96100f536600461060a565b610257565b348015610105575f5ffd5b505f5473ffffffffffffffffffffffffffffffffffffffff1661009c565b6100d961013136600461066e565b6102e0565b348015610141575f5ffd5b506100d961015036600461060a565b610371565b348015610160575f5ffd5b506100d961016f3660046105e8565b6103cd565b34801561017f575f5ffd5b5061009c61018e3660046105e8565b610489565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b5f60405180830381855afa9150503d805f8114610215576040519150601f19603f3d011682016040523d82523d5f602084013e61021a565b606091505b509150915081610228575f5ffd5b8080602001905181019061023c9190610782565b949350505050565b61024c6104d3565b6102555f610553565b565b61025f6104d3565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b5f604051808303815f87803b1580156102c6575f5ffd5b505af11580156102d8573d5f5f3e3d5ffd5b505050505050565b6102e86104d3565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061033e908690869060040161079d565b5f604051808303818588803b158015610355575f5ffd5b505af1158015610367573d5f5f3e3d5ffd5b5050505050505050565b6103796104d3565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102af565b6103d56104d3565b73ffffffffffffffffffffffffffffffffffffffff811661047d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61048681610553565b50565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610474565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610486575f5ffd5b5f602082840312156105f8575f5ffd5b8135610603816105c7565b9392505050565b5f5f6040838503121561061b575f5ffd5b8235610626816105c7565b91506020830135610636816105c7565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f5f60608486031215610680575f5ffd5b833561068b816105c7565b9250602084013561069b816105c7565b9150604084013567ffffffffffffffff8111156106b6575f5ffd5b8401601f810186136106c6575f5ffd5b803567ffffffffffffffff8111156106e0576106e0610641565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff8211171561074c5761074c610641565b604052818152828201602001881015610763575f5ffd5b816020840160208301375f602083830101528093505050509250925092565b5f60208284031215610792575f5ffd5b8151610603816105c7565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f82518060408401525f5b818110156107e557602081860181015160608684010152016107c8565b505f6060828501015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116840101915050939250505056fea26469706673582212208ab8743c787ecb046e26764a23735b65ae0affe7a9153fa2f3410ff80a26ba0464736f6c634300081c0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000027284dba79e6df953fbd232a9d8d87029f03bbf5" + } + }, + "0x12060cA70f50A24fde90fEA110002C235f558a56": { + "contractName": "PolygonZkEVMBridgeV2 implementation", + "balance": "0", + "nonce": "3", + "code": "0x608060405260043610610233575f3560e01c806383f2440311610129578063ccaa2d11116100a8578063ee25560b1161006d578063ee25560b146106fe578063f214e16114610729578063f5efcd7914610748578063f811bff714610767578063fb57083414610786575f5ffd5b8063ccaa2d1114610671578063cd58657914610690578063d02103ca146106a3578063dbc16976146106cb578063ece93c6f146106df575f5ffd5b8063bab161bf116100ee578063bab161bf146105db578063be5831c7146105fc578063c00f14ab1461061f578063c514f24e1461063e578063cc46163214610652575f5ffd5b806383f244031461054b5780638bd309c31461056a5780638c668f1c146105895780638ed7e3f21461059d578063b8b284d0146105bc575f5ffd5b80633c351e10116101b557806365d6f6541161017a57806365d6f6541461049c5780636e4ecfed146104d057806379e2cf97146104ef5780638129fc1c1461050357806381b1c17414610517575f5ffd5b80633c351e10146103f35780633cbc795b146104125780633e1970431461044a5780634b2f336d146104695780635ca1e16514610488575f5ffd5b80632dfdf0b5116101fb5780632dfdf0b5146102e6578063318aee3d14610309578063381fef6d1461037157806338b8fbbb146103a45780633b2fee9a146103c1575f5ffd5b806315064c96146102375780632072f6c51461026557806322e95f2c1461027b578063240ff378146102b257806327aef4e8146102c5575b5f5ffd5b348015610242575f5ffd5b506068546102509060ff1681565b60405190151581526020015b60405180910390f35b348015610270575f5ffd5b506102796107a5565b005b348015610286575f5ffd5b5061029a610295366004612f92565b6107da565b6040516001600160a01b03909116815260200161025c565b6102796102c0366004613019565b610844565b3480156102d0575f5ffd5b506102d96108b4565b60405161025c91906130db565b3480156102f1575f5ffd5b506102fb60535481565b60405190815260200161025c565b348015610314575f5ffd5b5061034d6103233660046130ed565b606b6020525f908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b0390911660208301520161025c565b34801561037c575f5ffd5b5061029a7f0000000000000000000000001eda899fe24907035ed6f5c6472a1f1e627ab35981565b3480156103af575f5ffd5b506070546001600160a01b031661029a565b3480156103cc575f5ffd5b507f000000000000000000000000ccf2f75629ff55768caf87f9d2e733dee92373dc61029a565b3480156103fe575f5ffd5b50606d5461029a906001600160a01b031681565b34801561041d575f5ffd5b50606d5461043590600160a01b900463ffffffff1681565b60405163ffffffff909116815260200161025c565b348015610455575f5ffd5b506102fb610464366004613116565b610940565b348015610474575f5ffd5b50606f5461029a906001600160a01b031681565b348015610493575f5ffd5b506102fb6109d1565b3480156104a7575f5ffd5b506102d9604051806040016040528060098152602001680616c2d76302e332e360bc1b81525081565b3480156104db575f5ffd5b5060705461029a906001600160a01b031681565b3480156104fa575f5ffd5b50610279610a50565b34801561050e575f5ffd5b50610279610a71565b348015610522575f5ffd5b5061029a610531366004613190565b606a6020525f90815260409020546001600160a01b031681565b348015610556575f5ffd5b506102fb6105653660046131b8565b610baf565b348015610575575f5ffd5b506102796105843660046130ed565b610c3e565b348015610594575f5ffd5b50610279610ccc565b3480156105a8575f5ffd5b50606c5461029a906001600160a01b031681565b3480156105c7575f5ffd5b506102796105d63660046131f4565b610d5d565b3480156105e6575f5ffd5b5060685461043590610100900463ffffffff1681565b348015610607575f5ffd5b5060685461043590600160c81b900463ffffffff1681565b34801561062a575f5ffd5b506102d96106393660046130ed565b610ddb565b348015610649575f5ffd5b506102d9610e20565b34801561065d575f5ffd5b5061025061066c366004613272565b610ea9565b34801561067c575f5ffd5b5061027961068b3660046132a3565b610f31565b61027961069e366004613382565b61136e565b3480156106ae575f5ffd5b5060685461029a906501000000000090046001600160a01b031681565b3480156106d6575f5ffd5b5061027961170a565b3480156106ea575f5ffd5b5060715461029a906001600160a01b031681565b348015610709575f5ffd5b506102fb610718366004613190565b60696020525f908152604090205481565b348015610734575f5ffd5b5061029a610743366004612f92565b61173d565b348015610753575f5ffd5b506102796107623660046132a3565b61182a565b348015610772575f5ffd5b5061027961078136600461347e565b611a8a565b348015610791575f5ffd5b506102506107a036600461354e565b611d6c565b606c546001600160a01b031633146107d057604051631736745960e31b815260040160405180910390fd5b6107d8611d83565b565b6040805160e084901b6001600160e01b031916602080830191909152606084901b6bffffffffffffffffffffffff1916602483015282516018818403018152603890920183528151918101919091205f908152606a90915220546001600160a01b03165b92915050565b60685460ff161561086857604051630bc011ff60e21b815260040160405180910390fd5b34158015906108815750606f546001600160a01b031615155b1561089f576040516301bd897160e61b815260040160405180910390fd5b6108ad858534868686611dde565b5050505050565b606e80546108c190613593565b80601f01602080910402602001604051908101604052809291908181526020018280546108ed90613593565b80156109385780601f1061090f57610100808354040283529160200191610938565b820191905f5260205f20905b81548152906001019060200180831161091b57829003601f168201915b505050505081565b6040516001600160f81b031960f889901b1660208201526001600160e01b031960e088811b821660218401526bffffffffffffffffffffffff19606089811b821660258601529188901b909216603984015285901b16603d82015260518101839052607181018290525f90609101604051602081830303815290604052805190602001209050979650505050505050565b6053545f90819081805b6020811015610a47578083901c600116600103610a2057610a1960338260208110610a0857610a086135cb565b0154855f9182526020526040902090565b9350610a30565b5f84815260208390526040902093505b5f82815260208390526040902091506001016109db565b50919392505050565b605354606854600160c81b900463ffffffff1610156107d8576107d8611eba565b5f5460ff166071805460ff60a01b1916600160a01b60ff938416021790555f5460029161010090910416158015610aae57505f5460ff8083169116105b610b165760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b5f805461ffff191660ff80841691909117610100178255607154600160a01b9004169003610b575760405163f57ac68360e01b815260040160405180910390fd5b610b5f611f50565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1506071805460ff60a01b19169055565b5f83815b6020811015610c3357600163ffffffff8516821c81169003610bff57610bf8858260208110610be457610be46135cb565b6020020135835f9182526020526040902090565b9150610c2b565b610c2882868360208110610c1557610c156135cb565b60200201355f9182526020526040902090565b91505b600101610bb3565b5090505b9392505050565b6070546001600160a01b03163314610c6957604051630866750360e01b815260040160405180910390fd5b607180546001600160a01b0319166001600160a01b038381169182179092556070546040805191909316815260208101919091527f0a34baa3feb299aef9c05cb59c6e0c8e7c0bcc65cbf0a647e7a7c8a2411591e291015b60405180910390a150565b6071546001600160a01b03163314610cf757604051630b59ef2760e21b815260040160405180910390fd5b60708054607180546001600160a01b038082166001600160a01b0319808616821790965594909116909155604080519190921680825260208201939093527fa9da6fb8c39e9c2fafda878eac316815987bdc948d241ba6d75ed035e0e829f29101610cc1565b60685460ff1615610d8157604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610daa5760405163dde3cda760e01b815260040160405180910390fd5b606f545f90610dc2906001600160a01b031686612071565b9050610dd2878783878787611dde565b50505050505050565b6060610de6826120d5565b610def83612198565b610df88461224c565b604051602001610e0a939291906135df565b6040516020818303038152906040529050919050565b60607f0000000000000000000000001eda899fe24907035ed6f5c6472a1f1e627ab3596001600160a01b031663c514f24e6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610e7d573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ea49190810190613645565b905090565b6068545f908190610100900463ffffffff16158015610ece575063ffffffff83166001145b15610ee0575063ffffffff8316610f08565b610ef564010000000063ffffffff851661369e565b610f059063ffffffff86166136b5565b90505b600881901c5f90815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610f5557604051630bc011ff60e21b815260040160405180910390fd5b610f5d612300565b60685463ffffffff8681166101009092041614610f8d576040516302caf51760e11b815260040160405180910390fd5b610fb88c8c8c8c8c5f8d8d8d8d8d8d8d604051610fab9291906136c8565b6040518091039020612359565b6001600160a01b038616158015610fd3575063ffffffff8716155b156110b157606f546001600160a01b0316611095575f6001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015611020576020820181803683370190505b5060405161102e91906136d7565b5f6040518083038185875af1925050503d805f8114611068576040519150601f19603f3d011682016040523d82523d5f602084013e61106d565b606091505b505090508061108f57604051630ce8f45160e31b815260040160405180910390fd5b506112fb565b606f546110ac906001600160a01b03168585612375565b6112fb565b606d546001600160a01b0387811691161480156110df5750606d5463ffffffff888116600160a01b90920416145b156110f6575f6001600160a01b0385168482610ff6565b60685463ffffffff610100909104811690881603611122576110ac6001600160a01b03871685856123ce565b6040516001600160e01b031960e089901b1660208201526bffffffffffffffffffffffff19606088901b1660248201525f9060380160408051601f1981840301815291815281516020928301205f818152606a9093529120549091506001600160a01b0316806112ed575f6111cc8386868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061243292505050565b90506111d9818888612375565b80606a5f8581526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b5f836001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548163ffffffff021916908363ffffffff1602179055506020820151815f0160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a8388886040516112df95949392919061371a565b60405180910390a1506112f8565b6112f8818787612375565b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a161136060018055565b505050505050505050505050565b60685460ff161561139257604051630bc011ff60e21b815260040160405180910390fd5b61139a612300565b60685463ffffffff6101009091048116908816036113cb576040516302caf51760e11b815260040160405180910390fd5b5f806060876001600160a01b0388166114ae578834146113fe5760405163b89240f560e01b815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff1694509061142b90613593565b80601f016020809104026020016040519081016040528092919081815260200182805461145790613593565b80156114a25780601f10611479576101008083540402835291602001916114a2565b820191905f5260205f20905b81548152906001019060200180831161148557829003601f168201915b50505050509150611692565b34156114cd5760405163798ee6f160e01b815260040160405180910390fd5b84156114de576114de888787612519565b606f546001600160a01b0390811690891603611505576114fe888a612071565b9050611692565b6001600160a01b038089165f908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901515806115585750805163ffffffff1615155b1561157a57611567898b612071565b6020820151825190965094509150611685565b6040516370a0823160e01b81523060048201525f906001600160a01b038b16906370a0823190602401602060405180830381865afa1580156115be573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e29190613762565b90506115f96001600160a01b038b1633308e612833565b6040516370a0823160e01b81523060048201525f906001600160a01b038c16906370a0823190602401602060405180830381865afa15801561163d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116619190613762565b905061166d8282613779565b6068548c9850610100900463ffffffff169650935050505b61168e89610ddb565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b5f84868e8e86886053546040516116d198979695949392919061378c565b60405180910390a16116ef5f84868e8e86888051906020012061286c565b86156116fd576116fd611eba565b50505050610dd260018055565b606c546001600160a01b0316331461173557604051631736745960e31b815260040160405180910390fd5b6107d8612883565b6040516001600160e01b031960e084901b1660208201526bffffffffffffffffffffffff19606083901b1660248201525f9081906038016040516020818303038152906040528051906020012090505f60ff60f81b308361179c610e20565b6040516020016117ac91906136d7565b6040516020818303038152906040528051906020012060405160200161180994939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012095945050505050565b60685460ff161561184e57604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff868116610100909204161461187e576040516302caf51760e11b815260040160405180910390fd5b61189d8c8c8c8c8c60018d8d8d8d8d8d8d604051610fab9291906136c8565b606f545f906001600160a01b031661195057846001600160a01b031684888a86866040516024016118d19493929190613800565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161190691906136d7565b5f6040518083038185875af1925050503d805f8114611940576040519150601f19603f3d011682016040523d82523d5f602084013e611945565b606091505b505080915050611a01565b606f54611967906001600160a01b03168686612375565b846001600160a01b0316878985856040516024016119889493929190613800565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b179052516119bd91906136d7565b5f604051808303815f865af19150503d805f81146119f6576040519150601f19603f3d011682016040523d82523d5f602084013e6119fb565b606091505b50909150505b80611a1f576040516337e391c360e01b815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b5f5460ff166071805460ff60a01b1916600160a01b60ff938416021790555f5460029161010090910416158015611ac757505f5460ff8083169116105b611b2a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b0d565b5f805461ffff191660ff8084169190911761010017909155607154600160a01b90041615611b6b5760405163f57ac68360e01b815260040160405180910390fd5b611b73611f50565b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8a16027fffffffffffffff0000000000000000000000000000000000000000ffffffffff1617650100000000006001600160a01b038781169190910291909117909155606c80546001600160a01b0319168583161790558616611c285763ffffffff851615611c2357604051630d43a60960e11b815260040160405180910390fd5b611d0e565b606d805463ffffffff8716600160a01b027fffffffffffffffff0000000000000000000000000000000000000000000000009091166001600160a01b03891617179055606e611c778382613872565b50611ced5f5f1b6012604051602001611cd991906060808252600d908201526c2bb930b83832b21022ba3432b960991b608082015260a060208201819052600490820152630ae8aa8960e31b60c082015260ff91909116604082015260e00190565b604051602081830303815290604052612432565b606f80546001600160a01b0319166001600160a01b03929092169190911790555b611d166128da565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150506071805460ff60a01b191690555050505050565b5f81611d79868686610baf565b1495945050505050565b60685460ff1615611da757604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497905f90a1565b60685463ffffffff610100909104811690871603611e0f576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611e639998979695949392919061392d565b60405180910390a1611ea46001606860019054906101000a900463ffffffff16338989898888604051611e979291906136c8565b604051809103902061286c565b8215611eb257611eb2611eba565b505050505050565b6053546068805463ffffffff909216600160c81b0263ffffffff60c81b1990921691909117908190556001600160a01b0365010000000000909104166333d6247d611f036109d1565b6040518263ffffffff1660e01b8152600401611f2191815260200190565b5f604051808303815f87803b158015611f38575f5ffd5b505af1158015611f4a573d5f5f3e3d5ffd5b50505050565b5f611f827fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103546001600160a01b031690565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fc0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fe491906139a3565b607080546001600160a01b0319166001600160a01b03929092169182179055819061202e57604051632a506c0560e11b81526001600160a01b039091166004820152602401610b0d565b50607054604080515f81526001600160a01b0390921660208301527fa9da6fb8c39e9c2fafda878eac316815987bdc948d241ba6d75ed035e0e829f29101610cc1565b604051632770a7eb60e21b8152336004820152602481018290525f906001600160a01b03841690639dc29fac906044015f604051808303815f87803b1580156120b8575f5ffd5b505af11580156120ca573d5f5f3e3d5ffd5b509395945050505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516060915f9182916001600160a01b0386169161211b91906136d7565b5f60405180830381855afa9150503d805f8114612153576040519150601f19603f3d011682016040523d82523d5f602084013e612158565b606091505b50915091508161218757604051806040016040528060078152602001664e4f5f4e414d4560c81b815250612190565b6121908161294c565b949350505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516060915f9182916001600160a01b038616916121de91906136d7565b5f60405180830381855afa9150503d805f8114612216576040519150601f19603f3d011682016040523d82523d5f602084013e61221b565b606091505b50915091508161218757604051806040016040528060098152602001681393d7d4d6535093d360ba1b815250612190565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290515f91829182916001600160a01b0386169161229191906136d7565b5f60405180830381855afa9150503d805f81146122c9576040519150601f19603f3d011682016040523d82523d5f602084013e6122ce565b606091505b50915091508180156122e1575080516020145b6122ec576012612190565b8080602001905181019061219091906139be565b6002600154036123525760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b0d565b6002600155565b6113608c8c8c8c8c6123708d8d8d8d8d8d8d610940565b612ae4565b6040516340c10f1960e01b81526001600160a01b038381166004830152602482018390528416906340c10f19906044015f604051808303815f87803b1580156123bc575f5ffd5b505af1158015610dd2573d5f5f3e3d5ffd5b6040516001600160a01b0383811660248301526044820183905261242d91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050612c35565b505050565b5f5f61243c610e20565b60405160200161244c91906136d7565b6040516020818303038152906040529050838151602083015ff591506001600160a01b03821661248f576040516331682e8d60e11b815260040160405180910390fd5b5f5f5f858060200190518101906124a691906139f7565b925092509250846001600160a01b0316631624f6c68484846040518463ffffffff1660e01b81526004016124dc939291906135df565b5f604051808303815f87803b1580156124f3575f5ffd5b505af1158015612505573d5f5f3e3d5ffd5b505050505050505092915050565b60018055565b5f6125276004828486613a6f565b61253091613a96565b9050632afa533160e01b6001600160e01b031982160161269f575f80808080808061255e896004818d613a6f565b81019061256b9190613ace565b9650965096509650965096509650336001600160a01b0316876001600160a01b0316146125ab5760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03861630146125d45760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b031663d505accf60e01b1790529151918d169161265291906136d7565b5f604051808303815f865af19150503d805f811461268b576040519150601f19603f3d011682016040523d82523d5f602084013e612690565b606091505b50505050505050505050611f4a565b6001600160e01b031981166323f2ebc360e21b146126d057604051637141605d60e11b815260040160405180910390fd5b5f808080808080806126e58a6004818e613a6f565b8101906126f29190613b1d565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146127345760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038716301461275d5760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918e16916127e491906136d7565b5f604051808303815f865af19150503d805f811461281d576040519150601f19603f3d011682016040523d82523d5f602084013e612822565b606091505b505050505050505050505050505050565b6040516001600160a01b038481166024830152838116604483015260648201839052611f4a9186918216906323b872dd906084016123fb565b610dd261287e88888888888888610940565b612c96565b60685460ff166128a657604051635386698160e01b815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3905f90a1565b5f54610100900460ff166129445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610b0d565b6107d8612d55565b6060604082511061296b578180602001905181019061083e9190613b9b565b8151602003612ab1575f5b6020811080156129a55750828181518110612993576129936135cb565b01602001516001600160f81b03191615155b156129bc57806129b481613bcd565b915050612976565b805f036129f35750506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b6020820152919050565b5f8167ffffffffffffffff811115612a0d57612a0d613412565b6040519080825280601f01601f191660200182016040528015612a37576020820181803683370190505b5090505f5b82811015612aa957848181518110612a5657612a566135cb565b602001015160f81c60f81b828281518110612a7357612a736135cb565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600101612a3c565b509392505050565b50506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b602082015290565b919050565b6068545f906501000000000090046001600160a01b031663257b3632612b1386865f9182526020526040902090565b6040518263ffffffff1660e01b8152600401612b3191815260200190565b6020604051808303815f875af1158015612b4d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b719190613762565b9050805f03612b9257604051622f6fad60e01b815260040160405180910390fd5b5f8068010000000000000000871615612bd657869150612bb4848a8489611d6c565b612bd1576040516338105f3b60e21b815260040160405180910390fd5b612c20565b602087901c612be6816001613be5565b9150879250612c01612bf9868c86610baf565b8a8389611d6c565b612c1e576040516338105f3b60e21b815260040160405180910390fd5b505b612c2a8282612dbf565b505050505050505050565b5f612c496001600160a01b03841683612e66565b905080515f14158015612c6d575080806020019051810190612c6b9190613c01565b155b1561242d57604051635274afe760e01b81526001600160a01b0384166004820152602401610b0d565b806001612ca560206002613cff565b612caf9190613779565b60535410612cd0576040516377ae67b360e11b815260040160405180910390fd5b5f60535f8154612cdf90613bcd565b918290555090505f5b6020811015612d4c578082901c600116600103612d1b578260338260208110612d1357612d136135cb565b015550505050565b612d4260338260208110612d3157612d316135cb565b0154845f9182526020526040902090565b9250600101612ce8565b5061242d613d0a565b5f54610100900460ff166125135760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610b0d565b6068545f90610100900463ffffffff16158015612de2575063ffffffff82166001145b15612df4575063ffffffff8216612e1c565b612e0964010000000063ffffffff841661369e565b612e199063ffffffff85166136b5565b90505b600881901c5f8181526069602052604081208054600160ff861690811b91821892839055929091908183169003610dd257604051630c8d9eab60e31b815260040160405180910390fd5b6060610c3783835f845f5f856001600160a01b03168486604051612e8a91906136d7565b5f6040518083038185875af1925050503d805f8114612ec4576040519150601f19603f3d011682016040523d82523d5f602084013e612ec9565b606091505b5091509150612ed9868383612ee3565b9695505050505050565b606082612ef857612ef382612f3f565b610c37565b8151158015612f0f57506001600160a01b0384163b155b15612f3857604051639996b31560e01b81526001600160a01b0385166004820152602401610b0d565b5080610c37565b805115612f4f5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b803563ffffffff81168114612adf575f5ffd5b6001600160a01b0381168114612f68575f5ffd5b5f5f60408385031215612fa3575f5ffd5b612fac83612f6b565b91506020830135612fbc81612f7e565b809150509250929050565b8015158114612f68575f5ffd5b5f5f83601f840112612fe4575f5ffd5b50813567ffffffffffffffff811115612ffb575f5ffd5b602083019150836020828501011115613012575f5ffd5b9250929050565b5f5f5f5f5f6080868803121561302d575f5ffd5b61303686612f6b565b9450602086013561304681612f7e565b9350604086013561305681612fc7565b9250606086013567ffffffffffffffff811115613071575f5ffd5b61307d88828901612fd4565b969995985093965092949392505050565b5f5b838110156130a8578181015183820152602001613090565b50505f910152565b5f81518084526130c781602086016020860161308e565b601f01601f19169290920160200192915050565b602081525f610c3760208301846130b0565b5f602082840312156130fd575f5ffd5b8135610c3781612f7e565b60ff81168114612f68575f5ffd5b5f5f5f5f5f5f5f60e0888a03121561312c575f5ffd5b873561313781613108565b965061314560208901612f6b565b9550604088013561315581612f7e565b945061316360608901612f6b565b9350608088013561317381612f7e565b9699959850939692959460a0840135945060c09093013592915050565b5f602082840312156131a0575f5ffd5b5035919050565b80610400810183101561083e575f5ffd5b5f5f5f61044084860312156131cb575f5ffd5b833592506131dc85602086016131a7565b91506131eb6104208501612f6b565b90509250925092565b5f5f5f5f5f5f60a08789031215613209575f5ffd5b61321287612f6b565b9550602087013561322281612f7e565b945060408701359350606087013561323981612fc7565b9250608087013567ffffffffffffffff811115613254575f5ffd5b61326089828a01612fd4565b979a9699509497509295939492505050565b5f5f60408385031215613283575f5ffd5b61328c83612f6b565b915061329a60208401612f6b565b90509250929050565b5f5f5f5f5f5f5f5f5f5f5f5f6109208d8f0312156132bf575f5ffd5b6132c98e8e6131a7565b9b506132d98e6104008f016131a7565b9a506108008d013599506108208d013598506108408d013597506133006108608e01612f6b565b96506133106108808e0135612f7e565b6108808d013595506133256108a08e01612f6b565b94506108c08d013561333681612f7e565b93506108e08d0135925067ffffffffffffffff6109008e01351115613359575f5ffd5b61336a8e6109008f01358f01612fd4565b81935080925050509295989b509295989b509295989b565b5f5f5f5f5f5f5f60c0888a031215613398575f5ffd5b6133a188612f6b565b965060208801356133b181612f7e565b95506040880135945060608801356133c881612f7e565b935060808801356133d881612fc7565b925060a088013567ffffffffffffffff8111156133f3575f5ffd5b6133ff8a828b01612fd4565b989b979a50959850939692959293505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561344f5761344f613412565b604052919050565b5f67ffffffffffffffff82111561347057613470613412565b50601f01601f191660200190565b5f5f5f5f5f5f60c08789031215613493575f5ffd5b61349c87612f6b565b955060208701356134ac81612f7e565b94506134ba60408801612f6b565b935060608701356134ca81612f7e565b925060808701356134da81612f7e565b915060a087013567ffffffffffffffff8111156134f5575f5ffd5b8701601f81018913613505575f5ffd5b803561351861351382613457565b613426565b8181528a602083850101111561352c575f5ffd5b816020840160208301375f602083830101528093505050509295509295509295565b5f5f5f5f6104608587031215613562575f5ffd5b8435935061357386602087016131a7565b92506135826104208601612f6b565b939692955092936104400135925050565b600181811c908216806135a757607f821691505b6020821081036135c557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b606081525f6135f160608301866130b0565b828103602084015261360381866130b0565b91505060ff83166040830152949350505050565b5f61362461351384613457565b9050828152838383011115613637575f5ffd5b610c3783602083018461308e565b5f60208284031215613655575f5ffd5b815167ffffffffffffffff81111561366b575f5ffd5b8201601f8101841361367b575f5ffd5b61219084825160208401613617565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761083e5761083e61368a565b8082018082111561083e5761083e61368a565b818382375f9101908152919050565b5f82516136e881846020870161308e565b9190910192915050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b63ffffffff861681526001600160a01b03851660208201526001600160a01b0384166040820152608060608201525f6137576080830184866136f2565b979650505050505050565b5f60208284031215613772575f5ffd5b5051919050565b8181038181111561083e5761083e61368a565b60ff8916815263ffffffff881660208201526001600160a01b038716604082015263ffffffff861660608201526001600160a01b03851660808201528360a082015261010060c08201525f6137e56101008301856130b0565b905063ffffffff831660e08301529998505050505050505050565b6001600160a01b038516815263ffffffff84166020820152606060408201525f612ed96060830184866136f2565b601f82111561242d57805f5260205f20601f840160051c810160208510156138535750805b601f840160051c820191505b818110156108ad575f815560010161385f565b815167ffffffffffffffff81111561388c5761388c613412565b6138a08161389a8454613593565b8461382e565b6020601f8211600181146138d2575f83156138bb5750848201515b5f19600385901b1c1916600184901b1784556108ad565b5f84815260208120601f198516915b8281101561390157878501518255602094850194600190920191016138e1565b508482101561391e57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b60ff8a16815263ffffffff891660208201526001600160a01b038816604082015263ffffffff871660608201526001600160a01b03861660808201528460a082015261010060c08201525f613987610100830185876136f2565b905063ffffffff831660e08301529a9950505050505050505050565b5f602082840312156139b3575f5ffd5b8151610c3781612f7e565b5f602082840312156139ce575f5ffd5b8151610c3781613108565b5f82601f8301126139e8575f5ffd5b610c3783835160208501613617565b5f5f5f60608486031215613a09575f5ffd5b835167ffffffffffffffff811115613a1f575f5ffd5b613a2b868287016139d9565b935050602084015167ffffffffffffffff811115613a47575f5ffd5b613a53868287016139d9565b9250506040840151613a6481613108565b809150509250925092565b5f5f85851115613a7d575f5ffd5b83861115613a89575f5ffd5b5050820193919092039150565b80356001600160e01b03198116906004841015613ac7576001600160e01b0319600485900360031b81901b82161691505b5092915050565b5f5f5f5f5f5f5f60e0888a031215613ae4575f5ffd5b8735613aef81612f7e565b96506020880135613aff81612f7e565b95506040880135945060608801359350608088013561317381613108565b5f5f5f5f5f5f5f5f610100898b031215613b35575f5ffd5b8835613b4081612f7e565b97506020890135613b5081612f7e565b965060408901359550606089013594506080890135613b6e81612fc7565b935060a0890135613b7e81613108565b979a969950949793969295929450505060c08201359160e0013590565b5f60208284031215613bab575f5ffd5b815167ffffffffffffffff811115613bc1575f5ffd5b612190848285016139d9565b5f60018201613bde57613bde61368a565b5060010190565b63ffffffff818116838216019081111561083e5761083e61368a565b5f60208284031215613c11575f5ffd5b8151610c3781612fc7565b6001815b6001841115613c5757808504811115613c3b57613c3b61368a565b6001841615613c4957908102905b60019390931c928002613c20565b935093915050565b5f82613c6d5750600161083e565b81613c7957505f61083e565b8160018114613c8f5760028114613c9957613cb5565b600191505061083e565b60ff841115613caa57613caa61368a565b50506001821b61083e565b5060208310610133831016604e8410600b8410161715613cd8575081810a61083e565b613ce45f198484613c1c565b805f1904821115613cf757613cf761368a565b029392505050565b5f610c378383613c5f565b634e487b7160e01b5f52600160045260245ffdfea2646970667358221220063c266597e2ffb56d9201c033295ea34c1635e74b868a78fefd4480fab2183364736f6c634300081c0033", + "storage": null + }, + "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851": { + "contractName": "PolygonZkEVMBridgeV2 proxy", + "balance": "340282366920938463463374607431768211455", + "nonce": "1", + "code": "0x60806040526004361061005d575f3560e01c80635c60da1b116100425780635c60da1b146100a65780638f283970146100e3578063f851a440146101025761006c565b80633659cfe6146100745780634f1ef286146100935761006c565b3661006c5761006a610116565b005b61006a610116565b34801561007f575f5ffd5b5061006a61008e366004610854565b610130565b61006a6100a136600461086d565b610178565b3480156100b1575f5ffd5b506100ba6101eb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee575f5ffd5b5061006a6100fd366004610854565b610228565b34801561010d575f5ffd5b506100ba610255565b61011e610282565b61012e610129610359565b610362565b565b610138610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d8160405180602001604052805f8152505f6103bf565b50565b61016d610116565b610180610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101e3576101de8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250600192506103bf915050565b505050565b6101de610116565b5f6101f4610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610359565b905090565b610225610116565b90565b610230610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d816103e9565b5f61025e610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610380565b61028a610380565b73ffffffffffffffffffffffffffffffffffffffff16330361012e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b5f61021861044a565b365f5f375f5f365f845af43d5f5f3e80801561037c573d5ff35b3d5ffd5b5f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103c883610471565b5f825111806103d45750805b156101de576103e383836104bd565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610412610380565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161016d816104e9565b5f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103a3565b61047a816105f5565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606104e28383604051806060016040528060278152602001610979602791396106c0565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811661058c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610350565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610350565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105af565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff16856040516106e9919061090d565b5f60405180830381855af49150503d805f8114610721576040519150601f19603f3d011682016040523d82523d5f602084013e610726565b606091505b509150915061073786838387610741565b9695505050505050565b606083156107d65782515f036107cf5773ffffffffffffffffffffffffffffffffffffffff85163b6107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610350565b50816107e0565b6107e083836107e8565b949350505050565b8151156107f85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103509190610928565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f575f5ffd5b919050565b5f60208284031215610864575f5ffd5b6104e28261082c565b5f5f5f6040848603121561087f575f5ffd5b6108888461082c565b9250602084013567ffffffffffffffff8111156108a3575f5ffd5b8401601f810186136108b3575f5ffd5b803567ffffffffffffffff8111156108c9575f5ffd5b8660208284010111156108da575f5ffd5b939660209190910195509293505050565b5f5b838110156109055781810151838201526020016108ed565b50505f910152565b5f825161091e8184602087016108eb565b9190910192915050565b602081525f82518060208401526109468160408501602087016108eb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e5f7d1b8c5bf56b8d0f8312db5fe19231c55d442867ab851e163d2e86985168464736f6c634300081c0033", + "storage": { + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000012060ca70f50a24fde90fea110002c235f558a56", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000c2c5fb710e85bedc5c18a8a0fa931d75983f2185" + } + }, + "0x21BD2401BA404841c7feC1816F5a0AaAdbc486eF": { + "contractName": "PolygonZkEVMGlobalExitRootL2 implementation", + "balance": "0", + "nonce": "1", + "code": "0x608060405234801561000f575f5ffd5b506004361061004a575f3560e01c806301fd90441461004e578063257b36321461006a57806333d6247d14610089578063a3c573eb1461009e575b5f5ffd5b61005760015481565b6040519081526020015b60405180910390f35b61005761007836600461015e565b5f6020819052908152604090205481565b61009c61009736600461015e565b6100ea565b005b6100c57f000000000000000000000000b2fac1ce54bb9bf77a7fe106fa69f81453b7285181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610061565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000b2fac1ce54bb9bf77a7fe106fa69f81453b728511614610159576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b5f6020828403121561016e575f5ffd5b503591905056fea2646970667358221220f0c42c4ea26e8c61a4cac40e1273224f46c3c1fd3c84d399b407eb29edfebdc864736f6c634300081c0033", + "storage": null + }, + "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa": { + "contractName": "PolygonZkEVMGlobalExitRootL2 proxy", + "balance": "0", + "nonce": "1", + "code": "0x60806040523661001357610011610017565b005b6100115b61001f6101b7565b6001600160a01b0316336001600160a01b0316141561016f5760606001600160e01b031960003516631b2ce7f360e11b8114156100655761005e6101ea565b9150610167565b6001600160e01b0319811663278f794360e11b14156100865761005e610241565b6001600160e01b031981166308f2839760e41b14156100a75761005e610287565b6001600160e01b031981166303e1469160e61b14156100c85761005e6102b8565b6001600160e01b03198116635c60da1b60e01b14156100e95761005e6102f8565b60405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b815160208301f35b61017761030c565b565b606061019e83836040518060600160405280602781526020016108576027913961031c565b9392505050565b90565b6001600160a01b03163b151590565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b60606101f4610394565b600061020336600481846106a2565b81019061021091906106e8565b905061022d8160405180602001604052806000815250600061039f565b505060408051602081019091526000815290565b606060008061025336600481846106a2565b8101906102609190610719565b915091506102708282600161039f565b604051806020016040528060008152509250505090565b6060610291610394565b60006102a036600481846106a2565b8101906102ad91906106e8565b905061022d816103cb565b60606102c2610394565b60006102cc6101b7565b604080516001600160a01b03831660208201529192500160405160208183030381529060405291505090565b6060610302610394565b60006102cc610422565b610177610317610422565b610431565b6060600080856001600160a01b0316856040516103399190610807565b600060405180830381855af49150503d8060008114610374576040519150601f19603f3d011682016040523d82523d6000602084013e610379565b606091505b509150915061038a86838387610455565b9695505050505050565b341561017757600080fd5b6103a8836104d3565b6000825111806103b55750805b156103c6576103c48383610179565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103f46101b7565b604080516001600160a01b03928316815291841660208301520160405180910390a161041f81610513565b50565b600061042c6105bc565b905090565b3660008037600080366000845af43d6000803e808015610450573d6000f35b3d6000fd5b606083156104c15782516104ba576001600160a01b0385163b6104ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161015e565b50816104cb565b6104cb83836105e4565b949350505050565b6104dc8161060e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105785760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6101db565b8151156105f45781518083602001fd5b8060405162461bcd60e51b815260040161015e9190610823565b6001600160a01b0381163b61067b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161015e565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61059b565b600080858511156106b257600080fd5b838611156106bf57600080fd5b5050820193919092039150565b80356001600160a01b03811681146106e357600080fd5b919050565b6000602082840312156106fa57600080fd5b61019e826106cc565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561072c57600080fd5b610735836106cc565b9150602083013567ffffffffffffffff8082111561075257600080fd5b818501915085601f83011261076657600080fd5b81358181111561077857610778610703565b604051601f8201601f19908116603f011681019083821181831017156107a0576107a0610703565b816040528281528860208487010111156107b957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b838110156107f65781810151838201526020016107de565b838111156103c45750506000910152565b600082516108198184602087016107db565b9190910192915050565b60208152600082518060208401526108428160408501602087016107db565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122012bb4f564f73959a03513dc74fc3c6e40e8386e6f02c16b78d6db00ce0aa16af64736f6c63430008090033", + "storage": { + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000021bd2401ba404841c7fec1816f5a0aaadbc486ef", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000c2c5fb710e85bedc5c18a8a0fa931d75983f2185" + } + }, + "0x27284DBa79e6DF953Fbd232A9d8D87029F03BBf5": { + "contractName": "PolygonZkEVMTimelock", + "balance": "0", + "nonce": "1", + "code": "0x6080604052600436106101bd575f3560e01c806364d62353116100f2578063b1c5f42711610092578063d547741f11610062578063d547741f1461063a578063e38335e514610659578063f23a6e611461066c578063f27a0c92146106b0575f80fd5b8063b1c5f4271461058d578063bc197c81146105ac578063c4d252f5146105f0578063d45c44351461060f575f80fd5b80638f61f4f5116100cd5780638f61f4f5146104c557806391d14854146104f8578063a217fddf14610547578063b08e51c01461055a575f80fd5b806364d62353146104685780638065657f146104875780638f2a0bb0146104a6575f80fd5b8063248a9ca31161015d57806331d507501161013857806331d50750146103b357806336568abe146103d25780633a6aae72146103f1578063584b153e14610449575f80fd5b8063248a9ca3146103375780632ab0f529146103655780632f2ff15d14610394575f80fd5b80630d3cf6fc116101985780630d3cf6fc1461025e578063134008d31461029157806313bc9f20146102a4578063150b7a02146102c3575f80fd5b806301d5062a146101c857806301ffc9a7146101e957806307bd02651461021d575f80fd5b366101c457005b5f80fd5b3480156101d3575f80fd5b506101e76101e2366004611bf6565b6106c4565b005b3480156101f4575f80fd5b50610208610203366004611c65565b610757565b60405190151581526020015b60405180910390f35b348015610228575f80fd5b506102507fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610214565b348015610269575f80fd5b506102507f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101e761029f366004611ca4565b6107b2565b3480156102af575f80fd5b506102086102be366004611d0b565b6108a7565b3480156102ce575f80fd5b506103066102dd366004611e28565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610214565b348015610342575f80fd5b50610250610351366004611d0b565b5f9081526020819052604090206001015490565b348015610370575f80fd5b5061020861037f366004611d0b565b5f908152600160208190526040909120541490565b34801561039f575f80fd5b506101e76103ae366004611e8c565b6108cc565b3480156103be575f80fd5b506102086103cd366004611d0b565b6108f5565b3480156103dd575f80fd5b506101e76103ec366004611e8c565b61090d565b3480156103fc575f80fd5b506104247f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b348015610454575f80fd5b50610208610463366004611d0b565b6109c5565b348015610473575f80fd5b506101e7610482366004611d0b565b6109da565b348015610492575f80fd5b506102506104a1366004611ca4565b610aaa565b3480156104b1575f80fd5b506101e76104c0366004611ef7565b610ae8565b3480156104d0575f80fd5b506102507fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b348015610503575f80fd5b50610208610512366004611e8c565b5f9182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610552575f80fd5b506102505f81565b348015610565575f80fd5b506102507ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b348015610598575f80fd5b506102506105a7366004611fa0565b610d18565b3480156105b7575f80fd5b506103066105c63660046120be565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b3480156105fb575f80fd5b506101e761060a366004611d0b565b610d5c565b34801561061a575f80fd5b50610250610629366004611d0b565b5f9081526001602052604090205490565b348015610645575f80fd5b506101e7610654366004611e8c565b610e56565b6101e7610667366004611fa0565b610e7a565b348015610677575f80fd5b50610306610686366004612161565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106bb575f80fd5b50610250611121565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc16106ee81611200565b5f6106fd898989898989610aaa565b9050610709818461120d565b5f817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a60405161074496959493929190612208565b60405180910390a3505050505050505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107ac57506107ac82611359565b92915050565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661082e5761082e81336113ef565b5f61083d888888888888610aaa565b905061084981856114a6565b610855888888886115e2565b5f817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a60405161088c9493929190612252565b60405180910390a361089d816116e2565b5050505050505050565b5f818152600160205260408120546001811180156108c55750428111155b9392505050565b5f828152602081905260409020600101546108e681611200565b6108f0838361178a565b505050565b5f8181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109c18282611878565b5050565b5f818152600160208190526040822054610906565b333014610a69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109ae565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b5f868686868686604051602001610ac696959493929190612208565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b1281611200565b888714610ba1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b888514610c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f610c418b8b8b8b8b8b8b8b610d18565b9050610c4d818461120d565b5f5b8a811015610d0a5780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610c8c57610c8c612291565b9050602002016020810190610ca191906122be565b8d8d86818110610cb357610cb3612291565b905060200201358c8c87818110610ccc57610ccc612291565b9050602002810190610cde91906122d7565b8c8b604051610cf296959493929190612208565b60405180910390a3610d0381612365565b9050610c4f565b505050505050505050505050565b5f8888888888888888604051602001610d38989796959493929190612447565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610d8681611200565b610d8f826109c5565b610e1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109ae565b5f828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b5f82815260208190526040902060010154610e7081611200565b6108f08383611878565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610ef657610ef681336113ef565b878614610f85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b878414611014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f6110258a8a8a8a8a8a8a8a610d18565b905061103181856114a6565b5f5b8981101561110b575f8b8b8381811061104e5761104e612291565b905060200201602081019061106391906122be565b90505f8a8a8481811061107857611078612291565b905060200201359050365f8a8a8681811061109557611095612291565b90506020028101906110a791906122d7565b915091506110b7848484846115e2565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58868686866040516110ee9493929190612252565b60405180910390a3505050508061110490612365565b9050611033565b50611115816116e2565b50505050505050505050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16158015906111ef57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ef919061250c565b156111f957505f90565b5060025490565b61120a81336113ef565b50565b611216826108f5565b156112a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109ae565b6112ab611121565b81101561133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109ae565b611344814261252b565b5f928352600160205260409092209190915550565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107ac57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107ac565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c15761142c8161192d565b61143783602061194c565b604051602001611448929190612560565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109ae916004016125e0565b6114af826108a7565b61153b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b80158061155657505f81815260016020819052604090912054145b6109c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f8473ffffffffffffffffffffffffffffffffffffffff1684848460405161160b929190612630565b5f6040518083038185875af1925050503d805f8114611645576040519150601f19603f3d011682016040523d82523d5f602084013e61164a565b606091505b50509050806116db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109ae565b5050505050565b6116eb816108a7565b611777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b5f90815260016020819052604090912055565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561181a3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107ac73ffffffffffffffffffffffffffffffffffffffff831660145b60605f61195a83600261263f565b61196590600261252b565b67ffffffffffffffff81111561197d5761197d611d22565b6040519080825280601f01601f1916602001820160405280156119a7576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106119dd576119dd612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a3f57611a3f612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f611a7984600261263f565b611a8490600161252b565b90505b6001811115611b20577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611ac557611ac5612291565b1a60f81b828281518110611adb57611adb612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c93611b1981612656565b9050611a87565b5083156108c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109ae565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bac575f80fd5b919050565b5f8083601f840112611bc1575f80fd5b50813567ffffffffffffffff811115611bd8575f80fd5b602083019150836020828501011115611bef575f80fd5b9250929050565b5f805f805f805f60c0888a031215611c0c575f80fd5b611c1588611b89565b965060208801359550604088013567ffffffffffffffff811115611c37575f80fd5b611c438a828b01611bb1565b989b979a50986060810135976080820135975060a09091013595509350505050565b5f60208284031215611c75575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108c5575f80fd5b5f805f805f8060a08789031215611cb9575f80fd5b611cc287611b89565b955060208701359450604087013567ffffffffffffffff811115611ce4575f80fd5b611cf089828a01611bb1565b979a9699509760608101359660809091013595509350505050565b5f60208284031215611d1b575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d9657611d96611d22565b604052919050565b5f82601f830112611dad575f80fd5b813567ffffffffffffffff811115611dc757611dc7611d22565b611df860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d4f565b818152846020838601011115611e0c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611e3b575f80fd5b611e4485611b89565b9350611e5260208601611b89565b925060408501359150606085013567ffffffffffffffff811115611e74575f80fd5b611e8087828801611d9e565b91505092959194509250565b5f8060408385031215611e9d575f80fd5b82359150611ead60208401611b89565b90509250929050565b5f8083601f840112611ec6575f80fd5b50813567ffffffffffffffff811115611edd575f80fd5b6020830191508360208260051b8501011115611bef575f80fd5b5f805f805f805f805f60c08a8c031215611f0f575f80fd5b893567ffffffffffffffff80821115611f26575f80fd5b611f328d838e01611eb6565b909b50995060208c0135915080821115611f4a575f80fd5b611f568d838e01611eb6565b909950975060408c0135915080821115611f6e575f80fd5b50611f7b8c828d01611eb6565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b5f805f805f805f8060a0898b031215611fb7575f80fd5b883567ffffffffffffffff80821115611fce575f80fd5b611fda8c838d01611eb6565b909a50985060208b0135915080821115611ff2575f80fd5b611ffe8c838d01611eb6565b909850965060408b0135915080821115612016575f80fd5b506120238b828c01611eb6565b999c989b509699959896976060870135966080013595509350505050565b5f82601f830112612050575f80fd5b8135602067ffffffffffffffff82111561206c5761206c611d22565b8160051b61207b828201611d4f565b9283528481018201928281019087851115612094575f80fd5b83870192505b848310156120b35782358252918301919083019061209a565b979650505050505050565b5f805f805f60a086880312156120d2575f80fd5b6120db86611b89565b94506120e960208701611b89565b9350604086013567ffffffffffffffff80821115612105575f80fd5b61211189838a01612041565b94506060880135915080821115612126575f80fd5b61213289838a01612041565b93506080880135915080821115612147575f80fd5b5061215488828901611d9e565b9150509295509295909350565b5f805f805f60a08688031215612175575f80fd5b61217e86611b89565b945061218c60208701611b89565b93506040860135925060608601359150608086013567ffffffffffffffff8111156121b5575f80fd5b61215488828901611d9e565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a060408201525f61223d60a0830186886121c1565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201525f6122876060830184866121c1565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082840312156122ce575f80fd5b6108c582611b89565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261230a575f80fd5b83018035915067ffffffffffffffff821115612324575f80fd5b602001915036819003821315611bef575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361239557612395612338565b5060010190565b8183525f6020808501808196508560051b81019150845f5b8781101561243a57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126123f2575f80fd5b8701858101903567ffffffffffffffff81111561240d575f80fd5b80360382131561241b575f80fd5b6124268682846121c1565b9a87019a95505050908401906001016123b4565b5091979650505050505050565b60a080825281018890525f8960c08301825b8b8110156124945773ffffffffffffffffffffffffffffffffffffffff61247f84611b89565b16825260209283019290910190600101612459565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8911156124cc575f80fd5b8860051b9150818a602083013701828103602090810160408501526124f4908201878961239c565b60608401959095525050608001529695505050505050565b5f6020828403121561251c575f80fd5b815180151581146108c5575f80fd5b808201808211156107ac576107ac612338565b5f5b83811015612558578181015183820152602001612540565b50505f910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f835161259781601785016020880161253e565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516125d481602884016020880161253e565b01602801949350505050565b602081525f82518060208401526125fe81604085016020870161253e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b818382375f9101908152919050565b80820281158282048414176107ac576107ac612338565b5f8161266457612664612338565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220ffae92f944289ff2d8d50b1f6dc43374b9a4ff2979d908883d35eec5819b612c64736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", + "0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x35fa115b92f0a8d03c972ada19f34c3fa238589ba573a59a419692abc6a91f1a": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x3e92e57d702d5fdc47a588386c93df7f5578fb6af324e63318e76ec6cffcab32": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x6b347b5397bd05b592ec00f3e3a28ac3cedc5d7ee6994c7533215f223a0cfe84": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x73aec4d9eb3be1097d809826691104f0c28da74ebf68d903dc9c6f12562fd822": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xc05edde0499e76380516353a6ad6ced0d360179c67da013977526f6fbac38774": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5" + } + }, + "0x6Ea4D2dd7dFEb6945d1B57a42DC68FE7E06126ce": { + "contractName": null, + "balance": "0", + "nonce": "1", + "code": null, + "storage": null + }, + "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534": { + "contractName": null, + "balance": "100000000000000000000000", + "nonce": "8", + "code": null, + "storage": null + } +} \ No newline at end of file diff --git a/test-pp-op/config/dynamic-mynetwork-chainspec.json b/test-pp-op/config/dynamic-mynetwork-chainspec.json new file mode 100644 index 0000000000000..62d49e44e1b6b --- /dev/null +++ b/test-pp-op/config/dynamic-mynetwork-chainspec.json @@ -0,0 +1,25 @@ +{ + "ChainName": "dynamic-mynetwork", + "chainId": 195, + "consensus": "ethash", + "homesteadBlock": 0, + "daoForkBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 9999999999999999999999999999999999999999999999999, + "arrowGlacierBlock": 9999999999999999999999999999999999999999999999999, + "grayGlacierBlock": 9999999999999999999999999999999999999999999999999, + "terminalTotalDifficulty": 58750000000000000000000, + "terminalTotalDifficultyPassed": false, + "shanghaiTime": 9999999999999999999999999999999999999999999999999, + "cancunTime": 9999999999999999999999999999999999999999999999999, + "pragueTime": 9999999999999999999999999999999999999999999999999, + "ethash": {} +} + diff --git a/test-pp-op/config/dynamic-mynetwork-conf.json b/test-pp-op/config/dynamic-mynetwork-conf.json new file mode 100644 index 0000000000000..9ce28d4252cc1 --- /dev/null +++ b/test-pp-op/config/dynamic-mynetwork-conf.json @@ -0,0 +1,6 @@ +{ + "root": "0x6565265b546acdc3b714218d5bdb667725002a6fa07b5045f5ed4ad7595ebd62", + "timestamp": 1760602860, + "gasLimit": 0, + "difficulty": 0 +} diff --git a/test-pp-op/config/first-batch-config.json b/test-pp-op/config/first-batch-config.json new file mode 100644 index 0000000000000..f622df8200c75 --- /dev/null +++ b/test-pp-op/config/first-batch-config.json @@ -0,0 +1,9 @@ +{ + "batchL2Data": "0xf901e480808401c9c38094b2fac1ce54bb9bf77a7fe106fa69f81453b7285180b901c4f811bff700000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000084f4b42546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034f4b42000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005ca1ab1e0000000000000000000000000000000000000000000000000000000005ca1ab1e1bff", + "globalExitRoot": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", + "timestamp": 1760602860, + "sequencer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "l1BlockNumber": 100, + "l1BlockHash": "0xfbd5bff822e23e6864b1185686864ac8bc9a7645756dce00586ed909b9f3c78e", + "l1ParentHash": "0xd3bf883426e5f8f374ed2699fc9c9026d136e212c57f4fc48288f8c2d189fadd" +} diff --git a/test-pp-op/config/local/local.erigon.rpc.config.yaml b/test-pp-op/config/local/local.erigon.rpc.config.yaml new file mode 100644 index 0000000000000..9368b7782aa84 --- /dev/null +++ b/test-pp-op/config/local/local.erigon.rpc.config.yaml @@ -0,0 +1,114 @@ +datadir: /home/erigon/data/ +chain: dynamic-mynetwork +http: true +private.api.addr: localhost:9091 +zkevm.l2-chain-id: 195 +zkevm.l2-sequencer-rpc-url: xlayer-seq:8545 +zkevm.l2-datastreamer-url: xlayer-seq:6900 +zkevm.l1-chain-id: 1337 +zkevm.l1-rpc-url: http://xlayer-mock-l1-network:8545 +zkevm.l1-highest-block-type: latest + +zkevm.address-sequencer: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" +zkevm.address-zkevm: "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" +zkevm.address-admin: "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" +zkevm.address-rollup: "0xE96dBF374555C6993618906629988d39184716B3" +zkevm.address-ger-manager: "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" + +zkevm.l1-rollup-id: 1 +zkevm.l1-first-block: 75 +zkevm.l1-block-range: 10 +zkevm.l1-query-delay: 6000 +zkevm.rpc-ratelimit: 0 +zkevm.datastream-version: 2 + +log.console.verbosity: info + +#zkevm.executor-urls: xlayer-executor:50071 +# zkevm.executor-strict: false +# zkevm.witness-full: false +# zkevm.executor-mock: true + +zkevm.sequencer-block-seal-time: "1s" +zkevm.sequencer-max-block-seal-time: "3s" +zkevm.sequencer-batch-seal-time: "10s" +zkevm.sequencer-batch-sleep-duration: "0s" + +#zkevm.data-stream-host: "localhost" +#zkevm.data-stream-port: 6900 +zkevm.default-gas-price: 1000000000 +zkevm.max-gas-price: 0 +zkevm.gas-price-factor: 0.000001 +zkevm.allow-free-transactions: true + +externalcl: true +http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] +http.addr: 0.0.0.0 +http.port: 8545 +http.vhosts: any +http.corsdomain: any +http.timeouts.read: "10s" +http.timeouts.write: "10s" +http.timeouts.idle: "10s" +rpc.batch.concurrency: 2 +rpc.batch.limit: 20 +ws: true + +zkevm.apollo-enabled: false +zkevm.apollo-ip-addr: "" +zkevm.apollo-app-id: "" +zkevm.apollo-namespace-name: "" + +zkevm.nacos-urls: "" +zkevm.nacos-namespace-id: "" +zkevm.nacos-application-name: "" +zkevm.nacos-external-listen-addr: "" + +metrics: true +metrics.addr: "0.0.0.0" +metrics.port: 9095 + +db.read.concurrency: 20000 +txpool.globalslots: 1000000 +txpool.globalbasefeeslots: 1000000 +txpool.globalqueue: 1000000 +txpool.packbatchspeciallist : ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534"] +txpool.gaspricemultiple : 2 +txpool.blockedlist: ["0xdD2FD4581271e230360230F9337D5c0430Bf44C0"] +txpool.enablefreegasbynonce : true +txpool.freegascountperaddr : 100 +txpool.commit.every: "10m" + +gpo.type: "follower" +gpo.update-period: "3s" +gpo.factor: 0.01 +gpo.kafka-url: "0.0.0.0" +gpo.topic: "explorer" +gpo.group-id: "web3" +gpo.blocks: 3 +gpo.default-l1-coin-price: 2000 +gpo.default-l2-coin-price: 50 +gpo.gas-price-usdt: 0.000000476190476 +gpo.congestion-threshold: 0 + +networkid: 195 + +pprof: true +pprof.port: 6060 +pprof.addr: 0.0.0.0 +txpool.enablefreegaslist : true +txpool.freegaslist : '[{"name":"e2e", "from_list":["0x586cbc95ed16031d9efdaebacf1c1d2bc3ccaa78"], "to_list":["0xad1d01007a56ee0a4ffd0488fb58fc6500cb1fbe"], "method_sigs":["a9059cbb"], "gas_price_multiple": 1}]' + +# close a block/batch immediately after the 1st zkCounter overflow TX +zkevm.seal-batch-immediately-on-overflow: true +zkevm.sequencer-timeout-on-empty-tx-pool: 5ms +zkevm.pre-run-address-list: [""] +zkevm.block-info-concurrent: true +zkevm.standalone-smt-db: true # true: enable split smt db, false: not split +zkevm.enable-async-commit: true + +# to reduce lock race in stress test +txpool.enabletimsort: true +zkevm.bulk-add-txs: true +zkevm.enable-add-tx-notify: true +zkevm.initial-batch.config: /usr/src/app/first-batch-config.json \ No newline at end of file diff --git a/test-pp-op/config/local/local.erigon.seq.config.yaml b/test-pp-op/config/local/local.erigon.seq.config.yaml new file mode 100644 index 0000000000000..05534cd103af4 --- /dev/null +++ b/test-pp-op/config/local/local.erigon.seq.config.yaml @@ -0,0 +1,109 @@ +datadir: /home/erigon/data/ +chain: dynamic-mynetwork +http: true +private.api.addr: localhost:9091 +zkevm.l2-chain-id: 195 +zkevm.l2-sequencer-rpc-url: +zkevm.l2-datastreamer-url: +zkevm.l1-chain-id: 1337 +zkevm.l1-rpc-url: http://xlayer-mock-l1-network:8545 +zkevm.l1-highest-block-type: latest + +zkevm.address-sequencer: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" +zkevm.address-zkevm: "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" +zkevm.address-admin: "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" +zkevm.address-rollup: "0xE96dBF374555C6993618906629988d39184716B3" +zkevm.address-ger-manager: "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" + +zkevm.l1-rollup-id: 1 +zkevm.l1-first-block: 156 +zkevm.l1-block-range: 10 +zkevm.l1-query-delay: 6000 +zkevm.rpc-ratelimit: 0 +zkevm.datastream-version: 2 + +log.console.verbosity: info + +zkevm.sequencer-block-seal-time: "1s" +zkevm.sequencer-max-block-seal-time: "3s" +zkevm.sequencer-batch-seal-time: "10s" +zkevm.sequencer-batch-sleep-duration: "0s" + +zkevm.data-stream-host: "localhost" +zkevm.data-stream-port: 6900 +zkevm.default-gas-price: 1000000000 +zkevm.max-gas-price: 0 +zkevm.gas-price-factor: 0.000001 +zkevm.allow-free-transactions: true + +externalcl: true +http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] +http.addr: 0.0.0.0 +http.port: 8545 +http.vhosts: any +http.corsdomain: any +http.timeouts.read: "10s" +http.timeouts.write: "10s" +http.timeouts.idle: "10s" +rpc.batch.concurrency: 2 +rpc.batch.limit: 20 +ws: true + +zkevm.apollo-enabled: false +zkevm.apollo-ip-addr: "" +zkevm.apollo-app-id: "" +zkevm.apollo-namespace-name: "" + +zkevm.nacos-urls: "" +zkevm.nacos-namespace-id: "" +zkevm.nacos-application-name: "" +zkevm.nacos-external-listen-addr: "" + +metrics: true +metrics.addr: "0.0.0.0" +metrics.port: 9095 + +db.read.concurrency: 20000 +txpool.globalslots: 1000000 +txpool.globalbasefeeslots: 1000000 +txpool.globalqueue: 1000000 +txpool.packbatchspeciallist : ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534"] +txpool.gaspricemultiple : 2 +txpool.blockedlist: ["0xdD2FD4581271e230360230F9337D5c0430Bf44C0"] +txpool.enablefreegasbynonce : true +txpool.freegascountperaddr : 100 +txpool.commit.every: "10m" + +gpo.type: "follower" +gpo.update-period: "3s" +gpo.factor: 0.01 +gpo.kafka-url: "0.0.0.0" +gpo.topic: "explorer" +gpo.group-id: "web3" +gpo.blocks: 3 +gpo.default-l1-coin-price: 2000 +gpo.default-l2-coin-price: 50 +gpo.gas-price-usdt: 0.000000476190476 +gpo.congestion-threshold: 0 + +networkid: 195 + +pprof: true +pprof.port: 6060 +pprof.addr: 0.0.0.0 +txpool.enablefreegaslist : true +txpool.freegaslist : '[{"name":"e2e", "from_list":["0x586cbc95ed16031d9efdaebacf1c1d2bc3ccaa78"], "to_list":["0xad1d01007a56ee0a4ffd0488fb58fc6500cb1fbe"], "method_sigs":["a9059cbb"], "gas_price_multiple": 1}]' + +# close a block/batch immediately after the 1st zkCounter overflow TX +zkevm.seal-batch-immediately-on-overflow: true +zkevm.sequencer-timeout-on-empty-tx-pool: 5ms +zkevm.pre-run-address-list: [""] +zkevm.block-info-concurrent: true +zkevm.standalone-smt-db: true # true: enable split smt db, false: not split +zkevm.enable-async-commit: true + +# to reduce lock race in stress test +txpool.enabletimsort: true +zkevm.bulk-add-txs: true +zkevm.enable-add-tx-notify: true +zkevm.initial-batch.config: /usr/src/app/first-batch-config.json diff --git a/test-pp-op/config/test.bridge.config.toml b/test-pp-op/config/test.bridge.config.toml new file mode 100644 index 0000000000000..87b7fc7e05729 --- /dev/null +++ b/test-pp-op/config/test.bridge.config.toml @@ -0,0 +1,132 @@ +[Log] +# Set the logging level (e.g., debug, info, warn, error) to control verbosity +Level = "debug" +# Specify the environment in which the application is running (e.g., production, development) +Environment = "production" +# Define where to output logs; options include stderr (standard error) or stdout +Outputs = ["stderr"] + +# Database Synchronization Configuration +# This section contains the database connection settings required for +# synchronizing data. +[SyncDB] +# Type of database to use (e.g., postgres) +Database = "postgres" + [SyncDB.PgStorage] + # Username for database authentication + User = "test_user" + # Name of the database to connect to + Name = "test_db" + # Password for the database user + Password = "test_password" + # Host address of the database server + Host = "xlayer-bridge-db" + # Port number on which the database server is listening + Port = "5432" + # Maximum number of concurrent connections to the database + MaxConns = 20 + +# Etherman Configuration +# This section specifies the RPC URLs for interacting with Layer 1 and Layer 2's. +[Etherman] +# URL for Layer 1 RPC endpoint to interact with the main blockchain +L1URL = "http://l1-geth:8545" +# URLs for Layer 2 RPC endpoints +L2URLs = ["http://xlayer-rpc:8545"] + +# Synchronization Settings +# This section defines the parameters for synchronizing data, including +# the interval and chunk size for synchronization operations. +[Synchronizer] +# Time interval for synchronization iterations (e.g., every 5 seconds) +SyncInterval = "1s" +# Number of blocks to read in each synchronization operation if the service is not synced and if there is enough data. +SyncChunkSize = 50 +# Forces the SyncChunkSize for L2 networks. The chunck size won't be higher than the value specified but if there is not enough events in the network, the reorg protection can be affected. +ForceL2SyncChunk = true + +# Bridge Controller Configuration +# This section contains settings for the bridge controller, including merkle tree height parameter. +[BridgeController] +# Height parameter specifies the height of the merkle tree used for the bridge. +Height = 32 + +# Bridge Server Configuration +# This section defines the settings for the bridge server API, including +# ports for gRPC and HTTP communication, pagination limits, and database. +[BridgeServer] +# Port for gRPC communication with the bridge server +GRPCPort = "9090" +# Port for HTTP communication with the bridge server +HTTPPort = "8080" +# Default limit for paginated results returned by the server +DefaultPageLimit = 25 +# Maximum limit for paginated results to prevent excessive data retrieval +MaxPageLimit = 1000 + # Database configuration for the bridge server. Could be the same config as SyncDB but ideally It should be a read replica to distribute the load. + [BridgeServer.DB] + # Type of database for the bridge server + Database = "postgres" + [BridgeServer.DB.PgStorage] + # Database user for authentication + User = "test_user" + # Database name for the bridge server + Name = "test_db" + # Password for the database user + Password = "test_password" + # Host address of the database server + Host = "xlayer-bridge-db" + # Port number for the database connection + Port = "5432" + # Maximum number of connections to the database for the bridge server + MaxConns = 20 + +# Network Configuration +# This section contains settings related to the network, including smart contract addresses and +# L1 bridge genesis block. +[NetworkConfig] +# Block number where the L1 bridge smart contract was deployed. The bridge needs to compute the merkle tree based on events from that block. +GenBlockNumber = 50 +# Address of the Polygon bridge smc +PolygonBridgeAddress = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" +# Address of the Global exit root smc +PolygonZkEVMGlobalExitRootAddress = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" +# Address of the rollup manager smc +PolygonRollupManagerAddress = "0xE96dBF374555C6993618906629988d39184716B3" +# Address of the zkEVM smc +PolygonZkEVMAddress = "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" +# List of Layer 2 Polygon bridge addresses. It must have the same length as L2URLs. e.g. If 5 networks need to be synced, the urls must be in this array. +L2PolygonBridgeAddresses = ["0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851"] +# Flag indicating whether to require sovereign chain smcs or not. It must have the same length as L2PolygonBridgeAddresses +RequireSovereignChainSmcs = [false] +# List of global exit root addresses for Layer 2. Same length as L2PolygonBridgeAddresses +L2PolygonZkEVMGlobalExitRootAddresses = ["0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa"] + +# Claim Transaction Manager Configuration +# This section contains settings for managing claim transactions. It includes +# enabling or disabling the ClaimTxManager, monitoring frequency, private key +# configuration, and retry settings for sending transactions. +[ClaimTxManager] +# Enable or disable the claim transaction manager +Enabled = true +# Frequency to monitor transactions +FrequencyToMonitorTxs = "5s" +# Path and password for the private key +PrivateKey = {Path = "/pk/keystore.claimtxmanager", Password = "testonly"} +# Interval between retries +RetryInterval = "1s" +# Number of retry attempts +RetryNumber = 10 + +# Metrics Configuration +# This section defines settings for collecting and exposing metrics related +# to the application's performance and health. It includes options to enable +# or disable metrics collection, as well as the host and port for metrics +# exposure. +[Metrics] +# Enable or disable metrics +Enabled = true +# Host address for the metrics +Host = "0.0.0.0" +# Port for the metrics +Port = "8090" diff --git a/test-pp-op/config/test.erigon.rpc.config.yaml b/test-pp-op/config/test.erigon.rpc.config.yaml new file mode 100644 index 0000000000000..ce41932f177d6 --- /dev/null +++ b/test-pp-op/config/test.erigon.rpc.config.yaml @@ -0,0 +1,86 @@ +datadir: /home/erigon/data/ +chain: dynamic-mynetwork +http: true +private.api.addr: localhost:9091 +zkevm.l2-chain-id: 195 +zkevm.l2-sequencer-rpc-url: http://xlayer-seq:8545 +zkevm.l2-datastreamer-url: xlayer-seq:6900 +zkevm.l1-chain-id: 1337 +zkevm.l1-rpc-url: http://l1-geth:8545 +zkevm.l1-highest-block-type: latest + +zkevm.address-sequencer: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" +zkevm.address-zkevm: "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" +zkevm.address-admin: "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" +zkevm.address-rollup: "0xE96dBF374555C6993618906629988d39184716B3" +zkevm.address-ger-manager: "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" + +zkevm.l1-rollup-id: 1 +zkevm.l1-first-block: 156 +zkevm.l1-block-range: 10 +zkevm.l1-query-delay: 6000 +zkevm.rpc-ratelimit: 300 +zkevm.datastream-version: 2 + +log.console.verbosity: info + +#zkevm.executor-urls: xlayer-executor:50071 +# zkevm.executor-urls: "" +# zkevm.executor-strict: false +# zkevm.witness-full: false + +zkevm.sequencer-block-seal-time: "6s" +zkevm.sequencer-batch-seal-time: "12s" +zkevm.sequencer-batch-sleep-duration: "0s" + +zkevm.data-stream-host: "localhost" +zkevm.data-stream-port: 6900 +zkevm.default-gas-price: 1000000000 +zkevm.max-gas-price: 0 +zkevm.gas-price-factor: 0.000001 +zkevm.allow-free-transactions: true +zkevm.allow-internal-transactions: true +externalcl: true +http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] +http.addr: 0.0.0.0 +http.port: 8545 +http.vhosts: any +http.corsdomain: any +http.timeouts.read: "10s" +http.timeouts.write: "10s" +http.timeouts.idle: "10s" +http.methodratelimit: "{\"methods\":[\"eth_syncing\"],\"count\":10,\"bucket\":1}" +# http.apikeys: | +# {"project":"Biconomy","key":"45543e0adc5dd3e316044909d32501a5","timeout":"2030-12-31","methods":["eth_syncing"],"count":10000,"bucket":1} + +ws: true + +zkevm.apollo-enabled: false +zkevm.apollo-ip-addr: "" +zkevm.apollo-app-id: "" +zkevm.apollo-namespace-name: "" + +zkevm.nacos-urls: "" +zkevm.nacos-namespace-id: "" +zkevm.nacos-application-name: "" +zkevm.nacos-external-listen-addr: "" + +metrics: true +metrics.addr: "0.0.0.0" +metrics.port: 9095 + +db.read.concurrency: 20000 +txpool.globalslots: 100000 +networkid: 195 + +zkevm.pool-manager-url: http://xlayer-pool-manager:8545 + +http.methodratelimit: "{\"methods\":[\"eth_syncing\"],\"count\":10,\"bucket\":1}" +#http.apikeys: | +# {"project":"project1","key":"944cd2a6939eb23053289d9b91d6c498","timeout":"2033-12-12","methods":["eth_syncing"],"count":5,"bucket":1} + +pprof: true +pprof.port: 6060 +pprof.addr: 0.0.0.0 + +zkevm.standalone-smt-db: true # true: enalbe split smt db, false: not split \ No newline at end of file diff --git a/test-pp-op/config/test.erigon.seq.config.yaml b/test-pp-op/config/test.erigon.seq.config.yaml new file mode 100644 index 0000000000000..44c8a3a7a6fe1 --- /dev/null +++ b/test-pp-op/config/test.erigon.seq.config.yaml @@ -0,0 +1,114 @@ +datadir: /home/erigon/data/ +chain: dynamic-mynetwork +http: true +private.api.addr: localhost:9091 +zkevm.l2-chain-id: 195 +zkevm.l2-sequencer-rpc-url: +zkevm.l2-datastreamer-url: +zkevm.l1-chain-id: 1337 +zkevm.l1-rpc-url: http://l1-geth:8545 +zkevm.l1-highest-block-type: latest + +zkevm.address-sequencer: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" +zkevm.address-zkevm: "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" +zkevm.address-admin: "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" +zkevm.address-rollup: "0xE96dBF374555C6993618906629988d39184716B3" +zkevm.address-ger-manager: "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" + +zkevm.l1-rollup-id: 1 +zkevm.l1-first-block: 91 +zkevm.l1-block-range: 10 +zkevm.l1-query-delay: 6000 +zkevm.rpc-ratelimit: 0 +zkevm.datastream-version: 2 + +log.console.verbosity: info + +#zkevm.executor-urls: xlayer-executor:50071 +# zkevm.executor-strict: false +# zkevm.witness-full: false +# zkevm.executor-mock: true + +zkevm.sequencer-block-seal-time: "1s" +zkevm.sequencer-max-block-seal-time: "3s" +zkevm.sequencer-batch-seal-time: "10s" +zkevm.sequencer-batch-sleep-duration: "0s" + +zkevm.data-stream-host: "localhost" +zkevm.data-stream-port: 6900 +zkevm.default-gas-price: 1000000000 +zkevm.max-gas-price: 0 +zkevm.gas-price-factor: 0.000001 +zkevm.allow-free-transactions: true + +externalcl: true +http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] +http.addr: 0.0.0.0 +http.port: 8545 +http.vhosts: any +http.corsdomain: any +http.timeouts.read: "10s" +http.timeouts.write: "10s" +http.timeouts.idle: "10s" +rpc.batch.concurrency: 2 +rpc.batch.limit: 20 +ws: true + +zkevm.apollo-enabled: false +zkevm.apollo-ip-addr: "" +zkevm.apollo-app-id: "" +zkevm.apollo-namespace-name: "" + +zkevm.nacos-urls: "" +zkevm.nacos-namespace-id: "" +zkevm.nacos-application-name: "" +zkevm.nacos-external-listen-addr: "" + +metrics: true +metrics.addr: "0.0.0.0" +metrics.port: 9095 + +db.read.concurrency: 20000 +txpool.globalslots: 1000000 +txpool.globalbasefeeslots: 1000000 +txpool.globalqueue: 1000000 +txpool.packbatchspeciallist : ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534"] +txpool.gaspricemultiple : 2 +txpool.blockedlist: ["0xdD2FD4581271e230360230F9337D5c0430Bf44C0"] +txpool.enablefreegasbynonce : true +txpool.freegascountperaddr : 100 +txpool.commit.every: "10m" + +gpo.type: "follower" +gpo.update-period: "3s" +gpo.factor: 0.01 +gpo.kafka-url: "0.0.0.0" +gpo.topic: "explorer" +gpo.group-id: "web3" +gpo.blocks: 3 +gpo.default-l1-coin-price: 2000 +gpo.default-l2-coin-price: 50 +gpo.gas-price-usdt: 0.000000476190476 +gpo.congestion-threshold: 0 + +networkid: 195 + +pprof: true +pprof.port: 6060 +pprof.addr: 0.0.0.0 +txpool.enablefreegaslist : true +txpool.freegaslist : '[{"name":"e2e", "from_list":["0x586cbc95ed16031d9efdaebacf1c1d2bc3ccaa78"], "to_list":["0xad1d01007a56ee0a4ffd0488fb58fc6500cb1fbe"], "method_sigs":["a9059cbb"], "gas_price_multiple": 1}]' + +# close a block/batch immediately after the 1st zkCounter overflow TX +zkevm.seal-batch-immediately-on-overflow: true +zkevm.sequencer-timeout-on-empty-tx-pool: 5ms +zkevm.pre-run-address-list: [""] +zkevm.block-info-concurrent: true +zkevm.standalone-smt-db: true # true: enable split smt db, false: not split +zkevm.enable-async-commit: true + +# to reduce lock race in stress test +txpool.enabletimsort: true +zkevm.bulk-add-txs: true +zkevm.enable-add-tx-notify: true +zkevm.initial-batch.config: /usr/src/app/first-batch-config.json \ No newline at end of file diff --git a/test-pp-op/config/test.genesis.config.json b/test-pp-op/config/test.genesis.config.json new file mode 100644 index 0000000000000..dca366627bfdc --- /dev/null +++ b/test-pp-op/config/test.genesis.config.json @@ -0,0 +1,109 @@ +{ + "L1Config": { + "chainId": 1337, + "polygonZkEVMAddress": "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd", + "polygonRollupManagerAddress": "0xE96dBF374555C6993618906629988d39184716B3", + "polTokenAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3", + "polygonZkEVMGlobalExitRootAddress": "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" + }, + "genesisBlockNumber": 91, + "rollupCreationBlockNumber": 100, + "rollupManagerCreationBlockNumber": 91, + "root": "0xef7bb96e820d4d8440f9bae6b1d58427c06e324ac9d5f7a5156438dd42e837c5", + "genesis": [ + { + "contractName": "TokenWrappedBridgeInitCode", + "balance": "0", + "nonce": "1", + "address": "0x750a9c3AB9334e28bdB05B121BDe530351733BC2", + "bytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806383c43a551461002d575b5f5ffd5b61003561004b565b604051610042919061006a565b60405180910390f35b60405180611ba00160405280611b6681526020016100b6611b66913981565b602081525f82518060208401525f5b818110156100965760208186018101516040868401015201610079565b505f604082850101526040601f19601f8301168401019150509291505056fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220e2e0b7899260251baf2cfa7cf6126f1d0a5731b4f1051ae5b437d90ddbc6867164736f6c634300081c0033" + }, + { + "contractName": "PolygonZkEVMDeployer", + "balance": "0", + "nonce": "4", + "address": "0x18c279c3Ed0b54b9f9D815cD12bee2d2d68a4B42", + "bytecode": "0x60806040526004361061006e575f3560e01c8063715018a61161004c578063715018a6146100e25780638da5cb5b146100f6578063e11ae6cb1461011f578063f2fde38b14610132575f80fd5b80632b79805a146100725780634a94d487146100875780636d07dbf81461009a575b5f80fd5b610085610080366004610908565b610151565b005b6100856100953660046109a2565b6101c2565b3480156100a5575f80fd5b506100b96100b43660046109f5565b610203565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ed575f80fd5b50610085610215565b348015610101575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff166100b9565b61008561012d366004610a15565b610228565b34801561013d575f80fd5b5061008561014c366004610a61565b61028e565b61015961034a565b5f6101658585856103ca565b90506101718183610527565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101ca61034a565b6101d583838361056a565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b905f90a1505050565b5f61020e8383610598565b9392505050565b61021d61034a565b6102265f6105a4565b565b61023061034a565b5f61023c8484846103ca565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b61029661034a565b73ffffffffffffffffffffffffffffffffffffffff811661033e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610347816105a4565b50565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610335565b5f83471015610435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610335565b81515f0361049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610335565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff811661020e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610335565b606061020e83835f6040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610618565b6060610590848484604051806060016040528060298152602001610b0860299139610618565b949350505050565b5f61020e83833061072d565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610335565b5f808673ffffffffffffffffffffffffffffffffffffffff1685876040516106d29190610a9c565b5f6040518083038185875af1925050503d805f811461070c576040519150601f19603f3d011682016040523d82523d5f602084013e610711565b606091505b509150915061072287838387610756565b979650505050505050565b5f604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156107eb5782515f036107e45773ffffffffffffffffffffffffffffffffffffffff85163b6107e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610335565b5081610590565b61059083838151156108005781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103359190610ab7565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112610870575f80fd5b813567ffffffffffffffff8082111561088b5761088b610834565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108d1576108d1610834565b816040528381528660208588010111156108e9575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f805f806080858703121561091b575f80fd5b8435935060208501359250604085013567ffffffffffffffff80821115610940575f80fd5b61094c88838901610861565b93506060870135915080821115610961575f80fd5b5061096e87828801610861565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff8116811461099d575f80fd5b919050565b5f805f606084860312156109b4575f80fd5b6109bd8461097a565b9250602084013567ffffffffffffffff8111156109d8575f80fd5b6109e486828701610861565b925050604084013590509250925092565b5f8060408385031215610a06575f80fd5b50508035926020909101359150565b5f805f60608486031215610a27575f80fd5b8335925060208401359150604084013567ffffffffffffffff811115610a4b575f80fd5b610a5786828701610861565b9150509250925092565b5f60208284031215610a71575f80fd5b61020e8261097a565b5f5b83811015610a94578181015183820152602001610a7c565b50505f910152565b5f8251610aad818460208701610a7a565b9190910192915050565b602081525f8251806020840152610ad5816040850160208701610a7a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220330b94dc698c4d290bf55c23f13b473cde6a6bae0030cb902de18af54e35839f64736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008f8e2d6cf621f30e9a11309d6a56a876281fd534" + } + }, + { + "contractName": "ProxyAdmin", + "balance": "0", + "nonce": "1", + "address": "0x5DE1783073a44e3bdE977689a768b9cFA1ac58E7", + "bytecode": "0x608060405260043610610079575f3560e01c80639623609d1161004c5780639623609d1461012357806399a88ec414610136578063f2fde38b14610155578063f3b7dead14610174575f5ffd5b8063204e1c7a1461007d578063715018a6146100c55780637eff275e146100db5780638da5cb5b146100fa575b5f5ffd5b348015610088575f5ffd5b5061009c6100973660046105e8565b610193565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d0575f5ffd5b506100d9610244565b005b3480156100e6575f5ffd5b506100d96100f536600461060a565b610257565b348015610105575f5ffd5b505f5473ffffffffffffffffffffffffffffffffffffffff1661009c565b6100d961013136600461066e565b6102e0565b348015610141575f5ffd5b506100d961015036600461060a565b610371565b348015610160575f5ffd5b506100d961016f3660046105e8565b6103cd565b34801561017f575f5ffd5b5061009c61018e3660046105e8565b610489565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b5f60405180830381855afa9150503d805f8114610215576040519150601f19603f3d011682016040523d82523d5f602084013e61021a565b606091505b509150915081610228575f5ffd5b8080602001905181019061023c9190610782565b949350505050565b61024c6104d3565b6102555f610553565b565b61025f6104d3565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b5f604051808303815f87803b1580156102c6575f5ffd5b505af11580156102d8573d5f5f3e3d5ffd5b505050505050565b6102e86104d3565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061033e908690869060040161079d565b5f604051808303818588803b158015610355575f5ffd5b505af1158015610367573d5f5f3e3d5ffd5b5050505050505050565b6103796104d3565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102af565b6103d56104d3565b73ffffffffffffffffffffffffffffffffffffffff811661047d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61048681610553565b50565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610474565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610486575f5ffd5b5f602082840312156105f8575f5ffd5b8135610603816105c7565b9392505050565b5f5f6040838503121561061b575f5ffd5b8235610626816105c7565b91506020830135610636816105c7565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f5f60608486031215610680575f5ffd5b833561068b816105c7565b9250602084013561069b816105c7565b9150604084013567ffffffffffffffff8111156106b6575f5ffd5b8401601f810186136106c6575f5ffd5b803567ffffffffffffffff8111156106e0576106e0610641565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff8211171561074c5761074c610641565b604052818152828201602001881015610763575f5ffd5b816020840160208301375f602083830101528093505050509250925092565b5f60208284031215610792575f5ffd5b8151610603816105c7565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f82518060408401525f5b818110156107e557602081860181015160608684010152016107c8565b505f6060828501015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116840101915050939250505056fea2646970667358221220e111b2ba242ce4421950dc7ff545a01914c776103ce1cd642024c628867ecbf064736f6c634300081c0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000027284dba79e6df953fbd232a9d8d87029f03bbf5" + } + }, + { + "contractName": "PolygonZkEVMBridgeV2 implementation", + "balance": "0", + "nonce": "2", + "address": "0xa5a941061eF748466b31002415d6dCAe831b015A", + "bytecode": "0x60806040526004361061020f575f3560e01c806383c43a5511610117578063cc461632116100ac578063dbc169761161007c578063f5efcd7911610062578063f5efcd7914610683578063f811bff7146106a2578063fb570834146106c1575f5ffd5b8063dbc1697614610644578063ee25560b14610658575f5ffd5b8063cc461632146105cb578063ccaa2d11146105ea578063cd58657914610609578063d02103ca1461061c575f5ffd5b8063b8b284d0116100e7578063b8b284d014610549578063bab161bf14610568578063be5831c714610589578063c00f14ab146105ac575f5ffd5b806383c43a55146104d857806383f24403146104ec5780638ed7e3f21461050b578063aaa13cc21461052a575f5ffd5b80633c351e10116101a75780635ca1e165116101775780637843298b1161015d5780637843298b1461047157806379e2cf971461049057806381b1c174146104a4575f5ffd5b80635ca1e1651461041557806365d6f65414610429575f5ffd5b80633c351e10146103805780633cbc795b1461039f5780633e197043146103d75780634b2f336d146103f6575f5ffd5b806327aef4e8116101e257806327aef4e8146102a15780632dfdf0b5146102c2578063318aee3d146102e5578063381fef6d1461034d575f5ffd5b806315064c96146102135780632072f6c51461024157806322e95f2c14610257578063240ff3781461028e575b5f5ffd5b34801561021e575f5ffd5b5060685461022c9060ff1681565b60405190151581526020015b60405180910390f35b34801561024c575f5ffd5b506102556106e0565b005b348015610262575f5ffd5b50610276610271366004612ea6565b610715565b6040516001600160a01b039091168152602001610238565b61025561029c366004612f2d565b61077f565b3480156102ac575f5ffd5b506102b5610808565b6040516102389190612fef565b3480156102cd575f5ffd5b506102d760535481565b604051908152602001610238565b3480156102f0575f5ffd5b506103296102ff366004613001565b606b6020525f908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b03909116602083015201610238565b348015610358575f5ffd5b506102767f000000000000000000000000750a9c3ab9334e28bdb05b121bde530351733bc281565b34801561038b575f5ffd5b50606d54610276906001600160a01b031681565b3480156103aa575f5ffd5b50606d546103c290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610238565b3480156103e2575f5ffd5b506102d76103f136600461302a565b610894565b348015610401575f5ffd5b50606f54610276906001600160a01b031681565b348015610420575f5ffd5b506102d761093d565b348015610434575f5ffd5b506102b56040518060400160405280600981526020017f616c2d76302e332e30000000000000000000000000000000000000000000000081525081565b34801561047c575f5ffd5b5061027661048b3660046130a4565b6109bc565b34801561049b575f5ffd5b506102556109e7565b3480156104af575f5ffd5b506102766104be3660046130ea565b606a6020525f90815260409020546001600160a01b031681565b3480156104e3575f5ffd5b506102b5610a08565b3480156104f7575f5ffd5b506102d7610506366004613112565b610a91565b348015610516575f5ffd5b50606c54610276906001600160a01b031681565b348015610535575f5ffd5b50610276610544366004613213565b610b1e565b348015610554575f5ffd5b506102556105633660046132ae565b610c49565b348015610573575f5ffd5b506068546103c290610100900463ffffffff1681565b348015610594575f5ffd5b506068546103c290600160c81b900463ffffffff1681565b3480156105b7575f5ffd5b506102b56105c6366004613001565b610ce0565b3480156105d6575f5ffd5b5061022c6105e536600461332c565b610d25565b3480156105f5575f5ffd5b5061025561060436600461335d565b610dad565b61025561061736600461343c565b611203565b348015610627575f5ffd5b50606854610276906501000000000090046001600160a01b031681565b34801561064f575f5ffd5b506102556115d2565b348015610663575f5ffd5b506102d76106723660046130ea565b60696020525f908152604090205481565b34801561068e575f5ffd5b5061025561069d36600461335d565b611605565b3480156106ad575f5ffd5b506102556106bc3660046134cc565b61187e565b3480156106cc575f5ffd5b5061022c6106db36600461356f565b611b99565b606c546001600160a01b0316331461070b57604051631736745960e31b815260040160405180910390fd5b610713611bb2565b565b6040805160e084901b6001600160e01b031916602080830191909152606084901b6bffffffffffffffffffffffff1916602483015282516018818403018152603890920183528151918101919091205f908152606a90915220546001600160a01b03165b92915050565b60685460ff16156107a357604051630bc011ff60e21b815260040160405180910390fd5b34158015906107bc5750606f546001600160a01b031615155b156107f3576040517f6f625c4000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610801858534868686611c0d565b5050505050565b606e8054610815906135b4565b80601f0160208091040260200160405190810160405280929190818152602001828054610841906135b4565b801561088c5780601f106108635761010080835404028352916020019161088c565b820191905f5260205f20905b81548152906001019060200180831161086f57829003601f168201915b505050505081565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201526001600160e01b031960e088811b821660218401526bffffffffffffffffffffffff19606089811b821660258601529188901b909216603984015285901b16603d82015260518101839052607181018290525f90609101604051602081830303815290604052805190602001209050979650505050505050565b6053545f90819081805b60208110156109b3578083901c60011660010361098c5761098560338260208110610974576109746135ec565b0154855f9182526020526040902090565b935061099c565b5f84815260208390526040902093505b5f8281526020839052604090209150600101610947565b50919392505050565b5f6109dd84846109cb85611ce9565b6109d486611dd3565b61054487611eb4565b90505b9392505050565b605354606854600160c81b900463ffffffff16101561071357610713611f81565b60607f000000000000000000000000750a9c3ab9334e28bdb05b121bde530351733bc26001600160a01b03166383c43a556040518163ffffffff1660e01b81526004015f60405180830381865afa158015610a65573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610a8c919081019061362e565b905090565b5f83815b6020811015610b1557600163ffffffff8516821c81169003610ae157610ada858260208110610ac657610ac66135ec565b6020020135835f9182526020526040902090565b9150610b0d565b610b0a82868360208110610af757610af76135ec565b60200201355f9182526020526040902090565b91505b600101610a95565b50949350505050565b6040516001600160e01b031960e087901b1660208201526bffffffffffffffffffffffff19606086901b1660248201525f9081906038016040516020818303038152906040528051906020012090505f60ff60f81b3083610b7d610a08565b898989604051602001610b9293929190613673565b60408051601f1981840301815290829052610bb092916020016136ab565b60405160208183030381529060405280519060200120604051602001610c2594939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012098975050505050505050565b60685460ff1615610c6d57604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610caf576040517fdde3cda700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f545f90610cc7906001600160a01b03168661202f565b9050610cd7878783878787611c0d565b50505050505050565b6060610ceb82611ce9565b610cf483611dd3565b610cfd84611eb4565b604051602001610d0f93929190613673565b6040516020818303038152906040529050919050565b6068545f908190610100900463ffffffff16158015610d4a575063ffffffff83166001145b15610d5c575063ffffffff8316610d84565b610d7164010000000063ffffffff85166136ed565b610d819063ffffffff8616613704565b90505b600881901c5f90815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610dd157604051630bc011ff60e21b815260040160405180910390fd5b610dd96120ac565b60685463ffffffff8681166101009092041614610e09576040516302caf51760e11b815260040160405180910390fd5b610e348c8c8c8c8c5f8d8d8d8d8d8d8d604051610e27929190613717565b6040518091039020612105565b6001600160a01b038616158015610e4f575063ffffffff8716155b15610f4657606f546001600160a01b0316610f2a575f6001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015610e9c576020820181803683370190505b50604051610eaa9190613726565b5f6040518083038185875af1925050503d805f8114610ee4576040519150601f19603f3d011682016040523d82523d5f602084013e610ee9565b606091505b5050905080610f24576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611190565b606f54610f41906001600160a01b03168585612121565b611190565b606d546001600160a01b038781169116148015610f745750606d5463ffffffff888116600160a01b90920416145b15610f8b575f6001600160a01b0385168482610e72565b60685463ffffffff610100909104811690881603610fb757610f416001600160a01b0387168585612193565b6040516001600160e01b031960e089901b1660208201526bffffffffffffffffffffffff19606088901b1660248201525f9060380160408051601f1981840301815291815281516020928301205f818152606a9093529120549091506001600160a01b031680611182575f6110618386868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061221492505050565b905061106e818888612121565b80606a5f8581526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b5f836001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548163ffffffff021916908363ffffffff1602179055506020820151815f0160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a838888604051611174959493929190613769565b60405180910390a15061118d565b61118d818787612121565b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a16111f560018055565b505050505050505050505050565b60685460ff161561122757604051630bc011ff60e21b815260040160405180910390fd5b61122f6120ac565b60685463ffffffff610100909104811690881603611260576040516302caf51760e11b815260040160405180910390fd5b5f806060876001600160a01b03881661135c578834146112ac576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff169450906112d9906135b4565b80601f0160208091040260200160405190810160405280929190818152602001828054611305906135b4565b80156113505780601f1061132757610100808354040283529160200191611350565b820191905f5260205f20905b81548152906001019060200180831161133357829003601f168201915b5050505050915061155a565b3415611394576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84156113a6576113a6888a8888612299565b606f546001600160a01b03908116908916036113cd576113c6888a61202f565b905061155a565b6001600160a01b038089165f908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901515806114205750805163ffffffff1615155b156114425761142f898b61202f565b602082015182519096509450915061154d565b6040516370a0823160e01b81523060048201525f906001600160a01b038b16906370a0823190602401602060405180830381865afa158015611486573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114aa91906137a6565b90506114c16001600160a01b038b1633308e6125ff565b6040516370a0823160e01b81523060048201525f906001600160a01b038c16906370a0823190602401602060405180830381865afa158015611505573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061152991906137a6565b905061153582826137bd565b6068548c9850610100900463ffffffff169650935050505b61155689610ce0565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b5f84868e8e86886053546040516115999897969594939291906137d0565b60405180910390a16115b75f84868e8e868880519060200120612650565b86156115c5576115c5611f81565b50505050610cd760018055565b606c546001600160a01b031633146115fd57604051631736745960e31b815260040160405180910390fd5b610713612667565b60685460ff161561162957604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614611659576040516302caf51760e11b815260040160405180910390fd5b6116788c8c8c8c8c60018d8d8d8d8d8d8d604051610e27929190613717565b606f545f906001600160a01b031661172b57846001600160a01b031684888a86866040516024016116ac9493929190613844565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b179052516116e19190613726565b5f6040518083038185875af1925050503d805f811461171b576040519150601f19603f3d011682016040523d82523d5f602084013e611720565b606091505b5050809150506117dc565b606f54611742906001600160a01b03168686612121565b846001600160a01b0316878985856040516024016117639493929190613844565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b179052516117989190613726565b5f604051808303815f865af19150503d805f81146117d1576040519150601f19603f3d011682016040523d82523d5f602084013e6117d6565b606091505b50909150505b80611813576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b5f54610100900460ff161580801561189c57505f54600160ff909116105b806118b55750303b1580156118b557505f5460ff166001145b61192c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b5f805460ff19166001179055801561194d575f805461ff0019166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8a16027fffffffffffffff0000000000000000000000000000000000000000ffffffffff1617650100000000006001600160a01b038781169190910291909117909155606c805473ffffffffffffffffffffffffffffffffffffffff19168583161790558616611a285763ffffffff851615611a23576040517f1a874c1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b44565b606d805463ffffffff8716600160a01b027fffffffffffffffff0000000000000000000000000000000000000000000000009091166001600160a01b03891617179055606e611a7783826138c0565b50611b165f5f1b6012604051602001611b0291906060808252600d908201527f5772617070656420457468657200000000000000000000000000000000000000608082015260a0602082018190526004908201527f574554480000000000000000000000000000000000000000000000000000000060c082015260ff91909116604082015260e00190565b604051602081830303815290604052612214565b606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03929092169190911790555b611b4c6126d7565b8015610cd7575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b5f81611ba6868686610a91565b1490505b949350505050565b60685460ff1615611bd657604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497905f90a1565b60685463ffffffff610100909104811690871603611c3e576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611c929998979695949392919061397b565b60405180910390a1611cd36001606860019054906101000a900463ffffffff16338989898888604051611cc6929190613717565b6040518091039020612650565b8215611ce157611ce1611f81565b505050505050565b60408051600481526024810182526020810180516001600160e01b03167f06fdde030000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611d489190613726565b5f60405180830381855afa9150503d805f8114611d80576040519150601f19603f3d011682016040523d82523d5f602084013e611d85565b606091505b509150915081611dca576040518060400160405280600781526020017f4e4f5f4e414d4500000000000000000000000000000000000000000000000000815250611baa565b611baa81612749565b60408051600481526024810182526020810180516001600160e01b03167f95d89b410000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611e329190613726565b5f60405180830381855afa9150503d805f8114611e6a576040519150601f19603f3d011682016040523d82523d5f602084013e611e6f565b606091505b509150915081611dca576040518060400160405280600981526020017f4e4f5f53594d424f4c0000000000000000000000000000000000000000000000815250611baa565b60408051600481526024810182526020810180516001600160e01b03167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f91829182916001600160a01b03861691611f129190613726565b5f60405180830381855afa9150503d805f8114611f4a576040519150601f19603f3d011682016040523d82523d5f602084013e611f4f565b606091505b5091509150818015611f62575080516020145b611f6d576012611baa565b80806020019051810190611baa91906139f1565b6053546068805463ffffffff909216600160c81b027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117908190556001600160a01b0365010000000000909104166333d6247d611fe261093d565b6040518263ffffffff1660e01b815260040161200091815260200190565b5f604051808303815f87803b158015612017575f5ffd5b505af1158015612029573d5f5f3e3d5ffd5b50505050565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018290525f906001600160a01b03841690639dc29fac906044015f604051808303815f87803b15801561208f575f5ffd5b505af11580156120a1573d5f5f3e3d5ffd5b509395945050505050565b6002600154036120fe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611923565b6002600155565b6111f58c8c8c8c8c61211c8d8d8d8d8d8d8d610894565b61290f565b6040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390528416906340c10f19906044015f604051808303815f87803b158015612181575f5ffd5b505af1158015610cd7573d5f5f3e3d5ffd5b6040516001600160a01b03831660248201526044810182905261220f9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a79565b505050565b5f5f61221e610a08565b836040516020016122309291906136ab565b6040516020818303038152906040529050838151602083015ff591506001600160a01b03821661228c576040517fbefb092000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5092915050565b60018055565b5f6122a76004828486613a0c565b6122b091613a33565b90507f2afa5331000000000000000000000000000000000000000000000000000000006001600160e01b0319821601612451575f8080808080806122f7896004818d613a0c565b8101906123049190613a68565b9650965096509650965096509650336001600160a01b0316876001600160a01b0316146123445760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038616301461236d5760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b03167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e16916124049190613726565b5f604051808303815f865af19150503d805f811461243d576040519150601f19603f3d011682016040523d82523d5f602084013e612442565b606091505b50505050505050505050610801565b6001600160e01b031981166323f2ebc360e21b1461249b576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f808080808080806124b08a6004818e613a0c565b8101906124bd9190613ab7565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146124ff5760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03871630146125285760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f16916125af9190613726565b5f604051808303815f865af19150503d805f81146125e8576040519150601f19603f3d011682016040523d82523d5f602084013e6125ed565b606091505b50505050505050505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526120299085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016121d8565b610cd761266288888888888888610894565b612b5d565b60685460ff166126a3576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3905f90a1565b5f54610100900460ff166127415760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611923565b610713612c35565b606060408251106127685781806020019051810190610779919061362e565b81516020036128d1575f5b6020811080156127ba5750828181518110612790576127906135ec565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b156127d157806127c981613b35565b915050612773565b805f0361281357505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b5f8167ffffffffffffffff81111561282d5761282d61314e565b6040519080825280601f01601f191660200182016040528015612857576020820181803683370190505b5090505f5b828110156128c957848181518110612876576128766135ec565b602001015160f81c60f81b828281518110612893576128936135ec565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060010161285c565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b6068545f906501000000000090046001600160a01b031663257b363261293e86865f9182526020526040902090565b6040518263ffffffff1660e01b815260040161295c91815260200190565b6020604051808303815f875af1158015612978573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061299c91906137a6565b9050805f036129d6576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8068010000000000000000871615612a1a578691506129f8848a8489611b99565b612a15576040516338105f3b60e21b815260040160405180910390fd5b612a64565b602087901c612a2a816001613b4d565b9150879250612a45612a3d868c86610a91565b8a8389611b99565b612a62576040516338105f3b60e21b815260040160405180910390fd5b505b612a6e8282612c9f565b505050505050505050565b5f612acd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612d5f9092919063ffffffff16565b80519091501561220f5780806020019051810190612aeb9190613b69565b61220f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611923565b806001612b6c60206002613c67565b612b7691906137bd565b60535410612bb0576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60535f8154612bbf90613b35565b918290555090505f5b6020811015612c2c578082901c600116600103612bfb578260338260208110612bf357612bf36135ec565b015550505050565b612c2260338260208110612c1157612c116135ec565b0154845f9182526020526040902090565b9250600101612bc8565b5061220f613c72565b5f54610100900460ff166122935760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611923565b6068545f90610100900463ffffffff16158015612cc2575063ffffffff82166001145b15612cd4575063ffffffff8216612cfc565b612ce964010000000063ffffffff84166136ed565b612cf99063ffffffff8516613704565b90505b600881901c5f8181526069602052604081208054600160ff861690811b91821892839055929091908183169003610cd7576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60606109dd84845f85855f5f866001600160a01b03168587604051612d849190613726565b5f6040518083038185875af1925050503d805f8114612dbe576040519150601f19603f3d011682016040523d82523d5f602084013e612dc3565b606091505b5091509150612dd487838387612ddf565b979650505050505050565b60608315612e4d5782515f03612e46576001600160a01b0385163b612e465760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611923565b5081611baa565b611baa8383815115612e625781518083602001fd5b8060405162461bcd60e51b81526004016119239190612fef565b803563ffffffff8116811461290a575f5ffd5b6001600160a01b0381168114612ea3575f5ffd5b50565b5f5f60408385031215612eb7575f5ffd5b612ec083612e7c565b91506020830135612ed081612e8f565b809150509250929050565b8015158114612ea3575f5ffd5b5f5f83601f840112612ef8575f5ffd5b50813567ffffffffffffffff811115612f0f575f5ffd5b602083019150836020828501011115612f26575f5ffd5b9250929050565b5f5f5f5f5f60808688031215612f41575f5ffd5b612f4a86612e7c565b94506020860135612f5a81612e8f565b93506040860135612f6a81612edb565b9250606086013567ffffffffffffffff811115612f85575f5ffd5b612f9188828901612ee8565b969995985093965092949392505050565b5f5b83811015612fbc578181015183820152602001612fa4565b50505f910152565b5f8151808452612fdb816020860160208601612fa2565b601f01601f19169290920160200192915050565b602081525f6109e06020830184612fc4565b5f60208284031215613011575f5ffd5b81356109e081612e8f565b60ff81168114612ea3575f5ffd5b5f5f5f5f5f5f5f60e0888a031215613040575f5ffd5b873561304b8161301c565b965061305960208901612e7c565b9550604088013561306981612e8f565b945061307760608901612e7c565b9350608088013561308781612e8f565b9699959850939692959460a0840135945060c09093013592915050565b5f5f5f606084860312156130b6575f5ffd5b6130bf84612e7c565b925060208401356130cf81612e8f565b915060408401356130df81612e8f565b809150509250925092565b5f602082840312156130fa575f5ffd5b5035919050565b806104008101831015610779575f5ffd5b5f5f5f6104408486031215613125575f5ffd5b833592506131368560208601613101565b91506131456104208501612e7c565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561318b5761318b61314e565b604052919050565b5f67ffffffffffffffff8211156131ac576131ac61314e565b50601f01601f191660200190565b5f6131cc6131c784613193565b613162565b90508281528383830111156131df575f5ffd5b828260208301375f602084830101529392505050565b5f82601f830112613204575f5ffd5b6109e0838335602085016131ba565b5f5f5f5f5f60a08688031215613227575f5ffd5b61323086612e7c565b9450602086013561324081612e8f565b9350604086013567ffffffffffffffff81111561325b575f5ffd5b613267888289016131f5565b935050606086013567ffffffffffffffff811115613283575f5ffd5b61328f888289016131f5565b92505060808601356132a08161301c565b809150509295509295909350565b5f5f5f5f5f5f60a087890312156132c3575f5ffd5b6132cc87612e7c565b955060208701356132dc81612e8f565b94506040870135935060608701356132f381612edb565b9250608087013567ffffffffffffffff81111561330e575f5ffd5b61331a89828a01612ee8565b979a9699509497509295939492505050565b5f5f6040838503121561333d575f5ffd5b61334683612e7c565b915061335460208401612e7c565b90509250929050565b5f5f5f5f5f5f5f5f5f5f5f5f6109208d8f031215613379575f5ffd5b6133838e8e613101565b9b506133938e6104008f01613101565b9a506108008d013599506108208d013598506108408d013597506133ba6108608e01612e7c565b96506133ca6108808e0135612e8f565b6108808d013595506133df6108a08e01612e7c565b94506108c08d01356133f081612e8f565b93506108e08d0135925067ffffffffffffffff6109008e01351115613413575f5ffd5b6134248e6109008f01358f01612ee8565b81935080925050509295989b509295989b509295989b565b5f5f5f5f5f5f5f60c0888a031215613452575f5ffd5b61345b88612e7c565b9650602088013561346b81612e8f565b955060408801359450606088013561348281612e8f565b9350608088013561349281612edb565b925060a088013567ffffffffffffffff8111156134ad575f5ffd5b6134b98a828b01612ee8565b989b979a50959850939692959293505050565b5f5f5f5f5f5f60c087890312156134e1575f5ffd5b6134ea87612e7c565b955060208701356134fa81612e8f565b945061350860408801612e7c565b9350606087013561351881612e8f565b9250608087013561352881612e8f565b915060a087013567ffffffffffffffff811115613543575f5ffd5b8701601f81018913613553575f5ffd5b613562898235602084016131ba565b9150509295509295509295565b5f5f5f5f6104608587031215613583575f5ffd5b843593506135948660208701613101565b92506135a36104208601612e7c565b939692955092936104400135925050565b600181811c908216806135c857607f821691505b6020821081036135e657634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b5f61360d6131c784613193565b9050828152838383011115613620575f5ffd5b6109e0836020830184612fa2565b5f6020828403121561363e575f5ffd5b815167ffffffffffffffff811115613654575f5ffd5b8201601f81018413613664575f5ffd5b611baa84825160208401613600565b606081525f6136856060830186612fc4565b82810360208401526136978186612fc4565b91505060ff83166040830152949350505050565b5f83516136bc818460208801612fa2565b8351908301906136d0818360208801612fa2565b01949350505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610779576107796136d9565b80820180821115610779576107796136d9565b818382375f9101908152919050565b5f8251613737818460208701612fa2565b9190910192915050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b63ffffffff861681526001600160a01b03851660208201526001600160a01b0384166040820152608060608201525f612dd4608083018486613741565b5f602082840312156137b6575f5ffd5b5051919050565b81810381811115610779576107796136d9565b60ff8916815263ffffffff881660208201526001600160a01b038716604082015263ffffffff861660608201526001600160a01b03851660808201528360a082015261010060c08201525f613829610100830185612fc4565b905063ffffffff831660e08301529998505050505050505050565b6001600160a01b038516815263ffffffff84166020820152606060408201525f613872606083018486613741565b9695505050505050565b601f82111561220f57805f5260205f20601f840160051c810160208510156138a15750805b601f840160051c820191505b81811015610801575f81556001016138ad565b815167ffffffffffffffff8111156138da576138da61314e565b6138ee816138e884546135b4565b8461387c565b6020601f821160018114613920575f83156139095750848201515b5f19600385901b1c1916600184901b178455610801565b5f84815260208120601f198516915b8281101561394f578785015182556020948501946001909201910161392f565b508482101561396c57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b60ff8a16815263ffffffff891660208201526001600160a01b038816604082015263ffffffff871660608201526001600160a01b03861660808201528460a082015261010060c08201525f6139d561010083018587613741565b905063ffffffff831660e08301529a9950505050505050505050565b5f60208284031215613a01575f5ffd5b81516109e08161301c565b5f5f85851115613a1a575f5ffd5b83861115613a26575f5ffd5b5050820193919092039150565b80356001600160e01b0319811690600484101561228c576001600160e01b0319808560040360031b1b82161691505092915050565b5f5f5f5f5f5f5f60e0888a031215613a7e575f5ffd5b8735613a8981612e8f565b96506020880135613a9981612e8f565b9550604088013594506060880135935060808801356130878161301c565b5f5f5f5f5f5f5f5f610100898b031215613acf575f5ffd5b8835613ada81612e8f565b97506020890135613aea81612e8f565b965060408901359550606089013594506080890135613b0881612edb565b935060a0890135613b188161301c565b979a969950949793969295929450505060c08201359160e0013590565b5f60018201613b4657613b466136d9565b5060010190565b63ffffffff8181168382160190811115610779576107796136d9565b5f60208284031215613b79575f5ffd5b81516109e081612edb565b6001815b6001841115613bbf57808504811115613ba357613ba36136d9565b6001841615613bb157908102905b60019390931c928002613b88565b935093915050565b5f82613bd557506001610779565b81613be157505f610779565b8160018114613bf75760028114613c0157613c1d565b6001915050610779565b60ff841115613c1257613c126136d9565b50506001821b610779565b5060208310610133831016604e8410600b8410161715613c40575081810a610779565b613c4c5f198484613b84565b805f1904821115613c5f57613c5f6136d9565b029392505050565b5f6109e08383613bc7565b634e487b7160e01b5f52600160045260245ffdfea2646970667358221220849aaee1cc1978fd76e0346e23e1c9651b52ff9e7089a5e63e964925adf544c264736f6c634300081c0033" + }, + { + "contractName": "PolygonZkEVMBridgeV2 proxy", + "balance": "340282366920938463463374607431768211455", + "nonce": "1", + "address": "0x4B24266C13AFEf2bb60e2C69A4C08A482d81e3CA", + "bytecode": "0x60806040526004361061005d575f3560e01c80635c60da1b116100425780635c60da1b146100a65780638f283970146100e3578063f851a440146101025761006c565b80633659cfe6146100745780634f1ef286146100935761006c565b3661006c5761006a610116565b005b61006a610116565b34801561007f575f5ffd5b5061006a61008e366004610854565b610130565b61006a6100a136600461086d565b610178565b3480156100b1575f5ffd5b506100ba6101eb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee575f5ffd5b5061006a6100fd366004610854565b610228565b34801561010d575f5ffd5b506100ba610255565b61011e610282565b61012e610129610359565b610362565b565b610138610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d8160405180602001604052805f8152505f6103bf565b50565b61016d610116565b610180610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101e3576101de8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250600192506103bf915050565b505050565b6101de610116565b5f6101f4610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610359565b905090565b610225610116565b90565b610230610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d816103e9565b5f61025e610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610380565b61028a610380565b73ffffffffffffffffffffffffffffffffffffffff16330361012e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b5f61021861044a565b365f5f375f5f365f845af43d5f5f3e80801561037c573d5ff35b3d5ffd5b5f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103c883610471565b5f825111806103d45750805b156101de576103e383836104bd565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610412610380565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161016d816104e9565b5f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103a3565b61047a816105f5565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606104e28383604051806060016040528060278152602001610979602791396106c0565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811661058c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610350565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610350565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105af565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff16856040516106e9919061090d565b5f60405180830381855af49150503d805f8114610721576040519150601f19603f3d011682016040523d82523d5f602084013e610726565b606091505b509150915061073786838387610741565b9695505050505050565b606083156107d65782515f036107cf5773ffffffffffffffffffffffffffffffffffffffff85163b6107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610350565b50816107e0565b6107e083836107e8565b949350505050565b8151156107f85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103509190610928565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f575f5ffd5b919050565b5f60208284031215610864575f5ffd5b6104e28261082c565b5f5f5f6040848603121561087f575f5ffd5b6108888461082c565b9250602084013567ffffffffffffffff8111156108a3575f5ffd5b8401601f810186136108b3575f5ffd5b803567ffffffffffffffff8111156108c9575f5ffd5b8660208284010111156108da575f5ffd5b939660209190910195509293505050565b5f5b838110156109055781810151838201526020016108ed565b50505f910152565b5f825161091e8184602087016108eb565b9190910192915050565b602081525f82518060208401526109468160408501602087016108eb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b4314c6ef866fe81c59eeee5f2b9032aaf3dc70c6d4ab82137af7b26a764741664736f6c634300081c0033", + "storage": { + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x0000000000000000000000005de1783073a44e3bde977689a768b9cfa1ac58e7", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000a5a941061ef748466b31002415d6dcae831b015a" + } + }, + { + "contractName": "PolygonZkEVMGlobalExitRootL2 implementation", + "balance": "0", + "nonce": "1", + "address": "0x21BD2401BA404841c7feC1816F5a0AaAdbc486eF", + "bytecode": "0x608060405234801561000f575f5ffd5b506004361061004a575f3560e01c806301fd90441461004e578063257b36321461006a57806333d6247d14610089578063a3c573eb1461009e575b5f5ffd5b61005760015481565b6040519081526020015b60405180910390f35b61005761007836600461015e565b5f6020819052908152604090205481565b61009c61009736600461015e565b6100ea565b005b6100c57f0000000000000000000000004b24266c13afef2bb60e2c69a4c08a482d81e3ca81565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610061565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004b24266c13afef2bb60e2c69a4c08a482d81e3ca1614610159576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b5f6020828403121561016e575f5ffd5b503591905056fea26469706673582212208915b6fcaffb67739719d531325bac93ba2790d8aec6a382f704b8d2db9769f964736f6c634300081c0033" + }, + { + "contractName": "PolygonZkEVMGlobalExitRootL2 proxy", + "balance": "0", + "nonce": "1", + "address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa", + "bytecode": "0x60806040523661001357610011610017565b005b6100115b61001f6101b7565b6001600160a01b0316336001600160a01b0316141561016f5760606001600160e01b031960003516631b2ce7f360e11b8114156100655761005e6101ea565b9150610167565b6001600160e01b0319811663278f794360e11b14156100865761005e610241565b6001600160e01b031981166308f2839760e41b14156100a75761005e610287565b6001600160e01b031981166303e1469160e61b14156100c85761005e6102b8565b6001600160e01b03198116635c60da1b60e01b14156100e95761005e6102f8565b60405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b815160208301f35b61017761030c565b565b606061019e83836040518060600160405280602781526020016108576027913961031c565b9392505050565b90565b6001600160a01b03163b151590565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b60606101f4610394565b600061020336600481846106a2565b81019061021091906106e8565b905061022d8160405180602001604052806000815250600061039f565b505060408051602081019091526000815290565b606060008061025336600481846106a2565b8101906102609190610719565b915091506102708282600161039f565b604051806020016040528060008152509250505090565b6060610291610394565b60006102a036600481846106a2565b8101906102ad91906106e8565b905061022d816103cb565b60606102c2610394565b60006102cc6101b7565b604080516001600160a01b03831660208201529192500160405160208183030381529060405291505090565b6060610302610394565b60006102cc610422565b610177610317610422565b610431565b6060600080856001600160a01b0316856040516103399190610807565b600060405180830381855af49150503d8060008114610374576040519150601f19603f3d011682016040523d82523d6000602084013e610379565b606091505b509150915061038a86838387610455565b9695505050505050565b341561017757600080fd5b6103a8836104d3565b6000825111806103b55750805b156103c6576103c48383610179565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103f46101b7565b604080516001600160a01b03928316815291841660208301520160405180910390a161041f81610513565b50565b600061042c6105bc565b905090565b3660008037600080366000845af43d6000803e808015610450573d6000f35b3d6000fd5b606083156104c15782516104ba576001600160a01b0385163b6104ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161015e565b50816104cb565b6104cb83836105e4565b949350505050565b6104dc8161060e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105785760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6101db565b8151156105f45781518083602001fd5b8060405162461bcd60e51b815260040161015e9190610823565b6001600160a01b0381163b61067b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161015e565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61059b565b600080858511156106b257600080fd5b838611156106bf57600080fd5b5050820193919092039150565b80356001600160a01b03811681146106e357600080fd5b919050565b6000602082840312156106fa57600080fd5b61019e826106cc565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561072c57600080fd5b610735836106cc565b9150602083013567ffffffffffffffff8082111561075257600080fd5b818501915085601f83011261076657600080fd5b81358181111561077857610778610703565b604051601f8201601f19908116603f011681019083821181831017156107a0576107a0610703565b816040528281528860208487010111156107b957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b838110156107f65781810151838201526020016107de565b838111156103c45750506000910152565b600082516108198184602087016107db565b9190910192915050565b60208152600082518060208401526108428160408501602087016107db565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122012bb4f564f73959a03513dc74fc3c6e40e8386e6f02c16b78d6db00ce0aa16af64736f6c63430008090033", + "storage": { + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x0000000000000000000000005de1783073a44e3bde977689a768b9cfa1ac58e7", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000021bd2401ba404841c7fec1816f5a0aaadbc486ef" + } + }, + { + "contractName": "PolygonZkEVMTimelock", + "balance": "0", + "nonce": "1", + "address": "0x27284DBa79e6DF953Fbd232A9d8D87029F03BBf5", + "bytecode": "0x6080604052600436106101bd575f3560e01c806364d62353116100f2578063b1c5f42711610092578063d547741f11610062578063d547741f1461063a578063e38335e514610659578063f23a6e611461066c578063f27a0c92146106b0575f80fd5b8063b1c5f4271461058d578063bc197c81146105ac578063c4d252f5146105f0578063d45c44351461060f575f80fd5b80638f61f4f5116100cd5780638f61f4f5146104c557806391d14854146104f8578063a217fddf14610547578063b08e51c01461055a575f80fd5b806364d62353146104685780638065657f146104875780638f2a0bb0146104a6575f80fd5b8063248a9ca31161015d57806331d507501161013857806331d50750146103b357806336568abe146103d25780633a6aae72146103f1578063584b153e14610449575f80fd5b8063248a9ca3146103375780632ab0f529146103655780632f2ff15d14610394575f80fd5b80630d3cf6fc116101985780630d3cf6fc1461025e578063134008d31461029157806313bc9f20146102a4578063150b7a02146102c3575f80fd5b806301d5062a146101c857806301ffc9a7146101e957806307bd02651461021d575f80fd5b366101c457005b5f80fd5b3480156101d3575f80fd5b506101e76101e2366004611bf6565b6106c4565b005b3480156101f4575f80fd5b50610208610203366004611c65565b610757565b60405190151581526020015b60405180910390f35b348015610228575f80fd5b506102507fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610214565b348015610269575f80fd5b506102507f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101e761029f366004611ca4565b6107b2565b3480156102af575f80fd5b506102086102be366004611d0b565b6108a7565b3480156102ce575f80fd5b506103066102dd366004611e28565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610214565b348015610342575f80fd5b50610250610351366004611d0b565b5f9081526020819052604090206001015490565b348015610370575f80fd5b5061020861037f366004611d0b565b5f908152600160208190526040909120541490565b34801561039f575f80fd5b506101e76103ae366004611e8c565b6108cc565b3480156103be575f80fd5b506102086103cd366004611d0b565b6108f5565b3480156103dd575f80fd5b506101e76103ec366004611e8c565b61090d565b3480156103fc575f80fd5b506104247f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b348015610454575f80fd5b50610208610463366004611d0b565b6109c5565b348015610473575f80fd5b506101e7610482366004611d0b565b6109da565b348015610492575f80fd5b506102506104a1366004611ca4565b610aaa565b3480156104b1575f80fd5b506101e76104c0366004611ef7565b610ae8565b3480156104d0575f80fd5b506102507fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b348015610503575f80fd5b50610208610512366004611e8c565b5f9182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610552575f80fd5b506102505f81565b348015610565575f80fd5b506102507ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b348015610598575f80fd5b506102506105a7366004611fa0565b610d18565b3480156105b7575f80fd5b506103066105c63660046120be565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b3480156105fb575f80fd5b506101e761060a366004611d0b565b610d5c565b34801561061a575f80fd5b50610250610629366004611d0b565b5f9081526001602052604090205490565b348015610645575f80fd5b506101e7610654366004611e8c565b610e56565b6101e7610667366004611fa0565b610e7a565b348015610677575f80fd5b50610306610686366004612161565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106bb575f80fd5b50610250611121565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc16106ee81611200565b5f6106fd898989898989610aaa565b9050610709818461120d565b5f817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a60405161074496959493929190612208565b60405180910390a3505050505050505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107ac57506107ac82611359565b92915050565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661082e5761082e81336113ef565b5f61083d888888888888610aaa565b905061084981856114a6565b610855888888886115e2565b5f817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a60405161088c9493929190612252565b60405180910390a361089d816116e2565b5050505050505050565b5f818152600160205260408120546001811180156108c55750428111155b9392505050565b5f828152602081905260409020600101546108e681611200565b6108f0838361178a565b505050565b5f8181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109c18282611878565b5050565b5f818152600160208190526040822054610906565b333014610a69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109ae565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b5f868686868686604051602001610ac696959493929190612208565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b1281611200565b888714610ba1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b888514610c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f610c418b8b8b8b8b8b8b8b610d18565b9050610c4d818461120d565b5f5b8a811015610d0a5780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610c8c57610c8c612291565b9050602002016020810190610ca191906122be565b8d8d86818110610cb357610cb3612291565b905060200201358c8c87818110610ccc57610ccc612291565b9050602002810190610cde91906122d7565b8c8b604051610cf296959493929190612208565b60405180910390a3610d0381612365565b9050610c4f565b505050505050505050505050565b5f8888888888888888604051602001610d38989796959493929190612447565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610d8681611200565b610d8f826109c5565b610e1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109ae565b5f828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b5f82815260208190526040902060010154610e7081611200565b6108f08383611878565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610ef657610ef681336113ef565b878614610f85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b878414611014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f6110258a8a8a8a8a8a8a8a610d18565b905061103181856114a6565b5f5b8981101561110b575f8b8b8381811061104e5761104e612291565b905060200201602081019061106391906122be565b90505f8a8a8481811061107857611078612291565b905060200201359050365f8a8a8681811061109557611095612291565b90506020028101906110a791906122d7565b915091506110b7848484846115e2565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58868686866040516110ee9493929190612252565b60405180910390a3505050508061110490612365565b9050611033565b50611115816116e2565b50505050505050505050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16158015906111ef57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ef919061250c565b156111f957505f90565b5060025490565b61120a81336113ef565b50565b611216826108f5565b156112a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109ae565b6112ab611121565b81101561133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109ae565b611344814261252b565b5f928352600160205260409092209190915550565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107ac57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107ac565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c15761142c8161192d565b61143783602061194c565b604051602001611448929190612560565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109ae916004016125e0565b6114af826108a7565b61153b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b80158061155657505f81815260016020819052604090912054145b6109c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f8473ffffffffffffffffffffffffffffffffffffffff1684848460405161160b929190612630565b5f6040518083038185875af1925050503d805f8114611645576040519150601f19603f3d011682016040523d82523d5f602084013e61164a565b606091505b50509050806116db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109ae565b5050505050565b6116eb816108a7565b611777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b5f90815260016020819052604090912055565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561181a3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107ac73ffffffffffffffffffffffffffffffffffffffff831660145b60605f61195a83600261263f565b61196590600261252b565b67ffffffffffffffff81111561197d5761197d611d22565b6040519080825280601f01601f1916602001820160405280156119a7576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106119dd576119dd612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a3f57611a3f612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f611a7984600261263f565b611a8490600161252b565b90505b6001811115611b20577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611ac557611ac5612291565b1a60f81b828281518110611adb57611adb612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c93611b1981612656565b9050611a87565b5083156108c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109ae565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bac575f80fd5b919050565b5f8083601f840112611bc1575f80fd5b50813567ffffffffffffffff811115611bd8575f80fd5b602083019150836020828501011115611bef575f80fd5b9250929050565b5f805f805f805f60c0888a031215611c0c575f80fd5b611c1588611b89565b965060208801359550604088013567ffffffffffffffff811115611c37575f80fd5b611c438a828b01611bb1565b989b979a50986060810135976080820135975060a09091013595509350505050565b5f60208284031215611c75575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108c5575f80fd5b5f805f805f8060a08789031215611cb9575f80fd5b611cc287611b89565b955060208701359450604087013567ffffffffffffffff811115611ce4575f80fd5b611cf089828a01611bb1565b979a9699509760608101359660809091013595509350505050565b5f60208284031215611d1b575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d9657611d96611d22565b604052919050565b5f82601f830112611dad575f80fd5b813567ffffffffffffffff811115611dc757611dc7611d22565b611df860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d4f565b818152846020838601011115611e0c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611e3b575f80fd5b611e4485611b89565b9350611e5260208601611b89565b925060408501359150606085013567ffffffffffffffff811115611e74575f80fd5b611e8087828801611d9e565b91505092959194509250565b5f8060408385031215611e9d575f80fd5b82359150611ead60208401611b89565b90509250929050565b5f8083601f840112611ec6575f80fd5b50813567ffffffffffffffff811115611edd575f80fd5b6020830191508360208260051b8501011115611bef575f80fd5b5f805f805f805f805f60c08a8c031215611f0f575f80fd5b893567ffffffffffffffff80821115611f26575f80fd5b611f328d838e01611eb6565b909b50995060208c0135915080821115611f4a575f80fd5b611f568d838e01611eb6565b909950975060408c0135915080821115611f6e575f80fd5b50611f7b8c828d01611eb6565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b5f805f805f805f8060a0898b031215611fb7575f80fd5b883567ffffffffffffffff80821115611fce575f80fd5b611fda8c838d01611eb6565b909a50985060208b0135915080821115611ff2575f80fd5b611ffe8c838d01611eb6565b909850965060408b0135915080821115612016575f80fd5b506120238b828c01611eb6565b999c989b509699959896976060870135966080013595509350505050565b5f82601f830112612050575f80fd5b8135602067ffffffffffffffff82111561206c5761206c611d22565b8160051b61207b828201611d4f565b9283528481018201928281019087851115612094575f80fd5b83870192505b848310156120b35782358252918301919083019061209a565b979650505050505050565b5f805f805f60a086880312156120d2575f80fd5b6120db86611b89565b94506120e960208701611b89565b9350604086013567ffffffffffffffff80821115612105575f80fd5b61211189838a01612041565b94506060880135915080821115612126575f80fd5b61213289838a01612041565b93506080880135915080821115612147575f80fd5b5061215488828901611d9e565b9150509295509295909350565b5f805f805f60a08688031215612175575f80fd5b61217e86611b89565b945061218c60208701611b89565b93506040860135925060608601359150608086013567ffffffffffffffff8111156121b5575f80fd5b61215488828901611d9e565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a060408201525f61223d60a0830186886121c1565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201525f6122876060830184866121c1565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082840312156122ce575f80fd5b6108c582611b89565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261230a575f80fd5b83018035915067ffffffffffffffff821115612324575f80fd5b602001915036819003821315611bef575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361239557612395612338565b5060010190565b8183525f6020808501808196508560051b81019150845f5b8781101561243a57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126123f2575f80fd5b8701858101903567ffffffffffffffff81111561240d575f80fd5b80360382131561241b575f80fd5b6124268682846121c1565b9a87019a95505050908401906001016123b4565b5091979650505050505050565b60a080825281018890525f8960c08301825b8b8110156124945773ffffffffffffffffffffffffffffffffffffffff61247f84611b89565b16825260209283019290910190600101612459565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8911156124cc575f80fd5b8860051b9150818a602083013701828103602090810160408501526124f4908201878961239c565b60608401959095525050608001529695505050505050565b5f6020828403121561251c575f80fd5b815180151581146108c5575f80fd5b808201808211156107ac576107ac612338565b5f5b83811015612558578181015183820152602001612540565b50505f910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f835161259781601785016020880161253e565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516125d481602884016020880161253e565b01602801949350505050565b602081525f82518060208401526125fe81604085016020870161253e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b818382375f9101908152919050565b80820281158282048414176107ac576107ac612338565b5f8161266457612664612338565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea264697066735822122085c4cf030f76482828ded4e6c9cb7851ec61b401cf6380abe817d249dc4719fb64736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", + "0x73aec4d9eb3be1097d809826691104f0c28da74ebf68d903dc9c6f12562fd822": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x6b347b5397bd05b592ec00f3e3a28ac3cedc5d7ee6994c7533215f223a0cfe84": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x35fa115b92f0a8d03c972ada19f34c3fa238589ba573a59a419692abc6a91f1a": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0xc05edde0499e76380516353a6ad6ced0d360179c67da013977526f6fbac38774": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x3e92e57d702d5fdc47a588386c93df7f5578fb6af324e63318e76ec6cffcab32": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5" + } + }, + { + "accountName": "keyless Deployer", + "balance": "0", + "nonce": "1", + "address": "0xCBb32b7819EC30d41e1399b32dbE32dd5D47a55E" + }, + { + "accountName": "deployer", + "balance": "100000000000000000000000", + "nonce": "8", + "address": "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" + } + ] +} \ No newline at end of file diff --git a/test-pp-op/config/test.node.config.toml b/test-pp-op/config/test.node.config.toml new file mode 100644 index 0000000000000..ac7d141e1c14c --- /dev/null +++ b/test-pp-op/config/test.node.config.toml @@ -0,0 +1,6 @@ +[Etherman] +URL = "http://l1-geth:8545" +ForkIDChunkSize = 100 +MultiGasProvider = false +[Etherscan] +ApiKey = "" \ No newline at end of file diff --git a/test-pp-op/config/test.poolmanager.toml b/test-pp-op/config/test.poolmanager.toml new file mode 100644 index 0000000000000..c7e4a2a41ee11 --- /dev/null +++ b/test-pp-op/config/test.poolmanager.toml @@ -0,0 +1,37 @@ +[Log] +Environment = "development" # "production" or "development" +Level = "info" +Outputs = ["stderr"] + +[Server] +Host = "0.0.0.0" +Port = 8545 +ReadTimeout = "60s" +WriteTimeout = "60s" +MaxRequestsPerIPAndSecond = 50000 +EnableHttpLog = true +BatchRequestsEnabled = false +BatchRequestsLimit = 20 + +[DB] +User = "pool_user" +Password = "pool_password" +Name = "pool_db" +Host = "xlayer-pool-db" +Port = "5432" +EnableLog = false +MaxConns = 200 + +[Sender] +SequencerURL = "http://xlayer-seq:8545" +ResendTxsCheckInterval = "1s" +Workers = 5 +QueueSize = 25 + +[Monitor] +L2NodeURL = "http://xlayer-seq:8545" +Workers = 5 +QueueSize = 25 +RetryWaitInterval = "3s" +InitialWaitInterval = "1s" +TxLifeTimeMax = "10s" \ No newline at end of file diff --git a/test-pp-op/config/xlayerconfig-mainnet-rpc.yaml b/test-pp-op/config/xlayerconfig-mainnet-rpc.yaml new file mode 100644 index 0000000000000..923419f1a8868 --- /dev/null +++ b/test-pp-op/config/xlayerconfig-mainnet-rpc.yaml @@ -0,0 +1,29 @@ +datadir: /home/erigon/data/ +chain: xlayer-mainnet +http: true +private.api.addr: localhost:9091 +zkevm.l2-chain-id: 196 +zkevm.l2-sequencer-rpc-url: https://rpc.xlayer.tech +zkevm.l2-datastreamer-url: stream.xlayer.tech:8800 +zkevm.l1-chain-id: 1 +zkevm.l1-rpc-url: https://rpc.ankr.com/eth +zkevm.increment-tree-always: true +zkevm.l1-cache-enabled: true + +zkevm.data-stream-host: "localhost" +zkevm.data-stream-port: 6900 + +zkevm.address-sequencer: "0xAF9d27ffe4d51eD54AC8eEc78f2785D7E11E5ab1" +zkevm.address-zkevm: "0x2B0ee28D4D51bC9aDde5E58E295873F61F4a0507" +zkevm.address-rollup: "0x5132A183E9F3CB7C848b0AAC5Ae0c4f0491B7aB2" +zkevm.address-ger-manager: "0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb" + +zkevm.l1-rollup-id: 3 +zkevm.l1-first-block: 19218658 +zkevm.l1-block-range: 2000 +zkevm.l1-query-delay: 1000 +zkevm.datastream-version: 3 + +http.api: [eth, debug, net, trace, web3, erigon, zkevm] +http.addr: 0.0.0.0 +http.port: 8545 diff --git a/test-pp-op/config/xlayerconfig-mainnet.yaml b/test-pp-op/config/xlayerconfig-mainnet.yaml new file mode 100644 index 0000000000000..50c2d06e82a4d --- /dev/null +++ b/test-pp-op/config/xlayerconfig-mainnet.yaml @@ -0,0 +1,87 @@ +datadir: /home/erigon/data/ +chain: xlayer-mainnet +http: true +private.api.addr: localhost:9091 +zkevm.l2-chain-id: 196 +zkevm.l2-sequencer-rpc-url: https://rpc.xlayer.tech +zkevm.l2-datastreamer-url: stream.xlayer.tech:8800 +zkevm.l1-chain-id: 1 +# `zkevm.l1-rpc-url` must be changed before running. +# using a wrong default value so it can report and error and remind you to change this value. +zkevm.l1-rpc-url: https://rpc.ankr.com/eth/ +#zkevm.increment-tree-always: true + +#debug.limit: 8554110 + +zkevm.sequencer-block-seal-time: "1s" +zkevm.sequencer-max-block-seal-time: "3s" +zkevm.sequencer-batch-seal-time: "10s" +zkevm.sequencer-batch-sleep-duration: "0s" + +zkevm.data-stream-host: "localhost" +zkevm.data-stream-port: 6900 +zkevm.default-gas-price: 1 +zkevm.max-gas-price: 0 +zkevm.gas-price-factor: 0.000001 +zkevm.allow-free-transactions: true + +txpool.packbatchspeciallist : ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534", "0xa03666Fb51Aa9aD2DE70e0434072A007b3C91A9E"] +txpool.globalslots: 1000000 +txpool.globalbasefeeslots: 1000000 +txpool.globalqueue: 1000000 +txpool.commit.every: "10m" + +zkevm.address-sequencer: "0xAF9d27ffe4d51eD54AC8eEc78f2785D7E11E5ab1" +zkevm.address-zkevm: "0x2B0ee28D4D51bC9aDde5E58E295873F61F4a0507" +zkevm.address-rollup: "0x5132A183E9F3CB7C848b0AAC5Ae0c4f0491B7aB2" +zkevm.address-ger-manager: "0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb" + +zkevm.l1-rollup-id: 3 +zkevm.l1-first-block: 19218658 +zkevm.l1-block-range: 2000 +zkevm.l1-query-delay: 1000 +zkevm.datastream-version: 3 + +http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] +http.addr: 0.0.0.0 +http.port: 8545 + +gpo.type: "follower" +gpo.update-period: "300s" +gpo.factor: 0.01 +gpo.kafka-url: "0.0.0.0" +gpo.topic: "explorer" +gpo.group-id: "web3" +gpo.blocks: 3 +gpo.default-l1-coin-price: 2000 +gpo.default-l2-coin-price: 50 +gpo.gas-price-usdt: 0.000000476190476 +gpo.congestion-threshold: 0 + +pprof: true +pprof.port: 6060 +pprof.addr: 0.0.0.0 + +metrics: true +metrics.addr: "0.0.0.0" +metrics.port: 9095 + +yieldsize: 35 +zkevm.seal-batch-immediately-on-overflow: true +zkevm.sequencer-timeout-on-empty-tx-pool: 1ms +zkevm.pre-run-address-list: [""] +zkevm.block-info-concurrent: true +zkevm.standalone-smt-db: true +zkevm.enable-async-commit: true + +# to reduce lock race in stress test +txpool.enabletimsort: true +zkevm.bulk-add-txs: true +zkevm.enable-add-tx-notify: true + +#zkevm.verification-batch-delay: 2 +#zkevm.skip-analysis-group-api: true +# zkevm.analysis-group-nacos-urls: "url1:80,url2:80" +# zkevm.analysis-group-nacos-namespace: "ns-global" +# zkevm.analysis-group-service-name: "analysis-group" +# zkevm.analysis-group-api-path: "api/v1/196/validHeight" diff --git a/test-pp-op/contracts/OKBToken.sol b/test-pp-op/contracts/OKBToken.sol new file mode 100644 index 0000000000000..7e9344d091bb3 --- /dev/null +++ b/test-pp-op/contracts/OKBToken.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +interface IERC20 { + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 amount) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 amount) external returns (bool); + function transferFrom(address from, address to, uint256 amount) external returns (bool); + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} + +contract StandardERC20 is IERC20 { + string public name; + string public symbol; + uint8 public constant decimals = 18; + uint256 private _totalSupply; + + mapping(address => uint256) private _balances; + mapping(address => mapping(address => uint256)) private _allowances; + + constructor( + string memory _name, + string memory _symbol, + uint256 _initialSupply + ) { + name = _name; + symbol = _symbol; + _totalSupply = _initialSupply * 10**decimals; + _balances[msg.sender] = _totalSupply; + emit Transfer(address(0), msg.sender, _totalSupply); + } + + function totalSupply() public view override returns (uint256) { + return _totalSupply; + } + + function balanceOf(address account) public view override returns (uint256) { + return _balances[account]; + } + + function transfer(address to, uint256 amount) public override returns (bool) { + require(to != address(0), "ERC20: transfer to zero address"); + require(_balances[msg.sender] >= amount, "ERC20: insufficient balance"); + + _balances[msg.sender] -= amount; + _balances[to] += amount; + + emit Transfer(msg.sender, to, amount); + return true; + } + + function allowance(address owner, address spender) public view override returns (uint256) { + return _allowances[owner][spender]; + } + + function approve(address spender, uint256 amount) public override returns (bool) { + require(spender != address(0), "ERC20: approve to zero address"); + + _allowances[msg.sender][spender] = amount; + emit Approval(msg.sender, spender, amount); + return true; + } + + function transferFrom(address from, address to, uint256 amount) public override returns (bool) { + require(from != address(0), "ERC20: transfer from zero address"); + require(to != address(0), "ERC20: transfer to zero address"); + require(_balances[from] >= amount, "ERC20: insufficient balance"); + require(_allowances[from][msg.sender] >= amount, "ERC20: insufficient allowance"); + + _balances[from] -= amount; + _balances[to] += amount; + _allowances[from][msg.sender] -= amount; + + emit Transfer(from, to, amount); + return true; + } + + function mint(address to, uint256 amount) public { + require(to != address(0), "ERC20: mint to zero address"); + + _totalSupply += amount; + _balances[to] += amount; + emit Transfer(address(0), to, amount); + } + + function burn(uint256 amount) public { + require(_balances[msg.sender] >= amount, "ERC20: insufficient balance"); + + _balances[msg.sender] -= amount; + _totalSupply -= amount; + emit Transfer(msg.sender, address(0), amount); + } +} diff --git a/test-pp-op/contracts/Transactor.sol b/test-pp-op/contracts/Transactor.sol new file mode 100644 index 0000000000000..e193db31e024f --- /dev/null +++ b/test-pp-op/contracts/Transactor.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +// Contracts +import { Owned } from "@rari-capital/solmate/src/auth/Owned.sol"; + +/// @title Transactor +/// @notice Transactor is a minimal contract that can send transactions. +contract Transactor is Owned { + /// @param _owner Initial contract owner. + constructor(address _owner) Owned(_owner) { } + + /// @notice Sends a CALL to a target address. + /// @param _target Address to call. + /// @param _data Data to send with the call. + /// @param _value ETH value to send with the call. + /// @return success_ Boolean success value. + /// @return data_ Bytes data returned by the call. + function CALL( + address _target, + bytes memory _data, + uint256 _value + ) + external + payable + onlyOwner + returns (bool success_, bytes memory data_) + { + (success_, data_) = _target.call{ value: _value }(_data); + require(success_, "Transactor: CALL failed"); + } + + /// @notice Sends a DELEGATECALL to a target address. + /// @param _target Address to call. + /// @param _data Data to send with the call. + /// @return success_ Boolean success value. + /// @return data_ Bytes data returned by the call. + function DELEGATECALL( + address _target, + bytes memory _data + ) + external + payable + onlyOwner + returns (bool success_, bytes memory data_) + { + // slither-disable-next-line controlled-delegatecall + (success_, data_) = _target.delegatecall(_data); + require(success_, "Transactor: DELEGATECALL failed"); + } +} diff --git a/test-pp-op/contracts/foundry.toml b/test-pp-op/contracts/foundry.toml new file mode 100644 index 0000000000000..27db5c056c5a9 --- /dev/null +++ b/test-pp-op/contracts/foundry.toml @@ -0,0 +1,9 @@ +[profile.default] +src = "." +out = "../tmp/OKB/out" +cache_path = "../tmp/OKB/cache" +libs = ["lib"] +solc_version = "0.8.19" + +[rpc_endpoints] +local = "http://127.0.0.1:8545" diff --git a/test-pp-op/docker-compose-local.yml b/test-pp-op/docker-compose-local.yml new file mode 100644 index 0000000000000..34f1d842c85e5 --- /dev/null +++ b/test-pp-op/docker-compose-local.yml @@ -0,0 +1,925 @@ +networks: + default: + name: pp-op + +services: + l1-geth-remove-db: + image: "alpine:3.19.0" + container_name: l1-geth-remove-db + command: rm -rf /execution/geth + volumes: + - ./l1-geth/execution:/execution + + l1-beacon-remove-db: + image: "alpine:3.19.0" + container_name: l1-beacon-remove-db + command: rm -rf /consensus/beacondata /consensus/validatordata /consensus/genesis.ssz + volumes: + - ./l1-geth/consensus:/consensus + + l1-create-beacon-chain-genesis: + image: "gcr.io/prysmaticlabs/prysm/cmd/prysmctl:v5.1.2" + container_name: l1-create-beacon-chain-genesis + command: + - testnet + - generate-genesis + - --fork=deneb + - --num-validators=4 + - --genesis-time-delay=0 + - --output-ssz=/consensus/genesis.ssz + - --chain-config-file=/consensus/config.yml + - --geth-genesis-json-in=/execution/genesis-raw.json + - --geth-genesis-json-out=/execution/genesis.json + volumes: + - ./l1-geth/consensus:/consensus + - ./l1-geth/execution:/execution + depends_on: + l1-beacon-remove-db: + condition: service_completed_successfully + + l1-fix-genesis-fork-times: + image: "alpine:3.19.0" + container_name: l1-fix-genesis-fork-times + command: + - /bin/sh + - -c + - | + apk add --no-cache jq + echo "Fixing genesis.json fork times..." + sed -i 's/"shanghaiTime": [0-9]*/"shanghaiTime": 0/g' /execution/genesis.json + sed -i 's/"cancunTime": [0-9]*/"cancunTime": 0/g' /execution/genesis.json + echo "Adding blobSchedule for Cancun..." + jq '.config.blobSchedule = {"cancun": {"target": 3, "max": 6, "baseFeeUpdateFraction": 3338477}}' /execution/genesis.json > /tmp/genesis.json && mv /tmp/genesis.json /execution/genesis.json + echo "Removing terminalTotalDifficultyPassed for op-node compatibility..." + jq 'del(.config.terminalTotalDifficultyPassed)' /execution/genesis.json > /tmp/genesis.json && mv /tmp/genesis.json /execution/genesis.json + echo "Genesis.json: shanghai=0, cancun=0 (MCOPY enabled), blobSchedule added, terminalTotalDifficultyPassed removed" + cat /execution/genesis.json | jq '.config | {shanghaiTime, cancunTime, terminalTotalDifficulty, blobSchedule}' + volumes: + - ./l1-geth/execution:/execution + depends_on: + l1-create-beacon-chain-genesis: + condition: service_completed_successfully + + l1-geth-genesis: + image: "ethereum/client-go:v1.15.11" + container_name: l1-geth-genesis + command: --datadir=/execution --gcmode=archive init --state.scheme=hash /execution/genesis.json + volumes: + - ./l1-geth/execution:/execution + - ./l1-geth/execution/genesis.json:/execution/genesis.json + depends_on: + l1-fix-genesis-fork-times: + condition: service_completed_successfully + l1-geth-remove-db: + condition: service_completed_successfully + + l1-geth: + image: "ethereum/client-go:v1.15.11" + container_name: l1-geth + command: + - --http + - --http.api=eth,net,web3,debug,admin + - --http.addr=0.0.0.0 + - --http.corsdomain=* + - --http.vhosts=* + - --ws + - --ws.api=eth,net,web3,debug + - --ws.addr=0.0.0.0 + - --ws.origins=* + - --authrpc.vhosts=* + - --authrpc.addr=0.0.0.0 + - --authrpc.jwtsecret=/execution/jwtsecret + - --datadir=/execution + - --allow-insecure-unlock + - --unlock=0x123463a4b065722e99115d6c222f267d9cabb524 + - --password=/execution/geth_password.txt + - --nodiscover + - --syncmode=full + - --gcmode=archive + - --ipcdisable + - --rpc.allow-unprotected-txs + - --verbosity=3 + ports: + - 8551:8551 + - 8545:8545 + - 8546:8546 + depends_on: + l1-geth-genesis: + condition: service_completed_successfully + volumes: + - ./l1-geth/execution:/execution + - ./l1-geth/execution/jwtsecret:/execution/jwtsecret + - ./l1-geth/execution/geth_password.txt:/execution/geth_password.txt + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] + interval: 10s + timeout: 5s + retries: 5 + + l1-beacon-chain: + image: "gcr.io/prysmaticlabs/prysm/beacon-chain:v5.1.2" + container_name: l1-beacon-chain + command: + - --datadir=/consensus/beacondata + - --min-sync-peers=0 + - --genesis-state=/consensus/genesis.ssz + - --bootstrap-node= + - --interop-eth1data-votes + - --chain-config-file=/consensus/config.yml + - --contract-deployment-block=0 + - --chain-id=${CHAIN_ID:-1337} + - --rpc-host=0.0.0.0 + - --grpc-gateway-host=0.0.0.0 + - --execution-endpoint=http://l1-geth:8551 + - --accept-terms-of-use + - --jwt-secret=/execution/jwtsecret + - --suggested-fee-recipient=0x123463a4b065722e99115d6c222f267d9cabb524 + - --minimum-peers-per-subnet=0 + - --enable-debug-rpc-endpoints + - --verbosity=info + depends_on: + l1-create-beacon-chain-genesis: + condition: service_completed_successfully + l1-geth: + condition: service_healthy + ports: + - 4000:4000 + - 3500:3500 + - 18080:8080 + - 6060:6060 + - 19090:9090 + volumes: + - ./l1-geth/consensus:/consensus + - ./l1-geth/execution:/execution + - ./l1-geth/execution/jwtsecret:/execution/jwtsecret + + l1-validator: + image: "gcr.io/prysmaticlabs/prysm/validator:v5.1.2" + container_name: l1-validator + command: + - --beacon-rpc-provider=l1-beacon-chain:4000 + - --datadir=/consensus/validatordata + - --accept-terms-of-use + - --interop-num-validators=4 + - --interop-start-index=0 + - --chain-config-file=/consensus/config.yml + - --verbosity=info + depends_on: + l1-beacon-chain: + condition: service_started + volumes: + - ./l1-geth/consensus:/consensus + + xlayer-approve: + container_name: xlayer-approve + image: hermeznetwork/zkevm-node:v0.6.6 + volumes: + - ./keystore/sequencer.keystore:/pk/keystore + - ./config/test.node.config.toml:/app/config.toml + - ./config/test.genesis.config.json:/app/genesis.json + command: + - "/bin/sh" + - "-c" + - "/app/zkevm-node approve --network custom --custom-network-file /app/genesis.json --key-store-path /pk/keystore --pw testonly --am 115792089237316195423570985008687907853269984665640564039457584007913129639935 -y --cfg /app/config.toml" + + xlayer-seq: + container_name: xlayer-seq + image: cdk-erigon + environment: + - CDK_ERIGON_SEQUENCER=1 + - WRITE_MAP=true + ports: + - 6062:6060 + - 8123:8545 + - 6900:6900 + - 9092:9095 + volumes: + - ./data/seq/:/home/erigon/data/ + - ./config/test.erigon.seq.config.yaml:/usr/src/app/config.yaml + - ./config/first-batch-config.json:/usr/src/app/first-batch-config.json + - ./config/dynamic-mynetwork-allocs.json:/usr/src/app/dynamic-mynetwork-allocs.json + - ./config/dynamic-mynetwork-chainspec.json:/usr/src/app/dynamic-mynetwork-chainspec.json + - ./config/dynamic-mynetwork-conf.json:/usr/src/app/dynamic-mynetwork-conf.json + command: > + cdk-erigon --http.vhosts=* --http.corsdomain=* --ws --config=/usr/src/app/config.yaml + + xlayer-mainnet-seq: + container_name: xlayer-seq + image: cdk-erigon + environment: + - CDK_ERIGON_SEQUENCER=1 + - WRITE_MAP=true + ports: + - 6062:6060 + - 8123:8545 + - 6900:6900 + - 9092:9095 + volumes: + - ./mainnet/seq:/home/erigon/data/ + - ./config/xlayerconfig-mainnet.yaml:/usr/src/app/config.yaml + command: > + cdk-erigon --http.vhosts=* --http.corsdomain=* --ws --config=/usr/src/app/config.yaml + + xlayer-bridge-db: + container_name: xlayer-bridge-db + image: postgres:15 + deploy: + resources: + limits: + memory: 2G + reservations: + memory: 1G + ports: + - 5439:5432 + environment: + - POSTGRES_USER=test_user + - POSTGRES_PASSWORD=test_password + - POSTGRES_DB=test_db + command: [ "postgres", "-N", "500" ] + + xlayer-bridge-service: + container_name: xlayer-bridge-service + image: ${XLAYER_BRIDGE_SERVICE_IMAGE_TAG} + ports: + - 8080:8080 + - 9090:9090 + environment: + - ZKEVM_BRIDGE_DATABASE_USER=test_user + - ZKEVM_BRIDGE_DATABASE_PASSWORD=test_password + - ZKEVM_BRIDGE_DATABASE_NAME=test_db + - ZKEVM_BRIDGE_DATABASE_HOST=xlayer-bridge-db + - ZKEVM_BRIDGE_DATABASE_PORT=5432 + volumes: + - ./keystore/sequencer.keystore:/pk/keystore.claimtxmanager + - ./config/test.bridge.config.toml:/app/config.toml + command: + - "/bin/sh" + - "-c" + - "/app/zkevm-bridge run --cfg /app/config.toml" + + xlayer-bridge-ui: + container_name: xlayer-bridge-ui + image: hermeznetwork/zkevm-bridge-ui:latest + ports: + - 8090:80 + environment: + - ETHEREUM_RPC_URL=http://127.0.0.1:8545 + - ETHEREUM_EXPLORER_URL=http://127.0.0.1:4000 + - ETHEREUM_ROLLUP_MANAGER_ADDRESS=0xE96dBF374555C6993618906629988d39184716B3 + - ETHEREUM_BRIDGE_CONTRACT_ADDRESS=0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851 + - ETHEREUM_FORCE_UPDATE_GLOBAL_EXIT_ROOT=true + - ETHEREUM_PROOF_OF_EFFICIENCY_CONTRACT_ADDRESS=0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd + - POLYGON_ZK_EVM_RPC_URL=http://127.0.0.1:8123 + - POLYGON_ZK_EVM_EXPLORER_URL=http://127.0.0.1:4001 + - POLYGON_ZK_EVM_BRIDGE_CONTRACT_ADDRESS=0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851 + - POLYGON_ZK_EVM_NETWORK_ID=1 + - BRIDGE_API_URL=http://127.0.0.1:8080 + - ENABLE_FIAT_EXCHANGE_RATES=false + - ENABLE_OUTDATED_NETWORK_MODAL=false + - ENABLE_DEPOSIT_WARNING=false + - ENABLE_REPORT_FORM=false + - RESOLVE_RELATIVE_URLS=false + + xlayer-pool-db: + container_name: xlayer-pool-db + image: postgres:15 + ports: + - 5440:5432 + volumes: + - /var/lib/postgresql/data + environment: + - POSTGRES_USER=pool_user + - POSTGRES_PASSWORD=pool_password + - POSTGRES_DB=pool_db + command: + - "postgres" + - "-N" + - "500" + + xlayer-pool-manager: + container_name: xlayer-pool-manager + image: hermeznetwork/zkevm-pool-manager:v0.1.2 + deploy: + resources: + limits: + memory: 1G + reservations: + memory: 512M + ports: + - 8125:8545 + volumes: + - ./config/test.poolmanager.toml:/app/poolmanager.toml + command: + - "/bin/sh" + - "-c" + - "/app/zkevm-pool-manager run --cfg /app/poolmanager.toml" + + xlayer-agg-sender: + container_name: xlayer-agg-sender + image: aggkit:local + restart: on-failure + volumes: + - ./data/cdk-node:/tmp + - ./keystore/aggregator.keystore:/etc/aggkit/aggregator.keystore + - ./keystore/sequencer.keystore:/etc/aggkit/sequencer.keystore + - ./config/aggkit.toml:/etc/aggkit/aggkit.toml + - ./config/test.genesis.config.json:/etc/aggkit/genesis.json + ports: + - 5576:5576 + command: ["run", "--cfg=/etc/aggkit/aggkit.toml", "--components=aggsender"] + + xlayer-agglayer: + container_name: xlayer-agglayer + image: zjg555543/agglayer:upstream-v0.3.3 + ports: + - 4443:4443 + - 4444:4444 + - 4446:4446 + - 9094:9092 + volumes: + - ./keystore/agglayer.keystore:/etc/zkevm/agglayer.keystore + - ./config/agglayer-config.toml:/etc/zkevm/agglayer-config.toml + - ./data/agglayer/storage:/etc/zkevm/storage/ + - ./data/agglayer/backups:/etc/zkevm/backups/ + command: + - "/bin/sh" + - "-c" + - "/usr/local/bin/agglayer run --cfg /etc/zkevm/agglayer-config.toml" + + xlayer-agglayer-prover: + container_name: xlayer-agglayer-prover + image: zjg555543/agglayer:upstream-v0.3.3 + volumes: + - ./config/agglayer-prover-config.toml:/etc/zkevm/agglayer-prover-config.toml + ports: + - 4445:4445 + - 9093:9093 + command: + - "/bin/sh" + - "-c" + - "/usr/local/bin/agglayer prover --cfg /etc/zkevm/agglayer-prover-config.toml" + + xlayer-agg-db: + container_name: xlayer-agg-db + image: postgres:15 + deploy: + resources: + limits: + memory: 2G + reservations: + memory: 1G + ports: + - 5434:5432 + environment: + - POSTGRES_USER=aggregator_user + - POSTGRES_PASSWORD=aggregator_password + - POSTGRES_DB=aggregator_db + command: + - "postgres" + - "-N" + - "500" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U aggregator_user -d aggregator_db"] + interval: 5s + timeout: 5s + retries: 5 + start_period: 5s + + xlayer-rpc: + container_name: xlayer-rpc + image: cdk-erigon + environment: + - CDK_ERIGON_SEQUENCER=0 + - WRITE_MAP=true + ports: + - 16061:6060 + - 18124:8545 + - 16901:6900 + - 19091:9095 + volumes: + - ./data/rpc/:/home/erigon/data/ + - ./config/test.erigon.rpc.config.yaml:/usr/src/app/config.yaml + - ./config/first-batch-config.json:/usr/src/app/first-batch-config.json + - ./config/dynamic-mynetwork-allocs.json:/usr/src/app/dynamic-mynetwork-allocs.json + - ./config/dynamic-mynetwork-chainspec.json:/usr/src/app/dynamic-mynetwork-chainspec.json + - ./config/dynamic-mynetwork-conf.json:/usr/src/app/dynamic-mynetwork-conf.json + command: > + cdk-erigon --http.vhosts=* --http.corsdomain=* --ws --config=/usr/src/app/config.yaml + xlayer-oracle: + container_name: xlayer-oracle + image: aggkit:local + volumes: + - ./data/oracle:/tmp + - ./keystore/aggoracle.keystore:/etc/aggkit/aggoracle.keystore + - ./config-op/aggkit.toml:/etc/aggkit/aggkit.toml + - ./config/test.genesis.config.json:/etc/aggkit/genesis.json + ports: + - 15576:5576 + command: ["run", "--cfg=/etc/aggkit/aggkit.toml", "--components=aggoracle"] + op-geth-seq: + image: "${OP_GETH_IMAGE_TAG}" + container_name: op-geth-seq + entrypoint: geth + volumes: + - ./data/op-geth-seq:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/test.seq.config.toml:/config.toml + ports: + - "8123:8545" + - "7546:7546" + - "8552:8552" + - "30303:30303" + - "30303:30303/udp" + - "9090:9090" # pprof port + command: + - --verbosity=3 + - --datadir=/datadir + - --db.engine=${DB_ENGINE} + - --config=/config.toml + - --gcmode=archive + - --rollup.disabletxpoolgossip=false + - --pp-rpc-legacy-header-sync-rate-limit=10000 + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-geth-rpc: + image: "${OP_GETH_IMAGE_TAG}" + container_name: op-geth-rpc + entrypoint: geth + volumes: + - ./data/op-geth-rpc:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/test.rpc.config.toml:/config.toml + ports: + - "8124:8545" + - "30304:30303" + - "30304:30303/udp" + command: + - --verbosity=3 + - --datadir=/datadir + - --db.engine=${DB_ENGINE} + - --config=/config.toml + - --gcmode=archive + # - --rollup.sequencerhttp=http://op-geth-seq:8545 + - --rollup.enabletxpooladmission + - --pp-rpc-legacy-header-sync-rate-limit=10000 + + op-seq: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-seq + volumes: + - ./config-op/rollup.json:/rollup.json + - ./config-op/jwt.txt:/jwt.txt + - ./data/op-seq:/data + - ./l1-geth/execution/:/l1/ + ports: + - "9545:9545" + - "7070:7070" + - "9223:9223" + - "9223:9223/udp" + - "9091:9091" # pprof port + command: + - /app/op-node/bin/op-node + - --log.level=debug + - --l2=http://op-geth-seq:8552 + - --l2.jwt-secret=/jwt.txt + - --sequencer.enabled + - --sequencer.l1-confs=5 + - --verifier.l1-confs=1 + - --rollup.config=/rollup.json + - --rpc.addr=0.0.0.0 + - --p2p.listen.tcp=9223 + - --p2p.listen.udp=9223 + - --p2p.priv.raw=e054b5748fb29a82994ea170af9e6094a163a0d11308dea91a38744c4e7c94da + - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db + - --p2p.discovery.path=/data/p2p/opnode_discovery_db + - --p2p.no-discovery + - --rpc.enable-admin + - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} + - --l1=${L1_RPC_URL_IN_DOCKER} + - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} + - --l1.rpckind=standard + - --rollup.l1-chain-config=/l1/genesis.json + - --safedb.path=/data/safedb + - --conductor.enabled=${CONDUCTOR_ENABLED:-false} # 默认关闭 + - --conductor.rpc=http://op-conductor:8547 + - --pprof.enabled + - --pprof.addr=0.0.0.0 + - --pprof.port=9091 + depends_on: + op-geth-seq: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-rpc: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-rpc + volumes: + - ./data/op-rpc:/data + - ./config-op/rollup.json:/rollup.json + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/oprpc_p2p_priv.txt:/opnode_p2p_priv.txt + - ./l1-geth/execution/:/l1 + ports: + - "9555:9545" + command: + - /app/op-node/bin/op-node + - --log.level=debug + - --l2=http://op-geth-rpc:8552 + - --l2.jwt-secret=/jwt.txt + - --sequencer.enabled=false + - --verifier.l1-confs=1 + - --rollup.config=/rollup.json + - --rpc.addr=0.0.0.0 + - --rpc.port=9545 + - --p2p.listen.tcp=9223 + - --p2p.listen.udp=9223 + - --p2p.priv.raw=604557d042fbea9ed42f46c0c95c346a932b6a5ef0c0dd07a00dbf95801a2510 + - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db + - --p2p.discovery.path=/data/p2p/opnode_discovery_db + - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65 + - --p2p.no-discovery + - --rpc.enable-admin=true + - --l1=${L1_RPC_URL_IN_DOCKER} + - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} + - --l1.rpckind=standard + - --rollup.l1-chain-config=/l1/genesis.json + - --safedb.path=/data/safedb + - --pp-rpc-url=${PP_RPC_URL} + depends_on: + - op-geth-rpc + + op-conductor: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-conductor + volumes: + - ./data/op-conductor:/data + - ./config-op/rollup.json:/rollup.json + ports: + - "8547:8547" # RPC port +# - "50050:50050" # Consensus port + command: + - /app/op-conductor/bin/op-conductor + - --log.level=debug + # already existed service + - --node.rpc=http://op-seq:9545 + - --execution.rpc=http://op-geth-seq:8545 + # Raft Config + - --raft.server.id=conductor-1 + - --raft.storage.dir=/data/raft + - --raft.bootstrap=true + - --consensus.addr=0.0.0.0 + - --consensus.port=50050 + - --consensus.advertised=op-conductor:50050 + # RPC Config + - --rpc.addr=0.0.0.0 + - --rpc.port=8547 + - --rpc.enable-proxy=true + # Healthcheck Config + - --healthcheck.interval=1 + - --healthcheck.unsafe-interval=3 + - --healthcheck.min-peer-count=1 + - --rollup.config=/rollup.json + depends_on: + op-seq: + condition: service_healthy + op-geth-seq: + condition: service_healthy + + op-batcher: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-batcher + command: + - /app/op-batcher/bin/op-batcher + - --log.level=debug + - --l2-eth-rpc=${OP_BATCHER_L2_ETH_RPC:-http://op-geth-seq:8545} + - --rollup-rpc=${OP_BATCHER_ROLLUP_RPC:-http://op-seq:9545} + - --wait-node-sync=true + - --check-recent-txs-depth=5 + - --poll-interval=5s + - --batch-type=1 + - --compression-algo=brotli-11 + - --data-availability-type=auto + - --max-channel-duration=30 + - --target-num-frames=5 + - --sub-safety-margin=6 + - --num-confirmations=4 + - --network-timeout=10s + - --safe-abort-nonce-too-low-count=3 + - --max-pending-tx=10 + - --resubmission-timeout=30s + - --rpc.addr=0.0.0.0 + - --rpc.port=8548 + - --rpc.enable-admin + - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} + - --private-key=${OP_BATCHER_PRIVATE_KEY} + - --throttle.block-size-upper-limit=1300000 + - --active-sequencer-check-duration=5s + + op-proposer: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-proposer + environment: + - DISPUTE_GAME_FACTORY_ADDRESS=${DISPUTE_GAME_FACTORY_ADDRESS} + command: + - /app/op-proposer/bin/op-proposer + - --log.level=debug + - --poll-interval=20s + - --wait-node-sync=true + - --allow-non-finalized=false + - --num-confirmations=1 + - --safe-abort-nonce-too-low-count=3 + - --resubmission-timeout=30s + - --rpc.port=8560 + - --rollup-rpc=http://op-rpc:9545 + - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} + - --proposal-interval=1m + - --private-key=${OP_PROPOSER_PRIVATE_KEY} + - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} + - --game-type=${GAME_TYPE:-0} + - --allow-non-finalized + - --genesis-height=${FORK_BLOCK} + depends_on: + - op-batcher + + op-challenger: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-challenger + environment: + - L1_RPC_URL_IN_DOCKER=${L1_RPC_URL_IN_DOCKER} + - L1_BEACON_URL_IN_DOCKER=${L1_BEACON_URL_IN_DOCKER} + - DISPUTE_GAME_FACTORY_ADDRESS=${DISPUTE_GAME_FACTORY_ADDRESS} + volumes: + - ./data/cannon-data:/data + - ./config-op/rollup.json:/rollup.json + - ./config-op/genesis.json:/l2-genesis.json + depends_on: + - op-seq + command: + - /app/op-challenger/bin/op-challenger + - --log.level=debug + - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} + - --l1-beacon=${L1_BEACON_URL_IN_DOCKER} + - --l2-eth-rpc=http://op-geth-rpc:8545 + - --rollup-rpc=http://op-rpc:9545 + - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} + - --cannon-bin=/app/cannon/bin/cannon + - --cannon-server=/data/op-program + - --cannon-prestate=/data/prestate-mt64.bin.gz + - --cannon-rollup-config=/rollup.json + - --cannon-l2-genesis=/l2-genesis.json + - --private-key=${OP_PROPOSER_PRIVATE_KEY} + - --trace-type=cannon,permissioned + - --datadir=/data + - --game-window=${GAME_WINDOW}s + + op-dispute-mon: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-dispute-mon + depends_on: + - op-challenger + - op-proposer + command: + - /app/op-dispute-mon/bin/op-dispute-mon + - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} + - --rollup-rpc=http://op-rpc:9545 + - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} + - --game-window=${GAME_WINDOW}s + - --honest-actors=${PROPOSER_ADDRESS} + + op-geth-seq2: + image: "${OP_GETH_IMAGE_TAG}" + container_name: op-geth-seq2 + entrypoint: geth + volumes: + - ./data/op-geth-seq2:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/test.seq.config.toml:/config.toml + ports: + - "8223:8545" + - "30305:30303" + - "30305:30303/udp" + command: + - --verbosity=3 + - --datadir=/datadir + - --db.engine=${DB_ENGINE} + - --config=/config.toml + - --gcmode=archive + - --rollup.disabletxpoolgossip=false + - --pp-rpc-legacy-header-sync-rate-limit=10000 + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-seq2: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-seq2 + volumes: + - ./config-op/rollup.json:/rollup.json + - ./config-op/jwt.txt:/jwt.txt + - ./data/op-seq2:/data + - ./l1-geth/execution/:/l1/ + ports: + - "9546:9545" + # - "7070:7070" + - "9224:9223" + - "9224:9223/udp" + command: + - /app/op-node/bin/op-node + - --log.level=info + - --l2=http://op-geth-seq2:8552 + - --l2.jwt-secret=/jwt.txt + - --sequencer.enabled + - --sequencer.stopped + - --sequencer.l1-confs=5 + - --verifier.l1-confs=1 + - --rollup.config=/rollup.json + - --rpc.addr=0.0.0.0 + - --p2p.listen.tcp=9223 + - --p2p.listen.udp=9223 + - --p2p.priv.raw=cff9dac7588f5e6755a72d1e5b5001da3d0f8c06c4242b27d67eb5df4216bd93 + - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db + - --p2p.discovery.path=/data/p2p/opnode_discovery_db + - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65,/dns4/op-seq3/tcp/9223/p2p/16Uiu2HAmRDGMm3UUrP8CfQ3YQo9aaXEXFXA7LeFNztdPMNK5moyD + - --p2p.no-discovery + - --rpc.enable-admin + - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} + - --l1=${L1_RPC_URL_IN_DOCKER} + - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} + - --l1.rpckind=standard + - --rollup.l1-chain-config=/l1/genesis.json + - --safedb.path=/data/safedb + - --conductor.enabled=${CONDUCTOR_ENABLED:-false} + - --conductor.rpc=http://op-conductor2:8547 + depends_on: + op-geth-seq2: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-conductor2: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-conductor2 + volumes: + - ./data/op-conductor2:/data + - ./config-op/rollup.json:/rollup.json + ports: + - "8548:8547" # RPC port +# - "50051:50050" # Consensus port + command: + - /app/op-conductor/bin/op-conductor + - --log.level=debug + # already existed service + - --node.rpc=http://op-seq2:9545 + - --execution.rpc=http://op-geth-seq2:8545 + # Raft Config + - --raft.server.id=conductor-2 + - --raft.storage.dir=/data/raft + - --raft.bootstrap=false + - --consensus.addr=0.0.0.0 + - --consensus.port=50050 + - --consensus.advertised=op-conductor2:50050 + # RPC Config + - --rpc.addr=0.0.0.0 + - --rpc.port=8547 + - --rpc.enable-proxy=true + # Healthcheck Config + - --healthcheck.interval=1 + - --healthcheck.unsafe-interval=3 + - --healthcheck.min-peer-count=1 + - --rollup.config=/rollup.json + depends_on: + op-seq2: + condition: service_healthy + op-geth-seq2: + condition: service_healthy + + op-geth-seq3: + image: "${OP_GETH_IMAGE_TAG}" + container_name: op-geth-seq3 + entrypoint: geth + volumes: + - ./data/op-geth-seq3:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/test.seq.config.toml:/config.toml + ports: + - "8323:8545" + - "30306:30303" + - "30306:30303/udp" + command: + - --verbosity=3 + - --datadir=/datadir + - --db.engine=${DB_ENGINE} + - --config=/config.toml + - --gcmode=archive + - --rollup.disabletxpoolgossip=false + - --pp-rpc-legacy-header-sync-rate-limit=10000 + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-seq3: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-seq3 + volumes: + - ./config-op/rollup.json:/rollup.json + - ./config-op/jwt.txt:/jwt.txt + - ./data/op-seq3:/data + - ./l1-geth/execution/:/l1/ + ports: + - "9547:9545" + # - "7070:7070" + - "9225:9223" + - "9225:9223/udp" + command: + - /app/op-node/bin/op-node + - --log.level=info + - --l2=http://op-geth-seq3:8552 + - --l2.jwt-secret=/jwt.txt + - --sequencer.enabled + - --sequencer.stopped + - --sequencer.l1-confs=5 + - --verifier.l1-confs=1 + - --rollup.config=/rollup.json + - --rpc.addr=0.0.0.0 + - --p2p.listen.tcp=9223 + - --p2p.listen.udp=9223 + - --p2p.priv.raw=10785157e7c98628e5e47c3d9b8ebbd12525c45f1554b4a39652b5ce02bb29dc + - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db + - --p2p.discovery.path=/data/p2p/opnode_discovery_db + - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65,/dns4/op-seq2/tcp/9223/p2p/16Uiu2HAmDTjVuEF6V9DccV1JhrHg7DYc5SKm3bw2T75kAFPsGuSp + - --p2p.no-discovery + - --rpc.enable-admin + - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} + - --l1=${L1_RPC_URL_IN_DOCKER} + - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} + - --l1.rpckind=standard + - --rollup.l1-chain-config=/l1/genesis.json + - --safedb.path=/data/safedb + - --conductor.enabled=${CONDUCTOR_ENABLED:-false} + - --conductor.rpc=http://op-conductor3:8547 + depends_on: + op-geth-seq3: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-conductor3: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-conductor3 + volumes: + - ./data/op-conductor3:/data + - ./config-op/rollup.json:/rollup.json + ports: + - "8549:8547" # RPC port +# - "50052:50050" # Consensus port + command: + - /app/op-conductor/bin/op-conductor + - --log.level=debug + # already existed service + - --node.rpc=http://op-seq3:9545 + - --execution.rpc=http://op-geth-seq3:8545 + # Raft Config + - --raft.server.id=conductor-3 + - --raft.storage.dir=/data/raft + - --raft.bootstrap=false + - --consensus.addr=0.0.0.0 + - --consensus.port=50050 + - --consensus.advertised=op-conductor3:50050 + # RPC Config + - --rpc.addr=0.0.0.0 + - --rpc.port=8547 + - --rpc.enable-proxy=true + # Healthcheck Config + - --healthcheck.interval=1 + - --healthcheck.unsafe-interval=3 + - --healthcheck.min-peer-count=1 + - --rollup.config=/rollup.json + depends_on: + op-seq3: + condition: service_healthy + op-geth-seq3: + condition: service_healthy diff --git a/test-pp-op/docker-compose.yml b/test-pp-op/docker-compose.yml new file mode 100644 index 0000000000000..a14ed53ce1a9b --- /dev/null +++ b/test-pp-op/docker-compose.yml @@ -0,0 +1,663 @@ +networks: + default: + name: ${DOCKER_NETWORK:-dev-op} + +services: + l1-geth-remove-db: + image: "alpine:3.19.0" + container_name: l1-geth-remove-db + command: rm -rf /execution/geth + volumes: + - ./l1-geth/execution:/execution + + l1-beacon-remove-db: + image: "alpine:3.19.0" + container_name: l1-beacon-remove-db + command: rm -rf /consensus/beacondata /consensus/validatordata /consensus/genesis.ssz + volumes: + - ./l1-geth/consensus:/consensus + + l1-create-beacon-chain-genesis: + image: "gcr.io/prysmaticlabs/prysm/cmd/prysmctl:v5.1.2" + container_name: l1-create-beacon-chain-genesis + command: + - testnet + - generate-genesis + - --fork=deneb + - --num-validators=4 + - --genesis-time-delay=0 + - --output-ssz=/consensus/genesis.ssz + - --chain-config-file=/consensus/config.yml + - --geth-genesis-json-in=/execution/genesis-raw.json + - --geth-genesis-json-out=/execution/genesis.json + volumes: + - ./l1-geth/consensus:/consensus + - ./l1-geth/execution:/execution + depends_on: + l1-beacon-remove-db: + condition: service_completed_successfully + + l1-fix-genesis-fork-times: + image: "alpine:3.19.0" + container_name: l1-fix-genesis-fork-times + command: + - /bin/sh + - -c + - | + apk add --no-cache jq + echo "Fixing genesis.json fork times..." + sed -i 's/"shanghaiTime": [0-9]*/"shanghaiTime": 0/g' /execution/genesis.json + sed -i 's/"cancunTime": [0-9]*/"cancunTime": 0/g' /execution/genesis.json + echo "Adding blobSchedule for Cancun..." + jq '.config.blobSchedule = {"cancun": {"target": 3, "max": 6, "baseFeeUpdateFraction": 3338477}}' /execution/genesis.json > /tmp/genesis.json && mv /tmp/genesis.json /execution/genesis.json + echo "Removing terminalTotalDifficultyPassed for op-node compatibility..." + jq 'del(.config.terminalTotalDifficultyPassed)' /execution/genesis.json > /tmp/genesis.json && mv /tmp/genesis.json /execution/genesis.json + echo "Genesis.json: shanghai=0, cancun=0 (MCOPY enabled), blobSchedule added, terminalTotalDifficultyPassed removed" + cat /execution/genesis.json | jq '.config | {shanghaiTime, cancunTime, terminalTotalDifficulty, blobSchedule}' + volumes: + - ./l1-geth/execution:/execution + depends_on: + l1-create-beacon-chain-genesis: + condition: service_completed_successfully + + l1-geth-genesis: + image: "ethereum/client-go:v1.15.11" + container_name: l1-geth-genesis + command: --datadir=/execution --gcmode=archive init --state.scheme=hash /execution/genesis.json + volumes: + - ./l1-geth/execution:/execution + - ./l1-geth/execution/genesis.json:/execution/genesis.json + depends_on: + l1-fix-genesis-fork-times: + condition: service_completed_successfully + l1-geth-remove-db: + condition: service_completed_successfully + + l1-geth: + image: "ethereum/client-go:v1.15.11" + container_name: l1-geth + command: + - --http + - --http.api=eth,net,web3,debug,admin + - --http.addr=0.0.0.0 + - --http.corsdomain=* + - --http.vhosts=* + - --ws + - --ws.api=eth,net,web3,debug + - --ws.addr=0.0.0.0 + - --ws.origins=* + - --authrpc.vhosts=* + - --authrpc.addr=0.0.0.0 + - --authrpc.jwtsecret=/execution/jwtsecret + - --datadir=/execution + - --allow-insecure-unlock + - --unlock=0x123463a4b065722e99115d6c222f267d9cabb524 + - --password=/execution/geth_password.txt + - --nodiscover + - --syncmode=full + - --gcmode=archive + - --ipcdisable + - --rpc.allow-unprotected-txs + - --verbosity=3 + ports: + - 8551:8551 + - 8545:8545 + - 8546:8546 + depends_on: + l1-geth-genesis: + condition: service_completed_successfully + volumes: + - ./l1-geth/execution:/execution + - ./l1-geth/execution/jwtsecret:/execution/jwtsecret + - ./l1-geth/execution/geth_password.txt:/execution/geth_password.txt + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] + interval: 10s + timeout: 5s + retries: 5 + + l1-beacon-chain: + image: "gcr.io/prysmaticlabs/prysm/beacon-chain:v5.1.2" + container_name: l1-beacon-chain + command: + - --datadir=/consensus/beacondata + - --min-sync-peers=0 + - --genesis-state=/consensus/genesis.ssz + - --bootstrap-node= + - --interop-eth1data-votes + - --chain-config-file=/consensus/config.yml + - --contract-deployment-block=0 + - --chain-id=${CHAIN_ID:-1337} + - --rpc-host=0.0.0.0 + - --grpc-gateway-host=0.0.0.0 + - --execution-endpoint=http://l1-geth:8551 + - --accept-terms-of-use + - --jwt-secret=/execution/jwtsecret + - --suggested-fee-recipient=0x123463a4b065722e99115d6c222f267d9cabb524 + - --minimum-peers-per-subnet=0 + - --enable-debug-rpc-endpoints + - --verbosity=info + depends_on: + l1-create-beacon-chain-genesis: + condition: service_completed_successfully + l1-geth: + condition: service_healthy + ports: + - 4000:4000 + - 3500:3500 + - 18080:8080 + - 6060:6060 + - 19090:9090 + volumes: + - ./l1-geth/consensus:/consensus + - ./l1-geth/execution:/execution + - ./l1-geth/execution/jwtsecret:/execution/jwtsecret + + l1-validator: + image: "gcr.io/prysmaticlabs/prysm/validator:v5.1.2" + container_name: l1-validator + command: + - --beacon-rpc-provider=l1-beacon-chain:4000 + - --datadir=/consensus/validatordata + - --accept-terms-of-use + - --interop-num-validators=4 + - --interop-start-index=0 + - --chain-config-file=/consensus/config.yml + - --verbosity=info + depends_on: + l1-beacon-chain: + condition: service_started + volumes: + - ./l1-geth/consensus:/consensus + + op-geth-seq: + image: "${OP_GETH_IMAGE_TAG}" + container_name: op-geth-seq + entrypoint: geth + volumes: + - ./data/op-geth-seq:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/test.seq.config.toml:/config.toml + ports: + - "8123:8545" + - "7546:7546" + - "8552:8552" + - "30303:30303" + - "30303:30303/udp" + - "9090:9090" # pprof port + command: + - --verbosity=3 + - --datadir=/datadir + - --db.engine=${DB_ENGINE} + - --config=/config.toml + - --gcmode=archive + - --rollup.disabletxpoolgossip=false + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-geth-rpc: + image: "${OP_GETH_IMAGE_TAG}" + container_name: op-geth-rpc + entrypoint: geth + volumes: + - ./data/op-geth-rpc:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/test.rpc.config.toml:/config.toml + ports: + - "8124:8545" + - "30304:30303" + - "30304:30303/udp" + command: + - --verbosity=3 + - --datadir=/datadir + - --db.engine=${DB_ENGINE} + - --config=/config.toml + - --gcmode=archive + # - --rollup.sequencerhttp=http://op-geth-seq:8545 + - --rollup.enabletxpooladmission + + op-seq: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-seq + volumes: + - ./config-op/rollup.json:/rollup.json + - ./config-op/jwt.txt:/jwt.txt + - ./data/op-seq:/data + - ./l1-geth/execution/:/l1/ + ports: + - "9545:9545" + - "7070:7070" + - "9223:9223" + - "9223:9223/udp" + - "9091:9091" # pprof port + command: + - /app/op-node/bin/op-node + - --log.level=debug + - --l2=http://op-geth-seq:8552 + - --l2.jwt-secret=/jwt.txt + - --sequencer.enabled + - --sequencer.l1-confs=5 + - --verifier.l1-confs=1 + - --rollup.config=/rollup.json + - --rpc.addr=0.0.0.0 + - --p2p.listen.tcp=9223 + - --p2p.listen.udp=9223 + - --p2p.priv.raw=e054b5748fb29a82994ea170af9e6094a163a0d11308dea91a38744c4e7c94da + - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db + - --p2p.discovery.path=/data/p2p/opnode_discovery_db + - --p2p.no-discovery + - --rpc.enable-admin + - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} + - --l1=${L1_RPC_URL_IN_DOCKER} + - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} + - --l1.rpckind=standard + - --rollup.l1-chain-config=/l1/genesis.json + - --safedb.path=/data/safedb + - --conductor.enabled=${CONDUCTOR_ENABLED:-false} # 默认关闭 + - --conductor.rpc=http://op-conductor:8547 + - --pprof.enabled + - --pprof.addr=0.0.0.0 + - --pprof.port=9091 + depends_on: + op-geth-seq: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-rpc: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-rpc + volumes: + - ./data/op-rpc:/data + - ./config-op/rollup.json:/rollup.json + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/oprpc_p2p_priv.txt:/opnode_p2p_priv.txt + - ./l1-geth/execution/genesis.json:/l1-genesis.json + ports: + - "9555:9545" + command: + - /app/op-node/bin/op-node + - --log.level=debug + - --l2=http://op-geth-rpc:8552 + - --l2.jwt-secret=/jwt.txt + - --sequencer.enabled=false + - --verifier.l1-confs=1 + - --rollup.config=/rollup.json + - --rpc.addr=0.0.0.0 + - --rpc.port=9545 + - --p2p.listen.tcp=9223 + - --p2p.listen.udp=9223 + - --p2p.priv.raw=604557d042fbea9ed42f46c0c95c346a932b6a5ef0c0dd07a00dbf95801a2510 + - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db + - --p2p.discovery.path=/data/p2p/opnode_discovery_db + - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65 + - --p2p.no-discovery + - --rpc.enable-admin=true + - --l1=${L1_RPC_URL_IN_DOCKER} + - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} + - --l1.rpckind=standard + - --rollup.l1-chain-config=/l1-genesis.json + - --safedb.path=/data/safedb + depends_on: + - op-geth-rpc + + op-conductor: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-conductor + volumes: + - ./data/op-conductor:/data + - ./config-op/rollup.json:/rollup.json + ports: + - "8547:8547" # RPC port + - "50050:50050" # Consensus port + command: + - /app/op-conductor/bin/op-conductor + - --log.level=debug + # already existed service + - --node.rpc=http://op-seq:9545 + - --execution.rpc=http://op-geth-seq:8545 + # Raft Config + - --raft.server.id=conductor-1 + - --raft.storage.dir=/data/raft + - --raft.bootstrap=true + - --consensus.addr=0.0.0.0 + - --consensus.port=50050 + - --consensus.advertised=op-conductor:50050 + # RPC Config + - --rpc.addr=0.0.0.0 + - --rpc.port=8547 + - --rpc.enable-proxy=true + # Healthcheck Config + - --healthcheck.interval=1 + - --healthcheck.unsafe-interval=3 + - --healthcheck.min-peer-count=1 + - --rollup.config=/rollup.json + depends_on: + op-seq: + condition: service_healthy + op-geth-seq: + condition: service_healthy + + op-batcher: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-batcher + command: + - /app/op-batcher/bin/op-batcher + - --log.level=debug + - --l2-eth-rpc=http://op-geth-seq:8545 + - --rollup-rpc=http://op-seq:9545 + - --poll-interval=1s + - --sub-safety-margin=6 + - --num-confirmations=1 + - --safe-abort-nonce-too-low-count=3 + - --resubmission-timeout=30s + - --rpc.addr=0.0.0.0 + - --rpc.port=8548 + - --rpc.enable-admin + - --max-channel-duration=25 + - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} + - --private-key=${OP_BATCHER_PRIVATE_KEY} + - --throttle.block-size-upper-limit=1300000 + - -data-availability-type=auto + depends_on: + - op-seq + + op-proposer: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-proposer + environment: + - DISPUTE_GAME_FACTORY_ADDRESS=${DISPUTE_GAME_FACTORY_ADDRESS} + command: + - /app/op-proposer/bin/op-proposer + - --log.level=debug + - --poll-interval=2s + - --rpc.port=8560 + - --rollup-rpc=http://op-seq:9545 + - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} + - --proposal-interval=1m + - --private-key=${OP_PROPOSER_PRIVATE_KEY} + - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} + - --game-type=${GAME_TYPE:-0} + - --allow-non-finalized + - --genesis-height=${FORK_BLOCK} + depends_on: + - op-batcher + + op-challenger: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-challenger + environment: + - L1_RPC_URL_IN_DOCKER=${L1_RPC_URL_IN_DOCKER} + - L1_BEACON_URL_IN_DOCKER=${L1_BEACON_URL_IN_DOCKER} + - DISPUTE_GAME_FACTORY_ADDRESS=${DISPUTE_GAME_FACTORY_ADDRESS} + volumes: + - ./data/cannon-data:/data + - ./config-op/rollup.json:/rollup.json + - ./config-op/genesis.json:/l2-genesis.json + depends_on: + - op-seq + command: + - /app/op-challenger/bin/op-challenger + - --log.level=debug + - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} + - --l1-beacon=${L1_BEACON_URL_IN_DOCKER} + - --l2-eth-rpc=http://op-geth-seq:8545 + - --rollup-rpc=http://op-seq:9545 + - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} + - --cannon-bin=/app/cannon/bin/cannon + - --cannon-server=/data/op-program + - --cannon-prestate=/data/prestate-mt64.bin.gz + - --cannon-rollup-config=/rollup.json + - --cannon-l2-genesis=/l2-genesis.json + - --private-key=${OP_PROPOSER_PRIVATE_KEY} + - --trace-type=cannon,permissioned + - --datadir=/data + - --game-window=${GAME_WINDOW}s + + op-dispute-mon: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-dispute-mon + depends_on: + - op-challenger + - op-proposer + command: + - /app/op-dispute-mon/bin/op-dispute-mon + - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} + - --rollup-rpc=http://op-seq:9545 + - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} + - --game-window=${GAME_WINDOW}s + - --honest-actors=${PROPOSER_ADDRESS} + + op-geth-seq2: + image: "${OP_GETH_IMAGE_TAG}" + container_name: op-geth-seq2 + entrypoint: geth + volumes: + - ./data/op-geth-seq2:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/test.seq.config.toml:/config.toml + ports: + - "8223:8545" + - "30305:30303" + - "30305:30303/udp" + command: + - --verbosity=3 + - --datadir=/datadir + - --db.engine=${DB_ENGINE} + - --config=/config.toml + - --gcmode=archive + - --rollup.disabletxpoolgossip=false + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-seq2: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-seq2 + volumes: + - ./config-op/rollup.json:/rollup.json + - ./config-op/jwt.txt:/jwt.txt + - ./data/op-seq2:/data + - ./l1-geth/execution/genesis.json:/l1-genesis.json + ports: + - "9546:9545" +# - "7070:7070" + - "9224:9223" + - "9224:9223/udp" + command: + - /app/op-node/bin/op-node + - --log.level=info + - --l2=http://op-geth-seq2:8552 + - --l2.jwt-secret=/jwt.txt + - --sequencer.enabled + - --sequencer.stopped + - --sequencer.l1-confs=5 + - --verifier.l1-confs=1 + - --rollup.config=/rollup.json + - --rpc.addr=0.0.0.0 + - --p2p.listen.tcp=9223 + - --p2p.listen.udp=9223 + - --p2p.priv.raw=cff9dac7588f5e6755a72d1e5b5001da3d0f8c06c4242b27d67eb5df4216bd93 + - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db + - --p2p.discovery.path=/data/p2p/opnode_discovery_db + - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65,/dns4/op-seq3/tcp/9223/p2p/16Uiu2HAmRDGMm3UUrP8CfQ3YQo9aaXEXFXA7LeFNztdPMNK5moyD + - --p2p.no-discovery + - --rpc.enable-admin + - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} + - --l1=${L1_RPC_URL_IN_DOCKER} + - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} + - --l1.rpckind=standard + - --rollup.l1-chain-config=/l1-genesis.json + - --safedb.path=/data/safedb + - --conductor.enabled=${CONDUCTOR_ENABLED:-false} + - --conductor.rpc=http://op-conductor2:8547 + depends_on: + op-geth-seq2: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-conductor2: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-conductor2 + volumes: + - ./data/op-conductor2:/data + - ./config-op/rollup.json:/rollup.json + ports: + - "8548:8547" # RPC port + - "50051:50050" # Consensus port + command: + - /app/op-conductor/bin/op-conductor + - --log.level=debug + # already existed service + - --node.rpc=http://op-seq2:9545 + - --execution.rpc=http://op-geth-seq2:8545 + # Raft Config + - --raft.server.id=conductor-2 + - --raft.storage.dir=/data/raft + - --raft.bootstrap=false + - --consensus.addr=0.0.0.0 + - --consensus.port=50050 + - --consensus.advertised=op-conductor2:50050 + # RPC Config + - --rpc.addr=0.0.0.0 + - --rpc.port=8547 + - --rpc.enable-proxy=true + # Healthcheck Config + - --healthcheck.interval=1 + - --healthcheck.unsafe-interval=3 + - --healthcheck.min-peer-count=1 + - --rollup.config=/rollup.json + depends_on: + op-seq2: + condition: service_healthy + op-geth-seq2: + condition: service_healthy + + op-geth-seq3: + image: "${OP_GETH_IMAGE_TAG}" + container_name: op-geth-seq3 + entrypoint: geth + volumes: + - ./data/op-geth-seq3:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/test.seq.config.toml:/config.toml + ports: + - "8323:8545" + - "30306:30303" + - "30306:30303/udp" + command: + - --verbosity=3 + - --datadir=/datadir + - --db.engine=${DB_ENGINE} + - --config=/config.toml + - --gcmode=archive + - --rollup.disabletxpoolgossip=false + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-seq3: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-seq3 + volumes: + - ./config-op/rollup.json:/rollup.json + - ./config-op/jwt.txt:/jwt.txt + - ./data/op-seq3:/data + - ./l1-geth/execution/genesis.json:/l1-genesis.json + ports: + - "9547:9545" +# - "7070:7070" + - "9225:9223" + - "9225:9223/udp" + command: + - /app/op-node/bin/op-node + - --log.level=info + - --l2=http://op-geth-seq3:8552 + - --l2.jwt-secret=/jwt.txt + - --sequencer.enabled + - --sequencer.stopped + - --sequencer.l1-confs=5 + - --verifier.l1-confs=1 + - --rollup.config=/rollup.json + - --rpc.addr=0.0.0.0 + - --p2p.listen.tcp=9223 + - --p2p.listen.udp=9223 + - --p2p.priv.raw=10785157e7c98628e5e47c3d9b8ebbd12525c45f1554b4a39652b5ce02bb29dc + - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db + - --p2p.discovery.path=/data/p2p/opnode_discovery_db + - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65,/dns4/op-seq2/tcp/9223/p2p/16Uiu2HAmDTjVuEF6V9DccV1JhrHg7DYc5SKm3bw2T75kAFPsGuSp + - --p2p.no-discovery + - --rpc.enable-admin + - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} + - --l1=${L1_RPC_URL_IN_DOCKER} + - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} + - --l1.rpckind=standard + - --rollup.l1-chain-config=/l1-genesis.json + - --safedb.path=/data/safedb + - --conductor.enabled=${CONDUCTOR_ENABLED:-false} + - --conductor.rpc=http://op-conductor3:8547 + depends_on: + op-geth-seq3: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + + op-conductor3: + image: "${OP_STACK_IMAGE_TAG}" + container_name: op-conductor3 + volumes: + - ./data/op-conductor3:/data + - ./config-op/rollup.json:/rollup.json + ports: + - "8549:8547" # RPC port + - "50052:50050" # Consensus port + command: + - /app/op-conductor/bin/op-conductor + - --log.level=debug + # already existed service + - --node.rpc=http://op-seq3:9545 + - --execution.rpc=http://op-geth-seq3:8545 + # Raft Config + - --raft.server.id=conductor-3 + - --raft.storage.dir=/data/raft + - --raft.bootstrap=false + - --consensus.addr=0.0.0.0 + - --consensus.port=50050 + - --consensus.advertised=op-conductor3:50050 + # RPC Config + - --rpc.addr=0.0.0.0 + - --rpc.port=8547 + - --rpc.enable-proxy=true + # Healthcheck Config + - --healthcheck.interval=1 + - --healthcheck.unsafe-interval=3 + - --healthcheck.min-peer-count=1 + - --rollup.config=/rollup.json + depends_on: + op-seq3: + condition: service_healthy + op-geth-seq3: + condition: service_healthy diff --git a/test-pp-op/dockerfile/Dockerfile-cdk-erigon b/test-pp-op/dockerfile/Dockerfile-cdk-erigon new file mode 100644 index 0000000000000..34996601bce97 --- /dev/null +++ b/test-pp-op/dockerfile/Dockerfile-cdk-erigon @@ -0,0 +1,87 @@ +# syntax = docker/dockerfile:1.2 +FROM docker.io/library/golang:1.24-alpine3.21 AS builder + +RUN apk --no-cache add build-base linux-headers git bash ca-certificates libstdc++ + +WORKDIR /app +ADD go.mod go.mod +ADD go.sum go.sum +ADD erigon-lib/go.mod erigon-lib/go.mod +ADD erigon-lib/go.sum erigon-lib/go.sum + +RUN go mod download +ADD . . + +RUN --mount=type=cache,target=/root/.cache \ + --mount=type=cache,target=/tmp/go-build \ + --mount=type=cache,target=/go/pkg/mod \ + make BUILD_TAGS=nosqlite,noboltdb,nosilkworm cdk-erigon + +RUN --mount=type=cache,target=/root/.cache \ + --mount=type=cache,target=/tmp/go-build \ + --mount=type=cache,target=/go/pkg/mod \ + make smt-db-split + +FROM docker.io/library/golang:1.24-alpine3.21 AS tools-builder +RUN apk --no-cache add build-base linux-headers git bash ca-certificates libstdc++ +WORKDIR /app + +ADD Makefile Makefile +ADD tools.go tools.go +ADD go.mod go.mod +ADD go.sum go.sum +ADD erigon-lib/go.mod erigon-lib/go.mod +ADD erigon-lib/go.sum erigon-lib/go.sum + +RUN mkdir -p /app/build/bin + +RUN --mount=type=cache,target=/root/.cache \ + --mount=type=cache,target=/tmp/go-build \ + --mount=type=cache,target=/go/pkg/mod \ + make db-tools + +FROM docker.io/library/alpine:3.17 + +# install required runtime libs, along with some helpers for debugging +RUN apk add --no-cache ca-certificates libstdc++ tzdata +RUN apk add --no-cache curl jq bind-tools +RUN apk add --no-cache perl perl-utils +RUN apk add --no-cache build-base git && \ + git clone https://github.com/hoytech/vmtouch.git && \ + cd vmtouch && \ + make && \ + install -m 755 vmtouch /usr/local/bin/ + +RUN mkdir -p ~/.local/share/erigon +WORKDIR /home/erigon + +## then give each binary its own layer +COPY --from=tools-builder /app/build/bin/mdbx_copy /usr/local/bin/mdbx_copy +COPY --from=builder /app/build/bin/cdk-erigon /usr/local/bin/cdk-erigon +COPY --from=builder /app/build/bin/smt-db-split /usr/local/bin/smt-db-split +COPY --from=builder /app/cmd/smt-db-split/prepare-db-split.sh /usr/local/bin/prepare-db-split.sh + +EXPOSE 8545 \ + 8551 \ + 8546 \ + 30303 \ + 30303/udp \ + 42069 \ + 42069/udp \ + 8080 \ + 9090 \ + 6060 + +# https://github.com/opencontainers/image-spec/blob/main/annotations.md +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION +LABEL org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.description="Erigon ZKEVM Client" \ + org.label-schema.name="ZKEVM Erigon" \ + org.label-schema.schema-version="1.0" \ + org.label-schema.url="https://torquem.ch" \ + org.label-schema.vcs-ref=$VCS_REF \ + org.label-schema.vcs-url="https://github.com/0xPolygonHermez/cdk-erigon.git" \ + org.label-schema.vendor="Torquem" \ + org.label-schema.version=$VERSION diff --git a/test-pp-op/dockerfile/Dockerfile.migrate b/test-pp-op/dockerfile/Dockerfile.migrate new file mode 100644 index 0000000000000..0a22581ecfef8 --- /dev/null +++ b/test-pp-op/dockerfile/Dockerfile.migrate @@ -0,0 +1,27 @@ +# Support setting various labels on the final image +ARG COMMIT="" +ARG VERSION="" +ARG BUILDNUM="" + +# Build Geth in a stock Go builder container +FROM golang:1.24-alpine AS builder + +RUN go env -w CGO_ENABLED=1 +RUN apk add --no-cache make gcc musl-dev linux-headers git + +WORKDIR /app + +COPY tmp/op-geth op-geth +RUN cd op-geth && make geth + +COPY . test-pp-op +RUN rm -rf test-pp-op/tmp + +FROM alpine:latest + +RUN apk add --no-cache jq bash ca-certificates libgcc libstdc++ + +COPY --from=builder /app/op-geth/build/bin/geth /usr/local/bin/geth +COPY --from=builder /app/test-pp-op /app/test-pp-op + +WORKDIR /app diff --git a/test-pp-op/dockerfile/Dockerfile.repro b/test-pp-op/dockerfile/Dockerfile.repro new file mode 100644 index 0000000000000..a092b7609d85e --- /dev/null +++ b/test-pp-op/dockerfile/Dockerfile.repro @@ -0,0 +1,60 @@ +ARG GO_VERSION=1.23.8-alpine3.21 +ARG EXPORT_TARGET=current +# we need a separate stage for src so we can build a service provides prestates for unnanounced chains +FROM golang:${GO_VERSION} AS builder +#FROM src AS builder +ARG EXPORT_TARGET +# We avoid copying the full .git dir into the build for just some metadata. +# Instead, specify: +# --build-arg GIT_COMMIT=$(git rev-parse HEAD) +# --build-arg GIT_DATE=$(git show -s --format='%ct') +ARG GIT_COMMIT +ARG GIT_DATE + +ARG CANNON_VERSION=v0.0.0 +ARG OP_PROGRAM_VERSION=v0.0.0 + +ARG TARGETOS TARGETARCH + +WORKDIR /app +RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build just \ + -d /app/op-program \ + -f /app/op-program/repro.justfile \ + GOOS="$TARGETOS" \ + GOARCH="$TARGETARCH" \ + GIT_COMMIT="$GIT_COMMIT" \ + GIT_DATE="$GIT_DATE" \ + CANNON_VERSION="$CANNON_VERSION" \ + OP_PROGRAM_VERSION="$OP_PROGRAM_VERSION" \ + "build-${EXPORT_TARGET}" + + +FROM scratch AS export-current +# Cannon64 files +COPY --from=builder /app/op-program/bin/op-program-client64.elf . +COPY --from=builder /app/op-program/bin/meta-mt64.json . +COPY --from=builder /app/op-program/bin/prestate-mt64.bin.gz . +COPY --from=builder /app/op-program/bin/prestate-proof-mt64.json . +# Interop files +COPY --from=builder ./app/op-program/bin/op-program-client-interop.elf . +COPY --from=builder /app/op-program/bin/meta-interop.json . +COPY --from=builder /app/op-program/bin/prestate-interop.bin.gz . +COPY --from=builder /app/op-program/bin/prestate-proof-interop.json . + +FROM scratch AS export-next +# Cannon64 Next VM files +COPY --from=builder /app/op-program/bin/op-program-client64.elf ./op-program-client-next64.elf +COPY --from=builder /app/op-program/bin/meta-mt64Next.json . +COPY --from=builder /app/op-program/bin/prestate-mt64Next.bin.gz . +COPY --from=builder /app/op-program/bin/prestate-proof-mt64Next.json . +# Interop Next files +COPY --from=builder ./app/op-program/bin/op-program-client-interop.elf ./op-program-client-interopNext.elf +COPY --from=builder /app/op-program/bin/meta-interopNext.json . +COPY --from=builder /app/op-program/bin/prestate-interopNext.bin.gz . +COPY --from=builder /app/op-program/bin/prestate-proof-interopNext.json . + +# Exports files to the specified output location. +# Writing files to host requires buildkit to be enabled. +# e.g. `BUILDKIT=1 docker build ...` +# Final export stage — dynamically selected +FROM export-${EXPORT_TARGET} AS export-stage diff --git a/test-pp-op/dockerfile/Dockerfile.repro-builder b/test-pp-op/dockerfile/Dockerfile.repro-builder new file mode 100644 index 0000000000000..22d89a1417034 --- /dev/null +++ b/test-pp-op/dockerfile/Dockerfile.repro-builder @@ -0,0 +1,19 @@ +# For caching deps to build reproducible prestate images on ECS. +ARG GO_VERSION=1.23.8-alpine3.21 +ARG EXPORT_TARGET=current +FROM golang:${GO_VERSION} AS src + +RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash just + +COPY ./go.mod /app/go.mod +COPY ./go.sum /app/go.sum +COPY ./op-geth /app/op-geth + +WORKDIR /app + +RUN echo "go mod cache: $(go env GOMODCACHE)" +RUN echo "go build cache: $(go env GOCACHE)" + +RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build go mod download + +COPY . /app diff --git a/test-pp-op/init-erigon.sh b/test-pp-op/init-erigon.sh new file mode 100755 index 0000000000000..ff4169d63b696 --- /dev/null +++ b/test-pp-op/init-erigon.sh @@ -0,0 +1,213 @@ +#!/bin/bash +set -e +set -x + +# ============================================================================= +# Init Erigon Chain +# ============================================================================= +# The script is a comprehensive initialization script for setting up a local XLayer Erigon +# development environment. It handles contract deployment, configuration generation, and system setup for a ZK-EVM rollup test environment. +# + + + +source .env +source utils.sh + +git checkout config/* + +if [ ! -d "tmp/xlayer-erigon" ]; then + echo "ERROR: tmp/xlayer-erigon directory does not exist!" + echo "Please ensure the xlayer-erigon directory is present before running this script." + echo "the hack cmd is required" + exit 1 +fi + +mkdir -p $TMP_DIR +cd $TMP_DIR +if [ -d "./xlayer-contracts" ]; then + cd xlayer-contracts + current_branch=$(git branch --show-current) + if [ "$current_branch" != "zjg/v11.0.0-rc.0-op-v1" ]; then + echo "Switching to correct branch: zjg/v11.0.0-rc.0-op-v1" + git fetch origin + git checkout zjg/v11.0.0-rc.0-op-v1 + git pull origin zjg/v11.0.0-rc.0-op-v1 + else + echo "Updating existing repository..." + git pull origin zjg/v11.0.0-rc.0-op-v1 + fi + echo "Cleaning contract repository (selective)..." + rm -rf artifacts cache .openzeppelin node_modules + rm -f deployment/v2/deploy_output.json deployment/v2/create_rollup_output_*.json deployment/v2/genesis.json .env + cd .. +else + echo "Cloning contract repository..." + git clone -b zjg/v11.0.0-rc.0-op-v1 https://github.com/okx/xlayer-contracts.git +fi + +cd $TMP_DIR/xlayer-contracts + +echo "Creating .env file..." +cat > .env << EOF +MNEMONIC="$DEPLOYER_MNEMONIC" +INFURA_PROJECT_ID="000" +ETHERSCAN_API_KEY="000" +EOF + +cd deployment/v2 + +echo "Creating create_rollup_parameters.json..." +cat > create_rollup_parameters.json << EOF +{ + "adminZkEVM": "$DEPLOYER_ADDRESS", + "chainID": 195, + "consensusContract": "PolygonPessimisticConsensus", + "dataAvailabilityProtocol": "PolygonDataCommittee", + "deployerPvtKey": "", + "description": "description", + "forkID": 13, + "gasTokenAddress":"$OKB_TOKEN_ADDRESS", + "maxFeePerGas": "", + "maxPriorityFeePerGas": "", + "multiplierGas": "", + "networkName": "xlayer", + "realVerifier": false, + "trustedSequencer": "$SEQUENCER_ADDRESS", + "trustedSequencerURL": "$L2_PP_SEQ_URL_IN_DOCKER", + "trustedAggregator":"$AGGREGATOR_ADDRESS", + "programVKey": "$PP_VKEY" +} +EOF + +echo "Creating deploy_parameters.json..." +cat > deploy_parameters.json << EOF +{ + "admin": "$DEPLOYER_ADDRESS", + "deployerPvtKey": "", + "emergencyCouncilAddress": "$DEPLOYER_ADDRESS", + "initialZkEVMDeployerOwner": "$DEPLOYER_ADDRESS", + "maxFeePerGas": "", + "maxPriorityFeePerGas": "", + "minDelayTimelock": 60, + "multiplierGas": "", + "description": "description", + "pendingStateTimeout": 604799, + "polTokenAddress": "$OKB_TOKEN_ADDRESS", + "salt": "0x0000000000000000000000000000000000000000000000000000000000000001", + "timelockAdminAddress": "$DEPLOYER_ADDRESS", + "trustedSequencer": "$SEQUENCER_ADDRESS", + "trustedSequencerURL": "$L2_PP_SEQ_URL_IN_DOCKER", + "trustedAggregator": "$AGGREGATOR_ADDRESS", + "trustedAggregatorTimeout": 604799, + "forkID": 13, + "test": true, + "ppVKey": "$PP_VKEY", + "ppVKeySelector": "0x00000001", + "realVerifier": false, + "defaultAdminAddress": "$DEPLOYER_ADDRESS", + "aggchainDefaultVKeyRoleAddress": "$DEPLOYER_ADDRESS", + "addRouteRoleAddress": "$DEPLOYER_ADDRESS", + "freezeRouteRoleAddress": "$DEPLOYER_ADDRESS", + "zkEVMDeployerAddress": "$DEPLOYER_ADDRESS" +} +EOF + +echo "Compiling contracts..." +cd ../../ +npm i +npm run deploy:v2:localhost + +cd "$ROOT_DIR" +mkdir -p $TMP_DIR/pp-deployed +ROLLUP_OUTPUT_PATH=$(find $TMP_DIR/xlayer-contracts/deployment/v2 -name "create_rollup_output_*.json" | sort -r | head -n 1) +cp -rf $ROLLUP_OUTPUT_PATH $TMP_DIR/pp-deployed/create_rollup_output.json +cp -rf $TMP_DIR/xlayer-contracts/deployment/v2/create_rollup_parameters.json $TMP_DIR/pp-deployed/ +cp -rf $TMP_DIR/xlayer-contracts/deployment/v2/deploy_parameters.json $TMP_DIR/pp-deployed/ +cp -rf $TMP_DIR/xlayer-contracts/deployment/v2/deploy_output.json $TMP_DIR/pp-deployed/ +cp -rf $TMP_DIR/xlayer-contracts/deployment/v2/genesis.json $TMP_DIR/pp-deployed/ +ROLLUP_OUTPUT_PATH="$TMP_DIR/pp-deployed/create_rollup_output.json" +DEPLOY_OUTPUT_PATH="$TMP_DIR/pp-deployed/deploy_output.json" + +# echo "Transferring ERC20 token to Sequencer..." +# cast send --legacy --from $SEQUENCER_ADDRESS --private-key $SEQUENCER_PRIVATE_KEY $TOKEN_ADDRESS "transfer(address,uint256)" $SEQUENCER_ADDRESS 1000 + +echo "Setting Trusted Sequencer URL..." +POE_ADDRESS=$(cat $ROLLUP_OUTPUT_PATH | grep -o '"rollupAddress": "[^"]*"' | cut -d'"' -f4) +BRIDGE_ADDRESS=$(cat $DEPLOY_OUTPUT_PATH | grep -o '"polygonZkEVMBridgeAddress": "[^"]*"' | cut -d'"' -f4) +GENESIS_VALUE=$(cat $ROLLUP_OUTPUT_PATH | grep -o '"genesis": "[^"]*"' | cut -d'"' -f4) +TIMESTAMP_VALUE=$(cat $ROLLUP_OUTPUT_PATH | grep -o '"timestamp": [0-9]*' | cut -d' ' -f2) +L1_FIRST_BLOCK=$(cat $DEPLOY_OUTPUT_PATH | grep -o '"upgradeToULxLyBlockNumber": [0-9]*' | cut -d' ' -f2) +L1_SECOND_BLOCK=$(cat $ROLLUP_OUTPUT_PATH | grep -o '"createRollupBlockNumber": [0-9]*' | cut -d' ' -f2) +ROLLUP_MANAGER_ADDRESS=$(grep -o '"polygonRollupManagerAddress": "[^"]*"' "$DEPLOY_OUTPUT_PATH" | cut -d'"' -f4) +GLOBAL_EXIT_ROOT_ADDRESS=$(grep -o '"polygonZkEVMGlobalExitRootAddress": "[^"]*"' "$DEPLOY_OUTPUT_PATH" | cut -d'"' -f4) +echo "Poe address from JSON: $POE_ADDRESS" +echo "Bridge address from JSON: $BRIDGE_ADDRESS" +echo "Genesis value from JSON: $GENESIS_VALUE" +echo "Timestamp value from JSON: $TIMESTAMP_VALUE" +echo "L1FirstBlock value from JSON: $L1_FIRST_BLOCK" +echo "L1SecondBlock value from JSON: $L1_SECOND_BLOCK" +echo "RollupManagerAddress value from JSON: $ROLLUP_MANAGER_ADDRESS" +echo "GlobalExitRootAddress value from JSON: $GLOBAL_EXIT_ROOT_ADDRESS" + +echo "Using POE address from JSON: $POE_ADDRESS" +cast send --legacy --from $DEPLOYER_ADDRESS --private-key $DEPLOYER_PRIVATE_KEY $POE_ADDRESS "setTrustedSequencerURL(string)" "$L2_PP_RPC_URL_IN_DOCKER" + +cast send --legacy --from $DEPLOYER_ADDRESS --private-key $DEPLOYER_PRIVATE_KEY $BRIDGE_ADDRESS 'function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) returns()' 7 0x0000000000000000000000000000000000000000 0 0x0000000000000000000000000000000000000000 true 0x + +echo "Generating configuration files..." + +cd "${PWD_DIR}/tmp/xlayer-erigon" +go install ./cmd/hack/allocs +cd ${PWD_DIR} +GO_PATH=$(go env GOPATH) +#TODO: make this adapt to multi environment, mac, linux +${GO_PATH}/bin/allocs $TMP_DIR/xlayer-contracts/deployment/v2/genesis.json +mv allocs.json $PWD_DIR/config/dynamic-mynetwork-allocs.json + +cat > $PWD_DIR/config/dynamic-mynetwork-conf.json << EOF +{ + "root": "$GENESIS_VALUE", + "timestamp": $TIMESTAMP_VALUE, + "gasLimit": 0, + "difficulty": 0 +} +EOF +echo "dynamic-mynetwork-conf.json file updated" + +echo "Updating test.erigon.seq.config.yaml file..." +ERIGON_SEQ_CONFIG_FILE="${PWD_DIR}/config/test.erigon.seq.config.yaml" +sed_inplace "s|zkevm.address-zkevm: \"[^\"]*\"|zkevm.address-zkevm: \"$POE_ADDRESS\"|g" "$ERIGON_SEQ_CONFIG_FILE" +sed_inplace "s|zkevm.address-rollup: \"[^\"]*\"|zkevm.address-rollup: \"$ROLLUP_MANAGER_ADDRESS\"|g" "$ERIGON_SEQ_CONFIG_FILE" +sed_inplace "s|zkevm.address-ger-manager: \"[^\"]*\"|zkevm.address-ger-manager: \"$GLOBAL_EXIT_ROOT_ADDRESS\"|g" "$ERIGON_SEQ_CONFIG_FILE" +sed_inplace "s|zkevm.l1-first-block: [0-9]*|zkevm.l1-first-block: $L1_FIRST_BLOCK|g" "$ERIGON_SEQ_CONFIG_FILE" + +mkdir -p "$PWD_DIR/config" +jq '.firstBatchData' "$ROLLUP_OUTPUT_PATH" > "$PWD_DIR/config/first-batch-config.json" +echo "Successfully exported firstBatchData to $PWD_DIR/config/first-batch-config.json" + +echo "Updating parameter in aggkit.toml..." +CONFIG_FILE="${PWD_DIR}/config/aggkit.toml" +sed_inplace "s|polygonBridgeAddr = \"[^\"]*\"|polygonBridgeAddr = \"$BRIDGE_ADDRESS\"|" "$CONFIG_FILE" +sed_inplace "s|BridgeAddr = \"[^\"]*\"|BridgeAddr = \"$BRIDGE_ADDRESS\"|" "$CONFIG_FILE" +sed_inplace "s|BridgeAddrL2 = \"[^\"]*\"|BridgeAddrL2 = \"$BRIDGE_ADDRESS\"|" "$CONFIG_FILE" +sed_inplace "s|rollupCreationBlockNumber = \"[^\"]*\"|rollupCreationBlockNumber = \"$L1_FIRST_BLOCK\"|" "$CONFIG_FILE" +sed_inplace "s|rollupManagerCreationBlockNumber = \"[^\"]*\"|rollupManagerCreationBlockNumber = \"$L1_SECOND_BLOCK\"|" "$CONFIG_FILE" +sed_inplace "s|genesisBlockNumber = \"[^\"]*\"|genesisBlockNumber = \"$L1_FIRST_BLOCK\"|" "$CONFIG_FILE" +sed_inplace "s|polygonRollupManagerAddress = \"[^\"]*\"|polygonRollupManagerAddress = \"$ROLLUP_MANAGER_ADDRESS\"|" "$CONFIG_FILE" +sed_inplace "s|polygonZkEVMGlobalExitRootAddress = \"[^\"]*\"|polygonZkEVMGlobalExitRootAddress = \"$GLOBAL_EXIT_ROOT_ADDRESS\"|" "$CONFIG_FILE" +sed_inplace "s|polygonZkEVMAddress = \"[^\"]*\"|polygonZkEVMAddress = \"$POE_ADDRESS\"|" "$CONFIG_FILE" +echo "Successfully updated contract address parameters in aggkit.toml" + +echo "Updating contract address parameters in agglayer-config.toml..." +AGGLAYER_CONFIG_FILE="${PWD_DIR}/config/agglayer-config.toml" +sed_inplace "s|rollup-manager-contract = \"[^\"]*\"|rollup-manager-contract = \"$ROLLUP_MANAGER_ADDRESS\"|" "$AGGLAYER_CONFIG_FILE" +sed_inplace "s|polygon-zkevm-global-exit-root-v2-contract = \"[^\"]*\"|polygon-zkevm-global-exit-root-v2-contract = \"$GLOBAL_EXIT_ROOT_ADDRESS\"|" "$AGGLAYER_CONFIG_FILE" +GENESIS_CONFIG_FILE="${PWD_DIR}/config/test.genesis.config.json" +sed_inplace "s|\"genesisBlockNumber\": [0-9]*|\"genesisBlockNumber\": $L1_FIRST_BLOCK|" "$GENESIS_CONFIG_FILE" +sed_inplace "s|\"rollupCreationBlockNumber\": [0-9]*|\"rollupCreationBlockNumber\": $L1_SECOND_BLOCK|" "$GENESIS_CONFIG_FILE" +sed_inplace "s|\"rollupManagerCreationBlockNumber\": [0-9]*|\"rollupManagerCreationBlockNumber\": $L1_FIRST_BLOCK|" "$GENESIS_CONFIG_FILE" +AGGLAYER_CONFIG_FILE="${PWD_DIR}/config/agglayer-config.toml" +sed_inplace "s|polygon-zkevm-global-exit-root-v2-contract = \"[^\"]*\"|polygon-zkevm-global-exit-root-v2-contract = \"$GLOBAL_EXIT_ROOT_ADDRESS\"|" "$AGGLAYER_CONFIG_FILE" + +echo "Initialization script completed!" diff --git a/test-pp-op/l1-geth/consensus/config.yml b/test-pp-op/l1-geth/consensus/config.yml new file mode 100644 index 0000000000000..cf6c353b902cd --- /dev/null +++ b/test-pp-op/l1-geth/consensus/config.yml @@ -0,0 +1,34 @@ +CONFIG_NAME: interop +PRESET_BASE: interop + +# Genesis +GENESIS_FORK_VERSION: 0x20000089 + +# Altair +ALTAIR_FORK_EPOCH: 0 +ALTAIR_FORK_VERSION: 0x20000090 + +# Merge +BELLATRIX_FORK_EPOCH: 0 +BELLATRIX_FORK_VERSION: 0x20000091 +TERMINAL_TOTAL_DIFFICULTY: 0 + +# Capella +CAPELLA_FORK_EPOCH: 0 +CAPELLA_FORK_VERSION: 0x20000092 +MAX_WITHDRAWALS_PER_PAYLOAD: 16 + +# Deneb +DENEB_FORK_EPOCH: 0 +DENEB_FORK_VERSION: 0x20000093 + +# Electra +# ELECTRA_FORK_EPOCH: 0 +ELECTRA_FORK_VERSION: 0x15000000 + +# Time parameters +SECONDS_PER_SLOT: 2 +SLOTS_PER_EPOCH: 6 + +# Deposit contract +DEPOSIT_CONTRACT_ADDRESS: 0x4242424242424242424242424242424242424242 diff --git a/test-pp-op/l1-geth/execution/genesis-raw.json b/test-pp-op/l1-geth/execution/genesis-raw.json new file mode 100644 index 0000000000000..4f0447ea58cab --- /dev/null +++ b/test-pp-op/l1-geth/execution/genesis-raw.json @@ -0,0 +1,119 @@ +{ + "config": { + "chainId": 1337, + "homesteadBlock": 0, + "daoForkSupport": true, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6, + "baseFeeUpdateFraction": 3338477 + } + } + }, + "nonce": "0x0", + "timestamp": "0x68621d8d", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000123463a4b065722e99115d6c222f267d9cabb5240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x1c9c380", + "difficulty": "0x1", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "123463a4b065722e99115d6c222f267d9cabb524": { + "balance": "0x43c33c1937564800000" + }, + "14dc79964da2c08b23698b3d3cc7ca32193d9955": { + "balance": "0x21e19e0c9bab2400000" + }, + "15d34aaf54267db7d7c367839aaf71a00a2c6a65": { + "balance": "0x21e19e0c9bab2400000" + }, + "1cbd3b2770909d4e10f157cabc84c7264073c9ec": { + "balance": "0x21e19e0c9bab2400000" + }, + "23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f": { + "balance": "0x21e19e0c9bab2400000" + }, + "2546bcd3c84621e976d8185a91a922ae77ecec30": { + "balance": "0x21e19e0c9bab2400000" + }, + "3c44cdddb6a900fa2b585dd299e03d12fa4293bc": { + "balance": "0x21e19e0c9bab2400000" + }, + "4242424242424242424242424242424242424242": { + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100b6578063621fd130146101e3578063c5f2892f14610273575b600080fd5b34801561005057600080fd5b5061009c6004803603602081101561006757600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919050505061029e565b604051808215151515815260200191505060405180910390f35b6101e1600480360360808110156100cc57600080fd5b81019080803590602001906401000000008111156100e957600080fd5b8201836020820111156100fb57600080fd5b8035906020019184600183028401116401000000008311171561011d57600080fd5b90919293919293908035906020019064010000000081111561013e57600080fd5b82018360208201111561015057600080fd5b8035906020019184600183028401116401000000008311171561017257600080fd5b90919293919293908035906020019064010000000081111561019357600080fd5b8201836020820111156101a557600080fd5b803590602001918460018302840111640100000000831117156101c757600080fd5b909192939192939080359060200190929190505050610370565b005b3480156101ef57600080fd5b506101f8610fd0565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561023857808201518184015260208101905061021d565b50505050905090810190601f1680156102655780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027f57600080fd5b50610288610fe2565b6040518082815260200191505060405180910390f35b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061036957507f85640907000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b603087879050146103cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806116ec6026913960400191505060405180910390fd5b60208585905014610428576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806116836036913960400191505060405180910390fd5b60608383905014610484576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018061175f6029913960400191505060405180910390fd5b670de0b6b3a76400003410156104e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806117396026913960400191505060405180910390fd5b6000633b9aca0034816104f457fe5b061461054b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806116b96033913960400191505060405180910390fd5b6000633b9aca00348161055a57fe5b04905067ffffffffffffffff80168111156105c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806117126027913960400191505060405180910390fd5b60606105cb82611314565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a610600602054611314565b60405180806020018060200180602001806020018060200186810386528e8e82818152602001925080828437600081840152601f19601f82011690508083019250505086810385528c8c82818152602001925080828437600081840152601f19601f82011690508083019250505086810384528a818151815260200191508051906020019080838360005b838110156106a657808201518184015260208101905061068b565b50505050905090810190601f1680156106d35780820380516001836020036101000a031916815260200191505b508681038352898982818152602001925080828437600081840152601f19601f820116905080830192505050868103825287818151815260200191508051906020019080838360005b8381101561073757808201518184015260208101905061071c565b50505050905090810190601f1680156107645780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b6040516020018084848082843780830192505050826fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff1916815260100193505050506040516020818303038152906040526040518082805190602001908083835b6020831061080e57805182526020820191506020810190506020830392506107eb565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610850573d6000803e3d6000fd5b5050506040513d602081101561086557600080fd5b8101908080519060200190929190505050905060006002808888600090604092610891939291906115da565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108eb57805182526020820191506020810190506020830392506108c8565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa15801561092d573d6000803e3d6000fd5b5050506040513d602081101561094257600080fd5b8101908080519060200190929190505050600289896040908092610968939291906115da565b6000801b604051602001808484808284378083019250505082815260200193505050506040516020818303038152906040526040518082805190602001908083835b602083106109cd57805182526020820191506020810190506020830392506109aa565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610a0f573d6000803e3d6000fd5b5050506040513d6020811015610a2457600080fd5b810190808051906020019092919050505060405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b60208310610a8e5780518252602082019150602081019050602083039250610a6b565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610ad0573d6000803e3d6000fd5b5050506040513d6020811015610ae557600080fd5b810190808051906020019092919050505090506000600280848c8c604051602001808481526020018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610b615780518252602082019150602081019050602083039250610b3e565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610ba3573d6000803e3d6000fd5b5050506040513d6020811015610bb857600080fd5b8101908080519060200190929190505050600286600060401b866040516020018084805190602001908083835b60208310610c085780518252602082019150602081019050602083039250610be5565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610c935780518252602082019150602081019050602083039250610c70565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610cd5573d6000803e3d6000fd5b5050506040513d6020811015610cea57600080fd5b810190808051906020019092919050505060405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b60208310610d545780518252602082019150602081019050602083039250610d31565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610d96573d6000803e3d6000fd5b5050506040513d6020811015610dab57600080fd5b81019080805190602001909291905050509050858114610e16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252605481526020018061162f6054913960600191505060405180910390fd5b6001602060020a0360205410610e77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061160e6021913960400191505060405180910390fd5b60016020600082825401925050819055506000602054905060008090505b6020811015610fb75760018083161415610ec8578260008260208110610eb757fe5b018190555050505050505050610fc7565b600260008260208110610ed757fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b60208310610f335780518252602082019150602081019050602083039250610f10565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610f75573d6000803e3d6000fd5b5050506040513d6020811015610f8a57600080fd5b8101908080519060200190929190505050925060028281610fa757fe5b0491508080600101915050610e95565b506000610fc057fe5b5050505050505b50505050505050565b6060610fdd602054611314565b905090565b6000806000602054905060008090505b60208110156111d057600180831614156110e05760026000826020811061101557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b60208310611071578051825260208201915060208101905060208303925061104e565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa1580156110b3573d6000803e3d6000fd5b5050506040513d60208110156110c857600080fd5b810190808051906020019092919050505092506111b6565b600283602183602081106110f057fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061114b5780518252602082019150602081019050602083039250611128565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa15801561118d573d6000803e3d6000fd5b5050506040513d60208110156111a257600080fd5b810190808051906020019092919050505092505b600282816111c057fe5b0491508080600101915050610ff2565b506002826111df602054611314565b600060401b6040516020018084815260200183805190602001908083835b6020831061122057805182526020820191506020810190506020830392506111fd565b6001836020036101000a0380198251168184511680821785525050505050509050018267ffffffffffffffff191667ffffffffffffffff1916815260180193505050506040516020818303038152906040526040518082805190602001908083835b602083106112a55780518252602082019150602081019050602083039250611282565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa1580156112e7573d6000803e3d6000fd5b5050506040513d60208110156112fc57600080fd5b81019080805190602001909291905050509250505090565b6060600867ffffffffffffffff8111801561132e57600080fd5b506040519080825280601f01601f1916602001820160405280156113615781602001600182028036833780820191505090505b50905060008260c01b90508060076008811061137957fe5b1a60f81b8260008151811061138a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806006600881106113c657fe5b1a60f81b826001815181106113d757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060056008811061141357fe5b1a60f81b8260028151811061142457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060046008811061146057fe5b1a60f81b8260038151811061147157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806003600881106114ad57fe5b1a60f81b826004815181106114be57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806002600881106114fa57fe5b1a60f81b8260058151811061150b57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060016008811061154757fe5b1a60f81b8260068151811061155857fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060006008811061159457fe5b1a60f81b826007815181106115a557fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b600080858511156115ea57600080fd5b838611156115f757600080fd5b600185028301915084860390509450949250505056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220230afd4b6e3551329e50f1239e08fa3ab7907b77403c4f237d9adf679e8e43cf64736f6c634300060b0033", + "balance": "0x0" + }, + "4e59b44847b379578588920ca78fbf26c0b4956c": { + "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3", + "balance": "0x0" + }, + "5678e9e827b3be0e3d4b910126a64a697a148267": { + "balance": "0x43c33c1937564800000" + }, + "70997970c51812dc3a010c7d01b50e0d17dc79c8": { + "balance": "0x21e19e0c9bab2400000" + }, + "71be63f3384f5fb98995898a86b02fb2426c5788": { + "balance": "0x21e19e0c9bab2400000" + }, + "8626f6940e2eb28930efb4cef49b2d1f2c9c1199": { + "balance": "0x21e19e0c9bab2400000" + }, + "90f79bf6eb2c4f870365e785982e1f101e93b906": { + "balance": "0x21e19e0c9bab2400000" + }, + "976ea74026e726554db657fa54763abd0c3a0aa9": { + "balance": "0x21e19e0c9bab2400000" + }, + "9965507d1a55bcc2695c58ba16fb37d819b0a4dc": { + "balance": "0x21e19e0c9bab2400000" + }, + "a0ee7a142d267c1f36714e4a8f75612f20a79720": { + "balance": "0x21e19e0c9bab2400000" + }, + "bcd4042de499d14e55001ccbb24a551f3b954096": { + "balance": "0x21e19e0c9bab2400000" + }, + "bda5747bfd65f08deb54cb465eb87d40e51b197e": { + "balance": "0x21e19e0c9bab2400000" + }, + "cd3b766ccdd6ae721141f452c550ca635964ce71": { + "balance": "0x21e19e0c9bab2400000" + }, + "dd2fd4581271e230360230f9337d5c0430bf44c0": { + "balance": "0x21e19e0c9bab2400000" + }, + "df3e18d64bc6a983f673ab319ccae4f1a57c7097": { + "balance": "0x21e19e0c9bab2400000" + }, + "f39fd6e51aad88f6f4ce6ab8827279cfffb92266": { + "balance": "0x21e19e0c9bab2400000" + }, + "fabb0ac9d68b0b445fb7357272ff202c5651694a": { + "balance": "0x21e19e0c9bab2400000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "baseFeePerGas": null, + "excessBlobGas": null, + "blobGasUsed": null +} diff --git a/test-pp-op/l1-geth/execution/geth_password.txt b/test-pp-op/l1-geth/execution/geth_password.txt new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test-pp-op/l1-geth/execution/jwtsecret b/test-pp-op/l1-geth/execution/jwtsecret new file mode 100755 index 0000000000000..c4454fe4fa342 --- /dev/null +++ b/test-pp-op/l1-geth/execution/jwtsecret @@ -0,0 +1 @@ +0xfad2709d0bb03bf0e8ba3c99bea194575d3e98863133d1af638ed056d1d59345 \ No newline at end of file diff --git a/test-pp-op/l1-geth/execution/keystore/UTC--2022-08-19T17-38-31.257380510Z--123463a4b065722e99115d6c222f267d9cabb524 b/test-pp-op/l1-geth/execution/keystore/UTC--2022-08-19T17-38-31.257380510Z--123463a4b065722e99115d6c222f267d9cabb524 new file mode 100644 index 0000000000000..4794e82c2ba30 --- /dev/null +++ b/test-pp-op/l1-geth/execution/keystore/UTC--2022-08-19T17-38-31.257380510Z--123463a4b065722e99115d6c222f267d9cabb524 @@ -0,0 +1 @@ +{"address":"123463a4b065722e99115d6c222f267d9cabb524","crypto":{"cipher":"aes-128-ctr","ciphertext":"93b90389b855889b9f91c89fd15b9bd2ae95b06fe8e2314009fc88859fc6fde9","cipherparams":{"iv":"9dc2eff7967505f0e6a40264d1511742"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"c07503bb1b66083c37527cd8f06f8c7c1443d4c724767f625743bd47ae6179a4"},"mac":"6d359be5d6c432d5bbb859484009a4bf1bd71b76e89420c380bd0593ce25a817"},"id":"622df904-0bb1-4236-b254-f1b8dfdff1ec","version":3} \ No newline at end of file diff --git a/test-pp-op/l1-geth/execution/sk.json b/test-pp-op/l1-geth/execution/sk.json new file mode 100644 index 0000000000000..8fe79fab50958 --- /dev/null +++ b/test-pp-op/l1-geth/execution/sk.json @@ -0,0 +1 @@ +2e0834786285daccd064ca17f1654f67b4aef298acbb82cef9ec422fb4975622 diff --git a/test-pp-op/local.env b/test-pp-op/local.env new file mode 100644 index 0000000000000..38e5dc5d1a020 --- /dev/null +++ b/test-pp-op/local.env @@ -0,0 +1,132 @@ +ENV=local + +CONDUCTOR_ENABLED=true +OWNER_TYPE=transactor # transactor or safe +CGT_ENABLED=true + +CHAIN_ID=195 + +DOCKER_NETWORK=pp-op +CONFIG_DIR=config-op + +# Images +OP_GETH_MIGRATION_IMAGE_TAG=op-geth-migrate:latest +OP_GETH_IMAGE_TAG=op-geth:latest +OP_STACK_IMAGE_TAG=op-stack:latest +OP_CONTRACTS_IMAGE_TAG=op-contract:latest +XLAYER_BRIDGE_SERVICE_IMAGE_TAG=hermeznetwork/zkevm-bridge-service:v0.6.0-RC16-patch +CDK_ERIGON_IMAGE_TAG=cdk-erigon:latest + +OP_GETH_DATADIR=./data/op-geth-seq +OP_GETH_DATADIR2=./data/op-geth-seq2 +OP_GETH_DATADIR3=./data/op-geth-seq3 +OP_GETH_RPC_DATADIR=./data/op-geth-rpc + +# RPC endpoints +L1_RPC_URL=http://127.0.0.1:8545 +L2_RPC_URL=http://127.0.0.1:8124 +L2_ERIGON_RPC_URL=http://127.0.0.1:18124 +L2_OP_SEQ_WS_URL=ws://localhost:7546 +L1_RPC_URL_IN_DOCKER=http://l1-geth:8545 +L2_PP_SEQ_URL_IN_DOCKER=http://xlayer-seq:8545 +L2_PP_RPC_URL_IN_DOCKER=http://xlayer-rpc:8545 +L2_OP_RPC_URL_IN_DOCKER=http://op-geth-rpc:8545 +L1_BEACON_URL_IN_DOCKER=http://l1-beacon-chain:3500 +BRIDGE_SERVICE=http://127.0.0.1:8080 + +# Common addresses & keys + +OKB_TOKEN_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 + +RICH_ADDRESS=0x14dC79964da2C08b23698B3D3cc7Ca32193d9955 +RICH_PRIVATE_KEY=0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356 + +DEPLOYER_ADDRESS=0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534 +DEPLOYER_PRIVATE_KEY=0x815405dddb0e2a99b12af775fd2929e526704e1d1aea6a0b4e74dc33e2f7fcd2 +DEPLOYER_MNEMONIC="moment wine false celery win galaxy glide thumb tail setup choose city" + +SEQUENCER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 +SEQUENCER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +SEQUENCER_P2P_KEY=0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba + +SYSTEM_CONFIG_OWNER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 +OKB_ADAPTER_OWNER_ADDRESS=0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534 + +# PP addresses & keys +AGGREGATOR_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 +AGGREGATOR_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d + +PP_VKEY=0x00d6e4bdab9cac75a50d58262bb4e60b3107a6b61131ccdff649576c624b6fb7 + +ORACLE_ADDRESS=0x70997970c51812dc3a010c7d01b50e0d17dc79c8 + +## Predeployed in PP +TIME_LOCK_ADDRESS=0x27284DBa79e6DF953Fbd232A9d8D87029F03BBf5 +GER_MANAGER_ADDRESS=0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa +BRIDGE_ADDRESS=0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851 + +L1_ETH_ADDRESS=0x0000000000000000000000000000000000000000 +L2_WETH=0xd80e5a44dc9628fae9b432eac67873238504ea29 + +# OP addresses & keys + +BATCHER_ADDRESS=0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC +OP_BATCHER_PRIVATE_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a + +## Same as aggregator +PROPOSER_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 +OP_PROPOSER_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d + +OPTIMISM_PORTAL_PROXY_ADDRESS=0xc8e8b7b181db301f27aef90ed285787a3ce179e9 + +CHALLENGER_ADDRESS=0x7d18a1b858253b5588f61fb5739d52e4b84e2cda +OP_CHALLENGER_PRIVATE_KEY=0x8b3a350cf5c34c9194ca9aa3f146b2b9afed22cd83d3c5f6a3f2f243ce220c01 + +ADMIN_OWNER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 +ADMIN_OWNER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + +# Deployed and modified in 2-deploy-op-contracts.sh +TRANSACTOR=0x0000000000000000000000000000000000000000 +SAFE_ADDRESS=0x0000000000000000000000000000000000000000 +L2OO_ADDRESS=0x0000000000000000000000000000000000000000 +DISPUTE_GAME_FACTORY_ADDRESS=0x3281215007aad854b44b6dbdb0f429e81577497f +OPCM_IMPL_ADDRESS=0x3bc5388bd43977644f73fb75c7d8d6015be71e59 +SYSTEM_CONFIG_PROXY_ADDRESS=0xabd433c36f6b2809ce238044afeb2fc48f6e6ff0 +PROXY_ADMIN=0x88c87adaf76a638cd81286b23b5830a7d6ffb80d + +# Upgrade l2 ger contract +TIME_LOCK_DELAY=70 + +# Set initial bond +INITIAL_BOND=10000000000 + +# First game only for update anchor root +TEMP_MAX_CLOCK_DURATION=40 +TEMP_CLOCK_EXTENSION=5 +TEMP_GAME_WINDOW=60 + +# proof config +PROOF_MATURITY_DELAY_SECONDS=1800 + +# Game config +MAX_CLOCK_DURATION=1800 +CLOCK_EXTENSION=600 +GAME_WINDOW=10800 + +# AnchorStateRegistry config +DISPUTE_GAME_FINALITY_DELAY_SECONDS=5 + +# PreimageOracle config +CHALLENGE_PERIOD_SECONDS=30 + +# WETH config +WITHDRAWAL_DELAY_SECONDS=$MAX_CLOCK_DURATION + +# pebble by default +# if panic, try leveldb +DB_ENGINE="pebble" + +# Modified in in 5-2-migrate-op.sh +FORK_BLOCK=0 +PARENT_HASH=0x0000000000000000000000000000000000000000000000000000000000000000 +PP_RPC_URL=http://xlayer-rpc:8124 diff --git a/test-pp-op/m1-deploy-and-upload.sh b/test-pp-op/m1-deploy-and-upload.sh new file mode 100755 index 0000000000000..7582c56c5b822 --- /dev/null +++ b/test-pp-op/m1-deploy-and-upload.sh @@ -0,0 +1,80 @@ +#!/bin/bash +set -e + +if [ ! -f .env ];then + echo "Please create .env file." + exit 1 +fi + +source .env +source tools.sh +source utils.sh + +UPLOAD_DIR="upload-to-oss" +IMAGE_NAME=$(echo "${OP_GETH_MIGRATION_IMAGE_TAG}" | cut -d':' -f1) +TAR_FILE="${UPLOAD_DIR}.tar.gz" +ARCH="linux/amd64" +SKIP_BUILD_GETH=false; [[ "$*" =~ --skip-geth ]] && SKIP_BUILD_GETH=true +SKIP_DEPLOY=false; [[ "$*" =~ --skip-deploy ]] && SKIP_DEPLOY=true + +echo "" +echo "==============================================" +echo "Step 1: Deploy OP Contracts" +echo "==============================================" +if [ "$SKIP_DEPLOY" = true ]; then + echo "⏭️ Skipping 2-deploy-op-contracts.sh (--skip-deploy flag detected)" +else + ./2-deploy-op-contracts.sh +fi + +echo "" +echo "==============================================" +echo "Step 2: Build op-migrate image" +echo "==============================================" + +# Remove previous uploads to keep size of docker image small. +echo "🗑️ Removing existing container ${UPLOAD_DIR}..." +rm -rf $UPLOAD_DIR ${UPLOAD_DIR}.tar.gz + +if [ "$SKIP_BUILD_GETH" = true ]; then + echo "⏭️ Skipping build_images.sh (--skip-geth flag detected)" +else + ./build_images.sh --op-geth-migrate --arch ${ARCH} --force +fi + +echo "" +echo "==============================================" +echo "Step 3: Save Docker image to tar.gz" +echo "==============================================" +docker save ${OP_GETH_MIGRATION_IMAGE_TAG} | gzip > ${IMAGE_NAME}.tar.gz +[ -n "$(docker images -q ${IMAGE_NAME})" ] || exit 1 +echo "✅ Image saved to ${IMAGE_NAME}.tar.gz" + +echo "" +echo "==============================================" +echo "Step 4: Create folder to store upload files" +echo "==============================================" +mkdir -p $UPLOAD_DIR +mv ${IMAGE_NAME}.tar.gz $UPLOAD_DIR +cp ./m2-migrate.sh $UPLOAD_DIR +cp ./m3-verify.sh $UPLOAD_DIR +tar -czvf $UPLOAD_DIR.tar.gz $UPLOAD_DIR +echo "✅ Upload file ${TAR_FILE} is created." + +echo "" +echo "==============================================" +echo "Step 5: Calculate MD5 hash" +echo "==============================================" +if [[ "$OSTYPE" == "darwin"* ]]; then + MD5_HASH=$(md5 -q ${TAR_FILE}) + echo "MD5 Hash: ${MD5_HASH}" +else + md5sum ${TAR_FILE} + MD5_HASH=$(md5sum ${TAR_FILE} | awk '{print $1}') +fi + +echo "" +echo "==============================================" +echo "Step 6: Upload to OSS" +echo "==============================================" +echo "Please create an OSS ticket using ${TAR_FILE} and its MD5 hash: ${MD5_HASH}." diff --git a/test-pp-op/m2-migrate.sh b/test-pp-op/m2-migrate.sh new file mode 100755 index 0000000000000..cea40a2c8be89 --- /dev/null +++ b/test-pp-op/m2-migrate.sh @@ -0,0 +1,630 @@ +#!/bin/bash +set -e + +# Debug mode - set to true to enable verbose output +DEBUG=${DEBUG:-false} +if [ "$DEBUG" = "true" ]; then + set -x +fi + +FORK_BLOCK=$1 + +IMAGE_NAME="op-geth-migrate:latest" +CONTAINER_NAME="op-migrate-container" +RAMDISK_PATH="/mnt/ramdisk_op" +DATA_DIR="/data" +ERIGON_DATA_DIR="/data/erigon-data" +BACKUP_DIR="${DATA_DIR}/migration-backup-$(date +%Y%m%d)" +L2_RPC_URL="${L2_RPC_URL:-http://10.2.29.232:18545}" +ENV=${ENV:-mainnet} +# Set expected chain ID based on ENV variable +EXPECTED_CHAIN=$([ "$ENV" = "testnet" ] && echo "1952" || echo "196") +EXPECTED_L1_CHAIN_ID=$([ "$ENV" = "testnet" ] && echo "11155111" || ([ "$ENV" = "fakemainnet" ] && echo "11155111" || echo "1")) +CHECK_BLOCK=${CHECK_BLOCK:-true} + +# Check required tools +for cmd in docker jq curl sed grep; do + if ! command -v $cmd >/dev/null 2>&1; then + echo "❌ Error: Required tool '$cmd' is not installed" + exit 1 + fi +done + +# Prompt to delete ${BACKUP_DIR} contents +if [ -d $BACKUP_DIR ];then + echo "" + echo "=============================================" + echo "Existing ${BACKUP_DIR}" + echo "=============================================" + ls -la $BACKUP_DIR + echo "" + read -p "Do you want to delete the contents of ${BACKUP_DIR}? (y/n): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "${BACKUP_DIR} contents are DELETED..." + rm -rf ${BACKUP_DIR}/* + else + echo "${BACKUP_DIR} contents are NOT deleted..." + fi +fi + +# Create and verify backup directory +mkdir -p ${BACKUP_DIR} +if ! touch ${BACKUP_DIR}/.write_test 2>/dev/null; then + echo "❌ Error: Cannot write to backup directory: ${BACKUP_DIR}" + exit 1 +fi +rm -f ${BACKUP_DIR}/.write_test + +# Function to fetch block data from RPC (executed on host) +fetch_block_data() { + local fork_block=$1 + + echo "Fetching block #$fork_block from RPC..." + echo "RPC URL: ${L2_RPC_URL}" + + # Convert to hex + local fork_block_hex=$(printf '0x%x' $fork_block) + + # Fetch block data from RPC (on host, not in container) + local block_data=$(curl -s --max-time 30 -X POST ${L2_RPC_URL} \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["'$fork_block_hex'",true],"id":1}') + + local curl_exit_code=$? + if [ $curl_exit_code -ne 0 ]; then + echo "❌ Error: Failed to fetch block data from RPC (curl exit code: $curl_exit_code)" + echo " RPC URL: ${L2_RPC_URL}" + echo " This may be due to network issues or RPC timeout." + echo " You can set L2_RPC_URL environment variable to customize." + exit 1 + fi + + # Extract hash and timestamp + local block_hash=$(echo "$block_data" | jq -r '.result.hash') + # max(old genesis timestamp, latest L2 block timestamp + 1) + local timestamp=$(echo "$block_data" | jq -r '.result.timestamp') + + echo "Block #$fork_block:" + echo " Hash: $block_hash" + echo " Timestamp: $timestamp" + + # Validate data + if [ "$block_hash" = "null" ] || [ -z "$block_hash" ]; then + echo "❌ Error: Failed to fetch block hash for block $fork_block" + echo " RPC Response: $block_data" + exit 1 + fi + + # Validate hash format (0x + 64 hex characters) + if ! [[ "$block_hash" =~ ^0x[0-9a-fA-F]{64}$ ]]; then + echo "❌ Error: Invalid block hash format: $block_hash" + echo " Expected: 0x followed by 64 hexadecimal characters" + exit 1 + fi + + if [ "$timestamp" = "null" ] || [ -z "$timestamp" ]; then + echo "❌ Error: Failed to fetch timestamp for block $fork_block" + echo " RPC Response: $block_data" + exit 1 + fi + + # Validate timestamp format (0x + hex number) + if ! [[ "$timestamp" =~ ^0x[0-9a-fA-F]+$ ]]; then + echo "❌ Error: Invalid timestamp format: $timestamp" + echo " Expected: 0x followed by hexadecimal number" + exit 1 + fi + + # Export for use by other functions + export FETCHED_BLOCK_HASH="$block_hash" + export FETCHED_TIMESTAMP="$timestamp" + export FETCHED_FORK_BLOCK="$fork_block" +} + +# Function to validate configuration (executed in container) +validate_configuration() { + local rpc_timestamp=$1 + + echo "" + echo "=============================================" + echo "Validating Configuration Files" + echo "=============================================" + + docker exec ${CONTAINER_NAME} bash -c " + set -e + cd /app/test-pp-op + + # 1. Validate .env + echo \"\" + echo \"[1/4] Validating .env...\" + ENV_CHAIN_ID=\$(grep '^CHAIN_ID=' .env | cut -d'=' -f2) + if [ -z \"\$ENV_CHAIN_ID\" ]; then + echo \" ❌ Error: CHAIN_ID not found in .env\" + echo \" Please ensure .env contains 'CHAIN_ID=$EXPECTED_CHAIN'\" + exit 1 + fi + echo \" CHAIN_ID: \$ENV_CHAIN_ID\" + if [ \"\$ENV_CHAIN_ID\" != \"$EXPECTED_CHAIN\" ]; then + echo \" ❌ Error: .env CHAIN_ID must be $EXPECTED_CHAIN, but got \$ENV_CHAIN_ID\" + exit 1 + fi + echo \" ✅ .env validation passed\" + + # 2. Validate genesis.json + echo \"\" + echo \"[2/4] Validating config-op/genesis.json...\" + if [ ! -f config-op/genesis.json ]; then + echo \" ❌ Error: config-op/genesis.json not found\" + exit 1 + fi + + CHAIN_ID=\$(jq -r '.config.chainId' config-op/genesis.json) + if [ -z \"\$CHAIN_ID\" ] || [ \"\$CHAIN_ID\" = \"null\" ]; then + echo \" ❌ Error: Failed to read .config.chainId from genesis.json\" + echo \" Response: \$CHAIN_ID\" + exit 1 + fi + echo \" config.chainId: \$CHAIN_ID\" + if [ \"\$CHAIN_ID\" != \"$EXPECTED_CHAIN\" ]; then + echo \" ❌ Error: Chain ID must be $EXPECTED_CHAIN, but got \$CHAIN_ID\" + exit 1 + fi + + # Validate timestamp: RPC timestamp must be < genesis.json timestamp + EXISTING_TIMESTAMP=\$(jq -r '.timestamp' config-op/genesis.json) + if [ -z \"\$EXISTING_TIMESTAMP\" ] || [ \"\$EXISTING_TIMESTAMP\" = \"null\" ]; then + echo \" ❌ Error: Failed to read .timestamp from genesis.json\" + exit 1 + fi + RPC_TS_DEC=\$(($rpc_timestamp)) + GENESIS_TS_DEC=\$((EXISTING_TIMESTAMP)) + echo \" genesis.json timestamp: \$EXISTING_TIMESTAMP (decimal: \$GENESIS_TS_DEC)\" + echo \" RPC timestamp: $rpc_timestamp (decimal: \$RPC_TS_DEC)\" + + #if [ \$RPC_TS_DEC -ge \$GENESIS_TS_DEC ]; then + # echo \" ❌ Error: RPC timestamp (\$RPC_TS_DEC) must be < genesis.json timestamp (\$GENESIS_TS_DEC)\" + # echo \" This indicates the fork block is at or after the genesis block.\" + # echo \" Please specify an earlier fork block number.\" + # exit 1 + #fi + #echo \" ✅ genesis.json timestamp validation passed (RPC < genesis)\" + + # 3. Validate intent.toml + echo \"\" + echo \"[3/4] Validating config-op/intent.toml...\" + if [ ! -f config-op/intent.toml ]; then + echo \" ❌ Error: config-op/intent.toml not found\" + exit 1 + fi + + L1_CHAIN_ID=\$(grep '^l1ChainID' config-op/intent.toml | head -1 | sed 's/.*=[[:space:]]*\\([0-9]*\\).*/\\1/') + if [ -z \"\$L1_CHAIN_ID\" ]; then + echo \" ❌ Error: Failed to extract l1ChainID from intent.toml\" + exit 1 + fi + echo \" l1ChainID: \$L1_CHAIN_ID\" + if [ \"\$L1_CHAIN_ID\" != \"$EXPECTED_L1_CHAIN_ID\" ]; then + echo \" ❌ Error: l1ChainID must be $EXPECTED_L1_CHAIN_ID, but got \$L1_CHAIN_ID\" + exit 1 + fi + + CHAIN_ID_HEX=\$(grep '^[[:space:]]*id[[:space:]]*=' config-op/intent.toml | head -1 | sed 's/.*\"\\(0x[0-9a-fA-F]*\\)\".*/\\1/') + if [ -z \"\$CHAIN_ID_HEX\" ]; then + echo \" ❌ Error: Failed to extract chains[0].id from intent.toml\" + exit 1 + fi + CHAIN_ID_DEC=\$((\$CHAIN_ID_HEX)) + echo \" chains[0].id: \$CHAIN_ID_HEX (decimal: \$CHAIN_ID_DEC)\" + if [ \"\$CHAIN_ID_DEC\" != \"$EXPECTED_CHAIN\" ]; then + echo \" ❌ Error: chains[0].id must be $EXPECTED_CHAIN, but got \$CHAIN_ID_DEC\" + exit 1 + fi + + echo \" ✅ intent.toml validation passed\" + + # 4. Validate rollup.json + echo \"\" + echo \"[4/4] Validating config-op/rollup.json...\" + if [ ! -f config-op/rollup.json ]; then + echo \" ❌ Error: config-op/rollup.json not found\" + exit 1 + fi + + ROLLUP_CHAIN_ID=\$(jq -r '.l2_chain_id' config-op/rollup.json) + if [ -z \"\$ROLLUP_CHAIN_ID\" ] || [ \"\$ROLLUP_CHAIN_ID\" = \"null\" ]; then + echo \" ❌ Error: Failed to read .l2_chain_id from rollup.json\" + exit 1 + fi + echo \" l2_chain_id: \$ROLLUP_CHAIN_ID\" + if [ \"\$ROLLUP_CHAIN_ID\" != \"$EXPECTED_CHAIN\" ]; then + echo \" ❌ Error: l2_chain_id must be $EXPECTED_CHAIN, but got \$ROLLUP_CHAIN_ID\" + exit 1 + fi + echo \" ✅ rollup.json validation passed\" + + echo \"\" + echo \"=============================================\" + echo \"✅ All Configuration Validations Passed\" + echo \"=============================================\" + " +} + +# Function to wait for Enter key +wait_for_enter() { + local prompt="$1" + echo "---" + read -n 1 -s -r -p "$prompt" key + echo "" + if [ "$key" != "" ]; then + echo "❌ Aborted by user" + exit 1 + fi +} + +# Function to extract and display configuration fields +extract_configuration_fields() { + local phase="$1" # "before" or "after" + + # Extract .env values + echo "=== .env Configuration ===" + docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ + echo 'CHAIN_ID='\$(grep '^CHAIN_ID=' .env | cut -d'=' -f2) && \ + echo 'OKB_TOKEN_ADDRESS='\$(grep '^OKB_TOKEN_ADDRESS=' .env | cut -d'=' -f2) && \ + echo 'BATCHER_ADDRESS='\$(grep '^BATCHER_ADDRESS=' .env | cut -d'=' -f2) && \ + echo 'PROPOSER_ADDRESS='\$(grep '^PROPOSER_ADDRESS=' .env | cut -d'=' -f2) && \ + echo 'CHALLENGER_ADDRESS='\$(grep '^CHALLENGER_ADDRESS=' .env | cut -d'=' -f2) && \ + echo 'ADMIN_OWNER_ADDRESS='\$(grep '^ADMIN_OWNER_ADDRESS=' .env | cut -d'=' -f2) && \ + echo 'TIME_LOCK_DELAY='\$(grep '^TIME_LOCK_DELAY=' .env | cut -d'=' -f2) && \ + echo 'TEMP_MAX_CLOCK_DURATION='\$(grep '^TEMP_MAX_CLOCK_DURATION=' .env | cut -d'=' -f2) && \ + echo 'TEMP_CLOCK_EXTENSION='\$(grep '^TEMP_CLOCK_EXTENSION=' .env | cut -d'=' -f2) && \ + echo 'PROOF_MATURITY_DELAY_SECONDS='\$(grep '^PROOF_MATURITY_DELAY_SECONDS=' .env | cut -d'=' -f2) && \ + echo 'MAX_CLOCK_DURATION='\$(grep '^MAX_CLOCK_DURATION=' .env | cut -d'=' -f2) && \ + echo 'CLOCK_EXTENSION='\$(grep '^CLOCK_EXTENSION=' .env | cut -d'=' -f2) && \ + echo 'DISPUTE_GAME_FINALITY_DELAY_SECONDS='\$(grep '^DISPUTE_GAME_FINALITY_DELAY_SECONDS=' .env | cut -d'=' -f2) && \ + echo 'CHALLENGE_PERIOD_SECONDS='\$(grep '^CHALLENGE_PERIOD_SECONDS=' .env | cut -d'=' -f2) && \ + echo 'WITHDRAWAL_DELAY_SECONDS='\$(grep '^WITHDRAWAL_DELAY_SECONDS=' .env | cut -d'=' -f2) && \ + echo 'DISPUTE_GAME_FACTORY_ADDRESS='\$(grep '^DISPUTE_GAME_FACTORY_ADDRESS=' .env | cut -d'=' -f2) && \ + echo 'TRANSACTOR='\$(grep '^TRANSACTOR=' .env | cut -d'=' -f2)" + + echo "" + echo "=== intent.toml Configuration ===" + docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ + echo 'l1ChainID='\$(grep '^l1ChainID' config-op/intent.toml | head -1 | sed 's/.*=[[:space:]]*\\([0-9]*\\).*/\\1/') && \ + echo 'opcmAddress='\$(grep '^opcmAddress' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'id='\$(grep '^[[:space:]]*id[[:space:]]*=' config-op/intent.toml | head -1 | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'baseFeeVaultRecipient='\$(grep 'baseFeeVaultRecipient' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'l1FeeVaultRecipient='\$(grep 'l1FeeVaultRecipient' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'sequencerFeeVaultRecipient='\$(grep 'sequencerFeeVaultRecipient' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'l2GenesisBlockGasLimit='\$(grep 'l2GenesisBlockGasLimit' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'l2GenesisBlockBaseFeePerGas='\$(grep 'l2GenesisBlockBaseFeePerGas' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'eip1559DenominatorCanyon='\$(grep 'eip1559DenominatorCanyon' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ + echo 'eip1559Denominator='\$(grep 'eip1559Denominator' config-op/intent.toml | head -1 | cut -d'=' -f2 | tr -d ' ') && \ + echo 'eip1559Elasticity='\$(grep 'eip1559Elasticity' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ + echo 'operatorFeeScalar='\$(grep 'operatorFeeScalar' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ + echo 'operatorFeeConstant='\$(grep 'operatorFeeConstant' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ + echo 'gasLimit='\$(grep 'gasLimit' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ + echo 'l1ProxyAdminOwner='\$(grep 'l1ProxyAdminOwner' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'l2ProxyAdminOwner='\$(grep 'l2ProxyAdminOwner' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'systemConfigOwner='\$(grep 'systemConfigOwner' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'unsafeBlockSigner='\$(grep 'unsafeBlockSigner' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'batcher='\$(grep 'batcher' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'proposer='\$(grep 'proposer' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ + echo 'challenger='\$(grep 'challenger' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/')" + + echo "" + echo "=== rollup.json Configuration ===" + docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ + echo 'hash='\$(jq -r '.genesis.l2.hash' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ + echo 'number='\$(jq -r '.genesis.l2.number' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ + echo 'l1_chain_id='\$(jq -r '.l1_chain_id' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ + echo 'l2_chain_id='\$(jq -r '.l2_chain_id' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ + echo 'batch_inbox_address='\$(jq -r '.batch_inbox_address' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ + echo 'deposit_contract_address='\$(jq -r '.deposit_contract_address' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ + echo 'l1_system_config_address='\$(jq -r '.l1_system_config_address' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ + echo 'protocol_versions_address='\$(jq -r '.protocol_versions_address' config-op/rollup.json 2>/dev/null || echo 'N/A')" + + # Only show merged.genesis.json if it exists (after migration) + if [ "$phase" = "after" ]; then + echo "" + echo "=== merged.genesis.json Configuration ===" + docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ + echo 'chainId='\$(head -n 20 merged.genesis.json | grep -o '\"chainId\":[[:space:]]*[0-9]*' | cut -d':' -f2 | tr -d ' ' || echo 'N/A') && \ + echo 'legacyXLayerBlock='\$(head -n 20 merged.genesis.json | grep -o '\"legacyXLayerBlock\":[[:space:]]*[0-9]*' | cut -d':' -f2 | tr -d ' ' || echo 'N/A') && \ + echo 'eip1559Elasticity='\$(head -n 50 merged.genesis.json | grep 'eip1559Elasticity' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A') && \ + echo 'eip1559Denominator='\$(head -n 50 merged.genesis.json | grep 'eip1559Denominator' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A') && \ + echo 'eip1559DenominatorCanyon='\$(head -n 50 merged.genesis.json | grep 'eip1559DenominatorCanyon' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A') && \ + echo 'parentHash='\$(tail -n 20 merged.genesis.json | grep -o '\"parentHash\":[[:space:]]*\"0x[0-9a-fA-F]*\"' | cut -d':' -f2 | tr -d ' \"' || echo 'N/A') && \ + echo 'baseFeePerGas='\$(tail -n 20 merged.genesis.json | grep -o '\"baseFeePerGas\":[[:space:]]*\"0x[0-9a-fA-F]*\"' | cut -d':' -f2 | tr -d ' \"' || echo 'N/A') && \ + echo 'timestamp='\$(head -n 50 merged.genesis.json | grep 'timestamp' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A')" + + echo "" + echo "=== state.json Configuration ===" + docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ + echo 'SystemConfigProxy='\$(head -n 200 config-op/state.json | grep 'SystemConfigProxy' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A')" + else + echo "" + echo "=== merged.genesis.json Configuration ===" + echo "⚠️ merged.genesis.json will be created during migration" + echo " This file contains the final genesis configuration after migration" + fi + + echo "" + echo "==============================================" + wait_for_enter "Press ENTER to continue..." + + echo "" + echo "✅ Configuration fields extracted and reviewed" +} + +# Function to execute migration +execute_migration() { + # Execute migration script inside container + if docker exec -i ${CONTAINER_NAME} bash -c " + set -e + cd /app/test-pp-op + ./4-migrate-op.sh + + if [ ! -f merged.genesis.json ]; then + echo \"❌ Error: merged.genesis.json not found after migration\" + exit 1 + fi + + # Copy files separately for better error handling + cp .env ${BACKUP_DIR}/ || exit 1 + cp merged.genesis.json ${BACKUP_DIR}/ || exit 1 + cp -rf config-op ${BACKUP_DIR}/config-op || exit 1 + + [ -f migrate.log ] && cp migrate.log ${BACKUP_DIR}/ + "; then + echo "" + echo "✅ Migration completed successfully inside container" + return 0 + else + local exit_code=$? + echo "" + echo "❌ Migration failed with exit code: ${exit_code}" + echo "" + read -p "Do you want to keep the container for debugging? (y/N): " KEEP_CONTAINER + if [[ ! "$KEEP_CONTAINER" =~ ^[Yy]$ ]]; then + echo "Stopping and removing container..." + docker stop ${CONTAINER_NAME} 2>/dev/null || true + docker rm ${CONTAINER_NAME} 2>/dev/null || true + else + echo "Container ${CONTAINER_NAME} kept for debugging" + echo "To enter the container: docker exec -it ${CONTAINER_NAME} bash" + fi + exit ${exit_code} + fi +} + +echo "==============================================" +echo "Step 1: Pre-flight checks" +echo "==============================================" + +# Check if ramdisk is mounted +if ! mountpoint -q ${RAMDISK_PATH}; then + echo "❌ Error: Ramdisk not mounted at ${RAMDISK_PATH}" + echo "Please run m2-download-image.sh first to setup ramdisk" + exit 1 +fi +echo "✅ Ramdisk is mounted at ${RAMDISK_PATH}" + +# Check if Docker image exists +if ! docker image inspect ${IMAGE_NAME} >/dev/null 2>&1; then + echo "❌ Error: Docker image ${IMAGE_NAME} not found" + echo "Please run m2-download-image.sh first to load the image" + exit 1 +fi + +# Check if erigon data directory exists +if [ ! -d "${ERIGON_DATA_DIR}" ]; then + echo "❌ Error: Erigon data directory ${ERIGON_DATA_DIR} not found" + exit 1 +fi + +echo "✅ All pre-flight checks passed" + +echo "" +echo "==============================================" +echo "Step 2: Start Docker container" +echo "==============================================" + +# Clean up any existing data from previous migrations +SOURCE_PATH="$RAMDISK_PATH/test-pp-op/data/op-geth-seq" +if [ -d "$SOURCE_PATH" ]; then + echo "🗑️ Removing contents from $SOURCE_PATH..." + rm -rf "$SOURCE_PATH"/* + echo "✅ Previous data contents cleaned up" +else + echo "✅ No existing data found at $SOURCE_PATH" +fi + +mkdir -p ${SOURCE_PATH} + +# Force remove existing container for clean migration +if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + echo "🗑️ Removing existing container ${CONTAINER_NAME} for clean migration..." + + # Stop container + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + echo " Stopping container..." + docker stop ${CONTAINER_NAME} 2>/dev/null || true + fi + + docker rm ${CONTAINER_NAME} 2>/dev/null || true + echo "✅ Old container removed" +fi + +# Start container if not running +if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + echo "Starting container ${CONTAINER_NAME}..." + docker run \ + --name ${CONTAINER_NAME} \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v ${ERIGON_DATA_DIR}:/data/erigon-data \ + -v ${BACKUP_DIR}:${BACKUP_DIR} \ + -v ${RAMDISK_PATH}:${RAMDISK_PATH} \ + -v ${RAMDISK_PATH}/test-pp-op/data/op-geth-seq:/app/test-pp-op/data/op-geth-seq \ + -e DOCKER_HOST=unix:///var/run/docker.sock \ + -d ${IMAGE_NAME} sleep infinity + + echo "✅ Container started successfully" + + # Wait a moment for container to be ready + sleep 2 +else + echo "✅ Container ${CONTAINER_NAME} is already running" +fi + +echo "" +echo "==============================================" +echo "Step 3: Check configuration" +echo "==============================================" + +if [ "$CHECK_BLOCK" = "true" ]; then + if [ -z "$FORK_BLOCK" ]; then + echo "❌ Error: FORK_BLOCK not set. Pls specify ./m2-migrate.sh FORK_BLOCK" + exit 1 + fi + + # Fetch block data from RPC (on host) + fetch_block_data $FORK_BLOCK + # Validate all configurations (pass RPC timestamp for validation) + validate_configuration $FETCHED_TIMESTAMP +fi + +echo "" +echo "==============================================" +echo "Step 4: Review Configuration Before Migration" +echo "==============================================" +extract_configuration_fields "before" + +echo "" +echo "==============================================" +echo "Step 5: Execute Migration" +echo "==============================================" +echo "Executing ./4-migrate-op.sh inside container..." +echo "" +execute_migration + +echo "" +echo "==============================================" +echo "Step 6: Copy results to disk" +echo "==============================================" + +TEMP_DIR="${BACKUP_DIR}.tmp" + +# Verify source exists +if [ ! -d "$SOURCE_PATH" ]; then + echo "❌ Error: Source directory not found: $SOURCE_PATH" + echo " Expected migration output in ramdisk, but directory does not exist" + echo "" + echo " Checking alternative locations..." + + # Check if data might be elsewhere + if [ -d "$RAMDISK_PATH/test-pp-op/data" ]; then + echo " Contents of $RAMDISK_PATH/test-pp-op/data/:" + ls -la "$RAMDISK_PATH/test-pp-op/data/" 2>/dev/null || echo " (unable to list)" + fi + + echo "" + echo " Please verify:" + echo " 1. Migration script completed successfully" + echo " 2. Output was written to ramdisk" + echo " 3. Container volume mounts are correct" + exit 1 +fi + +# Verify source is not empty +SOURCE_SIZE=$(du -sb "$SOURCE_PATH" 2>/dev/null | awk '{print $1}') +if [ "$SOURCE_SIZE" -lt 1024 ]; then + echo "⚠️ Warning: Source directory is very small (${SOURCE_SIZE} bytes)" + echo " This may indicate migration did not complete properly" + read -p "Continue anyway? (y/N): " CONTINUE + if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then + echo "Aborted by user" + exit 1 + fi +fi + +echo "Source size: $(du -sh "$SOURCE_PATH" 2>/dev/null | awk '{print $1}')" + +echo "Backup directory: ${BACKUP_DIR}" +echo "Copying data from ramdisk to disk (using atomic operation)..." + +# Safety check for TEMP_DIR +if [ -z "$TEMP_DIR" ] || [ "$TEMP_DIR" = "/" ] || [ "$TEMP_DIR" = "/tmp" ]; then + echo "❌ Error: Invalid TEMP_DIR value: $TEMP_DIR" + exit 1 +fi + +# Use temporary directory for atomic copy +rm -rf "$TEMP_DIR" +mkdir -p "$TEMP_DIR" + +# Copy to temporary location +if ! cp -r "$SOURCE_PATH" "$TEMP_DIR/op-geth-seq"; then + echo "❌ Error: Failed to copy data to temporary directory" + rm -rf "$TEMP_DIR" + exit 1 +fi + +# Move to final location (atomic operation) +if ! mv "$TEMP_DIR/op-geth-seq" "$BACKUP_DIR/"; then + echo "❌ Error: Failed to move data to backup directory" + rm -rf "$TEMP_DIR" + exit 1 +fi + +# Clean up +rm -rf "$TEMP_DIR" + +echo "✅ Files copied successfully" + +echo "" +echo "==============================================" +echo "Step 7: Review Configuration After Copy" +echo "==============================================" +extract_configuration_fields "after" + +echo "" +echo "==============================================" +echo "Step 8: Copy diff.genesis.json from container" +echo "==============================================" + +# Check if diff.genesis.json exists in container +if docker exec ${CONTAINER_NAME} test -f /app/test-pp-op/diff.genesis.json; then + echo "Copying diff.genesis.json from container..." + if docker cp ${CONTAINER_NAME}:/app/test-pp-op/diff.genesis.json ${BACKUP_DIR}/diff.genesis.json; then + echo "✅ diff.genesis.json copied successfully to ${BACKUP_DIR}/diff.genesis.json" + else + echo "⚠️ Warning: Failed to copy diff.genesis.json" + fi +else + echo "⚠️ Warning: diff.genesis.json not found in container" + echo " Expected location: /app/test-pp-op/diff.genesis.json" +fi + +echo "" +echo "==============================================" +echo "Step 9: Check for differences between mounted data and backup" +echo "==============================================" + +diff -r $SOURCE_PATH $BACKUP_DIR/op-geth-seq # exit script on failure (set -e) +echo "✅ Contents of ${SOURCE_PATH} matches ${BACKUP_DIR}/op-geth-seq" + +echo "" +echo "==============================================" +echo "✅ Migration process completed successfully!" +echo "==============================================" +echo "Backup directory: ${BACKUP_DIR}" + +if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + echo "" + echo "Stopping migration container at last." + echo "" + docker stop ${CONTAINER_NAME} 2>/dev/null || true +fi + +echo "==============================================" diff --git a/test-pp-op/m3-verify.sh b/test-pp-op/m3-verify.sh new file mode 100755 index 0000000000000..f97af85489ab9 --- /dev/null +++ b/test-pp-op/m3-verify.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -e +set -x + +IMAGE_NAME="op-geth-migrate:latest" +CONTAINER_NAME="op-verify-container" +RAMDISK_PATH="${RAMDISK_PATH:-/mnt/ramdisk_op}" +ERIGON_DATA_DIR="${ERIGON_DATA_DIR:-/data/erigon-data}" +OP_GETH_DATA_DIR="${RAMDISK_PATH}/test-pp-op/data/op-geth-seq" + +echo "Verifying migration in ramdisk..." +echo " Erigon: ${ERIGON_DATA_DIR}/chaindata" +echo " OP-Geth: ${OP_GETH_DATA_DIR}" + +# Basic checks +[ -d "${ERIGON_DATA_DIR}/chaindata" ] || { echo "❌ Erigon chaindata not found at ${ERIGON_DATA_DIR}/chaindata"; exit 1; } +[ -d "${OP_GETH_DATA_DIR}" ] || { echo "❌ OP-Geth data not found at ${OP_GETH_DATA_DIR}"; exit 1; } + +# Cleanup old container +docker rm -f ${CONTAINER_NAME} 2>/dev/null || true + +# Start container +docker run -d --name ${CONTAINER_NAME} \ + -v ${ERIGON_DATA_DIR}:/data/erigon-data \ + -v ${RAMDISK_PATH}:${RAMDISK_PATH} \ + ${IMAGE_NAME} sleep infinity + +sleep 2 + +# Run verification +echo "Running verification..." +docker exec -w /app/test-pp-op -it ${CONTAINER_NAME} geth verifyMigrate \ + --chaindata=/data/erigon-data/chaindata \ + --datadir=${OP_GETH_DATA_DIR} \ + --standalone-smt=true + +RESULT=$? + +# Cleanup +docker rm -f ${CONTAINER_NAME} 2>/dev/null || true + +exit $RESULT + diff --git a/test-pp-op/notes.txt b/test-pp-op/notes.txt new file mode 100644 index 0000000000000..e5ade6a866676 --- /dev/null +++ b/test-pp-op/notes.txt @@ -0,0 +1,28 @@ +# op node +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"opp2p_self","params":[],"id":1}' http://localhost:9545 + +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"opp2p_peerStats","params":[],"id":1}' http://localhost:9545 + +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_sequencerActive","params":[],"id":1}' http://localhost:9545 + +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' http://localhost:9545 + +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_overrideLeader","params":[],"id":1}' http://localhost:9545 + + + +# op conductor +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' http://localhost:8547 + +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_sequencerHealthy","params":[],"id":1}' http://localhost:8547 + +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_paused","params":[],"id":1}' http://localhost:8547 + +curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_resume","params":[],"id":1}' http://localhost:8547 + + + + + + + diff --git a/test-pp-op/patch/op-geth-0001-support-load-genesis-at-a-given-number.patch b/test-pp-op/patch/op-geth-0001-support-load-genesis-at-a-given-number.patch new file mode 100644 index 0000000000000..c44e001aa0fb7 --- /dev/null +++ b/test-pp-op/patch/op-geth-0001-support-load-genesis-at-a-given-number.patch @@ -0,0 +1,187 @@ +From c0308891304462768e9b1f662c35e77b614a427e Mon Sep 17 00:00:00 2001 +From: JimmyShi +Date: Tue, 8 Jul 2025 14:29:46 +0800 +Subject: [PATCH] support load genesis at a given number + +--- + core/blockchain_reader.go | 7 ++++++- + core/genesis.go | 13 ++++++++++--- + core/rawdb/accessors_chain.go | 17 +++++++++++++++++ + core/rawdb/chain_freezer.go | 6 ++++-- + core/rawdb/database.go | 36 ++++++++++++++++++++++++++++++----- + 5 files changed, 68 insertions(+), 11 deletions(-) + +diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go +index f53ddfa4c..1aa3caf90 100644 +--- a/core/blockchain_reader.go ++++ b/core/blockchain_reader.go +@@ -424,7 +424,12 @@ func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) { + func (bc *BlockChain) HistoryPruningCutoff() (uint64, common.Hash) { + pt := bc.historyPrunePoint.Load() + if pt == nil { +- return 0, bc.genesisBlock.Hash() ++ // get genesis block number ++ genesisHash := rawdb.ReadCanonicalHash(bc.db, 0) ++ genesisHeader := rawdb.ReadHeader(bc.db, genesisHash, 0) ++ genesisBlockNumber := genesisHeader.Number.Uint64() ++ ++ return genesisBlockNumber, genesisHash + } + return pt.BlockNumber, pt.BlockHash + } +diff --git a/core/genesis.go b/core/genesis.go +index 5db5c9813..33a0f1291 100644 +--- a/core/genesis.go ++++ b/core/genesis.go +@@ -683,9 +683,9 @@ func (g *Genesis) toBlockWithRoot(stateRoot, storageRootMessagePasser common.Has + // Commit writes the block and state of a genesis specification to the database. + // The block is committed as the canonical head block. + func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Block, error) { +- if g.Number != 0 { +- return nil, errors.New("can't commit genesis block with number > 0") +- } ++ // if g.Number != 0 { ++ // return nil, errors.New("can't commit genesis block with number > 0") ++ // } + config := g.Config + if config == nil { + return nil, errors.New("invalid genesis without chain config") +@@ -727,6 +727,13 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo + rawdb.WriteHeadFastBlockHash(batch, block.Hash()) + rawdb.WriteHeadHeaderHash(batch, block.Hash()) + rawdb.WriteChainConfig(batch, block.Hash(), config) ++ ++ if block.NumberU64() != 0 { ++ // Also write the genesis block as number 0 ++ rawdb.WriteCanonicalHash(batch, block.Hash(), 0) ++ rawdb.WriteGenesisHeader(batch, block.Header()) ++ } ++ + return block, batch.Write() + } + +diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go +index 59c73aa99..e77733f78 100644 +--- a/core/rawdb/accessors_chain.go ++++ b/core/rawdb/accessors_chain.go +@@ -404,6 +404,23 @@ func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) { + } + } + ++func WriteGenesisHeader(db ethdb.KeyValueWriter, header *types.Header) { ++ var ( ++ hash = header.Hash() ++ number = uint64(0) ++ ) ++ ++ // Write the encoded header ++ data, err := rlp.EncodeToBytes(header) ++ if err != nil { ++ log.Crit("Failed to RLP encode header", "err", err) ++ } ++ key := headerKey(number, hash) ++ if err := db.Put(key, data); err != nil { ++ log.Crit("Failed to store header", "err", err) ++ } ++} ++ + // DeleteHeader removes all block header data associated with a hash. + func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { + deleteHeaderWithoutNumber(db, hash, number) +diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go +index f3c671f45..ebebc9c95 100644 +--- a/core/rawdb/chain_freezer.go ++++ b/core/rawdb/chain_freezer.go +@@ -212,7 +212,8 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) { + batch := db.NewBatch() + for i := 0; i < len(ancients); i++ { + // Always keep the genesis block in active database +- if first+uint64(i) != 0 { ++ trueGenesisNumber := getGenesisBlockNumber(db) ++ if first+uint64(i) != trueGenesisNumber { + DeleteBlockWithoutNumber(batch, ancients[i], first+uint64(i)) + DeleteCanonicalHash(batch, first+uint64(i)) + } +@@ -225,9 +226,10 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) { + // Wipe out side chains also and track dangling side chains + var dangling []common.Hash + frozen, _ = f.Ancients() // Needs reload after during freezeRange ++ trueGenesisNumber := getGenesisBlockNumber(db) + for number := first; number < frozen; number++ { + // Always keep the genesis block in active database +- if number != 0 { ++ if number != trueGenesisNumber { + dangling = ReadAllHashes(db, number) + for _, hash := range dangling { + log.Trace("Deleting side chain", "number", number, "hash", hash) +diff --git a/core/rawdb/database.go b/core/rawdb/database.go +index 7ab6dbdc6..835df8167 100644 +--- a/core/rawdb/database.go ++++ b/core/rawdb/database.go +@@ -28,10 +28,12 @@ import ( + "time" + + "github.com/ethereum/go-ethereum/common" ++ "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ethereum/go-ethereum/log" ++ "github.com/ethereum/go-ethereum/rlp" + "github.com/olekukonko/tablewriter" + ) + +@@ -265,17 +267,19 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st + // store deletion, but that's fine). + } else { + // If the freezer is empty, ensure nothing was moved yet from the key-value +- // store, otherwise we'll end up missing data. We check block #1 to decide +- // if we froze anything previously or not, but do take care of databases with +- // only the genesis block. ++ // store, otherwise we'll end up missing data. We check the block after the ++ // true genesis block to decide if we froze anything previously or not. + if ReadHeadHeaderHash(db) != common.BytesToHash(kvgenesis) { + // Key-value store contains more data than the genesis block, make sure we + // didn't freeze anything yet. +- if kvblob, _ := db.Get(headerHashKey(1)); len(kvblob) == 0 { ++ trueGenesisNumber := getGenesisBlockNumber(db) ++ nextBlockNumber := trueGenesisNumber + 1 ++ ++ if kvblob, _ := db.Get(headerHashKey(nextBlockNumber)); len(kvblob) == 0 { + printChainMetadata(db) + return nil, errors.New("ancient chain segments already extracted, please set --datadir.ancient to the correct path") + } +- // Block #1 is still in the database, we're allowed to init a new freezer ++ // Block after true genesis is still in the database, we're allowed to init a new freezer + } + // Otherwise, the head header is still the genesis, we're allowed to init a new + // freezer. +@@ -680,3 +684,25 @@ func SafeDeleteRange(db ethdb.KeyValueStore, start, end []byte, hashScheme bool, + } + return batch.Write() + } ++ ++// getGenesisBlockNumber returns the actual genesis block number from the database. ++// This is needed for custom genesis logic where the genesis block might not be at block 0. ++func getGenesisBlockNumber(db ethdb.KeyValueStore) uint64 { ++ // First check if there's a genesis block at block 0 ++ if genesisHashData, _ := db.Get(headerHashKey(0)); len(genesisHashData) > 0 { ++ genesisHash := common.BytesToHash(genesisHashData) ++ // Try to read the block header to get the number ++ if headerData, _ := db.Get(headerKey(0, genesisHash)); len(headerData) > 0 { ++ var header types.Header ++ if err := rlp.DecodeBytes(headerData, &header); err == nil { ++ // Check if this block has a custom number field ++ if header.Number.Uint64() != 0 { ++ return header.Number.Uint64() ++ } ++ } ++ } ++ } ++ ++ // If no custom number found, return 0 as default ++ return 0 ++} +-- +2.50.1 + diff --git a/test-pp-op/patch/optimism-0001-decompress-genesis.patch b/test-pp-op/patch/optimism-0001-decompress-genesis.patch new file mode 100644 index 0000000000000..9895f51016c6b --- /dev/null +++ b/test-pp-op/patch/optimism-0001-decompress-genesis.patch @@ -0,0 +1,65 @@ +From e4dc440f1d47b95d2609bbe22e06d9878bcaa59c Mon Sep 17 00:00:00 2001 +From: "xingqiang.yuan" +Date: Tue, 19 Aug 2025 22:18:30 +0800 +Subject: [PATCH] decompress genesis + +--- + op-program/chainconfig/chaincfg.go | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/op-program/chainconfig/chaincfg.go b/op-program/chainconfig/chaincfg.go +index b4ae0ff95..58fa20dbf 100644 +--- a/op-program/chainconfig/chaincfg.go ++++ b/op-program/chainconfig/chaincfg.go +@@ -1,10 +1,15 @@ + package chainconfig + + import ( ++ "bytes" ++ "compress/gzip" ++ "crypto/md5" + "embed" + "encoding/json" + "errors" + "fmt" ++ "github.com/ethereum/go-ethereum/log" ++ "io" + "os" + "strings" + +@@ -87,6 +92,20 @@ func ChainConfigByChainID(chainID eth.ChainID) (*params.ChainConfig, error) { + return chainConfigByChainID(chainID, customChainConfigFS) + } + ++func decompressGzip(data []byte) ([]byte, error) { ++ reader, err := gzip.NewReader(bytes.NewReader(data)) ++ if err != nil { ++ return nil, err ++ } ++ defer reader.Close() ++ ++ var uncompressedData bytes.Buffer ++ if _, err := io.Copy(&uncompressedData, reader); err != nil { ++ return nil, err ++ } ++ return uncompressedData.Bytes(), nil ++} ++ + func chainConfigByChainID(chainID eth.ChainID, customChainFS embed.FS) (*params.ChainConfig, error) { + // Load from custom chain configs from embed FS + data, err := customChainFS.ReadFile(fmt.Sprintf("configs/%v-genesis-l2.json", chainID)) +@@ -95,6 +114,11 @@ func chainConfigByChainID(chainID eth.ChainID, customChainFS embed.FS) (*params. + } else if err != nil { + return nil, fmt.Errorf("failed to get chain config for chain ID %v: %w", chainID, err) + } ++ data, err = decompressGzip(data) ++ if err != nil { ++ return nil, fmt.Errorf("failed to decompress for chain ID %v: %w", chainID, err) ++ } ++ log.Info("decompress genesis", "chain id", chainID, "md5 hash", md5.Sum(data)) + var genesis core.Genesis + err = json.Unmarshal(data, &genesis) + if err != nil { +-- +2.39.5 (Apple Git-154) + diff --git a/test-pp-op/patch/optimism-0001-support-regenesis-op-geth-prestate.patch b/test-pp-op/patch/optimism-0001-support-regenesis-op-geth-prestate.patch new file mode 100644 index 0000000000000..ad0dffc4ffc92 --- /dev/null +++ b/test-pp-op/patch/optimism-0001-support-regenesis-op-geth-prestate.patch @@ -0,0 +1,82 @@ +diff --git a/Makefile b/Makefile +index b7e2e8102c..76f87fc9cf 100644 +--- a/Makefile ++++ b/Makefile +@@ -13,7 +13,7 @@ help: ## Prints this help message + build: build-go build-contracts ## Builds Go components and contracts-bedrock + .PHONY: build + +-build-go: submodules op-node op-proposer op-batcher op-challenger op-dispute-mon op-program cannon ## Builds main Go components ++build-go: submodules op-node op-proposer op-batcher op-challenger op-dispute-mon op-program cannon withdrawal ## Builds main Go components + .PHONY: build-go + + build-contracts: +@@ -128,6 +128,10 @@ cannon: ## Builds cannon binary + make -C ./cannon cannon + .PHONY: cannon + ++withdrawal: ## Builds withdrawal binary ++ just $(JUSTFLAGS) ./op-chain-ops/withdrawal ++.PHONY: withdrawal ++ + reproducible-prestate: ## Builds reproducible-prestate binary + make -C ./op-program reproducible-prestate + .PHONY: reproducible-prestate +diff --git a/go.mod b/go.mod +index b09102566e..7a3fc16755 100644 +--- a/go.mod ++++ b/go.mod +@@ -304,9 +304,9 @@ require ( + rsc.io/tmplfunc v0.0.3 // indirect + ) + +-replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101511.1-dev.1.0.20250608235258-6005dd53e1b5 ++// replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101511.1-dev.1.0.20250608235258-6005dd53e1b5 + +-//replace github.com/ethereum/go-ethereum => ../op-geth ++replace github.com/ethereum/go-ethereum => ./op-geth + + // replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain + +diff --git a/op-chain-ops/justfile b/op-chain-ops/justfile +index ee7efe7d6c..82ddb5467a 100644 +--- a/op-chain-ops/justfile ++++ b/op-chain-ops/justfile +@@ -12,9 +12,12 @@ _LDFLAGSSTRING := "'" + trim( + # Build ecotone-scalar binary + ecotone-scalar: (go_build "./bin/ecotone-scalar" "./cmd/ecotone-scalar" "-ldflags" _LDFLAGSSTRING) + +-# Build receipt-reference-builder binary ++# Build receipt-reference-builder binary + receipt-reference-builder: (go_build "./bin/receipt-reference-builder" "./cmd/receipt-reference-builder" "-ldflags" _LDFLAGSSTRING) + ++# Build withdrawal binary ++withdrawal: (go_build "./bin/withdrawal" "./cmd/withdrawal" "-ldflags" _LDFLAGSSTRING) ++ + # Run tests + test: (go_test "./...") + +diff --git a/op-program/Dockerfile.repro b/op-program/Dockerfile.repro +index 2f861f3b2f..b97057cd4e 100644 +--- a/op-program/Dockerfile.repro ++++ b/op-program/Dockerfile.repro +@@ -6,6 +6,7 @@ RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash just + + COPY ./go.mod /app/go.mod + COPY ./go.sum /app/go.sum ++COPY ./op-geth /app/op-geth + + WORKDIR /app + +diff --git a/op-program/Dockerfile.repro.dockerignore b/op-program/Dockerfile.repro.dockerignore +index 15d6cf7638..2844c7a062 100644 +--- a/op-program/Dockerfile.repro.dockerignore ++++ b/op-program/Dockerfile.repro.dockerignore +@@ -5,6 +5,7 @@ + # internal dependencies + !cannon/ + !op-alt-da/ ++!op-geth/ + !op-node/ + !op-preimage/ + !op-program/ diff --git a/test-pp-op/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch b/test-pp-op/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch new file mode 100644 index 0000000000000..989533773b258 --- /dev/null +++ b/test-pp-op/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch @@ -0,0 +1,70 @@ +From 8085cc9eae7a360862cf23472ed179cb14ab29c8 Mon Sep 17 00:00:00 2001 +From: JimmyShi +Date: Tue, 8 Jul 2025 14:27:45 +0800 +Subject: [PATCH] support sync L2 block at given number + +--- + cmd/run.go | 2 +- + config/network.go | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/cmd/run.go b/cmd/run.go +index a49c802..da7cf69 100644 +--- a/cmd/run.go ++++ b/cmd/run.go +@@ -109,7 +109,7 @@ func start(ctx *cli.Context) error { + chSyncedL2 := make(chan uint32) + chsExitRootEvent = append(chsExitRootEvent, chExitRootEventL2) + chsSyncedL2 = append(chsSyncedL2, chSyncedL2) +- go runSynchronizer(ctx.Context, 0, bridgeController, l2EthermanClient, c.Synchronizer, storage, zkEVMClient, chExitRootEventL2, nil, chSyncedL2, []uint32{}, c.NetworkConfig.RequireSovereignChainSmcs[i]) ++ go runSynchronizer(ctx.Context, c.NetworkConfig.L2GenBlockNumber, bridgeController, l2EthermanClient, c.Synchronizer, storage, zkEVMClient, chExitRootEventL2, nil, chSyncedL2, []uint32{}, c.NetworkConfig.RequireSovereignChainSmcs[i]) + } + chSynced := make(chan uint32) + go runSynchronizer(ctx.Context, c.NetworkConfig.GenBlockNumber, bridgeController, l1Etherman, c.Synchronizer, storage, nil, nil, chsExitRootEvent, chSynced, networkIDs, false) +diff --git a/config/network.go b/config/network.go +index 4edeb4f..ae332f9 100644 +--- a/config/network.go ++++ b/config/network.go +@@ -8,6 +8,7 @@ import ( + // NetworkConfig is the configuration struct for the different environments. + type NetworkConfig struct { + GenBlockNumber uint64 ++ L2GenBlockNumber uint64 + PolygonBridgeAddress common.Address + PolygonZkEVMGlobalExitRootAddress common.Address + PolygonRollupManagerAddress common.Address +@@ -26,6 +27,7 @@ var ( + networkConfigs = map[string]NetworkConfig{ + defaultNetwork: { + GenBlockNumber: 16896718, ++ L2GenBlockNumber: 0, + PolygonBridgeAddress: common.HexToAddress("0x2a3DD3EB832aF982ec71669E178424b10Dca2EDe"), + PolygonZkEVMGlobalExitRootAddress: common.HexToAddress("0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb"), + PolygonRollupManagerAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"), +@@ -37,6 +39,7 @@ var ( + + "testnet": { + GenBlockNumber: 8572995, ++ L2GenBlockNumber: 0, + PolygonBridgeAddress: common.HexToAddress("0xF6BEEeBB578e214CA9E23B0e9683454Ff88Ed2A7"), + PolygonZkEVMGlobalExitRootAddress: common.HexToAddress("0x4d9427DCA0406358445bC0a8F88C26b704004f74"), + PolygonRollupManagerAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"), +@@ -47,6 +50,7 @@ var ( + }, + "internaltestnet": { + GenBlockNumber: 7674349, ++ L2GenBlockNumber: 0, + PolygonBridgeAddress: common.HexToAddress("0x47c1090bc966280000Fe4356a501f1D0887Ce840"), + PolygonZkEVMGlobalExitRootAddress: common.HexToAddress("0xA379Dd55Eb12e8FCdb467A814A15DE2b29677066"), + PolygonRollupManagerAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"), +@@ -57,6 +61,7 @@ var ( + }, + "local": { + GenBlockNumber: 1, ++ L2GenBlockNumber: 0, + PolygonBridgeAddress: common.HexToAddress("0xFe12ABaa190Ef0c8638Ee0ba9F828BF41368Ca0E"), + PolygonZkEVMGlobalExitRootAddress: common.HexToAddress("0x8A791620dd6260079BF849Dc5567aDC3F2FdC318"), + PolygonRollupManagerAddress: common.HexToAddress("0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e"), +-- +2.39.5 (Apple Git-154) + diff --git a/test-pp-op/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch b/test-pp-op/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch new file mode 100644 index 0000000000000..c225790de1a45 --- /dev/null +++ b/test-pp-op/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch @@ -0,0 +1,30 @@ +From 3e3c4fa34b5e51e2436ae81faaf1fad90c136d39 Mon Sep 17 00:00:00 2001 +From: KyrinCode +Date: Sat, 13 Sep 2025 00:50:53 +0800 +Subject: [PATCH 1/2] skip reorg check after regenesis + +--- + synchronizer/synchronizer.go | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go +index 5708756..96088b0 100644 +--- a/synchronizer/synchronizer.go ++++ b/synchronizer/synchronizer.go +@@ -602,6 +602,13 @@ hash and has parent. This operation has to be done until a match is found. + */ + func (s *ClientSynchronizer) checkReorg(latestStoredBlock etherman.Block, syncedBlock *etherman.Block) (*etherman.Block, error) { + // This function only needs to worry about reorgs if some of the reorganized blocks contained rollup info. ++ ++ // Skip reorg check after a regenesis ++ if latestStoredBlock.BlockNumber < s.genBlockNumber { ++ log.Debugf("NetworkID: %d, skipping reorg check after a regenesis. Latest stored block: %d, genesis block: %d", s.networkID, latestStoredBlock.BlockNumber, s.genBlockNumber) ++ return nil, nil ++ } ++ + latestStoredEthBlock := latestStoredBlock + reorgedBlock := latestStoredBlock + var depth uint64 +-- +2.39.5 (Apple Git-154) + diff --git a/test-pp-op/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch b/test-pp-op/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch new file mode 100644 index 0000000000000..2c105507b8897 --- /dev/null +++ b/test-pp-op/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch @@ -0,0 +1,31 @@ +From 98e29ad0cf2625914c1d3b56b6ebd8648f647d49 Mon Sep 17 00:00:00 2001 +From: KyrinCode +Date: Sat, 13 Sep 2025 00:51:47 +0800 +Subject: [PATCH 2/2] skip syncing blocks before regenesis + +--- + synchronizer/synchronizer.go | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go +index 96088b0..69d8224 100644 +--- a/synchronizer/synchronizer.go ++++ b/synchronizer/synchronizer.go +@@ -128,6 +128,14 @@ func (s *ClientSynchronizer) Sync() error { + return err + } + } ++ if lastBlockSynced.BlockNumber < s.genBlockNumber { ++ log.Debugf("networkID: %d, latest stored block is before regenesis block. Setting regenesis block", s.networkID) ++ lastBlockSynced = ðerman.Block{ ++ BlockNumber: s.genBlockNumber, ++ NetworkID: s.networkID, ++ } ++ } ++ + metrics.InitializationTime(time.Since(startInitialization)) + log.Debugf("NetworkID: %d, initial lastBlockSynced: %+v", s.networkID, lastBlockSynced) + for { +-- +2.39.5 (Apple Git-154) + diff --git a/test-pp-op/scripts/active-sequencer.sh b/test-pp-op/scripts/active-sequencer.sh new file mode 100755 index 0000000000000..660143afeb01e --- /dev/null +++ b/test-pp-op/scripts/active-sequencer.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Function to detect leader conductor and set ports +detect_leader() { + echo "Detecting leader conductor..." + + # Check all three conductors to find the leader + for i in 1 2 3; do + CONDUCTOR_PORT=$((8546 + i)) # 8547, 8548, 8549 + SEQUENCER_PORT=$((9544 + i)) # 9545, 9546, 9547 + + IS_LEADER=$(curl -sS -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ + http://localhost:$CONDUCTOR_PORT 2>/dev/null | jq -r '.result' 2>/dev/null) + + if [ "$IS_LEADER" = "true" ]; then + LEADER_CONDUCTOR_PORT=$CONDUCTOR_PORT + LEADER_SEQUENCER_PORT=$SEQUENCER_PORT + echo "Found leader: Conductor $i (conductor port: $LEADER_CONDUCTOR_PORT, sequencer port: $LEADER_SEQUENCER_PORT)" + return 0 + else + echo "Conductor $i (port $CONDUCTOR_PORT): not leader (result: $IS_LEADER)" + fi + done + + echo "Error: No leader conductor found!" + exit 1 +} + +# Detect leader conductor and set ports +detect_leader + +# 1. check connected peers +CONNECTED=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"opp2p_peerStats","params":[],"id":1}' http://localhost:$LEADER_SEQUENCER_PORT | jq .result.connected) +if (( CONNECTED < 2 )); then + echo "$CONNECTED peers connected, which is less than 2" + echo 1 +fi + +# 2. try to resume conductor if it is paused +PAUSED=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_paused","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq -r .result) +if [ $PAUSED = "true" ]; then + curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_resume","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT + PAUSED=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_paused","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq -r .result) + if [ $PAUSED = "true" ]; then + echo "conductor is paused due to resume failure" + exit 1 + fi +fi + +# 3. try to start sequencer if it is stopped +ACTIVE=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_sequencerActive","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq -r .result) +if [ $ACTIVE = "false" ]; then + BLOCK_HASH=$(curl -sS -X POST -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false],"id":1}' http://localhost:8123 | jq -r .result.hash) + if [ -z "$BLOCK_HASH" ] || [ "$BLOCK_HASH" = "null" ]; then + echo "Failed to get latest block hash" + exit 1 + fi + echo "Got latest block hash: $BLOCK_HASH" + + # 3. Start sequencer with the block hash + curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_startSequencer","params":["'"$BLOCK_HASH"'"],"id":1}' http://localhost:$LEADER_SEQUENCER_PORT + if [ $? -ne 0 ]; then + echo "Failed to start sequencer" + exit 1 + fi +fi + +# 4. verify sequencer is active +sleep 1 +ACTIVE=$(curl -sS -X POST -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"admin_sequencerActive","params":[],"id":1}' http://localhost:$LEADER_SEQUENCER_PORT | jq -r .result) +if [ "$ACTIVE" != "true" ]; then + echo "Failed to activate sequencer" + exit 1 +fi + +echo "Sequencer successfully activated" + +# 5. try to add other two conductors to raft consensus cluster +SERVER_COUNT=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_clusterMembership","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq '.result.servers | length') +if (( $SERVER_COUNT < 3 )); then + curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_addServerAsVoter","params":["conductor-2", "op-conductor2:50050", 0],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT + curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_addServerAsVoter","params":["conductor-3", "op-conductor3:50050", 0],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT + SERVER_COUNT=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_clusterMembership","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq '.result.servers | length') + if (( $SERVER_COUNT != 3 )); then + echo "unexpected server count, expected: 3, real: $SERVER_COUNT" + exit 1 + fi + + echo "add 2 new voters to raft consensus cluster successfully!" +fi diff --git a/test-pp-op/scripts/add-game-type.sh b/test-pp-op/scripts/add-game-type.sh new file mode 100755 index 0000000000000..4ae3e209b6c6b --- /dev/null +++ b/test-pp-op/scripts/add-game-type.sh @@ -0,0 +1,192 @@ +#!/bin/bash + +set -e + +# Source environment variables +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="$(dirname "$SCRIPT_DIR")/.env" +source "$ENV_FILE" + +# Function to set respected game type +set_respected_game_type() { + local GAME_TYPE=${1:-0} # Default to game type 0 + + echo "=== Setting Respected Game Type to $GAME_TYPE ===" + + # Get contract addresses + echo " 📋 Gathering contract addresses..." + DISPUTE_GAME_FACTORY_ADDR=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'disputeGameFactory()(address)') + OPTIMISM_PORTAL_ADDR=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'optimismPortal()(address)') + ANCHOR_STATE_REGISTRY_ADDR=$(cast call --rpc-url $L1_RPC_URL $OPTIMISM_PORTAL_ADDR 'anchorStateRegistry()(address)') + GAME_ADDR=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDR 'gameImpls(uint32)(address)' $GAME_TYPE) + + echo "Contract addresses:" + echo " Dispute Game Factory: $DISPUTE_GAME_FACTORY_ADDR" + echo " Optimism Portal: $OPTIMISM_PORTAL_ADDR" + echo " Anchor State Registry: $ANCHOR_STATE_REGISTRY_ADDR" + echo " Game Implementation ($GAME_TYPE): $GAME_ADDR" + echo "" + + # Execute transaction and capture output + echo "Setting respected game type to $GAME_TYPE..." + # Use --legacy to force Type 0 transactions, avoiding EIP-1559 gas estimation issues on local testnet + TX_OUTPUT=$(cast send \ + --json \ + --legacy \ + --rpc-url $L1_RPC_URL \ + --private-key $DEPLOYER_PRIVATE_KEY \ + --from $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY) \ + $ANCHOR_STATE_REGISTRY_ADDR \ + 'setRespectedGameType(uint32)' \ + $GAME_TYPE) + + # Extract transaction hash and status + TX_HASH=$(echo "$TX_OUTPUT" | jq -r '.transactionHash // empty') + TX_STATUS=$(echo "$TX_OUTPUT" | jq -r '.status // empty') + + echo "Transaction sent, TX_HASH: $TX_HASH" + + # Check if transaction was successful + if [ "$TX_STATUS" = "0x1" ] || [ "$TX_STATUS" = "1" ]; then + echo " ✅ setRespectedGameType completed successfully" + else + echo " ❌ Transaction failed with status: $TX_STATUS" + echo "Full output: $TX_OUTPUT" + exit 1 + fi +} + +# Function to add game type via Transactor +add_game_type_via_transactor() { + # Check parameter count + if [ $# -ne 5 ]; then + echo "Error: add_game_type_via_transactor requires exactly 5 parameters" + echo "Usage: add_game_type_via_transactor " + echo "Example: add_game_type_via_transactor 2 true 600 1800 0x..." + return 1 + fi + + local GAME_TYPE=$1 + local IS_PERMISSIONED=$2 + local CLOCK_EXTENSION_VAL=$3 + local MAX_CLOCK_DURATION_VAL=$4 + local ABSOLUTE_PRESTATE_VAL=$5 + + echo "=== Adding Game Type $GAME_TYPE via Transactor ===" + echo " Game Type: $GAME_TYPE" + echo " Is Permissioned: $IS_PERMISSIONED" + echo " Clock Extension: $CLOCK_EXTENSION_VAL" + echo " Max Clock Duration: $MAX_CLOCK_DURATION_VAL" + echo "" + + # Get dispute game factory address + DISPUTE_GAME_FACTORY=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'disputeGameFactory()(address)') + + echo "Debug Info:" + echo " State JSON: $STATE_JSON_PATH" + echo " Dispute Game Factory: $DISPUTE_GAME_FACTORY" + echo " System Config: $SYSTEM_CONFIG_PROXY_ADDRESS" + echo " Proxy Admin: $PROXY_ADMIN" + echo " OPCM: $OPCM_IMPL_ADDRESS" + echo " Transactor: $TRANSACTOR" + echo " RPC URL: $L1_RPC_URL" + echo " Sender: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" + echo "" + + # Retrieve existing permissioned game implementation for parameters + echo "Retrieving permissioned game parameters..." + PERMISSIONED_GAME=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' 1) + echo "Permissioned Game Implementation: $PERMISSIONED_GAME" + + if [ "$PERMISSIONED_GAME" == "0x0000000000000000000000000000000000000000" ]; then + echo "Error: No permissioned game found. Cannot retrieve parameters." + exit 1 + fi + + # Retrieve parameters from existing permissioned game + ABSOLUTE_PRESTATE="$ABSOLUTE_PRESTATE_VAL" + MAX_GAME_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'maxGameDepth()') + SPLIT_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'splitDepth()') + VM=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'vm()(address)') + + echo "Retrieved parameters:" + echo " Absolute Prestate: $ABSOLUTE_PRESTATE" + echo " Max Game Depth: $MAX_GAME_DEPTH" + echo " Split Depth: $SPLIT_DEPTH" + echo " Clock Extension: $CLOCK_EXTENSION_VAL" + echo " Max Clock Duration: $MAX_CLOCK_DURATION_VAL" + echo " VM: $VM" + echo "" + + # Set constants + INITIAL_BOND='1000000000000000000' # 1 ETH in wei + SALT_MIXER='123' # Unique salt for game type + + echo "Creating addGameType calldata..." + + # Build game type parameters array (simplified) + GAME_PARAMS="[(\"$SALT_MIXER\",$SYSTEM_CONFIG_PROXY_ADDRESS,$PROXY_ADMIN,0x0000000000000000000000000000000000000000,$GAME_TYPE,$ABSOLUTE_PRESTATE,$MAX_GAME_DEPTH,$SPLIT_DEPTH,$CLOCK_EXTENSION_VAL,$MAX_CLOCK_DURATION_VAL,$INITIAL_BOND,$VM,$IS_PERMISSIONED)]" + + echo "Parameters prepared for addGameType" + + # Execute the transaction through Transactor + echo "Executing transaction via Transactor..." + echo "Target: $TRANSACTOR" + echo "From: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" + + # Simplified DELEGATECALL - build calldata first, then call + ADDGAMETYPE_CALLDATA=$(cast calldata 'addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[])' "$GAME_PARAMS") + + # Execute transaction and capture output + # Use --legacy to force Type 0 transactions, avoiding EIP-1559 gas estimation issues on local testnet + TX_OUTPUT=$(cast send \ + --json \ + --legacy \ + --rpc-url $L1_RPC_URL \ + --private-key $DEPLOYER_PRIVATE_KEY \ + --from $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY) \ + $TRANSACTOR \ + 'DELEGATECALL(address,bytes)' \ + $OPCM_IMPL_ADDRESS \ + $ADDGAMETYPE_CALLDATA) + + # Extract transaction hash and status + TX_HASH=$(echo "$TX_OUTPUT" | jq -r '.transactionHash // empty') + TX_STATUS=$(echo "$TX_OUTPUT" | jq -r '.status // empty') + + echo "" + echo "Transaction sent, TX_HASH: $TX_HASH" + + # Check if transaction was successful + if [ "$TX_STATUS" = "0x1" ] || [ "$TX_STATUS" = "1" ]; then + echo " ✅ Transaction successful!" + else + echo " ❌ Transaction failed with status: $TX_STATUS" + echo "Full output: $TX_OUTPUT" + exit 1 + fi + echo "" + + # Verify the new game type was added + echo "Verifying new game type was added..." + NEW_GAME_IMPL=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' $GAME_TYPE) + + if [ "$NEW_GAME_IMPL" != "0x0000000000000000000000000000000000000000" ]; then + echo " ✅ Success! New game type $GAME_TYPE added." + echo "Game Type $GAME_TYPE Implementation: $NEW_GAME_IMPL" + else + echo " ❌ Warning: Could not verify game type was added. Check transaction status." + fi + + echo " ✅ AddGameType operations completed successfully" + + # Set the newly added game type as respected + echo "" + set_respected_game_type "$GAME_TYPE" +} + +# Main execution +if [ "${BASH_SOURCE[0]}" == "${0}" ]; then + # Script is being executed directly - call the function + add_game_type_via_transactor "$@" +fi diff --git a/test-pp-op/scripts/deposit-from-banker.sh b/test-pp-op/scripts/deposit-from-banker.sh new file mode 100755 index 0000000000000..db1e6601efc9f --- /dev/null +++ b/test-pp-op/scripts/deposit-from-banker.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e +set -x + +BANKER_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d +BANKER=$(cast wallet a $BANKER_PRIVATE_KEY) + +# Source environment variables +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="$(dirname "$SCRIPT_DIR")/.env" +source "$ENV_FILE" + +TO_ADDRESS=0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534 +AMOUNT=1000000ether + +cast send $TO_ADDRESS --value $AMOUNT --legacy --rpc-url=$L2_RPC_URL --private-key=$BANKER_PRIVATE_KEY diff --git a/test-pp-op/scripts/deposit-from-l1.sh b/test-pp-op/scripts/deposit-from-l1.sh new file mode 100755 index 0000000000000..e8cd0edc996fc --- /dev/null +++ b/test-pp-op/scripts/deposit-from-l1.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +set -e + +# Source environment variables +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="$(dirname "$SCRIPT_DIR")/.env" +source "$ENV_FILE" + +OP_PORTAL_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy' config-op/state.json) +PRIVATE_KEY="0x815405dddb0e2a99b12af775fd2929e526704e1d1aea6a0b4e74dc33e2f7fcd2" +ADDRESS=$(cast wallet a $PRIVATE_KEY) #0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534 +ETHER=1000000000000000000 +AMOUNT=$(python3 -c "print(3000 * $ETHER)") +AMOUNT_PLUS_FEE=$(python3 -c "print($AMOUNT + $ETHER)") + +cast send --private-key $RICH_L1_PRIVATE_KEY --value $AMOUNT_PLUS_FEE $ADDRESS --legacy --rpc-url $L1_RPC_URL + +PRE_BALANCE=$(cast balance $ADDRESS --rpc-url=$L2_RPC_URL) + +cast send \ + --legacy \ + --private-key $PRIVATE_KEY \ + --value $AMOUNT \ + $OP_PORTAL_ADDRESS \ + 'function depositTransaction(address _target, uint256 _value, uint64 _gasLimit, bool _isCreation, bytes _data)' \ + $ADDRESS $AMOUNT 100000 false 0x --rpc-url $L1_RPC_URL + +echo " 📋 Initial balance: $PRE_BALANCE" + +START_TIME=$(date +%s) + +while true; do + NEW_BALANCE=$(cast balance $ADDRESS --rpc-url=$L2_RPC_URL) + + if [ "$NEW_BALANCE" != "$PRE_BALANCE" ]; then + CURRENT_TIME=$(date +%s) + ELAPSED_TIME=$((CURRENT_TIME - START_TIME)) + echo " ✅ Balance changed!" + echo " 📋 Previous balance: $PRE_BALANCE" + echo " 📋 New balance: $NEW_BALANCE" + echo " ⏱️ Total wait time: ${ELAPSED_TIME}s" + break + fi + + echo " ⏳ waiting for change..." + sleep 3 +done diff --git a/test-pp-op/scripts/docker-install-start.sh b/test-pp-op/scripts/docker-install-start.sh new file mode 100755 index 0000000000000..27177b7171ce4 --- /dev/null +++ b/test-pp-op/scripts/docker-install-start.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Install Docker in Docker and start Docker daemon + +# If default (rooted Docker) is used, just exit +if [ "$1" == "default" ]; then + exit 0 +fi + +# Otherwise (rootless Docker): remove docker.io, install and configure Docker in Docker +apt-get update +apt-get remove -y --purge docker.io + +curl -sSL https://get.docker.com/ | sh + +# The code below is taken from: https://github.com/moby/moby/blob/v26.0.1/hack/dind#L59 +# It is used to avoid the error: "docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: unable to apply cgroup configuration: cannot enter cgroupv2 "/sys/fs/cgroup/docker" with domain controllers -- it is in threaded mode: unknown." +# cgroup v2: enable nesting +if [ -f /sys/fs/cgroup/cgroup.controllers ]; then + # move the processes from the root group to the /init group, + # otherwise writing subtree_control fails with EBUSY. + # An error during moving non-existent process (i.e., "cat") is ignored. + mkdir -p /sys/fs/cgroup/init + xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : + # enable controllers + sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \ + > /sys/fs/cgroup/cgroup.subtree_control +fi + +# Start Docker daemon +dockerd > /dockerd.log 2>&1 & diff --git a/test-pp-op/scripts/gray-upgrade-simulation.sh b/test-pp-op/scripts/gray-upgrade-simulation.sh new file mode 100755 index 0000000000000..8bdcb60ab32bb --- /dev/null +++ b/test-pp-op/scripts/gray-upgrade-simulation.sh @@ -0,0 +1,309 @@ +#!/bin/bash + +set -e + +BASE_CONDUCTOR_PORT=8547 +BASE_SEQUENCER_PORT=9545 +CURRENT_LEADER=0 +UPGRADED_SEQUENCER=0 + +# Function to check if a conductor is leader +check_leader() { + local conductor_id=$1 + local port=$((BASE_CONDUCTOR_PORT + conductor_id - 1)) + curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ + http://localhost:$port | jq -r .result +} + +# Function to stop containers +stop_containers() { + local sequencer_id=$1 + echo "Stopping containers for sequencer-$sequencer_id..." + + # Handle sequencer 1 (no suffix) vs others (with suffix) + if [ "$sequencer_id" = "1" ]; then + docker stop op-seq op-geth-seq 2>/dev/null || true + echo "Containers stopped: op-seq, op-geth-seq" + else + docker stop op-seq$sequencer_id op-geth-seq$sequencer_id 2>/dev/null || true + echo "Containers stopped: op-seq$sequencer_id, op-geth-seq$sequencer_id" + fi +} + +# Function to start containers +start_containers() { + local sequencer_id=$1 + echo "Starting containers for sequencer-$sequencer_id..." + + # Handle sequencer 1 (no suffix) vs others (with suffix) + if [ "$sequencer_id" = "1" ]; then + docker start op-seq op-geth-seq 2>/dev/null || true + echo "Containers started: op-seq, op-geth-seq" + else + docker start op-seq$sequencer_id op-geth-seq$sequencer_id 2>/dev/null || true + echo "Containers started: op-seq$sequencer_id, op-geth-seq$sequencer_id" + fi +} + +# Function to wait for service to be ready +wait_for_service() { + local port=$1 + local service_name=$2 + local max_attempts=30 + local attempt=0 + + echo "Waiting for $service_name to be ready on port $port..." + while [ $attempt -lt $max_attempts ]; do + if curl -s http://localhost:$port > /dev/null 2>&1; then + echo "$service_name is ready" + return 0 + fi + sleep 1 + ((attempt++)) + done + echo "Warning: $service_name not ready after $max_attempts seconds" + return 1 +} + +# Function to find current leader +find_current_leader() { + for i in {0..2}; do + local port=$((BASE_CONDUCTOR_PORT + i)) + local is_leader=$(check_leader $((i+1))) + + if [ "$is_leader" = "true" ]; then + CURRENT_LEADER=$((i+1)) + echo "conductor-$CURRENT_LEADER is current leader (port $port)" + return 0 + fi + done + echo "No leader found!" + return 1 +} + +# Function to extract block info from sequencer logs +extract_last_block_info() { + local sequencer_id=$1 + + # Handle sequencer 1 (no suffix) vs others (with suffix) + local container_name + if [ "$sequencer_id" = "1" ]; then + container_name="op-seq" + else + container_name="op-seq$sequencer_id" + fi + + echo "Extracting last block info from $container_name..." >&2 + + # Get the last "Sequencer inserted block" log entry + local last_block_log=$(docker logs $container_name 2>&1 | grep "Sequencer inserted block" | tail -1) + + if [ -z "$last_block_log" ]; then + echo "❌ No 'Sequencer inserted block' log found in $container_name" >&2 + return 1 + fi + + echo "Last block log: $last_block_log" >&2 + + # Extract block hash and number using regex + if [[ $last_block_log =~ block=([^[:space:]]+) ]]; then + local block_info="${BASH_REMATCH[1]}" + echo "Block info: $block_info" >&2 + + # Split block hash and number (format: hash:number) + if [[ $block_info =~ ^([^:]+):([0-9]+)$ ]]; then + local block_hash="${BASH_REMATCH[1]}" + local block_number="${BASH_REMATCH[2]}" + echo "Extracted - Block Hash: $block_hash, Block Number: $block_number" >&2 + echo "$block_hash:$block_number" + return 0 + else + echo "❌ Failed to parse block info format: $block_info" >&2 + return 1 + fi + else + echo "❌ Failed to extract block info from log: $last_block_log" >&2 + return 1 + fi +} + +# Function to check if new leader continues from previous block +check_block_continuity() { + local prev_sequencer_id=$1 + local new_sequencer_id=$2 + local prev_block_info=$3 + + echo "Checking block continuity from sequencer-$prev_sequencer_id to sequencer-$new_sequencer_id..." + echo "Previous block info: $prev_block_info" + + # Parse previous block info + local prev_block_hash=$(echo "$prev_block_info" | cut -d':' -f1) + local prev_block_number=$(echo "$prev_block_info" | cut -d':' -f2) + + echo "Looking for block with parent=$prev_block_hash:$prev_block_number in sequencer-$new_sequencer_id..." + + # Check if new sequencer has a block with the previous block as parent + local container_name + if [ "$new_sequencer_id" = "1" ]; then + container_name="op-seq" + else + container_name="op-seq$new_sequencer_id" + fi + local continuity_log=$(docker logs $container_name 2>&1 | grep "Sequencer inserted block" | grep "parent=$prev_block_hash:$prev_block_number" | tail -1) + + if [ -n "$continuity_log" ]; then + echo "✅ Block continuity verified!" + echo "Continuity log: $continuity_log" + + # Extract the new block info + if [[ $continuity_log =~ block=([^[:space:]]+) ]]; then + local new_block_info="${BASH_REMATCH[1]}" + echo "New block info: $new_block_info" + return 0 + fi + else + echo "❌ Block continuity check failed - no block found with parent=$prev_block_hash:$prev_block_number" + return 1 + fi +} + +# Function to transfer leadership +transfer_leadership() { + local from_conductor=$1 + local to_conductor=$2 + local from_port=$((BASE_CONDUCTOR_PORT + from_conductor - 1)) + + # Build target conductor address + local target_addr="op-conductor" + [ "$to_conductor" != "1" ] && target_addr="${target_addr}${to_conductor}" + target_addr="${target_addr}:50050" + + echo "Transferring leadership from conductor-$from_conductor to conductor-$to_conductor..." + curl -s -X POST -H "Content-Type: application/json" \ + --data "{\"jsonrpc\":\"2.0\",\"method\":\"conductor_transferLeaderToServer\",\"params\":[\"conductor-$to_conductor\", \"$target_addr\"],\"id\":1}" \ + http://localhost:$from_port > /dev/null + echo "Leadership transfer command sent" +} + +echo "=== Starting Gray Upgrade Simulation ===" + +# Step 1: Find current leader +echo "Step 1: Finding current leader..." +if ! find_current_leader; then + echo "Error: No leader found, exiting" + exit 1 +fi + +# Step 2: Select a follower sequencer for upgrade +echo "Step 2: Selecting a follower sequencer for upgrade..." +# Find a follower (non-leader) sequencer to upgrade +UPGRADED_SEQUENCER=0 +for i in {1..3}; do + if [ "$i" != "$CURRENT_LEADER" ]; then + UPGRADED_SEQUENCER=$i + echo "Selected sequencer-$UPGRADED_SEQUENCER for upgrade (current leader is sequencer-$CURRENT_LEADER)" + break + fi +done + +if [ "$UPGRADED_SEQUENCER" -eq 0 ]; then + echo "Error: No follower sequencer found for upgrade" + exit 1 +fi + +# Step 3: Stop containers for the selected follower sequencer +echo "Step 3: Stopping containers for sequencer-$UPGRADED_SEQUENCER (simulating shutdown for upgrade)..." +stop_containers $UPGRADED_SEQUENCER + +# Step 4: Wait 10 seconds (simulating upgrade time) +echo "Step 4: Waiting 10 seconds for upgrade simulation..." +sleep 10 + +# Step 5: Restart containers +echo "Step 5: Restarting containers for sequencer-$UPGRADED_SEQUENCER (simulating post-upgrade restart)..." +start_containers $UPGRADED_SEQUENCER + +# Step 6: Wait for services to be ready +echo "Step 6: Waiting for services to be ready..." +wait_for_service $((BASE_SEQUENCER_PORT + UPGRADED_SEQUENCER - 1)) "op-seq$UPGRADED_SEQUENCER" +wait_for_service $((BASE_CONDUCTOR_PORT + UPGRADED_SEQUENCER - 1)) "op-conductor$UPGRADED_SEQUENCER" + +# Step 7: Verify the upgraded sequencer is inactive +echo "Step 7: Verifying upgraded sequencer is inactive..." +sleep 5 # Give it time to sync +is_leader_after_restart=$(check_leader $UPGRADED_SEQUENCER) + +if [ "$is_leader_after_restart" = "false" ]; then + echo "✅ Verified: Upgraded sequencer-$UPGRADED_SEQUENCER is inactive (not leader)" +else + echo "❌ Error: Upgraded sequencer-$UPGRADED_SEQUENCER is unexpectedly still leader" + exit 1 +fi +# Step 8: Wait for the upgraded sequencer to sync with latest blocks +echo "Step 8: Waiting 30 seconds for upgraded sequencer to sync with latest blocks..." +sleep 30 + +# Step 9: Find current leader and transfer leadership +echo "Step 9: Finding current leader and transferring leadership to upgraded sequencer..." +if ! find_current_leader; then + echo "Error: No current leader found for transfer" + exit 1 +fi + +if [ "$CURRENT_LEADER" = "$UPGRADED_SEQUENCER" ]; then + echo "✅ Upgraded sequencer-$UPGRADED_SEQUENCER is already the leader, no transfer needed" +else + echo "Current leader is conductor-$CURRENT_LEADER, transferring to conductor-$UPGRADED_SEQUENCER" + + # Transfer leadership to the upgraded sequencer + transfer_leadership $CURRENT_LEADER $UPGRADED_SEQUENCER + + # Verify the transfer was successful + sleep 2 + echo "Verifying leadership transfer..." + is_transfer_successful=$(check_leader $UPGRADED_SEQUENCER) + if [ "$is_transfer_successful" = "true" ]; then + echo "✅ Leadership transfer successful: conductor-$CURRENT_LEADER -> conductor-$UPGRADED_SEQUENCER" + + # Extract block info from previous leader AFTER transfer is confirmed + echo "Extracting block info from previous leader (sequencer-$CURRENT_LEADER) after final transfer..." + if ! CURRENT_BLOCK_INFO=$(extract_last_block_info $CURRENT_LEADER); then + echo "Warning: Could not extract block info from sequencer-$CURRENT_LEADER, continuing without continuity check" + CURRENT_BLOCK_INFO="" + fi + + # Check block continuity if we have current block info + if [ -n "$CURRENT_BLOCK_INFO" ]; then + echo "Checking block continuity after leadership transfer..." + sleep 3 # Give some time for upgraded sequencer to produce blocks + if check_block_continuity $CURRENT_LEADER $UPGRADED_SEQUENCER "$CURRENT_BLOCK_INFO"; then + echo "✅ Block continuity verified after leadership transfer" + else + echo "⚠️ Block continuity check failed after transfer, but upgrade simulation continues" + fi + fi + else + echo "❌ Leadership transfer failed, trying to find current leader..." + if find_current_leader; then + echo "Current leader is now conductor-$CURRENT_LEADER" + else + echo "Error: No leader found after transfer attempt" + exit 1 + fi + fi +fi + +# Step 10: Final verification +echo "Step 10: Final verification of upgraded sequencer leadership..." +sleep 1 + +is_leader_final=$(check_leader $UPGRADED_SEQUENCER) +if [ "$is_leader_final" = "true" ]; then + echo "✅ SUCCESS: Upgraded sequencer-$UPGRADED_SEQUENCER is now the leader!" + echo "=== Gray Upgrade Simulation Completed Successfully ===" +else + echo "❌ FAILED: Upgraded sequencer-$UPGRADED_SEQUENCER did not become leader" + echo "Final leader status: $is_leader_final" + exit 1 +fi diff --git a/test-pp-op/scripts/replace-genesis.sh b/test-pp-op/scripts/replace-genesis.sh new file mode 100755 index 0000000000000..e7817d13ae47f --- /dev/null +++ b/test-pp-op/scripts/replace-genesis.sh @@ -0,0 +1,29 @@ +#!/bin/bash +set -e + +sed_inplace() { + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + +ROOT_DIR=$(git rev-parse --show-toplevel) + +# TODO: change to the real location of genesis file +NEW_GENESIS_FILE="$ROOT_DIR/../genesis.json" + +TESTING_GENESIS_FILE="$ROOT_DIR/test/config-op/genesis.json" + +if [ -f ${TESTING_GENESIS_FILE} ]; then + mv ${TESTING_GENESIS_FILE} ${TESTING_GENESIS_FILE}.bak +fi + +cp ${NEW_GENESIS_FILE} ${TESTING_GENESIS_FILE} + +current_timestamp=$(date +%s) +hex_timestamp=$(printf "0x%x\n" "$current_timestamp") +echo "hex_timestamp: $hex_timestamp" + +sed_inplace "s/\"timestamp\": \"0x[0-9a-fA-F]*\"/\"timestamp\": \"$hex_timestamp\"/" ${TESTING_GENESIS_FILE} diff --git a/test-pp-op/scripts/set-init-bond.sh b/test-pp-op/scripts/set-init-bond.sh new file mode 100755 index 0000000000000..cac10d0149acf --- /dev/null +++ b/test-pp-op/scripts/set-init-bond.sh @@ -0,0 +1,152 @@ +#!/bin/bash + +set -e + +# Function to display usage +usage() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --game-type TYPE Game type (uint32) (required)" + echo " --init-bond WEI Initial bond amount in wei (required)" + echo " --transactor ADDRESS Transactor contract address (required)" + echo " --dispute-game-factory ADDRESS DisputeGameFactory contract address (required)" + echo " --private-key KEY Private key for transaction (required)" + echo " --rpc-url URL RPC URL (required)" + echo " --help Show this help message" + echo "" + echo "Example:" + echo " $0 --game-type 1 --init-bond 1000000000000000000 --transactor 0x456... --dispute-game-factory 0xabc... --private-key 0xdef... --rpc-url https://..." + exit 1 +} + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + --game-type) + GAME_TYPE="$2" + shift 2 + ;; + --init-bond) + INIT_BOND="$2" + shift 2 + ;; + --transactor) + TRANSACTOR_ADDRESS="$2" + shift 2 + ;; + --dispute-game-factory) + DISPUTE_GAME_FACTORY="$2" + shift 2 + ;; + --private-key) + PRIVATE_KEY="$2" + shift 2 + ;; + --rpc-url) + RPC_URL="$2" + shift 2 + ;; + --help) + usage + ;; + *) + echo "Unknown option: $1" + usage + ;; + esac +done + +# Validate required parameters +if [[ -z "$GAME_TYPE" || -z "$INIT_BOND" || -z "$TRANSACTOR_ADDRESS" || -z "$DISPUTE_GAME_FACTORY" || -z "$PRIVATE_KEY" || -z "$RPC_URL" ]]; then + echo "Error: Missing required parameters" + echo "" + usage +fi + +echo "=== Setting Init Bond via Transactor ===" +echo "Game Type: $GAME_TYPE" +echo "Init Bond: $INIT_BOND wei" +echo "Dispute Game Factory: $DISPUTE_GAME_FACTORY" +echo "Transactor Address: $TRANSACTOR_ADDRESS" +echo "RPC URL: $RPC_URL" +echo "" + +# Get sender address from private key +SENDER_ADDRESS=$(cast wallet address --private-key $PRIVATE_KEY) +echo "Sender Address: $SENDER_ADDRESS" +echo "" + +# Check if game type exists +echo "Checking if game type exists..." +GAME_IMPL=$(cast call --rpc-url $RPC_URL $DISPUTE_GAME_FACTORY "gameImpls(uint32)(address)" $GAME_TYPE) +echo "Game Type $GAME_TYPE Implementation: $GAME_IMPL" + +if [ "$GAME_IMPL" == "0x0000000000000000000000000000000000000000" ]; then + echo "Error: Game type $GAME_TYPE does not exist. Cannot set init bond." + exit 1 +fi + +# Get current init bond for comparison +echo "Retrieving current init bond..." +CURRENT_INIT_BOND_RAW=$(cast call --rpc-url $RPC_URL $DISPUTE_GAME_FACTORY "initBonds(uint32)(uint256)" $GAME_TYPE) +CURRENT_INIT_BOND=$(echo $CURRENT_INIT_BOND_RAW | sed 's/\[.*\]//' | xargs) +echo "Current Init Bond: $CURRENT_INIT_BOND wei" + +if [ "$CURRENT_INIT_BOND" == "$INIT_BOND" ]; then + echo "Warning: New init bond is the same as current init bond. No change needed." + exit 0 +fi + +echo "Creating setInitBond calldata..." +echo "Game Type: $GAME_TYPE" +echo "New Init Bond: $INIT_BOND wei" + +# Create calldata for setInitBond function +SETINITBOND_CALLDATA=$(cast calldata "setInitBond(uint32,uint256)" $GAME_TYPE $INIT_BOND) + +echo "SetInitBond calldata: $SETINITBOND_CALLDATA" +echo "" + +# Create calldata for Transactor's DELEGATECALL function +echo "Creating Transactor CALL calldata..." +TRANSACTOR_CALLDATA=$(cast calldata "CALL(address,bytes,uint256)" $DISPUTE_GAME_FACTORY $SETINITBOND_CALLDATA 0) + +echo "Transactor calldata: $TRANSACTOR_CALLDATA" +echo "" + +# Execute the transaction through Transactor +echo "Executing transaction via Transactor..." +echo "Target: $TRANSACTOR_ADDRESS" +echo "From: $SENDER_ADDRESS" + +cast send \ + --rpc-url $RPC_URL \ + --private-key $PRIVATE_KEY \ + --from $SENDER_ADDRESS \ + $TRANSACTOR_ADDRESS \ + $TRANSACTOR_CALLDATA \ + --json |jq + +echo "" +echo "Transaction sent! Check the transaction hash above for confirmation." +echo "" + +# Verify the init bond was updated +echo "Verifying init bond was updated..." +NEW_INIT_BOND=$(cast call --rpc-url $RPC_URL $DISPUTE_GAME_FACTORY "initBonds(uint32)(uint256)" $GAME_TYPE) + +# Extract the numeric value from the response (remove scientific notation and trim spaces) +NEW_INIT_BOND_NUMERIC=$(echo $NEW_INIT_BOND | sed 's/\[.*\]//' | xargs) + +if [ "$NEW_INIT_BOND_NUMERIC" == "$INIT_BOND" ]; then + echo "✅ Success! Init bond updated successfully." + echo "Previous Init Bond: $CURRENT_INIT_BOND wei" + echo "Game Type $GAME_TYPE Init Bond updated to: $NEW_INIT_BOND_NUMERIC wei" +else + echo "❌ Warning: Init bond was not updated as expected." + echo "Expected: $INIT_BOND wei" + echo "Actual: $NEW_INIT_BOND_NUMERIC wei" +fi + +echo "" +echo "Script completed." diff --git a/test-pp-op/scripts/show-dev-accounts.sh b/test-pp-op/scripts/show-dev-accounts.sh new file mode 100755 index 0000000000000..40f4346e5b25b --- /dev/null +++ b/test-pp-op/scripts/show-dev-accounts.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +echo "=== Optimism dev accounts ===" +echo "mnemonic: test test test test test test test test test test test junk" +echo "" + +for i in {0..29}; do + echo "path $i: m/44'/60'/0'/0/$i" + + private_key=$(cast wallet private-key --mnemonic "test test test test test test test test test test test junk" --mnemonic-derivation-path "m/44'/60'/0'/0/$i") + + address=$(cast wallet address --private-key "$private_key") + + echo "address: $address" + echo "private key: $private_key" + echo "---" +done diff --git a/test-pp-op/scripts/stop-leader-sequencer.sh b/test-pp-op/scripts/stop-leader-sequencer.sh new file mode 100755 index 0000000000000..99912e828fbaf --- /dev/null +++ b/test-pp-op/scripts/stop-leader-sequencer.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +BASE_PORT=8547 +LEADER_PORT=0 +OLD_LEADER=0 + +# Find current leader +for i in {0..2}; do + PORT=$((BASE_PORT + i)) + IS_LEADER=$(curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ + http://localhost:$PORT | jq -r .result) + + if [ "$IS_LEADER" = "true" ]; then + LEADER_PORT=$PORT + OLD_LEADER=$((i+1)) + echo "conductor-$OLD_LEADER is current leader (port $PORT)" + break + fi +done + +# Stop leader's sequencer +if [ "$LEADER_PORT" != "0" ]; then + SEQUENCER_PORT=$((9545 + OLD_LEADER -1)) + curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' http://localhost:$SEQUENCER_PORT > /dev/null + echo "sequencer stopped, waiting for leader transfer..." + + # Wait and check for leader change every second + echo "Waiting for leader transfer..." + MAX_SECONDS=10 + for ((second=1; second<=MAX_SECONDS; second++)); do + sleep 1 + NEW_LEADER=0 + for i in {0..2}; do + PORT=$((BASE_PORT + i)) + IS_LEADER=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' http://localhost:$PORT | jq -r .result) + if [ "$IS_LEADER" = "true" ]; then + NEW_LEADER=$((i+1)) + if [ "$NEW_LEADER" != "$OLD_LEADER" ]; then + echo "Leadership transferred: conductor-$OLD_LEADER -> conductor-$NEW_LEADER in (${second}s)" + exit 0 + fi + fi + done + done + echo "Warning: Leader transfer not detected after $MAX_SECONDS seconds" +fi diff --git a/test-pp-op/scripts/transfer-leader.sh b/test-pp-op/scripts/transfer-leader.sh new file mode 100755 index 0000000000000..ef1a34eeb3f73 --- /dev/null +++ b/test-pp-op/scripts/transfer-leader.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +BASE_PORT=8547 +LEADER_PORT=0 +OLD_LEADER=0 + +# Find leader +for i in {0..2}; do + PORT=$((BASE_PORT + i)) + IS_LEADER=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' http://localhost:$PORT | jq -r .result) + if [ "$IS_LEADER" = "true" ]; then + LEADER_PORT=$PORT + OLD_LEADER=$((i+1)) + echo "conductor-$OLD_LEADER is leader (port $PORT)" + break + fi +done + +# Transfer leadership +if [ "$LEADER_PORT" != "0" ]; then + echo "Transferring leadership..." + if [ -n "$1" ] && [ "$1" -ge 1 ] && [ "$1" -le 3 ]; then + # Transfer to specific node + TARGET_NUM=$1 + # Check if target is current leader + if [ "$TARGET_NUM" = "$OLD_LEADER" ]; then + echo "Error: conductor-$TARGET_NUM is already the leader" + exit 1 + fi + ADDR="op-conductor" + [ "$TARGET_NUM" != "1" ] && ADDR="${ADDR}${TARGET_NUM}" + curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_transferLeaderToServer","params":["conductor-'$TARGET_NUM'", "'$ADDR':50050"],"id":1}' http://localhost:$LEADER_PORT >/dev/null + # Check if leader transferred to target node + sleep 1 + NEW_LEADER=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' http://localhost:$((BASE_PORT + TARGET_NUM - 1)) | jq -r .result) + if [ "$NEW_LEADER" = "true" ]; then + echo "Leadership transferred: conductor-$OLD_LEADER -> conductor-$TARGET_NUM" + else + echo "Failed to transfer leadership from conductor-$OLD_LEADER to conductor-$TARGET_NUM" + fi + else + # Auto select target node + curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_transferLeader","params":[],"id":1}' http://localhost:$LEADER_PORT > /dev/null + # Find new leader + sleep 1 + echo "Checking new leader..." + for i in {0..2}; do + PORT=$((BASE_PORT + i)) + IS_LEADER=$(curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ + http://localhost:$PORT | jq -r .result) + + if [ "$IS_LEADER" = "true" ]; then + echo "Leadership transferred: conductor-$OLD_LEADER -> conductor-$((i+1))" + break + fi + done + fi +fi diff --git a/test-pp-op/tools.sh b/test-pp-op/tools.sh new file mode 100644 index 0000000000000..b3f3f6c7bb9a1 --- /dev/null +++ b/test-pp-op/tools.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Strict mode: exit on command failure or undefined variable +set -eu + +# ============================================================================= +# This script performs checks tools required in linux/mac +# ============================================================================= + +# Check if jq is available for JSON parsing +if ! command -v jq >/dev/null 2>&1; then + echo "❌ jq is required but not installed. Please install jq to parse JSON config files." + exit 1 +fi + +# check md5sum +if [[ "$OSTYPE" == "darwin"* ]]; then + MD5SUM_CMD=md5 +else + MD5SUM_CMD=md5sum +fi + +if [ "$ENV" = "local" ]; then + COMPOSE_FILE=docker-compose-local.yml +else + COMPOSE_FILE=docker-compose.yml +fi + +echo "COMPOSE_FILE: ${COMPOSE_FILE}" +DOCKER_COMPOSE=$(docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose") +DOCKER_COMPOSE_CMD="${DOCKER_COMPOSE} -f ${COMPOSE_FILE}" +echo "DOCKER_COMPOSE_CMD: ${DOCKER_COMPOSE_CMD}" diff --git a/test-pp-op/utils.sh b/test-pp-op/utils.sh new file mode 100644 index 0000000000000..80eaaaf03b246 --- /dev/null +++ b/test-pp-op/utils.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e + +# init-erigon.sh runs outside the container. +ROOT_DIR=$(which git &>/dev/null && git rev-parse --show-toplevel || echo "/data") +PWD_DIR="$(pwd)" +TMP_DIR="$PWD_DIR/tmp" + +sed_inplace() { + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} diff --git a/test/2-deploy-op-contracts.sh b/test/2-deploy-op-contracts.sh index ba028a796b2de..f03bd38fd4f47 100755 --- a/test/2-deploy-op-contracts.sh +++ b/test/2-deploy-op-contracts.sh @@ -24,7 +24,7 @@ deploy_safe() { -e DEPLOYER_PRIVATE_KEY="$DEPLOYER_PRIVATE_KEY" \ -w /app/packages/contracts-bedrock \ "${OP_CONTRACTS_IMAGE_TAG}" \ - forge script --json --broadcast \ + forge script --json --broadcast --legacy \ --rpc-url $L1_RPC_URL_IN_DOCKER \ --private-key $DEPLOYER_PRIVATE_KEY \ scripts/deploy/DeploySimpleSafe.s.sol:DeploySimpleSafe) @@ -86,6 +86,7 @@ PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd $PWD_DIR source .env +source ./setup-cgt-function.sh # Validate OWNER_TYPE configuration if [ "$OWNER_TYPE" != "transactor" ] && [ "$OWNER_TYPE" != "safe" ]; then @@ -161,8 +162,10 @@ docker run --rm \ --challenge-period-seconds $CHALLENGE_PERIOD_SECONDS \ --withdrawal-delay-seconds $WITHDRAWAL_DELAY_SECONDS \ --proof-maturity-delay-seconds $WITHDRAWAL_DELAY_SECONDS \ - --dispute-game-finality-delay-seconds $DISPUTE_GAME_FINALITY_DELAY_SECONDS + --dispute-game-finality-delay-seconds $DISPUTE_GAME_FINALITY_DELAY_SECONDS \ + --dev-feature-bitmap 0x0000000000000000000000000000000000000000000000000000000000001000 " +# Enable custom gas token feature: --dev-feature-bitmap 0x0000000000000000000000000000000000000000000000000000000000001000 cp ./config-op/intent.toml.bak ./config-op/intent.toml cp ./config-op/state.json.bak ./config-op/state.json @@ -218,3 +221,10 @@ docker run --rm \ echo "genesis.json and rollup.json are generated in deployments folder" echo "🎉 OP Stack deployment preparation completed!" + +echo "" +echo "🔧 Setting up Custom Gas Token (CGT)..." +setup_cgt + +echo "" +echo "🎉 Complete setup with Custom Gas Token finished!" diff --git a/test/3-op-init.sh b/test/3-op-init.sh index 1edf3186b8c81..e49e0e3ea5b4c 100755 --- a/test/3-op-init.sh +++ b/test/3-op-init.sh @@ -44,18 +44,21 @@ if [ -f "$STATE_JSON" ]; then L2OO_ADDRESS=$(jq -r '.opChainDeployments.L2OutputOracleProxy // empty' "$STATE_JSON") OPCM_IMPL_ADDRESS=$(jq -r '.appliedIntent.opcmAddress // empty' "$STATE_JSON") SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments.SystemConfigProxy // empty' "$STATE_JSON") + OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments.OptimismPortalProxy // empty' "$STATE_JSON") PROXY_ADMIN=$(jq -r '.superchainContracts.SuperchainProxyAdminImpl // empty' "$STATE_JSON") elif [ "$OPCD_TYPE" = "array" ]; then DISPUTE_GAME_FACTORY_ADDRESS=$(jq -r '.opChainDeployments[0].DisputeGameFactoryProxy // empty' "$STATE_JSON") L2OO_ADDRESS=$(jq -r '.opChainDeployments[0].L2OutputOracleProxy // empty' "$STATE_JSON") OPCM_IMPL_ADDRESS=$(jq -r '.appliedIntent.opcmAddress // empty' "$STATE_JSON") SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].SystemConfigProxy // empty' "$STATE_JSON") + OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy // empty' "$STATE_JSON") PROXY_ADMIN=$(jq -r '.superchainContracts.SuperchainProxyAdminImpl // empty' "$STATE_JSON") else DISPUTE_GAME_FACTORY_ADDRESS="" L2OO_ADDRESS="" OPCM_IMPL_ADDRESS="" SYSTEM_CONFIG_PROXY_ADDRESS="" + OPTIMISM_PORTAL_PROXY_ADDRESS="" PROXY_ADMIN="" fi @@ -88,6 +91,13 @@ if [ -f "$STATE_JSON" ]; then echo " ⚠️ SystemConfigProxy address not found in opChainDeployments" fi + if [ -n "$OPTIMISM_PORTAL_PROXY_ADDRESS" ]; then + echo " ✅ Found OptimismPortalProxy address: $OPTIMISM_PORTAL_PROXY_ADDRESS" + sed_inplace "s/OPTIMISM_PORTAL_PROXY_ADDRESS=.*/OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS/" .env + else + echo " ⚠️ OptimismPortalProxy address not found in opChainDeployments" + fi + if [ -n "$PROXY_ADMIN" ]; then echo " ✅ Found ProxyAdmin address: $PROXY_ADMIN" sed_inplace "s/PROXY_ADMIN=.*/PROXY_ADMIN=$PROXY_ADMIN/" .env @@ -101,6 +111,7 @@ if [ -f "$STATE_JSON" ]; then echo " L2OO_ADDRESS=$L2OO_ADDRESS" echo " OPCM_IMPL_ADDRESS=$OPCM_IMPL_ADDRESS" echo " SYSTEM_CONFIG_PROXY_ADDRESS=$SYSTEM_CONFIG_PROXY_ADDRESS" + echo " OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS" echo " PROXY_ADMIN=$PROXY_ADMIN" else echo " ❌ $STATE_JSON is not a valid JSON object" diff --git a/test/config-op/intent.toml.bak b/test/config-op/intent.toml.bak index 2adece7de8edf..cf04ac0b40e8b 100644 --- a/test/config-op/intent.toml.bak +++ b/test/config-op/intent.toml.bak @@ -28,3 +28,8 @@ l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" batcher = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" proposer = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" challenger = "0x7d18A1B858253b5588f61fb5739d52e4b84e2cdA" + [chains.customGasToken] + enabled = true + name = "OKB" + symbol = "OKB" + InitialLiquidity = "0x0" # 0 OKB, no premint diff --git a/test/example.env b/test/example.env index 0f84b119e8f0e..64e3f3e81a45a 100644 --- a/test/example.env +++ b/test/example.env @@ -30,6 +30,7 @@ L1_BEACON_URL_IN_DOCKER=http://l1-beacon-chain:3500 SAFE_ADDRESS=0x0000000000000000000000000000000000000000 TRANSACTOR=0x0000000000000000000000000000000000000000 +DEPLOYER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 DEPLOYER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 SEQUENCER_P2P_KEY=0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba OP_BATCHER_PRIVATE_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a @@ -43,6 +44,12 @@ OPCM_IMPL_ADDRESS=0xd5ea6d3f520eac42f989019a8d3c51a123e73113 SYSTEM_CONFIG_PROXY_ADDRESS=0x330cff9f99a75bc9c71750b5c60fdc0eff1789e1 PROXY_ADMIN=0x922d6956c99e12dfeb3224dea977d0939758a1fe PROPOSER_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 +OPTIMISM_PORTAL_PROXY_ADDRESS=0xc8e8b7b181db301f27aef90ed285787a3ce179e9 +# For testing, Adapter owner is the deployer +OKB_ADAPTER_OWNER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + +# OKB Token Address on L1. If not set, a new MockOKB will be deployed. +OKB_TOKEN_ADDRESS=0x75231f58b43240c9718dd58b4967c5114342a86c # First game only for update anchor root TEMP_MAX_CLOCK_DURATION=40 diff --git a/test/init-parallel.sh b/test/init-parallel.sh new file mode 100755 index 0000000000000..fac5041ab0c53 --- /dev/null +++ b/test/init-parallel.sh @@ -0,0 +1,271 @@ +#!/bin/bash +# Fully parallel build script - all three images build simultaneously + +set -x +set -e + +# Record start time +START_TIME=$(date +%s) + +# Track all background PIDs for cleanup +ALL_PIDS=() + +# Cleanup function to kill all background processes +cleanup() { + echo "" + echo "================================================" + echo "Caught interrupt signal, cleaning up..." + echo "================================================" + + # Kill all tracked processes and their children + for pid in "${ALL_PIDS[@]}"; do + if kill -0 "$pid" 2>/dev/null; then + echo "Killing process $pid and its children..." + # Try to kill process group first (for docker build and its children) + kill -- -$pid 2>/dev/null || kill "$pid" 2>/dev/null || true + fi + done + + # Give processes time to terminate gracefully + sleep 2 + + # Force kill any remaining processes + for pid in "${ALL_PIDS[@]}"; do + if kill -0 "$pid" 2>/dev/null; then + echo "Force killing process $pid..." + kill -9 -- -$pid 2>/dev/null || kill -9 "$pid" 2>/dev/null || true + fi + done + + echo "Cleanup complete. All build processes terminated." + exit 1 +} + +# Set up trap to catch Ctrl+C (SIGINT) and SIGTERM +trap cleanup SIGINT SIGTERM + +BRANCH_NAME=${1:-""} +PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +OPTIMISM_DIR=$(git rev-parse --show-toplevel) + +[ ! -f .env ] && cp example.env .env + +source .env + +if [ "$OP_GETH_LOCAL_DIRECTORY" = "" ]; then + git submodule update --init --recursive + OP_GETH_DIR="$OPTIMISM_DIR/op-geth" +else + OP_GETH_DIR="$OP_GETH_LOCAL_DIRECTORY" +fi + +# Switch to specified branch if provided +if [ -n "$BRANCH_NAME" ]; then + echo "Switching op-geth to branch: $BRANCH_NAME" + cd $OP_GETH_DIR + git fetch origin + git checkout "$BRANCH_NAME" + git pull origin "$BRANCH_NAME" + cd "$PWD_DIR" +else + echo "Using op-geth default branch" +fi + +# TODO: need to further confirm why it fails if we do not add require in this contract +cp $PWD_DIR/contracts/Transactor.sol $OPTIMISM_DIR/packages/contracts-bedrock/src/periphery/Transactor.sol + +cd $OPTIMISM_DIR + +# Create log directory +mkdir -p /tmp/docker-build-logs + +echo "================================================" +echo "FULLY PARALLEL BUILD MODE" +echo "================================================" +echo "Building op-geth, op-contracts, and op-stack simultaneously" +echo "================================================" +echo "" + +# Track PIDs for parallel builds +BUILD_PIDS=() +TAIL_PIDS=() + +# Start all builds in parallel +echo "Starting parallel builds..." + +# Build OP_CONTRACTS in background +if [ $SKIP_OP_CONTRACTS_BUILD = "true" ]; then + echo "Skipping op-contracts build" +else + echo "[1/3] Starting op-contracts build..." + CONTRACTS_START=$(date +%s) + + docker build -t $OP_CONTRACTS_IMAGE_TAG -f ./Dockerfile-contracts . > /tmp/docker-build-logs/op-contracts.log 2>&1 & + CONTRACTS_PID=$! + BUILD_PIDS+=("$CONTRACTS_PID:op-contracts:$CONTRACTS_START") + ALL_PIDS+=($CONTRACTS_PID) + + tail -f /tmp/docker-build-logs/op-contracts.log 2>/dev/null | sed 's/^/[op-contracts] /' & + TAIL_CONTRACTS_PID=$! + TAIL_PIDS+=($TAIL_CONTRACTS_PID) + ALL_PIDS+=($TAIL_CONTRACTS_PID) +fi + +# Build OP_GETH in background +if [ $SKIP_OP_GETH_BUILD = "true" ]; then + echo "Skipping op-geth build" +else + echo "[2/3] Starting op-geth build..." + GETH_START=$(date +%s) + + cd $OP_GETH_DIR + docker build -t $OP_GETH_IMAGE_TAG . > /tmp/docker-build-logs/op-geth.log 2>&1 & + GETH_PID=$! + BUILD_PIDS+=("$GETH_PID:op-geth:$GETH_START") + ALL_PIDS+=($GETH_PID) + + tail -f /tmp/docker-build-logs/op-geth.log 2>/dev/null | sed 's/^/[op-geth] /' & + TAIL_GETH_PID=$! + TAIL_PIDS+=($TAIL_GETH_PID) + ALL_PIDS+=($TAIL_GETH_PID) + + cd $OPTIMISM_DIR +fi + +# Build OP_STACK in background +if [ $SKIP_OP_STACK_BUILD = "true" ]; then + echo "Skipping op-stack build" +else + echo "[3/3] Starting op-stack build..." + STACK_START=$(date +%s) + + docker build -t $OP_STACK_IMAGE_TAG -f ./Dockerfile-opstack . > /tmp/docker-build-logs/op-stack.log 2>&1 & + STACK_PID=$! + BUILD_PIDS+=("$STACK_PID:op-stack:$STACK_START") + ALL_PIDS+=($STACK_PID) + + tail -f /tmp/docker-build-logs/op-stack.log 2>/dev/null | sed 's/^/[op-stack] /' & + TAIL_STACK_PID=$! + TAIL_PIDS+=($TAIL_STACK_PID) + ALL_PIDS+=($TAIL_STACK_PID) +fi + +# Wait for all builds to complete +if [ ${#BUILD_PIDS[@]} -gt 0 ]; then + echo "" + echo "Building in parallel... (live output below)" + echo "================================================" + echo "" + + # Disable debug output for monitoring loop to reduce noise + set +x + + # Monitor loop to record exact completion time for each build + while true; do + all_done=true + + for pid_info in "${BUILD_PIDS[@]}"; do + IFS=':' read -r pid name start_time <<< "$pid_info" + + # Check if process is still running + if kill -0 "$pid" 2>/dev/null; then + all_done=false + else + # Process finished, record time if not already recorded + if [ "$name" = "op-contracts" ] && [ -z "$CONTRACTS_END" ]; then + CONTRACTS_END=$(date +%s) + CONTRACTS_TIME=$((CONTRACTS_END - start_time)) + elif [ "$name" = "op-geth" ] && [ -z "$GETH_END" ]; then + GETH_END=$(date +%s) + GETH_TIME=$((GETH_END - start_time)) + elif [ "$name" = "op-stack" ] && [ -z "$STACK_END" ]; then + STACK_END=$(date +%s) + STACK_TIME=$((STACK_END - start_time)) + fi + fi + done + + if $all_done; then + break + fi + + sleep 1 + done + + # Re-enable debug output + set -x + + # Now wait for exit codes + FAILED=0 + for pid_info in "${BUILD_PIDS[@]}"; do + IFS=':' read -r pid name start_time <<< "$pid_info" + + wait "$pid" + exit_code=$? + + if [ $exit_code -ne 0 ]; then + FAILED=1 + fi + done + + # Stop all tail processes + for tail_pid in "${TAIL_PIDS[@]}"; do + kill $tail_pid 2>/dev/null || true + done + + # Give tail processes a moment to finish + sleep 1 + + echo "" + echo "================================================" + echo "BUILD RESULTS" + echo "================================================" + + # Display results for each build + if [ -n "$CONTRACTS_END" ]; then + contracts_min=$((CONTRACTS_TIME / 60)) + contracts_sec=$((CONTRACTS_TIME % 60)) + echo "✅ op-contracts: Success (${contracts_min}m ${contracts_sec}s)" + elif [ "$SKIP_OP_CONTRACTS_BUILD" != "true" ]; then + echo "❌ op-contracts: Failed" + fi + + if [ -n "$GETH_END" ]; then + geth_min=$((GETH_TIME / 60)) + geth_sec=$((GETH_TIME % 60)) + echo "✅ op-geth: Success (${geth_min}m ${geth_sec}s)" + elif [ "$SKIP_OP_GETH_BUILD" != "true" ]; then + echo "❌ op-geth: Failed" + fi + + if [ -n "$STACK_END" ]; then + stack_min=$((STACK_TIME / 60)) + stack_sec=$((STACK_TIME % 60)) + echo "✅ op-stack: Success (${stack_min}m ${stack_sec}s)" + elif [ "$SKIP_OP_STACK_BUILD" != "true" ]; then + echo "❌ op-stack: Failed" + fi + + if [ $FAILED -ne 0 ]; then + echo "" + echo "ERROR: Some builds failed. Check logs at /tmp/docker-build-logs/" + exit 1 + fi +fi + +# Calculate total time (from start to end) +END_TIME=$(date +%s) +TOTAL_TIME=$((END_TIME - START_TIME)) +TOTAL_MIN=$((TOTAL_TIME / 60)) +TOTAL_SEC=$((TOTAL_TIME % 60)) + +echo "" +echo "================================================" +echo "BUILD COMPLETE" +echo "================================================" +echo "Total time: ${TOTAL_MIN}m ${TOTAL_SEC}s" +echo "" +echo "Built images:" +docker images | grep -E "(op-geth|op-stack|op-contracts)" | grep latest +echo "" +echo "================================================" diff --git a/test/setup-cgt-function.sh b/test/setup-cgt-function.sh new file mode 100755 index 0000000000000..c60710bf8a83e --- /dev/null +++ b/test/setup-cgt-function.sh @@ -0,0 +1,133 @@ +#!/bin/bash + +sed_inplace() { + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + +# Setup Custom Gas Token (CGT) function +setup_cgt() { + echo "🔧 Setting up Custom Gas Token (CGT) configuration..." + echo "" + + # Check if OKB_TOKEN_ADDRESS is already set in environment + if [ -n "$OKB_TOKEN_ADDRESS" ]; then + echo "📝 Step 1: Using existing OKB token..." + echo " Found OKB_TOKEN_ADDRESS in environment: $OKB_TOKEN_ADDRESS" + echo "" + + # Verify the token exists at the specified address + cd $ROOT_DIR/packages/contracts-bedrock + echo " Verifying OKB token at address..." + + # Try to call a basic function to verify it's a valid ERC20 + if ! cast call "$OKB_TOKEN_ADDRESS" "name()(string)" --rpc-url "$L1_RPC_URL" >/dev/null 2>&1; then + echo "" + echo "❌ ERROR: Invalid OKB token address or token not deployed" + echo " Address: $OKB_TOKEN_ADDRESS" + echo " Please check the address or remove OKB_TOKEN_ADDRESS from .env to deploy a new MockOKB" + echo "" + return 1 + fi + + TOKEN_NAME=$(cast call "$OKB_TOKEN_ADDRESS" "name()(string)" --rpc-url "$L1_RPC_URL") + TOKEN_SYMBOL=$(cast call "$OKB_TOKEN_ADDRESS" "symbol()(string)" --rpc-url "$L1_RPC_URL") + echo " ✅ Token verified: $TOKEN_NAME ($TOKEN_SYMBOL)" + echo "" + else + # Deploy MockOKB token if not already set + echo "📝 Step 1: Deploying MockOKB token..." + cd $ROOT_DIR/packages/contracts-bedrock + + # Temporarily disable set -e to capture forge output properly + set +e + MOCK_OKB_OUTPUT=$(forge script scripts/DeployMockOKB.s.sol:DeployMockOKB \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" \ + --broadcast 2>&1 | tee /dev/tty) + MOCK_OKB_EXIT_CODE=$? + set -e + + # Check if MockOKB deployment failed + if [ $MOCK_OKB_EXIT_CODE -ne 0 ]; then + echo "" + echo "❌ ERROR: MockOKB deployment failed with exit code $MOCK_OKB_EXIT_CODE" + echo "Error output shown above ☝️" + echo "" + return $MOCK_OKB_EXIT_CODE + fi + + # Extract MockOKB contract address from forge output + OKB_TOKEN_ADDRESS=$(echo "$MOCK_OKB_OUTPUT" | grep "MockOKB deployed at:" | awk '{print $NF}') + + if [ -z "$OKB_TOKEN_ADDRESS" ]; then + echo "" + echo "❌ ERROR: Could not extract MockOKB address from deployment output" + echo "Please check the deployment logs above" + echo "" + return 1 + fi + + echo "" + echo "✅ MockOKB deployed successfully!" + echo " Address: $OKB_TOKEN_ADDRESS" + echo "" + echo "💡 TIP: Add this to your .env file to reuse in future runs:" + echo " export OKB_TOKEN_ADDRESS=$OKB_TOKEN_ADDRESS" + echo "" + fi + + # Export OKB_TOKEN_ADDRESS for the setup script + export OKB_TOKEN_ADDRESS="$OKB_TOKEN_ADDRESS" + + # Get required addresses from state.json + echo "📝 Step 2: Running Custom Gas Token setup script..." + STATE_JSON="$PWD_DIR/config-op/state.json" + SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].SystemConfigProxy' "$STATE_JSON") + OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy' "$STATE_JSON") + + # Export required environment variables for the setup script + export SYSTEM_CONFIG_PROXY_ADDRESS="$SYSTEM_CONFIG_PROXY_ADDRESS" + export OPTIMISM_PORTAL_PROXY_ADDRESS="$OPTIMISM_PORTAL_PROXY_ADDRESS" + export OKB_ADAPTER_OWNER_ADDRESS="$OKB_ADAPTER_OWNER_ADDRESS" + + # Temporarily disable set -e to capture forge output properly + set +e + FORGE_OUTPUT=$(forge script scripts/SetupCustomGasToken.s.sol:SetupCustomGasToken \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" \ + --broadcast 2>&1 | tee /dev/tty) + FORGE_EXIT_CODE=$? + set -e + + # Check if forge script failed + if [ $FORGE_EXIT_CODE -ne 0 ]; then + echo "" + echo "❌ ERROR: Custom Gas Token setup failed with exit code $FORGE_EXIT_CODE" + echo "Error output shown above ☝️" + echo "" + return $FORGE_EXIT_CODE + fi + + # Extract adapter address from setup script output + ADAPTER_ADDRESS=$(echo "$FORGE_OUTPUT" | grep "DepositedOKBAdapter deployed at:" | awk '{print $NF}') + + # Use the already deployed OKB token address + OKB_TOKEN="$OKB_TOKEN_ADDRESS" + + # Query initial OKB total supply + INIT_TOTAL_SUPPLY=$(cast call "$OKB_TOKEN" "totalSupply()(uint256)" --rpc-url "$L1_RPC_URL") + echo "" + echo "📊 Initial OKB Total Supply: $INIT_TOTAL_SUPPLY" + + echo "" + echo "✅ L1 Custom Gas Token setup complete!" + echo "" + echo "📋 Setup Contract Addresses:" + echo " OKB Token: $OKB_TOKEN" + echo " Adapter: $ADAPTER_ADDRESS" + echo "" +} diff --git a/test/test-cgt.sh b/test/test-cgt.sh new file mode 100755 index 0000000000000..70a231b9bc4ac --- /dev/null +++ b/test/test-cgt.sh @@ -0,0 +1,227 @@ +#!/bin/bash +set -e + +ROOT_DIR=$(git rev-parse --show-toplevel) + +# Use current working directory to allow symlinks to work +# This way test/ and test-pp-op/ can each use their own .env +PWD_DIR="$(pwd)" + +# Validate we're in a test directory with .env +if [ ! -f "$PWD_DIR/.env" ]; then + echo "❌ ERROR: .env file not found in current directory: $PWD_DIR" + echo "Please run this script from a test directory (test/ or test-pp-op/)" + exit 1 +fi + +source .env + +SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].SystemConfigProxy' $PWD_DIR/config-op/state.json) + +# Query ADAPTER_ADDRESS from SystemConfig.gasPayingToken() +echo "📝 Querying ADAPTER_ADDRESS from SystemConfig..." +ADAPTER_ADDRESS=$(cast call "$SYSTEM_CONFIG_PROXY_ADDRESS" "gasPayingToken()(address,uint8)" --rpc-url "$L1_RPC_URL" | head -n1) +if [ -z "$ADAPTER_ADDRESS" ] || [ "$ADAPTER_ADDRESS" = "0x0000000000000000000000000000000000000000" ]; then + echo "❌ ERROR: Could not query ADAPTER_ADDRESS from SystemConfig or CGT not configured" + echo " SystemConfig address: $SYSTEM_CONFIG_PROXY_ADDRESS" + exit 1 +fi + +# Query OKB_TOKEN_ADDRESS from the adapter +echo "📝 Querying OKB_TOKEN_ADDRESS from adapter..." +OKB_TOKEN_ADDRESS=$(cast call "$ADAPTER_ADDRESS" "OKB()(address)" --rpc-url "$L1_RPC_URL") +if [ -z "$OKB_TOKEN_ADDRESS" ] || [ "$OKB_TOKEN_ADDRESS" = "0x0000000000000000000000000000000000000000" ]; then + echo "❌ ERROR: Could not query OKB_TOKEN_ADDRESS from adapter" + echo " Adapter address: $ADAPTER_ADDRESS" + exit 1 +fi + +# Query INIT_TOTAL_SUPPLY from OKB token contract +echo "📝 Querying INIT_TOTAL_SUPPLY from OKB token..." +INIT_TOTAL_SUPPLY=$(cast call "$OKB_TOKEN_ADDRESS" "totalSupply()(uint256)" --rpc-url "$L1_RPC_URL") + +echo "" +echo "🧪 Testing Custom Gas Token (CGT) configuration..." +echo "" +echo "📋 Using Contract Addresses:" +echo " OKB Token: $OKB_TOKEN_ADDRESS" +echo " Adapter: $ADAPTER_ADDRESS (queried from SystemConfig)" +echo " Initial Supply: $INIT_TOTAL_SUPPLY (queried from OKB)" +echo "" + +# Check if L2 is running before verifying L2 configuration +if curl -s -X POST "$L2_RPC_URL" \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ + > /dev/null 2>&1; then + + echo "📝 Step 1: Verifying L2 configuration..." + echo "" + + # Call L1Block predeploy to check configuration + L1_BLOCK_ADDR="0x4200000000000000000000000000000000000015" + + # Check isCustomGasToken + IS_CUSTOM_GAS_TOKEN=$(cast call "$L1_BLOCK_ADDR" \ + "isCustomGasToken()(bool)" \ + --rpc-url "$L2_RPC_URL") + + echo " L1Block.isCustomGasToken(): $IS_CUSTOM_GAS_TOKEN" + + # Check gasPayingTokenName + TOKEN_NAME=$(cast call "$L1_BLOCK_ADDR" \ + "gasPayingTokenName()(string)" \ + --rpc-url "$L2_RPC_URL") + + echo " L1Block.gasPayingTokenName(): $TOKEN_NAME" + + # Check gasPayingTokenSymbol + TOKEN_SYMBOL=$(cast call "$L1_BLOCK_ADDR" \ + "gasPayingTokenSymbol()(string)" \ + --rpc-url "$L2_RPC_URL") + + echo " L1Block.gasPayingTokenSymbol(): $TOKEN_SYMBOL" + + echo "" + if [ "$IS_CUSTOM_GAS_TOKEN" = "true" ]; then + echo "✅ L2 Custom Gas Token configuration verified!" + else + echo "⚠️ WARNING: L2 custom gas token not yet active" + echo " The L2 chain needs to process the setCustomGasToken transaction" + echo " This will happen automatically when the chain processes L1 data" + fi +else + echo "⚠️ L2 node is not running yet - skipping L2 verification" + echo " Please verify L2 configuration after the L2 node starts" +fi + +echo "" +echo "🎉 Custom Gas Token verification completed!" +echo "" + +# Perform test deposit +if [ -n "$OKB_TOKEN_ADDRESS" ] && [ -n "$ADAPTER_ADDRESS" ]; then + echo "📝 Step 2: Performing test deposit..." + echo "" + + DEPOSIT_AMOUNT="7999000000000000" + + # Get deployer address and verify it's the adapter owner + DEPLOYER_ADDRESS=$(cast wallet address --private-key "$DEPLOYER_PRIVATE_KEY") + ADAPTER_OWNER=$(cast call "$ADAPTER_ADDRESS" "owner()(address)" --rpc-url "$L1_RPC_URL") + + echo " Deployer Address: $DEPLOYER_ADDRESS" + echo " Adapter Owner: $ADAPTER_OWNER" + + if [ "$DEPLOYER_ADDRESS" != "$ADAPTER_OWNER" ]; then + echo "" + echo "❌ ERROR: Deployer is not the adapter owner" + echo " This script assumes deployer has ownership of the adapter" + echo " Current owner: $ADAPTER_OWNER" + exit 1 + fi + + echo " ✅ Deployer is verified as adapter owner" + echo "" + + # Check deployer's OKB balance + DEPLOYER_OKB_BALANCE=$(cast call "$OKB_TOKEN_ADDRESS" "balanceOf(address)(uint256)" "$DEPLOYER_ADDRESS" --rpc-url "$L1_RPC_URL") + echo " Deployer OKB Balance: $DEPLOYER_OKB_BALANCE" + echo "" + + # Step 2a: Add deployer to whitelist + echo " Adding deployer to whitelist..." + cast send "$ADAPTER_ADDRESS" \ + "addToWhitelistBatch(address[])" \ + "[$DEPLOYER_ADDRESS]" \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" + echo " ✅ Deployer added to whitelist" + echo "" + + # Step 2b: Approve the adapter to spend OKB + cast send "$OKB_TOKEN_ADDRESS" \ + "approve(address,uint256)" \ + "$ADAPTER_ADDRESS" \ + "$DEPOSIT_AMOUNT" \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" + + # L2 recipient address + L2_RECIPIENT=$DEPLOYER_ADDRESS + + # Step 2c: Perform the deposit + cast send "$ADAPTER_ADDRESS" \ + "deposit(address,uint256)" \ + "$L2_RECIPIENT" \ + "$DEPOSIT_AMOUNT" \ + --rpc-url "$L1_RPC_URL" \ + --private-key "$DEPLOYER_PRIVATE_KEY" + + echo "" + echo "✅ Test deposit transaction sent!" + echo "" + echo "⏳ Waiting for L2 to process the deposit..." + echo " Checking balance every 5 seconds..." + echo "" + + INIT_BALANCE=$(cast balance $L2_RECIPIENT --rpc-url $L2_RPC_URL) + echo " Deposit From $DEPLOYER_ADDRESS to $L2_RECIPIENT" + echo " Deposit Amount: $DEPOSIT_AMOUNT" + echo " L2 Recipient: $L2_RECIPIENT" + echo " L2 Recipient Initial Balance: $INIT_BALANCE" + echo "" + + # Expected final balance + EXPECTED_BALANCE=$((INIT_BALANCE + DEPOSIT_AMOUNT)) + + # Timeout after 5 minutes (60 attempts * 5 seconds) + MAX_ATTEMPTS=60 + ATTEMPT=0 + + while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do + CURRENT_BALANCE=$(cast balance $L2_RECIPIENT --rpc-url $L2_RPC_URL) + + echo " [Attempt $((ATTEMPT + 1))/$MAX_ATTEMPTS] Current Balance: $CURRENT_BALANCE (Expected: $EXPECTED_BALANCE)" + + if [ "$CURRENT_BALANCE" = "$EXPECTED_BALANCE" ]; then + echo "" + echo "🎉 Deposit processed successfully!" + echo "" + + # Query OKB total supply after successful deposit + DEPOSIT_FINAL_TOTAL_SUPPLY=$(cast call "$OKB_TOKEN_ADDRESS" "totalSupply()(uint256)" --rpc-url "$L1_RPC_URL") + + echo "📊 Final Status:" + echo " Initial Balance: $INIT_BALANCE" + echo " Deposit Amount: $DEPOSIT_AMOUNT" + echo " Final Balance: $CURRENT_BALANCE" + echo " L2 Recipient: $L2_RECIPIENT" + echo "" + echo "🔥 OKB Token Supply Status:" + echo " Initial Total Supply: $INIT_TOTAL_SUPPLY" + echo " Final Total Supply: $DEPOSIT_FINAL_TOTAL_SUPPLY" + echo "" + break + fi + + ATTEMPT=$((ATTEMPT + 1)) + + if [ $ATTEMPT -lt $MAX_ATTEMPTS ]; then + sleep 5 + fi + done + + if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then + echo "" + echo "⚠️ WARNING: Deposit not processed within timeout period (5 minutes)" + echo " Current Balance: $CURRENT_BALANCE" + echo " Expected Balance: $EXPECTED_BALANCE" + echo "" + echo "📚 Troubleshooting:" + echo " 1. Check if L2 node is running and syncing" + echo " 2. Check L1 transaction status" + echo " 3. Monitor TransactionDeposited events on OptimismPortal: $OPTIMISM_PORTAL_PROXY_ADDRESS" + echo " 4. Manually check balance: cast balance $L2_RECIPIENT --rpc-url $L2_RPC_URL" + fi +fi From 30bd2d5571470f94bfd8aff641d6f60f2c71617f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=80=AA=E5=85=BD?= <32981645+albbm@users.noreply.github.com> Date: Mon, 27 Oct 2025 12:04:46 +0800 Subject: [PATCH 10/26] Jason/update cgt contract (#120) * Enhance DepositedOKBAdapter with ReentrancyGuard and update deposit/rescue functions. Added nonReentrant modifier to deposit and rescueERC20 functions to prevent reentrancy attacks. --------- Co-authored-by: Backdoor <20609724+doutv@users.noreply.github.com> Co-authored-by: Barry Co-authored-by: Louis Liu <35095310+louisliu2048@users.noreply.github.com> --- .../src/L1/DepositedOKBAdapter.sol | 16 +-- .../test/L1/DepositedOKBAdapter.t.sol | 107 ++++++++++++++++++ test-pp-op/local.env | 2 +- 3 files changed, 116 insertions(+), 9 deletions(-) diff --git a/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol b/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol index f3a30ad98120f..3ce2b02f6aa4a 100644 --- a/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol +++ b/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol @@ -5,7 +5,8 @@ pragma solidity 0.8.15; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - +import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; // Interfaces import { IOKB } from "interfaces/L1/IOKB.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; @@ -23,7 +24,9 @@ import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; /// - Automatically initiates L2 deposit transaction /// /// @dev This token is set as the gasPayingToken on SystemConfig. -contract DepositedOKBAdapter is ERC20, Ownable { +contract DepositedOKBAdapter is ERC20, Ownable, ReentrancyGuard { + using SafeERC20 for IERC20; + /// @notice Address of the OptimismPortal2 contract that this adapter works with. IOptimismPortal2 public immutable PORTAL; @@ -134,7 +137,7 @@ contract DepositedOKBAdapter is ERC20, Ownable { /// 7. Initiates an L2 deposit transaction via the portal /// @param _to Target address on L2 to receive the tokens. /// @param _amount Amount of OKB to burn and deposit. - function deposit(address _to, uint256 _amount) external { + function deposit(address _to, uint256 _amount) external nonReentrant { if (!whitelist[msg.sender]) { revert NotWhitelisted(); } @@ -211,7 +214,7 @@ contract DepositedOKBAdapter is ERC20, Ownable { /// @param _token Address of the ERC20 token to rescue. /// @param _to Address to send the tokens to. /// @param _amount Amount of tokens to rescue. - function rescueERC20(address _token, address _to, uint256 _amount) external onlyOwner { + function rescueERC20(address _token, address _to, uint256 _amount) external onlyOwner nonReentrant { if (_token == address(0)) { revert AddressCannotBeZero(); } @@ -222,9 +225,6 @@ contract DepositedOKBAdapter is ERC20, Ownable { revert AmountMustBeGreaterThanZero(); } - bool transferSuccess = IERC20(_token).transfer(_to, _amount); - if (!transferSuccess) { - revert TransferFailed(); - } + IERC20(_token).safeTransfer(_to, _amount); } } diff --git a/packages/contracts-bedrock/test/L1/DepositedOKBAdapter.t.sol b/packages/contracts-bedrock/test/L1/DepositedOKBAdapter.t.sol index dd223628cb90b..a23a097884353 100644 --- a/packages/contracts-bedrock/test/L1/DepositedOKBAdapter.t.sol +++ b/packages/contracts-bedrock/test/L1/DepositedOKBAdapter.t.sol @@ -578,16 +578,94 @@ contract DepositedOKBAdapter_Transfer_Test is DepositedOKBAdapter_TestInit { } } +/// @title MockUSDT +/// @notice Mock USDT contract that mimics real USDT behavior (no return value for transfer) +contract MockUSDT { + mapping(address => uint256) private _balances; + mapping(address => mapping(address => uint256)) private _allowances; + + uint256 private _totalSupply; + string public name = "Tether USD"; + string public symbol = "USDT"; + uint8 public decimals = 6; + + bool public shouldRevert = false; + + constructor(uint256 _supply) { + _totalSupply = _supply; + _balances[msg.sender] = _supply; + } + + function totalSupply() public view returns (uint256) { + return _totalSupply; + } + + function balanceOf(address account) public view returns (uint256) { + return _balances[account]; + } + + function allowance(address owner, address spender) public view returns (uint256) { + return _allowances[owner][spender]; + } + + /// @notice USDT-style transfer that doesn't return bool and reverts on failure + function transfer(address to, uint256 amount) public { + if (shouldRevert) { + revert("USDT: transfer failed"); + } + require(to != address(0), "USDT: transfer to zero address"); + require(_balances[msg.sender] >= amount, "USDT: insufficient balance"); + + _balances[msg.sender] -= amount; + _balances[to] += amount; + } + + /// @notice USDT-style transferFrom that doesn't return bool and reverts on failure + function transferFrom(address from, address to, uint256 amount) public { + if (shouldRevert) { + revert("USDT: transfer failed"); + } + require(to != address(0), "USDT: transfer to zero address"); + require(_balances[from] >= amount, "USDT: insufficient balance"); + require(_allowances[from][msg.sender] >= amount, "USDT: insufficient allowance"); + + _balances[from] -= amount; + _balances[to] += amount; + _allowances[from][msg.sender] -= amount; + } + + function approve(address spender, uint256 amount) public returns (bool) { + _allowances[msg.sender][spender] = amount; + return true; + } + + function setShouldRevert(bool _shouldRevert) external { + shouldRevert = _shouldRevert; + } + + /// @notice Mint tokens for testing + function mint(address to, uint256 amount) external { + _balances[to] += amount; + _totalSupply += amount; + } +} + /// @title DepositedOKBAdapter_Rescue_Test /// @notice Test contract for ERC20 rescue functionality contract DepositedOKBAdapter_Rescue_Test is DepositedOKBAdapter_TestInit { ERC20 testToken; + MockUSDT mockUSDT; function setUp() public override { super.setUp(); testToken = new ERC20("Test Token", "TEST"); // Mint some tokens to the adapter (simulating accidental transfer) deal(address(testToken), address(adapter), 1000e18); + + // Create mock USDT with 6 decimals (1M USDT) + mockUSDT = new MockUSDT(1_000_000e6); + // Transfer some USDT to the adapter (simulating accidental transfer) + mockUSDT.mint(address(adapter), 10_000e6); // 10,000 USDT } /// @notice Test successful ERC20 rescue @@ -631,6 +709,35 @@ contract DepositedOKBAdapter_Rescue_Test is DepositedOKBAdapter_TestInit { vm.prank(user1); adapter.rescueERC20(address(testToken), makeAddr("rescueTo"), 100); } + + /// @notice Test successful USDT rescue (USDT doesn't return bool from transfer) + function test_rescueUSDT_succeeds() public { + uint256 rescueAmount = 5000e6; // 5,000 USDT (6 decimals) + address rescueTo = makeAddr("rescueTo"); + + uint256 balanceBefore = mockUSDT.balanceOf(rescueTo); + uint256 adapterBalanceBefore = mockUSDT.balanceOf(address(adapter)); + + vm.prank(owner); + adapter.rescueERC20(address(mockUSDT), rescueTo, rescueAmount); + + assertEq(mockUSDT.balanceOf(rescueTo), balanceBefore + rescueAmount); + assertEq(mockUSDT.balanceOf(address(adapter)), adapterBalanceBefore - rescueAmount); + } + + /// @notice Test USDT rescue handles revert case properly + function test_rescueUSDT_transferReverts_fails() public { + uint256 rescueAmount = 5000e6; // 5,000 USDT (6 decimals) + address rescueTo = makeAddr("rescueTo"); + + // Make USDT transfers revert + mockUSDT.setShouldRevert(true); + + // The rescue should revert when USDT transfer fails + vm.expectRevert("USDT: transfer failed"); + vm.prank(owner); + adapter.rescueERC20(address(mockUSDT), rescueTo, rescueAmount); + } } /// @title DepositedOKBAdapter_Integration_Test diff --git a/test-pp-op/local.env b/test-pp-op/local.env index 38e5dc5d1a020..83398254490e7 100644 --- a/test-pp-op/local.env +++ b/test-pp-op/local.env @@ -98,7 +98,7 @@ PROXY_ADMIN=0x88c87adaf76a638cd81286b23b5830a7d6ffb80d TIME_LOCK_DELAY=70 # Set initial bond -INITIAL_BOND=10000000000 +INITIAL_BOND=10000000000 # First game only for update anchor root TEMP_MAX_CLOCK_DURATION=40 From c3286a9833966805f5dea6fca0f5db390d15cc40 Mon Sep 17 00:00:00 2001 From: Vui-Chee <46051576+Vui-Chee@users.noreply.github.com> Date: Mon, 27 Oct 2025 12:57:12 +0800 Subject: [PATCH 11/26] Drop overwrite fro Transactor.sol during build (#125) --- test-pp-op/build_images.sh | 3 -- test-pp-op/contracts/Transactor.sol | 51 ----------------------------- 2 files changed, 54 deletions(-) delete mode 100644 test-pp-op/contracts/Transactor.sol diff --git a/test-pp-op/build_images.sh b/test-pp-op/build_images.sh index 11a598914a708..bbaea9cd1c844 100755 --- a/test-pp-op/build_images.sh +++ b/test-pp-op/build_images.sh @@ -188,9 +188,6 @@ build_op_stack_contract() { echo "build op stack image" PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - # cp Transactor.sol to optimism, which is used for addGameType - cp $PWD_DIR/contracts/Transactor.sol ../packages/contracts-bedrock/src/periphery/Transactor.sol - cd .. docker build $( [ "$FORCE" = true ] && echo --no-cache ) --platform $ARCH -t $OP_CONTRACTS_IMAGE_TAG -f Dockerfile-contracts . diff --git a/test-pp-op/contracts/Transactor.sol b/test-pp-op/contracts/Transactor.sol deleted file mode 100644 index e193db31e024f..0000000000000 --- a/test-pp-op/contracts/Transactor.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -// Contracts -import { Owned } from "@rari-capital/solmate/src/auth/Owned.sol"; - -/// @title Transactor -/// @notice Transactor is a minimal contract that can send transactions. -contract Transactor is Owned { - /// @param _owner Initial contract owner. - constructor(address _owner) Owned(_owner) { } - - /// @notice Sends a CALL to a target address. - /// @param _target Address to call. - /// @param _data Data to send with the call. - /// @param _value ETH value to send with the call. - /// @return success_ Boolean success value. - /// @return data_ Bytes data returned by the call. - function CALL( - address _target, - bytes memory _data, - uint256 _value - ) - external - payable - onlyOwner - returns (bool success_, bytes memory data_) - { - (success_, data_) = _target.call{ value: _value }(_data); - require(success_, "Transactor: CALL failed"); - } - - /// @notice Sends a DELEGATECALL to a target address. - /// @param _target Address to call. - /// @param _data Data to send with the call. - /// @return success_ Boolean success value. - /// @return data_ Bytes data returned by the call. - function DELEGATECALL( - address _target, - bytes memory _data - ) - external - payable - onlyOwner - returns (bool success_, bytes memory data_) - { - // slither-disable-next-line controlled-delegatecall - (success_, data_) = _target.delegatecall(_data); - require(success_, "Transactor: DELEGATECALL failed"); - } -} From b2010063abdbe199eae002003eb044c17a012289 Mon Sep 17 00:00:00 2001 From: Louis Liu <35095310+louisliu2048@users.noreply.github.com> Date: Mon, 27 Oct 2025 14:43:06 +0800 Subject: [PATCH 12/26] update go mod, using remote op-geth instand local one (#126) Co-authored-by: louis.liu --- go.mod | 5 +++-- go.sum | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 254386a42af5a..075c22deb9688 100644 --- a/go.mod +++ b/go.mod @@ -193,6 +193,7 @@ require ( github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-reuseport v0.4.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.1 // indirect + github.com/linxGnu/grocksdb v1.10.2 // indirect github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect github.com/magiconair/properties v1.8.5 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect @@ -320,9 +321,9 @@ require ( lukechampine.com/blake3 v1.3.0 // indirect ) -//replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101603.1-rc.1 +replace github.com/ethereum/go-ethereum => github.com/okx/op-geth v0.0.6 -replace github.com/ethereum/go-ethereum => ./op-geth +//replace github.com/ethereum/go-ethereum => ./op-geth // replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain diff --git a/go.sum b/go.sum index 24819a243524a..4fa4161fd8483 100644 --- a/go.sum +++ b/go.sum @@ -680,6 +680,8 @@ github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQsc github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/linxGnu/grocksdb v1.10.2 h1:y0dXsWYULY15/BZMcwAZzLd13ZuyA470vyoNzWwmqG0= +github.com/linxGnu/grocksdb v1.10.2/go.mod h1:C3CNe9UYc9hlEM2pC82AqiGS3LRW537u9LFV4wIZuHk= github.com/lmittmann/w3 v0.19.5 h1:WwVRyIwhRLfIahmpB1EglsB3o1XWsgydgrxIUp5upFQ= github.com/lmittmann/w3 v0.19.5/go.mod h1:pN97sGGYGvsbqOYj/ms3Pd+7k/aiK/9OpNcxMmmzSOI= github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae h1:dIZY4ULFcto4tAFlj1FYZl8ztUZ13bdq+PLY+NOfbyI= @@ -800,6 +802,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/okx/op-geth v0.0.6 h1:6/jop2lGu2Ep9i466yprMJa1NeSCHIgqAArJSV35jS8= +github.com/okx/op-geth v0.0.6/go.mod h1:MD4m7TCs3bDlgtuio/99+iVscH4eEpkhvJuOojm7D/o= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= From 5e741d08daa96a446b130c6b53c54989ef5d9f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=80=AA=E5=85=BD?= <32981645+albbm@users.noreply.github.com> Date: Mon, 27 Oct 2025 19:03:31 +0800 Subject: [PATCH 13/26] =?UTF-8?q?Refactor=20DepositedOKBAdapter=20and=20Op?= =?UTF-8?q?timismPortal2=20to=20enhance=20token=20tra=E2=80=A6=20(#128)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor DepositedOKBAdapter and OptimismPortal2 to enhance token transfer handling and error management. Removed redundant error checks in DepositedOKBAdapter, integrated SafeERC20 for safer token transfers * Add error handling for insufficient deposit in OptimismPortal2 * Format code --- .../src/L1/DepositedOKBAdapter.sol | 22 ++++--------------- .../src/L1/OptimismPortal2.sol | 14 +++++++++++- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol b/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol index 3ce2b02f6aa4a..add7946ff72fd 100644 --- a/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol +++ b/packages/contracts-bedrock/src/L1/DepositedOKBAdapter.sol @@ -62,11 +62,6 @@ contract DepositedOKBAdapter is ERC20, Ownable, ReentrancyGuard { /// @notice Thrown when balance is insufficient. error InsufficientBalance(); - /// @notice Thrown when transfer fails. - error TransferFailed(); - - /// @notice Thrown when transfer OKB from user fails. - error TransferFromUserFailed(); /// @notice Thrown when OKB balance is not equal to the amount deposited. error OKBBalanceMismatch(); @@ -144,24 +139,15 @@ contract DepositedOKBAdapter is ERC20, Ownable, ReentrancyGuard { if (_amount == 0) { revert AmountMustBeGreaterThanZero(); } - if (OKB.balanceOf(msg.sender) < _amount) { - revert InsufficientBalance(); - } - // Transfer any remaining OKB to rescuer. // If someone mistakenly directly transfer OKB to this contract, transfer it to the owner. - if (OKB.balanceOf(address(this)) > 0) { - bool transferSuccess = OKB.transfer(owner(), OKB.balanceOf(address(this))); - if (!transferSuccess) { - revert TransferFailed(); - } + uint256 existingBalance = OKB.balanceOf(address(this)); + if (existingBalance > 0) { + IERC20(address(OKB)).safeTransfer(owner(), existingBalance); } // Transfer OKB from user to this contract first - bool transferFromUserSuccess = OKB.transferFrom(msg.sender, address(this), _amount); - if (!transferFromUserSuccess) { - revert TransferFromUserFailed(); - } + IERC20(address(OKB)).safeTransferFrom(msg.sender, address(this), _amount); // Check invariant: the amount of OKB in this contract should be equal to the amount deposited. if (OKB.balanceOf(address(this)) != _amount) { diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index a16c064e8724c..466258ecda327 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -29,6 +29,7 @@ import { IAnchorStateRegistry } from "interfaces/dispute/IAnchorStateRegistry.so import { IETHLockbox } from "interfaces/L1/IETHLockbox.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /// @custom:proxied true /// @title OptimismPortal2 @@ -36,6 +37,8 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /// and L2. Messages sent directly to the OptimismPortal have no form of replayability. /// Users are encouraged to use the L1CrossDomainMessenger for a higher-level interface. contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase, ProxyAdminOwnedBase, ISemver { + using SafeERC20 for IERC20; + /// @notice Represents a proven withdrawal. /// @custom:field disputeGameProxy Game that the withdrawal was proven against. /// @custom:field timestamp Timestamp at which the withdrawal was proven. @@ -215,6 +218,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase /// @notice Thrown when trying to use depositERC20Transaction but gas token not set. error OptimismPortal_InvalidGasToken(); + /// @notice Thrown when msg.value less than value. + error OptimismPortal_InsufficientDeposit(); + /// @notice Semantic version. /// @custom:semver 5.2.0 function version() public pure virtual returns (string memory) { @@ -584,6 +590,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase if (!_isUsingCustomGasToken()) { revert OptimismPortal_OnlyCustomGasToken(); } + if (_mint != _value) { + revert OptimismPortal_InsufficientDeposit(); + } // Transfer the custom gas token from the caller to this contract (address token,) = systemConfig.gasPayingToken(); @@ -592,7 +601,7 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase } if (_mint > 0) { - IERC20(token).transferFrom(msg.sender, address(this), _mint); + IERC20(token).safeTransferFrom(msg.sender, address(this), _mint); } // Just to be safe, make sure that people specify address(0) as the target when doing @@ -656,6 +665,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase if (_isUsingCustomGasToken()) { if (msg.value > 0) revert OptimismPortal_NotAllowedOnCGTMode(); } + if (msg.value != _value) { + revert OptimismPortal_InsufficientDeposit(); + } // If using ETHLockbox, lock the ETH in the ETHLockbox. if (_isUsingLockbox()) { From 9b0e12805320a9ab2835dcfda413aa24f9d916a2 Mon Sep 17 00:00:00 2001 From: cui Date: Tue, 28 Oct 2025 17:49:49 +0800 Subject: [PATCH 14/26] fix: remove script that cause failed (#131) Co-authored-by: weixie.cui --- test/0-all.sh | 1 - test/5-prepare-tests.sh | 59 ----------------------------------------- 2 files changed, 60 deletions(-) delete mode 100755 test/5-prepare-tests.sh diff --git a/test/0-all.sh b/test/0-all.sh index beed97fae7f57..04f483334ac9c 100755 --- a/test/0-all.sh +++ b/test/0-all.sh @@ -5,4 +5,3 @@ set -e ./2-deploy-op-contracts.sh ./3-op-init.sh ./4-op-start-service.sh -./5-prepare-tests.sh \ No newline at end of file diff --git a/test/5-prepare-tests.sh b/test/5-prepare-tests.sh deleted file mode 100755 index df9b61ee87a17..0000000000000 --- a/test/5-prepare-tests.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -set -e - -source .env - - -echo "=== Preparing test; Funding L1 Admin Address===" -L1_ADMIN_ADDRESS="0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" -L1_ADMIN_PRIVATE_KEY="0x815405dddb0e2a99b12af775fd2929e526704e1d1aea6a0b4e74dc33e2f7fcd2" -# cast send --rpc-url $L1_RPC_URL $L1_ADMIN_ADDRESS --private-key $RICH_L1_PRIVATE_KEY --value 1000ether --legacy - -echo "=== Bridging ETH from L1 to L2 ===" - -# Bridge contract addresses -OPTIMISM_PORTAL=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'optimismPortal()(address)') -RECIPIENT="0x14dC79964da2C08b23698B3D3cc7Ca32193d9955" # Default Rich Address -PRIVATE_KEY="0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356" # Default Rich Private Key - -echo "OPTIMISM PORTAL Address: $OPTIMISM_PORTAL" -echo "Recipient: $RECIPIENT" -cast balance $RECIPIENT --rpc-url $L2_RPC_URL -echo "Bridging 1 ETH from L1 to L2..." - -# Bridge 1 ETH to L2 -cast send $OPTIMISM_PORTAL \ - --rpc-url $L1_RPC_URL \ - --private-key $PRIVATE_KEY \ - --value 100ether \ - --legacy - -cast send $OPTIMISM_PORTAL \ - --rpc-url $L1_RPC_URL \ - --private-key $L1_ADMIN_PRIVATE_KEY \ - --value 100ether \ - --legacy - - - -echo -e "\nWaiting for bridging to complete..." - -echo "Checking L2 balance for $RECIPIENT:" -BALANCE=$(cast balance $RECIPIENT --rpc-url $L2_RPC_URL) -ADMIN_BALANCE=$(cast balance $L1_ADMIN_ADDRESS --rpc-url $L2_RPC_URL) - -WAIT_COUNT=0 -while [ $BALANCE == 0 ] || [ $ADMIN_BALANCE == 0 ]; do - WAIT_COUNT=$((WAIT_COUNT + 1)) - echo " ⏳ Waiting for bridge transactions to finalize... (${WAIT_COUNT})" - echo " Current L2 balance: $(cast --to-unit $BALANCE ether) ETH" - echo " Current Admin balance: $(cast --to-unit $ADMIN_BALANCE ether) ETH" - sleep 5 - BALANCE=$(cast balance $RECIPIENT --rpc-url $L2_RPC_URL) - ADMIN_BALANCE=$(cast balance $L1_ADMIN_ADDRESS --rpc-url $L2_RPC_URL) -done - -echo " ✅ Bridging complete!" -echo " Final L2 balance: $(cast --to-unit $BALANCE ether) ETH" -echo " Final Admin balance: $(cast --to-unit $ADMIN_BALANCE ether) ETH" From 2d5b5ab0b8e9dae5ea8a4f462497207d02fae02b Mon Sep 17 00:00:00 2001 From: Dumi Loghin Date: Wed, 29 Oct 2025 09:42:24 +0800 Subject: [PATCH 15/26] Improvement(devnet RPC): Reth as RPC (#88) * adding reth submodule * build op-reth docker image in init.sh * update op-geth submodule * add op-reth-rpc to docker-compose * bump op-reth * use rpc variable in docker compose * update op-reth * fix scripts to support op-reth-rpc * update op-reth * add p2p connections to op-reth-rpc * set trusted peers in geth rpc * update op-reth default branch * remove op-reth submodule and update init.sh * update readme * feature: RPC start and stop scripts for ease of testing * update op-geth * improvement(test): use entrypoint in docker compose for rpc * improvement(test): remove admin api from geth rpc * fix: init op-geth-rpc datadir on re-start * add new files to gitignore * change max-outbound-peers and max-inbound-peers to 10 * add reth rpc flags to enable tx forwarding * fix example.env * update readme * update readme * add stop rpc script * rm containers in kill-rpc.sh * fix example.env --- .gitignore | 3 ++ test/README.md | 18 ++++++++++ test/config-op/test.geth.rpc.config.toml | 2 +- test/docker-compose.yml | 44 ++++++------------------ test/entrypoint/geth-rpc.sh | 11 ++++++ test/entrypoint/reth-rpc.sh | 26 ++++++++++++++ test/example.env | 4 ++- test/scripts/kill-rpc.sh | 14 ++++++++ test/scripts/start-rpc.sh | 16 +++++++++ test/scripts/stop-rpc.sh | 10 ++++++ 10 files changed, 113 insertions(+), 35 deletions(-) create mode 100755 test/entrypoint/geth-rpc.sh create mode 100755 test/entrypoint/reth-rpc.sh create mode 100755 test/scripts/kill-rpc.sh create mode 100755 test/scripts/start-rpc.sh create mode 100755 test/scripts/stop-rpc.sh diff --git a/.gitignore b/.gitignore index 405751e77201a..6b2416a9507c2 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,9 @@ test/l1-geth/consensus/beacondata test/l1-geth/consensus/validatordata test/config-op/genesis.json test/config-op/genesis.json.gz +test/config-op/genesis-rpc.json +test/config-op/gen.test.geth.rpc.config.toml +test/config-op/gen.test.reth.rpc.config.toml test/config-op/implementations.json test/config-op/intent.toml test/config-op/rollup.json diff --git a/test/README.md b/test/README.md index e8c2ef2437050..73a29cfcad074 100644 --- a/test/README.md +++ b/test/README.md @@ -20,6 +20,24 @@ > Important: `init.sh` should only be run once during initial setup. Re-run only if you need to rebuild Docker images after code changes. +> Important: by default, `op-reth` image is not built. `op-geth` is used as RPC by default. If you want to run a Reth RPC node, please set the following variables in `example.env`: +```bash +OP_RETH_LOCAL_DIRECTORY= +OP_RETH_BRANCH= +SKIP_OP_RETH_BUILD=false +# L2_ENGINEKIND (RPC type): geth or reth +L2_ENGINEKIND=reth +RPC_TYPE=op-$L2_ENGINEKIND-rpc +``` + +For testing, we recommend using Reth v1.8.2, as follows: +```bash +git clone -b dev-1.8.2 https://github.com/okx/reth.git +cd reth +docker build -t op-reth:1.8.2 -f DockerfileOp . +docker tag op-reth:1.8.2 op-reth:latest +``` + ### Code Updates and Image Rebuilding (Optional) If you've updated the Optimism codebase and need to rebuild Docker images: diff --git a/test/config-op/test.geth.rpc.config.toml b/test/config-op/test.geth.rpc.config.toml index a98ff37bfad09..be5b88cf9e68e 100644 --- a/test/config-op/test.geth.rpc.config.toml +++ b/test/config-op/test.geth.rpc.config.toml @@ -3,7 +3,7 @@ HTTPHost = "0.0.0.0" HTTPPort = 8545 HTTPCors = ["*"] HTTPVirtualHosts = ["*"] -HTTPModules = ["web3", "debug", "eth", "txpool", "net", "engine", "miner", "admin"] +HTTPModules = ["web3", "debug", "eth", "txpool", "net", "engine", "miner"] WSHost = "0.0.0.0" WSPort = 7546 WSOrigins = ["*"] diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 3e9b11f13e020..881009d73bceb 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -200,60 +200,37 @@ services: start_period: 3s op-geth-rpc: - image: "${OP_GETH_IMAGE_TAG}" + image: "${OP_GETH_IMAGE_TAG:-op-geth:latest}" container_name: op-geth-rpc - entrypoint: geth + entrypoint: /entrypoint/geth-rpc.sh + env_file: + - .env volumes: - ./data/op-geth-rpc:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/gen.test.geth.rpc.config.toml:/config.toml + - ./entrypoint:/entrypoint ports: - "8124:8545" - "30304:30303" - "30304:30303/udp" - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - - --rollup.enabletxpooladmission op-reth-rpc: - image: "${OP_RETH_IMAGE_TAG}" + image: "${OP_RETH_IMAGE_TAG:-op-reth:latest}" container_name: op-reth-rpc - entrypoint: op-reth + entrypoint: /entrypoint/reth-rpc.sh + env_file: + - .env volumes: - ./data/op-reth-rpc:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/genesis-rpc.json:/genesis.json - ./config-op/gen.test.reth.rpc.config.toml:/config.toml + - ./entrypoint:/entrypoint ports: - "8124:8545" - "30304:30303" - "30304:30303/udp" - command: - - node - - --datadir=/datadir - - --chain=/genesis.json - - --config=/config.toml - - --http - - --http.corsdomain=* - - --http.port=8545 - - --http.addr=0.0.0.0 - - --http.api=web3,debug,eth,txpool,net,miner - - --ws - - --ws.addr=0.0.0.0 - - --ws.port=7546 - - --ws.origins=* - - --ws.api=debug,eth,txpool,net - - --disable-discovery - - --max-outbound-peers=0 - - --max-inbound-peers=0 - - --authrpc.addr=0.0.0.0 - - --authrpc.port=8552 - - --authrpc.jwtsecret=/jwt.txt - - --rollup.disable-tx-pool-gossip op-seq: image: "${OP_STACK_IMAGE_TAG}" @@ -341,6 +318,7 @@ services: - --l1.rpckind=standard - --rollup.l1-chain-config=/l1-genesis.json - --safedb.path=/data/safedb + - --l2.enginekind=${L2_ENGINEKIND} depends_on: - ${RPC_TYPE:-op-geth-rpc} diff --git a/test/entrypoint/geth-rpc.sh b/test/entrypoint/geth-rpc.sh new file mode 100755 index 0000000000000..1ceb47d391765 --- /dev/null +++ b/test/entrypoint/geth-rpc.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -e + +exec geth \ + --verbosity=3 \ + --datadir=/datadir \ + --db.engine=${DB_ENGINE:-pebble} \ + --config=/config.toml \ + --gcmode=archive \ + --rollup.enabletxpooladmission diff --git a/test/entrypoint/reth-rpc.sh b/test/entrypoint/reth-rpc.sh new file mode 100755 index 0000000000000..766dc296aaeda --- /dev/null +++ b/test/entrypoint/reth-rpc.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -e + +exec op-reth node \ + --datadir=/datadir \ + --chain=/genesis.json \ + --config=/config.toml \ + --http \ + --http.corsdomain=* \ + --http.port=8545 \ + --http.addr=0.0.0.0 \ + --http.api=web3,debug,eth,txpool,net,miner \ + --ws \ + --ws.addr=0.0.0.0 \ + --ws.port=7546 \ + --ws.origins=* \ + --ws.api=web3,debug,eth,txpool,net \ + --disable-discovery \ + --max-outbound-peers=10 \ + --max-inbound-peers=10 \ + --authrpc.addr=0.0.0.0 \ + --authrpc.port=8552 \ + --authrpc.jwtsecret=/jwt.txt \ + --rollup.disable-tx-pool-gossip \ + --rollup.sequencer-http=http://op-geth-seq:8545 diff --git a/test/example.env b/test/example.env index 64e3f3e81a45a..0e5e57f152a65 100644 --- a/test/example.env +++ b/test/example.env @@ -12,7 +12,9 @@ OP_RETH_IMAGE_TAG=op-reth:latest OP_STACK_IMAGE_TAG=op-stack:latest OP_CONTRACTS_IMAGE_TAG=op-contracts:latest -RPC_TYPE=op-geth-rpc +# L2_ENGINEKIND (RPC type): geth or reth +L2_ENGINEKIND=geth +RPC_TYPE=op-${L2_ENGINEKIND}-rpc DOCKER_NETWORK=dev-op CONFIG_DIR=config-op diff --git a/test/scripts/kill-rpc.sh b/test/scripts/kill-rpc.sh new file mode 100755 index 0000000000000..e31d928afe08d --- /dev/null +++ b/test/scripts/kill-rpc.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +source .env + +set -x + +docker compose kill $RPC_TYPE +docker compose kill op-rpc +docker rm -f $RPC_TYPE +docker rm -f op-rpc +rm -rf data/$RPC_TYPE +rm -rf data/op-rpc diff --git a/test/scripts/start-rpc.sh b/test/scripts/start-rpc.sh new file mode 100755 index 0000000000000..f60485826c96c --- /dev/null +++ b/test/scripts/start-rpc.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +source .env + +set -x + +if [ "$RPC_TYPE" = "op-geth-rpc" ]; then + OP_GETH_GENESIS_JSON="$(pwd)/config-op/genesis.json" + OP_GETH_RPC_DATADIR="$(pwd)/data/op-geth-rpc" + docker run --rm -v $OP_GETH_RPC_DATADIR:/datadir -v $OP_GETH_GENESIS_JSON:/genesis.json op-geth:latest init --datadir /datadir /genesis.json + sleep 3 +fi + +docker compose up -d op-rpc diff --git a/test/scripts/stop-rpc.sh b/test/scripts/stop-rpc.sh new file mode 100755 index 0000000000000..935466fdb026b --- /dev/null +++ b/test/scripts/stop-rpc.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -e + +source .env + +set -x + +docker compose kill $RPC_TYPE +docker compose kill op-rpc From f0f10320dbb149f8c7d38a55c5046d3da86a5292 Mon Sep 17 00:00:00 2001 From: Xzavier <707312973@qq.com> Date: Wed, 29 Oct 2025 12:07:55 +0800 Subject: [PATCH 16/26] support reth as sequencer and cooperate with conductor (#132) * feature(test): support reth as sequencer and work with op-conductor * chore(test): always use curl in healthcheck --- .gitignore | 1 + test/3-op-init.sh | 105 +++++++++-------------- test/4-op-start-service.sh | 58 +++++++++++-- test/clean.sh | 2 +- test/config-op/test.geth.rpc.config.toml | 7 +- test/config-op/test.seq.config.toml | 5 +- test/docker-compose.yml | 44 +++++++--- test/entrypoint/reth-rpc.sh | 6 +- test/example.env | 11 +-- test/scripts/add-peers.sh | 4 +- 10 files changed, 148 insertions(+), 95 deletions(-) diff --git a/.gitignore b/.gitignore index 6b2416a9507c2..cb4fa01415975 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ crytic-export test/l1-geth/consensus/beacondata test/l1-geth/consensus/validatordata test/config-op/genesis.json +test/config-op/genesis-reth.json test/config-op/genesis.json.gz test/config-op/genesis-rpc.json test/config-op/gen.test.geth.rpc.config.toml diff --git a/test/3-op-init.sh b/test/3-op-init.sh index e49e0e3ea5b4c..9198e7b2d2cd4 100755 --- a/test/3-op-init.sh +++ b/test/3-op-init.sh @@ -26,8 +26,8 @@ sed_inplace '/"70997970c51812dc3a010c7d01b50e0d17dc79c8": {/,/}/ s/"balance": "[ NEXT_BLOCK_NUMBER=$((FORK_BLOCK + 1)) NEXT_BLOCK_NUMBER_HEX=$(printf "0x%x" "$NEXT_BLOCK_NUMBER") sed_inplace 's/"number": 0/"number": '"$NEXT_BLOCK_NUMBER"'/' ./config-op/rollup.json -cp ./config-op/genesis.json ./config-op/genesis-rpc.json -sed_inplace 's/"number": "0x0"/"number": "'"$NEXT_BLOCK_NUMBER_HEX"'"/' ./config-op/genesis-rpc.json +cp ./config-op/genesis.json ./config-op/genesis-reth.json +sed_inplace 's/"number": "0x0"/"number": "'"$NEXT_BLOCK_NUMBER_HEX"'"/' ./config-op/genesis-reth.json # Extract contract addresses from state.json and update .env file echo "🔧 Extracting contract addresses from state.json..." @@ -130,40 +130,29 @@ docker compose run --no-deps --rm \ --datadir "/datadir" \ --gcmode=archive \ --db.engine=$DB_ENGINE \ - --log.format json \ init \ --state.scheme=hash \ - /genesis.json 2>&1 | tee init.log - -# Start op-geth-seq to get the block hash at FORK_BLOCK+1 -echo "🚀 Starting op-geth-seq to get block hash at FORK_BLOCK+1..." -docker compose up -d op-geth-seq - -# Wait for op-geth-seq to be ready -echo "⏳ Waiting for op-geth-seq to be ready..." -sleep 20 -set +x -# Get the block hash at FORK_BLOCK+1 -TARGET_BLOCK=$((FORK_BLOCK + 1)) -echo "🔍 Getting block hash at block number: $TARGET_BLOCK" -NEW_BLOCK_HASH=$(curl -s -X POST -H "Content-Type: application/json" --data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"params\":[\"0x$(printf "%x" $TARGET_BLOCK)\",false],\"id\":1}" http://localhost:8123 | jq -r '.result.hash' 2>/dev/null) -echo "New block hash: $NEW_BLOCK_HASH" -if [ -z "$NEW_BLOCK_HASH" ] || [ "$NEW_BLOCK_HASH" = "null" ] || [ "$NEW_BLOCK_HASH" = "undefined" ]; then - echo " ❌ Failed to get block hash at block $TARGET_BLOCK" - echo "Please check if op-geth-seq is running and has produced enough blocks" - docker compose logs op-geth-seq --tail=20 - exit 1 -fi -set -x - -echo " ✅ Got block hash at block $TARGET_BLOCK: $NEW_BLOCK_HASH" + /genesis.json + +# Remove nodekey to ensure other nodes generates a unique node ID +echo " 🔑 Removing nodekey to generate unique node ID for other nodes..." +rm -f "$OP_GETH_DATADIR/geth/nodekey" + +OP_RETH_DATADIR="$(pwd)/data/op-reth-seq" +rm -rf "$OP_RETH_DATADIR" +mkdir -p "$OP_RETH_DATADIR" +INIT_LOG=$(docker compose run --no-deps --rm \ + -v "$(pwd)/$CONFIG_DIR/genesis-reth.json:/genesis.json" \ + op-reth-seq \ + init \ + --datadir="/datadir" \ + --chain=/genesis.json \ + --log.stdout.format=json | tee init.log) -# Stop op-geth-seq after getting the hash -docker compose stop op-geth-seq +NEW_BLOCK_HASH=$(tail -n 1 init.log | jq -r .fields.hash) +echo "NEW_BLOCK_HASH=$NEW_BLOCK_HASH" +sed_inplace "s/NEW_BLOCK_HASH=.*/NEW_BLOCK_HASH=$NEW_BLOCK_HASH/" .env -# update genesis block hash in rollup.json -jq ".genesis.l2.hash = \"$NEW_BLOCK_HASH\"" config-op/rollup.json > config-op/rollup.json.tmp -mv config-op/rollup.json.tmp config-op/rollup.json # Copy initialized database from op-geth-seq to other nodes OP_GETH_RPC_DATADIR="$(pwd)/data/op-geth-rpc" @@ -172,38 +161,28 @@ echo " 🔄 Copying database from op-geth-seq to op-geth-rpc..." rm -rf "$OP_GETH_RPC_DATADIR" cp -r "$OP_GETH_DATADIR" "$OP_GETH_RPC_DATADIR" -# Remove nodekey to ensure op-geth-rpc generates a unique node ID -echo " 🔑 Removing nodekey to generate unique node ID for op-geth-rpc..." -rm -f "$OP_GETH_RPC_DATADIR/geth/nodekey" - - if [ "$CONDUCTOR_ENABLED" = "true" ]; then - OP_GETH_DATADIR="$(pwd)/data/op-geth-seq2" - rm -rf "$OP_GETH_DATADIR" - mkdir -p "$OP_GETH_DATADIR" - docker compose run --no-deps \ - -v "$(pwd)/$CONFIG_DIR/genesis.json:/genesis.json" \ - op-geth-seq2 \ - --datadir "/datadir" \ - --gcmode=archive \ - --db.engine=$DB_ENGINE \ - init \ - --state.scheme=hash \ - /genesis.json - - - OP_GETH_DATADIR="$(pwd)/data/op-geth-seq3" - rm -rf "$OP_GETH_DATADIR" - mkdir -p "$OP_GETH_DATADIR" - docker compose run --no-deps \ - -v "$(pwd)/$CONFIG_DIR/genesis.json:/genesis.json" \ - op-geth-seq3 \ - --datadir "/datadir" \ - --gcmode=archive \ - --db.engine=$DB_ENGINE \ - init \ - --state.scheme=hash \ - /genesis.json + if [ "$SEQ_TYPE" = "geth" ]; then + OP_GETH_DATADIR2="$(pwd)/data/op-geth-seq2" + rm -rf "$OP_GETH_DATADIR2" + cp -r $OP_GETH_DATADIR $OP_GETH_DATADIR2 + + OP_GETH_DATADIR3="$(pwd)/data/op-geth-seq3" + rm -rf "$OP_GETH_DATADIR3" + cp -r $OP_GETH_DATADIR $OP_GETH_DATADIR3 + elif [ "$SEQ_TYPE" = "reth" ]; then + OP_RETH_DATADIR2="$(pwd)/data/op-reth-seq2" + rm -rf "$OP_RETH_DATADIR2" + cp -r $OP_RETH_DATADIR $OP_RETH_DATADIR2 + + OP_RETH_DATADIR3="$(pwd)/data/op-reth-seq3" + rm -rf "$OP_RETH_DATADIR3" + cp -r $OP_RETH_DATADIR $OP_RETH_DATADIR3 + fi +fi + +if [ "$SEQ_TYPE" = "reth" ]; then + echo -n "1aba031aeb5aa8aedadaf04159d20e7d58eeefb3280176c7d59040476c2ab21b" > $OP_RETH_DATADIR/discovery-secret fi echo "finished init op-geth-seq and op-geth-rpc" diff --git a/test/4-op-start-service.sh b/test/4-op-start-service.sh index d6bba35e255ca..6e4d040843687 100755 --- a/test/4-op-start-service.sh +++ b/test/4-op-start-service.sh @@ -1,13 +1,63 @@ #!/bin/bash set -e +set -x # Load environment variables early source .env +sed_inplace() { + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(dirname "$PWD_DIR")" SCRIPTS_DIR=$ROOT_DIR/test/scripts +if [ "$SEQ_TYPE" = "geth" ]; then + # Start op-geth-seq to get the block hash at FORK_BLOCK+1 + echo "🚀 Starting op-geth-seq to get block hash at FORK_BLOCK+1..." + docker compose up -d op-geth-seq + sleep 5 + + # Get the block hash at FORK_BLOCK+1 + TARGET_BLOCK=$((FORK_BLOCK + 1)) + echo "⏳ Waiting for block height to reach $TARGET_BLOCK..." + while true; do + CURRENT_BLOCK=$(cast bn -r http://localhost:8123 2>/dev/null || echo "0") + if [ "$CURRENT_BLOCK" -ge "$TARGET_BLOCK" ]; then + echo "ok" + break + fi + echo " Current block height: $CURRENT_BLOCK, waiting for block $TARGET_BLOCK..." + sleep 1 + done + + NEW_BLOCK_HASH=$(cast block $TARGET_BLOCK -r http://localhost:8123 --json | jq -r .hash) + echo "New block hash: $NEW_BLOCK_HASH" + if [ -z "$NEW_BLOCK_HASH" ] || [ "$NEW_BLOCK_HASH" = "null" ] || [ "$NEW_BLOCK_HASH" = "undefined" ]; then + echo " ❌ Failed to get block hash at block $TARGET_BLOCK" + exit 1 + fi + + echo " ✅ Got block hash at block $TARGET_BLOCK: $NEW_BLOCK_HASH" + sed_inplace "s/NEW_BLOCK_HASH=.*/NEW_BLOCK_HASH=$NEW_BLOCK_HASH/" .env +else + echo "✅ Using existing NEW_BLOCK_HASH from .env for reth mode" + if [ -z "$NEW_BLOCK_HASH" ]; then + echo "❌ NEW_BLOCK_HASH is not set in .env for reth mode" + exit 1 + fi + echo "New block hash: $NEW_BLOCK_HASH" +fi + +# update genesis block hash in rollup.json +jq ".genesis.l2.hash = \"$NEW_BLOCK_HASH\"" config-op/rollup.json > config-op/rollup.json.tmp +mv config-op/rollup.json.tmp config-op/rollup.json + if [ "$CONDUCTOR_ENABLED" = "true" ]; then docker compose up -d op-conductor docker compose up -d op-conductor2 @@ -18,7 +68,7 @@ else docker compose up -d op-seq fi -$SCRIPTS_DIR/add-peers.sh +#$SCRIPTS_DIR/add-peers.sh if [ "$LAUNCH_RPC_NODE" = "true" ]; then docker compose up -d op-rpc @@ -31,12 +81,6 @@ if [ "$CONDUCTOR_ENABLED" = "true" ]; then export OP_BATCHER_L2_ETH_RPC="http://op-conductor:8547,http://op-conductor2:8547,http://op-conductor3:8547" export OP_BATCHER_ROLLUP_RPC="http://op-conductor:8547,http://op-conductor2:8547,http://op-conductor3:8547" echo "✅ op-batcher configured for conductor mode (connecting to conductor RPC endpoints)" -else - echo "🔧 Configuring op-batcher for single sequencer mode..." - # Set single sequencer mode endpoints - export OP_BATCHER_L2_ETH_RPC="http://op-geth-seq:8545" - export OP_BATCHER_ROLLUP_RPC="http://op-seq:9545" - echo "✅ op-batcher configured for single sequencer mode" fi docker compose up -d op-batcher diff --git a/test/clean.sh b/test/clean.sh index 6d21acdf8ea38..9198aeccbb433 100755 --- a/test/clean.sh +++ b/test/clean.sh @@ -9,7 +9,7 @@ echo " 📦 Stopping Docker containers..." echo " 🗑️ Removing generated files..." rm -rf data rm -rf config-op/genesis.json -rm -rf config-op/genesis-rpc.json +rm -rf config-op/genesis-reth.json rm -rf config-op/gen.test.reth.rpc.config.toml rm -rf config-op/gen.test.geth.rpc.config.toml rm -rf config-op/genesis.json.gz diff --git a/test/config-op/test.geth.rpc.config.toml b/test/config-op/test.geth.rpc.config.toml index be5b88cf9e68e..d78bdac58a606 100644 --- a/test/config-op/test.geth.rpc.config.toml +++ b/test/config-op/test.geth.rpc.config.toml @@ -16,8 +16,11 @@ JWTSecret = "/jwt.txt" [Node.P2P] MaxPeers = 30 DiscoveryV5 = true -StaticNodes = [] -TrustedNodes = [] +# we add both geth and reth to static nodes, but only one is live +StaticNodes = [ + "enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-geth-seq:30303", + "enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-reth-seq:30303" +] [Eth] NetworkId = 901 diff --git a/test/config-op/test.seq.config.toml b/test/config-op/test.seq.config.toml index ac2b0aa6b8269..39a5389fb61e5 100644 --- a/test/config-op/test.seq.config.toml +++ b/test/config-op/test.seq.config.toml @@ -16,6 +16,9 @@ JWTSecret = "/jwt.txt" [Node.P2P] MaxPeers = 30 DiscoveryV5 = true +StaticNodes = [ + "enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-geth-seq:30303" +] [Eth] NetworkId = 901 @@ -49,4 +52,4 @@ L1CoinId = 15756 L2CoinId = 7184 DefaultL1CoinPrice = 2000.0 DefaultL2CoinPrice = 0.5 -Factor = 0.1 \ No newline at end of file +Factor = 0.1 diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 881009d73bceb..3e9b11f13e020 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -200,37 +200,60 @@ services: start_period: 3s op-geth-rpc: - image: "${OP_GETH_IMAGE_TAG:-op-geth:latest}" + image: "${OP_GETH_IMAGE_TAG}" container_name: op-geth-rpc - entrypoint: /entrypoint/geth-rpc.sh - env_file: - - .env + entrypoint: geth volumes: - ./data/op-geth-rpc:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/gen.test.geth.rpc.config.toml:/config.toml - - ./entrypoint:/entrypoint ports: - "8124:8545" - "30304:30303" - "30304:30303/udp" + command: + - --verbosity=3 + - --datadir=/datadir + - --db.engine=${DB_ENGINE} + - --config=/config.toml + - --gcmode=archive + - --rollup.enabletxpooladmission op-reth-rpc: - image: "${OP_RETH_IMAGE_TAG:-op-reth:latest}" + image: "${OP_RETH_IMAGE_TAG}" container_name: op-reth-rpc - entrypoint: /entrypoint/reth-rpc.sh - env_file: - - .env + entrypoint: op-reth volumes: - ./data/op-reth-rpc:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/genesis-rpc.json:/genesis.json - ./config-op/gen.test.reth.rpc.config.toml:/config.toml - - ./entrypoint:/entrypoint ports: - "8124:8545" - "30304:30303" - "30304:30303/udp" + command: + - node + - --datadir=/datadir + - --chain=/genesis.json + - --config=/config.toml + - --http + - --http.corsdomain=* + - --http.port=8545 + - --http.addr=0.0.0.0 + - --http.api=web3,debug,eth,txpool,net,miner + - --ws + - --ws.addr=0.0.0.0 + - --ws.port=7546 + - --ws.origins=* + - --ws.api=debug,eth,txpool,net + - --disable-discovery + - --max-outbound-peers=0 + - --max-inbound-peers=0 + - --authrpc.addr=0.0.0.0 + - --authrpc.port=8552 + - --authrpc.jwtsecret=/jwt.txt + - --rollup.disable-tx-pool-gossip op-seq: image: "${OP_STACK_IMAGE_TAG}" @@ -318,7 +341,6 @@ services: - --l1.rpckind=standard - --rollup.l1-chain-config=/l1-genesis.json - --safedb.path=/data/safedb - - --l2.enginekind=${L2_ENGINEKIND} depends_on: - ${RPC_TYPE:-op-geth-rpc} diff --git a/test/entrypoint/reth-rpc.sh b/test/entrypoint/reth-rpc.sh index 766dc296aaeda..a7511fba391d1 100755 --- a/test/entrypoint/reth-rpc.sh +++ b/test/entrypoint/reth-rpc.sh @@ -5,12 +5,11 @@ set -e exec op-reth node \ --datadir=/datadir \ --chain=/genesis.json \ - --config=/config.toml \ --http \ --http.corsdomain=* \ --http.port=8545 \ --http.addr=0.0.0.0 \ - --http.api=web3,debug,eth,txpool,net,miner \ + --http.api=web3,debug,eth,txpool,net,miner,admin \ --ws \ --ws.addr=0.0.0.0 \ --ws.port=7546 \ @@ -23,4 +22,5 @@ exec op-reth node \ --authrpc.port=8552 \ --authrpc.jwtsecret=/jwt.txt \ --rollup.disable-tx-pool-gossip \ - --rollup.sequencer-http=http://op-geth-seq:8545 + --rollup.sequencer-http=http://op-${SEQ_TYPE}-seq:8545 + --trusted-peers=enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-${SEQ_TYPE}-seq:30303 diff --git a/test/example.env b/test/example.env index 0e5e57f152a65..49324ccc6bfff 100644 --- a/test/example.env +++ b/test/example.env @@ -12,10 +12,6 @@ OP_RETH_IMAGE_TAG=op-reth:latest OP_STACK_IMAGE_TAG=op-stack:latest OP_CONTRACTS_IMAGE_TAG=op-contracts:latest -# L2_ENGINEKIND (RPC type): geth or reth -L2_ENGINEKIND=geth -RPC_TYPE=op-${L2_ENGINEKIND}-rpc - DOCKER_NETWORK=dev-op CONFIG_DIR=config-op @@ -51,7 +47,7 @@ OPTIMISM_PORTAL_PROXY_ADDRESS=0xc8e8b7b181db301f27aef90ed285787a3ce179e9 OKB_ADAPTER_OWNER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 # OKB Token Address on L1. If not set, a new MockOKB will be deployed. -OKB_TOKEN_ADDRESS=0x75231f58b43240c9718dd58b4967c5114342a86c +OKB_TOKEN_ADDRESS= # First game only for update anchor root TEMP_MAX_CLOCK_DURATION=40 @@ -75,6 +71,7 @@ WITHDRAWAL_DELAY_SECONDS=$MAX_CLOCK_DURATION # TODO: use real fork block and parent hash in xlayer erigon FORK_BLOCK=8593920 PARENT_HASH="0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a" +NEW_BLOCK_HASH=0xddb9bdc86631494bab4b4749c4575035e2383da7c96d32d31341de862b1dd6c9 DB_ENGINE="pebble" @@ -82,3 +79,7 @@ CONDUCTOR_ENABLED=true LAUNCH_RPC_NODE=true OWNER_TYPE=transactor # safe + +# only support `geth` or `reth` +SEQ_TYPE=geth +RPC_TYPE=geth diff --git a/test/scripts/add-peers.sh b/test/scripts/add-peers.sh index 00bf0aa711728..4dc56503f9421 100755 --- a/test/scripts/add-peers.sh +++ b/test/scripts/add-peers.sh @@ -107,13 +107,13 @@ if [ "$LAUNCH_RPC_NODE" = "true" ]; then if [ "$CONDUCTOR_ENABLED" = "true" ]; then OP_RPC_TRUSTED_NODES="\"$OP_GETH_SEQ_ENODE\",\"$OP_GETH_SEQ2_ENODE\",\"$OP_GETH_SEQ3_ENODE\"" fi - if [ "$RPC_TYPE" = "op-geth-rpc" ]; then + if [ "$RPC_TYPE" = "geth" ]; then cp ./config-op/test.geth.rpc.config.toml ./config-op/gen.test.geth.rpc.config.toml # Here we use # as delimiter to avoid escaping // in enode URLs # Add as both StaticNodes for peers, and TrustedNodes to bypass peer limits sed_inplace 's#StaticNodes = \[\]#StaticNodes = \['"$OP_RPC_TRUSTED_NODES"'\]#' ./config-op/gen.test.geth.rpc.config.toml sed_inplace 's#TrustedNodes = \[\]#TrustedNodes = \['"$OP_RPC_TRUSTED_NODES"'\]#' ./config-op/gen.test.geth.rpc.config.toml - elif [ "$RPC_TYPE" = "op-reth-rpc" ]; then + elif [ "$RPC_TYPE" = "reth" ]; then cp ./config-op/test.reth.rpc.config.toml ./config-op/gen.test.reth.rpc.config.toml # Here we use # as delimiter to avoid escaping // in enode URLs sed_inplace 's#trusted_nodes = \[\]#trusted_nodes = \['"$OP_RPC_TRUSTED_NODES"'\]#' ./config-op/gen.test.reth.rpc.config.toml From ed48d795fe9dc16a4f245c4d907deed7e3f61289 Mon Sep 17 00:00:00 2001 From: Xzavier <707312973@qq.com> Date: Wed, 29 Oct 2025 16:27:56 +0800 Subject: [PATCH 17/26] chore(test): fix some issues (#134) --- test/config-op/test.geth.rpc.config.toml | 2 +- test/docker-compose.yml | 164 ++++++++++++++++++----- 2 files changed, 133 insertions(+), 33 deletions(-) diff --git a/test/config-op/test.geth.rpc.config.toml b/test/config-op/test.geth.rpc.config.toml index d78bdac58a606..1350e26ad5084 100644 --- a/test/config-op/test.geth.rpc.config.toml +++ b/test/config-op/test.geth.rpc.config.toml @@ -3,7 +3,7 @@ HTTPHost = "0.0.0.0" HTTPPort = 8545 HTTPCors = ["*"] HTTPVirtualHosts = ["*"] -HTTPModules = ["web3", "debug", "eth", "txpool", "net", "engine", "miner"] +HTTPModules = ["web3", "debug", "eth", "txpool", "net", "engine", "miner", "admin"] WSHost = "0.0.0.0" WSPort = 7546 WSOrigins = ["*"] diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 3e9b11f13e020..11857901c060c 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -192,6 +192,7 @@ services: - --config=/config.toml - --gcmode=archive - --rollup.disabletxpoolgossip=false + - -nodekeyhex=1aba031aeb5aa8aedadaf04159d20e7d58eeefb3280176c7d59040476c2ab21b healthcheck: test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] interval: 3s @@ -199,14 +200,53 @@ services: retries: 10 start_period: 3s + op-reth-seq: + image: "${OP_RETH_IMAGE_TAG}" + container_name: op-reth-seq + volumes: + - ./data/op-reth-seq:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/genesis-reth.json:/genesis.json + ports: + - "8123:8545" + - "7546:7546" + - "8552:8552" + - "30303:30303" + - "30303:30303/udp" + - "9090:9090" # pprof port + command: + - node + - --datadir=/datadir + - --chain=/genesis.json + - --http + - --http.corsdomain=* + - --http.port=8545 + - --http.addr=0.0.0.0 + - --http.api=web3,debug,eth,txpool,net,miner,admin + - --ws + - --ws.addr=0.0.0.0 + - --ws.port=7546 + - --ws.origins=* + - --ws.api=debug,eth,txpool,net + - --authrpc.addr=0.0.0.0 + - --authrpc.port=8552 + - --authrpc.jwtsecret=/jwt.txt + - --rollup.disable-tx-pool-gossip + - --rollup.sequencer=http://op-seq:8547 + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8545" ] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + op-geth-rpc: image: "${OP_GETH_IMAGE_TAG}" container_name: op-geth-rpc - entrypoint: geth volumes: - ./data/op-geth-rpc:/datadir - ./config-op/jwt.txt:/jwt.txt - - ./config-op/gen.test.geth.rpc.config.toml:/config.toml + - ./config-op/test.geth.rpc.config.toml:/config.toml ports: - "8124:8545" - "30304:30303" @@ -222,12 +262,10 @@ services: op-reth-rpc: image: "${OP_RETH_IMAGE_TAG}" container_name: op-reth-rpc - entrypoint: op-reth volumes: - ./data/op-reth-rpc:/datadir - ./config-op/jwt.txt:/jwt.txt - - ./config-op/genesis-rpc.json:/genesis.json - - ./config-op/gen.test.reth.rpc.config.toml:/config.toml + - ./config-op/genesis-reth.json:/genesis.json ports: - "8124:8545" - "30304:30303" @@ -241,19 +279,17 @@ services: - --http.corsdomain=* - --http.port=8545 - --http.addr=0.0.0.0 - - --http.api=web3,debug,eth,txpool,net,miner + - --http.api=web3,debug,eth,txpool,net,miner,admin - --ws - --ws.addr=0.0.0.0 - --ws.port=7546 - --ws.origins=* - --ws.api=debug,eth,txpool,net - - --disable-discovery - - --max-outbound-peers=0 - - --max-inbound-peers=0 - --authrpc.addr=0.0.0.0 - --authrpc.port=8552 - --authrpc.jwtsecret=/jwt.txt - --rollup.disable-tx-pool-gossip + - --trusted-peers=enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-${SEQ_TYPE}-seq:30303 op-seq: image: "${OP_STACK_IMAGE_TAG}" @@ -272,7 +308,7 @@ services: command: - /app/op-node/bin/op-node - --log.level=debug - - --l2=http://op-geth-seq:8552 + - --l2=http://op-${SEQ_TYPE}-seq:8552 - --l2.jwt-secret=/jwt.txt - --sequencer.enabled - --sequencer.l1-confs=5 @@ -297,9 +333,9 @@ services: - --pprof.enabled - --pprof.addr=0.0.0.0 - --pprof.port=9091 + - --l2.enginekind=${SEQ_TYPE} depends_on: - op-geth-seq: - condition: service_healthy + - op-${SEQ_TYPE}-seq healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9545"] interval: 3s @@ -314,14 +350,13 @@ services: - ./data/op-rpc:/data - ./config-op/rollup.json:/rollup.json - ./config-op/jwt.txt:/jwt.txt - - ./config-op/oprpc_p2p_priv.txt:/opnode_p2p_priv.txt - ./l1-geth/execution/genesis.json:/l1-genesis.json ports: - "9555:9545" command: - /app/op-node/bin/op-node - --log.level=debug - - --l2=http://${RPC_TYPE:-op-geth-rpc}:8552 + - --l2=http://op-${RPC_TYPE}-rpc:8552 - --l2.jwt-secret=/jwt.txt - --sequencer.enabled=false - --verifier.l1-confs=1 @@ -341,8 +376,9 @@ services: - --l1.rpckind=standard - --rollup.l1-chain-config=/l1-genesis.json - --safedb.path=/data/safedb + - --l2.enginekind=${RPC_TYPE} depends_on: - - ${RPC_TYPE:-op-geth-rpc} + - op-${RPC_TYPE}-rpc op-conductor: image: "${OP_STACK_IMAGE_TAG}" @@ -358,7 +394,7 @@ services: - --log.level=debug # already existed service - --node.rpc=http://op-seq:9545 - - --execution.rpc=http://op-geth-seq:8545 + - --execution.rpc=http://op-${RPC_TYPE}-seq:8545 # Raft Config - --raft.server.id=conductor-1 - --raft.storage.dir=/data/raft @@ -378,8 +414,6 @@ services: depends_on: op-seq: condition: service_healthy - op-geth-seq: - condition: service_healthy op-batcher: image: "${OP_STACK_IMAGE_TAG}" @@ -387,7 +421,7 @@ services: command: - /app/op-batcher/bin/op-batcher - --log.level=debug - - --l2-eth-rpc=${OP_BATCHER_L2_ETH_RPC:-http://op-geth-seq:8545} + - --l2-eth-rpc=${OP_BATCHER_L2_ETH_RPC:-http://op-${SEQ_TYPE}-seq:8545} - --rollup-rpc=${OP_BATCHER_ROLLUP_RPC:-http://op-seq:9545} # - --txmgr.enable-cell-proofs=true - --wait-node-sync=true @@ -456,7 +490,7 @@ services: - --log.level=debug - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} - --l1-beacon=${L1_BEACON_URL_IN_DOCKER} - - --l2-eth-rpc=http://op-geth-rpc:8545 + - --l2-eth-rpc=http://op-${RPC_TYPE}-rpc:8545 - --rollup-rpc=http://op-rpc:9545 - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} - --cannon-bin=/app/cannon/bin/cannon @@ -509,6 +543,44 @@ services: retries: 10 start_period: 3s + op-reth-seq2: + image: "${OP_RETH_IMAGE_TAG}" + container_name: op-reth-seq2 + volumes: + - ./data/op-reth-seq2:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/genesis-reth.json:/genesis.json + ports: + - "8223:8545" + - "30305:30303" + - "30305:30303/udp" + command: + - node + - --datadir=/datadir + - --chain=/genesis.json + - --http + - --http.corsdomain=* + - --http.port=8545 + - --http.addr=0.0.0.0 + - --http.api=web3,debug,eth,txpool,net,miner,admin + - --ws + - --ws.addr=0.0.0.0 + - --ws.port=7546 + - --ws.origins=* + - --ws.api=debug,eth,txpool,net + - --authrpc.addr=0.0.0.0 + - --authrpc.port=8552 + - --authrpc.jwtsecret=/jwt.txt + - --rollup.disable-tx-pool-gossip + - --rollup.sequencer=http://op-seq:8547 + - --trusted-peers=enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-reth-seq:30303 + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8545" ] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s + op-seq2: image: "${OP_STACK_IMAGE_TAG}" container_name: op-seq2 @@ -525,7 +597,7 @@ services: command: - /app/op-node/bin/op-node - --log.level=info - - --l2=http://op-geth-seq2:8552 + - --l2=http://op-${SEQ_TYPE}-seq2:8552 - --l2.jwt-secret=/jwt.txt - --sequencer.enabled - --sequencer.stopped @@ -549,9 +621,9 @@ services: - --safedb.path=/data/safedb - --conductor.enabled=${CONDUCTOR_ENABLED:-false} - --conductor.rpc=http://op-conductor2:8547 + - --l2.enginekind=${SEQ_TYPE} depends_on: - op-geth-seq2: - condition: service_healthy + - op-${SEQ_TYPE}-seq2 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9545"] interval: 3s @@ -573,7 +645,7 @@ services: - --log.level=debug # already existed service - --node.rpc=http://op-seq2:9545 - - --execution.rpc=http://op-geth-seq2:8545 + - --execution.rpc=http://op-${SEQ_TYPE}-seq2:8545 # Raft Config - --raft.server.id=conductor-2 - --raft.storage.dir=/data/raft @@ -593,8 +665,6 @@ services: depends_on: op-seq2: condition: service_healthy - op-geth-seq2: - condition: service_healthy op-geth-seq3: image: "${OP_GETH_IMAGE_TAG}" @@ -622,6 +692,38 @@ services: retries: 10 start_period: 3s + op-reth-seq3: + image: "${OP_RETH_IMAGE_TAG}" + container_name: op-reth-seq3 + volumes: + - ./data/op-reth-seq3:/datadir + - ./config-op/jwt.txt:/jwt.txt + - ./config-op/genesis-reth.json:/genesis.json + command: + - node + - --datadir=/datadir + - --chain=/genesis.json + - --http + - --http.corsdomain=* + - --http.port=8545 + - --http.addr=0.0.0.0 + - --http.api=web3,debug,eth,txpool,net,miner,admin + - --ws + - --ws.addr=0.0.0.0 + - --ws.port=7546 + - --ws.origins=* + - --ws.api=debug,eth,txpool,net + - --authrpc.addr=0.0.0.0 + - --authrpc.port=8552 + - --authrpc.jwtsecret=/jwt.txt + - --rollup.disable-tx-pool-gossip + - --rollup.sequencer=http://op-seq:8547 + - --trusted-peers=enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-reth-seq:30303 + ports: + - "8323:8545" + - "30306:30303" + - "30306:30303/udp" + op-seq3: image: "${OP_STACK_IMAGE_TAG}" container_name: op-seq3 @@ -638,7 +740,7 @@ services: command: - /app/op-node/bin/op-node - --log.level=info - - --l2=http://op-geth-seq3:8552 + - --l2=http://op-${SEQ_TYPE}-seq3:8552 - --l2.jwt-secret=/jwt.txt - --sequencer.enabled - --sequencer.stopped @@ -662,9 +764,9 @@ services: - --safedb.path=/data/safedb - --conductor.enabled=${CONDUCTOR_ENABLED:-false} - --conductor.rpc=http://op-conductor3:8547 + - --l2.enginekind=${SEQ_TYPE} depends_on: - op-geth-seq3: - condition: service_healthy + - op-${SEQ_TYPE}-seq3 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9545"] interval: 3s @@ -686,7 +788,7 @@ services: - --log.level=debug # already existed service - --node.rpc=http://op-seq3:9545 - - --execution.rpc=http://op-geth-seq3:8545 + - --execution.rpc=http://op-${SEQ_TYPE}-seq3:8545 # Raft Config - --raft.server.id=conductor-3 - --raft.storage.dir=/data/raft @@ -706,5 +808,3 @@ services: depends_on: op-seq3: condition: service_healthy - op-geth-seq3: - condition: service_healthy From 6bac4706a241b8e94040ca4d7ce64fce5fb002a3 Mon Sep 17 00:00:00 2001 From: Dumi Loghin Date: Wed, 29 Oct 2025 18:29:09 +0800 Subject: [PATCH 18/26] feature(devnet): Reth as sequencer (#133) * adding reth submodule * build op-reth docker image in init.sh * update op-geth submodule * add op-reth-rpc to docker-compose * bump op-reth * use rpc variable in docker compose * update op-reth * fix scripts to support op-reth-rpc * update op-reth * add p2p connections to op-reth-rpc * set trusted peers in geth rpc * update op-reth default branch * remove op-reth submodule and update init.sh * update readme * feature: RPC start and stop scripts for ease of testing * update op-geth * improvement(test): use entrypoint in docker compose for rpc * improvement(test): remove admin api from geth rpc * fix: init op-geth-rpc datadir on re-start * add new files to gitignore * change max-outbound-peers and max-inbound-peers to 10 * feat(reth seq): add initial changes to make reth seq run * add reth rpc flags to enable tx forwarding * updtae gitignore * add reth rpc flags to enable tx forwarding * fix example.env * update readme * update readme * add stop rpc script * rm containers in kill-rpc.sh * fix scripts * fix scripts and configs * fix script * fix: add trusted peer for reth seq --- .gitignore | 2 +- test/3-op-init.sh | 20 +++- test/4-op-start-service.sh | 8 ++ ....config.toml => test.geth.seq.config.toml} | 4 +- test/config-op/test.reth.rpc.config.toml | 3 + test/config-op/test.reth.seq.config.toml | 105 ++++++++++++++++++ test/docker-compose.yml | 72 ++++-------- test/entrypoint/reth-rpc.sh | 5 +- test/entrypoint/reth-seq.sh | 28 +++++ test/example.env | 11 +- test/scripts/add-peers.sh | 20 ++-- test/scripts/kill-rpc.sh | 6 +- test/scripts/start-rpc.sh | 4 +- test/scripts/stop-rpc.sh | 2 +- 14 files changed, 210 insertions(+), 80 deletions(-) rename test/config-op/{test.seq.config.toml => test.geth.seq.config.toml} (85%) create mode 100644 test/config-op/test.reth.seq.config.toml create mode 100755 test/entrypoint/reth-seq.sh diff --git a/.gitignore b/.gitignore index cb4fa01415975..67cf30aecd1c2 100644 --- a/.gitignore +++ b/.gitignore @@ -58,7 +58,7 @@ test/l1-geth/consensus/validatordata test/config-op/genesis.json test/config-op/genesis-reth.json test/config-op/genesis.json.gz -test/config-op/genesis-rpc.json +test/config-op/genesis-reth.json test/config-op/gen.test.geth.rpc.config.toml test/config-op/gen.test.reth.rpc.config.toml test/config-op/implementations.json diff --git a/test/3-op-init.sh b/test/3-op-init.sh index 9198e7b2d2cd4..3c05a598fb84e 100755 --- a/test/3-op-init.sh +++ b/test/3-op-init.sh @@ -120,10 +120,12 @@ else echo " ❌ state.json not found at $STATE_JSON" fi -# init op-geth-seq and op-geth-rpc +# init geth sequencer +echo " 🔧 Initializing geth sequencer..." OP_GETH_DATADIR="$(pwd)/data/op-geth-seq" rm -rf "$OP_GETH_DATADIR" mkdir -p "$OP_GETH_DATADIR" + docker compose run --no-deps --rm \ -v "$(pwd)/$CONFIG_DIR/genesis.json:/genesis.json" \ op-geth-seq \ @@ -138,11 +140,14 @@ docker compose run --no-deps --rm \ echo " 🔑 Removing nodekey to generate unique node ID for other nodes..." rm -f "$OP_GETH_DATADIR/geth/nodekey" +# init reth sequencer +echo " 🔧 Initializing reth sequencer..." OP_RETH_DATADIR="$(pwd)/data/op-reth-seq" rm -rf "$OP_RETH_DATADIR" mkdir -p "$OP_RETH_DATADIR" INIT_LOG=$(docker compose run --no-deps --rm \ -v "$(pwd)/$CONFIG_DIR/genesis-reth.json:/genesis.json" \ + --entrypoint op-reth \ op-reth-seq \ init \ --datadir="/datadir" \ @@ -185,13 +190,21 @@ if [ "$SEQ_TYPE" = "reth" ]; then echo -n "1aba031aeb5aa8aedadaf04159d20e7d58eeefb3280176c7d59040476c2ab21b" > $OP_RETH_DATADIR/discovery-secret fi -echo "finished init op-geth-seq and op-geth-rpc" +echo "✅ Finished init op-$SEQ_TYPE-seq and op-$RPC_TYPE-rpc." # genesis.json is too large to embed in go, so we compress it now and decompress it in go code gzip -c config-op/genesis.json > config-op/genesis.json.gz # Ensure prestate files exist and devnetL1.json is consistent before deploying contracts EXPORT_DIR="$PWD_DIR/data/cannon-data" +SAVED_CANNON_DATA_DIR="$PWD_DIR/saved-cannon-data" + +if [ "$SKIP_BUILD_PRESTATE" = "true" ] && [ -d "$SAVED_CANNON_DATA_DIR" ]; then + echo "🔄 Skipping building op-program prestate files. Copying saved cannon data from $SAVED_CANNON_DATA_DIR to $EXPORT_DIR..." + cp -r $SAVED_CANNON_DATA_DIR $EXPORT_DIR + exit 0 +fi + rm -rf $EXPORT_DIR mkdir -p $EXPORT_DIR @@ -220,3 +233,6 @@ $DOCKER_CMD \ /scripts/docker-install-start.sh $DOCKER_TYPE make -C op-program reproducible-prestate " + +echo "🔄 Copying built prestate files from $EXPORT_DIR to $SAVED_CANNON_DATA_DIR..." +cp -r $EXPORT_DIR $SAVED_CANNON_DATA_DIR diff --git a/test/4-op-start-service.sh b/test/4-op-start-service.sh index 6e4d040843687..84c867da6888e 100755 --- a/test/4-op-start-service.sh +++ b/test/4-op-start-service.sh @@ -68,6 +68,8 @@ else docker compose up -d op-seq fi +sleep 5 + #$SCRIPTS_DIR/add-peers.sh if [ "$LAUNCH_RPC_NODE" = "true" ]; then @@ -81,6 +83,12 @@ if [ "$CONDUCTOR_ENABLED" = "true" ]; then export OP_BATCHER_L2_ETH_RPC="http://op-conductor:8547,http://op-conductor2:8547,http://op-conductor3:8547" export OP_BATCHER_ROLLUP_RPC="http://op-conductor:8547,http://op-conductor2:8547,http://op-conductor3:8547" echo "✅ op-batcher configured for conductor mode (connecting to conductor RPC endpoints)" +else + echo "🔧 Configuring op-batcher for single sequencer mode..." + # Set single sequencer mode endpoints + export OP_BATCHER_L2_ETH_RPC="http://op-${SEQ_TYPE}-seq:8545" + export OP_BATCHER_ROLLUP_RPC="http://op-seq:9545" + echo "✅ op-batcher configured for single sequencer mode" fi docker compose up -d op-batcher diff --git a/test/config-op/test.seq.config.toml b/test/config-op/test.geth.seq.config.toml similarity index 85% rename from test/config-op/test.seq.config.toml rename to test/config-op/test.geth.seq.config.toml index 39a5389fb61e5..d7458e5d52633 100644 --- a/test/config-op/test.seq.config.toml +++ b/test/config-op/test.geth.seq.config.toml @@ -16,9 +16,7 @@ JWTSecret = "/jwt.txt" [Node.P2P] MaxPeers = 30 DiscoveryV5 = true -StaticNodes = [ - "enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-geth-seq:30303" -] +StaticNodes = [] [Eth] NetworkId = 901 diff --git a/test/config-op/test.reth.rpc.config.toml b/test/config-op/test.reth.rpc.config.toml index 36e1a77fc34c0..cdf0bd9fb8bef 100644 --- a/test/config-op/test.reth.rpc.config.toml +++ b/test/config-op/test.reth.rpc.config.toml @@ -68,6 +68,9 @@ incoming_ip_throttle_duration = "30s" max_outbound = 100 max_inbound = 30 max_concurrent_outbound_dials = 15 +trusted_nodes = ["enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-geth-seq:30303", +"enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-reth-seq:30303"] +trusted_nodes_only = true [peers.reputation_weights] bad_message = -16384 diff --git a/test/config-op/test.reth.seq.config.toml b/test/config-op/test.reth.seq.config.toml new file mode 100644 index 0000000000000..36e1a77fc34c0 --- /dev/null +++ b/test/config-op/test.reth.seq.config.toml @@ -0,0 +1,105 @@ +[stages.era] + +[stages.headers] +downloader_max_concurrent_requests = 100 +downloader_min_concurrent_requests = 5 +downloader_max_buffered_responses = 100 +downloader_request_limit = 1000 +commit_threshold = 10000 + +[stages.bodies] +downloader_request_limit = 200 +downloader_stream_batch_size = 1000 +downloader_max_buffered_blocks_size_bytes = 2147483648 +downloader_min_concurrent_requests = 5 +downloader_max_concurrent_requests = 100 + +[stages.sender_recovery] +commit_threshold = 5000000 + +[stages.execution] +max_blocks = 500000 +max_changes = 5000000 +max_cumulative_gas = 1500000000000 +max_duration = "10m" + +[stages.prune] +commit_threshold = 1000000 + +[stages.account_hashing] +clean_threshold = 500000 +commit_threshold = 100000 + +[stages.storage_hashing] +clean_threshold = 500000 +commit_threshold = 100000 + +[stages.merkle] +incremental_threshold = 7000 +rebuild_threshold = 100000 + +[stages.transaction_lookup] +chunk_size = 5000000 + +[stages.index_account_history] +commit_threshold = 100000 + +[stages.index_storage_history] +commit_threshold = 100000 + +[stages.etl] +file_size = 524288000 + +[prune] +block_interval = 5 + +[prune.segments.receipts_log_filter] + +[peers] +refill_slots_interval = "5s" +trusted_nodes = [] +trusted_nodes_only = true +trusted_nodes_resolution_interval = "1h" +max_backoff_count = 5 +ban_duration = "12h" +incoming_ip_throttle_duration = "30s" + +[peers.connection_info] +max_outbound = 100 +max_inbound = 30 +max_concurrent_outbound_dials = 15 + +[peers.reputation_weights] +bad_message = -16384 +bad_block = -16384 +bad_transactions = -16384 +already_seen_transactions = 0 +timeout = -4096 +bad_protocol = -2147483648 +failed_to_connect = -25600 +dropped = -4096 +bad_announcement = -1024 + +[peers.backoff_durations] +low = "30s" +medium = "3m" +high = "15m" +max = "1h" + +[sessions] +session_command_buffer = 32 +session_event_buffer = 260 + +[sessions.limits] + +[sessions.initial_internal_request_timeout] +secs = 20 +nanos = 0 + +[sessions.protocol_breach_request_timeout] +secs = 120 +nanos = 0 + +[sessions.pending_session_timeout] +secs = 20 +nanos = 0 diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 11857901c060c..95e571d2abef2 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -177,7 +177,7 @@ services: volumes: - ./data/op-geth-seq:/datadir - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.seq.config.toml:/config.toml + - ./config-op/test.geth.seq.config.toml:/config.toml ports: - "8123:8545" - "7546:7546" @@ -192,7 +192,7 @@ services: - --config=/config.toml - --gcmode=archive - --rollup.disabletxpoolgossip=false - - -nodekeyhex=1aba031aeb5aa8aedadaf04159d20e7d58eeefb3280176c7d59040476c2ab21b + - --nodekeyhex=1aba031aeb5aa8aedadaf04159d20e7d58eeefb3280176c7d59040476c2ab21b healthcheck: test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] interval: 3s @@ -203,38 +203,23 @@ services: op-reth-seq: image: "${OP_RETH_IMAGE_TAG}" container_name: op-reth-seq + entrypoint: /entrypoint/reth-seq.sh + env_file: + - .env volumes: - ./data/op-reth-seq:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/genesis-reth.json:/genesis.json + - ./config-op/test.reth.seq.config.toml:/config.toml + - ./entrypoint:/entrypoint ports: - "8123:8545" - "7546:7546" - "8552:8552" - "30303:30303" - "30303:30303/udp" - - "9090:9090" # pprof port - command: - - node - - --datadir=/datadir - - --chain=/genesis.json - - --http - - --http.corsdomain=* - - --http.port=8545 - - --http.addr=0.0.0.0 - - --http.api=web3,debug,eth,txpool,net,miner,admin - - --ws - - --ws.addr=0.0.0.0 - - --ws.port=7546 - - --ws.origins=* - - --ws.api=debug,eth,txpool,net - - --authrpc.addr=0.0.0.0 - - --authrpc.port=8552 - - --authrpc.jwtsecret=/jwt.txt - - --rollup.disable-tx-pool-gossip - - --rollup.sequencer=http://op-seq:8547 healthcheck: - test: [ "CMD", "curl", "-f", "http://localhost:8545" ] + test: ["CMD", "curl", "-f", "http://localhost:8545"] interval: 3s timeout: 3s retries: 10 @@ -243,53 +228,36 @@ services: op-geth-rpc: image: "${OP_GETH_IMAGE_TAG}" container_name: op-geth-rpc + entrypoint: /entrypoint/geth-rpc.sh + env_file: + - .env volumes: - ./data/op-geth-rpc:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/test.geth.rpc.config.toml:/config.toml + - ./entrypoint:/entrypoint ports: - "8124:8545" - "30304:30303" - "30304:30303/udp" - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - - --rollup.enabletxpooladmission op-reth-rpc: image: "${OP_RETH_IMAGE_TAG}" container_name: op-reth-rpc + entrypoint: /entrypoint/reth-rpc.sh + env_file: + - .env volumes: - ./data/op-reth-rpc:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/genesis-reth.json:/genesis.json + - ./config-op/test.reth.rpc.config.toml:/config.toml + - ./entrypoint:/entrypoint + - ./.env:/.env ports: - "8124:8545" - "30304:30303" - "30304:30303/udp" - command: - - node - - --datadir=/datadir - - --chain=/genesis.json - - --config=/config.toml - - --http - - --http.corsdomain=* - - --http.port=8545 - - --http.addr=0.0.0.0 - - --http.api=web3,debug,eth,txpool,net,miner,admin - - --ws - - --ws.addr=0.0.0.0 - - --ws.port=7546 - - --ws.origins=* - - --ws.api=debug,eth,txpool,net - - --authrpc.addr=0.0.0.0 - - --authrpc.port=8552 - - --authrpc.jwtsecret=/jwt.txt - - --rollup.disable-tx-pool-gossip - - --trusted-peers=enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-${SEQ_TYPE}-seq:30303 op-seq: image: "${OP_STACK_IMAGE_TAG}" @@ -524,7 +492,7 @@ services: volumes: - ./data/op-geth-seq2:/datadir - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.seq.config.toml:/config.toml + - ./config-op/test.geth.seq.config.toml:/config.toml ports: - "8223:8545" - "30305:30303" @@ -673,7 +641,7 @@ services: volumes: - ./data/op-geth-seq3:/datadir - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.seq.config.toml:/config.toml + - ./config-op/test.geth.seq.config.toml:/config.toml ports: - "8323:8545" - "30306:30303" diff --git a/test/entrypoint/reth-rpc.sh b/test/entrypoint/reth-rpc.sh index a7511fba391d1..e47ef0262aa51 100755 --- a/test/entrypoint/reth-rpc.sh +++ b/test/entrypoint/reth-rpc.sh @@ -2,9 +2,12 @@ set -e +source /.env + exec op-reth node \ --datadir=/datadir \ --chain=/genesis.json \ + --config=/config.toml \ --http \ --http.corsdomain=* \ --http.port=8545 \ @@ -22,5 +25,5 @@ exec op-reth node \ --authrpc.port=8552 \ --authrpc.jwtsecret=/jwt.txt \ --rollup.disable-tx-pool-gossip \ - --rollup.sequencer-http=http://op-${SEQ_TYPE}-seq:8545 + --rollup.sequencer-http=http://op-${SEQ_TYPE}-seq:8545 \ --trusted-peers=enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-${SEQ_TYPE}-seq:30303 diff --git a/test/entrypoint/reth-seq.sh b/test/entrypoint/reth-seq.sh new file mode 100755 index 0000000000000..d8c44cc9045b6 --- /dev/null +++ b/test/entrypoint/reth-seq.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +set -e + +source /.env + +exec op-reth node \ + --datadir=/datadir \ + --chain=/genesis.json \ + --config=/config.toml \ + --http \ + --http.corsdomain=* \ + --http.port=8545 \ + --http.addr=0.0.0.0 \ + --http.api=web3,debug,eth,txpool,net,miner \ + --ws \ + --ws.addr=0.0.0.0 \ + --ws.port=7546 \ + --ws.origins=* \ + --ws.api=web3,debug,eth,txpool,net \ + --disable-discovery \ + --max-outbound-peers=10 \ + --max-inbound-peers=10 \ + --authrpc.addr=0.0.0.0 \ + --authrpc.port=8552 \ + --authrpc.jwtsecret=/jwt.txt \ + --rollup.disable-tx-pool-gossip \ + --trusted-peers=enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-${SEQ_TYPE}-seq:30303 diff --git a/test/example.env b/test/example.env index 49324ccc6bfff..974dff554267f 100644 --- a/test/example.env +++ b/test/example.env @@ -6,12 +6,17 @@ SKIP_OP_STACK_BUILD=false SKIP_OP_CONTRACTS_BUILD=false SKIP_OP_GETH_BUILD=false SKIP_OP_RETH_BUILD=true +SKIP_BUILD_PRESTATE=false OP_GETH_IMAGE_TAG=op-geth:latest OP_RETH_IMAGE_TAG=op-reth:latest OP_STACK_IMAGE_TAG=op-stack:latest OP_CONTRACTS_IMAGE_TAG=op-contracts:latest +# only support `geth` or `reth` +SEQ_TYPE=geth +RPC_TYPE=geth + DOCKER_NETWORK=dev-op CONFIG_DIR=config-op @@ -22,7 +27,7 @@ RICH_L1_PRIVATE_KEY=0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7c L1_RPC_URL=http://localhost:8545 L2_RPC_URL=http://localhost:8124 L1_RPC_URL_IN_DOCKER=http://l1-geth:8545 -L2_RPC_URL_IN_DOCKER=http://op-geth-seq:8545 +L2_RPC_URL_IN_DOCKER=http://op-$SEQ_TYPE-seq:8545 L1_BEACON_URL_IN_DOCKER=http://l1-beacon-chain:3500 SAFE_ADDRESS=0x0000000000000000000000000000000000000000 @@ -79,7 +84,3 @@ CONDUCTOR_ENABLED=true LAUNCH_RPC_NODE=true OWNER_TYPE=transactor # safe - -# only support `geth` or `reth` -SEQ_TYPE=geth -RPC_TYPE=geth diff --git a/test/scripts/add-peers.sh b/test/scripts/add-peers.sh index 4dc56503f9421..cf02efb4d34f2 100755 --- a/test/scripts/add-peers.sh +++ b/test/scripts/add-peers.sh @@ -13,7 +13,7 @@ echo "🔗 Setting up P2P static connections between op-geth nodes..." # Function to get enode from a geth container get_enode() { local container_name=$1 - local enode=$(docker logs $container_name 2>&1 | head -n 100 | grep "enode" | tail -1 | cut -d '=' -f 2 | tr -d '"') + local enode=$(docker logs $container_name 2>&1 | head -n 100 | grep --color=never "enode" | tail -1 | cut -d '=' -f 2 | tr -d '"' | sed 's/\x1b\[[0-9;]*m//g') echo "$enode" } @@ -36,9 +36,9 @@ sed_inplace() { echo "📡 Getting enode addresses..." # Get enodes -OP_GETH_SEQ_ENODE=$(get_enode "op-geth-seq") -if [ -z "$OP_GETH_SEQ_ENODE" ]; then - echo "❌ Failed to get enode for op-geth-seq" +OP_SEQ_ENODE=$(get_enode "op-${SEQ_TYPE}-seq") +if [ -z "$OP_SEQ_ENODE" ]; then + echo "❌ Failed to get enode for ${SEQ_TYPE}" exit 1 fi @@ -56,7 +56,7 @@ if [ "$CONDUCTOR_ENABLED" = "true" ]; then fi # Replace 127.0.0.1 with container names -OP_GETH_SEQ_ENODE=$(replace_enode_ip "$OP_GETH_SEQ_ENODE" "op-geth-seq") +OP_SEQ_ENODE=$(replace_enode_ip "$OP_SEQ_ENODE" "op-${SEQ_TYPE}-seq") if [ "$CONDUCTOR_ENABLED" = "true" ]; then OP_GETH_SEQ2_ENODE=$(replace_enode_ip "$OP_GETH_SEQ2_ENODE" "op-geth-seq2") @@ -64,7 +64,7 @@ if [ "$CONDUCTOR_ENABLED" = "true" ]; then fi echo "✅ Enode addresses:" -echo " op-geth-seq: $OP_GETH_SEQ_ENODE" +echo " op-${SEQ_TYPE}-seq: $OP_SEQ_ENODE" if [ "$CONDUCTOR_ENABLED" = "true" ]; then echo " op-geth-seq2: $OP_GETH_SEQ2_ENODE" echo " op-geth-seq3: $OP_GETH_SEQ3_ENODE" @@ -81,8 +81,8 @@ add_peer() { # Setup static connections between sequencer nodes echo "🔗 Setting up static connections between sequencer nodes..." -# Add peers to op-geth-seq (connect to other sequencers) -echo "🔗 Setting up peers for op-geth-seq..." +# Add peers to sequencer (connect to other sequencers) +echo "🔗 Setting up peers for op-${SEQ_TYPE}-seq..." if [ "$CONDUCTOR_ENABLED" = "true" ]; then add_peer "op-geth-seq" "$OP_GETH_SEQ2_ENODE" add_peer "op-geth-seq" "$OP_GETH_SEQ3_ENODE" @@ -103,9 +103,9 @@ fi # Setup RPC node to connect to all sequencer nodes if [ "$LAUNCH_RPC_NODE" = "true" ]; then echo "🔗 Setting up RPC node to connect to all sequencer nodes..." - OP_RPC_TRUSTED_NODES="\"$OP_GETH_SEQ_ENODE\"" + OP_RPC_TRUSTED_NODES="\"$OP_SEQ_ENODE\"" if [ "$CONDUCTOR_ENABLED" = "true" ]; then - OP_RPC_TRUSTED_NODES="\"$OP_GETH_SEQ_ENODE\",\"$OP_GETH_SEQ2_ENODE\",\"$OP_GETH_SEQ3_ENODE\"" + OP_RPC_TRUSTED_NODES="\"$OP_SEQ_ENODE\",\"$OP_GETH_SEQ2_ENODE\",\"$OP_GETH_SEQ3_ENODE\"" fi if [ "$RPC_TYPE" = "geth" ]; then cp ./config-op/test.geth.rpc.config.toml ./config-op/gen.test.geth.rpc.config.toml diff --git a/test/scripts/kill-rpc.sh b/test/scripts/kill-rpc.sh index e31d928afe08d..f46a73bf05689 100755 --- a/test/scripts/kill-rpc.sh +++ b/test/scripts/kill-rpc.sh @@ -6,9 +6,9 @@ source .env set -x -docker compose kill $RPC_TYPE +docker compose kill op-$RPC_TYPE-rpc docker compose kill op-rpc -docker rm -f $RPC_TYPE +docker rm -f op-$RPC_TYPE-rpc docker rm -f op-rpc -rm -rf data/$RPC_TYPE +rm -rf data/op-$RPC_TYPE-rpc rm -rf data/op-rpc diff --git a/test/scripts/start-rpc.sh b/test/scripts/start-rpc.sh index f60485826c96c..e77c25d5a1b5b 100755 --- a/test/scripts/start-rpc.sh +++ b/test/scripts/start-rpc.sh @@ -6,10 +6,10 @@ source .env set -x -if [ "$RPC_TYPE" = "op-geth-rpc" ]; then +if [ "$RPC_TYPE" = "geth" ]; then OP_GETH_GENESIS_JSON="$(pwd)/config-op/genesis.json" OP_GETH_RPC_DATADIR="$(pwd)/data/op-geth-rpc" - docker run --rm -v $OP_GETH_RPC_DATADIR:/datadir -v $OP_GETH_GENESIS_JSON:/genesis.json op-geth:latest init --datadir /datadir /genesis.json + docker run --rm -v $OP_GETH_RPC_DATADIR:/datadir -v $OP_GETH_GENESIS_JSON:/genesis.json $OP_GETH_IMAGE_TAG init --datadir /datadir /genesis.json sleep 3 fi diff --git a/test/scripts/stop-rpc.sh b/test/scripts/stop-rpc.sh index 935466fdb026b..33c433526fe33 100755 --- a/test/scripts/stop-rpc.sh +++ b/test/scripts/stop-rpc.sh @@ -6,5 +6,5 @@ source .env set -x -docker compose kill $RPC_TYPE +docker compose kill op-$RPC_TYPE-rpc docker compose kill op-rpc From db1a9622cc429fb71add32826f7b63b0e54698fc Mon Sep 17 00:00:00 2001 From: Dumi Loghin Date: Thu, 30 Oct 2025 09:33:34 +0800 Subject: [PATCH 19/26] fix docker compose by adding env to container (#135) --- test/docker-compose.yml | 58 +++++++++++-------------------------- test/entrypoint/reth-seq.sh | 1 - 2 files changed, 17 insertions(+), 42 deletions(-) diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 95e571d2abef2..86cc6ed728fc1 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -210,8 +210,8 @@ services: - ./data/op-reth-seq:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/genesis-reth.json:/genesis.json - - ./config-op/test.reth.seq.config.toml:/config.toml - ./entrypoint:/entrypoint + - ./.env:/.env ports: - "8123:8545" - "7546:7546" @@ -514,34 +514,19 @@ services: op-reth-seq2: image: "${OP_RETH_IMAGE_TAG}" container_name: op-reth-seq2 + entrypoint: /entrypoint/reth-seq.sh + env_file: + - ./.env volumes: - ./data/op-reth-seq2:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/genesis-reth.json:/genesis.json + - ./entrypoint:/entrypoint + - ./.env:/.env ports: - "8223:8545" - "30305:30303" - "30305:30303/udp" - command: - - node - - --datadir=/datadir - - --chain=/genesis.json - - --http - - --http.corsdomain=* - - --http.port=8545 - - --http.addr=0.0.0.0 - - --http.api=web3,debug,eth,txpool,net,miner,admin - - --ws - - --ws.addr=0.0.0.0 - - --ws.port=7546 - - --ws.origins=* - - --ws.api=debug,eth,txpool,net - - --authrpc.addr=0.0.0.0 - - --authrpc.port=8552 - - --authrpc.jwtsecret=/jwt.txt - - --rollup.disable-tx-pool-gossip - - --rollup.sequencer=http://op-seq:8547 - - --trusted-peers=enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-reth-seq:30303 healthcheck: test: [ "CMD", "curl", "-f", "http://localhost:8545" ] interval: 3s @@ -663,34 +648,25 @@ services: op-reth-seq3: image: "${OP_RETH_IMAGE_TAG}" container_name: op-reth-seq3 + entrypoint: /entrypoint/reth-seq.sh + env_file: + - ./.env volumes: - ./data/op-reth-seq3:/datadir - ./config-op/jwt.txt:/jwt.txt - ./config-op/genesis-reth.json:/genesis.json - command: - - node - - --datadir=/datadir - - --chain=/genesis.json - - --http - - --http.corsdomain=* - - --http.port=8545 - - --http.addr=0.0.0.0 - - --http.api=web3,debug,eth,txpool,net,miner,admin - - --ws - - --ws.addr=0.0.0.0 - - --ws.port=7546 - - --ws.origins=* - - --ws.api=debug,eth,txpool,net - - --authrpc.addr=0.0.0.0 - - --authrpc.port=8552 - - --authrpc.jwtsecret=/jwt.txt - - --rollup.disable-tx-pool-gossip - - --rollup.sequencer=http://op-seq:8547 - - --trusted-peers=enode://ef8135659def07b48b54fe2de7d0368e3eaa0a080ef13dde560169357900954be1a1e890b5973a821f9158e512a2da3ff600368f44e18e725a86931eaae5ef64@op-reth-seq:30303 + - ./entrypoint:/entrypoint + - ./.env:/.env ports: - "8323:8545" - "30306:30303" - "30306:30303/udp" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8545"] + interval: 3s + timeout: 3s + retries: 10 + start_period: 3s op-seq3: image: "${OP_STACK_IMAGE_TAG}" diff --git a/test/entrypoint/reth-seq.sh b/test/entrypoint/reth-seq.sh index d8c44cc9045b6..cff07dc1ad3d2 100755 --- a/test/entrypoint/reth-seq.sh +++ b/test/entrypoint/reth-seq.sh @@ -7,7 +7,6 @@ source /.env exec op-reth node \ --datadir=/datadir \ --chain=/genesis.json \ - --config=/config.toml \ --http \ --http.corsdomain=* \ --http.port=8545 \ From 945912e1cf3896de243bda18a23b156ca74fa22e Mon Sep 17 00:00:00 2001 From: Kyrin Date: Mon, 3 Nov 2025 15:57:26 +0800 Subject: [PATCH 20/26] fix scripts (#136) --- op-geth | 2 +- test/config-op/intent.toml.bak | 1 + test/docker-compose.yml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/op-geth b/op-geth index 717a6ab11f3d5..b36860d848ecc 160000 --- a/op-geth +++ b/op-geth @@ -1 +1 @@ -Subproject commit 717a6ab11f3d5a9724a5fbb1a1c78d3c781fa1a1 +Subproject commit b36860d848ecc95cf188f3850a0712c41d13c7f4 diff --git a/test/config-op/intent.toml.bak b/test/config-op/intent.toml.bak index cf04ac0b40e8b..238bc8aa9ea14 100644 --- a/test/config-op/intent.toml.bak +++ b/test/config-op/intent.toml.bak @@ -20,6 +20,7 @@ l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" l2GenesisBlockGasLimit = "0xbebc200" l2GenesisBlockBaseFeePerGas = "0x3B9ACA00" l2BlockTime = 1 + sequencerWindowSize = 7200 [chains.roles] l1ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" l2ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 86cc6ed728fc1..8d65f1f14998c 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -362,7 +362,7 @@ services: - --log.level=debug # already existed service - --node.rpc=http://op-seq:9545 - - --execution.rpc=http://op-${RPC_TYPE}-seq:8545 + - --execution.rpc=http://op-${SEQ_TYPE}-seq:8545 # Raft Config - --raft.server.id=conductor-1 - --raft.storage.dir=/data/raft From 38e895d6b742ffdbb5223419c76737987d88c72d Mon Sep 17 00:00:00 2001 From: Louis Liu <35095310+louisliu2048@users.noreply.github.com> Date: Tue, 4 Nov 2025 09:57:45 +0800 Subject: [PATCH 21/26] update test readme to make it more easy to run reth (#137) Co-authored-by: louis.liu --- test/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/README.md b/test/README.md index 73a29cfcad074..c0972df425577 100644 --- a/test/README.md +++ b/test/README.md @@ -1,5 +1,22 @@ # Optimism Test Environment Setup Guide +## Environment Configuration + +Configure `example.env` (do not modify `.env` directly) and run `./clean.sh` to sync changes. + +| Case | .env Configuration | +|------|---------------------| +| **Geth as Sequencer** | `SEQ_TYPE=geth`
`SKIP_OP_RETH_BUILD=true`
`DB_ENGINE=pebble` | +| **Reth as Sequencer** | `SEQ_TYPE=reth`
`SKIP_OP_RETH_BUILD=false`
`OP_RETH_LOCAL_DIRECTORY=/absolute/path/to/reth/repository`
`OP_RETH_BRANCH=dev` | +| **Geth as RPC** | `RPC_TYPE=geth`
`LAUNCH_RPC_NODE=true`
`SKIP_OP_RETH_BUILD=true`
`DB_ENGINE=pebble` | +| **Reth as RPC** | `RPC_TYPE=reth`
`LAUNCH_RPC_NODE=true`
`SKIP_OP_RETH_BUILD=false`
`OP_RETH_LOCAL_DIRECTORY=/absolute/path/to/reth/repository`
`OP_RETH_BRANCH=dev` | + +**Notes:** +- Always modify `example.env`, then run `./clean.sh` to sync to `.env` +- For Reth configurations, `OP_RETH_LOCAL_DIRECTORY` must be an absolute path +- Run `./init.sh` to build Docker images after configuration changes +- `DB_ENGINE` can be `pebble` or `leveldb` (only required for Geth) + ## Prerequisites ### System Requirements From bc1f74e5bf7b1e77944b34806e8ea01aec9d0f65 Mon Sep 17 00:00:00 2001 From: EricQ <50510214+xrqin@users.noreply.github.com> Date: Tue, 4 Nov 2025 17:43:48 +0800 Subject: [PATCH 22/26] fix: add .env sync functionality to clean.sh (#139) - Added automatic sync from example.env to .env in clean.sh - This ensures the behavior matches what's documented in README.md - Users can now modify example.env and run clean.sh to update .env --- test/clean.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/clean.sh b/test/clean.sh index 9198aeccbb433..364e246ed852b 100755 --- a/test/clean.sh +++ b/test/clean.sh @@ -6,6 +6,9 @@ echo " 🧹 Cleaning up Optimism test environment..." echo " 📦 Stopping Docker containers..." [ -f .env ] && docker compose down +echo " 🔄 Syncing .env from example.env..." +[ -f example.env ] && cp example.env .env && echo " ✅ .env synced from example.env" + echo " 🗑️ Removing generated files..." rm -rf data rm -rf config-op/genesis.json From 1b4c2db614de16916bb891c29b51f2bdd38787c0 Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 5 Nov 2025 11:34:29 +0800 Subject: [PATCH 23/26] feat: Add mempool rebroadcaster service (#138) * Add mempool rebroadcaster * Add readme --- .gitignore | 1 + test/3-op-init.sh | 13 +++---- test/README.md | 20 ++++++++++ test/docker-compose.yml | 39 ++++++------------- .../mempool-rebroadcaster-scheduler.sh | 24 ++++++++++++ 5 files changed, 62 insertions(+), 35 deletions(-) create mode 100755 test/scripts/mempool-rebroadcaster-scheduler.sh diff --git a/.gitignore b/.gitignore index 67cf30aecd1c2..30735e6c3bc76 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ test/l1-geth/consensus/genesis.ssz test/l1-geth/execution/geth/genesis.json test/l1-geth/execution/geth test/data +test/saved-cannon-data # ignore local asdf config .tool-versions diff --git a/test/3-op-init.sh b/test/3-op-init.sh index 3c05a598fb84e..b032d3b5a5a2f 100755 --- a/test/3-op-init.sh +++ b/test/3-op-init.sh @@ -171,19 +171,16 @@ if [ "$CONDUCTOR_ENABLED" = "true" ]; then OP_GETH_DATADIR2="$(pwd)/data/op-geth-seq2" rm -rf "$OP_GETH_DATADIR2" cp -r $OP_GETH_DATADIR $OP_GETH_DATADIR2 - - OP_GETH_DATADIR3="$(pwd)/data/op-geth-seq3" - rm -rf "$OP_GETH_DATADIR3" - cp -r $OP_GETH_DATADIR $OP_GETH_DATADIR3 elif [ "$SEQ_TYPE" = "reth" ]; then OP_RETH_DATADIR2="$(pwd)/data/op-reth-seq2" rm -rf "$OP_RETH_DATADIR2" cp -r $OP_RETH_DATADIR $OP_RETH_DATADIR2 - - OP_RETH_DATADIR3="$(pwd)/data/op-reth-seq3" - rm -rf "$OP_RETH_DATADIR3" - cp -r $OP_RETH_DATADIR $OP_RETH_DATADIR3 fi + + # op-seq3 default EL is always op-geth to ensure multiple seqs' geth and reth compatibilities + OP_GETH_DATADIR3="$(pwd)/data/op-geth-seq3" + rm -rf "$OP_GETH_DATADIR3" + cp -r $OP_GETH_DATADIR $OP_GETH_DATADIR3 fi if [ "$SEQ_TYPE" = "reth" ]; then diff --git a/test/README.md b/test/README.md index c0972df425577..5c6e429de7f21 100644 --- a/test/README.md +++ b/test/README.md @@ -97,6 +97,7 @@ test/ │ ├── deposit-from-l1.sh # L1 to L2 deposit script │ ├── deposit-from-banker.sh # transfer ETH from banker script │ └── show-dev-accounts.sh # Display dev accounts info +| └── mempool-rebroadcaster-secheduler.sh # Compares and rebroadcasts missing txs between reth and geth ├── config-op/ # Configuration directory ├── data/ # Data storage directory ├── contracts/ # Smart contracts @@ -334,6 +335,25 @@ The `scripts/show-dev-accounts.sh` script displays all development accounts with #### Important Notes - **Balance Status**: Most dev accounts are pre-funded with 10,000 ETH, but some accounts may have zero initial balance +### Mempool rebroadcaster scheduler + +The `scripts/mempool-rebroadcaster-scheduler.sh` script facilitates running the mempool rebroadcaster tool periodically in a default 1 minute interval. + +### Usage + +- The mempool rebroadcaster tool is crucial to ensure reth and geth transaction pool consistency. +- In production, the mempool-rebroadcaster should be running inside a scheduler or cron job. +- For our local devnet, we can deploy the tool inside the scheduler by running the script. + +### Reth vs geth txpool + +- There are slight differences in the txpool behaviour between opgeth and reth which thus the need for the tool. + +||Geth|Reth| +|---------|------|------| +|Pending| Next nonce transactions with no nonce gap | Next nonce transactions with a fee higher than the base fee| +|Queued| Transactions with a nonce gap | Transactions below the base fee, even if they are next nonce, and transactions with a nonce gap| + ## Troubleshooting ### Common Issues diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 8d65f1f14998c..9874145a08423 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -645,29 +645,7 @@ services: retries: 10 start_period: 3s - op-reth-seq3: - image: "${OP_RETH_IMAGE_TAG}" - container_name: op-reth-seq3 - entrypoint: /entrypoint/reth-seq.sh - env_file: - - ./.env - volumes: - - ./data/op-reth-seq3:/datadir - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/genesis-reth.json:/genesis.json - - ./entrypoint:/entrypoint - - ./.env:/.env - ports: - - "8323:8545" - - "30306:30303" - - "30306:30303/udp" - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - + # Keep op-seq3 to run op-geth as default EL op-seq3: image: "${OP_STACK_IMAGE_TAG}" container_name: op-seq3 @@ -684,7 +662,7 @@ services: command: - /app/op-node/bin/op-node - --log.level=info - - --l2=http://op-${SEQ_TYPE}-seq3:8552 + - --l2=http://op-geth-seq3:8552 - --l2.jwt-secret=/jwt.txt - --sequencer.enabled - --sequencer.stopped @@ -708,9 +686,9 @@ services: - --safedb.path=/data/safedb - --conductor.enabled=${CONDUCTOR_ENABLED:-false} - --conductor.rpc=http://op-conductor3:8547 - - --l2.enginekind=${SEQ_TYPE} + - --l2.enginekind=geth depends_on: - - op-${SEQ_TYPE}-seq3 + - op-geth-seq3 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9545"] interval: 3s @@ -732,7 +710,7 @@ services: - --log.level=debug # already existed service - --node.rpc=http://op-seq3:9545 - - --execution.rpc=http://op-${SEQ_TYPE}-seq3:8545 + - --execution.rpc=http://op-geth-seq3:8545 # Raft Config - --raft.server.id=conductor-3 - --raft.storage.dir=/data/raft @@ -752,3 +730,10 @@ services: depends_on: op-seq3: condition: service_healthy + + mempool-rebroadcaster: + image: xlayerdev/mempool-rebroadcaster + container_name: mempool-rebroadcaster + command: + - --geth-mempool-endpoint=http://op-reth-seq:8545 + - --reth-mempool-endpoint=http://op-geth-seq3:8545 diff --git a/test/scripts/mempool-rebroadcaster-scheduler.sh b/test/scripts/mempool-rebroadcaster-scheduler.sh new file mode 100755 index 0000000000000..76169aaf24858 --- /dev/null +++ b/test/scripts/mempool-rebroadcaster-scheduler.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e +set -x + +# Scheduler to run mempool rebroadcaster at regular intervals when reth is enabled. +# Default interval is set at 1 minute (60 seconds) +INTERVAL=60 + +SEQ_TYPE="${SEQ_TYPE:-reth}" + +# Start mempool rebroadcaster scheduler for reth mode +if [ "$SEQ_TYPE" = "reth" ]; then + echo "Starting mempool rebroadcaster scheduler with ${INTERVAL}s interval." + + while true; do + # Run the mempool rebroadcaster + echo "$(date): Running mempool rebroadcaster..." + docker compose run --rm mempool-rebroadcaster + echo "$(date): Mempool rebroadcaster completed." + sleep "$INTERVAL" + done +else + echo "Mempool rebroadcaster scheduler is not in reth mode, exiting." +fi From a30dc4560da92174aa4a9c9d1a13b0a0d94db025 Mon Sep 17 00:00:00 2001 From: Louis Liu <35095310+louisliu2048@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:54:37 +0800 Subject: [PATCH 24/26] update geth version (#140) Co-authored-by: louis.liu --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 075c22deb9688..49ac7018c2d05 100644 --- a/go.mod +++ b/go.mod @@ -321,7 +321,7 @@ require ( lukechampine.com/blake3 v1.3.0 // indirect ) -replace github.com/ethereum/go-ethereum => github.com/okx/op-geth v0.0.6 +replace github.com/ethereum/go-ethereum => github.com/okx/op-geth v0.0.7 //replace github.com/ethereum/go-ethereum => ./op-geth diff --git a/go.sum b/go.sum index 4fa4161fd8483..8363282244b0b 100644 --- a/go.sum +++ b/go.sum @@ -802,8 +802,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= -github.com/okx/op-geth v0.0.6 h1:6/jop2lGu2Ep9i466yprMJa1NeSCHIgqAArJSV35jS8= -github.com/okx/op-geth v0.0.6/go.mod h1:MD4m7TCs3bDlgtuio/99+iVscH4eEpkhvJuOojm7D/o= +github.com/okx/op-geth v0.0.7 h1:EOxCr2qmObfTQj7nmI1aO9QoWztsq1Mip/1YsuzLcGk= +github.com/okx/op-geth v0.0.7/go.mod h1:MD4m7TCs3bDlgtuio/99+iVscH4eEpkhvJuOojm7D/o= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= From 2d4253649cf4a395d23a79b5ba942ae0a447dd8f Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 5 Nov 2025 19:00:20 +0800 Subject: [PATCH 25/26] update (#142) --- test-pp-op/0-all-local.sh | 13 - test-pp-op/1-start-erigon.sh | 60 -- test-pp-op/2-deploy-op-contracts.sh | 455 --------- test-pp-op/3-stop-erigon.sh | 27 - test-pp-op/4-migrate-op.sh | 209 ---- test-pp-op/5-start-op.sh | 168 ---- test-pp-op/6-build-op-program.sh | 174 ---- test-pp-op/7-setup-fraud-proof.sh | 505 ---------- test-pp-op/8-prepare-tests.sh | 57 -- test-pp-op/Makefile | 204 ---- test-pp-op/README.md | 393 -------- test-pp-op/build_images.sh | 297 ------ .../config-op/intent.fakemainnet.toml.bak | 35 - test-pp-op/config-op/intent.local.toml.bak | 36 - test-pp-op/config-op/intent.mainnet.toml.bak | 36 - test-pp-op/config-op/intent.testnet.toml.bak | 35 - test-pp-op/config-op/intent.toml.bak | 35 - test-pp-op/config-op/jwt.txt | 1 - test-pp-op/config-op/state.json.bak | 13 - test-pp-op/config-op/test.rpc.config.toml | 38 - test-pp-op/config-op/test.seq.config.toml | 46 - test-pp-op/config/aggkit.toml | 129 --- test-pp-op/config/agglayer-config.toml | 91 -- test-pp-op/config/agglayer-prover-config.toml | 25 - test-pp-op/config/cdk.config.toml | 296 ------ .../config/dynamic-mynetwork-allocs.json | 100 -- .../config/dynamic-mynetwork-chainspec.json | 25 - test-pp-op/config/dynamic-mynetwork-conf.json | 6 - test-pp-op/config/first-batch-config.json | 9 - .../config/local/local.erigon.rpc.config.yaml | 114 --- .../config/local/local.erigon.seq.config.yaml | 109 --- test-pp-op/config/test.bridge.config.toml | 132 --- test-pp-op/config/test.erigon.rpc.config.yaml | 86 -- test-pp-op/config/test.erigon.seq.config.yaml | 114 --- test-pp-op/config/test.genesis.config.json | 109 --- test-pp-op/config/test.node.config.toml | 6 - test-pp-op/config/test.poolmanager.toml | 37 - .../config/xlayerconfig-mainnet-rpc.yaml | 29 - test-pp-op/config/xlayerconfig-mainnet.yaml | 87 -- test-pp-op/contracts/OKBToken.sol | 97 -- test-pp-op/contracts/foundry.toml | 9 - test-pp-op/docker-compose-local.yml | 925 ------------------ test-pp-op/docker-compose.yml | 663 ------------- test-pp-op/dockerfile/Dockerfile-cdk-erigon | 87 -- test-pp-op/dockerfile/Dockerfile.migrate | 27 - test-pp-op/dockerfile/Dockerfile.repro | 60 -- .../dockerfile/Dockerfile.repro-builder | 19 - test-pp-op/init-erigon.sh | 213 ---- test-pp-op/l1-geth/consensus/config.yml | 34 - test-pp-op/l1-geth/execution/genesis-raw.json | 119 --- .../l1-geth/execution/geth_password.txt | 0 test-pp-op/l1-geth/execution/jwtsecret | 1 - ...--123463a4b065722e99115d6c222f267d9cabb524 | 1 - test-pp-op/l1-geth/execution/sk.json | 1 - test-pp-op/local.env | 132 --- test-pp-op/m1-deploy-and-upload.sh | 80 -- test-pp-op/m2-migrate.sh | 630 ------------ test-pp-op/m3-verify.sh | 43 - test-pp-op/notes.txt | 28 - ...pport-load-genesis-at-a-given-number.patch | 187 ---- .../optimism-0001-decompress-genesis.patch | 65 -- ...1-support-regenesis-op-geth-prestate.patch | 82 -- ...upport-sync-L2-block-at-given-number.patch | 70 -- ...002-skip-reorg-check-after-regenesis.patch | 30 - ...skip-syncing-blocks-before-regenesis.patch | 31 - test-pp-op/scripts/active-sequencer.sh | 91 -- test-pp-op/scripts/add-game-type.sh | 192 ---- test-pp-op/scripts/deposit-from-banker.sh | 17 - test-pp-op/scripts/deposit-from-l1.sh | 48 - test-pp-op/scripts/docker-install-start.sh | 31 - test-pp-op/scripts/gray-upgrade-simulation.sh | 309 ------ test-pp-op/scripts/replace-genesis.sh | 29 - test-pp-op/scripts/set-init-bond.sh | 152 --- test-pp-op/scripts/show-dev-accounts.sh | 17 - test-pp-op/scripts/stop-leader-sequencer.sh | 47 - test-pp-op/scripts/transfer-leader.sh | 59 -- test-pp-op/tools.sh | 32 - test-pp-op/utils.sh | 15 - 78 files changed, 9014 deletions(-) delete mode 100755 test-pp-op/0-all-local.sh delete mode 100755 test-pp-op/1-start-erigon.sh delete mode 100755 test-pp-op/2-deploy-op-contracts.sh delete mode 100755 test-pp-op/3-stop-erigon.sh delete mode 100755 test-pp-op/4-migrate-op.sh delete mode 100755 test-pp-op/5-start-op.sh delete mode 100755 test-pp-op/6-build-op-program.sh delete mode 100755 test-pp-op/7-setup-fraud-proof.sh delete mode 100755 test-pp-op/8-prepare-tests.sh delete mode 100644 test-pp-op/Makefile delete mode 100644 test-pp-op/README.md delete mode 100755 test-pp-op/build_images.sh delete mode 100644 test-pp-op/config-op/intent.fakemainnet.toml.bak delete mode 100644 test-pp-op/config-op/intent.local.toml.bak delete mode 100644 test-pp-op/config-op/intent.mainnet.toml.bak delete mode 100644 test-pp-op/config-op/intent.testnet.toml.bak delete mode 100644 test-pp-op/config-op/intent.toml.bak delete mode 100644 test-pp-op/config-op/jwt.txt delete mode 100755 test-pp-op/config-op/state.json.bak delete mode 100644 test-pp-op/config-op/test.rpc.config.toml delete mode 100644 test-pp-op/config-op/test.seq.config.toml delete mode 100644 test-pp-op/config/aggkit.toml delete mode 100644 test-pp-op/config/agglayer-config.toml delete mode 100644 test-pp-op/config/agglayer-prover-config.toml delete mode 100644 test-pp-op/config/cdk.config.toml delete mode 100644 test-pp-op/config/dynamic-mynetwork-allocs.json delete mode 100644 test-pp-op/config/dynamic-mynetwork-chainspec.json delete mode 100644 test-pp-op/config/dynamic-mynetwork-conf.json delete mode 100644 test-pp-op/config/first-batch-config.json delete mode 100644 test-pp-op/config/local/local.erigon.rpc.config.yaml delete mode 100644 test-pp-op/config/local/local.erigon.seq.config.yaml delete mode 100644 test-pp-op/config/test.bridge.config.toml delete mode 100644 test-pp-op/config/test.erigon.rpc.config.yaml delete mode 100644 test-pp-op/config/test.erigon.seq.config.yaml delete mode 100644 test-pp-op/config/test.genesis.config.json delete mode 100644 test-pp-op/config/test.node.config.toml delete mode 100644 test-pp-op/config/test.poolmanager.toml delete mode 100644 test-pp-op/config/xlayerconfig-mainnet-rpc.yaml delete mode 100644 test-pp-op/config/xlayerconfig-mainnet.yaml delete mode 100644 test-pp-op/contracts/OKBToken.sol delete mode 100644 test-pp-op/contracts/foundry.toml delete mode 100644 test-pp-op/docker-compose-local.yml delete mode 100644 test-pp-op/docker-compose.yml delete mode 100644 test-pp-op/dockerfile/Dockerfile-cdk-erigon delete mode 100644 test-pp-op/dockerfile/Dockerfile.migrate delete mode 100644 test-pp-op/dockerfile/Dockerfile.repro delete mode 100644 test-pp-op/dockerfile/Dockerfile.repro-builder delete mode 100755 test-pp-op/init-erigon.sh delete mode 100644 test-pp-op/l1-geth/consensus/config.yml delete mode 100644 test-pp-op/l1-geth/execution/genesis-raw.json delete mode 100644 test-pp-op/l1-geth/execution/geth_password.txt delete mode 100755 test-pp-op/l1-geth/execution/jwtsecret delete mode 100644 test-pp-op/l1-geth/execution/keystore/UTC--2022-08-19T17-38-31.257380510Z--123463a4b065722e99115d6c222f267d9cabb524 delete mode 100644 test-pp-op/l1-geth/execution/sk.json delete mode 100644 test-pp-op/local.env delete mode 100755 test-pp-op/m1-deploy-and-upload.sh delete mode 100755 test-pp-op/m2-migrate.sh delete mode 100755 test-pp-op/m3-verify.sh delete mode 100644 test-pp-op/notes.txt delete mode 100644 test-pp-op/patch/op-geth-0001-support-load-genesis-at-a-given-number.patch delete mode 100644 test-pp-op/patch/optimism-0001-decompress-genesis.patch delete mode 100644 test-pp-op/patch/optimism-0001-support-regenesis-op-geth-prestate.patch delete mode 100644 test-pp-op/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch delete mode 100644 test-pp-op/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch delete mode 100644 test-pp-op/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch delete mode 100755 test-pp-op/scripts/active-sequencer.sh delete mode 100755 test-pp-op/scripts/add-game-type.sh delete mode 100755 test-pp-op/scripts/deposit-from-banker.sh delete mode 100755 test-pp-op/scripts/deposit-from-l1.sh delete mode 100755 test-pp-op/scripts/docker-install-start.sh delete mode 100755 test-pp-op/scripts/gray-upgrade-simulation.sh delete mode 100755 test-pp-op/scripts/replace-genesis.sh delete mode 100755 test-pp-op/scripts/set-init-bond.sh delete mode 100755 test-pp-op/scripts/show-dev-accounts.sh delete mode 100755 test-pp-op/scripts/stop-leader-sequencer.sh delete mode 100755 test-pp-op/scripts/transfer-leader.sh delete mode 100644 test-pp-op/tools.sh delete mode 100644 test-pp-op/utils.sh diff --git a/test-pp-op/0-all-local.sh b/test-pp-op/0-all-local.sh deleted file mode 100755 index efa8aad44a6ea..0000000000000 --- a/test-pp-op/0-all-local.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -set -e - -# ./build_images.sh --all # build all images. add --force if want to force rebuild -make clean -cp local.env .env -./1-start-erigon.sh -./2-deploy-op-contracts.sh -./3-stop-erigon.sh -./4-migrate-op.sh -./5-start-op.sh -./6-build-op-program.sh -./7-setup-fraud-proof.sh diff --git a/test-pp-op/1-start-erigon.sh b/test-pp-op/1-start-erigon.sh deleted file mode 100755 index 00e95fd74e9b1..0000000000000 --- a/test-pp-op/1-start-erigon.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -set -e -set -x - -if ! [ -f .env ]; then - echo "need to provide .env file" -fi - -source .env -source tools.sh - -if [ "$ENV" = "local" ]; then - COMPOSE_FILE="docker-compose-local.yml" -else - COMPOSE_FILE="docker-compose.yml" -fi - -DOCKER_COMPOSE=$(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose") -DOCKER_COMPOSE_CMD="${DOCKER_COMPOSE} -f ${COMPOSE_FILE}" -echo ${DOCKER_COMPOSE_CMD} - -# 1. setup l1 -# 2. run & init erigon pp -start_local_xlayer_erigon() { - export ENV=local - make run_erigon - sleep 3 - # Calculate addresses for all actors - OP_BATCHER_ADDR=$(cast wallet a $OP_BATCHER_PRIVATE_KEY) - OP_PROPOSER_ADDR=$(cast wallet a $OP_PROPOSER_PRIVATE_KEY) - OP_CHALLENGER_ADDR=$(cast wallet a $OP_CHALLENGER_PRIVATE_KEY) - - # Wait for L1 node to finish syncing - while [[ "$(cast rpc eth_syncing --rpc-url $L1_RPC_URL)" != "false" ]]; do - echo "Waiting for node to finish syncing..." - sleep 1 - done - - # Fund all actor addresses - for addr in $OP_BATCHER_ADDR $OP_PROPOSER_ADDR $OP_CHALLENGER_ADDR; do - cast send --private-key $RICH_PRIVATE_KEY --value 100ether $addr --legacy --rpc-url $L1_RPC_URL - done -} - -setup_xlayer_erigon() { - if [ "$ENV" = "local" ]; then - echo "Starting local environment setup..." - start_local_xlayer_erigon - elif [ "$ENV" = "testnet" ]; then - echo "Starting ${ENV} environment setup..." - echo "not implemented" - exit 1 - else - echo "Starting ${ENV} environment setup..." - echo "not implemented" - exit 1 - fi -} - -setup_xlayer_erigon diff --git a/test-pp-op/2-deploy-op-contracts.sh b/test-pp-op/2-deploy-op-contracts.sh deleted file mode 100755 index 1ad0435cb2c9e..0000000000000 --- a/test-pp-op/2-deploy-op-contracts.sh +++ /dev/null @@ -1,455 +0,0 @@ -#!/bin/bash -set -e -set -x - -source .env -source tools.sh -source utils.sh - -ROOT_DIR=$(git rev-parse --show-toplevel) - -# Set global OP_CONTRACTS_IMAGE_TAG based on environment -if [ "$ENV" = "local" ]; then - # Use local image tag for local environment - DOCKER_NETWORK_ARG="$DOCKER_NETWORK" -else - # Use cert image tag for non-local environments - DOCKER_NETWORK_ARG="host" -fi - -if [ -z "$CHAIN_ID" ]; then - echo "❌ ERROR: CHAIN_ID is not set. Set it explicitly or derive it from intent.toml before proceeding." - exit 1 -fi -if ! [[ "$CHAIN_ID" =~ ^[0-9]+$ ]]; then - echo "❌ ERROR: CHAIN_ID must be a numeric value, got: '$CHAIN_ID'" - exit 1 -fi - -cd $PWD_DIR - -deploy_safe() { - echo "=== Deploying Gnosis Safe ===" - - # Use deployer as single owner with threshold 1 - echo "Using deployer as single owner with threshold 1" - - # Execute Safe deployment - SAFE_DEPLOY_OUTPUT=$(docker run --rm \ - --network "$DOCKER_NETWORK" \ - -v "$(pwd)/$CONFIG_DIR:/deployments" \ - -e DEPLOYER_PRIVATE_KEY="$DEPLOYER_PRIVATE_KEY" \ - -w /app/packages/contracts-bedrock \ - "${OP_CONTRACTS_IMAGE_TAG}" \ - forge script --json --broadcast \ - --rpc-url $L1_RPC_URL_IN_DOCKER \ - --private-key $DEPLOYER_PRIVATE_KEY \ - scripts/deploy/DeploySimpleSafe.s.sol:DeploySimpleSafe) - - # Extract Safe address - SAFE_ADDRESS=$(echo "$SAFE_DEPLOY_OUTPUT" | jq -r '.logs[] | select(contains("New Safe L1ProxyAdminSafe deployed at:")) | split(": ")[1]' 2>/dev/null | head -1) - - if [ -z "$SAFE_ADDRESS" ] || [ "$SAFE_ADDRESS" = "null" ]; then - echo "❌ Failed to deploy Safe" - exit 1 - fi - - echo "✅ Safe deployed at: $SAFE_ADDRESS" - echo " Owner: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" - echo " Threshold: 1" - - # Update .env file - sed_inplace "s/SAFE_ADDRESS=.*/SAFE_ADDRESS=$SAFE_ADDRESS/" .env - source .env - echo " ✅ Updated SAFE_ADDRESS in .env: $SAFE_ADDRESS" -} - -deploy_transactor() { - # Deploy Transactor contract first - echo "🔧 Deploying Transactor contract..." - - # Debug: Show environment variables - echo "ENV: $ENV" - echo "CHAIN_ID: $CHAIN_ID" - echo "DOCKER_NETWORK: $DOCKER_NETWORK" - echo "L1_RPC_URL_IN_DOCKER: $L1_RPC_URL_IN_DOCKER" - echo "DEPLOYER_PRIVATE_KEY: ${DEPLOYER_PRIVATE_KEY:0:10}..." - echo "DEPLOYER_ADDRESS: $DEPLOYER_ADDRESS" - echo "OP_CONTRACTS_IMAGE_TAG: $OP_CONTRACTS_IMAGE_TAG" - - # Build docker run command with conditional network flag - DOCKER_ARGS=() - DOCKER_ARGS+=("--rm") - DOCKER_ARGS+=("-v" "$(pwd)/$CONFIG_DIR:/deployments") - DOCKER_ARGS+=("-w" "/app/packages/contracts-bedrock") - - if [ "$ENV" = "local" ]; then - DOCKER_ARGS+=("--network" "$DOCKER_NETWORK") - echo "✅ Using Docker network: $DOCKER_NETWORK" - else - DOCKER_ARGS+=("--network" "host") - echo "✅ Skipping Docker network (ENV=$ENV)" - fi - - DOCKER_ARGS+=("$OP_CONTRACTS_IMAGE_TAG") - - # Create the forge create command - FORGE_CMD="forge create --json --broadcast --legacy \ - --rpc-url $L1_RPC_URL_IN_DOCKER \ - --private-key $DEPLOYER_PRIVATE_KEY \ - src/periphery/Transactor.sol:Transactor.0.8.30 \ - --constructor-args $DEPLOYER_ADDRESS" - - echo "🔧 Executing Docker command..." - echo "Command: docker run ${DOCKER_ARGS[*]} $FORGE_CMD" - - TRANSACTOR_DEPLOY_OUTPUT=$(docker run "${DOCKER_ARGS[@]}" $FORGE_CMD) - - echo "Raw deployment output:" - echo "$TRANSACTOR_DEPLOY_OUTPUT" - echo "--- End of raw output ---" - - # Extract contract address from deployment output - TRANSACTOR_ADDRESS=$(echo "$TRANSACTOR_DEPLOY_OUTPUT" | jq -r '.deployedTo // empty' 2>/dev/null || echo "") - if [ -z "$TRANSACTOR_ADDRESS" ] || [ "$TRANSACTOR_ADDRESS" = "null" ]; then - echo "❌ Failed to extract Transactor contract address from deployment output" - echo "Deployment output: $TRANSACTOR_DEPLOY_OUTPUT" - echo "Trying to extract address manually..." - - # Try alternative extraction methods for forge output - TRANSACTOR_ADDRESS=$(echo "$TRANSACTOR_DEPLOY_OUTPUT" | jq -r '.deployedTo' 2>/dev/null || echo "") - if [ -z "$TRANSACTOR_ADDRESS" ]; then - TRANSACTOR_ADDRESS=$(echo "$TRANSACTOR_DEPLOY_OUTPUT" | grep -o '"deployedTo":"[^"]*"' | cut -d'"' -f4 || echo "") - fi - if [ -z "$TRANSACTOR_ADDRESS" ]; then - TRANSACTOR_ADDRESS=$(echo "$TRANSACTOR_DEPLOY_OUTPUT" | grep -o '0x[a-fA-F0-9]\{40\}' | head -1 || echo "") - fi - - if [ -z "$TRANSACTOR_ADDRESS" ]; then - echo "❌ Still failed to extract contract address" - exit 1 - else - echo "✅ Extracted address manually: $TRANSACTOR_ADDRESS" - fi - fi - - echo "✅ Transactor contract deployed at: $TRANSACTOR_ADDRESS" - - # Update .env file with Transactor address - sed_inplace "s/TRANSACTOR=.*/TRANSACTOR=$TRANSACTOR_ADDRESS/" .env - source .env - echo "✅ Updated TRANSACTOR address in .env: $TRANSACTOR_ADDRESS" -} - -# Bootstrapping superchain with op-deployer -# Output: after deploy, it will output `superchain.json` under config-op -# e.g. { -# "protocolVersionsImplAddress": "0x37e15e4d6dffa9e5e320ee1ec036922e563cb76c", -# "protocolVersionsProxyAddress": "0xfb5a7622e23e0f807b97a8ed608d50d56d202688", -# "superchainConfigImplAddress": "0xce28685eb204186b557133766eca00334eb441e4", -# "superchainConfigProxyAddress": "0x8c15b9d397b5bf29e114aebff0663fdd34976756", -# "proxyAdminAddress": "0x210879bec4c74c7e4e6df5e919f9525d75e15183" -# } -deploy_op_stack_bootstrap_superchain() { - source .env - echo "🔧 Bootstrapping superchain with op-deployer..." - - # Build docker run command with conditional network flag - DOCKER_ARGS=() - DOCKER_ARGS+=("-v" "$(pwd)/$CONFIG_DIR:/deployments") - DOCKER_ARGS+=("-w" "/app") - DOCKER_ARGS+=("-e" "CURL_CA_BUNDLE=") - DOCKER_ARGS+=("-e" "GIT_SSL_NO_VERIFY=true") - DOCKER_ARGS+=("-e" "NODE_TLS_REJECT_UNAUTHORIZED=0") - DOCKER_ARGS+=("-e" "GODEBUG=x509ignoreCN=1,x509ignoreUnknownCA=1,x509ignoreSystemRoots=1") - DOCKER_ARGS+=("--network" "$DOCKER_NETWORK_ARG") - - DOCKER_ARGS+=("$OP_CONTRACTS_IMAGE_TAG") - - BASH_CMD="set -e && /app/op-deployer/bin/op-deployer bootstrap superchain --l1-rpc-url $L1_RPC_URL_IN_DOCKER --private-key $DEPLOYER_PRIVATE_KEY --artifacts-locator file:///app/packages/contracts-bedrock/forge-artifacts --superchain-proxy-admin-owner $L1_PROXY_ADMIN_OWNER --protocol-versions-owner $ADMIN_OWNER_ADDRESS --guardian $ADMIN_OWNER_ADDRESS --outfile /deployments/superchain.json" - - docker run "${DOCKER_ARGS[@]}" bash -c "$BASH_CMD" -} - -deploy_op_stack_bootstrap_implementations() { - source .env - echo "🔧 Bootstrapping implementations with op-deployer..." - SUPERCHAIN_JSON="$CONFIG_DIR/superchain.json" - PROTOCOL_VERSIONS_PROXY=$(jq -r '.protocolVersionsProxyAddress' "$SUPERCHAIN_JSON") - SUPERCHAIN_CONFIG_PROXY=$(jq -r '.superchainConfigProxyAddress' "$SUPERCHAIN_JSON") - PROXY_ADMIN=$(jq -r '.proxyAdminAddress' "$SUPERCHAIN_JSON") - # Build docker run command with conditional network flag - DOCKER_ARGS=() - DOCKER_ARGS+=("-v" "$(pwd)/$CONFIG_DIR:/deployments") - DOCKER_ARGS+=("-w" "/app") - DOCKER_ARGS+=("-e" "CURL_CA_BUNDLE=") - DOCKER_ARGS+=("-e" "GIT_SSL_NO_VERIFY=true") - DOCKER_ARGS+=("-e" "NODE_TLS_REJECT_UNAUTHORIZED=0") - DOCKER_ARGS+=("--network" "$DOCKER_NETWORK_ARG") - - DOCKER_ARGS+=("$OP_CONTRACTS_IMAGE_TAG") - - # Build the base command - BASH_CMD="set -e && export CURL_CA_BUNDLE= && export GIT_SSL_NO_VERIFY=true && /app/op-deployer/bin/op-deployer bootstrap implementations --artifacts-locator file:///app/packages/contracts-bedrock/forge-artifacts --l1-rpc-url $L1_RPC_URL_IN_DOCKER --outfile /deployments/implementations.json --mips-version \"7\" --private-key $DEPLOYER_PRIVATE_KEY --protocol-versions-proxy $PROTOCOL_VERSIONS_PROXY --superchain-config-proxy $SUPERCHAIN_CONFIG_PROXY --superchain-proxy-admin $PROXY_ADMIN --upgrade-controller $ADMIN_OWNER_ADDRESS --challenger $CHALLENGER_ADDRESS --challenge-period-seconds $CHALLENGE_PERIOD_SECONDS --withdrawal-delay-seconds $WITHDRAWAL_DELAY_SECONDS --proof-maturity-delay-seconds $PROOF_MATURITY_DELAY_SECONDS --dispute-game-finality-delay-seconds $DISPUTE_GAME_FINALITY_DELAY_SECONDS" - - # Add dev-feature-bitmap only when CGT_ENABLED=true - if [ "$CGT_ENABLED" = "true" ]; then - BASH_CMD="$BASH_CMD --dev-feature-bitmap 0x0000000000000000000000000000000000000000000000000000000000001000" - fi - - docker run "${DOCKER_ARGS[@]}" bash -c "$BASH_CMD" - - # Update intent.toml - sed_inplace "s/l1ProxyAdminOwner = .*/l1ProxyAdminOwner = \"$L1_PROXY_ADMIN_OWNER\"/" "$CONFIG_DIR/intent.toml" - echo " ✅ Updated intent.toml with $OWNER_TYPE owner: $L1_PROXY_ADMIN_OWNER" - - # Read opcmAddress from implementations.json and write it into intent.toml - OPCM_ADDRESS=$(jq -r '.opcmAddress' ./config-op/implementations.json) - if [ -z "$OPCM_ADDRESS" ] || [ "$OPCM_ADDRESS" = "null" ]; then - echo "❌ Failed to read opcmAddress from implementations.json" - exit 1 - fi - - # Replace the opcmAddress field in intent.toml with the new value - sed_inplace "s/^opcmAddress = \".*\"/opcmAddress = \"$OPCM_ADDRESS\"/" ./config-op/intent.toml - echo "✅ Updated opcmAddress ($OPCM_ADDRESS) in intent.toml" -} - -deploy_op_stack_contracts() { - # Deploy contracts, TODO: should we need to modify source code to deploy contracts? - # Build docker run command with conditional network flag - DOCKER_ARGS=() - DOCKER_ARGS+=("-v" "$(pwd)/$CONFIG_DIR:/deployments") - DOCKER_ARGS+=("-w" "/app") - DOCKER_ARGS+=("-e" "CURL_CA_BUNDLE=") - DOCKER_ARGS+=("-e" "GIT_SSL_NO_VERIFY=true") - DOCKER_ARGS+=("-e" "NODE_TLS_REJECT_UNAUTHORIZED=0") - DOCKER_ARGS+=("--network" "$DOCKER_NETWORK_ARG") - - DOCKER_ARGS+=("$OP_CONTRACTS_IMAGE_TAG") - - BASH_CMD="set -e && export CURL_CA_BUNDLE= && export GIT_SSL_NO_VERIFY=true && echo '🔧 Starting contract deployment with op-deployer...' && echo '' && echo 'Deploy using op-deployer, wait for completion before proceeding' && /app/op-deployer/bin/op-deployer apply --workdir /deployments --private-key $DEPLOYER_PRIVATE_KEY --l1-rpc-url $L1_RPC_URL_IN_DOCKER && echo '' && echo '📄 Generating L2 genesis and rollup config...' && echo '' && echo 'Generate L2 genesis using op-deployer' && /app/op-deployer/bin/op-deployer inspect genesis --workdir /deployments $CHAIN_ID > /deployments/genesis.json && echo '' && echo 'Generate L2 rollup using op-node' && /app/op-deployer/bin/op-deployer inspect rollup --workdir /deployments $CHAIN_ID > /deployments/rollup.json && echo '' && echo '✅ Contract deployment completed successfully'" - - docker run "${DOCKER_ARGS[@]}" bash -c "$BASH_CMD" - - echo "genesis.json and rollup.json are generated in deployments folder" - echo "🎉 OP Stack deployment preparation completed!" -} - -deploy_custom_gas_token() { - echo "🔧 Setting up Custom Gas Token (CGT) configuration..." - echo "" - - # Extract parameters from intent.toml BEFORE changing directory - GAS_LIMIT=$(grep -E "^[[:space:]]*gasLimit[[:space:]]*=" "$CONFIG_DIR/intent.toml" | sed -E 's/^[[:space:]]*gasLimit[[:space:]]*=[[:space:]]*([0-9]+).*/\1/') - EIP1559_DENOMINATOR=$(grep -E "^[[:space:]]*eip1559Denominator[[:space:]]*=" "$CONFIG_DIR/intent.toml" | sed -E 's/^[[:space:]]*eip1559Denominator[[:space:]]*=[[:space:]]*([0-9]+).*/\1/') - EIP1559_ELASTICITY=$(grep -E "^[[:space:]]*eip1559Elasticity[[:space:]]*=" "$CONFIG_DIR/intent.toml" | sed -E 's/^[[:space:]]*eip1559Elasticity[[:space:]]*=[[:space:]]*([0-9]+).*/\1/') - - echo "📋 Configuration from intent.toml:" - echo " Gas Limit: $GAS_LIMIT" - echo " EIP1559 Denominator: $EIP1559_DENOMINATOR" - echo " EIP1559 Elasticity: $EIP1559_ELASTICITY" - echo "" - - # Validate extracted parameters - if [ -z "$GAS_LIMIT" ]; then - echo "❌ Failed to extract gasLimit from intent.toml" - exit 1 - fi - if [ -z "$EIP1559_DENOMINATOR" ]; then - echo "❌ Failed to extract eip1559Denominator from intent.toml" - exit 1 - fi - if [ -z "$EIP1559_ELASTICITY" ]; then - echo "❌ Failed to extract eip1559Elasticity from intent.toml" - exit 1 - fi - - SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].SystemConfigProxy' "$CONFIG_DIR/state.json") - OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy' "$CONFIG_DIR/state.json") - - if [ -z "$SYSTEM_CONFIG_PROXY_ADDRESS" ] || [ "$SYSTEM_CONFIG_PROXY_ADDRESS" = "null" ]; then - echo "❌ Failed to read systemConfigProxyAddress from state.json" - exit 1 - fi - if [ -z "$OPTIMISM_PORTAL_PROXY_ADDRESS" ] || [ "$OPTIMISM_PORTAL_PROXY_ADDRESS" = "null" ]; then - echo "❌ Failed to read optimismPortalProxyAddress from state.json" - exit 1 - fi - echo "📝 Running Foundry setup script for Custom Gas Token..." - - cd $ROOT_DIR/packages/contracts-bedrock - export SYSTEM_CONFIG_PROXY_ADDRESS=$SYSTEM_CONFIG_PROXY_ADDRESS - export OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS - export OKB_TOKEN_ADDRESS=$OKB_TOKEN_ADDRESS - export OKB_ADAPTER_OWNER_ADDRESS=$OKB_ADAPTER_OWNER_ADDRESS - - FORGE_OUTPUT=$(forge script scripts/SetupCustomGasToken.s.sol:SetupCustomGasToken \ - --rpc-url "$L1_RPC_URL" \ - --private-key "$DEPLOYER_PRIVATE_KEY" \ - --broadcast 2>&1) - - echo "$FORGE_OUTPUT" - - # Extract contract addresses from forge output - ADAPTER_ADDRESS=$(echo "$FORGE_OUTPUT" | grep "DepositedOKBAdapter deployed at:" | awk '{print $NF}') - - # Query initial OKB total supply - INIT_TOTAL_SUPPLY=$(cast call "$OKB_TOKEN_ADDRESS" "totalSupply()(uint256)" --rpc-url "$L1_RPC_URL") - echo "" - echo "📊 Initial OKB Total Supply: $INIT_TOTAL_SUPPLY" - - echo "" - echo "✅ L1 Custom Gas Token setup complete!" - echo "📋 Deployed Contract Addresses:" - echo "" - echo " OKB Token: $OKB_TOKEN_ADDRESS" - echo " Adapter: $ADAPTER_ADDRESS" - echo "" - - # Set gas config to 0 for custom gas token (Ecotone upgrade) - echo "🔧 Setting gas config for Ecotone (Custom Gas Token)..." - cast send "$SYSTEM_CONFIG_PROXY_ADDRESS" \ - "setGasConfigEcotone(uint32,uint32)" \ - 0 \ - 0 \ - --rpc-url "$L1_RPC_URL" \ - --private-key "$DEPLOYER_PRIVATE_KEY" - echo "✅ Gas config set to (0, 0) for Custom Gas Token" - echo "" - - # Set gas limit - echo "🔧 Setting gas limit to $GAS_LIMIT..." - cast send "$SYSTEM_CONFIG_PROXY_ADDRESS" \ - "setGasLimit(uint64)" \ - "$GAS_LIMIT" \ - --rpc-url "$L1_RPC_URL" \ - --private-key "$DEPLOYER_PRIVATE_KEY" - echo "✅ Gas limit set successfully" - echo "" - - # Set EIP-1559 parameters - echo "🔧 Setting EIP-1559 parameters (denominator: $EIP1559_DENOMINATOR, elasticity: $EIP1559_ELASTICITY)..." - cast send "$SYSTEM_CONFIG_PROXY_ADDRESS" \ - "setEIP1559Params(uint32,uint32)" \ - "$EIP1559_DENOMINATOR" \ - "$EIP1559_ELASTICITY" \ - --rpc-url "$L1_RPC_URL" \ - --private-key "$DEPLOYER_PRIVATE_KEY" - echo "✅ EIP-1559 parameters set successfully" - echo "" - - # Transfer SystemConfig ownership - echo "🔧 Transferring SystemConfig ownership..." - echo "" - - # Check current owner - CURRENT_OWNER=$(cast call "$SYSTEM_CONFIG_PROXY_ADDRESS" "owner()(address)" --rpc-url "$L1_RPC_URL") - echo "📋 Current SystemConfig owner: $CURRENT_OWNER" - echo "📋 Target owner: $SYSTEM_CONFIG_OWNER_ADDRESS" - - if [ "$CURRENT_OWNER" != "$SYSTEM_CONFIG_OWNER_ADDRESS" ]; then - echo "🔄 Transferring ownership to $SYSTEM_CONFIG_OWNER_ADDRESS..." - - cast send "$SYSTEM_CONFIG_PROXY_ADDRESS" \ - "transferOwnership(address)" \ - "$SYSTEM_CONFIG_OWNER_ADDRESS" \ - --rpc-url "$L1_RPC_URL" \ - --private-key "$DEPLOYER_PRIVATE_KEY" - - # Verify transfer - NEW_OWNER=$(cast call "$SYSTEM_CONFIG_PROXY_ADDRESS" "owner()(address)" --rpc-url "$L1_RPC_URL") - echo "✅ SystemConfig ownership transferred to: $NEW_OWNER" - else - echo "✅ SystemConfig already owned by $SYSTEM_CONFIG_OWNER_ADDRESS" - fi - echo "" - - # Set init bond for game type 1 - set_init_bond - - # Transfer Transactor ownership - echo "🔧 Transferring Transactor ownership..." - echo "" - - # Check current Transactor owner - CURRENT_TRANSACTOR_OWNER=$(cast call "$TRANSACTOR_ADDRESS" "owner()(address)" --rpc-url "$L1_RPC_URL") - echo "📋 Current Transactor owner: $CURRENT_TRANSACTOR_OWNER" - echo "📋 Target owner: $ADMIN_OWNER_ADDRESS" - - if [ "$CURRENT_TRANSACTOR_OWNER" != "$ADMIN_OWNER_ADDRESS" ]; then - echo "🔄 Transferring Transactor ownership to $ADMIN_OWNER_ADDRESS..." - - cast send "$TRANSACTOR_ADDRESS" \ - "setOwner(address)" \ - "$ADMIN_OWNER_ADDRESS" \ - --rpc-url "$L1_RPC_URL" \ - --private-key "$DEPLOYER_PRIVATE_KEY" - - # Verify transfer - NEW_TRANSACTOR_OWNER=$(cast call "$TRANSACTOR_ADDRESS" "owner()(address)" --rpc-url "$L1_RPC_URL") - echo "✅ Transactor ownership transferred to: $NEW_TRANSACTOR_OWNER" - else - echo "✅ Transactor already owned by $ADMIN_OWNER_ADDRESS" - fi - echo "" - -} - -set_init_bond() { - echo "🔧 Setting init bond for game type 1..." - echo "" - - # Get DisputeGameFactory address from state.json - DISPUTE_GAME_FACTORY_ADDRESS=$(cat $ROOT_DIR/test-pp-op/config-op/state.json | jq -r '.opChainDeployments[0].DisputeGameFactoryProxy') - echo "📋 DisputeGameFactory Address: $DISPUTE_GAME_FACTORY_ADDRESS" - - # Set init bond using the script - bash $ROOT_DIR/test-pp-op/scripts/set-init-bond.sh \ - --game-type 1 \ - --init-bond $INITIAL_BOND \ - --transactor $TRANSACTOR_ADDRESS \ - --dispute-game-factory $DISPUTE_GAME_FACTORY_ADDRESS \ - --private-key $DEPLOYER_PRIVATE_KEY \ - --rpc-url $L1_RPC_URL - - echo "" -} - -echo "CGT_ENABLED: ${CGT_ENABLED}" - -cp ./config-op/intent.${ENV}.toml.bak ./config-op/intent.toml -cp ./config-op/state.json.bak ./config-op/state.json - -CHAIN_ID_UINT256=$(cast to-uint256 $CHAIN_ID) -sed_inplace 's/id = .*/id = "'"$CHAIN_ID_UINT256"'"/' ./config-op/intent.toml -echo " ✅ Updated chain id in intent.toml: $CHAIN_ID_UINT256" - -# Validate OWNER_TYPE configuration -if [ "$OWNER_TYPE" != "transactor" ] && [ "$OWNER_TYPE" != "safe" ]; then - echo "❌ Error: Invalid OWNER_TYPE '$OWNER_TYPE'. Must be 'transactor' or 'safe'" - exit 1 -fi - -echo "=== Deploying with OWNER_TYPE: $OWNER_TYPE ===" - -# Deploy owner contract based on OWNER_TYPE -if [ "$OWNER_TYPE" = "safe" ]; then - echo "🔧 Deploying Gnosis Safe for l1ProxyAdminOwner..." - deploy_safe - L1_PROXY_ADMIN_OWNER=$SAFE_ADDRESS -elif [ "$OWNER_TYPE" = "transactor" ]; then - echo "🔧 Deploying Transactor for l1ProxyAdminOwner..." - deploy_transactor - L1_PROXY_ADMIN_OWNER=$TRANSACTOR_ADDRESS -fi - -echo "Using $OWNER_TYPE as l1ProxyAdminOwner: $L1_PROXY_ADMIN_OWNER" - -deploy_op_stack_bootstrap_superchain -deploy_op_stack_bootstrap_implementations -deploy_op_stack_contracts - -if [ "$CGT_ENABLED" = "true" ]; then - deploy_custom_gas_token -fi diff --git a/test-pp-op/3-stop-erigon.sh b/test-pp-op/3-stop-erigon.sh deleted file mode 100755 index 5a6b2845f2b53..0000000000000 --- a/test-pp-op/3-stop-erigon.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -set -x -set -e -source .env -source tools.sh -source utils.sh - -cd $PWD_DIR - -## Stop X Layer services -echo "DOCKER_COMPOSE_CMD: ${DOCKER_COMPOSE_CMD}" -${DOCKER_COMPOSE_CMD} stop xlayer-seq -#${DOCKER_COMPOSE_CMD} stop xlayer-rpc -${DOCKER_COMPOSE_CMD} stop xlayer-bridge-service -${DOCKER_COMPOSE_CMD} stop xlayer-bridge-ui -${DOCKER_COMPOSE_CMD} stop xlayer-agg-sender - -# Get fork block number and parent hash -LOG_OUTPUT=$(docker logs xlayer-seq 2>&1) -FORK_BLOCK=$(echo "$LOG_OUTPUT" | grep "Finish block" | tail -1 | sed -n 's/.*Finish block \([0-9]*\) with.*/\1/p') - -echo "FORK_BLOCK=$FORK_BLOCK" - -sed_inplace "s/FORK_BLOCK=.*/FORK_BLOCK=$((FORK_BLOCK+1))/" .env -PARENT_HASH=$(echo "$LOG_OUTPUT" | grep "RPC Daemon notified of new headers" | tail -1 | sed -n 's/.*hash=\([0-9a-fx]*\) .*/\1/p') -echo "PARENT_HASH=$PARENT_HASH" -sed_inplace "s/PARENT_HASH=.*/PARENT_HASH=$PARENT_HASH/" .env diff --git a/test-pp-op/4-migrate-op.sh b/test-pp-op/4-migrate-op.sh deleted file mode 100755 index b34624e272506..0000000000000 --- a/test-pp-op/4-migrate-op.sh +++ /dev/null @@ -1,209 +0,0 @@ -#!/bin/bash -set -e - -# Debug mode - set to true to enable verbose output -DEBUG=${DEBUG:-false} - -if [ "$DEBUG" = "true" ]; then - set -x -fi - -source .env -source tools.sh -source utils.sh - -prepare() { - # Check required files exist - if [ ! -f "./config-op/genesis.json" ]; then - echo "❌ ERROR: ./config-op/genesis.json not found!" - exit 1 - fi - - if [ ! -f "./config-op/rollup.json" ]; then - echo "❌ ERROR: ./config-op/rollup.json not found!" - exit 1 - fi - - cp ./config-op/genesis.json ./config-op/genesis-op-raw.json - cp ./config-op/genesis.json ./config-op/genesis-op-before-number.json - cp ./config-op/genesis.json ./config-op/genesis-op-after-number.json - - # Extract contract addresses from state.json and update .env file - echo "🔧 Extracting contract addresses from state.json..." - STATE_JSON="$PWD_DIR/config-op/state.json" - - if [ -f "$STATE_JSON" ]; then - # Extract contract addresses from state.json - DEPLOYMENTS_TYPE=$(jq -r 'type' "$STATE_JSON") - if [ "$DEPLOYMENTS_TYPE" = "object" ]; then - OPCD_TYPE=$(jq -r '.opChainDeployments | type' "$STATE_JSON" 2>/dev/null) - if [ "$OPCD_TYPE" = "object" ]; then - DISPUTE_GAME_FACTORY_ADDRESS=$(jq -r '.opChainDeployments.DisputeGameFactoryProxy // empty' "$STATE_JSON") - L2OO_ADDRESS=$(jq -r '.opChainDeployments.L2OutputOracleProxy // empty' "$STATE_JSON") - OPCM_IMPL_ADDRESS=$(jq -r '.appliedIntent.opcmAddress // empty' "$STATE_JSON") - SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments.SystemConfigProxy // empty' "$STATE_JSON") - PROXY_ADMIN=$(jq -r '.superchainContracts.SuperchainProxyAdminImpl // empty' "$STATE_JSON") - OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments.OptimismPortalProxy // empty' "$STATE_JSON") - elif [ "$OPCD_TYPE" = "array" ]; then - DISPUTE_GAME_FACTORY_ADDRESS=$(jq -r '.opChainDeployments[0].DisputeGameFactoryProxy // empty' "$STATE_JSON") - L2OO_ADDRESS=$(jq -r '.opChainDeployments[0].L2OutputOracleProxy // empty' "$STATE_JSON") - OPCM_IMPL_ADDRESS=$(jq -r '.appliedIntent.opcmAddress // empty' "$STATE_JSON") - SYSTEM_CONFIG_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].SystemConfigProxy // empty' "$STATE_JSON") - PROXY_ADMIN=$(jq -r '.superchainContracts.SuperchainProxyAdminImpl // empty' "$STATE_JSON") - OPTIMISM_PORTAL_PROXY_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy // empty' "$STATE_JSON") - else - DISPUTE_GAME_FACTORY_ADDRESS="" - L2OO_ADDRESS="" - OPCM_IMPL_ADDRESS="" - SYSTEM_CONFIG_PROXY_ADDRESS="" - PROXY_ADMIN="" - OPTIMISM_PORTAL_PROXY_ADDRESS="" - fi - - # Update .env if found - if [ -n "$DISPUTE_GAME_FACTORY_ADDRESS" ]; then - echo "✅ Found DisputeGameFactoryProxy address: $DISPUTE_GAME_FACTORY_ADDRESS" - sed_inplace "s/DISPUTE_GAME_FACTORY_ADDRESS=.*/DISPUTE_GAME_FACTORY_ADDRESS=$DISPUTE_GAME_FACTORY_ADDRESS/" .env - else - echo "⚠️ DisputeGameFactoryProxy address not found in opChainDeployments" - fi - - if [ -n "$L2OO_ADDRESS" ]; then - echo "✅ Found L2OutputOracleProxy address: $L2OO_ADDRESS" - sed_inplace "s/L2OO_ADDRESS=.*/L2OO_ADDRESS=$L2OO_ADDRESS/" .env - else - echo "⚠️ L2OutputOracleProxy address not found in opChainDeployments" - fi - - if [ -n "$OPCM_IMPL_ADDRESS" ]; then - echo "✅ Found opcmAddress address: $OPCM_IMPL_ADDRESS" - sed_inplace "s/OPCM_IMPL_ADDRESS=.*/OPCM_IMPL_ADDRESS=$OPCM_IMPL_ADDRESS/" .env - else - echo "⚠️ opcmAddress address not found in opChainDeployments" - fi - - if [ -n "$SYSTEM_CONFIG_PROXY_ADDRESS" ]; then - echo "✅ Found SystemConfigProxy address: $SYSTEM_CONFIG_PROXY_ADDRESS" - sed_inplace "s/SYSTEM_CONFIG_PROXY_ADDRESS=.*/SYSTEM_CONFIG_PROXY_ADDRESS=$SYSTEM_CONFIG_PROXY_ADDRESS/" .env - else - echo "⚠️ SystemConfigProxy address not found in opChainDeployments" - fi - - if [ -n "$OPTIMISM_PORTAL_PROXY_ADDRESS" ]; then - echo " ✅ Found OptimismPortalProxy address: $OPTIMISM_PORTAL_PROXY_ADDRESS" - sed_inplace "s/OPTIMISM_PORTAL_PROXY_ADDRESS=.*/OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS/" .env - else - echo " ⚠️ OptimismPortalProxy address not found in opChainDeployments" - fi - - if [ -n "$PROXY_ADMIN" ]; then - echo "✅ Found ProxyAdmin address: $PROXY_ADMIN" - sed_inplace "s/PROXY_ADMIN=.*/PROXY_ADMIN=$PROXY_ADMIN/" .env - else - echo "⚠️ ProxyAdmin address not found in opChainDeployments" - fi - - # Show summary - echo "📄 Contract addresses updated in .env:" - echo " DISPUTE_GAME_FACTORY_ADDRESS=$DISPUTE_GAME_FACTORY_ADDRESS" - echo " L2OO_ADDRESS=$L2OO_ADDRESS" - echo " OPCM_IMPL_ADDRESS=$OPCM_IMPL_ADDRESS" - echo " SYSTEM_CONFIG_PROXY_ADDRESS=$SYSTEM_CONFIG_PROXY_ADDRESS" - echo " OPTIMISM_PORTAL_PROXY_ADDRESS=$OPTIMISM_PORTAL_PROXY_ADDRESS" - echo " PROXY_ADMIN=$PROXY_ADMIN" - else - echo "❌ $STATE_JSON is not a valid JSON object" - fi - else - echo "❌ state.json not found at $STATE_JSON" - fi -} - - -migrate() { - export OP_DATA_DIR=./data/op-geth-seq - export OP_GENESIS_PATH=${PWD_DIR}/config-op/genesis-op-after-number.json - - if [ "$ENV" = "local" ]; then - ERIGON_CHAINDATA_DIR=${PWD_DIR}/data/rpc/chaindata/ - ERIGON_SMTDATA_DIR=${PWD_DIR}/data/rpc/smt/ - else - ERIGON_CHAINDATA_DIR=/data/erigon-data/chaindata/ - ERIGON_SMTDATA_DIR=/data/erigon-data/smt/ - fi - - if [[ "$OSTYPE" == "darwin"* ]]; then - export GETH_CMD=$(go env GOPATH)/bin/geth - - if [ ! -f ${GETH_CMD} ]; then - cd ./tmp/op-geth - make geth - sudo cp ./build/bin/geth /usr/local/bin/geth - cd $PWD_DIR - else - echo "✅ geth found at optimism/op-geth/build/bin" - fi - else - export GETH_CMD=geth - echo "✅ Using Linux geth path: $GETH_CMD" - fi - - echo "GETH_CMD: $GETH_CMD" - # Build the base command - MIGRATE_CMD="${GETH_CMD} --datadir=${OP_DATA_DIR} --gcmode=archive migrate --state.scheme=hash --ignore-addresses=0x000000000000000000000000000000005ca1ab1e --chaindata=${ERIGON_CHAINDATA_DIR} --smt-db-path=${ERIGON_SMTDATA_DIR} --output merged.genesis.json" - - # Add --override-proposer if TIMELOCK_OVERRIDE_PROPOSER_ADDRESS is set and non-empty - if [ -n "${TIMELOCK_OVERRIDE_PROPOSER_ADDRESS:-}" ]; then - MIGRATE_CMD="$MIGRATE_CMD --override-proposer=${TIMELOCK_OVERRIDE_PROPOSER_ADDRESS}" - fi - - # Add --override-executor if TIMELOCK_OVERRIDE_EXECUTOR_ADDRESS is set and non-empty - if [ -n "${TIMELOCK_OVERRIDE_EXECUTOR_ADDRESS:-}" ]; then - MIGRATE_CMD="$MIGRATE_CMD --override-executor=${TIMELOCK_OVERRIDE_EXECUTOR_ADDRESS}" - fi - - # Add the genesis path at the end - MIGRATE_CMD="$MIGRATE_CMD ${OP_GENESIS_PATH}" - - # Execute the command - $MIGRATE_CMD 2>&1 | tee migrate.log - - LOG_BLOCK=$(grep -A 5 "Update rollup.json file with the following information l2" migrate.log | tail -n 5) - L2_NUMBER=$(echo "$LOG_BLOCK" | grep '"number"' | sed 's/[^0-9]*\([0-9]*\).*/\1/') - L2_HASH=$(echo "$LOG_BLOCK" | grep '"hash"' | sed 's/.*"\(0x[0-9a-fA-F]*\)".*/\1/') - echo "L2_NUMBER: $L2_NUMBER" - echo "L2_HASH: $L2_HASH" - - jq --argjson num "$L2_NUMBER" --arg hash "$L2_HASH" \ - '.genesis.l2.number = $num | .genesis.l2.hash = $hash' \ - config-op/rollup.json > config-op/rollup.json.tmp && mv config-op/rollup.json.tmp config-op/rollup.json - - # Update eip1559DenominatorCanyon to match eip1559Denominator in rollup.json - echo "🔧 Updating eip1559DenominatorCanyon to match eip1559Denominator..." - - # Extract eip1559Denominator from rollup.json - EIP1559_DENOMINATOR=$(jq -r '.chain_op_config.eip1559Denominator' config-op/rollup.json) - echo "eip1559Denominator value from rollup.json: $EIP1559_DENOMINATOR" - - # Debug: Check current rollup.json structure - echo "🔍 Current rollup.json chain_op_config structure:" - jq '.chain_op_config' config-op/rollup.json - - # Update rollup.json with the eip1559DenominatorCanyon value - echo "🔧 Updating rollup.json chain_op_config..." - jq --argjson denominator "$EIP1559_DENOMINATOR" \ - '.chain_op_config.eip1559DenominatorCanyon = $denominator' \ - config-op/rollup.json > config-op/rollup.json.tmp && mv config-op/rollup.json.tmp config-op/rollup.json - - # Verify the update - echo "🔍 Updated rollup.json chain_op_config structure:" - jq '.chain_op_config' config-op/rollup.json - - echo "✅ Updated eip1559DenominatorCanyon to $EIP1559_DENOMINATOR in rollup.json" - - echo "finished migrate op-geth" -} - -cd $PWD_DIR -prepare -migrate diff --git a/test-pp-op/5-start-op.sh b/test-pp-op/5-start-op.sh deleted file mode 100755 index 62ff8b6c8c18f..0000000000000 --- a/test-pp-op/5-start-op.sh +++ /dev/null @@ -1,168 +0,0 @@ -set -e -set -x -source .env -source utils.sh -source tools.sh - -PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ROOT_DIR="$(dirname "$PWD_DIR")" -SCRIPTS_DIR=$ROOT_DIR/test/scripts - -start_sequencer() { - rm -rf "$OP_GETH_DATADIR2" - cp -r "$OP_GETH_DATADIR" "$OP_GETH_DATADIR2" - - rm -rf "$OP_GETH_DATADIR3" - cp -r "$OP_GETH_DATADIR" "$OP_GETH_DATADIR3" - - if [ "$ENV" = "testnet" ];then - L1_RPC_URL="https://fullnode-inner.okg.com/sepolia/fork/okbc/rpc" - L1_BEACON_URL_IN_DOCKER="https://fullnode-inner.okg.com/ethsepoliabeacon/native/layer1/rpc" - sed_inplace "s|L1_RPC_URL=.*|L1_RPC_URL=$L1_RPC_URL|" .env - sed_inplace "s|L1_RPC_URL_IN_DOCKER=.*|L1_RPC_URL_IN_DOCKER=$L1_RPC_URL|" .env - sed_inplace "s|L1_BEACON_URL_IN_DOCKER=.*|L1_BEACON_URL_IN_DOCKER=$L1_BEACON_URL_IN_DOCKER|" .env - fi - - if [ "$CONDUCTOR_ENABLED" = "true" ]; then - ${DOCKER_COMPOSE_CMD} up -d op-conductor - ${DOCKER_COMPOSE_CMD} up -d op-conductor2 - ${DOCKER_COMPOSE_CMD} up -d op-conductor3 - sleep 3 - $SCRIPTS_DIR/active-sequencer.sh - else - ${DOCKER_COMPOSE_CMD} up -d op-seq - fi - - # Check for L2 genesis hash mismatch - LOG_OUTPUT=$(${DOCKER_COMPOSE_CMD} logs op-seq 2>&1 | tail -20) - if echo "$LOG_OUTPUT" | grep -q "expected L2 genesis hash to match L2 block at genesis block number"; then - echo "❌ L2 genesis hash mismatch detected!" - echo "Error details:" - echo "$LOG_OUTPUT" | grep "expected L2 genesis hash to match L2 block at genesis block number" - exit 1 - fi -} - -start_rpc() { - rm -rf "$OP_GETH_RPC_DATADIR" - cp -r "$OP_GETH_DATADIR" "$OP_GETH_RPC_DATADIR" - ${DOCKER_COMPOSE_CMD} up -d op-rpc -} - -connect_static_peers() { - - # Setup P2P static connections between op-geth nodes - echo "🔗 Setting up P2P static connections between op-geth nodes..." - - # Get enodes for all op-geth containers - echo "📡 Getting enode addresses..." - - # Get enodes - OP_GETH_SEQ_ENODE=$(get_enode "op-geth-seq" "8545") - OP_GETH_RPC_ENODE=$(get_enode "op-geth-rpc" "8545") - - if [ "$CONDUCTOR_ENABLED" = "true" ]; then - OP_GETH_SEQ2_ENODE=$(get_enode "op-geth-seq2" "8545") - OP_GETH_SEQ3_ENODE=$(get_enode "op-geth-seq3" "8545") - fi - - # Replace 127.0.0.1 with container names - OP_GETH_SEQ_ENODE=$(replace_enode_ip "$OP_GETH_SEQ_ENODE" "op-geth-seq") - OP_GETH_RPC_ENODE=$(replace_enode_ip "$OP_GETH_RPC_ENODE" "op-geth-rpc") - - if [ "$CONDUCTOR_ENABLED" = "true" ]; then - OP_GETH_SEQ2_ENODE=$(replace_enode_ip "$OP_GETH_SEQ2_ENODE" "op-geth-seq2") - OP_GETH_SEQ3_ENODE=$(replace_enode_ip "$OP_GETH_SEQ3_ENODE" "op-geth-seq3") - fi - - echo "✅ Enode addresses:" - echo " op-geth-seq: $OP_GETH_SEQ_ENODE" - echo " op-geth-rpc: $OP_GETH_RPC_ENODE" - if [ "$CONDUCTOR_ENABLED" = "true" ]; then - echo " op-geth-seq2: $OP_GETH_SEQ2_ENODE" - echo " op-geth-seq3: $OP_GETH_SEQ3_ENODE" - fi - - - # Setup static connections between sequencer nodes - echo "🔗 Setting up static connections between sequencer nodes..." - - # Add peers to op-geth-seq (connect to other sequencers) - echo "🔗 Setting up peers for op-geth-seq..." - if [ "$CONDUCTOR_ENABLED" = "true" ]; then - add_peer "op-geth-seq" "$OP_GETH_SEQ2_ENODE" - add_peer "op-geth-seq" "$OP_GETH_SEQ3_ENODE" - fi - - if [ "$CONDUCTOR_ENABLED" = "true" ]; then - # Add peers to op-geth-seq2 (connect to other sequencers) - echo "🔗 Setting up peers for op-geth-seq2..." - add_peer "op-geth-seq2" "$OP_GETH_SEQ_ENODE" - add_peer "op-geth-seq2" "$OP_GETH_SEQ3_ENODE" - - # Add peers to op-geth-seq3 (connect to other sequencers) - echo "🔗 Setting up peers for op-geth-seq3..." - add_peer "op-geth-seq3" "$OP_GETH_SEQ_ENODE" - add_peer "op-geth-seq3" "$OP_GETH_SEQ2_ENODE" - fi - - # Setup RPC node to connect to all sequencer nodes - echo "🔗 Setting up RPC node to connect to all sequencer nodes..." - add_peer "op-geth-rpc" "$OP_GETH_SEQ_ENODE" - if [ "$CONDUCTOR_ENABLED" = "true" ]; then - add_peer "op-geth-rpc" "$OP_GETH_SEQ2_ENODE" - add_peer "op-geth-rpc" "$OP_GETH_SEQ3_ENODE" - fi - - echo "✅ P2P static connections established:" - echo " - Sequencer nodes (op-geth-seq, op-geth-seq2, op-geth-seq3) are connected to each other" - echo " - RPC node (op-geth-rpc) is connected to all sequencer nodes" - -} - -# Function to get enode from a geth container -get_enode() { - local container_name=$1 - local rpc_port=$2 - local enode=$(docker exec $container_name geth attach --exec "admin.nodeInfo.enode" --datadir /datadir 2>/dev/null | tr -d '"') - echo "$enode" -} - -# Function to replace 127.0.0.1 with container name in enode -replace_enode_ip() { - local enode=$1 - local container_name=$2 - echo "$enode" | sed "s/@127.0.0.1:/@$container_name:/" -} - -# Function to add peer to a geth container -add_peer() { - local container_name=$1 - local peer_enode=$2 - echo "🔗 Adding peer to $container_name: $peer_enode" - docker exec $container_name geth attach --exec "admin.addPeer('$peer_enode')" --datadir /datadir 2>/dev/null -} - -start_batcher() { - # Configure op-batcher endpoints based on conductor mode - if [ "$CONDUCTOR_ENABLED" = "true" ]; then - echo "🔧 Configuring op-batcher for conductor mode with conductor RPC endpoints..." - # Set conductor mode endpoints - export OP_BATCHER_L2_ETH_RPC="http://op-conductor:8547,http://op-conductor2:8547,http://op-conductor3:8547" - export OP_BATCHER_ROLLUP_RPC="http://op-conductor:8547,http://op-conductor2:8547,http://op-conductor3:8547" - echo "✅ op-batcher configured for conductor mode (connecting to conductor RPC endpoints)" - else - echo "🔧 Configuring op-batcher for single sequencer mode..." - # Set single sequencer mode endpoints - export OP_BATCHER_L2_ETH_RPC="http://op-geth-seq:8545" - export OP_BATCHER_ROLLUP_RPC="http://op-seq:9545" - echo "✅ op-batcher configured for single sequencer mode" - fi - - ${DOCKER_COMPOSE_CMD} up -d op-batcher -} - -start_sequencer -start_rpc -connect_static_peers -start_batcher diff --git a/test-pp-op/6-build-op-program.sh b/test-pp-op/6-build-op-program.sh deleted file mode 100755 index 867ec1be3d168..0000000000000 --- a/test-pp-op/6-build-op-program.sh +++ /dev/null @@ -1,174 +0,0 @@ -#!/bin/bash -set -x -set -e -source .env -source tools.sh - -PWD_DIR=$(pwd) - -if [ -z "$CHAIN_ID" ]; then - echo "❌ ERROR: CHAIN_ID is not set. Set it explicitly or derive it from intent.toml before proceeding." - exit 1 -fi -if ! [[ "$CHAIN_ID" =~ ^[0-9]+$ ]]; then - echo "❌ ERROR: CHAIN_ID must be a numeric value, got: '$CHAIN_ID'" - exit 1 -fi -# Function to show usage -show_usage() { - echo "Usage: $0 [OPTIONS]" - echo "Options:" - echo " -a, --arch ARCH Target architecture (x86|arm|amd64|arm64)" - echo " Default: auto-detect from OSTYPE" - echo " -h, --help Show this help message" - echo "" - echo "Architecture mapping:" - echo " x86/amd64 -> linux/amd64" - echo " arm/arm64 -> linux/arm64" - echo "" - echo "Current OSTYPE: $OSTYPE" -} - -# Default architecture detection based on OSTYPE -detect_arch() { - case "$OSTYPE" in - *darwin*) - if [[ $(uname -m) == "arm64" ]]; then - echo "linux/arm64" - else - echo "linux/amd64" - fi - ;; - *linux*) - if [[ $(uname -m) == "aarch64" ]] || [[ $(uname -m) == "arm64" ]]; then - echo "linux/arm64" - else - echo "linux/amd64" - fi - ;; - *) - echo "linux/amd64" # Default fallback - ;; - esac -} - -# Parse command line arguments -DOCKER_PLATFORM="" -while [[ $# -gt 0 ]]; do - case $1 in - -a|--arch) - case "$2" in - x86|amd64) - DOCKER_PLATFORM="linux/amd64" - ;; - arm|arm64) - DOCKER_PLATFORM="linux/arm64" - ;; - *) - echo "Error: Invalid architecture '$2'" - echo "Valid options: x86, amd64, arm, arm64" - exit 1 - ;; - esac - shift 2 - ;; - -h|--help) - show_usage - exit 0 - ;; - *) - echo "Error: Unknown option '$1'" - show_usage - exit 1 - ;; - esac -done - -# Set default platform if not specified -if [ -z "$DOCKER_PLATFORM" ]; then - DOCKER_PLATFORM=$(detect_arch) - echo "Auto-detected platform: $DOCKER_PLATFORM" -else - echo "Using specified platform: $DOCKER_PLATFORM" -fi - -post_migrate() { - # Check if genesis.json exists, panic if it doesn't - if [ ! -f "merged.genesis.json" ]; then - echo "ERROR: merged.genesis.json does not exist!" - echo "Please ensure the genesis.json file is present before running this script." - exit 1 - fi - - $MD5SUM_CMD merged.genesis.json - # genesis.json is too large to embed in go, so we compress it now and decompress it in go code - gzip -c merged.genesis.json > config-op/merged.genesis.gz.json - - # Ensure prestate files exist and devnetL1.json is consistent before deploying contracts - EXPORT_DIR="$PWD_DIR/data/cannon-data" - rm -rf $EXPORT_DIR - mkdir -p $EXPORT_DIR - - # Set network based on ENV - if [ "$ENV" = "local" ]; then - DOCKER_NETWORK_ARG="--network ${DOCKER_NETWORK}" - else - DOCKER_NETWORK_ARG="--network host" - fi - - ROOTLESS_DOCKER=$(docker info -f "{{println .SecurityOptions}}" | grep rootless || true) - - if ! [ -z "$ROOTLESS_DOCKER" ]; then - docker run -it --privileged \ - --platform $DOCKER_PLATFORM \ - -v "$(pwd)/scripts:/scripts" \ - -v "$(pwd)/config-op/rollup.json:/app/op-program/chainconfig/configs/${CHAIN_ID}-rollup.json" \ - -v "$(pwd)/config-op/merged.genesis.gz.json:/app/op-program/chainconfig/configs/${CHAIN_ID}-genesis-l2.json" \ - -v "$(pwd)/l1-geth/execution/genesis.json:/app/op-program/chainconfig/configs/1337-genesis-l1.json" \ - -v "$EXPORT_DIR:/app/op-program/bin" \ - --name op-program \ - -w /app \ - ${DOCKER_NETWORK_ARG} \ - "${OP_STACK_IMAGE_TAG}" \ - bash -c " - echo '📊 Verifying Docker connection:' - /scripts/dind-install-start.sh - docker --version - docker ps --format 'table {{.Names}}\t{{.Status}}' | head -3 - - echo '🚀 Running make reproducible-prestate...' - make reproducible-prestate - - echo '📁 Checking contents of op-program/bin:' - ls -la /app/op-program/bin/ || echo 'Directory is empty or does not exist' - " - else - docker run -it \ - --platform $DOCKER_PLATFORM \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v "$(pwd)/config-op/rollup.json:/app/op-program/chainconfig/configs/${CHAIN_ID}-rollup.json" \ - -v "$(pwd)/config-op/merged.genesis.gz.json:/app/op-program/chainconfig/configs/${CHAIN_ID}-genesis-l2.json" \ - -v "$(pwd)/l1-geth/execution/genesis.json:/app/op-program/chainconfig/configs/1337-genesis-l1.json" \ - -v "$EXPORT_DIR:/app/op-program/bin" \ - --name op-program \ - -w /app \ - ${DOCKER_NETWORK_ARG} \ - -e DOCKER_HOST=unix:///var/run/docker.sock \ - "${OP_STACK_IMAGE_TAG}" \ - bash -c " - echo '📊 Verifying Docker connection:' - apt-get update - apt-get install docker.io -y - docker --version - docker ps --format 'table {{.Names}}\t{{.Status}}' | head -3 - - echo '🚀 Running make reproducible-prestate...' - make reproducible-prestate - - echo '📁 Checking contents of op-program/bin:' - ls -la /app/op-program/bin/ || echo 'Directory is empty or does not exist' - " - fi -} - -post_migrate diff --git a/test-pp-op/7-setup-fraud-proof.sh b/test-pp-op/7-setup-fraud-proof.sh deleted file mode 100755 index 2dad87ecf5731..0000000000000 --- a/test-pp-op/7-setup-fraud-proof.sh +++ /dev/null @@ -1,505 +0,0 @@ -#!/bin/bash -set -e -set -x - -source .env -source tools.sh - -if [ "$ENV" = "testnet" ];then - shopt -s expand_aliases - alias cast='docker run --rm --network host op-migrate:amd64 cast' -fi - -PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd $PWD_DIR -EXPORT_DIR="$PWD_DIR/data/cannon-data" - -# Get prestate value from prestate-proof-mt64.json -ABSOLUTE_PRESTATE=$(jq -r '.pre' "$EXPORT_DIR/prestate-proof-mt64.json") - -# Validate OWNER_TYPE configuration -if [ "$OWNER_TYPE" != "transactor" ] && [ "$OWNER_TYPE" != "safe" ]; then - echo "❌ Error: Invalid OWNER_TYPE '$OWNER_TYPE'. Must be 'transactor' or 'safe'" - exit 1 -fi - -echo "=== Using OWNER_TYPE: $OWNER_TYPE ===" - -# Function to add game type via Safe -add_game_type_via_safe() { - # Check parameter count - if [ $# -ne 5 ]; then - echo "Error: add_game_type_via_safe requires exactly 5 parameters" - echo "Usage: add_game_type_via_safe " - echo "Example: add_game_type_via_safe 2 true 600 1800 0x..." - return 1 - fi - - local GAME_TYPE=$1 - local IS_PERMISSIONED=$2 - local CLOCK_EXTENSION_VAL=$3 - local MAX_CLOCK_DURATION_VAL=$4 - local ABSOLUTE_PRESTATE_VAL=$5 - - echo "=== Adding Game Type $GAME_TYPE via Safe ===" - echo " Game Type: $GAME_TYPE" - echo " Is Permissioned: $IS_PERMISSIONED" - echo " Clock Extension: $CLOCK_EXTENSION_VAL" - echo " Max Clock Duration: $MAX_CLOCK_DURATION_VAL" - echo "" - - # Get dispute game factory address - DISPUTE_GAME_FACTORY=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'disputeGameFactory()(address)') - - echo "Debug Info:" - echo " State JSON: $STATE_JSON_PATH" - echo " Dispute Game Factory: $DISPUTE_GAME_FACTORY" - echo " System Config: $SYSTEM_CONFIG_PROXY_ADDRESS" - echo " Proxy Admin: $PROXY_ADMIN" - echo " OPCM: $OPCM_IMPL_ADDRESS" - echo " Safe: $SAFE_ADDRESS" - echo " RPC URL: $L1_RPC_URL" - echo " Sender: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" - echo "" - - # Retrieve existing permissioned game implementation for parameters - echo "Retrieving permissioned game parameters..." - PERMISSIONED_GAME=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' 1) - echo "Permissioned Game Implementation: $PERMISSIONED_GAME" - - if [ "$PERMISSIONED_GAME" == "0x0000000000000000000000000000000000000000" ]; then - echo "Error: No permissioned game found. Cannot retrieve parameters." - exit 1 - fi - - # Retrieve parameters from existing permissioned game - ABSOLUTE_PRESTATE="$ABSOLUTE_PRESTATE_VAL" - MAX_GAME_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'maxGameDepth()') - SPLIT_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'splitDepth()') - VM=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'vm()(address)') - - echo "Retrieved parameters:" - echo " Absolute Prestate: $ABSOLUTE_PRESTATE" - echo " Max Game Depth: $MAX_GAME_DEPTH" - echo " Split Depth: $SPLIT_DEPTH" - echo " Clock Extension: $CLOCK_EXTENSION_VAL" - echo " Max Clock Duration: $MAX_CLOCK_DURATION_VAL" - echo " VM: $VM" - echo "" - - # Set constants - INITIAL_BOND='80000000000000000' # 0.08 ETH in wei - SALT_MIXER='123' # Unique salt for game type - - echo "Creating addGameType calldata..." - - # Build game type parameters array (simplified) - GAME_PARAMS="[(\"$SALT_MIXER\",$SYSTEM_CONFIG_PROXY_ADDRESS,$PROXY_ADMIN,0x0000000000000000000000000000000000000000,$GAME_TYPE,$ABSOLUTE_PRESTATE,$MAX_GAME_DEPTH,$SPLIT_DEPTH,$CLOCK_EXTENSION_VAL,$MAX_CLOCK_DURATION_VAL,$INITIAL_BOND,$VM,$IS_PERMISSIONED)]" - - echo "Parameters prepared for addGameType" - - # Execute the transaction through Safe - echo "Executing transaction via Safe..." - echo "Target: $SAFE_ADDRESS" - echo "From: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" - - # Simplified DELEGATECALL - build calldata first, then call - ADDGAMETYPE_CALLDATA=$(cast calldata 'addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[])' "$GAME_PARAMS") - - - # Execute transaction via Safe's execTransaction with proper signature - echo "Executing transaction via Safe with signature..." - DEPLOYER_ADDRESS=$(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY) - - # Use the calldata we built earlier - echo "Using calldata: $ADDGAMETYPE_CALLDATA" - - # Get Safe nonce - SAFE_NONCE=$(cast call --rpc-url $L1_RPC_URL $SAFE_ADDRESS 'nonce()(uint256)') - echo "Safe nonce: $SAFE_NONCE" - - # Build signature exactly like DeployOwnership.s.sol _callViaSafe method - # abi.encodePacked(uint256(uint160(msg.sender)), bytes32(0), uint8(1)) - echo "Building signature like DeployOwnership.s.sol _callViaSafe..." - - # Convert deployer address to uint256(uint160(address)) format - # This is equivalent to: uint256(uint160(msg.sender)) - DEPLOYER_ADDRESS_NO_PREFIX=${DEPLOYER_ADDRESS#0x} - DEPLOYER_ADDRESS_PADDED=$(printf "%064s" $DEPLOYER_ADDRESS_NO_PREFIX) - - # Build signature: uint256(uint160(msg.sender)) + bytes32(0) + uint8(1) - # This is exactly what abi.encodePacked(uint256(uint160(msg.sender)), bytes32(0), uint8(1)) produces - PACKED_SIGNATURE="0x${DEPLOYER_ADDRESS_PADDED}000000000000000000000000000000000000000000000000000000000000000001" - - echo "Deployer address: $DEPLOYER_ADDRESS" - echo "Signature (abi.encodePacked format): $PACKED_SIGNATURE" - echo "Signature length: $((${#PACKED_SIGNATURE} - 2)) hex chars = $(((${#PACKED_SIGNATURE} - 2) / 2)) bytes" - - # Execute transaction via Safe's execTransaction - echo "Executing execTransaction on Safe..." - TX_OUTPUT=$(cast send \ - --json \ - --legacy \ - --rpc-url $L1_RPC_URL \ - --private-key $DEPLOYER_PRIVATE_KEY \ - --from $DEPLOYER_ADDRESS \ - $SAFE_ADDRESS \ - 'execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)' \ - $OPCM_IMPL_ADDRESS \ - 0 \ - $ADDGAMETYPE_CALLDATA \ - 1 \ - 0 \ - 0 \ - 0 \ - 0x0000000000000000000000000000000000000000 \ - 0x0000000000000000000000000000000000000000 \ - $PACKED_SIGNATURE) - - # Extract transaction hash and status - TX_HASH=$(echo "$TX_OUTPUT" | jq -r '.transactionHash // empty') - TX_STATUS=$(echo "$TX_OUTPUT" | jq -r '.status // empty') - - echo "" - echo "Transaction sent, TX_HASH: $TX_HASH" - - # Check if transaction was successful - if [ "$TX_STATUS" = "0x1" ] || [ "$TX_STATUS" = "1" ]; then - echo " ✅ Transaction successful!" - else - echo " ❌ Transaction failed with status: $TX_STATUS" - echo "Full output: $TX_OUTPUT" - exit 1 - fi - echo "" - - # Verify the new game type was added - echo "Verifying new game type was added..." - NEW_GAME_IMPL=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' $GAME_TYPE) - - if [ "$NEW_GAME_IMPL" != "0x0000000000000000000000000000000000000000" ] && [ "$NEW_GAME_IMPL" != "$PERMISSIONED_GAME" ]; then - echo " ✅ Success! New game type $GAME_TYPE added." - echo "Game Type $GAME_TYPE Implementation: $NEW_GAME_IMPL" - else - echo " ❌ Warning: Could not verify game type was added. Check transaction status." - fi - - echo " ✅ AddGameType operations completed successfully" - - # Set the newly added game type as respected - echo "" - set_respected_game_type "$GAME_TYPE" -} - -# Function to add game type via Transactor -add_game_type_via_transactor() { - local GAME_TYPE=$1 - local IS_PERMISSIONED=$2 - local CLOCK_EXTENSION_VAL=$3 - local MAX_CLOCK_DURATION_VAL=$4 - local ABSOLUTE_PRESTATE_VAL=$5 - - echo "=== Adding Game Type $GAME_TYPE via Transactor ===" - echo "Game Type: $GAME_TYPE" - echo "Is Permissioned: $IS_PERMISSIONED" - echo "Clock Extension: $CLOCK_EXTENSION_VAL" - echo "Max Clock Duration: $MAX_CLOCK_DURATION_VAL" - echo "" - - docker run --rm \ - --network "$DOCKER_NETWORK" \ - -v "$(pwd)/$CONFIG_DIR:/deployments" \ - -w /app \ - "${OP_CONTRACTS_IMAGE_TAG}" \ - bash -c " - set -e - - # Get addresses from environment - RPC_URL=$L1_RPC_URL_IN_DOCKER - TRANSACTOR_ADDRESS=$TRANSACTOR - SENDER_ADDRESS=\$(cast wallet address --private-key $ADMIN_OWNER_PRIVATE_KEY) - PRIVATE_KEY=$ADMIN_OWNER_PRIVATE_KEY - - # Get addresses from environment variables - SYSTEM_CONFIG=$SYSTEM_CONFIG_PROXY_ADDRESS - PROXY_ADMIN=$PROXY_ADMIN - OPCM=$OPCM_IMPL_ADDRESS - DISPUTE_GAME_FACTORY=\$(cast call --rpc-url \$RPC_URL \$SYSTEM_CONFIG 'disputeGameFactory()(address)') - - echo 'State JSON Path: '\$STATE_JSON_PATH - echo 'Dispute Game Factory: '\$DISPUTE_GAME_FACTORY - echo 'System Config: '\$SYSTEM_CONFIG - echo 'Proxy Admin: '\$PROXY_ADMIN - echo 'OPCM: '\$OPCM - echo 'Transactor Address: '\$TRANSACTOR_ADDRESS - echo 'RPC URL: '\$RPC_URL - echo 'Sender Address: '\$SENDER_ADDRESS - echo '' - - # Retrieve existing permissioned game implementation for parameters - echo 'Retrieving permissioned game parameters...' - PERMISSIONED_GAME=\$(cast call --rpc-url \$RPC_URL \$DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' 1) - echo 'Permissioned Game Implementation: '\$PERMISSIONED_GAME - - if [ \"\$PERMISSIONED_GAME\" == \"0x0000000000000000000000000000000000000000\" ]; then - echo 'Error: No permissioned game found. Cannot retrieve parameters.' - exit 1 - fi - - # Retrieve parameters from existing permissioned game - ABSOLUTE_PRESTATE='$ABSOLUTE_PRESTATE_VAL' - MAX_GAME_DEPTH=\$(cast call --rpc-url \$RPC_URL \$PERMISSIONED_GAME 'maxGameDepth()') - SPLIT_DEPTH=\$(cast call --rpc-url \$RPC_URL \$PERMISSIONED_GAME 'splitDepth()') - VM=\$(cast call --rpc-url \$RPC_URL \$PERMISSIONED_GAME 'vm()(address)') - - echo 'Retrieved parameters:' - echo ' Absolute Prestate: '\$ABSOLUTE_PRESTATE - echo ' Max Game Depth: '\$MAX_GAME_DEPTH - echo ' Split Depth: '\$SPLIT_DEPTH - echo ' Clock Extension: '$CLOCK_EXTENSION_VAL' - echo ' Max Clock Duration: '$MAX_CLOCK_DURATION_VAL' - echo ' VM: '\$VM - echo '' - - # Set initial bond - INITIAL_BOND='80000000000000000' # 0.08 ETH in wei - - # Create unique salt mixer - SALT_MIXER='123' - - echo 'Creating addGameType calldata...' - - # Create calldata for addGameType function - ADDGAMETYPE_CALLDATA=\$(cast calldata 'addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[])' \ - \"[(\ - \\\"\$SALT_MIXER\\\",\ - \$SYSTEM_CONFIG,\ - \$PROXY_ADMIN,\ - 0x0000000000000000000000000000000000000000,\ - $GAME_TYPE,\ - \$ABSOLUTE_PRESTATE,\ - \$MAX_GAME_DEPTH,\ - \$SPLIT_DEPTH,\ - $CLOCK_EXTENSION_VAL,\ - $MAX_CLOCK_DURATION_VAL,\ - \$INITIAL_BOND,\ - \$VM,\ - $IS_PERMISSIONED\ - )]\") - echo 'AddGameType calldata: '\$ADDGAMETYPE_CALLDATA - echo '' - - # Create calldata for Transactor's DELEGATECALL function - echo 'Creating Transactor DELEGATECALL calldata...' - TRANSACTOR_CALLDATA=\$(cast calldata 'DELEGATECALL(address,bytes)' \$OPCM \$ADDGAMETYPE_CALLDATA) - - echo 'Transactor calldata: '\$TRANSACTOR_CALLDATA - echo '' - - # Execute the transaction through Transactor - echo 'Executing transaction via Transactor...' - echo 'Target: '\$TRANSACTOR_ADDRESS - echo 'RPC_URL: '\$RPC_URL - - cast send \\ - --rpc-url \$RPC_URL \\ - --private-key \$PRIVATE_KEY \\ - --from \$SENDER_ADDRESS \\ - \$TRANSACTOR_ADDRESS \\ - \$TRANSACTOR_CALLDATA - - echo '' - echo 'Transaction sent! Check the transaction hash above for confirmation.' - echo '' - - # Verify the new game type was added - echo 'Verifying new game type was added...' - NEW_GAME_IMPL=\$(cast call --rpc-url \$RPC_URL \$DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' $GAME_TYPE) - - if [ \"\$NEW_GAME_IMPL\" != \"0x0000000000000000000000000000000000000000\" ] && [ \"\$NEW_GAME_IMPL\" != \"\$PERMISSIONED_GAME\" ]; then - echo '✅ Success! New game type $GAME_TYPE added.' - echo 'Game Type $GAME_TYPE Implementation: '\$NEW_GAME_IMPL - else - echo '❌ Warning: Could not verify game type was added. Check transaction status.' - fi - - echo '✅ AddGameType operations completed successfully' - " -} - -add_permissioned_game_type() { - echo "Adding game type to DisputeGameFactory via op-deployer..." - - # Retrieve existing values from chain for reference - # Get permissioned game implementation - PERMISSIONED_GAME_RAW=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameImpls(uint32)" 1) - # Convert 32-byte hex to 20-byte address (last 40 hex chars, with 0x prefix) - PERMISSIONED_GAME="0x${PERMISSIONED_GAME_RAW: -40}" - - MAX_GAME_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "maxGameDepth()") - SPLIT_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "splitDepth()") - VM_RAW=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "vm()") - VM="0x${VM_RAW: -40}" - ANCHOR_STATE_REGISTRY=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "anchorStateRegistry()") - L2_CHAIN_ID=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "l2ChainId()") - - # Call the function to add game type 1 (permissioned) via Transactor - add_game_type_via_transactor 1 true $TEMP_CLOCK_EXTENSION $TEMP_MAX_CLOCK_DURATION $ABSOLUTE_PRESTATE - export GAME_TYPE=1 -} - -wait_op_proposer_create_game() { - - echo "Waiting for op-proposer to create a game..." - ${DOCKER_COMPOSE_CMD} up -d op-proposer - - GAME_CREATED=false - MAX_WAIT_TIME=600 # 10 minutes timeout - WAIT_COUNT=0 - - while [ "$GAME_CREATED" = false ] && [ $WAIT_COUNT -lt $MAX_WAIT_TIME ]; do - # Check if a game was created by op-proposer - GAME_COUNT=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameCount()(uint256)") - if [ "$GAME_COUNT" -gt 0 ]; then - echo "✅ Game created! Game count: $GAME_COUNT" - GAME_CREATED=true - else - echo "⏳ Waiting for game creation... ($WAIT_COUNT/$MAX_WAIT_TIME seconds)" - sleep 1 - WAIT_COUNT=$((WAIT_COUNT + 1)) - fi - done - - if [ "$GAME_CREATED" = false ]; then - echo "❌ Timeout waiting for game creation" - exit 1 - fi - - echo "🛑 Stopping op-proposer..." - ${DOCKER_COMPOSE_CMD} stop op-proposer - -} - -fetch_and_set_latest_game_address() { - echo "get game address" -# echo "🔧 Executing dispute resolution sequence using op-challenger..." - GAME_COUNT=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameCount()(uint256)") - # Get the latest game address - LATEST_GAME_INDEX=$((GAME_COUNT - 1)) - GAME_INFO=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameAtIndex(uint256)(uint256,uint256,address)" $LATEST_GAME_INDEX) - # Extract the third value (address) from the returned tuple - address is the last 40 hex chars - GAME_ADDRESS="0x${GAME_INFO: -40}" - echo "Latest game address: $GAME_ADDRESS" -} - -resolve_claim() { - # Execute the dispute resolution sequence using op-challenger commands - echo "1. Resolving claim (0,0) using op-challenger..." - docker run --rm \ - --network "$DOCKER_NETWORK" \ - -v "$(pwd)/data/cannon-data:/data" \ - -v "$(pwd)/config-op/rollup.json:/rollup.json" \ - -v "$(pwd)/config-op/genesis.json:/l2-genesis.json" \ - "${OP_STACK_IMAGE_TAG}" \ - /app/op-challenger/bin/op-challenger resolve-claim \ - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} \ - --private-key=${OP_CHALLENGER_PRIVATE_KEY} \ - --game-address=$GAME_ADDRESS \ - --claim=0 -} - -resolve_game() { - echo "2. Resolving game using op-challenger..." - docker run --rm \ - --network "$DOCKER_NETWORK" \ - -v "$(pwd)/data/cannon-data:/data" \ - -v "$(pwd)/config-op/rollup.json:/rollup.json" \ - -v "$(pwd)/config-op/genesis.json:/l2-genesis.json" \ - "${OP_STACK_IMAGE_TAG}" \ - /app/op-challenger/bin/op-challenger resolve \ - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} \ - --private-key=${OP_CHALLENGER_PRIVATE_KEY} \ - --game-address=$GAME_ADDRESS -} - -claim_credit() { - echo "3. Claiming credit for proposer using cast command..." - docker run --rm \ - --network "$DOCKER_NETWORK" \ - "${OP_STACK_IMAGE_TAG}" \ - cast send \ - --rpc-url ${L1_RPC_URL_IN_DOCKER} \ - --private-key ${OP_CHALLENGER_PRIVATE_KEY} \ - $GAME_ADDRESS \ - "claimCredit(address)" \ - $PROPOSER_ADDRESS - echo "✅ Dispute resolution sequence completed using op-challenger commands!" -} - -set_game_type_permissionless() { - # Retrieve existing values from chain for reference - # Get permissioned game implementation - PERMISSIONED_GAME_RAW=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDRESS "gameImpls(uint32)" 1) - # Convert 32-byte hex to 20-byte address (last 40 hex chars, with 0x prefix) - PERMISSIONED_GAME="0x${PERMISSIONED_GAME_RAW: -40}" - # - ABSOLUTE_PRESTATE=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "absolutePrestate()") - ANCHOR_STATE_REGISTRY=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME "anchorStateRegistry()") - - # Call the function to add game type 0 (permissionless) via Transactor or Safe - # Script is being executed directly - choose function based on OWNER_TYPE - if [ "$OWNER_TYPE" = "safe" ]; then - add_game_type_via_safe 0 false $CLOCK_EXTENSION $MAX_CLOCK_DURATION $ABSOLUTE_PRESTATE - elif [ "$OWNER_TYPE" = "transactor" ]; then - add_game_type_via_transactor 0 false $CLOCK_EXTENSION $MAX_CLOCK_DURATION $ABSOLUTE_PRESTATE - else - echo "Error: Invalid OWNER_TYPE '$OWNER_TYPE'" - exit 1 - fi - - docker run --rm \ - --network "$DOCKER_NETWORK" \ - -v "$(pwd)/$CONFIG_DIR:/deployments" \ - -w /app \ - "${OP_CONTRACTS_IMAGE_TAG}" \ - bash -c " - set -e - - echo '📋 Gathering contract addresses and generating calldata...' - DISPUTE_GAME_FACTORY_ADDR=\$(cast call --rpc-url $L1_RPC_URL_IN_DOCKER $SYSTEM_CONFIG_PROXY_ADDRESS 'disputeGameFactory()(address)') - OPTIMISM_PORTAL_ADDR=\$(cast call --rpc-url $L1_RPC_URL_IN_DOCKER $SYSTEM_CONFIG_PROXY_ADDRESS 'optimismPortal()(address)') - echo 'disputeGameFactory: '\$DISPUTE_GAME_FACTORY_ADDR - echo 'optimismPortal: '\$OPTIMISM_PORTAL_ADDR - - # Get anchorStateRegistry address with proper return type specification - ANCHOR_STATE_REGISTRY_ADDR=\$(cast call --rpc-url $L1_RPC_URL_IN_DOCKER \$OPTIMISM_PORTAL_ADDR 'anchorStateRegistry()(address)') - echo 'anchorStateRegistry: '\$ANCHOR_STATE_REGISTRY_ADDR - - GAME_ADDR=\$(cast call --rpc-url $L1_RPC_URL_IN_DOCKER \$DISPUTE_GAME_FACTORY_ADDR 'gameImpls(uint32)(address)' 0) - echo 'gameImpls(0): '\$GAME_ADDR - - cast send \$ANCHOR_STATE_REGISTRY_ADDR 'setRespectedGameType(uint32)' 0 --rpc-url $L1_RPC_URL_IN_DOCKER --private-key $ADMIN_OWNER_PRIVATE_KEY - - echo '✅ setRespectedGameType completed successfully' - " - - export GAME_TYPE=0 -} - -add_permissioned_game_type -wait_op_proposer_create_game -# -#echo "⏰ Sleeping for ($TEMP_MAX_CLOCK_DURATION seconds)..." -#sleep $TEMP_MAX_CLOCK_DURATION -# -#fetch_and_set_latest_game_address -#resolve_claim -#resolve_game -# -#sleep $DISPUTE_GAME_FINALITY_DELAY_SECONDS -#claim_credit -# -#set_game_type_permissionless -# -sleep $TEMP_GAME_WINDOW -${DOCKER_COMPOSE_CMD} up -d op-proposer op-challenger op-dispute-mon diff --git a/test-pp-op/8-prepare-tests.sh b/test-pp-op/8-prepare-tests.sh deleted file mode 100755 index 8f3dd154bc382..0000000000000 --- a/test-pp-op/8-prepare-tests.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -set -e - -source .env - - -echo "=== Preparing test; Funding L1 Admin Address===" -L1_ADMIN_ADDRESS="0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" -L1_ADMIN_PRIVATE_KEY="0x815405dddb0e2a99b12af775fd2929e526704e1d1aea6a0b4e74dc33e2f7fcd2" -cast send --rpc-url $L1_RPC_URL $L1_ADMIN_ADDRESS --private-key $RICH_L1_PRIVATE_KEY --value 1000ether - -echo "=== Bridging ETH from L1 to L2 ===" - -# Bridge contract addresses -OPTIMISM_PORTAL=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'optimismPortal()(address)') -RECIPIENT="0x14dC79964da2C08b23698B3D3cc7Ca32193d9955" # Default Rich Address -PRIVATE_KEY="0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356" # Default Rich Private Key - -echo "OPTIMISM PORTAL Address: $OPTIMISM_PORTAL" -echo "Recipient: $RECIPIENT" -cast balance $RECIPIENT --rpc-url $L2_RPC_URL -echo "Bridging 1 ETH from L1 to L2..." - -# Bridge 1 ETH to L2 -cast send $OPTIMISM_PORTAL \ - --rpc-url $L1_RPC_URL \ - --private-key $PRIVATE_KEY \ - --value 100ether - -cast send $OPTIMISM_PORTAL \ - --rpc-url $L1_RPC_URL \ - --private-key $L1_ADMIN_PRIVATE_KEY \ - --value 100ether - - - -echo -e "\nWaiting for bridging to complete..." - -echo "Checking L2 balance for $RECIPIENT:" -BALANCE=$(cast balance $RECIPIENT --rpc-url $L2_RPC_URL) -ADMIN_BALANCE=$(cast balance $L1_ADMIN_ADDRESS --rpc-url $L2_RPC_URL) - -WAIT_COUNT=0 -while [ $BALANCE == 0 ] || [ $ADMIN_BALANCE == 0 ]; do - WAIT_COUNT=$((WAIT_COUNT + 1)) - echo " ⏳ Waiting for bridge transactions to finalize... (${WAIT_COUNT})" - echo " Current L2 balance: $(cast --to-unit $BALANCE ether) ETH" - echo " Current Admin balance: $(cast --to-unit $ADMIN_BALANCE ether) ETH" - sleep 5 - BALANCE=$(cast balance $RECIPIENT --rpc-url $L2_RPC_URL) - ADMIN_BALANCE=$(cast balance $L1_ADMIN_ADDRESS --rpc-url $L2_RPC_URL) -done - -echo " ✅ Bridging complete!" -echo " Final L2 balance: $(cast --to-unit $BALANCE ether) ETH" -echo " Final Admin balance: $(cast --to-unit $ADMIN_BALANCE ether) ETH" diff --git a/test-pp-op/Makefile b/test-pp-op/Makefile deleted file mode 100644 index e3bcf091c2529..0000000000000 --- a/test-pp-op/Makefile +++ /dev/null @@ -1,204 +0,0 @@ --include .env -export - -ifeq ($(ENV),local) - COMPOSE_FILE := docker-compose-local.yml - include local.env -else - COMPOSE_FILE := docker-compose.yml - include testnet.env -endif - -DOCKER_COMPOSE := $(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose") -f ${COMPOSE_FILE} - -RUN_DOCKER_MOCK_L1_NETWORK := $(DOCKER_COMPOSE) up -d xlayer-mock-l1-network - -PAUSE := $(DOCKER_COMPOSE) down --remove-orphans; \ - sleep 3; \ - rm -Rf ./l1-geth/consensus/beacondata; \ - rm -Rf ./l1-geth/consensus/validatordata; \ - rm -Rf ./l1-geth/consensus/genesis.ssz; \ - rm -Rf ./l1-geth/execution/geth; \ - rm -Rf ./config-op/artifact.json; \ - rm -Rf ./config-op/31337-deploy.json; \ - rm -Rf ./config-op/genesis.json; \ - rm -Rf ./config-op/rollup.json; \ - rm -Rf ./config-op/state_dump.json; \ - rm -Rf ./l1-geth/execution/genesis.json; \ - rm -Rf ./config-op/genesis-op-raw.json; \ - rm -Rf ./config-op/superchain.json; \ - rm -Rf ./config-op/implementations.json; \ - - -DEPLOY_ERC20_L1 := cd contracts && forge create OKBToken.sol:StandardERC20 --private-key $(SEQUENCER_PRIVATE_KEY) --rpc-url $(L1_RPC_URL) --legacy --broadcast --constructor-args "OKBToken" "OKB" 1000000000 -INIT_ACCOUNT_1 := cast send -f $(SEQUENCER_ADDRESS) --private-key $(SEQUENCER_PRIVATE_KEY) --value 1000ether $(DEPLOYER_ADDRESS) --legacy --rpc-url $(L1_RPC_URL) -INIT_ACCOUNT_2 := cast send -f $(SEQUENCER_ADDRESS) --private-key $(SEQUENCER_PRIVATE_KEY) --value 1000ether $(AGGREGATOR_ADDRESS) --legacy --rpc-url $(L1_RPC_URL) -INIT_ACCOUNT_3 := cast send -f $(SEQUENCER_ADDRESS) --private-key $(SEQUENCER_PRIVATE_KEY) --value 1000ether $(RICH_ADDRESS) --legacy --rpc-url $(L1_RPC_URL) -INIT_ACCOUNT_4 := cast send -f $(SEQUENCER_ADDRESS) --private-key $(SEQUENCER_PRIVATE_KEY) --value 1000ether $(CHALLENGER_ADDRESS) --legacy --rpc-url $(L1_RPC_URL) - -INIT_BRIDGE_ACCOUNT := cast send -f $(DEPLOYER_ADDRESS) --private-key $(DEPLOYER_PRIVATE_KEY) --value 0.01ether $(SEQUENCER_ADDRESS) --legacy --rpc-url $(L2_ERIGON_RPC_URL) - -.PHONY: set-env -set-env: - @if [ "$(ENV)" = "local" ]; then \ - if [ -f local.env ]; then \ - cp local.env .env; \ - echo "Using local.env -> .env"; \ - else \ - echo "local.env not found"; \ - exit 1; \ - fi; \ - fi - -.PHONY: show-env -show-env: - @echo "Current ENV: $(ENV)" - @echo "Using compose file: $(COMPOSE_FILE)" - -.PHONY: run_erigon -run_erigon: set-env show-env - @echo "🚀 Starting L1 PoS environment automatic dependency management..." - $(DOCKER_COMPOSE) up -d l1-validator - @echo "🎉 L1 PoS environment started!" - sleep 30 - $(DEPLOY_ERC20_L1) - $(INIT_ACCOUNT_1) - $(INIT_ACCOUNT_2) - $(INIT_ACCOUNT_3) - $(INIT_ACCOUNT_4) - sleep 5 - ./init-erigon.sh - sleep 5 - $(DOCKER_COMPOSE) up -d xlayer-bridge-db - $(DOCKER_COMPOSE) up -d xlayer-pool-db - sleep 5 - $(DOCKER_COMPOSE) up -d xlayer-agglayer-prover - $(DOCKER_COMPOSE) up -d xlayer-agglayer - sleep 5 - - sleep 3 - $(DOCKER_COMPOSE) up -d xlayer-approve - $(DOCKER_COMPOSE) up -d xlayer-seq - $(DOCKER_COMPOSE) up -d xlayer-pool-manager - - sleep 5 - $(DOCKER_COMPOSE) up -d xlayer-rpc - - sleep 10 - $(DOCKER_COMPOSE) up -d xlayer-bridge-service - $(DOCKER_COMPOSE) up -d xlayer-bridge-ui - $(INIT_BRIDGE_ACCOUNT) - - $(DOCKER_COMPOSE) up -d xlayer-agg-sender - -.PHONY: mainnet -mainnet: - @echo "🚀 Starting XLayer Fake Mainnet ..." - $(DOCKER_COMPOSE) up -d l1-validator - sleep 20 - $(INIT_ACCOUNT_1) - $(INIT_ACCOUNT_2) - $(INIT_ACCOUNT_3) - $(INIT_ACCOUNT_4) - $(DOCKER_COMPOSE) up -d xlayer-mainnet-seq - sleep 5 - $(DOCKER_COMPOSE) up -d xlayer-rpc - -.PHONY: build-docker -build-docker: ## build images for all - ./build_images.sh --all - -.PHONY: build-force -build-force: ## Force rebuild all images - ./build_images.sh --all --force - -.PHONY: build-op-geth -build-op-geth: ## Build op-geth image only - ./build_images.sh --op-geth - -.PHONY: build-op-stack -build-op-stack: ## Build op-stack images only - ./build_images.sh --op-stack - -.PHONY: build-cdk-erigon -build-cdk-erigon: - ./build_images.sh --cdk-erigon - -.PHONY: pause -pause: ## Stops all services - $(PAUSE) - -.PHONY: stop -stop: pause - rm -rf data - -.PHONY: clean -clean: stop - rm -rf data - rm -rf config-op/genesis.json - rm -rf config-op/genesis.json.gz - rm -rf config-op/implementations.json - rm -rf config-op/intent.toml - rm -rf config-op/rollup.json - rm -rf config-op/state.json - rm -rf config-op/superchain.json - rm -rf config-op/genesis-op-before-number.json - rm -rf config-op/genesis-op-after-number.json - rm -rf config-op/merged.genesis.gz.json - rm -rf config-op/196-* - rm -rf config-op/195-* - rm -rf config-op/1952-* - rm -rf l1-geth/consensus/beacondata/ - rm -rf l1-geth/consensus/genesis.ssz - rm -rf l1-geth/consensus/validatordata/ - rm -rf l1-geth/execution/genesis.json - rm -rf l1-geth/execution/geth/ - rm -rf merged.genesis.json - rm -rf migrate.log - rm -rf .env - -.PHONY: run -run: stop - @mkdir -p tmp - @echo "OP_GETH_BRANCH: $(OP_GETH_BRANCH)" - @if [ -n "$(OP_GETH_BRANCH)" ]; then \ - echo "Initializing with branch: $(OP_GETH_BRANCH)"; \ - ./init.sh $(OP_GETH_BRANCH); \ - else \ - echo "Initializing with default branch"; \ - ./init.sh; \ - fi - ./0-all.sh - -.PHONY: run-test -run-test: - @echo "OP_GETH_LOCAL_DIRECTORY: $$OP_GETH_LOCAL_DIRECTORY" - @echo "OP_GETH_BRANCH: $(OP_GETH_BRANCH)" - @if [ -n "$$OP_GETH_LOCAL_DIRECTORY" ]; then \ - echo "Using custom local directory: $$OP_GETH_LOCAL_DIRECTORY"; \ - cd "$$OP_GETH_LOCAL_DIRECTORY"; \ - else \ - echo "Using default submodule: ../op-geth"; \ - cd ../op-geth; \ - fi && \ - if [ -n "$(OP_GETH_BRANCH)" ]; then \ - echo "Switching to branch: $(OP_GETH_BRANCH)"; \ - git fetch origin && git checkout "$(OP_GETH_BRANCH)" && git pull origin "$(OP_GETH_BRANCH)"; \ - else \ - echo "Using current branch"; \ - fi && \ - echo "Running E2E tests..."; \ - MallocNanoZone=0 go test -count=1 -failfast -race -v -p 1 -timeout 600s ./test/e2e/... - -.PHONY: test-e2e -test-e2e: stop - @trap 'make stop' EXIT ERR INT TERM; - @echo "OP_GETH_BRANCH: $(OP_GETH_BRANCH)" - if [ -n "$(OP_GETH_BRANCH)" ]; then \ - echo "Running E2E tests with branch: $(OP_GETH_BRANCH)"; \ - make run && sleep 3 && make run-test; \ - else \ - echo "Running E2E tests with default branch"; \ - make run && sleep 3 && make run-test; \ - fi && echo "✅ E2E tests passed ✅" - diff --git a/test-pp-op/README.md b/test-pp-op/README.md deleted file mode 100644 index 7375b653a7204..0000000000000 --- a/test-pp-op/README.md +++ /dev/null @@ -1,393 +0,0 @@ -# Optimism Test Environment Setup Guide - -## run on local -```bash -# git submodule update --recursive --force -make clean -cp local.env .env -# ./build_images.sh --all # build all images. add --force if want to force rebuild -./1-start-erigon.sh -./2-deploy-op-contracts.sh -./3-stop-erigon.sh -./4-migrate-op.sh -./5-start-op.sh -./6-build-op-program.sh -./7-setup-fraud-proof.sh -``` - -## run on testnet -```bash -make clean - -cp testnet.env .env -./m1-deploy-and-upload.sh - -# Upload with md5 hash -osstool -f upload-to-oss.tar.gz -a upload -ticket ${TICKET_ID} - - -# Download to ECS machine -osstool -a download -ticket ${TICKET_ID} - -# Unzip -tar -xzvf upload-to-oss.tar.gz -cd upload-to-oss - -# On ECS machine, just run and follow prompts. -./m2-migrate.sh -``` - -## Prerequisites - -### System Requirements -- Docker 20.10.0 or higher -- Docker Compose -- At least 32GB RAM -- At least 32GB available disk space - -> **Important**: If you encounter performance issues, increase Docker engine memory limit to over 32GB -> ![issue](./images/stuck.png) -> ![solution](./images/docker.png) - -### Initial Setup (First Time Only) -1. Run `./init.sh` to initialize the environment (only needed once): - - Install all git submodules - - Build required Docker images - - Prepare base environment - -> Important: `init.sh` should only be run once during initial setup. Re-run only if you need to rebuild Docker images after code changes. - -### Code Updates and Image Rebuilding (Optional) -If you've updated the Optimism codebase and need to rebuild Docker images: - -1. **Update image tags** in `example.env`: - ```bash - # Example: increment version numbers - OP_GETH_IMAGE_TAG=op-geth:v1.101512.0-patch - OP_STACK_IMAGE_TAG=op-stack:v1.13.5 - OP_CONTRACTS_IMAGE_TAG=op-contracts:v1.13.5 - ``` - -2. **Apply changes**: - ```bash - ./clean.sh # This will update .env from example.env - ``` - -3. **Rebuild images**: - ```bash - ./init.sh # Rebuilds all Docker images - - # Or rebuild specific images only (optional) - source .env && cd .. && docker build -t ${OP_STACK_IMAGE_TAG} -f Dockerfile-opstack . && cd - - ``` - -### Directory Structure -``` -test/ -├── 0-all.sh # One-click deployment script -├── init.sh # Initialization script -├── clean.sh # Environment cleanup script -├── 1-start-l1.sh # L1 chain startup script -├── 2-deploy-op-contracts.sh # Contract deployment script -├── 3-op-init.sh # Environment initialization script -├── 4-op-start-service.sh # Service startup script -├── scripts/ # Utility scripts -│ ├── transfer_leader.sh # Leader transfer script -│ ├── stop_leader_sequencer.sh # Sequencer stop script -│ ├── active_sequencer.sh # Check active sequencer -│ ├── add_game_type.sh # Add dispute game type -│ ├── deposit-from-l1.sh # L1 to L2 deposit script -│ ├── deposit-from-banker.sh # transfer ETH from banker script -│ └── show-dev-accounts.sh # Display dev accounts info -├── config-op/ # Configuration directory -├── data/ # Data storage directory -├── contracts/ # Smart contracts -├── images/ # Documentation images -├── example.env # Environment template -``` - -## Quick Start - -### One-Click Deployment -Run `./0-all.sh` to automatically: -- Initialize the environment -- Start all required components -- Complete all configurations and deployments - -⚠️ **Important Notes**: - -1. Configuration Management: - - Always make configuration changes in `example.env` - - Never modify `.env` directly as it will be reset by `clean.sh` - - Run `clean.sh` to apply changes from `example.env` - -2. Environment Reset: - - `clean.sh` will stop all containers - - Clean all data directories - - Reset `.env` to values from `example.env` - -> Note: For first-time setup, we recommend following the step-by-step deployment process to better understand each component and troubleshoot any potential issues. - -### Step-by-Step Deployment -For more granular control or troubleshooting, follow the steps below. - -## Deployment Process - -### 1. L1 Environment Setup -Run `./1-start-l1.sh`: -- Starts a complete PoS L1 test chain (EL + CL) -- CL node handles blob data storage -- Automatically funds test accounts: - - Batcher - - Proposer - - Challenger - -### 2. Smart Contract Deployment -Run `./2-deploy-op-contracts.sh`: -- Deploys Transactor contract -- Deploys and initializes all Optimism L1 contracts -- Generates configuration files: - - `rollup.json`: op-node configuration - - `genesis.json`: L2 initial state - -### 3. Environment Initialization -Run `./3-op-init.sh`: -- Initializes op-geth database - - Sequencer node - - RPC node -- Generates dispute game components: - - Compiles op-program - - Generates prestate files - - Creates state proofs - -### 4. Service Startup -Run `./4-op-start-service.sh`: -- Launches core services: - - op-batcher: L2 transaction batch processing - - op-proposer: L2 state submission - - op-node: State sync and validation - - op-geth: L2 execution engine - - op-challenger: State validation - - op-dispute-mon: Dispute monitoring - - op-conductor: Sequencer HA management - -### 5. Conductor Management -The test environment includes a 3-node conductor cluster for sequencer high availability (HA). - -#### Architecture -- **Cluster Type**: 3-node Raft consensus cluster -- **Active Sequencer**: Only runs on leader node -- **Failover**: Automatic when leader becomes unhealthy -- **High Availability**: Ensures continuous L2 block production - -#### Configuration -Enable or disable conductor cluster in `example.env`: -```bash -# Enable HA mode with conductor cluster -CONDUCTOR_ENABLED=true - -# Disable HA, run single sequencer -CONDUCTOR_ENABLED=false -``` - -#### Network Ports -Each conductor node uses three ports: -- **RPC Port**: Management API - - Node 1: 8547 - - Node 2: 8548 - - Node 3: 8549 - -- **Consensus Port**: Raft protocol - - Node 1: 50050 - - Node 2: 50051 - - Node 3: 50052 - -- **Sequencer Port**: L2 execution - - Node 1: 9545 - - Node 2: 9546 - - Node 3: 9547 - -#### Health Monitoring -The conductor cluster monitors each node's: -- Sync status with L1 -- P2P network connectivity -- Block production rate - -When leader becomes unhealthy: -- Automatically transfers leadership -- Deactivates unhealthy sequencer -- Activates sequencer on new leader - -#### Leadership Management -There are two ways to trigger leader transfer: - -1. Using `transfer-leader.sh`: -```bash -# Auto transfer to any healthy node -./scripts/transfer-leader.sh - -# Transfer to specific node (1 or 2 or 3) -./scripts/transfer-leader.sh 2 -``` - -2. Force transfer by stopping leader's sequencer: -```bash -# Stops block production while keeping the container running -# Automatically triggers leader transfer after health check timeout -# Can be run multiple times to test different leadership scenarios -./scripts/stop-leader-sequencer.sh -``` - -This method simulates a sequencer failure scenario, enabling comprehensive testing of automatic failover mechanisms. Each execution stops the current leader's sequencer and triggers a transfer to another node, allowing you to test different leadership scenarios by running the script multiple times. The cluster maintains high availability through dynamic role switching - when a sequencer stops producing blocks, it transitions to follower status while another node assumes leadership. The system remains resilient as any follower can automatically promote to leader if the current leader encounters issues. - -3. Gray upgrade using op-conductor: -```bash -# Emulate the whole gray upgrade process to achieve 0 downtime -./scripts/gray-upgrade-simulation.sh -# Meanwhile, open another terminal window to load test -polycli loadtest --rpc-url http://localhost:8124 \ - --private-key "0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356" \ - --verbosity 700 --requests 50000 -c 1 --rate-limit -1 -``` - -The `scripts/gray-upgrade-simulation.sh` script simulates a rolling upgrade process for the sequencer cluster managed by op-conductor. It upgrades a follower sequencer while keeping the leader running, then transfers leadership to the upgraded node. This approach ensures service continuity and validates the cluster's resilience during upgrades. - -## Utility Scripts - -### L1 to L2 Deposit Script - -The `scripts/deposit-from-l1.sh` script facilitates testing L1 to L2 cross-chain deposits: - -#### Features -- **Automatic Deposit**: Deposits 3000 ETH from L1 to L2 -- **Balance Monitoring**: Monitors L2 balance changes in real-time -- **Wait Time Tracking**: Measures total deposit confirmation time -- **Status Updates**: Provides clear progress feedback - -#### Usage -```bash -# Run the deposit script -./scripts/deposit-from-l1.sh -``` - -#### What it does -1. **Funds Test Account**: Sends ETH to the test account on L1 -2. **Creates Deposit Transaction**: Calls OptimismPortal.depositTransaction() -3. **Monitors L2 Balance**: Continuously checks L2 balance until change detected -4. **Reports Results**: Shows deposit confirmation time and balance changes - -#### Configuration -The script uses these default parameters: -- **Deposit Amount**: 3000 ETH -- **Gas Limit**: 100,000 -- **Target Address**: Same as sender (self-deposit) -- **L2 RPC**: http://127.0.0.1:8123 - -This script is useful for: -- Testing cross-chain deposit functionality -- Measuring deposit confirmation times -- Verifying L1/L2 synchronization -- Validating OptimismPortal contract integration - -### Banker Account Deposit Script - -The `scripts/deposit-from-banker.sh` script enables large-scale testing using a banker account with massive balance: - -#### Features -- **Large Amount Transfers**: Transfers 1,000,000 ETH (1 million ETH) -- **Banker Account**: Uses a pre-funded account with astronomical balance -- **Simple Transfer**: Direct ETH transfer without cross-chain complexity -- **Legacy Transaction**: Uses legacy transaction format for compatibility - -#### Usage -```bash -# Run the banker deposit script -./scripts/deposit-from-banker.sh -``` - -#### What it does -1. **Uses Banker Account**: Leverages account `0x70997970C51812dc3A010C7d01b50e0d17dc79C8` -2. **Large Transfer**: Sends 1,000,000 ETH to target address -3. **Direct Transfer**: Simple ETH transfer on L2 network -4. **Legacy Format**: Uses legacy transaction format - -### Development Accounts Display Script - -The `scripts/show-dev-accounts.sh` script displays all development accounts with their private keys: - -#### Features -- **Account Listing**: Shows all 30 development accounts (paths 0-29) -- **Private Key Display**: Reveals private keys for testing -- **Address Generation**: Shows corresponding addresses -- **Mnemonic Path**: Displays derivation paths - -#### Usage -```bash -# Display all dev accounts -./scripts/show-dev-accounts.sh -``` - -#### What it does -1. **Generates Accounts**: Creates 30 accounts from standard mnemonic (paths 0-29) -2. **Shows Details**: Displays address, private key, and derivation path -3. **Standard Mnemonic**: Uses "test test test test test test test test test test test junk" -4. **Path Format**: Uses `m/44'/60'/0'/0/{i}` derivation paths - -#### Important Notes -- **Balance Status**: Most dev accounts are pre-funded with 10,000 ETH, but some accounts may have zero initial balance - -## Troubleshooting - -### Common Issues - -#### 1. Service Startup Failures -- **Check Docker logs**: `docker compose logs ` -- **Verify port availability**: Ensure ports 8545, 8546, 4000, 3500 are free -- **Validate environment variables**: Check `.env` file matches `example.env` -- **Memory issues**: Increase Docker memory limit to 32GB+ - -#### 2. Contract Deployment Issues -- **Verify L1 node is running**: Check `docker compose ps` -- **Check account balances**: Ensure test accounts have sufficient ETH -- **Validate gas settings**: Check gas limit and price in deployment logs - -#### 3. Synchronization Issues -- **L2 not syncing**: Check op-geth-seq is running and producing blocks -- **RPC node issues**: Verify op-geth-rpc can connect to op-geth-seq -- **Genesis mismatch**: Ensure rollup.json matches actual L2 genesis - -#### 4. Conductor Cluster Issues -- **Leader election problems**: Check Raft consensus logs -- **Sequencer not switching**: Verify health check configuration -- **P2P connectivity**: Check network configuration and firewall - -## Service Ports Overview - -| Service | Port | Description | -|---------|------|-------------| -| **L1 Services** | | | -| l1-geth | 8545 | L1 Ethereum RPC | -| l1-geth | 8546 | L1 Ethereum WebSocket | -| l1-geth | 8551 | L1 Ethereum Engine API | -| l1-beacon-chain | 4000 | L1 Beacon RPC | -| l1-beacon-chain | 3500 | L1 Beacon HTTP | -| l1-beacon-chain | 18080 | L1 Beacon Metrics | -| **L2 Services** | | | -| op-geth-seq | 8123 | L2 Sequencer RPC | -| op-geth-seq | 7546 | L2 Sequencer WebSocket | -| op-geth-seq | 8552 | L2 Sequencer Engine API | -| op-geth-rpc | 9123 | L2 RPC Node RPC | -| op-seq | 9545 | L2 Node RPC | -| op-seq | 7070 | L2 Node P2P | -| op-seq | 9223 | L2 Node P2P (UDP) | -| op-rpc | 9555 | L2 RPC Node RPC | -| **Conductor Cluster** | | | -| op-conductor | 8547 | Conductor 1 RPC | -| op-conductor | 50050 | Conductor 1 Consensus | -| op-conductor2 | 8548 | Conductor 2 RPC | -| op-conductor2 | 50051 | Conductor 2 Consensus | -| op-conductor3 | 8549 | Conductor 3 RPC | -| op-conductor3 | 50052 | Conductor 3 Consensus | -| **Other Services** | | | -| op-batcher | 8548 | Batcher RPC | -| op-proposer | 8560 | Proposer RPC | diff --git a/test-pp-op/build_images.sh b/test-pp-op/build_images.sh deleted file mode 100755 index bbaea9cd1c844..0000000000000 --- a/test-pp-op/build_images.sh +++ /dev/null @@ -1,297 +0,0 @@ -#!/bin/bash -set -e - -# ============================================================================= -# Build Images Script -# ============================================================================= -# This script builds Docker images for the OP-Geth project with support for -# selective building and force rebuilds. -# -# USAGE: -# ./build_images.sh [OPTIONS] -# -# OPTIONS: -# --op-geth Build op-geth image only -# --op-stack Build op-stack images only (contracts + opstack) -# --op-contract Build op-contracts images only -# --bridge Build bridge service image only -# --aggkit Build aggkit image only -# --all Build all images (default if no options specified) -# --force Force rebuild even if images exist -# -h, --help Show this help message -# -# EXAMPLES: -# ./build_images.sh # Build all images (default) -# ./build_images.sh --op-geth # Build op-geth only -# ./build_images.sh --op-stack # Build op-stack only -# ./build_images.sh --bridge # Build bridge service only -# ./build_images.sh --aggkit # Build aggkit only -# ./build_images.sh --all --force # Force rebuild all images -# ./build_images.sh --op-geth --force # Force rebuild op-geth only -# ./build_images.sh --help # Show help -# -# IMAGES BUILT: -# - OP-Geth: Ethereum client with OP Stack modifications -# - OP-Stack: Core OP Stack components (contracts + opstack) -# - Bridge Service: Patched zkevm-bridge-service -# - AggKit: OKX aggregation toolkit -# ============================================================================= - -source .env - -# Default values -ARCH=$(docker version --format '{{.Server.Os}}/{{.Server.Arch}}') -BUILD_CDK_ERIGON=false -BUILD_OP_GETH=false -BUILD_OP_GETH_MIGRATE=false -BUILD_OP_STACK=false -BUILD_OP_CONTRACT=false -BUILD_BRIDGE=false -BUILD_AGGKIT=false -BUILD_ALL=false -FORCE=false - -# Parse command line arguments -while [[ $# -gt 0 ]]; do - case $1 in - --cdk-erigon) - BUILD_CDK_ERIGON=true - shift - ;; - --op-geth) - BUILD_OP_GETH=true - shift - ;; - --op-geth-migrate) - BUILD_OP_GETH_MIGRATE=true - shift - ;; - --op-stack) - BUILD_OP_STACK=true - shift - ;; - --op-contract) - BUILD_OP_CONTRACT=true - shift - ;; - --bridge) - BUILD_BRIDGE=true - shift - ;; - --aggkit) - BUILD_AGGKIT=true - shift - ;; - --all) - BUILD_ALL=true - shift - ;; - --force) - FORCE=true - shift - ;; - --arch) - echo "ARCH: $2" - ARCH="$2" - shift 2 - ;; - -h|--help) - echo "Usage: $0 [OPTIONS]" - echo "Options:" - echo " --cdk-erigon Build cdk-erigon image only" - echo " --op-geth Build op-geth image only" - echo " --op-geth-migrate Build op-geth-migrate image only" - echo " --op-stack Build op-stack images" - echo " --op-contract Build op contract image" - echo " --bridge Build bridge service image only" - echo " --aggkit Build aggkit image only" - echo " --all Build all images (default if no options specified)" - echo " --force Force rebuild even if images exist" - echo " -h, --help Show this help message" - exit 0 - ;; - *) - echo "Unknown option: $1" - echo "Use --help for usage information" - exit 1 - ;; - esac -done - -# If no specific options provided, build all -if [ "$BUILD_OP_GETH" = false ] && [ "$BUILD_CDK_ERIGON" = false ] && [ "$BUILD_OP_STACK" = false ] && [ "$BUILD_OP_CONTRACT" = false ] && [ "$BUILD_BRIDGE" = false ] && [ "$BUILD_AGGKIT" = false ] && [ "$BUILD_OP_GETH_MIGRATE" = false ] && [ "$BUILD_ALL" = false ]; then - BUILD_ALL=true -fi - -# If --all is specified, set all flags -if [ "$BUILD_ALL" = true ]; then - BUILD_CDK_ERIGON=true - BUILD_OP_GETH=true - BUILD_OP_GETH_MIGRATE=true - BUILD_OP_STACK=true - BUILD_OP_CONTRACT=true - BUILD_BRIDGE=true - BUILD_AGGKIT=true -fi - -build_patched_zkevm_bridge_service_image() { - echo "build patched zkevm bridge service image" - PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - rm -rf $PWD_DIR/tmp/zkevm-bridge-service - mkdir -p $PWD_DIR/tmp - cd $PWD_DIR/tmp/ - git clone -b v0.6.0-RC16 https://github.com/0xPolygon/zkevm-bridge-service.git - # it has docker file - cd zkevm-bridge-service - - # patch zkevm-bridge-service - git apply $PWD_DIR/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch - git apply $PWD_DIR/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch - git apply $PWD_DIR/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch - - docker build --platform $ARCH -t $XLAYER_BRIDGE_SERVICE_IMAGE_TAG . - cd $PWD_DIR -} - -build_aggkit_image() { - echo "build aggkit image" - PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - rm -rf $PWD_DIR/tmp/aggkit - mkdir -p $PWD_DIR/tmp - cd $PWD_DIR/tmp/ - - echo "Cloning contract repository..." - git clone -b feature/0.1.0 https://github.com/okx/aggkit.git - cd ./aggkit - echo "Cleaning and resting contract repository..." - git reset --hard; git checkout feature/0.1.0;git pull - make build-docker - cd $PWD_DIR -} - -build_cdk_erigon_image() { - echo "build cdk_erigon image" - PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - rm -rf $PWD_DIR/tmp/xlayer-erigon - mkdir -p $PWD_DIR/tmp - cd $PWD_DIR/tmp/ - - echo "Cloning cdk-erigon repository..." - git clone -b dev https://github.com/okx/xlayer-erigon.git - cd ./xlayer-erigon - git reset --hard; git checkout dev;git pull - docker build --platform $ARCH -t ${CDK_ERIGON_IMAGE_TAG} -f ./Dockerfile.local . - cd $PWD_DIR -} - -build_op_stack_contract() { - echo "build op stack image" - PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - - cd .. - docker build $( [ "$FORCE" = true ] && echo --no-cache ) --platform $ARCH -t $OP_CONTRACTS_IMAGE_TAG -f Dockerfile-contracts . - - cd $PWD_DIR - -} - -build_op_stack_image() { - echo "build op stack image" - # Check if op_contract image exists - if ! image_exists "$OP_CONTRACTS_IMAGE_TAG"; then - echo "Error: OP contracts image ($OP_CONTRACTS_IMAGE_TAG) does not exist." - echo "Please build the contracts image first using --op-contract or --all" - exit 1 - fi - - PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - - cd .. - docker tag "$OP_CONTRACTS_IMAGE_TAG" "op-contracts:latest" - docker build --platform $ARCH -t $OP_STACK_IMAGE_TAG -f Dockerfile-opstack . - docker tag "op-contracts:latest" "$OP_CONTRACTS_IMAGE_TAG" - - cd $PWD_DIR -} - -build_op_geth_migrate_image() { - echo "build op-geth image" - PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - PROJECT_ROOT="$(git rev-parse --show-toplevel)" - - # If tmp/optimism doesn't exist, clone it - if [ ! -d "$PWD_DIR/tmp/op-geth" ]; then - rm -rf $PWD_DIR/tmp/op-geth - mkdir -p $PWD_DIR/tmp - cd $PWD_DIR/tmp/ - echo "Cloning op-geth repository..." - git clone --recurse-submodules -b dev-op https://github.com/okx/op-geth.git - cd $PWD_DIR - fi - - # Must build at test-pp-op to copy config files (eg. .env) over as well. - docker build --platform $ARCH -t $OP_GETH_MIGRATION_IMAGE_TAG --progress=plain --no-cache -f dockerfile/Dockerfile.migrate . - # cd "$PWD_DIR/tmp/op-geth" - # docker build --platform $ARCH -t $OP_GETH_MIGRATION_IMAGE_TAG . - cd $PWD_DIR -} - -build_op_geth_image() { - echo "build op-geth image" - PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - - cd ../op-geth - docker build $( [ "$FORCE" = true ] && echo --no-cache ) --platform $ARCH -t $OP_GETH_IMAGE_TAG . - cd $PWD_DIR -} - -# Helper function to check if image exists -image_exists() { - local image_tag=$1 - docker image inspect "$image_tag" >/dev/null 2>&1 -} - -# Helper function to build if needed -build_if_needed() { - local image_tag=$1 - local build_function=$2 - local description=$3 - - if [ "$FORCE" = true ] || ! image_exists "$image_tag"; then - echo "Building $description..." - $build_function - else - echo "Image $image_tag already exists (use --force to rebuild)" - fi -} - -# Build images based on selected options -if [ "$BUILD_OP_CONTRACT" = true ]; then - build_if_needed "$OP_CONTRACTS_IMAGE_TAG" "build_op_stack_contract" "OP Stack contracts" -fi - -if [ "$BUILD_OP_STACK" = true ]; then - build_if_needed "$OP_STACK_IMAGE_TAG" "build_op_stack_image" "OP Stack image" -fi - -if [ "$BUILD_OP_GETH" = true ]; then - build_if_needed "$OP_GETH_IMAGE_TAG" "build_op_geth_image" "OP-Geth image" -fi - -if [ "$BUILD_OP_GETH_MIGRATE" = true ]; then - build_if_needed "$OP_GETH_MIGRATION_IMAGE_TAG" "build_op_geth_migrate_image" "OP-Geth migrate image" -fi - -if [ "$BUILD_CDK_ERIGON" = true ]; then - build_if_needed "$CDK_ERIGON_IMAGE_TAG" "build_cdk_erigon_image" "cdk-erigon image" -fi - -if [ "$BUILD_BRIDGE" = true ]; then - build_if_needed "$XLAYER_BRIDGE_SERVICE_IMAGE_TAG" "build_patched_zkevm_bridge_service_image" "patched zkevm bridge service" -fi - -if [ "$BUILD_AGGKIT" = true ]; then - build_if_needed "aggkit:local" "build_aggkit_image" "aggkit" -fi - -echo "Build completed!" diff --git a/test-pp-op/config-op/intent.fakemainnet.toml.bak b/test-pp-op/config-op/intent.fakemainnet.toml.bak deleted file mode 100644 index d423adaa5a5e3..0000000000000 --- a/test-pp-op/config-op/intent.fakemainnet.toml.bak +++ /dev/null @@ -1,35 +0,0 @@ -configType = "standard-overrides" -l1ChainID = 11155111 -fundDevAccounts = false -opcmAddress = "0x0000000000000000000000000000000000000000" -l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" -l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" - -[[chains]] - id = "0x00000000000000000000000000000000000000000000000000000000000000C4" - baseFeeVaultRecipient = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" - l1FeeVaultRecipient = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" - sequencerFeeVaultRecipient = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" - eip1559DenominatorCanyon = 100000000 - eip1559Denominator = 100000000 - eip1559Elasticity = 1 - operatorFeeScalar = 0 - operatorFeeConstant = 0 - gasLimit = 50000000 - [chains.deployOverrides] - l2GenesisBlockGasLimit = "0x2faf080" - l2GenesisBlockBaseFeePerGas = "0x5FC01C5" - l2BlockTime = 1 - [chains.customGasToken] - enabled = true - name = "OKB" - symbol = "OKB" - initialLiquidity = "0x0" - [chains.roles] - l1ProxyAdminOwner = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" - l2ProxyAdminOwner = "0x27a6a7B5E972aC6D0e7A12BdA1ffAD37Dc7777A2" - systemConfigOwner = "0x1183f158515091c94188C13Cd16923cee663d4c4" - unsafeBlockSigner = "0xe44FaF74D0EA83D962BB8cE077F69e449c6D8c4a" - batcher = "0x02E0eF87B04FD60E7F2215D1932420a80Cc35c55" - proposer = "0xe43944421681170648e10007f73816e04f74394f" - challenger = "0x736e68af2cbf2ab0e46e4310fe5ae568b3642ff6" diff --git a/test-pp-op/config-op/intent.local.toml.bak b/test-pp-op/config-op/intent.local.toml.bak deleted file mode 100644 index 3265223ca8fd1..0000000000000 --- a/test-pp-op/config-op/intent.local.toml.bak +++ /dev/null @@ -1,36 +0,0 @@ -configType = "standard-overrides" -l1ChainID = 1337 -fundDevAccounts = true -opcmAddress = "0x0000000000000000000000000000000000000000" -l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" -l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" - -[[chains]] - id = "0x00000000000000000000000000000000000000000000000000000000000000c3" - baseFeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - l1FeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - sequencerFeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - eip1559DenominatorCanyon = 250 - eip1559Denominator = 50 - eip1559Elasticity = 6 - operatorFeeScalar = 0 - operatorFeeConstant = 0 - gasLimit = 30000000 - minBaseFee = 1000000 - [chains.deployOverrides] - l2GenesisBlockGasLimit = "0xbebc200" - l2GenesisBlockBaseFeePerGas = "0x3B9ACA00" - l2BlockTime = 1 - [chains.customGasToken] - enabled = true - name = "OKB" - symbol = "OKB" - initialLiquidity = "0x0" - [chains.roles] - l1ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - l2ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - systemConfigOwner = "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" - unsafeBlockSigner = "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc" - batcher = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" - proposer = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" - challenger = "0x7d18A1B858253b5588f61fb5739d52e4b84e2cdA" diff --git a/test-pp-op/config-op/intent.mainnet.toml.bak b/test-pp-op/config-op/intent.mainnet.toml.bak deleted file mode 100644 index 8c2059f99af90..0000000000000 --- a/test-pp-op/config-op/intent.mainnet.toml.bak +++ /dev/null @@ -1,36 +0,0 @@ -configType = "standard-overrides" -l1ChainID = 1 -fundDevAccounts = false -opcmAddress = "0x0000000000000000000000000000000000000000" -l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" -l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" - -[[chains]] - id = "0x00000000000000000000000000000000000000000000000000000000000000C4" - baseFeeVaultRecipient = "0x610DE9141a2c51A9A9624278AA97fbE54b27c102" - l1FeeVaultRecipient = "0x610DE9141a2c51A9A9624278AA97fbE54b27c102" - sequencerFeeVaultRecipient = "0x610DE9141a2c51A9A9624278AA97fbE54b27c102" - eip1559DenominatorCanyon = 100000000 - eip1559Denominator = 100000000 - eip1559Elasticity = 1 - operatorFeeScalar = 0 - operatorFeeConstant = 0 - gasLimit = 50000000 - [chains.deployOverrides] - l2GenesisBlockGasLimit = "0x2faf080" - l2GenesisBlockBaseFeePerGas = "0x5FC01C5" - l2BlockTime = 1 - sequencerWindowSize = 7200 - [chains.customGasToken] - enabled = true - name = "OKB" - symbol = "OKB" - initialLiquidity = "0x0" - [chains.roles] - l1ProxyAdminOwner = "0x0000000000000000000000000000000000000000" - l2ProxyAdminOwner = "0xF21637a6d8407aaE4bB0a051986261832dD91DDD" - systemConfigOwner = "0xAd9bCE315bF77C0Ade22097199953381C6Cc72eE" - unsafeBlockSigner = "0x09dA216351B5E3df326220DaDA71cCCEEcD0D2f3" - batcher = "0xdfd6C636Dcb5a013c2431316c4A0762B84e70a5d" - proposer = "0xE43944421681170648E10007f73816e04F74394F" - challenger = "0x736E68Af2CbF2aB0E46E4310fE5Ae568b3642FF6" diff --git a/test-pp-op/config-op/intent.testnet.toml.bak b/test-pp-op/config-op/intent.testnet.toml.bak deleted file mode 100644 index 44b5ea978ea98..0000000000000 --- a/test-pp-op/config-op/intent.testnet.toml.bak +++ /dev/null @@ -1,35 +0,0 @@ -configType = "standard-overrides" -l1ChainID = 11155111 -fundDevAccounts = false -opcmAddress = "0x0000000000000000000000000000000000000000" -l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" -l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" - -[[chains]] - id = "0x00000000000000000000000000000000000000000000000000000000000007A0" - baseFeeVaultRecipient = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" - l1FeeVaultRecipient = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" - sequencerFeeVaultRecipient = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" - eip1559DenominatorCanyon = 100000000 - eip1559Denominator = 100000000 - eip1559Elasticity = 1 - operatorFeeScalar = 0 - operatorFeeConstant = 0 - gasLimit = 30000000 - [chains.deployOverrides] - l2GenesisBlockGasLimit = "0x1C9C380" - l2GenesisBlockBaseFeePerGas = "0x5FC01C5" - l2BlockTime = 1 - [chains.customGasToken] - enabled = true - name = "OKB" - symbol = "OKB" - initialLiquidity = "0x0" - [chains.roles] - l1ProxyAdminOwner = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" - l2ProxyAdminOwner = "0x86Df3Aa8a02b7b67A1b83f1B062F93563F7494d2" - systemConfigOwner = "0x1183f158515091c94188C13Cd16923cee663d4c4" - unsafeBlockSigner = "0x8A8926FEbCFEdD0B189886858B32ad1e7F4a5b4B" - batcher = "0x8EDf9B54e1c693b7B0caEa85E6a005C35e229124" - proposer = "0x829D57F38D2A94514a3dbA2297fDD1Bc52bB1938" - challenger = "0x7c3787BF0D78a9e2F802916110e4Ddd6E3eD262C" diff --git a/test-pp-op/config-op/intent.toml.bak b/test-pp-op/config-op/intent.toml.bak deleted file mode 100644 index cf04ac0b40e8b..0000000000000 --- a/test-pp-op/config-op/intent.toml.bak +++ /dev/null @@ -1,35 +0,0 @@ -configType = "standard-overrides" -l1ChainID = 1337 -fundDevAccounts = true -opcmAddress = "0x0000000000000000000000000000000000000000" -l1ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" -l2ContractsLocator = "file:///app/packages/contracts-bedrock/forge-artifacts" - -[[chains]] - id = "0x00000000000000000000000000000000000000000000000000000000000000c4" - baseFeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - l1FeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - sequencerFeeVaultRecipient = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - eip1559DenominatorCanyon = 250 - eip1559Denominator = 50 - eip1559Elasticity = 6 - gasLimit = 60000000 - operatorFeeScalar = 0 - operatorFeeConstant = 0 - [chains.deployOverrides] - l2GenesisBlockGasLimit = "0xbebc200" - l2GenesisBlockBaseFeePerGas = "0x3B9ACA00" - l2BlockTime = 1 - [chains.roles] - l1ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - l2ProxyAdminOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - systemConfigOwner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - unsafeBlockSigner = "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc" - batcher = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" - proposer = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" - challenger = "0x7d18A1B858253b5588f61fb5739d52e4b84e2cdA" - [chains.customGasToken] - enabled = true - name = "OKB" - symbol = "OKB" - InitialLiquidity = "0x0" # 0 OKB, no premint diff --git a/test-pp-op/config-op/jwt.txt b/test-pp-op/config-op/jwt.txt deleted file mode 100644 index f9be65a53906f..0000000000000 --- a/test-pp-op/config-op/jwt.txt +++ /dev/null @@ -1 +0,0 @@ -0c00f14247582fcd3c837311148cda1f56e7c2caa42fb1ba8a3cc7843603846e diff --git a/test-pp-op/config-op/state.json.bak b/test-pp-op/config-op/state.json.bak deleted file mode 100755 index 466b3f965891e..0000000000000 --- a/test-pp-op/config-op/state.json.bak +++ /dev/null @@ -1,13 +0,0 @@ -{ - "version": 1, - "create2Salt": "0x0000000000000000000000000000000000000000000000000000000000000000", - "appliedIntent": null, - "prestateManifest": null, - "superchainContracts": null, - "superchainRoles": null, - "implementationsDeployment": null, - "opChainDeployments": null, - "l1StateDump": null, - "DeploymentCalldata": null -} - diff --git a/test-pp-op/config-op/test.rpc.config.toml b/test-pp-op/config-op/test.rpc.config.toml deleted file mode 100644 index d0470fc21f615..0000000000000 --- a/test-pp-op/config-op/test.rpc.config.toml +++ /dev/null @@ -1,38 +0,0 @@ -[Node] -HTTPHost = "0.0.0.0" -HTTPPort = 8545 -HTTPCors = ["*"] -HTTPVirtualHosts = ["*"] -HTTPModules = ["web3", "debug", "eth", "txpool", "net", "engine", "miner", "admin"] -WSHost = "0.0.0.0" -WSPort = 7546 -WSOrigins = ["*"] -WSModules = ["debug", "eth", "txpool", "net", "engine"] -AuthAddr = "0.0.0.0" -AuthPort = 8552 -AuthVirtualHosts = ["*"] -JWTSecret = "/jwt.txt" - -[Node.P2P] -MaxPeers = 30 -DiscoveryV5 = true - -[Eth] -NetworkId = 901 -SyncMode = "full" -EnableInnerTx = true - - -[Eth.GPO] -Blocks = 20 -Percentile = 60 -MaxHeaderHistory = 1024 -MaxBlockHistory = 1024 -MaxPrice = "50000000000" #50GWei -IgnorePrice = "2" -MinSuggestedPriorityFee = 1 - -[Eth.GPO.XLayer] -Type = "default" -UpdatePeriod = 3000000000 # 3s -Default = "100000000" # 0.1 GWei diff --git a/test-pp-op/config-op/test.seq.config.toml b/test-pp-op/config-op/test.seq.config.toml deleted file mode 100644 index 117652fb59b31..0000000000000 --- a/test-pp-op/config-op/test.seq.config.toml +++ /dev/null @@ -1,46 +0,0 @@ -[Node] -HTTPHost = "0.0.0.0" -HTTPPort = 8545 -HTTPCors = ["*"] -HTTPVirtualHosts = ["*"] -HTTPModules = ["web3", "debug", "eth", "txpool", "net", "engine", "miner", "admin"] -WSHost = "0.0.0.0" -WSPort = 7546 -WSOrigins = ["*"] -WSModules = ["debug", "eth", "txpool", "net", "engine"] -AuthAddr = "0.0.0.0" -AuthPort = 8552 -AuthVirtualHosts = ["*"] -JWTSecret = "/jwt.txt" - -[Node.P2P] -MaxPeers = 30 -DiscoveryV5 = true - -[Eth] -NetworkId = 901 -SyncMode = "full" -EnableInnerTx = true - - - -[Eth.TxPool] -GlobalSlots = 500000 -GlobalQueue = 100000 -AccountSlots = 50000 -AccountQueue = 10000 - - -[Eth.GPO] -Blocks = 20 -Percentile = 60 -MaxHeaderHistory = 1024 -MaxBlockHistory = 1024 -MaxPrice = "50000000000" #50GWei -IgnorePrice = "2" -MinSuggestedPriorityFee = 1 - -[Eth.GPO.XLayer] -Type = "default" -UpdatePeriod = 3000000000 # 3s -Default = "100000000" # 0.1 GWei diff --git a/test-pp-op/config/aggkit.toml b/test-pp-op/config/aggkit.toml deleted file mode 100644 index 3740349a09bcd..0000000000000 --- a/test-pp-op/config/aggkit.toml +++ /dev/null @@ -1,129 +0,0 @@ -PathRWData = "/tmp/" -L1URL="http://l1-geth:8545" - -L2URL="http://xlayer-rpc:8545" - -AggLayerURL="xlayer-agglayer:4443" - -ForkId = 13 -ContractVersions = "banana" -IsValidiumMode = false -NetworkID = 1 - -L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" -SequencerPrivateKeyPath = "/etc/aggkit/sequencer.keystore" -SequencerPrivateKeyPassword = "testonly" - -AggregatorPrivateKeyPath = "/etc/aggkit/aggregator.keystore" -AggregatorPrivateKeyPassword = "testonly" -SenderProofToL1Addr = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" -polygonBridgeAddr = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" - -rollupCreationBlockNumber = "91" -rollupManagerCreationBlockNumber = "100" -genesisBlockNumber = "91" - -[Common] -NetworkID = 1 -IsValidiumMode = false -ContractVersions = "banana" -# TODO, should we config with base -L2RPC = { Mode = "basic", URL = "{{L2URL}}", OpNodeURL = "http://op-rpc:8545" } - -[L1Config] -chainId = "1337" -polygonZkEVMGlobalExitRootAddress = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" -polygonRollupManagerAddress = "0xE96dBF374555C6993618906629988d39184716B3" -polTokenAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3" -polygonZkEVMAddress = "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" - -[L2Config] -GlobalExitRootAddr = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" - -[Log] -Environment = "development" -Level = "debug" -Outputs = ["stderr"] - -[RPC] -Port = 5576 - -[AggSender] -StoragePath = "/tmp/aggsender.sqlite" -AggsenderPrivateKey = {Path = "/etc/aggkit/sequencer.keystore", Password = "testonly"} -CheckStatusCertificateInterval = "1s" -Mode="PessimisticProof" -UseAgglayerTLS = false -MaxCertSize = 0 -MaxL2BlockNumber = 0 -StopOnFinishedSendingAllCertificates = false - -[AggSender.MaxSubmitCertificateRate] -NumRequests = 20 -Interval = "1m" -BlockFinality = "LatestBlock" -SaveCertificatesToFilesPath = "/tmp/certificates" -KeepCertificatesHistory = true -[AggOracle] -BlockFinality = "LatestBlock" -WaitPeriodNextGER = "10s" - -[AggOracle.EVMSender] -GlobalExitRootL2 = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" -WaitPeriodMonitorTx = "10s" - -[AggOracle.EVMSender.EthTxManager] -PrivateKeys = [{Path = "/etc/aggkit/aggoracle.keystore", Password = "testonly"}] -[AggOracle.EVMSender.EthTxManager.Etherman] -L1ChainID = "195" - -[BridgeL1Sync] -BlockFinality = "LatestBlock" - -[BridgeL2Sync] -BridgeAddr = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" - -DBPath = "/tmp/bridgel2sync.sqlite" -BlockFinality = "LatestBlock" - -SyncBlockChunkSize = 1000 - -[ReorgDetectorL1] -DBPath = "/tmp/reorgdetectorl1.sqlite" -LatestBlock="LatestBlock" - -[ReorgDetectorL2] -DBPath = "/tmp/reorgdetectorl2.sqlite" -LatestBlock="LatestBlock" - -[L1InfoTreeSync] -InitialBlock = "36" -BlockFinality = "LatestBlock" - -[LastGERSync] -BlockFinality = "LatestBlock" - -[ClaimSponsor] -DBPath = "/tmp/claimsponsor.sqlite" -Enabled = false - -SenderAddr = "0x5f5dB0D4D58310F53713eF4Df80ba6717868A9f8" - -BridgeAddrL2 = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" - -[ClaimSponsor.EthTxManager] -PrivateKeys = [ - {Path = "/etc/aggkit/claimtxmanager.keystore", Password = ""}, -] - -StoragePath = "" - -[ClaimSponsor.EthTxManager.Etherman] -URL = "" - -L1ChainID = "195" - -[Profiling] -ProfilingHost = "0.0.0.0" - -ProfilingPort = 6060 \ No newline at end of file diff --git a/test-pp-op/config/agglayer-config.toml b/test-pp-op/config/agglayer-config.toml deleted file mode 100644 index d070a4ce6aee8..0000000000000 --- a/test-pp-op/config/agglayer-config.toml +++ /dev/null @@ -1,91 +0,0 @@ -prover-entrypoint = "http://xlayer-agglayer-prover:4445" -debug-mode = true - -# Only supported by fork 12+ -mock-verifier = true - -[full-node-rpcs] -# TODO switch this to permissionless -1 = "http://op-geth-rpc:8545" - -[proof-signers] -1 = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" - -[rpc] -grpc-port = 4443 -readrpc-port = 4444 -admin-port = 4446 -host = "0.0.0.0" -request-timeout = 180 -# size is define in bytes e.g. 100 * 1024 * 1024 -# same for `max_response_body_size` -# default value is equal to 10MB -max-request-body-size = 104857600 - -[prover.grpc] -# size is define in bytes e.g. 100 * 1024 * 1024 -# same for `max-encoding-message-size` -# default value is equal to 4MB -max-decoding-message-size = 104857600 - -[outbound.rpc.settle] -max-retries = 3 -retry-interval = 7 -confirmations = 1 -settlement-timeout = 1200 - -[log] -# level = "info" -# we want debug visibility here for now -level = "debug" -outputs = ["stderr"] -format = "json" - -[auth.local] -private-keys = [ - { path = "/etc/zkevm/agglayer.keystore", password = "testonly" }, -] - -[l1] -chain-id = 1337 -node-url = "http://l1-geth:8545" -ws-node-url = "ws://l1-geth:8546" -rollup-manager-contract = "0xE96dBF374555C6993618906629988d39184716B3" -polygon-zkevm-global-exit-root-v2-contract = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" -rpc-timeout = 45 - -[l2] -rpc-timeout = 45 - -[telemetry] -prometheus-addr = "0.0.0.0:9092" - -# https://github.com/orgs/agglayer/discussions/213 - -[rate-limiting] -send-tx = "unlimited" -# [rate-limiting.send-tx] -# max-per-interval = 1 -# time-interval = "15m" - -[rate-limiting.network] - -[epoch.block-clock] -epoch-duration = 6 -genesis-block = 0 - -[shutdown] -runtime-timeout = 5 - -[certificate-orchestrator] -input-backpressure-buffer-size = 1000 - -[certificate-orchestrator.prover.sp1-local] - -[storage] -db-path = "/etc/zkevm/storage" - -[storage.backup] -path = "/etc/zkevm/backups" -state-max-backup-count = 100 -pending-max-backup-count = 100 \ No newline at end of file diff --git a/test-pp-op/config/agglayer-prover-config.toml b/test-pp-op/config/agglayer-prover-config.toml deleted file mode 100644 index fb7255e14c7f9..0000000000000 --- a/test-pp-op/config/agglayer-prover-config.toml +++ /dev/null @@ -1,25 +0,0 @@ -grpc-endpoint = "0.0.0.0:4445" -max-concurrency-limit = 100 -max-request-duration = 300 -max-buffered-queries = 100 - -[log] -environment = "production" # "production" or "development" -# level = "info" -level = "debug" -outputs = ["stderr"] -format = "json" - -[telemetry] -prometheus-addr = "0.0.0.0:9093" - - -[primary-prover.mock-prover] - -proving-timeout = 900 - -[grpc] -# size is define in bytes e.g. 100 * 1024 * 1024 -# same for `max-encoding-message-size` -# default value is equal to 4MB -max-decoding-message-size = 104857600 \ No newline at end of file diff --git a/test-pp-op/config/cdk.config.toml b/test-pp-op/config/cdk.config.toml deleted file mode 100644 index 8500a1af38bfc..0000000000000 --- a/test-pp-op/config/cdk.config.toml +++ /dev/null @@ -1,296 +0,0 @@ -ForkUpgradeBatchNumber = 0 -ForkUpgradeNewForkId = 0 - -[Log] -Environment = "development" # "production" or "development" -Level = "info" -Outputs = ["stderr"] - -[NetworkConfig.L1] -L1ChainID = 1337 -PolAddr = "0x5FbDB2315678afecb367f032d93F642f64180aa3" -ZkEVMAddr = "0xeb173087729c88a47568AF87b17C653039377BA6" -RollupManagerAddr = "0x2d42E2899662EFf08b13eeb65b154b904C7a1c8a" -GlobalExitRootManagerAddr = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" - -[Etherman] - URL="http://xlayer-mock-l1-network:8545" - ForkIDChunkSize=100 - [Etherman.EthermanConfig] - URL="http://xlayer-mock-l1-network:8545" - MultiGasProvider=false - L1ChainID=1337 - HTTPHeaders=[] - [Etherman.EthermanConfig.Etherscan] - ApiKey="" - Url="https://api.etherscan.io/api?module=gastracker&action=gasoracle&apikey=" - -[Common] -NetworkID = 1 -IsValidiumMode = true -ContractVersions = "banana" - -[SequenceSender] -WaitPeriodSendSequence = "15s" -LastBatchVirtualizationTimeMaxWaitPeriod = "10s" -L1BlockTimestampMargin = "30s" -MaxTxSizeForL1 = 131072 -L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" -PrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"} -SequencesTxFileName = "sequencesender.json" -GasOffset = 80000 -WaitPeriodPurgeTxFile = "60m" -MaxPendingTx = 1 -MaxBatchesForL1 = 300 -BlockFinality = "FinalizedBlock" -RPCURL = "http://xlayer-rpc:8545" -GetBatchWaitInterval = "10s" - [SequenceSender.EthTxManager] - FrequencyToMonitorTxs = "1s" - WaitTxToBeMined = "2m" - GetReceiptMaxTime = "250ms" - GetReceiptWaitInterval = "1s" - PrivateKeys = [ - {Path = "/pk/sequencer.keystore", Password = "testonly"}, - ] - ForcedGas = 0 - GasPriceMarginFactor = 1 - MaxGasPriceLimit = 0 - StoragePath = "/tmp/cdk/ethtxmanager.sqlite" - ReadPendingL1Txs = false - SafeStatusL1NumberOfBlocks = 0 - FinalizedStatusL1NumberOfBlocks = 0 - [SequenceSender.EthTxManager.Etherman] - URL = "http://xlayer-mock-l1-network:8545" - MultiGasProvider = false - L1ChainID = 1337 -[Aggregator] -# GRPC server host -Host = "0.0.0.0" -# GRPC server port -Port = 50081 -RetryTime = "5s" -VerifyProofInterval = "10s" -ProofStatePollingInterval = "5s" -TxProfitabilityCheckerType = "acceptall" -TxProfitabilityMinReward = "1.1" -IntervalAfterWhichBatchConsolidateAnyway="0s" -BatchProofSanityCheckEnabled = true -# ChainID is L2ChainID. Is populated on runtimme -ChainID = 0 -ForkId = 13 -SenderAddress = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" -CleanupLockedProofsInterval = "2m" -GeneratingProofCleanupThreshold = "10m" -GasOffset = 0 -RPCURL = "http://xlayer-rpc:8545" -WitnessURL = "http://xlayer-rpc:8545" -UseFullWitness = false -SettlementBackend = "l1" -AggLayerTxTimeout = "5m" -AggLayerURL = "" -SyncModeOnlyEnabled = false - [Aggregator.SequencerPrivateKey] - Path = "/pk/sequencer.keystore" - Password = "testonly" - [Aggregator.DB] - Name = "aggregator_db" - User = "aggregator_user" - Password = "aggregator_password" - Host = "xlayer-agg-db-old" - Port = "5432" - EnableLog = false - MaxConns = 200 - [Aggregator.Log] - Environment = "development" # "production" or "development" - Level = "info" - Outputs = ["stderr"] - [Aggregator.EthTxManager] - FrequencyToMonitorTxs = "1s" - WaitTxToBeMined = "2m" - GetReceiptMaxTime = "250ms" - GetReceiptWaitInterval = "1s" - PrivateKeys = [ - {Path = "/pk/aggregator.keystore", Password = "testonly"}, - ] - ForcedGas = 0 - GasPriceMarginFactor = 1 - MaxGasPriceLimit = 0 - StoragePath = "/tmp/cdk/ethtxmanager.sqlite" - ReadPendingL1Txs = false - SafeStatusL1NumberOfBlocks = 0 - FinalizedStatusL1NumberOfBlocks = 0 - [Aggregator.EthTxManager.Etherman] - URL = "http://xlayer-mock-l1-network:8545" - L1ChainID = 1337 - HTTPHeaders = [] - [Aggregator.Synchronizer] - [Aggregator.Synchronizer.Log] - Environment = "development" # "production" or "development" - Level = "info" - Outputs = ["stderr"] - [Aggregator.Synchronizer.SQLDB] - DriverName = "sqlite3" - DataSource = "/tmp/cdk/aggregator_sync_db.sqlite" - [Aggregator.Synchronizer.Synchronizer] - SyncInterval = "10s" - SyncChunkSize = 1000 - GenesisBlockNumber = 123 - SyncUpToBlock = "finalized" - BlockFinality = "finalized" - OverrideStorageCheck = false - [Aggregator.Synchronizer.Etherman] - L1URL = "http://xlayer-mock-l1-network:8545" - ForkIDChunkSize = 100 - L1ChainID = 1337 - PararellBlockRequest = false - [Aggregator.Synchronizer.Etherman.Contracts] - GlobalExitRootManagerAddr = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" - RollupManagerAddr = "0x2d42E2899662EFf08b13eeb65b154b904C7a1c8a" - ZkEVMAddr = "0xeb173087729c88a47568AF87b17C653039377BA6" - [Aggregator.Synchronizer.Etherman.Validium] - Enabled = true - # L2URL, empty ask to contract - TrustedSequencerURL = "" - RetryOnDACErrorInterval = "1m" - DataSourcePriority = ["trusted", "external"] - [Aggregator.Synchronizer.Etherman.Validium.Translator] - FullMatchRules = [] - [Aggregator.Synchronizer.Etherman.Validium.RateLimit] - NumRequests = 1000 - Interval = "1s" -[ReorgDetectorL1] -DBPath = "/tmp/cdk/reorg_detector_l1.sqlite" - -# Only for AGGORACLE, RPC, AGGSENDER -#[ReorgDetectorL2] -#DBPath = "/tmp/cdk/reorg_detector_l2.sqlite" - -[L1InfoTreeSync] -DBPath = "/tmp/cdk/l1_info_tree_sync.sqlite" -GlobalExitRootAddr="0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" -RollupManagerAddr = "0x2d42E2899662EFf08b13eeb65b154b904C7a1c8a" -SyncBlockChunkSize=10 -BlockFinality="LatestBlock" -WaitForNewBlocksPeriod="100ms" -InitialBlock= 123 - -# Only for AGGORACLE, RPC, AGGSENDER -#[AggOracle] -#TargetChainType="EVM" -#URLRPCL1="" -#BlockFinality="FinalizedBlock" -#WaitPeriodNextGER="100ms" -# [AggOracle.EVMSender] -# GlobalExitRootL2="0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" -# URLRPCL2="" -# ChainIDL2=195 -# GasOffset=0 -# WaitPeriodMonitorTx="100ms" -# SenderAddr="0x70997970c51812dc3a010c7d01b50e0d17dc79c8" -# [AggOracle.EVMSender.EthTxManager] -# FrequencyToMonitorTxs = "1s" -# WaitTxToBeMined = "2s" -# GetReceiptMaxTime = "250ms" -# GetReceiptWaitInterval = "1s" -# PrivateKeys = [ -# {Path = "/app/keystore/aggoracle.keystore", Password = "testonly"}, -# ] -# ForcedGas = 0 -# GasPriceMarginFactor = 1 -# MaxGasPriceLimit = 0 -# StoragePath = "/tmp/cdk/ethtxmanager-sequencesender.sqlite" -# ReadPendingL1Txs = false -# SafeStatusL1NumberOfBlocks = 5 -# FinalizedStatusL1NumberOfBlocks = 10 -# [AggOracle.EVMSender.EthTxManager.Etherman] -# URL = "http://xlayer-mock-l1-network:8545" -# MultiGasProvider = false -# L1ChainID = 1337 -# HTTPHeaders = [] - -# Only for RPC -#[RPC] -#Host = "0.0.0.0" -#Port = 5576 -#ReadTimeout = "2s" -#WriteTimeout = "2s" -#MaxRequestsPerIPAndSecond = 10 - -# Only for RPC -#[ClaimSponsor] -#DBPath = "/tmp/cdk/claimsopnsor.sqlite" -#Enabled = true -#SenderAddr = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" -#BridgeAddrL2 = "0x3a277Fa4E78cc1266F32E26c467F99A8eAEfF7c3" -#MaxGas = 200000 -#RetryAfterErrorPeriod = "1s" -#MaxRetryAttemptsAfterError = -1 -#WaitTxToBeMinedPeriod = "3s" -#WaitOnEmptyQueue = "3s" -#GasOffset = 0 -# [ClaimSponsor.EthTxManager] -# FrequencyToMonitorTxs = "1s" -# WaitTxToBeMined = "2s" -# GetReceiptMaxTime = "250ms" -# GetReceiptWaitInterval = "1s" -# PrivateKeys = [ -# {Path = "/app/keystore/claimsopnsor.keystore", Password = "testonly"}, -# ] -# ForcedGas = 0 -# GasPriceMarginFactor = 1 -# MaxGasPriceLimit = 0 -# StoragePath = "/tmp/cdk/ethtxmanager-claimsponsor.sqlite" -# ReadPendingL1Txs = false -# SafeStatusL1NumberOfBlocks = 5 -# FinalizedStatusL1NumberOfBlocks = 10 -# [ClaimSponsor.EthTxManager.Etherman] -# URL = "http://xlayer-mock-l1-network:8545" -# MultiGasProvider = false -# L1ChainID = 1337 -# HTTPHeaders = [] - -# Only for RPC -#[BridgeL1Sync] -#DBPath = "/tmp/cdk/bridgel1sync.sqlite" -#BlockFinality = "LatestBlock" -#InitialBlockNum = 0 -#BridgeAddr = "0x3a277Fa4E78cc1266F32E26c467F99A8eAEfF7c3" -#SyncBlockChunkSize = 100 -#RetryAfterErrorPeriod = "1s" -#MaxRetryAttemptsAfterError = -1 -#WaitForNewBlocksPeriod = "3s" -#OriginNetwork=0 - -# For RPC and aggsender -#[BridgeL2Sync] -#DBPath = "/tmp/cdk/bridgel2sync.sqlite" -#BlockFinality = "LatestBlock" -#InitialBlockNum = 0 -#BridgeAddr = "0x3a277Fa4E78cc1266F32E26c467F99A8eAEfF7c3" -#SyncBlockChunkSize = 100 -#RetryAfterErrorPeriod = "1s" -#MaxRetryAttemptsAfterError = -1 -#WaitForNewBlocksPeriod = "3s" -#OriginNetwork=1 - -# Only for RPC -#[LastGERSync] -## MDBX database path -#DBPath = "/tmp/cdk/lastgersync.sqlite" -#BlockFinality = "LatestBlock" -#InitialBlockNum = 0 -#GlobalExitRootL2Addr = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" -#RetryAfterErrorPeriod = "1s" -#MaxRetryAttemptsAfterError = -1 -#WaitForNewBlocksPeriod = "1s" -#DownloadBufferSize = 100 - -#[AggSender] -#StoragePath = "/tmp/cdk/aggsender.sqlite" -#AggLayerURL = "" -#AggsenderPrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"} -#BlockGetInterval = "2s" -#URLRPCL2="http://xlayer-rpc:8545" -#CheckSettledInterval = "2s" -#SaveCertificatesToFiles = false \ No newline at end of file diff --git a/test-pp-op/config/dynamic-mynetwork-allocs.json b/test-pp-op/config/dynamic-mynetwork-allocs.json deleted file mode 100644 index 013af5343dd56..0000000000000 --- a/test-pp-op/config/dynamic-mynetwork-allocs.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "0x1eDa899fE24907035Ed6F5C6472a1f1E627aB359": { - "contractName": "BytecodeStorer", - "balance": "0", - "nonce": "1", - "code": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063c514f24e1461002d575b5f5ffd5b61003561004b565b604051610042919061006a565b60405180910390f35b60405180610f000160405280610ec881526020016100b6610ec8913981565b602081525f82518060208401525f5b818110156100965760208186018101516040868401015201610079565b505f604082850101526040601f19601f8301168401019150509291505056fe60806040819052631d97f74d60e11b81523390633b2fee9a90608490602090600481865afa158015610033573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100579190610433565b604080515f80825260208201909252905061007382825f6100e2565b50506100dd336001600160a01b03166338b8fbbb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100b4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100d89190610433565b61010d565b6104c8565b6100eb8361017a565b5f825111806100f75750805b156101085761010683836101b9565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61014c5f516020610e815f395f51905f52546001600160a01b031690565b604080516001600160a01b03928316815291841660208301520160405180910390a1610177816101e5565b50565b61018381610280565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606101de8383604051806060016040528060278152602001610ea160279139610314565b9392505050565b6001600160a01b03811661024f5760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b805f516020610e815f395f51905f525b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b0381163b6102ed5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610246565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61025f565b60605f5f856001600160a01b031685604051610330919061047b565b5f60405180830381855af49150503d805f8114610368576040519150601f19603f3d011682016040523d82523d5f602084013e61036d565b606091505b50909250905061037f86838387610389565b9695505050505050565b606083156103f75782515f036103f0576001600160a01b0385163b6103f05760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610246565b5081610401565b6104018383610409565b949350505050565b8151156104195781518083602001fd5b8060405162461bcd60e51b81526004016102469190610496565b5f60208284031215610443575f5ffd5b81516001600160a01b03811681146101de575f5ffd5b5f5b8381101561047357818101518382015260200161045b565b50505f910152565b5f825161048c818460208701610459565b9190910192915050565b602081525f82518060208401526104b4816040850160208701610459565b601f01601f19169190910160400192915050565b6109ac806104d55f395ff3fe60806040526004361061005d575f3560e01c80635c60da1b116100425780635c60da1b146100a65780638f283970146100e3578063f851a440146101025761006c565b80633659cfe6146100745780634f1ef286146100935761006c565b3661006c5761006a610116565b005b61006a610116565b34801561007f575f5ffd5b5061006a61008e366004610854565b610130565b61006a6100a136600461086d565b610178565b3480156100b1575f5ffd5b506100ba6101eb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee575f5ffd5b5061006a6100fd366004610854565b610228565b34801561010d575f5ffd5b506100ba610255565b61011e610282565b61012e610129610359565b610362565b565b610138610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d8160405180602001604052805f8152505f6103bf565b50565b61016d610116565b610180610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101e3576101de8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250600192506103bf915050565b505050565b6101de610116565b5f6101f4610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610359565b905090565b610225610116565b90565b610230610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d816103e9565b5f61025e610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610380565b61028a610380565b73ffffffffffffffffffffffffffffffffffffffff16330361012e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b5f61021861044a565b365f5f375f5f365f845af43d5f5f3e80801561037c573d5ff35b3d5ffd5b5f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103c883610471565b5f825111806103d45750805b156101de576103e383836104bd565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610412610380565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161016d816104e9565b5f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103a3565b61047a816105f5565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606104e28383604051806060016040528060278152602001610979602791396106c0565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811661058c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610350565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610350565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105af565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff16856040516106e9919061090d565b5f60405180830381855af49150503d805f8114610721576040519150601f19603f3d011682016040523d82523d5f602084013e610726565b606091505b509150915061073786838387610741565b9695505050505050565b606083156107d65782515f036107cf5773ffffffffffffffffffffffffffffffffffffffff85163b6107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610350565b50816107e0565b6107e083836107e8565b949350505050565b8151156107f85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103509190610928565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f575f5ffd5b919050565b5f60208284031215610864575f5ffd5b6104e28261082c565b5f5f5f6040848603121561087f575f5ffd5b6108888461082c565b9250602084013567ffffffffffffffff8111156108a3575f5ffd5b8401601f810186136108b3575f5ffd5b803567ffffffffffffffff8111156108c9575f5ffd5b8660208284010111156108da575f5ffd5b939660209190910195509293505050565b5f5b838110156109055781810151838201526020016108ed565b50505f910152565b5f825161091e8184602087016108eb565b9190910192915050565b602081525f82518060208401526109468160408501602087016108eb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a164736f6c634300081c000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220f9f921f910b22a2a14f9dce017cc4be5206c1f1f3690adcea59699078c36984a64736f6c634300081c0033", - "storage": null - }, - "0xccF2F75629fF55768cAF87F9D2e733dee92373DC": { - "contractName": "TokenWrapped Implementation", - "balance": "0", - "nonce": "1", - "code": "0x608060405234801561000f575f5ffd5b5060043610610106575f3560e01c806370a082311161009e5780639dc29fac1161006e5780639dc29fac1461023c578063a3c573eb1461024f578063a9059cbb14610297578063d505accf146102aa578063dd62ed3e146102bd575f5ffd5b806370a08231146101f35780637ecebe001461020657806384b0196e1461021957806395d89b4114610234575f5ffd5b806323b872dd116100d957806323b872dd14610191578063313ce567146101a45780633644e515146101d857806340c10f19146101e0575f5ffd5b806306fdde031461010a578063095ea7b3146101285780631624f6c61461014b57806318160ddd14610160575b5f5ffd5b610112610314565b60405161011f919061115f565b60405180910390f35b61013b610136366004611193565b6103b9565b604051901515815260200161011f565b61015e61015936600461126a565b6103d2565b005b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace02545b60405190815260200161011f565b61013b61019f3660046112de565b61054a565b7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d005460405160ff909116815260200161011f565b61018361056d565b61015e6101ee366004611193565b61057b565b610183610201366004611318565b6105de565b610183610214366004611318565b61060e565b610221610618565b60405161011f9796959493929190611331565b6101126106ce565b61015e61024a366004611193565b61070c565b7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d005461010090046001600160a01b03166040516001600160a01b03909116815260200161011f565b61013b6102a5366004611193565b61076a565b61015e6102b83660046113c7565b610777565b6101836102cb36600461142d565b6001600160a01b039182165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b60605f5f5160206115c95f395f51905f525b90508060030180546103379061145e565b80601f01602080910402602001604051908101604052809291908181526020018280546103639061145e565b80156103ae5780601f10610385576101008083540402835291602001916103ae565b820191905f5260205f20905b81548152906001019060200180831161039157829003601f168201915b505050505091505090565b5f336103c68185856108cc565b60019150505b92915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f8115801561041c5750825b90505f8267ffffffffffffffff1660011480156104385750303b155b905081158015610446575080155b156104645760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561049857845468ff00000000000000001916680100000000000000001785555b6104a288886108d9565b6104ab886108ef565b7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d00805460ff881674ffffffffffffffffffffffffffffffffffffffffff19909116176101003302179055831561054057845468ff000000000000000019168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f3361055785828561091d565b6105628585856109b7565b506001949350505050565b5f610576610a14565b905090565b5f7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d00805490915061010090046001600160a01b031633146105cf576040516338da3b1560e01b815260040160405180910390fd5b6105d98383610a1d565b505050565b5f805f5160206115c95f395f51905f525b6001600160a01b039093165f9081526020939093525050604090205490565b5f6103cc82610a51565b5f60608082808083815f5160206115e95f395f51905f52805490915015801561064357506001810154155b6106945760405162461bcd60e51b815260206004820152601560248201527f4549503731323a20556e696e697469616c697a6564000000000000000000000060448201526064015b60405180910390fd5b61069c610a5b565b6106a4610a99565b604080515f80825260208201909252600f60f81b9c939b5091995046985030975095509350915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060915f5160206115c95f395f51905f52916103379061145e565b5f7f863b064fe9383d75d38f584f64f1aaba4520e9ebc98515fa15bdeae8c4274d00805490915061010090046001600160a01b03163314610760576040516338da3b1560e01b815260040160405180910390fd5b6105d98383610aaf565b5f336103c68185856109b7565b8342111561079b5760405163313c898160e11b81526004810185905260240161068b565b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886108058c6001600160a01b03165f9081527f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090505f61085f82610ae3565b90505f61086e82878787610b0f565b9050896001600160a01b0316816001600160a01b0316146108b5576040516325c0072360e11b81526001600160a01b0380831660048301528b16602482015260440161068b565b6108c08a8a8a6108cc565b50505050505050505050565b6105d98383836001610b3b565b6108e1610c1f565b6108eb8282610c6f565b5050565b6108f7610c1f565b61091a81604051806040016040528060018152602001603160f81b815250610cbf565b50565b6001600160a01b038381165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0160209081526040808320938616835292905220545f1981146109b157818110156109a357604051637dc7a0d960e11b81526001600160a01b0384166004820152602481018290526044810183905260640161068b565b6109b184848484035f610b3b565b50505050565b6001600160a01b0383166109e057604051634b637e8f60e11b81525f600482015260240161068b565b6001600160a01b038216610a095760405163ec442f0560e01b81525f600482015260240161068b565b6105d9838383610d1e565b5f610576610e57565b6001600160a01b038216610a465760405163ec442f0560e01b81525f600482015260240161068b565b6108eb5f8383610d1e565b5f6103cc82610eca565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060915f5160206115e95f395f51905f52916103379061145e565b60605f5f5160206115e95f395f51905f52610326565b6001600160a01b038216610ad857604051634b637e8f60e11b81525f600482015260240161068b565b6108eb825f83610d1e565b5f6103cc610aef610a14565b8360405161190160f01b8152600281019290925260228201526042902090565b5f5f5f5f610b1f88888888610ef2565b925092509250610b2f8282610fba565b50909695505050505050565b5f5160206115c95f395f51905f526001600160a01b038516610b725760405163e602df0560e01b81525f600482015260240161068b565b6001600160a01b038416610b9b57604051634a1406b160e11b81525f600482015260240161068b565b6001600160a01b038086165f90815260018301602090815260408083209388168352929052208390558115610c1857836001600160a01b0316856001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051610c0f91815260200190565b60405180910390a35b5050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16610c6d57604051631afcd79f60e31b815260040160405180910390fd5b565b610c77610c1f565b5f5160206115c95f395f51905f527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace03610cb084826114da565b50600481016109b183826114da565b610cc7610c1f565b5f5160206115e95f395f51905f527fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102610d0084826114da565b5060038101610d0f83826114da565b505f8082556001909101555050565b5f5160206115c95f395f51905f526001600160a01b038416610d585781816002015f828254610d4d9190611595565b90915550610dc89050565b6001600160a01b0384165f9081526020829052604090205482811015610daa5760405163391434e360e21b81526001600160a01b0386166004820152602481018290526044810184905260640161068b565b6001600160a01b0385165f9081526020839052604090209083900390555b6001600160a01b038316610de6576002810180548390039055610e04565b6001600160a01b0383165f9081526020829052604090208054830190555b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e4991815260200190565b60405180910390a350505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f610e81611072565b610e896110da565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f807f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006105ef565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610f2b57505f91506003905082610fb0565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610f7c573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b038116610fa757505f925060019150829050610fb0565b92505f91508190505b9450945094915050565b5f826003811115610fcd57610fcd6115b4565b03610fd6575050565b6001826003811115610fea57610fea6115b4565b036110085760405163f645eedf60e01b815260040160405180910390fd5b600282600381111561101c5761101c6115b4565b0361103d5760405163fce698f760e01b81526004810182905260240161068b565b6003826003811115611051576110516115b4565b036108eb576040516335e2f38360e21b81526004810182905260240161068b565b5f5f5160206115e95f395f51905f528161108a610a5b565b8051909150156110a257805160209091012092915050565b815480156110b1579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b5f5f5160206115e95f395f51905f52816110f2610a99565b80519091501561110a57805160209091012092915050565b600182015480156110b1579392505050565b5f81518084525f5b8181101561114057602081850181015186830182015201611124565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f611171602083018461111c565b9392505050565b80356001600160a01b038116811461118e575f5ffd5b919050565b5f5f604083850312156111a4575f5ffd5b6111ad83611178565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126111de575f5ffd5b813567ffffffffffffffff8111156111f8576111f86111bb565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715611227576112276111bb565b60405281815283820160200185101561123e575f5ffd5b816020850160208301375f918101602001919091529392505050565b803560ff8116811461118e575f5ffd5b5f5f5f6060848603121561127c575f5ffd5b833567ffffffffffffffff811115611292575f5ffd5b61129e868287016111cf565b935050602084013567ffffffffffffffff8111156112ba575f5ffd5b6112c6868287016111cf565b9250506112d56040850161125a565b90509250925092565b5f5f5f606084860312156112f0575f5ffd5b6112f984611178565b925061130760208501611178565b929592945050506040919091013590565b5f60208284031215611328575f5ffd5b61117182611178565b60ff60f81b8816815260e060208201525f61134f60e083018961111c565b8281036040840152611361818961111c565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b818110156113b6578351835260209384019390920191600101611398565b50909b9a5050505050505050505050565b5f5f5f5f5f5f5f60e0888a0312156113dd575f5ffd5b6113e688611178565b96506113f460208901611178565b955060408801359450606088013593506114106080890161125a565b9699959850939692959460a0840135945060c09093013592915050565b5f5f6040838503121561143e575f5ffd5b61144783611178565b915061145560208401611178565b90509250929050565b600181811c9082168061147257607f821691505b60208210810361149057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156105d957805f5260205f20601f840160051c810160208510156114bb5750805b601f840160051c820191505b81811015610c18575f81556001016114c7565b815167ffffffffffffffff8111156114f4576114f46111bb565b61150881611502845461145e565b84611496565b6020601f82116001811461153a575f83156115235750848201515b5f19600385901b1c1916600184901b178455610c18565b5f84815260208120601f198516915b828110156115695787850151825560209485019460019092019101611549565b508482101561158657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b808201808211156103cc57634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52602160045260245ffdfe52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100a2646970667358221220f0e100f498b6f41fbf597025b81d217623a1e4b7d8ee5bf92572b87e86172a6264736f6c634300081c0033", - "storage": null - }, - "0x9C1aBd1fB3569e951DcC3cd5D678a7a618088CFa": { - "contractName": "PolygonZkEVMDeployer", - "balance": "0", - "nonce": "4", - "code": "0x60806040526004361061006e575f3560e01c8063715018a61161004c578063715018a6146100e25780638da5cb5b146100f6578063e11ae6cb1461011f578063f2fde38b14610132575f80fd5b80632b79805a146100725780634a94d487146100875780636d07dbf81461009a575b5f80fd5b610085610080366004610908565b610151565b005b6100856100953660046109a2565b6101c2565b3480156100a5575f80fd5b506100b96100b43660046109f5565b610203565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ed575f80fd5b50610085610215565b348015610101575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff166100b9565b61008561012d366004610a15565b610228565b34801561013d575f80fd5b5061008561014c366004610a61565b61028e565b61015961034a565b5f6101658585856103ca565b90506101718183610527565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101ca61034a565b6101d583838361056a565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b905f90a1505050565b5f61020e8383610598565b9392505050565b61021d61034a565b6102265f6105a4565b565b61023061034a565b5f61023c8484846103ca565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b61029661034a565b73ffffffffffffffffffffffffffffffffffffffff811661033e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610347816105a4565b50565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610335565b5f83471015610435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610335565b81515f0361049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610335565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff811661020e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610335565b606061020e83835f6040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610618565b6060610590848484604051806060016040528060298152602001610b0860299139610618565b949350505050565b5f61020e83833061072d565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610335565b5f808673ffffffffffffffffffffffffffffffffffffffff1685876040516106d29190610a9c565b5f6040518083038185875af1925050503d805f811461070c576040519150601f19603f3d011682016040523d82523d5f602084013e610711565b606091505b509150915061072287838387610756565b979650505050505050565b5f604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156107eb5782515f036107e45773ffffffffffffffffffffffffffffffffffffffff85163b6107e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610335565b5081610590565b61059083838151156108005781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103359190610ab7565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112610870575f80fd5b813567ffffffffffffffff8082111561088b5761088b610834565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108d1576108d1610834565b816040528381528660208588010111156108e9575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f805f806080858703121561091b575f80fd5b8435935060208501359250604085013567ffffffffffffffff80821115610940575f80fd5b61094c88838901610861565b93506060870135915080821115610961575f80fd5b5061096e87828801610861565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff8116811461099d575f80fd5b919050565b5f805f606084860312156109b4575f80fd5b6109bd8461097a565b9250602084013567ffffffffffffffff8111156109d8575f80fd5b6109e486828701610861565b925050604084013590509250925092565b5f8060408385031215610a06575f80fd5b50508035926020909101359150565b5f805f60608486031215610a27575f80fd5b8335925060208401359150604084013567ffffffffffffffff811115610a4b575f80fd5b610a5786828701610861565b9150509250925092565b5f60208284031215610a71575f80fd5b61020e8261097a565b5f5b83811015610a94578181015183820152602001610a7c565b50505f910152565b5f8251610aad818460208701610a7a565b9190910192915050565b602081525f8251806020840152610ad5816040850160208701610a7a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a26469706673582212206c37fb6ca2362734c4736703fbea1e2f5c6060623d61a5acc99beb96437a122364736f6c63430008140033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008f8e2d6cf621f30e9a11309d6a56a876281fd534" - } - }, - "0xc2c5fb710E85BedC5C18A8a0Fa931D75983F2185": { - "contractName": "ProxyAdmin", - "balance": "0", - "nonce": "1", - "code": "0x608060405260043610610079575f3560e01c80639623609d1161004c5780639623609d1461012357806399a88ec414610136578063f2fde38b14610155578063f3b7dead14610174575f5ffd5b8063204e1c7a1461007d578063715018a6146100c55780637eff275e146100db5780638da5cb5b146100fa575b5f5ffd5b348015610088575f5ffd5b5061009c6100973660046105e8565b610193565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d0575f5ffd5b506100d9610244565b005b3480156100e6575f5ffd5b506100d96100f536600461060a565b610257565b348015610105575f5ffd5b505f5473ffffffffffffffffffffffffffffffffffffffff1661009c565b6100d961013136600461066e565b6102e0565b348015610141575f5ffd5b506100d961015036600461060a565b610371565b348015610160575f5ffd5b506100d961016f3660046105e8565b6103cd565b34801561017f575f5ffd5b5061009c61018e3660046105e8565b610489565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b5f60405180830381855afa9150503d805f8114610215576040519150601f19603f3d011682016040523d82523d5f602084013e61021a565b606091505b509150915081610228575f5ffd5b8080602001905181019061023c9190610782565b949350505050565b61024c6104d3565b6102555f610553565b565b61025f6104d3565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b5f604051808303815f87803b1580156102c6575f5ffd5b505af11580156102d8573d5f5f3e3d5ffd5b505050505050565b6102e86104d3565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061033e908690869060040161079d565b5f604051808303818588803b158015610355575f5ffd5b505af1158015610367573d5f5f3e3d5ffd5b5050505050505050565b6103796104d3565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102af565b6103d56104d3565b73ffffffffffffffffffffffffffffffffffffffff811661047d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61048681610553565b50565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610474565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610486575f5ffd5b5f602082840312156105f8575f5ffd5b8135610603816105c7565b9392505050565b5f5f6040838503121561061b575f5ffd5b8235610626816105c7565b91506020830135610636816105c7565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f5f60608486031215610680575f5ffd5b833561068b816105c7565b9250602084013561069b816105c7565b9150604084013567ffffffffffffffff8111156106b6575f5ffd5b8401601f810186136106c6575f5ffd5b803567ffffffffffffffff8111156106e0576106e0610641565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff8211171561074c5761074c610641565b604052818152828201602001881015610763575f5ffd5b816020840160208301375f602083830101528093505050509250925092565b5f60208284031215610792575f5ffd5b8151610603816105c7565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f82518060408401525f5b818110156107e557602081860181015160608684010152016107c8565b505f6060828501015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116840101915050939250505056fea26469706673582212208ab8743c787ecb046e26764a23735b65ae0affe7a9153fa2f3410ff80a26ba0464736f6c634300081c0033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000027284dba79e6df953fbd232a9d8d87029f03bbf5" - } - }, - "0x12060cA70f50A24fde90fEA110002C235f558a56": { - "contractName": "PolygonZkEVMBridgeV2 implementation", - "balance": "0", - "nonce": "3", - "code": "0x608060405260043610610233575f3560e01c806383f2440311610129578063ccaa2d11116100a8578063ee25560b1161006d578063ee25560b146106fe578063f214e16114610729578063f5efcd7914610748578063f811bff714610767578063fb57083414610786575f5ffd5b8063ccaa2d1114610671578063cd58657914610690578063d02103ca146106a3578063dbc16976146106cb578063ece93c6f146106df575f5ffd5b8063bab161bf116100ee578063bab161bf146105db578063be5831c7146105fc578063c00f14ab1461061f578063c514f24e1461063e578063cc46163214610652575f5ffd5b806383f244031461054b5780638bd309c31461056a5780638c668f1c146105895780638ed7e3f21461059d578063b8b284d0146105bc575f5ffd5b80633c351e10116101b557806365d6f6541161017a57806365d6f6541461049c5780636e4ecfed146104d057806379e2cf97146104ef5780638129fc1c1461050357806381b1c17414610517575f5ffd5b80633c351e10146103f35780633cbc795b146104125780633e1970431461044a5780634b2f336d146104695780635ca1e16514610488575f5ffd5b80632dfdf0b5116101fb5780632dfdf0b5146102e6578063318aee3d14610309578063381fef6d1461037157806338b8fbbb146103a45780633b2fee9a146103c1575f5ffd5b806315064c96146102375780632072f6c51461026557806322e95f2c1461027b578063240ff378146102b257806327aef4e8146102c5575b5f5ffd5b348015610242575f5ffd5b506068546102509060ff1681565b60405190151581526020015b60405180910390f35b348015610270575f5ffd5b506102796107a5565b005b348015610286575f5ffd5b5061029a610295366004612f92565b6107da565b6040516001600160a01b03909116815260200161025c565b6102796102c0366004613019565b610844565b3480156102d0575f5ffd5b506102d96108b4565b60405161025c91906130db565b3480156102f1575f5ffd5b506102fb60535481565b60405190815260200161025c565b348015610314575f5ffd5b5061034d6103233660046130ed565b606b6020525f908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b0390911660208301520161025c565b34801561037c575f5ffd5b5061029a7f0000000000000000000000001eda899fe24907035ed6f5c6472a1f1e627ab35981565b3480156103af575f5ffd5b506070546001600160a01b031661029a565b3480156103cc575f5ffd5b507f000000000000000000000000ccf2f75629ff55768caf87f9d2e733dee92373dc61029a565b3480156103fe575f5ffd5b50606d5461029a906001600160a01b031681565b34801561041d575f5ffd5b50606d5461043590600160a01b900463ffffffff1681565b60405163ffffffff909116815260200161025c565b348015610455575f5ffd5b506102fb610464366004613116565b610940565b348015610474575f5ffd5b50606f5461029a906001600160a01b031681565b348015610493575f5ffd5b506102fb6109d1565b3480156104a7575f5ffd5b506102d9604051806040016040528060098152602001680616c2d76302e332e360bc1b81525081565b3480156104db575f5ffd5b5060705461029a906001600160a01b031681565b3480156104fa575f5ffd5b50610279610a50565b34801561050e575f5ffd5b50610279610a71565b348015610522575f5ffd5b5061029a610531366004613190565b606a6020525f90815260409020546001600160a01b031681565b348015610556575f5ffd5b506102fb6105653660046131b8565b610baf565b348015610575575f5ffd5b506102796105843660046130ed565b610c3e565b348015610594575f5ffd5b50610279610ccc565b3480156105a8575f5ffd5b50606c5461029a906001600160a01b031681565b3480156105c7575f5ffd5b506102796105d63660046131f4565b610d5d565b3480156105e6575f5ffd5b5060685461043590610100900463ffffffff1681565b348015610607575f5ffd5b5060685461043590600160c81b900463ffffffff1681565b34801561062a575f5ffd5b506102d96106393660046130ed565b610ddb565b348015610649575f5ffd5b506102d9610e20565b34801561065d575f5ffd5b5061025061066c366004613272565b610ea9565b34801561067c575f5ffd5b5061027961068b3660046132a3565b610f31565b61027961069e366004613382565b61136e565b3480156106ae575f5ffd5b5060685461029a906501000000000090046001600160a01b031681565b3480156106d6575f5ffd5b5061027961170a565b3480156106ea575f5ffd5b5060715461029a906001600160a01b031681565b348015610709575f5ffd5b506102fb610718366004613190565b60696020525f908152604090205481565b348015610734575f5ffd5b5061029a610743366004612f92565b61173d565b348015610753575f5ffd5b506102796107623660046132a3565b61182a565b348015610772575f5ffd5b5061027961078136600461347e565b611a8a565b348015610791575f5ffd5b506102506107a036600461354e565b611d6c565b606c546001600160a01b031633146107d057604051631736745960e31b815260040160405180910390fd5b6107d8611d83565b565b6040805160e084901b6001600160e01b031916602080830191909152606084901b6bffffffffffffffffffffffff1916602483015282516018818403018152603890920183528151918101919091205f908152606a90915220546001600160a01b03165b92915050565b60685460ff161561086857604051630bc011ff60e21b815260040160405180910390fd5b34158015906108815750606f546001600160a01b031615155b1561089f576040516301bd897160e61b815260040160405180910390fd5b6108ad858534868686611dde565b5050505050565b606e80546108c190613593565b80601f01602080910402602001604051908101604052809291908181526020018280546108ed90613593565b80156109385780601f1061090f57610100808354040283529160200191610938565b820191905f5260205f20905b81548152906001019060200180831161091b57829003601f168201915b505050505081565b6040516001600160f81b031960f889901b1660208201526001600160e01b031960e088811b821660218401526bffffffffffffffffffffffff19606089811b821660258601529188901b909216603984015285901b16603d82015260518101839052607181018290525f90609101604051602081830303815290604052805190602001209050979650505050505050565b6053545f90819081805b6020811015610a47578083901c600116600103610a2057610a1960338260208110610a0857610a086135cb565b0154855f9182526020526040902090565b9350610a30565b5f84815260208390526040902093505b5f82815260208390526040902091506001016109db565b50919392505050565b605354606854600160c81b900463ffffffff1610156107d8576107d8611eba565b5f5460ff166071805460ff60a01b1916600160a01b60ff938416021790555f5460029161010090910416158015610aae57505f5460ff8083169116105b610b165760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b5f805461ffff191660ff80841691909117610100178255607154600160a01b9004169003610b575760405163f57ac68360e01b815260040160405180910390fd5b610b5f611f50565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1506071805460ff60a01b19169055565b5f83815b6020811015610c3357600163ffffffff8516821c81169003610bff57610bf8858260208110610be457610be46135cb565b6020020135835f9182526020526040902090565b9150610c2b565b610c2882868360208110610c1557610c156135cb565b60200201355f9182526020526040902090565b91505b600101610bb3565b5090505b9392505050565b6070546001600160a01b03163314610c6957604051630866750360e01b815260040160405180910390fd5b607180546001600160a01b0319166001600160a01b038381169182179092556070546040805191909316815260208101919091527f0a34baa3feb299aef9c05cb59c6e0c8e7c0bcc65cbf0a647e7a7c8a2411591e291015b60405180910390a150565b6071546001600160a01b03163314610cf757604051630b59ef2760e21b815260040160405180910390fd5b60708054607180546001600160a01b038082166001600160a01b0319808616821790965594909116909155604080519190921680825260208201939093527fa9da6fb8c39e9c2fafda878eac316815987bdc948d241ba6d75ed035e0e829f29101610cc1565b60685460ff1615610d8157604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610daa5760405163dde3cda760e01b815260040160405180910390fd5b606f545f90610dc2906001600160a01b031686612071565b9050610dd2878783878787611dde565b50505050505050565b6060610de6826120d5565b610def83612198565b610df88461224c565b604051602001610e0a939291906135df565b6040516020818303038152906040529050919050565b60607f0000000000000000000000001eda899fe24907035ed6f5c6472a1f1e627ab3596001600160a01b031663c514f24e6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610e7d573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ea49190810190613645565b905090565b6068545f908190610100900463ffffffff16158015610ece575063ffffffff83166001145b15610ee0575063ffffffff8316610f08565b610ef564010000000063ffffffff851661369e565b610f059063ffffffff86166136b5565b90505b600881901c5f90815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610f5557604051630bc011ff60e21b815260040160405180910390fd5b610f5d612300565b60685463ffffffff8681166101009092041614610f8d576040516302caf51760e11b815260040160405180910390fd5b610fb88c8c8c8c8c5f8d8d8d8d8d8d8d604051610fab9291906136c8565b6040518091039020612359565b6001600160a01b038616158015610fd3575063ffffffff8716155b156110b157606f546001600160a01b0316611095575f6001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015611020576020820181803683370190505b5060405161102e91906136d7565b5f6040518083038185875af1925050503d805f8114611068576040519150601f19603f3d011682016040523d82523d5f602084013e61106d565b606091505b505090508061108f57604051630ce8f45160e31b815260040160405180910390fd5b506112fb565b606f546110ac906001600160a01b03168585612375565b6112fb565b606d546001600160a01b0387811691161480156110df5750606d5463ffffffff888116600160a01b90920416145b156110f6575f6001600160a01b0385168482610ff6565b60685463ffffffff610100909104811690881603611122576110ac6001600160a01b03871685856123ce565b6040516001600160e01b031960e089901b1660208201526bffffffffffffffffffffffff19606088901b1660248201525f9060380160408051601f1981840301815291815281516020928301205f818152606a9093529120549091506001600160a01b0316806112ed575f6111cc8386868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061243292505050565b90506111d9818888612375565b80606a5f8581526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b5f836001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548163ffffffff021916908363ffffffff1602179055506020820151815f0160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a8388886040516112df95949392919061371a565b60405180910390a1506112f8565b6112f8818787612375565b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a161136060018055565b505050505050505050505050565b60685460ff161561139257604051630bc011ff60e21b815260040160405180910390fd5b61139a612300565b60685463ffffffff6101009091048116908816036113cb576040516302caf51760e11b815260040160405180910390fd5b5f806060876001600160a01b0388166114ae578834146113fe5760405163b89240f560e01b815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff1694509061142b90613593565b80601f016020809104026020016040519081016040528092919081815260200182805461145790613593565b80156114a25780601f10611479576101008083540402835291602001916114a2565b820191905f5260205f20905b81548152906001019060200180831161148557829003601f168201915b50505050509150611692565b34156114cd5760405163798ee6f160e01b815260040160405180910390fd5b84156114de576114de888787612519565b606f546001600160a01b0390811690891603611505576114fe888a612071565b9050611692565b6001600160a01b038089165f908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901515806115585750805163ffffffff1615155b1561157a57611567898b612071565b6020820151825190965094509150611685565b6040516370a0823160e01b81523060048201525f906001600160a01b038b16906370a0823190602401602060405180830381865afa1580156115be573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e29190613762565b90506115f96001600160a01b038b1633308e612833565b6040516370a0823160e01b81523060048201525f906001600160a01b038c16906370a0823190602401602060405180830381865afa15801561163d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116619190613762565b905061166d8282613779565b6068548c9850610100900463ffffffff169650935050505b61168e89610ddb565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b5f84868e8e86886053546040516116d198979695949392919061378c565b60405180910390a16116ef5f84868e8e86888051906020012061286c565b86156116fd576116fd611eba565b50505050610dd260018055565b606c546001600160a01b0316331461173557604051631736745960e31b815260040160405180910390fd5b6107d8612883565b6040516001600160e01b031960e084901b1660208201526bffffffffffffffffffffffff19606083901b1660248201525f9081906038016040516020818303038152906040528051906020012090505f60ff60f81b308361179c610e20565b6040516020016117ac91906136d7565b6040516020818303038152906040528051906020012060405160200161180994939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012095945050505050565b60685460ff161561184e57604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff868116610100909204161461187e576040516302caf51760e11b815260040160405180910390fd5b61189d8c8c8c8c8c60018d8d8d8d8d8d8d604051610fab9291906136c8565b606f545f906001600160a01b031661195057846001600160a01b031684888a86866040516024016118d19493929190613800565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161190691906136d7565b5f6040518083038185875af1925050503d805f8114611940576040519150601f19603f3d011682016040523d82523d5f602084013e611945565b606091505b505080915050611a01565b606f54611967906001600160a01b03168686612375565b846001600160a01b0316878985856040516024016119889493929190613800565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b179052516119bd91906136d7565b5f604051808303815f865af19150503d805f81146119f6576040519150601f19603f3d011682016040523d82523d5f602084013e6119fb565b606091505b50909150505b80611a1f576040516337e391c360e01b815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b5f5460ff166071805460ff60a01b1916600160a01b60ff938416021790555f5460029161010090910416158015611ac757505f5460ff8083169116105b611b2a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b0d565b5f805461ffff191660ff8084169190911761010017909155607154600160a01b90041615611b6b5760405163f57ac68360e01b815260040160405180910390fd5b611b73611f50565b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8a16027fffffffffffffff0000000000000000000000000000000000000000ffffffffff1617650100000000006001600160a01b038781169190910291909117909155606c80546001600160a01b0319168583161790558616611c285763ffffffff851615611c2357604051630d43a60960e11b815260040160405180910390fd5b611d0e565b606d805463ffffffff8716600160a01b027fffffffffffffffff0000000000000000000000000000000000000000000000009091166001600160a01b03891617179055606e611c778382613872565b50611ced5f5f1b6012604051602001611cd991906060808252600d908201526c2bb930b83832b21022ba3432b960991b608082015260a060208201819052600490820152630ae8aa8960e31b60c082015260ff91909116604082015260e00190565b604051602081830303815290604052612432565b606f80546001600160a01b0319166001600160a01b03929092169190911790555b611d166128da565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150506071805460ff60a01b191690555050505050565b5f81611d79868686610baf565b1495945050505050565b60685460ff1615611da757604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497905f90a1565b60685463ffffffff610100909104811690871603611e0f576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611e639998979695949392919061392d565b60405180910390a1611ea46001606860019054906101000a900463ffffffff16338989898888604051611e979291906136c8565b604051809103902061286c565b8215611eb257611eb2611eba565b505050505050565b6053546068805463ffffffff909216600160c81b0263ffffffff60c81b1990921691909117908190556001600160a01b0365010000000000909104166333d6247d611f036109d1565b6040518263ffffffff1660e01b8152600401611f2191815260200190565b5f604051808303815f87803b158015611f38575f5ffd5b505af1158015611f4a573d5f5f3e3d5ffd5b50505050565b5f611f827fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103546001600160a01b031690565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fc0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fe491906139a3565b607080546001600160a01b0319166001600160a01b03929092169182179055819061202e57604051632a506c0560e11b81526001600160a01b039091166004820152602401610b0d565b50607054604080515f81526001600160a01b0390921660208301527fa9da6fb8c39e9c2fafda878eac316815987bdc948d241ba6d75ed035e0e829f29101610cc1565b604051632770a7eb60e21b8152336004820152602481018290525f906001600160a01b03841690639dc29fac906044015f604051808303815f87803b1580156120b8575f5ffd5b505af11580156120ca573d5f5f3e3d5ffd5b509395945050505050565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b17905290516060915f9182916001600160a01b0386169161211b91906136d7565b5f60405180830381855afa9150503d805f8114612153576040519150601f19603f3d011682016040523d82523d5f602084013e612158565b606091505b50915091508161218757604051806040016040528060078152602001664e4f5f4e414d4560c81b815250612190565b6121908161294c565b949350505050565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b17905290516060915f9182916001600160a01b038616916121de91906136d7565b5f60405180830381855afa9150503d805f8114612216576040519150601f19603f3d011682016040523d82523d5f602084013e61221b565b606091505b50915091508161218757604051806040016040528060098152602001681393d7d4d6535093d360ba1b815250612190565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b17905290515f91829182916001600160a01b0386169161229191906136d7565b5f60405180830381855afa9150503d805f81146122c9576040519150601f19603f3d011682016040523d82523d5f602084013e6122ce565b606091505b50915091508180156122e1575080516020145b6122ec576012612190565b8080602001905181019061219091906139be565b6002600154036123525760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b0d565b6002600155565b6113608c8c8c8c8c6123708d8d8d8d8d8d8d610940565b612ae4565b6040516340c10f1960e01b81526001600160a01b038381166004830152602482018390528416906340c10f19906044015f604051808303815f87803b1580156123bc575f5ffd5b505af1158015610dd2573d5f5f3e3d5ffd5b6040516001600160a01b0383811660248301526044820183905261242d91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050612c35565b505050565b5f5f61243c610e20565b60405160200161244c91906136d7565b6040516020818303038152906040529050838151602083015ff591506001600160a01b03821661248f576040516331682e8d60e11b815260040160405180910390fd5b5f5f5f858060200190518101906124a691906139f7565b925092509250846001600160a01b0316631624f6c68484846040518463ffffffff1660e01b81526004016124dc939291906135df565b5f604051808303815f87803b1580156124f3575f5ffd5b505af1158015612505573d5f5f3e3d5ffd5b505050505050505092915050565b60018055565b5f6125276004828486613a6f565b61253091613a96565b9050632afa533160e01b6001600160e01b031982160161269f575f80808080808061255e896004818d613a6f565b81019061256b9190613ace565b9650965096509650965096509650336001600160a01b0316876001600160a01b0316146125ab5760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03861630146125d45760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b031663d505accf60e01b1790529151918d169161265291906136d7565b5f604051808303815f865af19150503d805f811461268b576040519150601f19603f3d011682016040523d82523d5f602084013e612690565b606091505b50505050505050505050611f4a565b6001600160e01b031981166323f2ebc360e21b146126d057604051637141605d60e11b815260040160405180910390fd5b5f808080808080806126e58a6004818e613a6f565b8101906126f29190613b1d565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146127345760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038716301461275d5760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918e16916127e491906136d7565b5f604051808303815f865af19150503d805f811461281d576040519150601f19603f3d011682016040523d82523d5f602084013e612822565b606091505b505050505050505050505050505050565b6040516001600160a01b038481166024830152838116604483015260648201839052611f4a9186918216906323b872dd906084016123fb565b610dd261287e88888888888888610940565b612c96565b60685460ff166128a657604051635386698160e01b815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3905f90a1565b5f54610100900460ff166129445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610b0d565b6107d8612d55565b6060604082511061296b578180602001905181019061083e9190613b9b565b8151602003612ab1575f5b6020811080156129a55750828181518110612993576129936135cb565b01602001516001600160f81b03191615155b156129bc57806129b481613bcd565b915050612976565b805f036129f35750506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b6020820152919050565b5f8167ffffffffffffffff811115612a0d57612a0d613412565b6040519080825280601f01601f191660200182016040528015612a37576020820181803683370190505b5090505f5b82811015612aa957848181518110612a5657612a566135cb565b602001015160f81c60f81b828281518110612a7357612a736135cb565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600101612a3c565b509392505050565b50506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b602082015290565b919050565b6068545f906501000000000090046001600160a01b031663257b3632612b1386865f9182526020526040902090565b6040518263ffffffff1660e01b8152600401612b3191815260200190565b6020604051808303815f875af1158015612b4d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b719190613762565b9050805f03612b9257604051622f6fad60e01b815260040160405180910390fd5b5f8068010000000000000000871615612bd657869150612bb4848a8489611d6c565b612bd1576040516338105f3b60e21b815260040160405180910390fd5b612c20565b602087901c612be6816001613be5565b9150879250612c01612bf9868c86610baf565b8a8389611d6c565b612c1e576040516338105f3b60e21b815260040160405180910390fd5b505b612c2a8282612dbf565b505050505050505050565b5f612c496001600160a01b03841683612e66565b905080515f14158015612c6d575080806020019051810190612c6b9190613c01565b155b1561242d57604051635274afe760e01b81526001600160a01b0384166004820152602401610b0d565b806001612ca560206002613cff565b612caf9190613779565b60535410612cd0576040516377ae67b360e11b815260040160405180910390fd5b5f60535f8154612cdf90613bcd565b918290555090505f5b6020811015612d4c578082901c600116600103612d1b578260338260208110612d1357612d136135cb565b015550505050565b612d4260338260208110612d3157612d316135cb565b0154845f9182526020526040902090565b9250600101612ce8565b5061242d613d0a565b5f54610100900460ff166125135760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610b0d565b6068545f90610100900463ffffffff16158015612de2575063ffffffff82166001145b15612df4575063ffffffff8216612e1c565b612e0964010000000063ffffffff841661369e565b612e199063ffffffff85166136b5565b90505b600881901c5f8181526069602052604081208054600160ff861690811b91821892839055929091908183169003610dd257604051630c8d9eab60e31b815260040160405180910390fd5b6060610c3783835f845f5f856001600160a01b03168486604051612e8a91906136d7565b5f6040518083038185875af1925050503d805f8114612ec4576040519150601f19603f3d011682016040523d82523d5f602084013e612ec9565b606091505b5091509150612ed9868383612ee3565b9695505050505050565b606082612ef857612ef382612f3f565b610c37565b8151158015612f0f57506001600160a01b0384163b155b15612f3857604051639996b31560e01b81526001600160a01b0385166004820152602401610b0d565b5080610c37565b805115612f4f5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b803563ffffffff81168114612adf575f5ffd5b6001600160a01b0381168114612f68575f5ffd5b5f5f60408385031215612fa3575f5ffd5b612fac83612f6b565b91506020830135612fbc81612f7e565b809150509250929050565b8015158114612f68575f5ffd5b5f5f83601f840112612fe4575f5ffd5b50813567ffffffffffffffff811115612ffb575f5ffd5b602083019150836020828501011115613012575f5ffd5b9250929050565b5f5f5f5f5f6080868803121561302d575f5ffd5b61303686612f6b565b9450602086013561304681612f7e565b9350604086013561305681612fc7565b9250606086013567ffffffffffffffff811115613071575f5ffd5b61307d88828901612fd4565b969995985093965092949392505050565b5f5b838110156130a8578181015183820152602001613090565b50505f910152565b5f81518084526130c781602086016020860161308e565b601f01601f19169290920160200192915050565b602081525f610c3760208301846130b0565b5f602082840312156130fd575f5ffd5b8135610c3781612f7e565b60ff81168114612f68575f5ffd5b5f5f5f5f5f5f5f60e0888a03121561312c575f5ffd5b873561313781613108565b965061314560208901612f6b565b9550604088013561315581612f7e565b945061316360608901612f6b565b9350608088013561317381612f7e565b9699959850939692959460a0840135945060c09093013592915050565b5f602082840312156131a0575f5ffd5b5035919050565b80610400810183101561083e575f5ffd5b5f5f5f61044084860312156131cb575f5ffd5b833592506131dc85602086016131a7565b91506131eb6104208501612f6b565b90509250925092565b5f5f5f5f5f5f60a08789031215613209575f5ffd5b61321287612f6b565b9550602087013561322281612f7e565b945060408701359350606087013561323981612fc7565b9250608087013567ffffffffffffffff811115613254575f5ffd5b61326089828a01612fd4565b979a9699509497509295939492505050565b5f5f60408385031215613283575f5ffd5b61328c83612f6b565b915061329a60208401612f6b565b90509250929050565b5f5f5f5f5f5f5f5f5f5f5f5f6109208d8f0312156132bf575f5ffd5b6132c98e8e6131a7565b9b506132d98e6104008f016131a7565b9a506108008d013599506108208d013598506108408d013597506133006108608e01612f6b565b96506133106108808e0135612f7e565b6108808d013595506133256108a08e01612f6b565b94506108c08d013561333681612f7e565b93506108e08d0135925067ffffffffffffffff6109008e01351115613359575f5ffd5b61336a8e6109008f01358f01612fd4565b81935080925050509295989b509295989b509295989b565b5f5f5f5f5f5f5f60c0888a031215613398575f5ffd5b6133a188612f6b565b965060208801356133b181612f7e565b95506040880135945060608801356133c881612f7e565b935060808801356133d881612fc7565b925060a088013567ffffffffffffffff8111156133f3575f5ffd5b6133ff8a828b01612fd4565b989b979a50959850939692959293505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561344f5761344f613412565b604052919050565b5f67ffffffffffffffff82111561347057613470613412565b50601f01601f191660200190565b5f5f5f5f5f5f60c08789031215613493575f5ffd5b61349c87612f6b565b955060208701356134ac81612f7e565b94506134ba60408801612f6b565b935060608701356134ca81612f7e565b925060808701356134da81612f7e565b915060a087013567ffffffffffffffff8111156134f5575f5ffd5b8701601f81018913613505575f5ffd5b803561351861351382613457565b613426565b8181528a602083850101111561352c575f5ffd5b816020840160208301375f602083830101528093505050509295509295509295565b5f5f5f5f6104608587031215613562575f5ffd5b8435935061357386602087016131a7565b92506135826104208601612f6b565b939692955092936104400135925050565b600181811c908216806135a757607f821691505b6020821081036135c557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b606081525f6135f160608301866130b0565b828103602084015261360381866130b0565b91505060ff83166040830152949350505050565b5f61362461351384613457565b9050828152838383011115613637575f5ffd5b610c3783602083018461308e565b5f60208284031215613655575f5ffd5b815167ffffffffffffffff81111561366b575f5ffd5b8201601f8101841361367b575f5ffd5b61219084825160208401613617565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761083e5761083e61368a565b8082018082111561083e5761083e61368a565b818382375f9101908152919050565b5f82516136e881846020870161308e565b9190910192915050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b63ffffffff861681526001600160a01b03851660208201526001600160a01b0384166040820152608060608201525f6137576080830184866136f2565b979650505050505050565b5f60208284031215613772575f5ffd5b5051919050565b8181038181111561083e5761083e61368a565b60ff8916815263ffffffff881660208201526001600160a01b038716604082015263ffffffff861660608201526001600160a01b03851660808201528360a082015261010060c08201525f6137e56101008301856130b0565b905063ffffffff831660e08301529998505050505050505050565b6001600160a01b038516815263ffffffff84166020820152606060408201525f612ed96060830184866136f2565b601f82111561242d57805f5260205f20601f840160051c810160208510156138535750805b601f840160051c820191505b818110156108ad575f815560010161385f565b815167ffffffffffffffff81111561388c5761388c613412565b6138a08161389a8454613593565b8461382e565b6020601f8211600181146138d2575f83156138bb5750848201515b5f19600385901b1c1916600184901b1784556108ad565b5f84815260208120601f198516915b8281101561390157878501518255602094850194600190920191016138e1565b508482101561391e57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b60ff8a16815263ffffffff891660208201526001600160a01b038816604082015263ffffffff871660608201526001600160a01b03861660808201528460a082015261010060c08201525f613987610100830185876136f2565b905063ffffffff831660e08301529a9950505050505050505050565b5f602082840312156139b3575f5ffd5b8151610c3781612f7e565b5f602082840312156139ce575f5ffd5b8151610c3781613108565b5f82601f8301126139e8575f5ffd5b610c3783835160208501613617565b5f5f5f60608486031215613a09575f5ffd5b835167ffffffffffffffff811115613a1f575f5ffd5b613a2b868287016139d9565b935050602084015167ffffffffffffffff811115613a47575f5ffd5b613a53868287016139d9565b9250506040840151613a6481613108565b809150509250925092565b5f5f85851115613a7d575f5ffd5b83861115613a89575f5ffd5b5050820193919092039150565b80356001600160e01b03198116906004841015613ac7576001600160e01b0319600485900360031b81901b82161691505b5092915050565b5f5f5f5f5f5f5f60e0888a031215613ae4575f5ffd5b8735613aef81612f7e565b96506020880135613aff81612f7e565b95506040880135945060608801359350608088013561317381613108565b5f5f5f5f5f5f5f5f610100898b031215613b35575f5ffd5b8835613b4081612f7e565b97506020890135613b5081612f7e565b965060408901359550606089013594506080890135613b6e81612fc7565b935060a0890135613b7e81613108565b979a969950949793969295929450505060c08201359160e0013590565b5f60208284031215613bab575f5ffd5b815167ffffffffffffffff811115613bc1575f5ffd5b612190848285016139d9565b5f60018201613bde57613bde61368a565b5060010190565b63ffffffff818116838216019081111561083e5761083e61368a565b5f60208284031215613c11575f5ffd5b8151610c3781612fc7565b6001815b6001841115613c5757808504811115613c3b57613c3b61368a565b6001841615613c4957908102905b60019390931c928002613c20565b935093915050565b5f82613c6d5750600161083e565b81613c7957505f61083e565b8160018114613c8f5760028114613c9957613cb5565b600191505061083e565b60ff841115613caa57613caa61368a565b50506001821b61083e565b5060208310610133831016604e8410600b8410161715613cd8575081810a61083e565b613ce45f198484613c1c565b805f1904821115613cf757613cf761368a565b029392505050565b5f610c378383613c5f565b634e487b7160e01b5f52600160045260245ffdfea2646970667358221220063c266597e2ffb56d9201c033295ea34c1635e74b868a78fefd4480fab2183364736f6c634300081c0033", - "storage": null - }, - "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851": { - "contractName": "PolygonZkEVMBridgeV2 proxy", - "balance": "340282366920938463463374607431768211455", - "nonce": "1", - "code": "0x60806040526004361061005d575f3560e01c80635c60da1b116100425780635c60da1b146100a65780638f283970146100e3578063f851a440146101025761006c565b80633659cfe6146100745780634f1ef286146100935761006c565b3661006c5761006a610116565b005b61006a610116565b34801561007f575f5ffd5b5061006a61008e366004610854565b610130565b61006a6100a136600461086d565b610178565b3480156100b1575f5ffd5b506100ba6101eb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee575f5ffd5b5061006a6100fd366004610854565b610228565b34801561010d575f5ffd5b506100ba610255565b61011e610282565b61012e610129610359565b610362565b565b610138610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d8160405180602001604052805f8152505f6103bf565b50565b61016d610116565b610180610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101e3576101de8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250600192506103bf915050565b505050565b6101de610116565b5f6101f4610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610359565b905090565b610225610116565b90565b610230610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d816103e9565b5f61025e610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610380565b61028a610380565b73ffffffffffffffffffffffffffffffffffffffff16330361012e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b5f61021861044a565b365f5f375f5f365f845af43d5f5f3e80801561037c573d5ff35b3d5ffd5b5f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103c883610471565b5f825111806103d45750805b156101de576103e383836104bd565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610412610380565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161016d816104e9565b5f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103a3565b61047a816105f5565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606104e28383604051806060016040528060278152602001610979602791396106c0565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811661058c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610350565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610350565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105af565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff16856040516106e9919061090d565b5f60405180830381855af49150503d805f8114610721576040519150601f19603f3d011682016040523d82523d5f602084013e610726565b606091505b509150915061073786838387610741565b9695505050505050565b606083156107d65782515f036107cf5773ffffffffffffffffffffffffffffffffffffffff85163b6107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610350565b50816107e0565b6107e083836107e8565b949350505050565b8151156107f85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103509190610928565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f575f5ffd5b919050565b5f60208284031215610864575f5ffd5b6104e28261082c565b5f5f5f6040848603121561087f575f5ffd5b6108888461082c565b9250602084013567ffffffffffffffff8111156108a3575f5ffd5b8401601f810186136108b3575f5ffd5b803567ffffffffffffffff8111156108c9575f5ffd5b8660208284010111156108da575f5ffd5b939660209190910195509293505050565b5f5b838110156109055781810151838201526020016108ed565b50505f910152565b5f825161091e8184602087016108eb565b9190910192915050565b602081525f82518060208401526109468160408501602087016108eb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e5f7d1b8c5bf56b8d0f8312db5fe19231c55d442867ab851e163d2e86985168464736f6c634300081c0033", - "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000012060ca70f50a24fde90fea110002c235f558a56", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000c2c5fb710e85bedc5c18a8a0fa931d75983f2185" - } - }, - "0x21BD2401BA404841c7feC1816F5a0AaAdbc486eF": { - "contractName": "PolygonZkEVMGlobalExitRootL2 implementation", - "balance": "0", - "nonce": "1", - "code": "0x608060405234801561000f575f5ffd5b506004361061004a575f3560e01c806301fd90441461004e578063257b36321461006a57806333d6247d14610089578063a3c573eb1461009e575b5f5ffd5b61005760015481565b6040519081526020015b60405180910390f35b61005761007836600461015e565b5f6020819052908152604090205481565b61009c61009736600461015e565b6100ea565b005b6100c57f000000000000000000000000b2fac1ce54bb9bf77a7fe106fa69f81453b7285181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610061565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000b2fac1ce54bb9bf77a7fe106fa69f81453b728511614610159576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b5f6020828403121561016e575f5ffd5b503591905056fea2646970667358221220f0c42c4ea26e8c61a4cac40e1273224f46c3c1fd3c84d399b407eb29edfebdc864736f6c634300081c0033", - "storage": null - }, - "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa": { - "contractName": "PolygonZkEVMGlobalExitRootL2 proxy", - "balance": "0", - "nonce": "1", - "code": "0x60806040523661001357610011610017565b005b6100115b61001f6101b7565b6001600160a01b0316336001600160a01b0316141561016f5760606001600160e01b031960003516631b2ce7f360e11b8114156100655761005e6101ea565b9150610167565b6001600160e01b0319811663278f794360e11b14156100865761005e610241565b6001600160e01b031981166308f2839760e41b14156100a75761005e610287565b6001600160e01b031981166303e1469160e61b14156100c85761005e6102b8565b6001600160e01b03198116635c60da1b60e01b14156100e95761005e6102f8565b60405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b815160208301f35b61017761030c565b565b606061019e83836040518060600160405280602781526020016108576027913961031c565b9392505050565b90565b6001600160a01b03163b151590565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b60606101f4610394565b600061020336600481846106a2565b81019061021091906106e8565b905061022d8160405180602001604052806000815250600061039f565b505060408051602081019091526000815290565b606060008061025336600481846106a2565b8101906102609190610719565b915091506102708282600161039f565b604051806020016040528060008152509250505090565b6060610291610394565b60006102a036600481846106a2565b8101906102ad91906106e8565b905061022d816103cb565b60606102c2610394565b60006102cc6101b7565b604080516001600160a01b03831660208201529192500160405160208183030381529060405291505090565b6060610302610394565b60006102cc610422565b610177610317610422565b610431565b6060600080856001600160a01b0316856040516103399190610807565b600060405180830381855af49150503d8060008114610374576040519150601f19603f3d011682016040523d82523d6000602084013e610379565b606091505b509150915061038a86838387610455565b9695505050505050565b341561017757600080fd5b6103a8836104d3565b6000825111806103b55750805b156103c6576103c48383610179565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103f46101b7565b604080516001600160a01b03928316815291841660208301520160405180910390a161041f81610513565b50565b600061042c6105bc565b905090565b3660008037600080366000845af43d6000803e808015610450573d6000f35b3d6000fd5b606083156104c15782516104ba576001600160a01b0385163b6104ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161015e565b50816104cb565b6104cb83836105e4565b949350505050565b6104dc8161060e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105785760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6101db565b8151156105f45781518083602001fd5b8060405162461bcd60e51b815260040161015e9190610823565b6001600160a01b0381163b61067b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161015e565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61059b565b600080858511156106b257600080fd5b838611156106bf57600080fd5b5050820193919092039150565b80356001600160a01b03811681146106e357600080fd5b919050565b6000602082840312156106fa57600080fd5b61019e826106cc565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561072c57600080fd5b610735836106cc565b9150602083013567ffffffffffffffff8082111561075257600080fd5b818501915085601f83011261076657600080fd5b81358181111561077857610778610703565b604051601f8201601f19908116603f011681019083821181831017156107a0576107a0610703565b816040528281528860208487010111156107b957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b838110156107f65781810151838201526020016107de565b838111156103c45750506000910152565b600082516108198184602087016107db565b9190910192915050565b60208152600082518060208401526108428160408501602087016107db565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122012bb4f564f73959a03513dc74fc3c6e40e8386e6f02c16b78d6db00ce0aa16af64736f6c63430008090033", - "storage": { - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000021bd2401ba404841c7fec1816f5a0aaadbc486ef", - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000c2c5fb710e85bedc5c18a8a0fa931d75983f2185" - } - }, - "0x27284DBa79e6DF953Fbd232A9d8D87029F03BBf5": { - "contractName": "PolygonZkEVMTimelock", - "balance": "0", - "nonce": "1", - "code": "0x6080604052600436106101bd575f3560e01c806364d62353116100f2578063b1c5f42711610092578063d547741f11610062578063d547741f1461063a578063e38335e514610659578063f23a6e611461066c578063f27a0c92146106b0575f80fd5b8063b1c5f4271461058d578063bc197c81146105ac578063c4d252f5146105f0578063d45c44351461060f575f80fd5b80638f61f4f5116100cd5780638f61f4f5146104c557806391d14854146104f8578063a217fddf14610547578063b08e51c01461055a575f80fd5b806364d62353146104685780638065657f146104875780638f2a0bb0146104a6575f80fd5b8063248a9ca31161015d57806331d507501161013857806331d50750146103b357806336568abe146103d25780633a6aae72146103f1578063584b153e14610449575f80fd5b8063248a9ca3146103375780632ab0f529146103655780632f2ff15d14610394575f80fd5b80630d3cf6fc116101985780630d3cf6fc1461025e578063134008d31461029157806313bc9f20146102a4578063150b7a02146102c3575f80fd5b806301d5062a146101c857806301ffc9a7146101e957806307bd02651461021d575f80fd5b366101c457005b5f80fd5b3480156101d3575f80fd5b506101e76101e2366004611bf6565b6106c4565b005b3480156101f4575f80fd5b50610208610203366004611c65565b610757565b60405190151581526020015b60405180910390f35b348015610228575f80fd5b506102507fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610214565b348015610269575f80fd5b506102507f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101e761029f366004611ca4565b6107b2565b3480156102af575f80fd5b506102086102be366004611d0b565b6108a7565b3480156102ce575f80fd5b506103066102dd366004611e28565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610214565b348015610342575f80fd5b50610250610351366004611d0b565b5f9081526020819052604090206001015490565b348015610370575f80fd5b5061020861037f366004611d0b565b5f908152600160208190526040909120541490565b34801561039f575f80fd5b506101e76103ae366004611e8c565b6108cc565b3480156103be575f80fd5b506102086103cd366004611d0b565b6108f5565b3480156103dd575f80fd5b506101e76103ec366004611e8c565b61090d565b3480156103fc575f80fd5b506104247f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b348015610454575f80fd5b50610208610463366004611d0b565b6109c5565b348015610473575f80fd5b506101e7610482366004611d0b565b6109da565b348015610492575f80fd5b506102506104a1366004611ca4565b610aaa565b3480156104b1575f80fd5b506101e76104c0366004611ef7565b610ae8565b3480156104d0575f80fd5b506102507fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b348015610503575f80fd5b50610208610512366004611e8c565b5f9182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610552575f80fd5b506102505f81565b348015610565575f80fd5b506102507ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b348015610598575f80fd5b506102506105a7366004611fa0565b610d18565b3480156105b7575f80fd5b506103066105c63660046120be565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b3480156105fb575f80fd5b506101e761060a366004611d0b565b610d5c565b34801561061a575f80fd5b50610250610629366004611d0b565b5f9081526001602052604090205490565b348015610645575f80fd5b506101e7610654366004611e8c565b610e56565b6101e7610667366004611fa0565b610e7a565b348015610677575f80fd5b50610306610686366004612161565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106bb575f80fd5b50610250611121565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc16106ee81611200565b5f6106fd898989898989610aaa565b9050610709818461120d565b5f817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a60405161074496959493929190612208565b60405180910390a3505050505050505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107ac57506107ac82611359565b92915050565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661082e5761082e81336113ef565b5f61083d888888888888610aaa565b905061084981856114a6565b610855888888886115e2565b5f817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a60405161088c9493929190612252565b60405180910390a361089d816116e2565b5050505050505050565b5f818152600160205260408120546001811180156108c55750428111155b9392505050565b5f828152602081905260409020600101546108e681611200565b6108f0838361178a565b505050565b5f8181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109c18282611878565b5050565b5f818152600160208190526040822054610906565b333014610a69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109ae565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b5f868686868686604051602001610ac696959493929190612208565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b1281611200565b888714610ba1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b888514610c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f610c418b8b8b8b8b8b8b8b610d18565b9050610c4d818461120d565b5f5b8a811015610d0a5780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610c8c57610c8c612291565b9050602002016020810190610ca191906122be565b8d8d86818110610cb357610cb3612291565b905060200201358c8c87818110610ccc57610ccc612291565b9050602002810190610cde91906122d7565b8c8b604051610cf296959493929190612208565b60405180910390a3610d0381612365565b9050610c4f565b505050505050505050505050565b5f8888888888888888604051602001610d38989796959493929190612447565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610d8681611200565b610d8f826109c5565b610e1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109ae565b5f828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b5f82815260208190526040902060010154610e7081611200565b6108f08383611878565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610ef657610ef681336113ef565b878614610f85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b878414611014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f6110258a8a8a8a8a8a8a8a610d18565b905061103181856114a6565b5f5b8981101561110b575f8b8b8381811061104e5761104e612291565b905060200201602081019061106391906122be565b90505f8a8a8481811061107857611078612291565b905060200201359050365f8a8a8681811061109557611095612291565b90506020028101906110a791906122d7565b915091506110b7848484846115e2565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58868686866040516110ee9493929190612252565b60405180910390a3505050508061110490612365565b9050611033565b50611115816116e2565b50505050505050505050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16158015906111ef57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ef919061250c565b156111f957505f90565b5060025490565b61120a81336113ef565b50565b611216826108f5565b156112a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109ae565b6112ab611121565b81101561133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109ae565b611344814261252b565b5f928352600160205260409092209190915550565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107ac57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107ac565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c15761142c8161192d565b61143783602061194c565b604051602001611448929190612560565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109ae916004016125e0565b6114af826108a7565b61153b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b80158061155657505f81815260016020819052604090912054145b6109c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f8473ffffffffffffffffffffffffffffffffffffffff1684848460405161160b929190612630565b5f6040518083038185875af1925050503d805f8114611645576040519150601f19603f3d011682016040523d82523d5f602084013e61164a565b606091505b50509050806116db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109ae565b5050505050565b6116eb816108a7565b611777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b5f90815260016020819052604090912055565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561181a3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107ac73ffffffffffffffffffffffffffffffffffffffff831660145b60605f61195a83600261263f565b61196590600261252b565b67ffffffffffffffff81111561197d5761197d611d22565b6040519080825280601f01601f1916602001820160405280156119a7576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106119dd576119dd612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a3f57611a3f612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f611a7984600261263f565b611a8490600161252b565b90505b6001811115611b20577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611ac557611ac5612291565b1a60f81b828281518110611adb57611adb612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c93611b1981612656565b9050611a87565b5083156108c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109ae565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bac575f80fd5b919050565b5f8083601f840112611bc1575f80fd5b50813567ffffffffffffffff811115611bd8575f80fd5b602083019150836020828501011115611bef575f80fd5b9250929050565b5f805f805f805f60c0888a031215611c0c575f80fd5b611c1588611b89565b965060208801359550604088013567ffffffffffffffff811115611c37575f80fd5b611c438a828b01611bb1565b989b979a50986060810135976080820135975060a09091013595509350505050565b5f60208284031215611c75575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108c5575f80fd5b5f805f805f8060a08789031215611cb9575f80fd5b611cc287611b89565b955060208701359450604087013567ffffffffffffffff811115611ce4575f80fd5b611cf089828a01611bb1565b979a9699509760608101359660809091013595509350505050565b5f60208284031215611d1b575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d9657611d96611d22565b604052919050565b5f82601f830112611dad575f80fd5b813567ffffffffffffffff811115611dc757611dc7611d22565b611df860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d4f565b818152846020838601011115611e0c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611e3b575f80fd5b611e4485611b89565b9350611e5260208601611b89565b925060408501359150606085013567ffffffffffffffff811115611e74575f80fd5b611e8087828801611d9e565b91505092959194509250565b5f8060408385031215611e9d575f80fd5b82359150611ead60208401611b89565b90509250929050565b5f8083601f840112611ec6575f80fd5b50813567ffffffffffffffff811115611edd575f80fd5b6020830191508360208260051b8501011115611bef575f80fd5b5f805f805f805f805f60c08a8c031215611f0f575f80fd5b893567ffffffffffffffff80821115611f26575f80fd5b611f328d838e01611eb6565b909b50995060208c0135915080821115611f4a575f80fd5b611f568d838e01611eb6565b909950975060408c0135915080821115611f6e575f80fd5b50611f7b8c828d01611eb6565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b5f805f805f805f8060a0898b031215611fb7575f80fd5b883567ffffffffffffffff80821115611fce575f80fd5b611fda8c838d01611eb6565b909a50985060208b0135915080821115611ff2575f80fd5b611ffe8c838d01611eb6565b909850965060408b0135915080821115612016575f80fd5b506120238b828c01611eb6565b999c989b509699959896976060870135966080013595509350505050565b5f82601f830112612050575f80fd5b8135602067ffffffffffffffff82111561206c5761206c611d22565b8160051b61207b828201611d4f565b9283528481018201928281019087851115612094575f80fd5b83870192505b848310156120b35782358252918301919083019061209a565b979650505050505050565b5f805f805f60a086880312156120d2575f80fd5b6120db86611b89565b94506120e960208701611b89565b9350604086013567ffffffffffffffff80821115612105575f80fd5b61211189838a01612041565b94506060880135915080821115612126575f80fd5b61213289838a01612041565b93506080880135915080821115612147575f80fd5b5061215488828901611d9e565b9150509295509295909350565b5f805f805f60a08688031215612175575f80fd5b61217e86611b89565b945061218c60208701611b89565b93506040860135925060608601359150608086013567ffffffffffffffff8111156121b5575f80fd5b61215488828901611d9e565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a060408201525f61223d60a0830186886121c1565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201525f6122876060830184866121c1565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082840312156122ce575f80fd5b6108c582611b89565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261230a575f80fd5b83018035915067ffffffffffffffff821115612324575f80fd5b602001915036819003821315611bef575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361239557612395612338565b5060010190565b8183525f6020808501808196508560051b81019150845f5b8781101561243a57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126123f2575f80fd5b8701858101903567ffffffffffffffff81111561240d575f80fd5b80360382131561241b575f80fd5b6124268682846121c1565b9a87019a95505050908401906001016123b4565b5091979650505050505050565b60a080825281018890525f8960c08301825b8b8110156124945773ffffffffffffffffffffffffffffffffffffffff61247f84611b89565b16825260209283019290910190600101612459565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8911156124cc575f80fd5b8860051b9150818a602083013701828103602090810160408501526124f4908201878961239c565b60608401959095525050608001529695505050505050565b5f6020828403121561251c575f80fd5b815180151581146108c5575f80fd5b808201808211156107ac576107ac612338565b5f5b83811015612558578181015183820152602001612540565b50505f910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f835161259781601785016020880161253e565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516125d481602884016020880161253e565b01602801949350505050565b602081525f82518060208401526125fe81604085016020870161253e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b818382375f9101908152919050565b80820281158282048414176107ac576107ac612338565b5f8161266457612664612338565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220ffae92f944289ff2d8d50b1f6dc43374b9a4ff2979d908883d35eec5819b612c64736f6c63430008140033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", - "0x35fa115b92f0a8d03c972ada19f34c3fa238589ba573a59a419692abc6a91f1a": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x3e92e57d702d5fdc47a588386c93df7f5578fb6af324e63318e76ec6cffcab32": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", - "0x6b347b5397bd05b592ec00f3e3a28ac3cedc5d7ee6994c7533215f223a0cfe84": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x73aec4d9eb3be1097d809826691104f0c28da74ebf68d903dc9c6f12562fd822": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xc05edde0499e76380516353a6ad6ced0d360179c67da013977526f6fbac38774": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", - "0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5" - } - }, - "0x6Ea4D2dd7dFEb6945d1B57a42DC68FE7E06126ce": { - "contractName": null, - "balance": "0", - "nonce": "1", - "code": null, - "storage": null - }, - "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534": { - "contractName": null, - "balance": "100000000000000000000000", - "nonce": "8", - "code": null, - "storage": null - } -} \ No newline at end of file diff --git a/test-pp-op/config/dynamic-mynetwork-chainspec.json b/test-pp-op/config/dynamic-mynetwork-chainspec.json deleted file mode 100644 index 62d49e44e1b6b..0000000000000 --- a/test-pp-op/config/dynamic-mynetwork-chainspec.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "ChainName": "dynamic-mynetwork", - "chainId": 195, - "consensus": "ethash", - "homesteadBlock": 0, - "daoForkBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "berlinBlock": 0, - "londonBlock": 9999999999999999999999999999999999999999999999999, - "arrowGlacierBlock": 9999999999999999999999999999999999999999999999999, - "grayGlacierBlock": 9999999999999999999999999999999999999999999999999, - "terminalTotalDifficulty": 58750000000000000000000, - "terminalTotalDifficultyPassed": false, - "shanghaiTime": 9999999999999999999999999999999999999999999999999, - "cancunTime": 9999999999999999999999999999999999999999999999999, - "pragueTime": 9999999999999999999999999999999999999999999999999, - "ethash": {} -} - diff --git a/test-pp-op/config/dynamic-mynetwork-conf.json b/test-pp-op/config/dynamic-mynetwork-conf.json deleted file mode 100644 index 9ce28d4252cc1..0000000000000 --- a/test-pp-op/config/dynamic-mynetwork-conf.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": "0x6565265b546acdc3b714218d5bdb667725002a6fa07b5045f5ed4ad7595ebd62", - "timestamp": 1760602860, - "gasLimit": 0, - "difficulty": 0 -} diff --git a/test-pp-op/config/first-batch-config.json b/test-pp-op/config/first-batch-config.json deleted file mode 100644 index f622df8200c75..0000000000000 --- a/test-pp-op/config/first-batch-config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "batchL2Data": "0xf901e480808401c9c38094b2fac1ce54bb9bf77a7fe106fa69f81453b7285180b901c4f811bff700000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000084f4b42546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034f4b42000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005ca1ab1e0000000000000000000000000000000000000000000000000000000005ca1ab1e1bff", - "globalExitRoot": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", - "timestamp": 1760602860, - "sequencer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "l1BlockNumber": 100, - "l1BlockHash": "0xfbd5bff822e23e6864b1185686864ac8bc9a7645756dce00586ed909b9f3c78e", - "l1ParentHash": "0xd3bf883426e5f8f374ed2699fc9c9026d136e212c57f4fc48288f8c2d189fadd" -} diff --git a/test-pp-op/config/local/local.erigon.rpc.config.yaml b/test-pp-op/config/local/local.erigon.rpc.config.yaml deleted file mode 100644 index 9368b7782aa84..0000000000000 --- a/test-pp-op/config/local/local.erigon.rpc.config.yaml +++ /dev/null @@ -1,114 +0,0 @@ -datadir: /home/erigon/data/ -chain: dynamic-mynetwork -http: true -private.api.addr: localhost:9091 -zkevm.l2-chain-id: 195 -zkevm.l2-sequencer-rpc-url: xlayer-seq:8545 -zkevm.l2-datastreamer-url: xlayer-seq:6900 -zkevm.l1-chain-id: 1337 -zkevm.l1-rpc-url: http://xlayer-mock-l1-network:8545 -zkevm.l1-highest-block-type: latest - -zkevm.address-sequencer: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" -zkevm.address-zkevm: "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" -zkevm.address-admin: "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" -zkevm.address-rollup: "0xE96dBF374555C6993618906629988d39184716B3" -zkevm.address-ger-manager: "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" - -zkevm.l1-rollup-id: 1 -zkevm.l1-first-block: 75 -zkevm.l1-block-range: 10 -zkevm.l1-query-delay: 6000 -zkevm.rpc-ratelimit: 0 -zkevm.datastream-version: 2 - -log.console.verbosity: info - -#zkevm.executor-urls: xlayer-executor:50071 -# zkevm.executor-strict: false -# zkevm.witness-full: false -# zkevm.executor-mock: true - -zkevm.sequencer-block-seal-time: "1s" -zkevm.sequencer-max-block-seal-time: "3s" -zkevm.sequencer-batch-seal-time: "10s" -zkevm.sequencer-batch-sleep-duration: "0s" - -#zkevm.data-stream-host: "localhost" -#zkevm.data-stream-port: 6900 -zkevm.default-gas-price: 1000000000 -zkevm.max-gas-price: 0 -zkevm.gas-price-factor: 0.000001 -zkevm.allow-free-transactions: true - -externalcl: true -http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] -http.addr: 0.0.0.0 -http.port: 8545 -http.vhosts: any -http.corsdomain: any -http.timeouts.read: "10s" -http.timeouts.write: "10s" -http.timeouts.idle: "10s" -rpc.batch.concurrency: 2 -rpc.batch.limit: 20 -ws: true - -zkevm.apollo-enabled: false -zkevm.apollo-ip-addr: "" -zkevm.apollo-app-id: "" -zkevm.apollo-namespace-name: "" - -zkevm.nacos-urls: "" -zkevm.nacos-namespace-id: "" -zkevm.nacos-application-name: "" -zkevm.nacos-external-listen-addr: "" - -metrics: true -metrics.addr: "0.0.0.0" -metrics.port: 9095 - -db.read.concurrency: 20000 -txpool.globalslots: 1000000 -txpool.globalbasefeeslots: 1000000 -txpool.globalqueue: 1000000 -txpool.packbatchspeciallist : ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534"] -txpool.gaspricemultiple : 2 -txpool.blockedlist: ["0xdD2FD4581271e230360230F9337D5c0430Bf44C0"] -txpool.enablefreegasbynonce : true -txpool.freegascountperaddr : 100 -txpool.commit.every: "10m" - -gpo.type: "follower" -gpo.update-period: "3s" -gpo.factor: 0.01 -gpo.kafka-url: "0.0.0.0" -gpo.topic: "explorer" -gpo.group-id: "web3" -gpo.blocks: 3 -gpo.default-l1-coin-price: 2000 -gpo.default-l2-coin-price: 50 -gpo.gas-price-usdt: 0.000000476190476 -gpo.congestion-threshold: 0 - -networkid: 195 - -pprof: true -pprof.port: 6060 -pprof.addr: 0.0.0.0 -txpool.enablefreegaslist : true -txpool.freegaslist : '[{"name":"e2e", "from_list":["0x586cbc95ed16031d9efdaebacf1c1d2bc3ccaa78"], "to_list":["0xad1d01007a56ee0a4ffd0488fb58fc6500cb1fbe"], "method_sigs":["a9059cbb"], "gas_price_multiple": 1}]' - -# close a block/batch immediately after the 1st zkCounter overflow TX -zkevm.seal-batch-immediately-on-overflow: true -zkevm.sequencer-timeout-on-empty-tx-pool: 5ms -zkevm.pre-run-address-list: [""] -zkevm.block-info-concurrent: true -zkevm.standalone-smt-db: true # true: enable split smt db, false: not split -zkevm.enable-async-commit: true - -# to reduce lock race in stress test -txpool.enabletimsort: true -zkevm.bulk-add-txs: true -zkevm.enable-add-tx-notify: true -zkevm.initial-batch.config: /usr/src/app/first-batch-config.json \ No newline at end of file diff --git a/test-pp-op/config/local/local.erigon.seq.config.yaml b/test-pp-op/config/local/local.erigon.seq.config.yaml deleted file mode 100644 index 05534cd103af4..0000000000000 --- a/test-pp-op/config/local/local.erigon.seq.config.yaml +++ /dev/null @@ -1,109 +0,0 @@ -datadir: /home/erigon/data/ -chain: dynamic-mynetwork -http: true -private.api.addr: localhost:9091 -zkevm.l2-chain-id: 195 -zkevm.l2-sequencer-rpc-url: -zkevm.l2-datastreamer-url: -zkevm.l1-chain-id: 1337 -zkevm.l1-rpc-url: http://xlayer-mock-l1-network:8545 -zkevm.l1-highest-block-type: latest - -zkevm.address-sequencer: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" -zkevm.address-zkevm: "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" -zkevm.address-admin: "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" -zkevm.address-rollup: "0xE96dBF374555C6993618906629988d39184716B3" -zkevm.address-ger-manager: "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" - -zkevm.l1-rollup-id: 1 -zkevm.l1-first-block: 156 -zkevm.l1-block-range: 10 -zkevm.l1-query-delay: 6000 -zkevm.rpc-ratelimit: 0 -zkevm.datastream-version: 2 - -log.console.verbosity: info - -zkevm.sequencer-block-seal-time: "1s" -zkevm.sequencer-max-block-seal-time: "3s" -zkevm.sequencer-batch-seal-time: "10s" -zkevm.sequencer-batch-sleep-duration: "0s" - -zkevm.data-stream-host: "localhost" -zkevm.data-stream-port: 6900 -zkevm.default-gas-price: 1000000000 -zkevm.max-gas-price: 0 -zkevm.gas-price-factor: 0.000001 -zkevm.allow-free-transactions: true - -externalcl: true -http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] -http.addr: 0.0.0.0 -http.port: 8545 -http.vhosts: any -http.corsdomain: any -http.timeouts.read: "10s" -http.timeouts.write: "10s" -http.timeouts.idle: "10s" -rpc.batch.concurrency: 2 -rpc.batch.limit: 20 -ws: true - -zkevm.apollo-enabled: false -zkevm.apollo-ip-addr: "" -zkevm.apollo-app-id: "" -zkevm.apollo-namespace-name: "" - -zkevm.nacos-urls: "" -zkevm.nacos-namespace-id: "" -zkevm.nacos-application-name: "" -zkevm.nacos-external-listen-addr: "" - -metrics: true -metrics.addr: "0.0.0.0" -metrics.port: 9095 - -db.read.concurrency: 20000 -txpool.globalslots: 1000000 -txpool.globalbasefeeslots: 1000000 -txpool.globalqueue: 1000000 -txpool.packbatchspeciallist : ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534"] -txpool.gaspricemultiple : 2 -txpool.blockedlist: ["0xdD2FD4581271e230360230F9337D5c0430Bf44C0"] -txpool.enablefreegasbynonce : true -txpool.freegascountperaddr : 100 -txpool.commit.every: "10m" - -gpo.type: "follower" -gpo.update-period: "3s" -gpo.factor: 0.01 -gpo.kafka-url: "0.0.0.0" -gpo.topic: "explorer" -gpo.group-id: "web3" -gpo.blocks: 3 -gpo.default-l1-coin-price: 2000 -gpo.default-l2-coin-price: 50 -gpo.gas-price-usdt: 0.000000476190476 -gpo.congestion-threshold: 0 - -networkid: 195 - -pprof: true -pprof.port: 6060 -pprof.addr: 0.0.0.0 -txpool.enablefreegaslist : true -txpool.freegaslist : '[{"name":"e2e", "from_list":["0x586cbc95ed16031d9efdaebacf1c1d2bc3ccaa78"], "to_list":["0xad1d01007a56ee0a4ffd0488fb58fc6500cb1fbe"], "method_sigs":["a9059cbb"], "gas_price_multiple": 1}]' - -# close a block/batch immediately after the 1st zkCounter overflow TX -zkevm.seal-batch-immediately-on-overflow: true -zkevm.sequencer-timeout-on-empty-tx-pool: 5ms -zkevm.pre-run-address-list: [""] -zkevm.block-info-concurrent: true -zkevm.standalone-smt-db: true # true: enable split smt db, false: not split -zkevm.enable-async-commit: true - -# to reduce lock race in stress test -txpool.enabletimsort: true -zkevm.bulk-add-txs: true -zkevm.enable-add-tx-notify: true -zkevm.initial-batch.config: /usr/src/app/first-batch-config.json diff --git a/test-pp-op/config/test.bridge.config.toml b/test-pp-op/config/test.bridge.config.toml deleted file mode 100644 index 87b7fc7e05729..0000000000000 --- a/test-pp-op/config/test.bridge.config.toml +++ /dev/null @@ -1,132 +0,0 @@ -[Log] -# Set the logging level (e.g., debug, info, warn, error) to control verbosity -Level = "debug" -# Specify the environment in which the application is running (e.g., production, development) -Environment = "production" -# Define where to output logs; options include stderr (standard error) or stdout -Outputs = ["stderr"] - -# Database Synchronization Configuration -# This section contains the database connection settings required for -# synchronizing data. -[SyncDB] -# Type of database to use (e.g., postgres) -Database = "postgres" - [SyncDB.PgStorage] - # Username for database authentication - User = "test_user" - # Name of the database to connect to - Name = "test_db" - # Password for the database user - Password = "test_password" - # Host address of the database server - Host = "xlayer-bridge-db" - # Port number on which the database server is listening - Port = "5432" - # Maximum number of concurrent connections to the database - MaxConns = 20 - -# Etherman Configuration -# This section specifies the RPC URLs for interacting with Layer 1 and Layer 2's. -[Etherman] -# URL for Layer 1 RPC endpoint to interact with the main blockchain -L1URL = "http://l1-geth:8545" -# URLs for Layer 2 RPC endpoints -L2URLs = ["http://xlayer-rpc:8545"] - -# Synchronization Settings -# This section defines the parameters for synchronizing data, including -# the interval and chunk size for synchronization operations. -[Synchronizer] -# Time interval for synchronization iterations (e.g., every 5 seconds) -SyncInterval = "1s" -# Number of blocks to read in each synchronization operation if the service is not synced and if there is enough data. -SyncChunkSize = 50 -# Forces the SyncChunkSize for L2 networks. The chunck size won't be higher than the value specified but if there is not enough events in the network, the reorg protection can be affected. -ForceL2SyncChunk = true - -# Bridge Controller Configuration -# This section contains settings for the bridge controller, including merkle tree height parameter. -[BridgeController] -# Height parameter specifies the height of the merkle tree used for the bridge. -Height = 32 - -# Bridge Server Configuration -# This section defines the settings for the bridge server API, including -# ports for gRPC and HTTP communication, pagination limits, and database. -[BridgeServer] -# Port for gRPC communication with the bridge server -GRPCPort = "9090" -# Port for HTTP communication with the bridge server -HTTPPort = "8080" -# Default limit for paginated results returned by the server -DefaultPageLimit = 25 -# Maximum limit for paginated results to prevent excessive data retrieval -MaxPageLimit = 1000 - # Database configuration for the bridge server. Could be the same config as SyncDB but ideally It should be a read replica to distribute the load. - [BridgeServer.DB] - # Type of database for the bridge server - Database = "postgres" - [BridgeServer.DB.PgStorage] - # Database user for authentication - User = "test_user" - # Database name for the bridge server - Name = "test_db" - # Password for the database user - Password = "test_password" - # Host address of the database server - Host = "xlayer-bridge-db" - # Port number for the database connection - Port = "5432" - # Maximum number of connections to the database for the bridge server - MaxConns = 20 - -# Network Configuration -# This section contains settings related to the network, including smart contract addresses and -# L1 bridge genesis block. -[NetworkConfig] -# Block number where the L1 bridge smart contract was deployed. The bridge needs to compute the merkle tree based on events from that block. -GenBlockNumber = 50 -# Address of the Polygon bridge smc -PolygonBridgeAddress = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" -# Address of the Global exit root smc -PolygonZkEVMGlobalExitRootAddress = "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" -# Address of the rollup manager smc -PolygonRollupManagerAddress = "0xE96dBF374555C6993618906629988d39184716B3" -# Address of the zkEVM smc -PolygonZkEVMAddress = "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" -# List of Layer 2 Polygon bridge addresses. It must have the same length as L2URLs. e.g. If 5 networks need to be synced, the urls must be in this array. -L2PolygonBridgeAddresses = ["0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851"] -# Flag indicating whether to require sovereign chain smcs or not. It must have the same length as L2PolygonBridgeAddresses -RequireSovereignChainSmcs = [false] -# List of global exit root addresses for Layer 2. Same length as L2PolygonBridgeAddresses -L2PolygonZkEVMGlobalExitRootAddresses = ["0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa"] - -# Claim Transaction Manager Configuration -# This section contains settings for managing claim transactions. It includes -# enabling or disabling the ClaimTxManager, monitoring frequency, private key -# configuration, and retry settings for sending transactions. -[ClaimTxManager] -# Enable or disable the claim transaction manager -Enabled = true -# Frequency to monitor transactions -FrequencyToMonitorTxs = "5s" -# Path and password for the private key -PrivateKey = {Path = "/pk/keystore.claimtxmanager", Password = "testonly"} -# Interval between retries -RetryInterval = "1s" -# Number of retry attempts -RetryNumber = 10 - -# Metrics Configuration -# This section defines settings for collecting and exposing metrics related -# to the application's performance and health. It includes options to enable -# or disable metrics collection, as well as the host and port for metrics -# exposure. -[Metrics] -# Enable or disable metrics -Enabled = true -# Host address for the metrics -Host = "0.0.0.0" -# Port for the metrics -Port = "8090" diff --git a/test-pp-op/config/test.erigon.rpc.config.yaml b/test-pp-op/config/test.erigon.rpc.config.yaml deleted file mode 100644 index ce41932f177d6..0000000000000 --- a/test-pp-op/config/test.erigon.rpc.config.yaml +++ /dev/null @@ -1,86 +0,0 @@ -datadir: /home/erigon/data/ -chain: dynamic-mynetwork -http: true -private.api.addr: localhost:9091 -zkevm.l2-chain-id: 195 -zkevm.l2-sequencer-rpc-url: http://xlayer-seq:8545 -zkevm.l2-datastreamer-url: xlayer-seq:6900 -zkevm.l1-chain-id: 1337 -zkevm.l1-rpc-url: http://l1-geth:8545 -zkevm.l1-highest-block-type: latest - -zkevm.address-sequencer: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" -zkevm.address-zkevm: "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" -zkevm.address-admin: "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" -zkevm.address-rollup: "0xE96dBF374555C6993618906629988d39184716B3" -zkevm.address-ger-manager: "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" - -zkevm.l1-rollup-id: 1 -zkevm.l1-first-block: 156 -zkevm.l1-block-range: 10 -zkevm.l1-query-delay: 6000 -zkevm.rpc-ratelimit: 300 -zkevm.datastream-version: 2 - -log.console.verbosity: info - -#zkevm.executor-urls: xlayer-executor:50071 -# zkevm.executor-urls: "" -# zkevm.executor-strict: false -# zkevm.witness-full: false - -zkevm.sequencer-block-seal-time: "6s" -zkevm.sequencer-batch-seal-time: "12s" -zkevm.sequencer-batch-sleep-duration: "0s" - -zkevm.data-stream-host: "localhost" -zkevm.data-stream-port: 6900 -zkevm.default-gas-price: 1000000000 -zkevm.max-gas-price: 0 -zkevm.gas-price-factor: 0.000001 -zkevm.allow-free-transactions: true -zkevm.allow-internal-transactions: true -externalcl: true -http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] -http.addr: 0.0.0.0 -http.port: 8545 -http.vhosts: any -http.corsdomain: any -http.timeouts.read: "10s" -http.timeouts.write: "10s" -http.timeouts.idle: "10s" -http.methodratelimit: "{\"methods\":[\"eth_syncing\"],\"count\":10,\"bucket\":1}" -# http.apikeys: | -# {"project":"Biconomy","key":"45543e0adc5dd3e316044909d32501a5","timeout":"2030-12-31","methods":["eth_syncing"],"count":10000,"bucket":1} - -ws: true - -zkevm.apollo-enabled: false -zkevm.apollo-ip-addr: "" -zkevm.apollo-app-id: "" -zkevm.apollo-namespace-name: "" - -zkevm.nacos-urls: "" -zkevm.nacos-namespace-id: "" -zkevm.nacos-application-name: "" -zkevm.nacos-external-listen-addr: "" - -metrics: true -metrics.addr: "0.0.0.0" -metrics.port: 9095 - -db.read.concurrency: 20000 -txpool.globalslots: 100000 -networkid: 195 - -zkevm.pool-manager-url: http://xlayer-pool-manager:8545 - -http.methodratelimit: "{\"methods\":[\"eth_syncing\"],\"count\":10,\"bucket\":1}" -#http.apikeys: | -# {"project":"project1","key":"944cd2a6939eb23053289d9b91d6c498","timeout":"2033-12-12","methods":["eth_syncing"],"count":5,"bucket":1} - -pprof: true -pprof.port: 6060 -pprof.addr: 0.0.0.0 - -zkevm.standalone-smt-db: true # true: enalbe split smt db, false: not split \ No newline at end of file diff --git a/test-pp-op/config/test.erigon.seq.config.yaml b/test-pp-op/config/test.erigon.seq.config.yaml deleted file mode 100644 index 44c8a3a7a6fe1..0000000000000 --- a/test-pp-op/config/test.erigon.seq.config.yaml +++ /dev/null @@ -1,114 +0,0 @@ -datadir: /home/erigon/data/ -chain: dynamic-mynetwork -http: true -private.api.addr: localhost:9091 -zkevm.l2-chain-id: 195 -zkevm.l2-sequencer-rpc-url: -zkevm.l2-datastreamer-url: -zkevm.l1-chain-id: 1337 -zkevm.l1-rpc-url: http://l1-geth:8545 -zkevm.l1-highest-block-type: latest - -zkevm.address-sequencer: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" -zkevm.address-zkevm: "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd" -zkevm.address-admin: "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" -zkevm.address-rollup: "0xE96dBF374555C6993618906629988d39184716B3" -zkevm.address-ger-manager: "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" - -zkevm.l1-rollup-id: 1 -zkevm.l1-first-block: 91 -zkevm.l1-block-range: 10 -zkevm.l1-query-delay: 6000 -zkevm.rpc-ratelimit: 0 -zkevm.datastream-version: 2 - -log.console.verbosity: info - -#zkevm.executor-urls: xlayer-executor:50071 -# zkevm.executor-strict: false -# zkevm.witness-full: false -# zkevm.executor-mock: true - -zkevm.sequencer-block-seal-time: "1s" -zkevm.sequencer-max-block-seal-time: "3s" -zkevm.sequencer-batch-seal-time: "10s" -zkevm.sequencer-batch-sleep-duration: "0s" - -zkevm.data-stream-host: "localhost" -zkevm.data-stream-port: 6900 -zkevm.default-gas-price: 1000000000 -zkevm.max-gas-price: 0 -zkevm.gas-price-factor: 0.000001 -zkevm.allow-free-transactions: true - -externalcl: true -http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] -http.addr: 0.0.0.0 -http.port: 8545 -http.vhosts: any -http.corsdomain: any -http.timeouts.read: "10s" -http.timeouts.write: "10s" -http.timeouts.idle: "10s" -rpc.batch.concurrency: 2 -rpc.batch.limit: 20 -ws: true - -zkevm.apollo-enabled: false -zkevm.apollo-ip-addr: "" -zkevm.apollo-app-id: "" -zkevm.apollo-namespace-name: "" - -zkevm.nacos-urls: "" -zkevm.nacos-namespace-id: "" -zkevm.nacos-application-name: "" -zkevm.nacos-external-listen-addr: "" - -metrics: true -metrics.addr: "0.0.0.0" -metrics.port: 9095 - -db.read.concurrency: 20000 -txpool.globalslots: 1000000 -txpool.globalbasefeeslots: 1000000 -txpool.globalqueue: 1000000 -txpool.packbatchspeciallist : ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534"] -txpool.gaspricemultiple : 2 -txpool.blockedlist: ["0xdD2FD4581271e230360230F9337D5c0430Bf44C0"] -txpool.enablefreegasbynonce : true -txpool.freegascountperaddr : 100 -txpool.commit.every: "10m" - -gpo.type: "follower" -gpo.update-period: "3s" -gpo.factor: 0.01 -gpo.kafka-url: "0.0.0.0" -gpo.topic: "explorer" -gpo.group-id: "web3" -gpo.blocks: 3 -gpo.default-l1-coin-price: 2000 -gpo.default-l2-coin-price: 50 -gpo.gas-price-usdt: 0.000000476190476 -gpo.congestion-threshold: 0 - -networkid: 195 - -pprof: true -pprof.port: 6060 -pprof.addr: 0.0.0.0 -txpool.enablefreegaslist : true -txpool.freegaslist : '[{"name":"e2e", "from_list":["0x586cbc95ed16031d9efdaebacf1c1d2bc3ccaa78"], "to_list":["0xad1d01007a56ee0a4ffd0488fb58fc6500cb1fbe"], "method_sigs":["a9059cbb"], "gas_price_multiple": 1}]' - -# close a block/batch immediately after the 1st zkCounter overflow TX -zkevm.seal-batch-immediately-on-overflow: true -zkevm.sequencer-timeout-on-empty-tx-pool: 5ms -zkevm.pre-run-address-list: [""] -zkevm.block-info-concurrent: true -zkevm.standalone-smt-db: true # true: enable split smt db, false: not split -zkevm.enable-async-commit: true - -# to reduce lock race in stress test -txpool.enabletimsort: true -zkevm.bulk-add-txs: true -zkevm.enable-add-tx-notify: true -zkevm.initial-batch.config: /usr/src/app/first-batch-config.json \ No newline at end of file diff --git a/test-pp-op/config/test.genesis.config.json b/test-pp-op/config/test.genesis.config.json deleted file mode 100644 index dca366627bfdc..0000000000000 --- a/test-pp-op/config/test.genesis.config.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "L1Config": { - "chainId": 1337, - "polygonZkEVMAddress": "0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd", - "polygonRollupManagerAddress": "0xE96dBF374555C6993618906629988d39184716B3", - "polTokenAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "polygonZkEVMGlobalExitRootAddress": "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" - }, - "genesisBlockNumber": 91, - "rollupCreationBlockNumber": 100, - "rollupManagerCreationBlockNumber": 91, - "root": "0xef7bb96e820d4d8440f9bae6b1d58427c06e324ac9d5f7a5156438dd42e837c5", - "genesis": [ - { - "contractName": "TokenWrappedBridgeInitCode", - "balance": "0", - "nonce": "1", - "address": "0x750a9c3AB9334e28bdB05B121BDe530351733BC2", - "bytecode": "0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c806383c43a551461002d575b5f5ffd5b61003561004b565b604051610042919061006a565b60405180910390f35b60405180611ba00160405280611b6681526020016100b6611b66913981565b602081525f82518060208401525f5b818110156100965760208186018101516040868401015201610079565b505f604082850101526040601f19601f8301168401019150509291505056fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220e2e0b7899260251baf2cfa7cf6126f1d0a5731b4f1051ae5b437d90ddbc6867164736f6c634300081c0033" - }, - { - "contractName": "PolygonZkEVMDeployer", - "balance": "0", - "nonce": "4", - "address": "0x18c279c3Ed0b54b9f9D815cD12bee2d2d68a4B42", - "bytecode": "0x60806040526004361061006e575f3560e01c8063715018a61161004c578063715018a6146100e25780638da5cb5b146100f6578063e11ae6cb1461011f578063f2fde38b14610132575f80fd5b80632b79805a146100725780634a94d487146100875780636d07dbf81461009a575b5f80fd5b610085610080366004610908565b610151565b005b6100856100953660046109a2565b6101c2565b3480156100a5575f80fd5b506100b96100b43660046109f5565b610203565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ed575f80fd5b50610085610215565b348015610101575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff166100b9565b61008561012d366004610a15565b610228565b34801561013d575f80fd5b5061008561014c366004610a61565b61028e565b61015961034a565b5f6101658585856103ca565b90506101718183610527565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101ca61034a565b6101d583838361056a565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b905f90a1505050565b5f61020e8383610598565b9392505050565b61021d61034a565b6102265f6105a4565b565b61023061034a565b5f61023c8484846103ca565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b61029661034a565b73ffffffffffffffffffffffffffffffffffffffff811661033e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610347816105a4565b50565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610335565b5f83471015610435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610335565b81515f0361049f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610335565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff811661020e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610335565b606061020e83835f6040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610618565b6060610590848484604051806060016040528060298152602001610b0860299139610618565b949350505050565b5f61020e83833061072d565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610335565b5f808673ffffffffffffffffffffffffffffffffffffffff1685876040516106d29190610a9c565b5f6040518083038185875af1925050503d805f811461070c576040519150601f19603f3d011682016040523d82523d5f602084013e610711565b606091505b509150915061072287838387610756565b979650505050505050565b5f604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156107eb5782515f036107e45773ffffffffffffffffffffffffffffffffffffffff85163b6107e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610335565b5081610590565b61059083838151156108005781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103359190610ab7565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112610870575f80fd5b813567ffffffffffffffff8082111561088b5761088b610834565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108d1576108d1610834565b816040528381528660208588010111156108e9575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f805f806080858703121561091b575f80fd5b8435935060208501359250604085013567ffffffffffffffff80821115610940575f80fd5b61094c88838901610861565b93506060870135915080821115610961575f80fd5b5061096e87828801610861565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff8116811461099d575f80fd5b919050565b5f805f606084860312156109b4575f80fd5b6109bd8461097a565b9250602084013567ffffffffffffffff8111156109d8575f80fd5b6109e486828701610861565b925050604084013590509250925092565b5f8060408385031215610a06575f80fd5b50508035926020909101359150565b5f805f60608486031215610a27575f80fd5b8335925060208401359150604084013567ffffffffffffffff811115610a4b575f80fd5b610a5786828701610861565b9150509250925092565b5f60208284031215610a71575f80fd5b61020e8261097a565b5f5b83811015610a94578181015183820152602001610a7c565b50505f910152565b5f8251610aad818460208701610a7a565b9190910192915050565b602081525f8251806020840152610ad5816040850160208701610a7a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220330b94dc698c4d290bf55c23f13b473cde6a6bae0030cb902de18af54e35839f64736f6c63430008140033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008f8e2d6cf621f30e9a11309d6a56a876281fd534" - } - }, - { - "contractName": "ProxyAdmin", - "balance": "0", - "nonce": "1", - "address": "0x5DE1783073a44e3bdE977689a768b9cFA1ac58E7", - "bytecode": "0x608060405260043610610079575f3560e01c80639623609d1161004c5780639623609d1461012357806399a88ec414610136578063f2fde38b14610155578063f3b7dead14610174575f5ffd5b8063204e1c7a1461007d578063715018a6146100c55780637eff275e146100db5780638da5cb5b146100fa575b5f5ffd5b348015610088575f5ffd5b5061009c6100973660046105e8565b610193565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d0575f5ffd5b506100d9610244565b005b3480156100e6575f5ffd5b506100d96100f536600461060a565b610257565b348015610105575f5ffd5b505f5473ffffffffffffffffffffffffffffffffffffffff1661009c565b6100d961013136600461066e565b6102e0565b348015610141575f5ffd5b506100d961015036600461060a565b610371565b348015610160575f5ffd5b506100d961016f3660046105e8565b6103cd565b34801561017f575f5ffd5b5061009c61018e3660046105e8565b610489565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b5f60405180830381855afa9150503d805f8114610215576040519150601f19603f3d011682016040523d82523d5f602084013e61021a565b606091505b509150915081610228575f5ffd5b8080602001905181019061023c9190610782565b949350505050565b61024c6104d3565b6102555f610553565b565b61025f6104d3565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b5f604051808303815f87803b1580156102c6575f5ffd5b505af11580156102d8573d5f5f3e3d5ffd5b505050505050565b6102e86104d3565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061033e908690869060040161079d565b5f604051808303818588803b158015610355575f5ffd5b505af1158015610367573d5f5f3e3d5ffd5b5050505050505050565b6103796104d3565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102af565b6103d56104d3565b73ffffffffffffffffffffffffffffffffffffffff811661047d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61048681610553565b50565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff166040516101dd907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610255576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610474565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114610486575f5ffd5b5f602082840312156105f8575f5ffd5b8135610603816105c7565b9392505050565b5f5f6040838503121561061b575f5ffd5b8235610626816105c7565b91506020830135610636816105c7565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f5f5f60608486031215610680575f5ffd5b833561068b816105c7565b9250602084013561069b816105c7565b9150604084013567ffffffffffffffff8111156106b6575f5ffd5b8401601f810186136106c6575f5ffd5b803567ffffffffffffffff8111156106e0576106e0610641565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff8211171561074c5761074c610641565b604052818152828201602001881015610763575f5ffd5b816020840160208301375f602083830101528093505050509250925092565b5f60208284031215610792575f5ffd5b8151610603816105c7565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f82518060408401525f5b818110156107e557602081860181015160608684010152016107c8565b505f6060828501015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116840101915050939250505056fea2646970667358221220e111b2ba242ce4421950dc7ff545a01914c776103ce1cd642024c628867ecbf064736f6c634300081c0033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000027284dba79e6df953fbd232a9d8d87029f03bbf5" - } - }, - { - "contractName": "PolygonZkEVMBridgeV2 implementation", - "balance": "0", - "nonce": "2", - "address": "0xa5a941061eF748466b31002415d6dCAe831b015A", - "bytecode": "0x60806040526004361061020f575f3560e01c806383c43a5511610117578063cc461632116100ac578063dbc169761161007c578063f5efcd7911610062578063f5efcd7914610683578063f811bff7146106a2578063fb570834146106c1575f5ffd5b8063dbc1697614610644578063ee25560b14610658575f5ffd5b8063cc461632146105cb578063ccaa2d11146105ea578063cd58657914610609578063d02103ca1461061c575f5ffd5b8063b8b284d0116100e7578063b8b284d014610549578063bab161bf14610568578063be5831c714610589578063c00f14ab146105ac575f5ffd5b806383c43a55146104d857806383f24403146104ec5780638ed7e3f21461050b578063aaa13cc21461052a575f5ffd5b80633c351e10116101a75780635ca1e165116101775780637843298b1161015d5780637843298b1461047157806379e2cf971461049057806381b1c174146104a4575f5ffd5b80635ca1e1651461041557806365d6f65414610429575f5ffd5b80633c351e10146103805780633cbc795b1461039f5780633e197043146103d75780634b2f336d146103f6575f5ffd5b806327aef4e8116101e257806327aef4e8146102a15780632dfdf0b5146102c2578063318aee3d146102e5578063381fef6d1461034d575f5ffd5b806315064c96146102135780632072f6c51461024157806322e95f2c14610257578063240ff3781461028e575b5f5ffd5b34801561021e575f5ffd5b5060685461022c9060ff1681565b60405190151581526020015b60405180910390f35b34801561024c575f5ffd5b506102556106e0565b005b348015610262575f5ffd5b50610276610271366004612ea6565b610715565b6040516001600160a01b039091168152602001610238565b61025561029c366004612f2d565b61077f565b3480156102ac575f5ffd5b506102b5610808565b6040516102389190612fef565b3480156102cd575f5ffd5b506102d760535481565b604051908152602001610238565b3480156102f0575f5ffd5b506103296102ff366004613001565b606b6020525f908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b03909116602083015201610238565b348015610358575f5ffd5b506102767f000000000000000000000000750a9c3ab9334e28bdb05b121bde530351733bc281565b34801561038b575f5ffd5b50606d54610276906001600160a01b031681565b3480156103aa575f5ffd5b50606d546103c290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610238565b3480156103e2575f5ffd5b506102d76103f136600461302a565b610894565b348015610401575f5ffd5b50606f54610276906001600160a01b031681565b348015610420575f5ffd5b506102d761093d565b348015610434575f5ffd5b506102b56040518060400160405280600981526020017f616c2d76302e332e30000000000000000000000000000000000000000000000081525081565b34801561047c575f5ffd5b5061027661048b3660046130a4565b6109bc565b34801561049b575f5ffd5b506102556109e7565b3480156104af575f5ffd5b506102766104be3660046130ea565b606a6020525f90815260409020546001600160a01b031681565b3480156104e3575f5ffd5b506102b5610a08565b3480156104f7575f5ffd5b506102d7610506366004613112565b610a91565b348015610516575f5ffd5b50606c54610276906001600160a01b031681565b348015610535575f5ffd5b50610276610544366004613213565b610b1e565b348015610554575f5ffd5b506102556105633660046132ae565b610c49565b348015610573575f5ffd5b506068546103c290610100900463ffffffff1681565b348015610594575f5ffd5b506068546103c290600160c81b900463ffffffff1681565b3480156105b7575f5ffd5b506102b56105c6366004613001565b610ce0565b3480156105d6575f5ffd5b5061022c6105e536600461332c565b610d25565b3480156105f5575f5ffd5b5061025561060436600461335d565b610dad565b61025561061736600461343c565b611203565b348015610627575f5ffd5b50606854610276906501000000000090046001600160a01b031681565b34801561064f575f5ffd5b506102556115d2565b348015610663575f5ffd5b506102d76106723660046130ea565b60696020525f908152604090205481565b34801561068e575f5ffd5b5061025561069d36600461335d565b611605565b3480156106ad575f5ffd5b506102556106bc3660046134cc565b61187e565b3480156106cc575f5ffd5b5061022c6106db36600461356f565b611b99565b606c546001600160a01b0316331461070b57604051631736745960e31b815260040160405180910390fd5b610713611bb2565b565b6040805160e084901b6001600160e01b031916602080830191909152606084901b6bffffffffffffffffffffffff1916602483015282516018818403018152603890920183528151918101919091205f908152606a90915220546001600160a01b03165b92915050565b60685460ff16156107a357604051630bc011ff60e21b815260040160405180910390fd5b34158015906107bc5750606f546001600160a01b031615155b156107f3576040517f6f625c4000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610801858534868686611c0d565b5050505050565b606e8054610815906135b4565b80601f0160208091040260200160405190810160405280929190818152602001828054610841906135b4565b801561088c5780601f106108635761010080835404028352916020019161088c565b820191905f5260205f20905b81548152906001019060200180831161086f57829003601f168201915b505050505081565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201526001600160e01b031960e088811b821660218401526bffffffffffffffffffffffff19606089811b821660258601529188901b909216603984015285901b16603d82015260518101839052607181018290525f90609101604051602081830303815290604052805190602001209050979650505050505050565b6053545f90819081805b60208110156109b3578083901c60011660010361098c5761098560338260208110610974576109746135ec565b0154855f9182526020526040902090565b935061099c565b5f84815260208390526040902093505b5f8281526020839052604090209150600101610947565b50919392505050565b5f6109dd84846109cb85611ce9565b6109d486611dd3565b61054487611eb4565b90505b9392505050565b605354606854600160c81b900463ffffffff16101561071357610713611f81565b60607f000000000000000000000000750a9c3ab9334e28bdb05b121bde530351733bc26001600160a01b03166383c43a556040518163ffffffff1660e01b81526004015f60405180830381865afa158015610a65573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610a8c919081019061362e565b905090565b5f83815b6020811015610b1557600163ffffffff8516821c81169003610ae157610ada858260208110610ac657610ac66135ec565b6020020135835f9182526020526040902090565b9150610b0d565b610b0a82868360208110610af757610af76135ec565b60200201355f9182526020526040902090565b91505b600101610a95565b50949350505050565b6040516001600160e01b031960e087901b1660208201526bffffffffffffffffffffffff19606086901b1660248201525f9081906038016040516020818303038152906040528051906020012090505f60ff60f81b3083610b7d610a08565b898989604051602001610b9293929190613673565b60408051601f1981840301815290829052610bb092916020016136ab565b60405160208183030381529060405280519060200120604051602001610c2594939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012098975050505050505050565b60685460ff1615610c6d57604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610caf576040517fdde3cda700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f545f90610cc7906001600160a01b03168661202f565b9050610cd7878783878787611c0d565b50505050505050565b6060610ceb82611ce9565b610cf483611dd3565b610cfd84611eb4565b604051602001610d0f93929190613673565b6040516020818303038152906040529050919050565b6068545f908190610100900463ffffffff16158015610d4a575063ffffffff83166001145b15610d5c575063ffffffff8316610d84565b610d7164010000000063ffffffff85166136ed565b610d819063ffffffff8616613704565b90505b600881901c5f90815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610dd157604051630bc011ff60e21b815260040160405180910390fd5b610dd96120ac565b60685463ffffffff8681166101009092041614610e09576040516302caf51760e11b815260040160405180910390fd5b610e348c8c8c8c8c5f8d8d8d8d8d8d8d604051610e27929190613717565b6040518091039020612105565b6001600160a01b038616158015610e4f575063ffffffff8716155b15610f4657606f546001600160a01b0316610f2a575f6001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015610e9c576020820181803683370190505b50604051610eaa9190613726565b5f6040518083038185875af1925050503d805f8114610ee4576040519150601f19603f3d011682016040523d82523d5f602084013e610ee9565b606091505b5050905080610f24576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611190565b606f54610f41906001600160a01b03168585612121565b611190565b606d546001600160a01b038781169116148015610f745750606d5463ffffffff888116600160a01b90920416145b15610f8b575f6001600160a01b0385168482610e72565b60685463ffffffff610100909104811690881603610fb757610f416001600160a01b0387168585612193565b6040516001600160e01b031960e089901b1660208201526bffffffffffffffffffffffff19606088901b1660248201525f9060380160408051601f1981840301815291815281516020928301205f818152606a9093529120549091506001600160a01b031680611182575f6110618386868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061221492505050565b905061106e818888612121565b80606a5f8581526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b5f836001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548163ffffffff021916908363ffffffff1602179055506020820151815f0160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a838888604051611174959493929190613769565b60405180910390a15061118d565b61118d818787612121565b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a16111f560018055565b505050505050505050505050565b60685460ff161561122757604051630bc011ff60e21b815260040160405180910390fd5b61122f6120ac565b60685463ffffffff610100909104811690881603611260576040516302caf51760e11b815260040160405180910390fd5b5f806060876001600160a01b03881661135c578834146112ac576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff169450906112d9906135b4565b80601f0160208091040260200160405190810160405280929190818152602001828054611305906135b4565b80156113505780601f1061132757610100808354040283529160200191611350565b820191905f5260205f20905b81548152906001019060200180831161133357829003601f168201915b5050505050915061155a565b3415611394576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84156113a6576113a6888a8888612299565b606f546001600160a01b03908116908916036113cd576113c6888a61202f565b905061155a565b6001600160a01b038089165f908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901515806114205750805163ffffffff1615155b156114425761142f898b61202f565b602082015182519096509450915061154d565b6040516370a0823160e01b81523060048201525f906001600160a01b038b16906370a0823190602401602060405180830381865afa158015611486573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114aa91906137a6565b90506114c16001600160a01b038b1633308e6125ff565b6040516370a0823160e01b81523060048201525f906001600160a01b038c16906370a0823190602401602060405180830381865afa158015611505573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061152991906137a6565b905061153582826137bd565b6068548c9850610100900463ffffffff169650935050505b61155689610ce0565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b5f84868e8e86886053546040516115999897969594939291906137d0565b60405180910390a16115b75f84868e8e868880519060200120612650565b86156115c5576115c5611f81565b50505050610cd760018055565b606c546001600160a01b031633146115fd57604051631736745960e31b815260040160405180910390fd5b610713612667565b60685460ff161561162957604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614611659576040516302caf51760e11b815260040160405180910390fd5b6116788c8c8c8c8c60018d8d8d8d8d8d8d604051610e27929190613717565b606f545f906001600160a01b031661172b57846001600160a01b031684888a86866040516024016116ac9493929190613844565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b179052516116e19190613726565b5f6040518083038185875af1925050503d805f811461171b576040519150601f19603f3d011682016040523d82523d5f602084013e611720565b606091505b5050809150506117dc565b606f54611742906001600160a01b03168686612121565b846001600160a01b0316878985856040516024016117639493929190613844565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b179052516117989190613726565b5f604051808303815f865af19150503d805f81146117d1576040519150601f19603f3d011682016040523d82523d5f602084013e6117d6565b606091505b50909150505b80611813576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b5f54610100900460ff161580801561189c57505f54600160ff909116105b806118b55750303b1580156118b557505f5460ff166001145b61192c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b5f805460ff19166001179055801561194d575f805461ff0019166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8a16027fffffffffffffff0000000000000000000000000000000000000000ffffffffff1617650100000000006001600160a01b038781169190910291909117909155606c805473ffffffffffffffffffffffffffffffffffffffff19168583161790558616611a285763ffffffff851615611a23576040517f1a874c1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b44565b606d805463ffffffff8716600160a01b027fffffffffffffffff0000000000000000000000000000000000000000000000009091166001600160a01b03891617179055606e611a7783826138c0565b50611b165f5f1b6012604051602001611b0291906060808252600d908201527f5772617070656420457468657200000000000000000000000000000000000000608082015260a0602082018190526004908201527f574554480000000000000000000000000000000000000000000000000000000060c082015260ff91909116604082015260e00190565b604051602081830303815290604052612214565b606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03929092169190911790555b611b4c6126d7565b8015610cd7575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b5f81611ba6868686610a91565b1490505b949350505050565b60685460ff1615611bd657604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497905f90a1565b60685463ffffffff610100909104811690871603611c3e576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611c929998979695949392919061397b565b60405180910390a1611cd36001606860019054906101000a900463ffffffff16338989898888604051611cc6929190613717565b6040518091039020612650565b8215611ce157611ce1611f81565b505050505050565b60408051600481526024810182526020810180516001600160e01b03167f06fdde030000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611d489190613726565b5f60405180830381855afa9150503d805f8114611d80576040519150601f19603f3d011682016040523d82523d5f602084013e611d85565b606091505b509150915081611dca576040518060400160405280600781526020017f4e4f5f4e414d4500000000000000000000000000000000000000000000000000815250611baa565b611baa81612749565b60408051600481526024810182526020810180516001600160e01b03167f95d89b410000000000000000000000000000000000000000000000000000000017905290516060915f9182916001600160a01b03861691611e329190613726565b5f60405180830381855afa9150503d805f8114611e6a576040519150601f19603f3d011682016040523d82523d5f602084013e611e6f565b606091505b509150915081611dca576040518060400160405280600981526020017f4e4f5f53594d424f4c0000000000000000000000000000000000000000000000815250611baa565b60408051600481526024810182526020810180516001600160e01b03167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f91829182916001600160a01b03861691611f129190613726565b5f60405180830381855afa9150503d805f8114611f4a576040519150601f19603f3d011682016040523d82523d5f602084013e611f4f565b606091505b5091509150818015611f62575080516020145b611f6d576012611baa565b80806020019051810190611baa91906139f1565b6053546068805463ffffffff909216600160c81b027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117908190556001600160a01b0365010000000000909104166333d6247d611fe261093d565b6040518263ffffffff1660e01b815260040161200091815260200190565b5f604051808303815f87803b158015612017575f5ffd5b505af1158015612029573d5f5f3e3d5ffd5b50505050565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018290525f906001600160a01b03841690639dc29fac906044015f604051808303815f87803b15801561208f575f5ffd5b505af11580156120a1573d5f5f3e3d5ffd5b509395945050505050565b6002600154036120fe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611923565b6002600155565b6111f58c8c8c8c8c61211c8d8d8d8d8d8d8d610894565b61290f565b6040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390528416906340c10f19906044015f604051808303815f87803b158015612181575f5ffd5b505af1158015610cd7573d5f5f3e3d5ffd5b6040516001600160a01b03831660248201526044810182905261220f9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a79565b505050565b5f5f61221e610a08565b836040516020016122309291906136ab565b6040516020818303038152906040529050838151602083015ff591506001600160a01b03821661228c576040517fbefb092000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5092915050565b60018055565b5f6122a76004828486613a0c565b6122b091613a33565b90507f2afa5331000000000000000000000000000000000000000000000000000000006001600160e01b0319821601612451575f8080808080806122f7896004818d613a0c565b8101906123049190613a68565b9650965096509650965096509650336001600160a01b0316876001600160a01b0316146123445760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038616301461236d5760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b03167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e16916124049190613726565b5f604051808303815f865af19150503d805f811461243d576040519150601f19603f3d011682016040523d82523d5f602084013e612442565b606091505b50505050505050505050610801565b6001600160e01b031981166323f2ebc360e21b1461249b576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f808080808080806124b08a6004818e613a0c565b8101906124bd9190613ab7565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146124ff5760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03871630146125285760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f16916125af9190613726565b5f604051808303815f865af19150503d805f81146125e8576040519150601f19603f3d011682016040523d82523d5f602084013e6125ed565b606091505b50505050505050505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526120299085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016121d8565b610cd761266288888888888888610894565b612b5d565b60685460ff166126a3576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3905f90a1565b5f54610100900460ff166127415760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611923565b610713612c35565b606060408251106127685781806020019051810190610779919061362e565b81516020036128d1575f5b6020811080156127ba5750828181518110612790576127906135ec565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b156127d157806127c981613b35565b915050612773565b805f0361281357505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b5f8167ffffffffffffffff81111561282d5761282d61314e565b6040519080825280601f01601f191660200182016040528015612857576020820181803683370190505b5090505f5b828110156128c957848181518110612876576128766135ec565b602001015160f81c60f81b828281518110612893576128936135ec565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060010161285c565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b6068545f906501000000000090046001600160a01b031663257b363261293e86865f9182526020526040902090565b6040518263ffffffff1660e01b815260040161295c91815260200190565b6020604051808303815f875af1158015612978573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061299c91906137a6565b9050805f036129d6576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8068010000000000000000871615612a1a578691506129f8848a8489611b99565b612a15576040516338105f3b60e21b815260040160405180910390fd5b612a64565b602087901c612a2a816001613b4d565b9150879250612a45612a3d868c86610a91565b8a8389611b99565b612a62576040516338105f3b60e21b815260040160405180910390fd5b505b612a6e8282612c9f565b505050505050505050565b5f612acd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612d5f9092919063ffffffff16565b80519091501561220f5780806020019051810190612aeb9190613b69565b61220f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611923565b806001612b6c60206002613c67565b612b7691906137bd565b60535410612bb0576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60535f8154612bbf90613b35565b918290555090505f5b6020811015612c2c578082901c600116600103612bfb578260338260208110612bf357612bf36135ec565b015550505050565b612c2260338260208110612c1157612c116135ec565b0154845f9182526020526040902090565b9250600101612bc8565b5061220f613c72565b5f54610100900460ff166122935760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611923565b6068545f90610100900463ffffffff16158015612cc2575063ffffffff82166001145b15612cd4575063ffffffff8216612cfc565b612ce964010000000063ffffffff84166136ed565b612cf99063ffffffff8516613704565b90505b600881901c5f8181526069602052604081208054600160ff861690811b91821892839055929091908183169003610cd7576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60606109dd84845f85855f5f866001600160a01b03168587604051612d849190613726565b5f6040518083038185875af1925050503d805f8114612dbe576040519150601f19603f3d011682016040523d82523d5f602084013e612dc3565b606091505b5091509150612dd487838387612ddf565b979650505050505050565b60608315612e4d5782515f03612e46576001600160a01b0385163b612e465760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611923565b5081611baa565b611baa8383815115612e625781518083602001fd5b8060405162461bcd60e51b81526004016119239190612fef565b803563ffffffff8116811461290a575f5ffd5b6001600160a01b0381168114612ea3575f5ffd5b50565b5f5f60408385031215612eb7575f5ffd5b612ec083612e7c565b91506020830135612ed081612e8f565b809150509250929050565b8015158114612ea3575f5ffd5b5f5f83601f840112612ef8575f5ffd5b50813567ffffffffffffffff811115612f0f575f5ffd5b602083019150836020828501011115612f26575f5ffd5b9250929050565b5f5f5f5f5f60808688031215612f41575f5ffd5b612f4a86612e7c565b94506020860135612f5a81612e8f565b93506040860135612f6a81612edb565b9250606086013567ffffffffffffffff811115612f85575f5ffd5b612f9188828901612ee8565b969995985093965092949392505050565b5f5b83811015612fbc578181015183820152602001612fa4565b50505f910152565b5f8151808452612fdb816020860160208601612fa2565b601f01601f19169290920160200192915050565b602081525f6109e06020830184612fc4565b5f60208284031215613011575f5ffd5b81356109e081612e8f565b60ff81168114612ea3575f5ffd5b5f5f5f5f5f5f5f60e0888a031215613040575f5ffd5b873561304b8161301c565b965061305960208901612e7c565b9550604088013561306981612e8f565b945061307760608901612e7c565b9350608088013561308781612e8f565b9699959850939692959460a0840135945060c09093013592915050565b5f5f5f606084860312156130b6575f5ffd5b6130bf84612e7c565b925060208401356130cf81612e8f565b915060408401356130df81612e8f565b809150509250925092565b5f602082840312156130fa575f5ffd5b5035919050565b806104008101831015610779575f5ffd5b5f5f5f6104408486031215613125575f5ffd5b833592506131368560208601613101565b91506131456104208501612e7c565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561318b5761318b61314e565b604052919050565b5f67ffffffffffffffff8211156131ac576131ac61314e565b50601f01601f191660200190565b5f6131cc6131c784613193565b613162565b90508281528383830111156131df575f5ffd5b828260208301375f602084830101529392505050565b5f82601f830112613204575f5ffd5b6109e0838335602085016131ba565b5f5f5f5f5f60a08688031215613227575f5ffd5b61323086612e7c565b9450602086013561324081612e8f565b9350604086013567ffffffffffffffff81111561325b575f5ffd5b613267888289016131f5565b935050606086013567ffffffffffffffff811115613283575f5ffd5b61328f888289016131f5565b92505060808601356132a08161301c565b809150509295509295909350565b5f5f5f5f5f5f60a087890312156132c3575f5ffd5b6132cc87612e7c565b955060208701356132dc81612e8f565b94506040870135935060608701356132f381612edb565b9250608087013567ffffffffffffffff81111561330e575f5ffd5b61331a89828a01612ee8565b979a9699509497509295939492505050565b5f5f6040838503121561333d575f5ffd5b61334683612e7c565b915061335460208401612e7c565b90509250929050565b5f5f5f5f5f5f5f5f5f5f5f5f6109208d8f031215613379575f5ffd5b6133838e8e613101565b9b506133938e6104008f01613101565b9a506108008d013599506108208d013598506108408d013597506133ba6108608e01612e7c565b96506133ca6108808e0135612e8f565b6108808d013595506133df6108a08e01612e7c565b94506108c08d01356133f081612e8f565b93506108e08d0135925067ffffffffffffffff6109008e01351115613413575f5ffd5b6134248e6109008f01358f01612ee8565b81935080925050509295989b509295989b509295989b565b5f5f5f5f5f5f5f60c0888a031215613452575f5ffd5b61345b88612e7c565b9650602088013561346b81612e8f565b955060408801359450606088013561348281612e8f565b9350608088013561349281612edb565b925060a088013567ffffffffffffffff8111156134ad575f5ffd5b6134b98a828b01612ee8565b989b979a50959850939692959293505050565b5f5f5f5f5f5f60c087890312156134e1575f5ffd5b6134ea87612e7c565b955060208701356134fa81612e8f565b945061350860408801612e7c565b9350606087013561351881612e8f565b9250608087013561352881612e8f565b915060a087013567ffffffffffffffff811115613543575f5ffd5b8701601f81018913613553575f5ffd5b613562898235602084016131ba565b9150509295509295509295565b5f5f5f5f6104608587031215613583575f5ffd5b843593506135948660208701613101565b92506135a36104208601612e7c565b939692955092936104400135925050565b600181811c908216806135c857607f821691505b6020821081036135e657634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b5f61360d6131c784613193565b9050828152838383011115613620575f5ffd5b6109e0836020830184612fa2565b5f6020828403121561363e575f5ffd5b815167ffffffffffffffff811115613654575f5ffd5b8201601f81018413613664575f5ffd5b611baa84825160208401613600565b606081525f6136856060830186612fc4565b82810360208401526136978186612fc4565b91505060ff83166040830152949350505050565b5f83516136bc818460208801612fa2565b8351908301906136d0818360208801612fa2565b01949350505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610779576107796136d9565b80820180821115610779576107796136d9565b818382375f9101908152919050565b5f8251613737818460208701612fa2565b9190910192915050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b63ffffffff861681526001600160a01b03851660208201526001600160a01b0384166040820152608060608201525f612dd4608083018486613741565b5f602082840312156137b6575f5ffd5b5051919050565b81810381811115610779576107796136d9565b60ff8916815263ffffffff881660208201526001600160a01b038716604082015263ffffffff861660608201526001600160a01b03851660808201528360a082015261010060c08201525f613829610100830185612fc4565b905063ffffffff831660e08301529998505050505050505050565b6001600160a01b038516815263ffffffff84166020820152606060408201525f613872606083018486613741565b9695505050505050565b601f82111561220f57805f5260205f20601f840160051c810160208510156138a15750805b601f840160051c820191505b81811015610801575f81556001016138ad565b815167ffffffffffffffff8111156138da576138da61314e565b6138ee816138e884546135b4565b8461387c565b6020601f821160018114613920575f83156139095750848201515b5f19600385901b1c1916600184901b178455610801565b5f84815260208120601f198516915b8281101561394f578785015182556020948501946001909201910161392f565b508482101561396c57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b60ff8a16815263ffffffff891660208201526001600160a01b038816604082015263ffffffff871660608201526001600160a01b03861660808201528460a082015261010060c08201525f6139d561010083018587613741565b905063ffffffff831660e08301529a9950505050505050505050565b5f60208284031215613a01575f5ffd5b81516109e08161301c565b5f5f85851115613a1a575f5ffd5b83861115613a26575f5ffd5b5050820193919092039150565b80356001600160e01b0319811690600484101561228c576001600160e01b0319808560040360031b1b82161691505092915050565b5f5f5f5f5f5f5f60e0888a031215613a7e575f5ffd5b8735613a8981612e8f565b96506020880135613a9981612e8f565b9550604088013594506060880135935060808801356130878161301c565b5f5f5f5f5f5f5f5f610100898b031215613acf575f5ffd5b8835613ada81612e8f565b97506020890135613aea81612e8f565b965060408901359550606089013594506080890135613b0881612edb565b935060a0890135613b188161301c565b979a969950949793969295929450505060c08201359160e0013590565b5f60018201613b4657613b466136d9565b5060010190565b63ffffffff8181168382160190811115610779576107796136d9565b5f60208284031215613b79575f5ffd5b81516109e081612edb565b6001815b6001841115613bbf57808504811115613ba357613ba36136d9565b6001841615613bb157908102905b60019390931c928002613b88565b935093915050565b5f82613bd557506001610779565b81613be157505f610779565b8160018114613bf75760028114613c0157613c1d565b6001915050610779565b60ff841115613c1257613c126136d9565b50506001821b610779565b5060208310610133831016604e8410600b8410161715613c40575081810a610779565b613c4c5f198484613b84565b805f1904821115613c5f57613c5f6136d9565b029392505050565b5f6109e08383613bc7565b634e487b7160e01b5f52600160045260245ffdfea2646970667358221220849aaee1cc1978fd76e0346e23e1c9651b52ff9e7089a5e63e964925adf544c264736f6c634300081c0033" - }, - { - "contractName": "PolygonZkEVMBridgeV2 proxy", - "balance": "340282366920938463463374607431768211455", - "nonce": "1", - "address": "0x4B24266C13AFEf2bb60e2C69A4C08A482d81e3CA", - "bytecode": "0x60806040526004361061005d575f3560e01c80635c60da1b116100425780635c60da1b146100a65780638f283970146100e3578063f851a440146101025761006c565b80633659cfe6146100745780634f1ef286146100935761006c565b3661006c5761006a610116565b005b61006a610116565b34801561007f575f5ffd5b5061006a61008e366004610854565b610130565b61006a6100a136600461086d565b610178565b3480156100b1575f5ffd5b506100ba6101eb565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee575f5ffd5b5061006a6100fd366004610854565b610228565b34801561010d575f5ffd5b506100ba610255565b61011e610282565b61012e610129610359565b610362565b565b610138610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d8160405180602001604052805f8152505f6103bf565b50565b61016d610116565b610180610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101e3576101de8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250600192506103bf915050565b505050565b6101de610116565b5f6101f4610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610359565b905090565b610225610116565b90565b610230610380565b73ffffffffffffffffffffffffffffffffffffffff1633036101705761016d816103e9565b5f61025e610380565b73ffffffffffffffffffffffffffffffffffffffff16330361021d57610218610380565b61028a610380565b73ffffffffffffffffffffffffffffffffffffffff16330361012e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b5f61021861044a565b365f5f375f5f365f845af43d5f5f3e80801561037c573d5ff35b3d5ffd5b5f7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103c883610471565b5f825111806103d45750805b156101de576103e383836104bd565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610412610380565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161016d816104e9565b5f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103a3565b61047a816105f5565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606104e28383604051806060016040528060278152602001610979602791396106c0565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff811661058c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610350565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b610699576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610350565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105af565b60605f5f8573ffffffffffffffffffffffffffffffffffffffff16856040516106e9919061090d565b5f60405180830381855af49150503d805f8114610721576040519150601f19603f3d011682016040523d82523d5f602084013e610726565b606091505b509150915061073786838387610741565b9695505050505050565b606083156107d65782515f036107cf5773ffffffffffffffffffffffffffffffffffffffff85163b6107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610350565b50816107e0565b6107e083836107e8565b949350505050565b8151156107f85781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103509190610928565b803573ffffffffffffffffffffffffffffffffffffffff8116811461084f575f5ffd5b919050565b5f60208284031215610864575f5ffd5b6104e28261082c565b5f5f5f6040848603121561087f575f5ffd5b6108888461082c565b9250602084013567ffffffffffffffff8111156108a3575f5ffd5b8401601f810186136108b3575f5ffd5b803567ffffffffffffffff8111156108c9575f5ffd5b8660208284010111156108da575f5ffd5b939660209190910195509293505050565b5f5b838110156109055781810151838201526020016108ed565b50505f910152565b5f825161091e8184602087016108eb565b9190910192915050565b602081525f82518060208401526109468160408501602087016108eb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b4314c6ef866fe81c59eeee5f2b9032aaf3dc70c6d4ab82137af7b26a764741664736f6c634300081c0033", - "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x0000000000000000000000005de1783073a44e3bde977689a768b9cfa1ac58e7", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000a5a941061ef748466b31002415d6dcae831b015a" - } - }, - { - "contractName": "PolygonZkEVMGlobalExitRootL2 implementation", - "balance": "0", - "nonce": "1", - "address": "0x21BD2401BA404841c7feC1816F5a0AaAdbc486eF", - "bytecode": "0x608060405234801561000f575f5ffd5b506004361061004a575f3560e01c806301fd90441461004e578063257b36321461006a57806333d6247d14610089578063a3c573eb1461009e575b5f5ffd5b61005760015481565b6040519081526020015b60405180910390f35b61005761007836600461015e565b5f6020819052908152604090205481565b61009c61009736600461015e565b6100ea565b005b6100c57f0000000000000000000000004b24266c13afef2bb60e2c69a4c08a482d81e3ca81565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610061565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004b24266c13afef2bb60e2c69a4c08a482d81e3ca1614610159576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b5f6020828403121561016e575f5ffd5b503591905056fea26469706673582212208915b6fcaffb67739719d531325bac93ba2790d8aec6a382f704b8d2db9769f964736f6c634300081c0033" - }, - { - "contractName": "PolygonZkEVMGlobalExitRootL2 proxy", - "balance": "0", - "nonce": "1", - "address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa", - "bytecode": "0x60806040523661001357610011610017565b005b6100115b61001f6101b7565b6001600160a01b0316336001600160a01b0316141561016f5760606001600160e01b031960003516631b2ce7f360e11b8114156100655761005e6101ea565b9150610167565b6001600160e01b0319811663278f794360e11b14156100865761005e610241565b6001600160e01b031981166308f2839760e41b14156100a75761005e610287565b6001600160e01b031981166303e1469160e61b14156100c85761005e6102b8565b6001600160e01b03198116635c60da1b60e01b14156100e95761005e6102f8565b60405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b815160208301f35b61017761030c565b565b606061019e83836040518060600160405280602781526020016108576027913961031c565b9392505050565b90565b6001600160a01b03163b151590565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b60606101f4610394565b600061020336600481846106a2565b81019061021091906106e8565b905061022d8160405180602001604052806000815250600061039f565b505060408051602081019091526000815290565b606060008061025336600481846106a2565b8101906102609190610719565b915091506102708282600161039f565b604051806020016040528060008152509250505090565b6060610291610394565b60006102a036600481846106a2565b8101906102ad91906106e8565b905061022d816103cb565b60606102c2610394565b60006102cc6101b7565b604080516001600160a01b03831660208201529192500160405160208183030381529060405291505090565b6060610302610394565b60006102cc610422565b610177610317610422565b610431565b6060600080856001600160a01b0316856040516103399190610807565b600060405180830381855af49150503d8060008114610374576040519150601f19603f3d011682016040523d82523d6000602084013e610379565b606091505b509150915061038a86838387610455565b9695505050505050565b341561017757600080fd5b6103a8836104d3565b6000825111806103b55750805b156103c6576103c48383610179565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103f46101b7565b604080516001600160a01b03928316815291841660208301520160405180910390a161041f81610513565b50565b600061042c6105bc565b905090565b3660008037600080366000845af43d6000803e808015610450573d6000f35b3d6000fd5b606083156104c15782516104ba576001600160a01b0385163b6104ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161015e565b50816104cb565b6104cb83836105e4565b949350505050565b6104dc8161060e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105785760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6101db565b8151156105f45781518083602001fd5b8060405162461bcd60e51b815260040161015e9190610823565b6001600160a01b0381163b61067b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161015e565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61059b565b600080858511156106b257600080fd5b838611156106bf57600080fd5b5050820193919092039150565b80356001600160a01b03811681146106e357600080fd5b919050565b6000602082840312156106fa57600080fd5b61019e826106cc565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561072c57600080fd5b610735836106cc565b9150602083013567ffffffffffffffff8082111561075257600080fd5b818501915085601f83011261076657600080fd5b81358181111561077857610778610703565b604051601f8201601f19908116603f011681019083821181831017156107a0576107a0610703565b816040528281528860208487010111156107b957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b838110156107f65781810151838201526020016107de565b838111156103c45750506000910152565b600082516108198184602087016107db565b9190910192915050565b60208152600082518060208401526108428160408501602087016107db565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122012bb4f564f73959a03513dc74fc3c6e40e8386e6f02c16b78d6db00ce0aa16af64736f6c63430008090033", - "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x0000000000000000000000005de1783073a44e3bde977689a768b9cfa1ac58e7", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000021bd2401ba404841c7fec1816f5a0aaadbc486ef" - } - }, - { - "contractName": "PolygonZkEVMTimelock", - "balance": "0", - "nonce": "1", - "address": "0x27284DBa79e6DF953Fbd232A9d8D87029F03BBf5", - "bytecode": "0x6080604052600436106101bd575f3560e01c806364d62353116100f2578063b1c5f42711610092578063d547741f11610062578063d547741f1461063a578063e38335e514610659578063f23a6e611461066c578063f27a0c92146106b0575f80fd5b8063b1c5f4271461058d578063bc197c81146105ac578063c4d252f5146105f0578063d45c44351461060f575f80fd5b80638f61f4f5116100cd5780638f61f4f5146104c557806391d14854146104f8578063a217fddf14610547578063b08e51c01461055a575f80fd5b806364d62353146104685780638065657f146104875780638f2a0bb0146104a6575f80fd5b8063248a9ca31161015d57806331d507501161013857806331d50750146103b357806336568abe146103d25780633a6aae72146103f1578063584b153e14610449575f80fd5b8063248a9ca3146103375780632ab0f529146103655780632f2ff15d14610394575f80fd5b80630d3cf6fc116101985780630d3cf6fc1461025e578063134008d31461029157806313bc9f20146102a4578063150b7a02146102c3575f80fd5b806301d5062a146101c857806301ffc9a7146101e957806307bd02651461021d575f80fd5b366101c457005b5f80fd5b3480156101d3575f80fd5b506101e76101e2366004611bf6565b6106c4565b005b3480156101f4575f80fd5b50610208610203366004611c65565b610757565b60405190151581526020015b60405180910390f35b348015610228575f80fd5b506102507fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610214565b348015610269575f80fd5b506102507f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101e761029f366004611ca4565b6107b2565b3480156102af575f80fd5b506102086102be366004611d0b565b6108a7565b3480156102ce575f80fd5b506103066102dd366004611e28565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610214565b348015610342575f80fd5b50610250610351366004611d0b565b5f9081526020819052604090206001015490565b348015610370575f80fd5b5061020861037f366004611d0b565b5f908152600160208190526040909120541490565b34801561039f575f80fd5b506101e76103ae366004611e8c565b6108cc565b3480156103be575f80fd5b506102086103cd366004611d0b565b6108f5565b3480156103dd575f80fd5b506101e76103ec366004611e8c565b61090d565b3480156103fc575f80fd5b506104247f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b348015610454575f80fd5b50610208610463366004611d0b565b6109c5565b348015610473575f80fd5b506101e7610482366004611d0b565b6109da565b348015610492575f80fd5b506102506104a1366004611ca4565b610aaa565b3480156104b1575f80fd5b506101e76104c0366004611ef7565b610ae8565b3480156104d0575f80fd5b506102507fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b348015610503575f80fd5b50610208610512366004611e8c565b5f9182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610552575f80fd5b506102505f81565b348015610565575f80fd5b506102507ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b348015610598575f80fd5b506102506105a7366004611fa0565b610d18565b3480156105b7575f80fd5b506103066105c63660046120be565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b3480156105fb575f80fd5b506101e761060a366004611d0b565b610d5c565b34801561061a575f80fd5b50610250610629366004611d0b565b5f9081526001602052604090205490565b348015610645575f80fd5b506101e7610654366004611e8c565b610e56565b6101e7610667366004611fa0565b610e7a565b348015610677575f80fd5b50610306610686366004612161565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106bb575f80fd5b50610250611121565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc16106ee81611200565b5f6106fd898989898989610aaa565b9050610709818461120d565b5f817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a60405161074496959493929190612208565b60405180910390a3505050505050505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107ac57506107ac82611359565b92915050565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661082e5761082e81336113ef565b5f61083d888888888888610aaa565b905061084981856114a6565b610855888888886115e2565b5f817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a60405161088c9493929190612252565b60405180910390a361089d816116e2565b5050505050505050565b5f818152600160205260408120546001811180156108c55750428111155b9392505050565b5f828152602081905260409020600101546108e681611200565b6108f0838361178a565b505050565b5f8181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109c18282611878565b5050565b5f818152600160208190526040822054610906565b333014610a69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109ae565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b5f868686868686604051602001610ac696959493929190612208565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b1281611200565b888714610ba1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b888514610c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f610c418b8b8b8b8b8b8b8b610d18565b9050610c4d818461120d565b5f5b8a811015610d0a5780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610c8c57610c8c612291565b9050602002016020810190610ca191906122be565b8d8d86818110610cb357610cb3612291565b905060200201358c8c87818110610ccc57610ccc612291565b9050602002810190610cde91906122d7565b8c8b604051610cf296959493929190612208565b60405180910390a3610d0381612365565b9050610c4f565b505050505050505050505050565b5f8888888888888888604051602001610d38989796959493929190612447565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610d8681611200565b610d8f826109c5565b610e1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109ae565b5f828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b5f82815260208190526040902060010154610e7081611200565b6108f08383611878565b5f80527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610ef657610ef681336113ef565b878614610f85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b878414611014576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f6110258a8a8a8a8a8a8a8a610d18565b905061103181856114a6565b5f5b8981101561110b575f8b8b8381811061104e5761104e612291565b905060200201602081019061106391906122be565b90505f8a8a8481811061107857611078612291565b905060200201359050365f8a8a8681811061109557611095612291565b90506020028101906110a791906122d7565b915091506110b7848484846115e2565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58868686866040516110ee9493929190612252565b60405180910390a3505050508061110490612365565b9050611033565b50611115816116e2565b50505050505050505050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16158015906111ef57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ef919061250c565b156111f957505f90565b5060025490565b61120a81336113ef565b50565b611216826108f5565b156112a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109ae565b6112ab611121565b81101561133a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109ae565b611344814261252b565b5f928352600160205260409092209190915550565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107ac57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107ac565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c15761142c8161192d565b61143783602061194c565b604051602001611448929190612560565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109ae916004016125e0565b6114af826108a7565b61153b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b80158061155657505f81815260016020819052604090912054145b6109c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109ae565b5f8473ffffffffffffffffffffffffffffffffffffffff1684848460405161160b929190612630565b5f6040518083038185875af1925050503d805f8114611645576040519150601f19603f3d011682016040523d82523d5f602084013e61164a565b606091505b50509050806116db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109ae565b5050505050565b6116eb816108a7565b611777576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109ae565b5f90815260016020819052604090912055565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561181a3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b5f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109c1575f8281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107ac73ffffffffffffffffffffffffffffffffffffffff831660145b60605f61195a83600261263f565b61196590600261252b565b67ffffffffffffffff81111561197d5761197d611d22565b6040519080825280601f01601f1916602001820160405280156119a7576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106119dd576119dd612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a3f57611a3f612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f611a7984600261263f565b611a8490600161252b565b90505b6001811115611b20577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611ac557611ac5612291565b1a60f81b828281518110611adb57611adb612291565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c93611b1981612656565b9050611a87565b5083156108c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109ae565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bac575f80fd5b919050565b5f8083601f840112611bc1575f80fd5b50813567ffffffffffffffff811115611bd8575f80fd5b602083019150836020828501011115611bef575f80fd5b9250929050565b5f805f805f805f60c0888a031215611c0c575f80fd5b611c1588611b89565b965060208801359550604088013567ffffffffffffffff811115611c37575f80fd5b611c438a828b01611bb1565b989b979a50986060810135976080820135975060a09091013595509350505050565b5f60208284031215611c75575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108c5575f80fd5b5f805f805f8060a08789031215611cb9575f80fd5b611cc287611b89565b955060208701359450604087013567ffffffffffffffff811115611ce4575f80fd5b611cf089828a01611bb1565b979a9699509760608101359660809091013595509350505050565b5f60208284031215611d1b575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d9657611d96611d22565b604052919050565b5f82601f830112611dad575f80fd5b813567ffffffffffffffff811115611dc757611dc7611d22565b611df860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d4f565b818152846020838601011115611e0c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611e3b575f80fd5b611e4485611b89565b9350611e5260208601611b89565b925060408501359150606085013567ffffffffffffffff811115611e74575f80fd5b611e8087828801611d9e565b91505092959194509250565b5f8060408385031215611e9d575f80fd5b82359150611ead60208401611b89565b90509250929050565b5f8083601f840112611ec6575f80fd5b50813567ffffffffffffffff811115611edd575f80fd5b6020830191508360208260051b8501011115611bef575f80fd5b5f805f805f805f805f60c08a8c031215611f0f575f80fd5b893567ffffffffffffffff80821115611f26575f80fd5b611f328d838e01611eb6565b909b50995060208c0135915080821115611f4a575f80fd5b611f568d838e01611eb6565b909950975060408c0135915080821115611f6e575f80fd5b50611f7b8c828d01611eb6565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b5f805f805f805f8060a0898b031215611fb7575f80fd5b883567ffffffffffffffff80821115611fce575f80fd5b611fda8c838d01611eb6565b909a50985060208b0135915080821115611ff2575f80fd5b611ffe8c838d01611eb6565b909850965060408b0135915080821115612016575f80fd5b506120238b828c01611eb6565b999c989b509699959896976060870135966080013595509350505050565b5f82601f830112612050575f80fd5b8135602067ffffffffffffffff82111561206c5761206c611d22565b8160051b61207b828201611d4f565b9283528481018201928281019087851115612094575f80fd5b83870192505b848310156120b35782358252918301919083019061209a565b979650505050505050565b5f805f805f60a086880312156120d2575f80fd5b6120db86611b89565b94506120e960208701611b89565b9350604086013567ffffffffffffffff80821115612105575f80fd5b61211189838a01612041565b94506060880135915080821115612126575f80fd5b61213289838a01612041565b93506080880135915080821115612147575f80fd5b5061215488828901611d9e565b9150509295509295909350565b5f805f805f60a08688031215612175575f80fd5b61217e86611b89565b945061218c60208701611b89565b93506040860135925060608601359150608086013567ffffffffffffffff8111156121b5575f80fd5b61215488828901611d9e565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a060408201525f61223d60a0830186886121c1565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201525f6122876060830184866121c1565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f602082840312156122ce575f80fd5b6108c582611b89565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261230a575f80fd5b83018035915067ffffffffffffffff821115612324575f80fd5b602001915036819003821315611bef575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361239557612395612338565b5060010190565b8183525f6020808501808196508560051b81019150845f5b8781101561243a57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126123f2575f80fd5b8701858101903567ffffffffffffffff81111561240d575f80fd5b80360382131561241b575f80fd5b6124268682846121c1565b9a87019a95505050908401906001016123b4565b5091979650505050505050565b60a080825281018890525f8960c08301825b8b8110156124945773ffffffffffffffffffffffffffffffffffffffff61247f84611b89565b16825260209283019290910190600101612459565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8911156124cc575f80fd5b8860051b9150818a602083013701828103602090810160408501526124f4908201878961239c565b60608401959095525050608001529695505050505050565b5f6020828403121561251c575f80fd5b815180151581146108c5575f80fd5b808201808211156107ac576107ac612338565b5f5b83811015612558578181015183820152602001612540565b50505f910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f835161259781601785016020880161253e565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516125d481602884016020880161253e565b01602801949350505050565b602081525f82518060208401526125fe81604085016020870161253e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b818382375f9101908152919050565b80820281158282048414176107ac576107ac612338565b5f8161266457612664612338565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea264697066735822122085c4cf030f76482828ded4e6c9cb7851ec61b401cf6380abe817d249dc4719fb64736f6c63430008140033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x73aec4d9eb3be1097d809826691104f0c28da74ebf68d903dc9c6f12562fd822": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x6b347b5397bd05b592ec00f3e3a28ac3cedc5d7ee6994c7533215f223a0cfe84": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", - "0x35fa115b92f0a8d03c972ada19f34c3fa238589ba573a59a419692abc6a91f1a": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", - "0xc05edde0499e76380516353a6ad6ced0d360179c67da013977526f6fbac38774": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", - "0x3e92e57d702d5fdc47a588386c93df7f5578fb6af324e63318e76ec6cffcab32": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5" - } - }, - { - "accountName": "keyless Deployer", - "balance": "0", - "nonce": "1", - "address": "0xCBb32b7819EC30d41e1399b32dbE32dd5D47a55E" - }, - { - "accountName": "deployer", - "balance": "100000000000000000000000", - "nonce": "8", - "address": "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534" - } - ] -} \ No newline at end of file diff --git a/test-pp-op/config/test.node.config.toml b/test-pp-op/config/test.node.config.toml deleted file mode 100644 index ac7d141e1c14c..0000000000000 --- a/test-pp-op/config/test.node.config.toml +++ /dev/null @@ -1,6 +0,0 @@ -[Etherman] -URL = "http://l1-geth:8545" -ForkIDChunkSize = 100 -MultiGasProvider = false -[Etherscan] -ApiKey = "" \ No newline at end of file diff --git a/test-pp-op/config/test.poolmanager.toml b/test-pp-op/config/test.poolmanager.toml deleted file mode 100644 index c7e4a2a41ee11..0000000000000 --- a/test-pp-op/config/test.poolmanager.toml +++ /dev/null @@ -1,37 +0,0 @@ -[Log] -Environment = "development" # "production" or "development" -Level = "info" -Outputs = ["stderr"] - -[Server] -Host = "0.0.0.0" -Port = 8545 -ReadTimeout = "60s" -WriteTimeout = "60s" -MaxRequestsPerIPAndSecond = 50000 -EnableHttpLog = true -BatchRequestsEnabled = false -BatchRequestsLimit = 20 - -[DB] -User = "pool_user" -Password = "pool_password" -Name = "pool_db" -Host = "xlayer-pool-db" -Port = "5432" -EnableLog = false -MaxConns = 200 - -[Sender] -SequencerURL = "http://xlayer-seq:8545" -ResendTxsCheckInterval = "1s" -Workers = 5 -QueueSize = 25 - -[Monitor] -L2NodeURL = "http://xlayer-seq:8545" -Workers = 5 -QueueSize = 25 -RetryWaitInterval = "3s" -InitialWaitInterval = "1s" -TxLifeTimeMax = "10s" \ No newline at end of file diff --git a/test-pp-op/config/xlayerconfig-mainnet-rpc.yaml b/test-pp-op/config/xlayerconfig-mainnet-rpc.yaml deleted file mode 100644 index 923419f1a8868..0000000000000 --- a/test-pp-op/config/xlayerconfig-mainnet-rpc.yaml +++ /dev/null @@ -1,29 +0,0 @@ -datadir: /home/erigon/data/ -chain: xlayer-mainnet -http: true -private.api.addr: localhost:9091 -zkevm.l2-chain-id: 196 -zkevm.l2-sequencer-rpc-url: https://rpc.xlayer.tech -zkevm.l2-datastreamer-url: stream.xlayer.tech:8800 -zkevm.l1-chain-id: 1 -zkevm.l1-rpc-url: https://rpc.ankr.com/eth -zkevm.increment-tree-always: true -zkevm.l1-cache-enabled: true - -zkevm.data-stream-host: "localhost" -zkevm.data-stream-port: 6900 - -zkevm.address-sequencer: "0xAF9d27ffe4d51eD54AC8eEc78f2785D7E11E5ab1" -zkevm.address-zkevm: "0x2B0ee28D4D51bC9aDde5E58E295873F61F4a0507" -zkevm.address-rollup: "0x5132A183E9F3CB7C848b0AAC5Ae0c4f0491B7aB2" -zkevm.address-ger-manager: "0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb" - -zkevm.l1-rollup-id: 3 -zkevm.l1-first-block: 19218658 -zkevm.l1-block-range: 2000 -zkevm.l1-query-delay: 1000 -zkevm.datastream-version: 3 - -http.api: [eth, debug, net, trace, web3, erigon, zkevm] -http.addr: 0.0.0.0 -http.port: 8545 diff --git a/test-pp-op/config/xlayerconfig-mainnet.yaml b/test-pp-op/config/xlayerconfig-mainnet.yaml deleted file mode 100644 index 50c2d06e82a4d..0000000000000 --- a/test-pp-op/config/xlayerconfig-mainnet.yaml +++ /dev/null @@ -1,87 +0,0 @@ -datadir: /home/erigon/data/ -chain: xlayer-mainnet -http: true -private.api.addr: localhost:9091 -zkevm.l2-chain-id: 196 -zkevm.l2-sequencer-rpc-url: https://rpc.xlayer.tech -zkevm.l2-datastreamer-url: stream.xlayer.tech:8800 -zkevm.l1-chain-id: 1 -# `zkevm.l1-rpc-url` must be changed before running. -# using a wrong default value so it can report and error and remind you to change this value. -zkevm.l1-rpc-url: https://rpc.ankr.com/eth/ -#zkevm.increment-tree-always: true - -#debug.limit: 8554110 - -zkevm.sequencer-block-seal-time: "1s" -zkevm.sequencer-max-block-seal-time: "3s" -zkevm.sequencer-batch-seal-time: "10s" -zkevm.sequencer-batch-sleep-duration: "0s" - -zkevm.data-stream-host: "localhost" -zkevm.data-stream-port: 6900 -zkevm.default-gas-price: 1 -zkevm.max-gas-price: 0 -zkevm.gas-price-factor: 0.000001 -zkevm.allow-free-transactions: true - -txpool.packbatchspeciallist : ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534", "0xa03666Fb51Aa9aD2DE70e0434072A007b3C91A9E"] -txpool.globalslots: 1000000 -txpool.globalbasefeeslots: 1000000 -txpool.globalqueue: 1000000 -txpool.commit.every: "10m" - -zkevm.address-sequencer: "0xAF9d27ffe4d51eD54AC8eEc78f2785D7E11E5ab1" -zkevm.address-zkevm: "0x2B0ee28D4D51bC9aDde5E58E295873F61F4a0507" -zkevm.address-rollup: "0x5132A183E9F3CB7C848b0AAC5Ae0c4f0491B7aB2" -zkevm.address-ger-manager: "0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb" - -zkevm.l1-rollup-id: 3 -zkevm.l1-first-block: 19218658 -zkevm.l1-block-range: 2000 -zkevm.l1-query-delay: 1000 -zkevm.datastream-version: 3 - -http.api: [eth, debug, net, trace, web3, erigon, txpool, zkevm] -http.addr: 0.0.0.0 -http.port: 8545 - -gpo.type: "follower" -gpo.update-period: "300s" -gpo.factor: 0.01 -gpo.kafka-url: "0.0.0.0" -gpo.topic: "explorer" -gpo.group-id: "web3" -gpo.blocks: 3 -gpo.default-l1-coin-price: 2000 -gpo.default-l2-coin-price: 50 -gpo.gas-price-usdt: 0.000000476190476 -gpo.congestion-threshold: 0 - -pprof: true -pprof.port: 6060 -pprof.addr: 0.0.0.0 - -metrics: true -metrics.addr: "0.0.0.0" -metrics.port: 9095 - -yieldsize: 35 -zkevm.seal-batch-immediately-on-overflow: true -zkevm.sequencer-timeout-on-empty-tx-pool: 1ms -zkevm.pre-run-address-list: [""] -zkevm.block-info-concurrent: true -zkevm.standalone-smt-db: true -zkevm.enable-async-commit: true - -# to reduce lock race in stress test -txpool.enabletimsort: true -zkevm.bulk-add-txs: true -zkevm.enable-add-tx-notify: true - -#zkevm.verification-batch-delay: 2 -#zkevm.skip-analysis-group-api: true -# zkevm.analysis-group-nacos-urls: "url1:80,url2:80" -# zkevm.analysis-group-nacos-namespace: "ns-global" -# zkevm.analysis-group-service-name: "analysis-group" -# zkevm.analysis-group-api-path: "api/v1/196/validHeight" diff --git a/test-pp-op/contracts/OKBToken.sol b/test-pp-op/contracts/OKBToken.sol deleted file mode 100644 index 7e9344d091bb3..0000000000000 --- a/test-pp-op/contracts/OKBToken.sol +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -interface IERC20 { - function totalSupply() external view returns (uint256); - function balanceOf(address account) external view returns (uint256); - function transfer(address to, uint256 amount) external returns (bool); - function allowance(address owner, address spender) external view returns (uint256); - function approve(address spender, uint256 amount) external returns (bool); - function transferFrom(address from, address to, uint256 amount) external returns (bool); - - event Transfer(address indexed from, address indexed to, uint256 value); - event Approval(address indexed owner, address indexed spender, uint256 value); -} - -contract StandardERC20 is IERC20 { - string public name; - string public symbol; - uint8 public constant decimals = 18; - uint256 private _totalSupply; - - mapping(address => uint256) private _balances; - mapping(address => mapping(address => uint256)) private _allowances; - - constructor( - string memory _name, - string memory _symbol, - uint256 _initialSupply - ) { - name = _name; - symbol = _symbol; - _totalSupply = _initialSupply * 10**decimals; - _balances[msg.sender] = _totalSupply; - emit Transfer(address(0), msg.sender, _totalSupply); - } - - function totalSupply() public view override returns (uint256) { - return _totalSupply; - } - - function balanceOf(address account) public view override returns (uint256) { - return _balances[account]; - } - - function transfer(address to, uint256 amount) public override returns (bool) { - require(to != address(0), "ERC20: transfer to zero address"); - require(_balances[msg.sender] >= amount, "ERC20: insufficient balance"); - - _balances[msg.sender] -= amount; - _balances[to] += amount; - - emit Transfer(msg.sender, to, amount); - return true; - } - - function allowance(address owner, address spender) public view override returns (uint256) { - return _allowances[owner][spender]; - } - - function approve(address spender, uint256 amount) public override returns (bool) { - require(spender != address(0), "ERC20: approve to zero address"); - - _allowances[msg.sender][spender] = amount; - emit Approval(msg.sender, spender, amount); - return true; - } - - function transferFrom(address from, address to, uint256 amount) public override returns (bool) { - require(from != address(0), "ERC20: transfer from zero address"); - require(to != address(0), "ERC20: transfer to zero address"); - require(_balances[from] >= amount, "ERC20: insufficient balance"); - require(_allowances[from][msg.sender] >= amount, "ERC20: insufficient allowance"); - - _balances[from] -= amount; - _balances[to] += amount; - _allowances[from][msg.sender] -= amount; - - emit Transfer(from, to, amount); - return true; - } - - function mint(address to, uint256 amount) public { - require(to != address(0), "ERC20: mint to zero address"); - - _totalSupply += amount; - _balances[to] += amount; - emit Transfer(address(0), to, amount); - } - - function burn(uint256 amount) public { - require(_balances[msg.sender] >= amount, "ERC20: insufficient balance"); - - _balances[msg.sender] -= amount; - _totalSupply -= amount; - emit Transfer(msg.sender, address(0), amount); - } -} diff --git a/test-pp-op/contracts/foundry.toml b/test-pp-op/contracts/foundry.toml deleted file mode 100644 index 27db5c056c5a9..0000000000000 --- a/test-pp-op/contracts/foundry.toml +++ /dev/null @@ -1,9 +0,0 @@ -[profile.default] -src = "." -out = "../tmp/OKB/out" -cache_path = "../tmp/OKB/cache" -libs = ["lib"] -solc_version = "0.8.19" - -[rpc_endpoints] -local = "http://127.0.0.1:8545" diff --git a/test-pp-op/docker-compose-local.yml b/test-pp-op/docker-compose-local.yml deleted file mode 100644 index 34f1d842c85e5..0000000000000 --- a/test-pp-op/docker-compose-local.yml +++ /dev/null @@ -1,925 +0,0 @@ -networks: - default: - name: pp-op - -services: - l1-geth-remove-db: - image: "alpine:3.19.0" - container_name: l1-geth-remove-db - command: rm -rf /execution/geth - volumes: - - ./l1-geth/execution:/execution - - l1-beacon-remove-db: - image: "alpine:3.19.0" - container_name: l1-beacon-remove-db - command: rm -rf /consensus/beacondata /consensus/validatordata /consensus/genesis.ssz - volumes: - - ./l1-geth/consensus:/consensus - - l1-create-beacon-chain-genesis: - image: "gcr.io/prysmaticlabs/prysm/cmd/prysmctl:v5.1.2" - container_name: l1-create-beacon-chain-genesis - command: - - testnet - - generate-genesis - - --fork=deneb - - --num-validators=4 - - --genesis-time-delay=0 - - --output-ssz=/consensus/genesis.ssz - - --chain-config-file=/consensus/config.yml - - --geth-genesis-json-in=/execution/genesis-raw.json - - --geth-genesis-json-out=/execution/genesis.json - volumes: - - ./l1-geth/consensus:/consensus - - ./l1-geth/execution:/execution - depends_on: - l1-beacon-remove-db: - condition: service_completed_successfully - - l1-fix-genesis-fork-times: - image: "alpine:3.19.0" - container_name: l1-fix-genesis-fork-times - command: - - /bin/sh - - -c - - | - apk add --no-cache jq - echo "Fixing genesis.json fork times..." - sed -i 's/"shanghaiTime": [0-9]*/"shanghaiTime": 0/g' /execution/genesis.json - sed -i 's/"cancunTime": [0-9]*/"cancunTime": 0/g' /execution/genesis.json - echo "Adding blobSchedule for Cancun..." - jq '.config.blobSchedule = {"cancun": {"target": 3, "max": 6, "baseFeeUpdateFraction": 3338477}}' /execution/genesis.json > /tmp/genesis.json && mv /tmp/genesis.json /execution/genesis.json - echo "Removing terminalTotalDifficultyPassed for op-node compatibility..." - jq 'del(.config.terminalTotalDifficultyPassed)' /execution/genesis.json > /tmp/genesis.json && mv /tmp/genesis.json /execution/genesis.json - echo "Genesis.json: shanghai=0, cancun=0 (MCOPY enabled), blobSchedule added, terminalTotalDifficultyPassed removed" - cat /execution/genesis.json | jq '.config | {shanghaiTime, cancunTime, terminalTotalDifficulty, blobSchedule}' - volumes: - - ./l1-geth/execution:/execution - depends_on: - l1-create-beacon-chain-genesis: - condition: service_completed_successfully - - l1-geth-genesis: - image: "ethereum/client-go:v1.15.11" - container_name: l1-geth-genesis - command: --datadir=/execution --gcmode=archive init --state.scheme=hash /execution/genesis.json - volumes: - - ./l1-geth/execution:/execution - - ./l1-geth/execution/genesis.json:/execution/genesis.json - depends_on: - l1-fix-genesis-fork-times: - condition: service_completed_successfully - l1-geth-remove-db: - condition: service_completed_successfully - - l1-geth: - image: "ethereum/client-go:v1.15.11" - container_name: l1-geth - command: - - --http - - --http.api=eth,net,web3,debug,admin - - --http.addr=0.0.0.0 - - --http.corsdomain=* - - --http.vhosts=* - - --ws - - --ws.api=eth,net,web3,debug - - --ws.addr=0.0.0.0 - - --ws.origins=* - - --authrpc.vhosts=* - - --authrpc.addr=0.0.0.0 - - --authrpc.jwtsecret=/execution/jwtsecret - - --datadir=/execution - - --allow-insecure-unlock - - --unlock=0x123463a4b065722e99115d6c222f267d9cabb524 - - --password=/execution/geth_password.txt - - --nodiscover - - --syncmode=full - - --gcmode=archive - - --ipcdisable - - --rpc.allow-unprotected-txs - - --verbosity=3 - ports: - - 8551:8551 - - 8545:8545 - - 8546:8546 - depends_on: - l1-geth-genesis: - condition: service_completed_successfully - volumes: - - ./l1-geth/execution:/execution - - ./l1-geth/execution/jwtsecret:/execution/jwtsecret - - ./l1-geth/execution/geth_password.txt:/execution/geth_password.txt - healthcheck: - test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] - interval: 10s - timeout: 5s - retries: 5 - - l1-beacon-chain: - image: "gcr.io/prysmaticlabs/prysm/beacon-chain:v5.1.2" - container_name: l1-beacon-chain - command: - - --datadir=/consensus/beacondata - - --min-sync-peers=0 - - --genesis-state=/consensus/genesis.ssz - - --bootstrap-node= - - --interop-eth1data-votes - - --chain-config-file=/consensus/config.yml - - --contract-deployment-block=0 - - --chain-id=${CHAIN_ID:-1337} - - --rpc-host=0.0.0.0 - - --grpc-gateway-host=0.0.0.0 - - --execution-endpoint=http://l1-geth:8551 - - --accept-terms-of-use - - --jwt-secret=/execution/jwtsecret - - --suggested-fee-recipient=0x123463a4b065722e99115d6c222f267d9cabb524 - - --minimum-peers-per-subnet=0 - - --enable-debug-rpc-endpoints - - --verbosity=info - depends_on: - l1-create-beacon-chain-genesis: - condition: service_completed_successfully - l1-geth: - condition: service_healthy - ports: - - 4000:4000 - - 3500:3500 - - 18080:8080 - - 6060:6060 - - 19090:9090 - volumes: - - ./l1-geth/consensus:/consensus - - ./l1-geth/execution:/execution - - ./l1-geth/execution/jwtsecret:/execution/jwtsecret - - l1-validator: - image: "gcr.io/prysmaticlabs/prysm/validator:v5.1.2" - container_name: l1-validator - command: - - --beacon-rpc-provider=l1-beacon-chain:4000 - - --datadir=/consensus/validatordata - - --accept-terms-of-use - - --interop-num-validators=4 - - --interop-start-index=0 - - --chain-config-file=/consensus/config.yml - - --verbosity=info - depends_on: - l1-beacon-chain: - condition: service_started - volumes: - - ./l1-geth/consensus:/consensus - - xlayer-approve: - container_name: xlayer-approve - image: hermeznetwork/zkevm-node:v0.6.6 - volumes: - - ./keystore/sequencer.keystore:/pk/keystore - - ./config/test.node.config.toml:/app/config.toml - - ./config/test.genesis.config.json:/app/genesis.json - command: - - "/bin/sh" - - "-c" - - "/app/zkevm-node approve --network custom --custom-network-file /app/genesis.json --key-store-path /pk/keystore --pw testonly --am 115792089237316195423570985008687907853269984665640564039457584007913129639935 -y --cfg /app/config.toml" - - xlayer-seq: - container_name: xlayer-seq - image: cdk-erigon - environment: - - CDK_ERIGON_SEQUENCER=1 - - WRITE_MAP=true - ports: - - 6062:6060 - - 8123:8545 - - 6900:6900 - - 9092:9095 - volumes: - - ./data/seq/:/home/erigon/data/ - - ./config/test.erigon.seq.config.yaml:/usr/src/app/config.yaml - - ./config/first-batch-config.json:/usr/src/app/first-batch-config.json - - ./config/dynamic-mynetwork-allocs.json:/usr/src/app/dynamic-mynetwork-allocs.json - - ./config/dynamic-mynetwork-chainspec.json:/usr/src/app/dynamic-mynetwork-chainspec.json - - ./config/dynamic-mynetwork-conf.json:/usr/src/app/dynamic-mynetwork-conf.json - command: > - cdk-erigon --http.vhosts=* --http.corsdomain=* --ws --config=/usr/src/app/config.yaml - - xlayer-mainnet-seq: - container_name: xlayer-seq - image: cdk-erigon - environment: - - CDK_ERIGON_SEQUENCER=1 - - WRITE_MAP=true - ports: - - 6062:6060 - - 8123:8545 - - 6900:6900 - - 9092:9095 - volumes: - - ./mainnet/seq:/home/erigon/data/ - - ./config/xlayerconfig-mainnet.yaml:/usr/src/app/config.yaml - command: > - cdk-erigon --http.vhosts=* --http.corsdomain=* --ws --config=/usr/src/app/config.yaml - - xlayer-bridge-db: - container_name: xlayer-bridge-db - image: postgres:15 - deploy: - resources: - limits: - memory: 2G - reservations: - memory: 1G - ports: - - 5439:5432 - environment: - - POSTGRES_USER=test_user - - POSTGRES_PASSWORD=test_password - - POSTGRES_DB=test_db - command: [ "postgres", "-N", "500" ] - - xlayer-bridge-service: - container_name: xlayer-bridge-service - image: ${XLAYER_BRIDGE_SERVICE_IMAGE_TAG} - ports: - - 8080:8080 - - 9090:9090 - environment: - - ZKEVM_BRIDGE_DATABASE_USER=test_user - - ZKEVM_BRIDGE_DATABASE_PASSWORD=test_password - - ZKEVM_BRIDGE_DATABASE_NAME=test_db - - ZKEVM_BRIDGE_DATABASE_HOST=xlayer-bridge-db - - ZKEVM_BRIDGE_DATABASE_PORT=5432 - volumes: - - ./keystore/sequencer.keystore:/pk/keystore.claimtxmanager - - ./config/test.bridge.config.toml:/app/config.toml - command: - - "/bin/sh" - - "-c" - - "/app/zkevm-bridge run --cfg /app/config.toml" - - xlayer-bridge-ui: - container_name: xlayer-bridge-ui - image: hermeznetwork/zkevm-bridge-ui:latest - ports: - - 8090:80 - environment: - - ETHEREUM_RPC_URL=http://127.0.0.1:8545 - - ETHEREUM_EXPLORER_URL=http://127.0.0.1:4000 - - ETHEREUM_ROLLUP_MANAGER_ADDRESS=0xE96dBF374555C6993618906629988d39184716B3 - - ETHEREUM_BRIDGE_CONTRACT_ADDRESS=0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851 - - ETHEREUM_FORCE_UPDATE_GLOBAL_EXIT_ROOT=true - - ETHEREUM_PROOF_OF_EFFICIENCY_CONTRACT_ADDRESS=0xE45CCD0757670580a4a3600DE5cef1e45F0Ec2bd - - POLYGON_ZK_EVM_RPC_URL=http://127.0.0.1:8123 - - POLYGON_ZK_EVM_EXPLORER_URL=http://127.0.0.1:4001 - - POLYGON_ZK_EVM_BRIDGE_CONTRACT_ADDRESS=0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851 - - POLYGON_ZK_EVM_NETWORK_ID=1 - - BRIDGE_API_URL=http://127.0.0.1:8080 - - ENABLE_FIAT_EXCHANGE_RATES=false - - ENABLE_OUTDATED_NETWORK_MODAL=false - - ENABLE_DEPOSIT_WARNING=false - - ENABLE_REPORT_FORM=false - - RESOLVE_RELATIVE_URLS=false - - xlayer-pool-db: - container_name: xlayer-pool-db - image: postgres:15 - ports: - - 5440:5432 - volumes: - - /var/lib/postgresql/data - environment: - - POSTGRES_USER=pool_user - - POSTGRES_PASSWORD=pool_password - - POSTGRES_DB=pool_db - command: - - "postgres" - - "-N" - - "500" - - xlayer-pool-manager: - container_name: xlayer-pool-manager - image: hermeznetwork/zkevm-pool-manager:v0.1.2 - deploy: - resources: - limits: - memory: 1G - reservations: - memory: 512M - ports: - - 8125:8545 - volumes: - - ./config/test.poolmanager.toml:/app/poolmanager.toml - command: - - "/bin/sh" - - "-c" - - "/app/zkevm-pool-manager run --cfg /app/poolmanager.toml" - - xlayer-agg-sender: - container_name: xlayer-agg-sender - image: aggkit:local - restart: on-failure - volumes: - - ./data/cdk-node:/tmp - - ./keystore/aggregator.keystore:/etc/aggkit/aggregator.keystore - - ./keystore/sequencer.keystore:/etc/aggkit/sequencer.keystore - - ./config/aggkit.toml:/etc/aggkit/aggkit.toml - - ./config/test.genesis.config.json:/etc/aggkit/genesis.json - ports: - - 5576:5576 - command: ["run", "--cfg=/etc/aggkit/aggkit.toml", "--components=aggsender"] - - xlayer-agglayer: - container_name: xlayer-agglayer - image: zjg555543/agglayer:upstream-v0.3.3 - ports: - - 4443:4443 - - 4444:4444 - - 4446:4446 - - 9094:9092 - volumes: - - ./keystore/agglayer.keystore:/etc/zkevm/agglayer.keystore - - ./config/agglayer-config.toml:/etc/zkevm/agglayer-config.toml - - ./data/agglayer/storage:/etc/zkevm/storage/ - - ./data/agglayer/backups:/etc/zkevm/backups/ - command: - - "/bin/sh" - - "-c" - - "/usr/local/bin/agglayer run --cfg /etc/zkevm/agglayer-config.toml" - - xlayer-agglayer-prover: - container_name: xlayer-agglayer-prover - image: zjg555543/agglayer:upstream-v0.3.3 - volumes: - - ./config/agglayer-prover-config.toml:/etc/zkevm/agglayer-prover-config.toml - ports: - - 4445:4445 - - 9093:9093 - command: - - "/bin/sh" - - "-c" - - "/usr/local/bin/agglayer prover --cfg /etc/zkevm/agglayer-prover-config.toml" - - xlayer-agg-db: - container_name: xlayer-agg-db - image: postgres:15 - deploy: - resources: - limits: - memory: 2G - reservations: - memory: 1G - ports: - - 5434:5432 - environment: - - POSTGRES_USER=aggregator_user - - POSTGRES_PASSWORD=aggregator_password - - POSTGRES_DB=aggregator_db - command: - - "postgres" - - "-N" - - "500" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U aggregator_user -d aggregator_db"] - interval: 5s - timeout: 5s - retries: 5 - start_period: 5s - - xlayer-rpc: - container_name: xlayer-rpc - image: cdk-erigon - environment: - - CDK_ERIGON_SEQUENCER=0 - - WRITE_MAP=true - ports: - - 16061:6060 - - 18124:8545 - - 16901:6900 - - 19091:9095 - volumes: - - ./data/rpc/:/home/erigon/data/ - - ./config/test.erigon.rpc.config.yaml:/usr/src/app/config.yaml - - ./config/first-batch-config.json:/usr/src/app/first-batch-config.json - - ./config/dynamic-mynetwork-allocs.json:/usr/src/app/dynamic-mynetwork-allocs.json - - ./config/dynamic-mynetwork-chainspec.json:/usr/src/app/dynamic-mynetwork-chainspec.json - - ./config/dynamic-mynetwork-conf.json:/usr/src/app/dynamic-mynetwork-conf.json - command: > - cdk-erigon --http.vhosts=* --http.corsdomain=* --ws --config=/usr/src/app/config.yaml - xlayer-oracle: - container_name: xlayer-oracle - image: aggkit:local - volumes: - - ./data/oracle:/tmp - - ./keystore/aggoracle.keystore:/etc/aggkit/aggoracle.keystore - - ./config-op/aggkit.toml:/etc/aggkit/aggkit.toml - - ./config/test.genesis.config.json:/etc/aggkit/genesis.json - ports: - - 15576:5576 - command: ["run", "--cfg=/etc/aggkit/aggkit.toml", "--components=aggoracle"] - op-geth-seq: - image: "${OP_GETH_IMAGE_TAG}" - container_name: op-geth-seq - entrypoint: geth - volumes: - - ./data/op-geth-seq:/datadir - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.seq.config.toml:/config.toml - ports: - - "8123:8545" - - "7546:7546" - - "8552:8552" - - "30303:30303" - - "30303:30303/udp" - - "9090:9090" # pprof port - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - - --rollup.disabletxpoolgossip=false - - --pp-rpc-legacy-header-sync-rate-limit=10000 - healthcheck: - test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-geth-rpc: - image: "${OP_GETH_IMAGE_TAG}" - container_name: op-geth-rpc - entrypoint: geth - volumes: - - ./data/op-geth-rpc:/datadir - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.rpc.config.toml:/config.toml - ports: - - "8124:8545" - - "30304:30303" - - "30304:30303/udp" - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - # - --rollup.sequencerhttp=http://op-geth-seq:8545 - - --rollup.enabletxpooladmission - - --pp-rpc-legacy-header-sync-rate-limit=10000 - - op-seq: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-seq - volumes: - - ./config-op/rollup.json:/rollup.json - - ./config-op/jwt.txt:/jwt.txt - - ./data/op-seq:/data - - ./l1-geth/execution/:/l1/ - ports: - - "9545:9545" - - "7070:7070" - - "9223:9223" - - "9223:9223/udp" - - "9091:9091" # pprof port - command: - - /app/op-node/bin/op-node - - --log.level=debug - - --l2=http://op-geth-seq:8552 - - --l2.jwt-secret=/jwt.txt - - --sequencer.enabled - - --sequencer.l1-confs=5 - - --verifier.l1-confs=1 - - --rollup.config=/rollup.json - - --rpc.addr=0.0.0.0 - - --p2p.listen.tcp=9223 - - --p2p.listen.udp=9223 - - --p2p.priv.raw=e054b5748fb29a82994ea170af9e6094a163a0d11308dea91a38744c4e7c94da - - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db - - --p2p.discovery.path=/data/p2p/opnode_discovery_db - - --p2p.no-discovery - - --rpc.enable-admin - - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} - - --l1=${L1_RPC_URL_IN_DOCKER} - - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} - - --l1.rpckind=standard - - --rollup.l1-chain-config=/l1/genesis.json - - --safedb.path=/data/safedb - - --conductor.enabled=${CONDUCTOR_ENABLED:-false} # 默认关闭 - - --conductor.rpc=http://op-conductor:8547 - - --pprof.enabled - - --pprof.addr=0.0.0.0 - - --pprof.port=9091 - depends_on: - op-geth-seq: - condition: service_healthy - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-rpc: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-rpc - volumes: - - ./data/op-rpc:/data - - ./config-op/rollup.json:/rollup.json - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/oprpc_p2p_priv.txt:/opnode_p2p_priv.txt - - ./l1-geth/execution/:/l1 - ports: - - "9555:9545" - command: - - /app/op-node/bin/op-node - - --log.level=debug - - --l2=http://op-geth-rpc:8552 - - --l2.jwt-secret=/jwt.txt - - --sequencer.enabled=false - - --verifier.l1-confs=1 - - --rollup.config=/rollup.json - - --rpc.addr=0.0.0.0 - - --rpc.port=9545 - - --p2p.listen.tcp=9223 - - --p2p.listen.udp=9223 - - --p2p.priv.raw=604557d042fbea9ed42f46c0c95c346a932b6a5ef0c0dd07a00dbf95801a2510 - - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db - - --p2p.discovery.path=/data/p2p/opnode_discovery_db - - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65 - - --p2p.no-discovery - - --rpc.enable-admin=true - - --l1=${L1_RPC_URL_IN_DOCKER} - - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} - - --l1.rpckind=standard - - --rollup.l1-chain-config=/l1/genesis.json - - --safedb.path=/data/safedb - - --pp-rpc-url=${PP_RPC_URL} - depends_on: - - op-geth-rpc - - op-conductor: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-conductor - volumes: - - ./data/op-conductor:/data - - ./config-op/rollup.json:/rollup.json - ports: - - "8547:8547" # RPC port -# - "50050:50050" # Consensus port - command: - - /app/op-conductor/bin/op-conductor - - --log.level=debug - # already existed service - - --node.rpc=http://op-seq:9545 - - --execution.rpc=http://op-geth-seq:8545 - # Raft Config - - --raft.server.id=conductor-1 - - --raft.storage.dir=/data/raft - - --raft.bootstrap=true - - --consensus.addr=0.0.0.0 - - --consensus.port=50050 - - --consensus.advertised=op-conductor:50050 - # RPC Config - - --rpc.addr=0.0.0.0 - - --rpc.port=8547 - - --rpc.enable-proxy=true - # Healthcheck Config - - --healthcheck.interval=1 - - --healthcheck.unsafe-interval=3 - - --healthcheck.min-peer-count=1 - - --rollup.config=/rollup.json - depends_on: - op-seq: - condition: service_healthy - op-geth-seq: - condition: service_healthy - - op-batcher: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-batcher - command: - - /app/op-batcher/bin/op-batcher - - --log.level=debug - - --l2-eth-rpc=${OP_BATCHER_L2_ETH_RPC:-http://op-geth-seq:8545} - - --rollup-rpc=${OP_BATCHER_ROLLUP_RPC:-http://op-seq:9545} - - --wait-node-sync=true - - --check-recent-txs-depth=5 - - --poll-interval=5s - - --batch-type=1 - - --compression-algo=brotli-11 - - --data-availability-type=auto - - --max-channel-duration=30 - - --target-num-frames=5 - - --sub-safety-margin=6 - - --num-confirmations=4 - - --network-timeout=10s - - --safe-abort-nonce-too-low-count=3 - - --max-pending-tx=10 - - --resubmission-timeout=30s - - --rpc.addr=0.0.0.0 - - --rpc.port=8548 - - --rpc.enable-admin - - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} - - --private-key=${OP_BATCHER_PRIVATE_KEY} - - --throttle.block-size-upper-limit=1300000 - - --active-sequencer-check-duration=5s - - op-proposer: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-proposer - environment: - - DISPUTE_GAME_FACTORY_ADDRESS=${DISPUTE_GAME_FACTORY_ADDRESS} - command: - - /app/op-proposer/bin/op-proposer - - --log.level=debug - - --poll-interval=20s - - --wait-node-sync=true - - --allow-non-finalized=false - - --num-confirmations=1 - - --safe-abort-nonce-too-low-count=3 - - --resubmission-timeout=30s - - --rpc.port=8560 - - --rollup-rpc=http://op-rpc:9545 - - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} - - --proposal-interval=1m - - --private-key=${OP_PROPOSER_PRIVATE_KEY} - - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} - - --game-type=${GAME_TYPE:-0} - - --allow-non-finalized - - --genesis-height=${FORK_BLOCK} - depends_on: - - op-batcher - - op-challenger: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-challenger - environment: - - L1_RPC_URL_IN_DOCKER=${L1_RPC_URL_IN_DOCKER} - - L1_BEACON_URL_IN_DOCKER=${L1_BEACON_URL_IN_DOCKER} - - DISPUTE_GAME_FACTORY_ADDRESS=${DISPUTE_GAME_FACTORY_ADDRESS} - volumes: - - ./data/cannon-data:/data - - ./config-op/rollup.json:/rollup.json - - ./config-op/genesis.json:/l2-genesis.json - depends_on: - - op-seq - command: - - /app/op-challenger/bin/op-challenger - - --log.level=debug - - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} - - --l1-beacon=${L1_BEACON_URL_IN_DOCKER} - - --l2-eth-rpc=http://op-geth-rpc:8545 - - --rollup-rpc=http://op-rpc:9545 - - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} - - --cannon-bin=/app/cannon/bin/cannon - - --cannon-server=/data/op-program - - --cannon-prestate=/data/prestate-mt64.bin.gz - - --cannon-rollup-config=/rollup.json - - --cannon-l2-genesis=/l2-genesis.json - - --private-key=${OP_PROPOSER_PRIVATE_KEY} - - --trace-type=cannon,permissioned - - --datadir=/data - - --game-window=${GAME_WINDOW}s - - op-dispute-mon: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-dispute-mon - depends_on: - - op-challenger - - op-proposer - command: - - /app/op-dispute-mon/bin/op-dispute-mon - - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} - - --rollup-rpc=http://op-rpc:9545 - - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} - - --game-window=${GAME_WINDOW}s - - --honest-actors=${PROPOSER_ADDRESS} - - op-geth-seq2: - image: "${OP_GETH_IMAGE_TAG}" - container_name: op-geth-seq2 - entrypoint: geth - volumes: - - ./data/op-geth-seq2:/datadir - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.seq.config.toml:/config.toml - ports: - - "8223:8545" - - "30305:30303" - - "30305:30303/udp" - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - - --rollup.disabletxpoolgossip=false - - --pp-rpc-legacy-header-sync-rate-limit=10000 - healthcheck: - test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-seq2: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-seq2 - volumes: - - ./config-op/rollup.json:/rollup.json - - ./config-op/jwt.txt:/jwt.txt - - ./data/op-seq2:/data - - ./l1-geth/execution/:/l1/ - ports: - - "9546:9545" - # - "7070:7070" - - "9224:9223" - - "9224:9223/udp" - command: - - /app/op-node/bin/op-node - - --log.level=info - - --l2=http://op-geth-seq2:8552 - - --l2.jwt-secret=/jwt.txt - - --sequencer.enabled - - --sequencer.stopped - - --sequencer.l1-confs=5 - - --verifier.l1-confs=1 - - --rollup.config=/rollup.json - - --rpc.addr=0.0.0.0 - - --p2p.listen.tcp=9223 - - --p2p.listen.udp=9223 - - --p2p.priv.raw=cff9dac7588f5e6755a72d1e5b5001da3d0f8c06c4242b27d67eb5df4216bd93 - - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db - - --p2p.discovery.path=/data/p2p/opnode_discovery_db - - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65,/dns4/op-seq3/tcp/9223/p2p/16Uiu2HAmRDGMm3UUrP8CfQ3YQo9aaXEXFXA7LeFNztdPMNK5moyD - - --p2p.no-discovery - - --rpc.enable-admin - - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} - - --l1=${L1_RPC_URL_IN_DOCKER} - - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} - - --l1.rpckind=standard - - --rollup.l1-chain-config=/l1/genesis.json - - --safedb.path=/data/safedb - - --conductor.enabled=${CONDUCTOR_ENABLED:-false} - - --conductor.rpc=http://op-conductor2:8547 - depends_on: - op-geth-seq2: - condition: service_healthy - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-conductor2: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-conductor2 - volumes: - - ./data/op-conductor2:/data - - ./config-op/rollup.json:/rollup.json - ports: - - "8548:8547" # RPC port -# - "50051:50050" # Consensus port - command: - - /app/op-conductor/bin/op-conductor - - --log.level=debug - # already existed service - - --node.rpc=http://op-seq2:9545 - - --execution.rpc=http://op-geth-seq2:8545 - # Raft Config - - --raft.server.id=conductor-2 - - --raft.storage.dir=/data/raft - - --raft.bootstrap=false - - --consensus.addr=0.0.0.0 - - --consensus.port=50050 - - --consensus.advertised=op-conductor2:50050 - # RPC Config - - --rpc.addr=0.0.0.0 - - --rpc.port=8547 - - --rpc.enable-proxy=true - # Healthcheck Config - - --healthcheck.interval=1 - - --healthcheck.unsafe-interval=3 - - --healthcheck.min-peer-count=1 - - --rollup.config=/rollup.json - depends_on: - op-seq2: - condition: service_healthy - op-geth-seq2: - condition: service_healthy - - op-geth-seq3: - image: "${OP_GETH_IMAGE_TAG}" - container_name: op-geth-seq3 - entrypoint: geth - volumes: - - ./data/op-geth-seq3:/datadir - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.seq.config.toml:/config.toml - ports: - - "8323:8545" - - "30306:30303" - - "30306:30303/udp" - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - - --rollup.disabletxpoolgossip=false - - --pp-rpc-legacy-header-sync-rate-limit=10000 - healthcheck: - test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-seq3: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-seq3 - volumes: - - ./config-op/rollup.json:/rollup.json - - ./config-op/jwt.txt:/jwt.txt - - ./data/op-seq3:/data - - ./l1-geth/execution/:/l1/ - ports: - - "9547:9545" - # - "7070:7070" - - "9225:9223" - - "9225:9223/udp" - command: - - /app/op-node/bin/op-node - - --log.level=info - - --l2=http://op-geth-seq3:8552 - - --l2.jwt-secret=/jwt.txt - - --sequencer.enabled - - --sequencer.stopped - - --sequencer.l1-confs=5 - - --verifier.l1-confs=1 - - --rollup.config=/rollup.json - - --rpc.addr=0.0.0.0 - - --p2p.listen.tcp=9223 - - --p2p.listen.udp=9223 - - --p2p.priv.raw=10785157e7c98628e5e47c3d9b8ebbd12525c45f1554b4a39652b5ce02bb29dc - - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db - - --p2p.discovery.path=/data/p2p/opnode_discovery_db - - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65,/dns4/op-seq2/tcp/9223/p2p/16Uiu2HAmDTjVuEF6V9DccV1JhrHg7DYc5SKm3bw2T75kAFPsGuSp - - --p2p.no-discovery - - --rpc.enable-admin - - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} - - --l1=${L1_RPC_URL_IN_DOCKER} - - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} - - --l1.rpckind=standard - - --rollup.l1-chain-config=/l1/genesis.json - - --safedb.path=/data/safedb - - --conductor.enabled=${CONDUCTOR_ENABLED:-false} - - --conductor.rpc=http://op-conductor3:8547 - depends_on: - op-geth-seq3: - condition: service_healthy - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-conductor3: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-conductor3 - volumes: - - ./data/op-conductor3:/data - - ./config-op/rollup.json:/rollup.json - ports: - - "8549:8547" # RPC port -# - "50052:50050" # Consensus port - command: - - /app/op-conductor/bin/op-conductor - - --log.level=debug - # already existed service - - --node.rpc=http://op-seq3:9545 - - --execution.rpc=http://op-geth-seq3:8545 - # Raft Config - - --raft.server.id=conductor-3 - - --raft.storage.dir=/data/raft - - --raft.bootstrap=false - - --consensus.addr=0.0.0.0 - - --consensus.port=50050 - - --consensus.advertised=op-conductor3:50050 - # RPC Config - - --rpc.addr=0.0.0.0 - - --rpc.port=8547 - - --rpc.enable-proxy=true - # Healthcheck Config - - --healthcheck.interval=1 - - --healthcheck.unsafe-interval=3 - - --healthcheck.min-peer-count=1 - - --rollup.config=/rollup.json - depends_on: - op-seq3: - condition: service_healthy - op-geth-seq3: - condition: service_healthy diff --git a/test-pp-op/docker-compose.yml b/test-pp-op/docker-compose.yml deleted file mode 100644 index a14ed53ce1a9b..0000000000000 --- a/test-pp-op/docker-compose.yml +++ /dev/null @@ -1,663 +0,0 @@ -networks: - default: - name: ${DOCKER_NETWORK:-dev-op} - -services: - l1-geth-remove-db: - image: "alpine:3.19.0" - container_name: l1-geth-remove-db - command: rm -rf /execution/geth - volumes: - - ./l1-geth/execution:/execution - - l1-beacon-remove-db: - image: "alpine:3.19.0" - container_name: l1-beacon-remove-db - command: rm -rf /consensus/beacondata /consensus/validatordata /consensus/genesis.ssz - volumes: - - ./l1-geth/consensus:/consensus - - l1-create-beacon-chain-genesis: - image: "gcr.io/prysmaticlabs/prysm/cmd/prysmctl:v5.1.2" - container_name: l1-create-beacon-chain-genesis - command: - - testnet - - generate-genesis - - --fork=deneb - - --num-validators=4 - - --genesis-time-delay=0 - - --output-ssz=/consensus/genesis.ssz - - --chain-config-file=/consensus/config.yml - - --geth-genesis-json-in=/execution/genesis-raw.json - - --geth-genesis-json-out=/execution/genesis.json - volumes: - - ./l1-geth/consensus:/consensus - - ./l1-geth/execution:/execution - depends_on: - l1-beacon-remove-db: - condition: service_completed_successfully - - l1-fix-genesis-fork-times: - image: "alpine:3.19.0" - container_name: l1-fix-genesis-fork-times - command: - - /bin/sh - - -c - - | - apk add --no-cache jq - echo "Fixing genesis.json fork times..." - sed -i 's/"shanghaiTime": [0-9]*/"shanghaiTime": 0/g' /execution/genesis.json - sed -i 's/"cancunTime": [0-9]*/"cancunTime": 0/g' /execution/genesis.json - echo "Adding blobSchedule for Cancun..." - jq '.config.blobSchedule = {"cancun": {"target": 3, "max": 6, "baseFeeUpdateFraction": 3338477}}' /execution/genesis.json > /tmp/genesis.json && mv /tmp/genesis.json /execution/genesis.json - echo "Removing terminalTotalDifficultyPassed for op-node compatibility..." - jq 'del(.config.terminalTotalDifficultyPassed)' /execution/genesis.json > /tmp/genesis.json && mv /tmp/genesis.json /execution/genesis.json - echo "Genesis.json: shanghai=0, cancun=0 (MCOPY enabled), blobSchedule added, terminalTotalDifficultyPassed removed" - cat /execution/genesis.json | jq '.config | {shanghaiTime, cancunTime, terminalTotalDifficulty, blobSchedule}' - volumes: - - ./l1-geth/execution:/execution - depends_on: - l1-create-beacon-chain-genesis: - condition: service_completed_successfully - - l1-geth-genesis: - image: "ethereum/client-go:v1.15.11" - container_name: l1-geth-genesis - command: --datadir=/execution --gcmode=archive init --state.scheme=hash /execution/genesis.json - volumes: - - ./l1-geth/execution:/execution - - ./l1-geth/execution/genesis.json:/execution/genesis.json - depends_on: - l1-fix-genesis-fork-times: - condition: service_completed_successfully - l1-geth-remove-db: - condition: service_completed_successfully - - l1-geth: - image: "ethereum/client-go:v1.15.11" - container_name: l1-geth - command: - - --http - - --http.api=eth,net,web3,debug,admin - - --http.addr=0.0.0.0 - - --http.corsdomain=* - - --http.vhosts=* - - --ws - - --ws.api=eth,net,web3,debug - - --ws.addr=0.0.0.0 - - --ws.origins=* - - --authrpc.vhosts=* - - --authrpc.addr=0.0.0.0 - - --authrpc.jwtsecret=/execution/jwtsecret - - --datadir=/execution - - --allow-insecure-unlock - - --unlock=0x123463a4b065722e99115d6c222f267d9cabb524 - - --password=/execution/geth_password.txt - - --nodiscover - - --syncmode=full - - --gcmode=archive - - --ipcdisable - - --rpc.allow-unprotected-txs - - --verbosity=3 - ports: - - 8551:8551 - - 8545:8545 - - 8546:8546 - depends_on: - l1-geth-genesis: - condition: service_completed_successfully - volumes: - - ./l1-geth/execution:/execution - - ./l1-geth/execution/jwtsecret:/execution/jwtsecret - - ./l1-geth/execution/geth_password.txt:/execution/geth_password.txt - healthcheck: - test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] - interval: 10s - timeout: 5s - retries: 5 - - l1-beacon-chain: - image: "gcr.io/prysmaticlabs/prysm/beacon-chain:v5.1.2" - container_name: l1-beacon-chain - command: - - --datadir=/consensus/beacondata - - --min-sync-peers=0 - - --genesis-state=/consensus/genesis.ssz - - --bootstrap-node= - - --interop-eth1data-votes - - --chain-config-file=/consensus/config.yml - - --contract-deployment-block=0 - - --chain-id=${CHAIN_ID:-1337} - - --rpc-host=0.0.0.0 - - --grpc-gateway-host=0.0.0.0 - - --execution-endpoint=http://l1-geth:8551 - - --accept-terms-of-use - - --jwt-secret=/execution/jwtsecret - - --suggested-fee-recipient=0x123463a4b065722e99115d6c222f267d9cabb524 - - --minimum-peers-per-subnet=0 - - --enable-debug-rpc-endpoints - - --verbosity=info - depends_on: - l1-create-beacon-chain-genesis: - condition: service_completed_successfully - l1-geth: - condition: service_healthy - ports: - - 4000:4000 - - 3500:3500 - - 18080:8080 - - 6060:6060 - - 19090:9090 - volumes: - - ./l1-geth/consensus:/consensus - - ./l1-geth/execution:/execution - - ./l1-geth/execution/jwtsecret:/execution/jwtsecret - - l1-validator: - image: "gcr.io/prysmaticlabs/prysm/validator:v5.1.2" - container_name: l1-validator - command: - - --beacon-rpc-provider=l1-beacon-chain:4000 - - --datadir=/consensus/validatordata - - --accept-terms-of-use - - --interop-num-validators=4 - - --interop-start-index=0 - - --chain-config-file=/consensus/config.yml - - --verbosity=info - depends_on: - l1-beacon-chain: - condition: service_started - volumes: - - ./l1-geth/consensus:/consensus - - op-geth-seq: - image: "${OP_GETH_IMAGE_TAG}" - container_name: op-geth-seq - entrypoint: geth - volumes: - - ./data/op-geth-seq:/datadir - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.seq.config.toml:/config.toml - ports: - - "8123:8545" - - "7546:7546" - - "8552:8552" - - "30303:30303" - - "30303:30303/udp" - - "9090:9090" # pprof port - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - - --rollup.disabletxpoolgossip=false - healthcheck: - test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-geth-rpc: - image: "${OP_GETH_IMAGE_TAG}" - container_name: op-geth-rpc - entrypoint: geth - volumes: - - ./data/op-geth-rpc:/datadir - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.rpc.config.toml:/config.toml - ports: - - "8124:8545" - - "30304:30303" - - "30304:30303/udp" - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - # - --rollup.sequencerhttp=http://op-geth-seq:8545 - - --rollup.enabletxpooladmission - - op-seq: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-seq - volumes: - - ./config-op/rollup.json:/rollup.json - - ./config-op/jwt.txt:/jwt.txt - - ./data/op-seq:/data - - ./l1-geth/execution/:/l1/ - ports: - - "9545:9545" - - "7070:7070" - - "9223:9223" - - "9223:9223/udp" - - "9091:9091" # pprof port - command: - - /app/op-node/bin/op-node - - --log.level=debug - - --l2=http://op-geth-seq:8552 - - --l2.jwt-secret=/jwt.txt - - --sequencer.enabled - - --sequencer.l1-confs=5 - - --verifier.l1-confs=1 - - --rollup.config=/rollup.json - - --rpc.addr=0.0.0.0 - - --p2p.listen.tcp=9223 - - --p2p.listen.udp=9223 - - --p2p.priv.raw=e054b5748fb29a82994ea170af9e6094a163a0d11308dea91a38744c4e7c94da - - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db - - --p2p.discovery.path=/data/p2p/opnode_discovery_db - - --p2p.no-discovery - - --rpc.enable-admin - - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} - - --l1=${L1_RPC_URL_IN_DOCKER} - - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} - - --l1.rpckind=standard - - --rollup.l1-chain-config=/l1/genesis.json - - --safedb.path=/data/safedb - - --conductor.enabled=${CONDUCTOR_ENABLED:-false} # 默认关闭 - - --conductor.rpc=http://op-conductor:8547 - - --pprof.enabled - - --pprof.addr=0.0.0.0 - - --pprof.port=9091 - depends_on: - op-geth-seq: - condition: service_healthy - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-rpc: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-rpc - volumes: - - ./data/op-rpc:/data - - ./config-op/rollup.json:/rollup.json - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/oprpc_p2p_priv.txt:/opnode_p2p_priv.txt - - ./l1-geth/execution/genesis.json:/l1-genesis.json - ports: - - "9555:9545" - command: - - /app/op-node/bin/op-node - - --log.level=debug - - --l2=http://op-geth-rpc:8552 - - --l2.jwt-secret=/jwt.txt - - --sequencer.enabled=false - - --verifier.l1-confs=1 - - --rollup.config=/rollup.json - - --rpc.addr=0.0.0.0 - - --rpc.port=9545 - - --p2p.listen.tcp=9223 - - --p2p.listen.udp=9223 - - --p2p.priv.raw=604557d042fbea9ed42f46c0c95c346a932b6a5ef0c0dd07a00dbf95801a2510 - - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db - - --p2p.discovery.path=/data/p2p/opnode_discovery_db - - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65 - - --p2p.no-discovery - - --rpc.enable-admin=true - - --l1=${L1_RPC_URL_IN_DOCKER} - - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} - - --l1.rpckind=standard - - --rollup.l1-chain-config=/l1-genesis.json - - --safedb.path=/data/safedb - depends_on: - - op-geth-rpc - - op-conductor: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-conductor - volumes: - - ./data/op-conductor:/data - - ./config-op/rollup.json:/rollup.json - ports: - - "8547:8547" # RPC port - - "50050:50050" # Consensus port - command: - - /app/op-conductor/bin/op-conductor - - --log.level=debug - # already existed service - - --node.rpc=http://op-seq:9545 - - --execution.rpc=http://op-geth-seq:8545 - # Raft Config - - --raft.server.id=conductor-1 - - --raft.storage.dir=/data/raft - - --raft.bootstrap=true - - --consensus.addr=0.0.0.0 - - --consensus.port=50050 - - --consensus.advertised=op-conductor:50050 - # RPC Config - - --rpc.addr=0.0.0.0 - - --rpc.port=8547 - - --rpc.enable-proxy=true - # Healthcheck Config - - --healthcheck.interval=1 - - --healthcheck.unsafe-interval=3 - - --healthcheck.min-peer-count=1 - - --rollup.config=/rollup.json - depends_on: - op-seq: - condition: service_healthy - op-geth-seq: - condition: service_healthy - - op-batcher: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-batcher - command: - - /app/op-batcher/bin/op-batcher - - --log.level=debug - - --l2-eth-rpc=http://op-geth-seq:8545 - - --rollup-rpc=http://op-seq:9545 - - --poll-interval=1s - - --sub-safety-margin=6 - - --num-confirmations=1 - - --safe-abort-nonce-too-low-count=3 - - --resubmission-timeout=30s - - --rpc.addr=0.0.0.0 - - --rpc.port=8548 - - --rpc.enable-admin - - --max-channel-duration=25 - - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} - - --private-key=${OP_BATCHER_PRIVATE_KEY} - - --throttle.block-size-upper-limit=1300000 - - -data-availability-type=auto - depends_on: - - op-seq - - op-proposer: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-proposer - environment: - - DISPUTE_GAME_FACTORY_ADDRESS=${DISPUTE_GAME_FACTORY_ADDRESS} - command: - - /app/op-proposer/bin/op-proposer - - --log.level=debug - - --poll-interval=2s - - --rpc.port=8560 - - --rollup-rpc=http://op-seq:9545 - - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} - - --proposal-interval=1m - - --private-key=${OP_PROPOSER_PRIVATE_KEY} - - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} - - --game-type=${GAME_TYPE:-0} - - --allow-non-finalized - - --genesis-height=${FORK_BLOCK} - depends_on: - - op-batcher - - op-challenger: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-challenger - environment: - - L1_RPC_URL_IN_DOCKER=${L1_RPC_URL_IN_DOCKER} - - L1_BEACON_URL_IN_DOCKER=${L1_BEACON_URL_IN_DOCKER} - - DISPUTE_GAME_FACTORY_ADDRESS=${DISPUTE_GAME_FACTORY_ADDRESS} - volumes: - - ./data/cannon-data:/data - - ./config-op/rollup.json:/rollup.json - - ./config-op/genesis.json:/l2-genesis.json - depends_on: - - op-seq - command: - - /app/op-challenger/bin/op-challenger - - --log.level=debug - - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} - - --l1-beacon=${L1_BEACON_URL_IN_DOCKER} - - --l2-eth-rpc=http://op-geth-seq:8545 - - --rollup-rpc=http://op-seq:9545 - - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} - - --cannon-bin=/app/cannon/bin/cannon - - --cannon-server=/data/op-program - - --cannon-prestate=/data/prestate-mt64.bin.gz - - --cannon-rollup-config=/rollup.json - - --cannon-l2-genesis=/l2-genesis.json - - --private-key=${OP_PROPOSER_PRIVATE_KEY} - - --trace-type=cannon,permissioned - - --datadir=/data - - --game-window=${GAME_WINDOW}s - - op-dispute-mon: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-dispute-mon - depends_on: - - op-challenger - - op-proposer - command: - - /app/op-dispute-mon/bin/op-dispute-mon - - --l1-eth-rpc=${L1_RPC_URL_IN_DOCKER} - - --rollup-rpc=http://op-seq:9545 - - --game-factory-address=${DISPUTE_GAME_FACTORY_ADDRESS} - - --game-window=${GAME_WINDOW}s - - --honest-actors=${PROPOSER_ADDRESS} - - op-geth-seq2: - image: "${OP_GETH_IMAGE_TAG}" - container_name: op-geth-seq2 - entrypoint: geth - volumes: - - ./data/op-geth-seq2:/datadir - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.seq.config.toml:/config.toml - ports: - - "8223:8545" - - "30305:30303" - - "30305:30303/udp" - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - - --rollup.disabletxpoolgossip=false - healthcheck: - test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-seq2: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-seq2 - volumes: - - ./config-op/rollup.json:/rollup.json - - ./config-op/jwt.txt:/jwt.txt - - ./data/op-seq2:/data - - ./l1-geth/execution/genesis.json:/l1-genesis.json - ports: - - "9546:9545" -# - "7070:7070" - - "9224:9223" - - "9224:9223/udp" - command: - - /app/op-node/bin/op-node - - --log.level=info - - --l2=http://op-geth-seq2:8552 - - --l2.jwt-secret=/jwt.txt - - --sequencer.enabled - - --sequencer.stopped - - --sequencer.l1-confs=5 - - --verifier.l1-confs=1 - - --rollup.config=/rollup.json - - --rpc.addr=0.0.0.0 - - --p2p.listen.tcp=9223 - - --p2p.listen.udp=9223 - - --p2p.priv.raw=cff9dac7588f5e6755a72d1e5b5001da3d0f8c06c4242b27d67eb5df4216bd93 - - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db - - --p2p.discovery.path=/data/p2p/opnode_discovery_db - - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65,/dns4/op-seq3/tcp/9223/p2p/16Uiu2HAmRDGMm3UUrP8CfQ3YQo9aaXEXFXA7LeFNztdPMNK5moyD - - --p2p.no-discovery - - --rpc.enable-admin - - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} - - --l1=${L1_RPC_URL_IN_DOCKER} - - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} - - --l1.rpckind=standard - - --rollup.l1-chain-config=/l1-genesis.json - - --safedb.path=/data/safedb - - --conductor.enabled=${CONDUCTOR_ENABLED:-false} - - --conductor.rpc=http://op-conductor2:8547 - depends_on: - op-geth-seq2: - condition: service_healthy - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-conductor2: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-conductor2 - volumes: - - ./data/op-conductor2:/data - - ./config-op/rollup.json:/rollup.json - ports: - - "8548:8547" # RPC port - - "50051:50050" # Consensus port - command: - - /app/op-conductor/bin/op-conductor - - --log.level=debug - # already existed service - - --node.rpc=http://op-seq2:9545 - - --execution.rpc=http://op-geth-seq2:8545 - # Raft Config - - --raft.server.id=conductor-2 - - --raft.storage.dir=/data/raft - - --raft.bootstrap=false - - --consensus.addr=0.0.0.0 - - --consensus.port=50050 - - --consensus.advertised=op-conductor2:50050 - # RPC Config - - --rpc.addr=0.0.0.0 - - --rpc.port=8547 - - --rpc.enable-proxy=true - # Healthcheck Config - - --healthcheck.interval=1 - - --healthcheck.unsafe-interval=3 - - --healthcheck.min-peer-count=1 - - --rollup.config=/rollup.json - depends_on: - op-seq2: - condition: service_healthy - op-geth-seq2: - condition: service_healthy - - op-geth-seq3: - image: "${OP_GETH_IMAGE_TAG}" - container_name: op-geth-seq3 - entrypoint: geth - volumes: - - ./data/op-geth-seq3:/datadir - - ./config-op/jwt.txt:/jwt.txt - - ./config-op/test.seq.config.toml:/config.toml - ports: - - "8323:8545" - - "30306:30303" - - "30306:30303/udp" - command: - - --verbosity=3 - - --datadir=/datadir - - --db.engine=${DB_ENGINE} - - --config=/config.toml - - --gcmode=archive - - --rollup.disabletxpoolgossip=false - healthcheck: - test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:8545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-seq3: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-seq3 - volumes: - - ./config-op/rollup.json:/rollup.json - - ./config-op/jwt.txt:/jwt.txt - - ./data/op-seq3:/data - - ./l1-geth/execution/genesis.json:/l1-genesis.json - ports: - - "9547:9545" -# - "7070:7070" - - "9225:9223" - - "9225:9223/udp" - command: - - /app/op-node/bin/op-node - - --log.level=info - - --l2=http://op-geth-seq3:8552 - - --l2.jwt-secret=/jwt.txt - - --sequencer.enabled - - --sequencer.stopped - - --sequencer.l1-confs=5 - - --verifier.l1-confs=1 - - --rollup.config=/rollup.json - - --rpc.addr=0.0.0.0 - - --p2p.listen.tcp=9223 - - --p2p.listen.udp=9223 - - --p2p.priv.raw=10785157e7c98628e5e47c3d9b8ebbd12525c45f1554b4a39652b5ce02bb29dc - - --p2p.peerstore.path=/data/p2p/opnode_peerstore_db - - --p2p.discovery.path=/data/p2p/opnode_discovery_db - - --p2p.static=/dns4/op-seq/tcp/9223/p2p/16Uiu2HAkzHdkbmS2VrCsccLibsu7MvGHpmFUMJnMTkKifrtS5m65,/dns4/op-seq2/tcp/9223/p2p/16Uiu2HAmDTjVuEF6V9DccV1JhrHg7DYc5SKm3bw2T75kAFPsGuSp - - --p2p.no-discovery - - --rpc.enable-admin - - --p2p.sequencer.key=${SEQUENCER_P2P_KEY} - - --l1=${L1_RPC_URL_IN_DOCKER} - - --l1.beacon=${L1_BEACON_URL_IN_DOCKER} - - --l1.rpckind=standard - - --rollup.l1-chain-config=/l1-genesis.json - - --safedb.path=/data/safedb - - --conductor.enabled=${CONDUCTOR_ENABLED:-false} - - --conductor.rpc=http://op-conductor3:8547 - depends_on: - op-geth-seq3: - condition: service_healthy - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9545"] - interval: 3s - timeout: 3s - retries: 10 - start_period: 3s - - op-conductor3: - image: "${OP_STACK_IMAGE_TAG}" - container_name: op-conductor3 - volumes: - - ./data/op-conductor3:/data - - ./config-op/rollup.json:/rollup.json - ports: - - "8549:8547" # RPC port - - "50052:50050" # Consensus port - command: - - /app/op-conductor/bin/op-conductor - - --log.level=debug - # already existed service - - --node.rpc=http://op-seq3:9545 - - --execution.rpc=http://op-geth-seq3:8545 - # Raft Config - - --raft.server.id=conductor-3 - - --raft.storage.dir=/data/raft - - --raft.bootstrap=false - - --consensus.addr=0.0.0.0 - - --consensus.port=50050 - - --consensus.advertised=op-conductor3:50050 - # RPC Config - - --rpc.addr=0.0.0.0 - - --rpc.port=8547 - - --rpc.enable-proxy=true - # Healthcheck Config - - --healthcheck.interval=1 - - --healthcheck.unsafe-interval=3 - - --healthcheck.min-peer-count=1 - - --rollup.config=/rollup.json - depends_on: - op-seq3: - condition: service_healthy - op-geth-seq3: - condition: service_healthy diff --git a/test-pp-op/dockerfile/Dockerfile-cdk-erigon b/test-pp-op/dockerfile/Dockerfile-cdk-erigon deleted file mode 100644 index 34996601bce97..0000000000000 --- a/test-pp-op/dockerfile/Dockerfile-cdk-erigon +++ /dev/null @@ -1,87 +0,0 @@ -# syntax = docker/dockerfile:1.2 -FROM docker.io/library/golang:1.24-alpine3.21 AS builder - -RUN apk --no-cache add build-base linux-headers git bash ca-certificates libstdc++ - -WORKDIR /app -ADD go.mod go.mod -ADD go.sum go.sum -ADD erigon-lib/go.mod erigon-lib/go.mod -ADD erigon-lib/go.sum erigon-lib/go.sum - -RUN go mod download -ADD . . - -RUN --mount=type=cache,target=/root/.cache \ - --mount=type=cache,target=/tmp/go-build \ - --mount=type=cache,target=/go/pkg/mod \ - make BUILD_TAGS=nosqlite,noboltdb,nosilkworm cdk-erigon - -RUN --mount=type=cache,target=/root/.cache \ - --mount=type=cache,target=/tmp/go-build \ - --mount=type=cache,target=/go/pkg/mod \ - make smt-db-split - -FROM docker.io/library/golang:1.24-alpine3.21 AS tools-builder -RUN apk --no-cache add build-base linux-headers git bash ca-certificates libstdc++ -WORKDIR /app - -ADD Makefile Makefile -ADD tools.go tools.go -ADD go.mod go.mod -ADD go.sum go.sum -ADD erigon-lib/go.mod erigon-lib/go.mod -ADD erigon-lib/go.sum erigon-lib/go.sum - -RUN mkdir -p /app/build/bin - -RUN --mount=type=cache,target=/root/.cache \ - --mount=type=cache,target=/tmp/go-build \ - --mount=type=cache,target=/go/pkg/mod \ - make db-tools - -FROM docker.io/library/alpine:3.17 - -# install required runtime libs, along with some helpers for debugging -RUN apk add --no-cache ca-certificates libstdc++ tzdata -RUN apk add --no-cache curl jq bind-tools -RUN apk add --no-cache perl perl-utils -RUN apk add --no-cache build-base git && \ - git clone https://github.com/hoytech/vmtouch.git && \ - cd vmtouch && \ - make && \ - install -m 755 vmtouch /usr/local/bin/ - -RUN mkdir -p ~/.local/share/erigon -WORKDIR /home/erigon - -## then give each binary its own layer -COPY --from=tools-builder /app/build/bin/mdbx_copy /usr/local/bin/mdbx_copy -COPY --from=builder /app/build/bin/cdk-erigon /usr/local/bin/cdk-erigon -COPY --from=builder /app/build/bin/smt-db-split /usr/local/bin/smt-db-split -COPY --from=builder /app/cmd/smt-db-split/prepare-db-split.sh /usr/local/bin/prepare-db-split.sh - -EXPOSE 8545 \ - 8551 \ - 8546 \ - 30303 \ - 30303/udp \ - 42069 \ - 42069/udp \ - 8080 \ - 9090 \ - 6060 - -# https://github.com/opencontainers/image-spec/blob/main/annotations.md -ARG BUILD_DATE -ARG VCS_REF -ARG VERSION -LABEL org.label-schema.build-date=$BUILD_DATE \ - org.label-schema.description="Erigon ZKEVM Client" \ - org.label-schema.name="ZKEVM Erigon" \ - org.label-schema.schema-version="1.0" \ - org.label-schema.url="https://torquem.ch" \ - org.label-schema.vcs-ref=$VCS_REF \ - org.label-schema.vcs-url="https://github.com/0xPolygonHermez/cdk-erigon.git" \ - org.label-schema.vendor="Torquem" \ - org.label-schema.version=$VERSION diff --git a/test-pp-op/dockerfile/Dockerfile.migrate b/test-pp-op/dockerfile/Dockerfile.migrate deleted file mode 100644 index 0a22581ecfef8..0000000000000 --- a/test-pp-op/dockerfile/Dockerfile.migrate +++ /dev/null @@ -1,27 +0,0 @@ -# Support setting various labels on the final image -ARG COMMIT="" -ARG VERSION="" -ARG BUILDNUM="" - -# Build Geth in a stock Go builder container -FROM golang:1.24-alpine AS builder - -RUN go env -w CGO_ENABLED=1 -RUN apk add --no-cache make gcc musl-dev linux-headers git - -WORKDIR /app - -COPY tmp/op-geth op-geth -RUN cd op-geth && make geth - -COPY . test-pp-op -RUN rm -rf test-pp-op/tmp - -FROM alpine:latest - -RUN apk add --no-cache jq bash ca-certificates libgcc libstdc++ - -COPY --from=builder /app/op-geth/build/bin/geth /usr/local/bin/geth -COPY --from=builder /app/test-pp-op /app/test-pp-op - -WORKDIR /app diff --git a/test-pp-op/dockerfile/Dockerfile.repro b/test-pp-op/dockerfile/Dockerfile.repro deleted file mode 100644 index a092b7609d85e..0000000000000 --- a/test-pp-op/dockerfile/Dockerfile.repro +++ /dev/null @@ -1,60 +0,0 @@ -ARG GO_VERSION=1.23.8-alpine3.21 -ARG EXPORT_TARGET=current -# we need a separate stage for src so we can build a service provides prestates for unnanounced chains -FROM golang:${GO_VERSION} AS builder -#FROM src AS builder -ARG EXPORT_TARGET -# We avoid copying the full .git dir into the build for just some metadata. -# Instead, specify: -# --build-arg GIT_COMMIT=$(git rev-parse HEAD) -# --build-arg GIT_DATE=$(git show -s --format='%ct') -ARG GIT_COMMIT -ARG GIT_DATE - -ARG CANNON_VERSION=v0.0.0 -ARG OP_PROGRAM_VERSION=v0.0.0 - -ARG TARGETOS TARGETARCH - -WORKDIR /app -RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build just \ - -d /app/op-program \ - -f /app/op-program/repro.justfile \ - GOOS="$TARGETOS" \ - GOARCH="$TARGETARCH" \ - GIT_COMMIT="$GIT_COMMIT" \ - GIT_DATE="$GIT_DATE" \ - CANNON_VERSION="$CANNON_VERSION" \ - OP_PROGRAM_VERSION="$OP_PROGRAM_VERSION" \ - "build-${EXPORT_TARGET}" - - -FROM scratch AS export-current -# Cannon64 files -COPY --from=builder /app/op-program/bin/op-program-client64.elf . -COPY --from=builder /app/op-program/bin/meta-mt64.json . -COPY --from=builder /app/op-program/bin/prestate-mt64.bin.gz . -COPY --from=builder /app/op-program/bin/prestate-proof-mt64.json . -# Interop files -COPY --from=builder ./app/op-program/bin/op-program-client-interop.elf . -COPY --from=builder /app/op-program/bin/meta-interop.json . -COPY --from=builder /app/op-program/bin/prestate-interop.bin.gz . -COPY --from=builder /app/op-program/bin/prestate-proof-interop.json . - -FROM scratch AS export-next -# Cannon64 Next VM files -COPY --from=builder /app/op-program/bin/op-program-client64.elf ./op-program-client-next64.elf -COPY --from=builder /app/op-program/bin/meta-mt64Next.json . -COPY --from=builder /app/op-program/bin/prestate-mt64Next.bin.gz . -COPY --from=builder /app/op-program/bin/prestate-proof-mt64Next.json . -# Interop Next files -COPY --from=builder ./app/op-program/bin/op-program-client-interop.elf ./op-program-client-interopNext.elf -COPY --from=builder /app/op-program/bin/meta-interopNext.json . -COPY --from=builder /app/op-program/bin/prestate-interopNext.bin.gz . -COPY --from=builder /app/op-program/bin/prestate-proof-interopNext.json . - -# Exports files to the specified output location. -# Writing files to host requires buildkit to be enabled. -# e.g. `BUILDKIT=1 docker build ...` -# Final export stage — dynamically selected -FROM export-${EXPORT_TARGET} AS export-stage diff --git a/test-pp-op/dockerfile/Dockerfile.repro-builder b/test-pp-op/dockerfile/Dockerfile.repro-builder deleted file mode 100644 index 22d89a1417034..0000000000000 --- a/test-pp-op/dockerfile/Dockerfile.repro-builder +++ /dev/null @@ -1,19 +0,0 @@ -# For caching deps to build reproducible prestate images on ECS. -ARG GO_VERSION=1.23.8-alpine3.21 -ARG EXPORT_TARGET=current -FROM golang:${GO_VERSION} AS src - -RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash just - -COPY ./go.mod /app/go.mod -COPY ./go.sum /app/go.sum -COPY ./op-geth /app/op-geth - -WORKDIR /app - -RUN echo "go mod cache: $(go env GOMODCACHE)" -RUN echo "go build cache: $(go env GOCACHE)" - -RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build go mod download - -COPY . /app diff --git a/test-pp-op/init-erigon.sh b/test-pp-op/init-erigon.sh deleted file mode 100755 index ff4169d63b696..0000000000000 --- a/test-pp-op/init-erigon.sh +++ /dev/null @@ -1,213 +0,0 @@ -#!/bin/bash -set -e -set -x - -# ============================================================================= -# Init Erigon Chain -# ============================================================================= -# The script is a comprehensive initialization script for setting up a local XLayer Erigon -# development environment. It handles contract deployment, configuration generation, and system setup for a ZK-EVM rollup test environment. -# - - - -source .env -source utils.sh - -git checkout config/* - -if [ ! -d "tmp/xlayer-erigon" ]; then - echo "ERROR: tmp/xlayer-erigon directory does not exist!" - echo "Please ensure the xlayer-erigon directory is present before running this script." - echo "the hack cmd is required" - exit 1 -fi - -mkdir -p $TMP_DIR -cd $TMP_DIR -if [ -d "./xlayer-contracts" ]; then - cd xlayer-contracts - current_branch=$(git branch --show-current) - if [ "$current_branch" != "zjg/v11.0.0-rc.0-op-v1" ]; then - echo "Switching to correct branch: zjg/v11.0.0-rc.0-op-v1" - git fetch origin - git checkout zjg/v11.0.0-rc.0-op-v1 - git pull origin zjg/v11.0.0-rc.0-op-v1 - else - echo "Updating existing repository..." - git pull origin zjg/v11.0.0-rc.0-op-v1 - fi - echo "Cleaning contract repository (selective)..." - rm -rf artifacts cache .openzeppelin node_modules - rm -f deployment/v2/deploy_output.json deployment/v2/create_rollup_output_*.json deployment/v2/genesis.json .env - cd .. -else - echo "Cloning contract repository..." - git clone -b zjg/v11.0.0-rc.0-op-v1 https://github.com/okx/xlayer-contracts.git -fi - -cd $TMP_DIR/xlayer-contracts - -echo "Creating .env file..." -cat > .env << EOF -MNEMONIC="$DEPLOYER_MNEMONIC" -INFURA_PROJECT_ID="000" -ETHERSCAN_API_KEY="000" -EOF - -cd deployment/v2 - -echo "Creating create_rollup_parameters.json..." -cat > create_rollup_parameters.json << EOF -{ - "adminZkEVM": "$DEPLOYER_ADDRESS", - "chainID": 195, - "consensusContract": "PolygonPessimisticConsensus", - "dataAvailabilityProtocol": "PolygonDataCommittee", - "deployerPvtKey": "", - "description": "description", - "forkID": 13, - "gasTokenAddress":"$OKB_TOKEN_ADDRESS", - "maxFeePerGas": "", - "maxPriorityFeePerGas": "", - "multiplierGas": "", - "networkName": "xlayer", - "realVerifier": false, - "trustedSequencer": "$SEQUENCER_ADDRESS", - "trustedSequencerURL": "$L2_PP_SEQ_URL_IN_DOCKER", - "trustedAggregator":"$AGGREGATOR_ADDRESS", - "programVKey": "$PP_VKEY" -} -EOF - -echo "Creating deploy_parameters.json..." -cat > deploy_parameters.json << EOF -{ - "admin": "$DEPLOYER_ADDRESS", - "deployerPvtKey": "", - "emergencyCouncilAddress": "$DEPLOYER_ADDRESS", - "initialZkEVMDeployerOwner": "$DEPLOYER_ADDRESS", - "maxFeePerGas": "", - "maxPriorityFeePerGas": "", - "minDelayTimelock": 60, - "multiplierGas": "", - "description": "description", - "pendingStateTimeout": 604799, - "polTokenAddress": "$OKB_TOKEN_ADDRESS", - "salt": "0x0000000000000000000000000000000000000000000000000000000000000001", - "timelockAdminAddress": "$DEPLOYER_ADDRESS", - "trustedSequencer": "$SEQUENCER_ADDRESS", - "trustedSequencerURL": "$L2_PP_SEQ_URL_IN_DOCKER", - "trustedAggregator": "$AGGREGATOR_ADDRESS", - "trustedAggregatorTimeout": 604799, - "forkID": 13, - "test": true, - "ppVKey": "$PP_VKEY", - "ppVKeySelector": "0x00000001", - "realVerifier": false, - "defaultAdminAddress": "$DEPLOYER_ADDRESS", - "aggchainDefaultVKeyRoleAddress": "$DEPLOYER_ADDRESS", - "addRouteRoleAddress": "$DEPLOYER_ADDRESS", - "freezeRouteRoleAddress": "$DEPLOYER_ADDRESS", - "zkEVMDeployerAddress": "$DEPLOYER_ADDRESS" -} -EOF - -echo "Compiling contracts..." -cd ../../ -npm i -npm run deploy:v2:localhost - -cd "$ROOT_DIR" -mkdir -p $TMP_DIR/pp-deployed -ROLLUP_OUTPUT_PATH=$(find $TMP_DIR/xlayer-contracts/deployment/v2 -name "create_rollup_output_*.json" | sort -r | head -n 1) -cp -rf $ROLLUP_OUTPUT_PATH $TMP_DIR/pp-deployed/create_rollup_output.json -cp -rf $TMP_DIR/xlayer-contracts/deployment/v2/create_rollup_parameters.json $TMP_DIR/pp-deployed/ -cp -rf $TMP_DIR/xlayer-contracts/deployment/v2/deploy_parameters.json $TMP_DIR/pp-deployed/ -cp -rf $TMP_DIR/xlayer-contracts/deployment/v2/deploy_output.json $TMP_DIR/pp-deployed/ -cp -rf $TMP_DIR/xlayer-contracts/deployment/v2/genesis.json $TMP_DIR/pp-deployed/ -ROLLUP_OUTPUT_PATH="$TMP_DIR/pp-deployed/create_rollup_output.json" -DEPLOY_OUTPUT_PATH="$TMP_DIR/pp-deployed/deploy_output.json" - -# echo "Transferring ERC20 token to Sequencer..." -# cast send --legacy --from $SEQUENCER_ADDRESS --private-key $SEQUENCER_PRIVATE_KEY $TOKEN_ADDRESS "transfer(address,uint256)" $SEQUENCER_ADDRESS 1000 - -echo "Setting Trusted Sequencer URL..." -POE_ADDRESS=$(cat $ROLLUP_OUTPUT_PATH | grep -o '"rollupAddress": "[^"]*"' | cut -d'"' -f4) -BRIDGE_ADDRESS=$(cat $DEPLOY_OUTPUT_PATH | grep -o '"polygonZkEVMBridgeAddress": "[^"]*"' | cut -d'"' -f4) -GENESIS_VALUE=$(cat $ROLLUP_OUTPUT_PATH | grep -o '"genesis": "[^"]*"' | cut -d'"' -f4) -TIMESTAMP_VALUE=$(cat $ROLLUP_OUTPUT_PATH | grep -o '"timestamp": [0-9]*' | cut -d' ' -f2) -L1_FIRST_BLOCK=$(cat $DEPLOY_OUTPUT_PATH | grep -o '"upgradeToULxLyBlockNumber": [0-9]*' | cut -d' ' -f2) -L1_SECOND_BLOCK=$(cat $ROLLUP_OUTPUT_PATH | grep -o '"createRollupBlockNumber": [0-9]*' | cut -d' ' -f2) -ROLLUP_MANAGER_ADDRESS=$(grep -o '"polygonRollupManagerAddress": "[^"]*"' "$DEPLOY_OUTPUT_PATH" | cut -d'"' -f4) -GLOBAL_EXIT_ROOT_ADDRESS=$(grep -o '"polygonZkEVMGlobalExitRootAddress": "[^"]*"' "$DEPLOY_OUTPUT_PATH" | cut -d'"' -f4) -echo "Poe address from JSON: $POE_ADDRESS" -echo "Bridge address from JSON: $BRIDGE_ADDRESS" -echo "Genesis value from JSON: $GENESIS_VALUE" -echo "Timestamp value from JSON: $TIMESTAMP_VALUE" -echo "L1FirstBlock value from JSON: $L1_FIRST_BLOCK" -echo "L1SecondBlock value from JSON: $L1_SECOND_BLOCK" -echo "RollupManagerAddress value from JSON: $ROLLUP_MANAGER_ADDRESS" -echo "GlobalExitRootAddress value from JSON: $GLOBAL_EXIT_ROOT_ADDRESS" - -echo "Using POE address from JSON: $POE_ADDRESS" -cast send --legacy --from $DEPLOYER_ADDRESS --private-key $DEPLOYER_PRIVATE_KEY $POE_ADDRESS "setTrustedSequencerURL(string)" "$L2_PP_RPC_URL_IN_DOCKER" - -cast send --legacy --from $DEPLOYER_ADDRESS --private-key $DEPLOYER_PRIVATE_KEY $BRIDGE_ADDRESS 'function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) returns()' 7 0x0000000000000000000000000000000000000000 0 0x0000000000000000000000000000000000000000 true 0x - -echo "Generating configuration files..." - -cd "${PWD_DIR}/tmp/xlayer-erigon" -go install ./cmd/hack/allocs -cd ${PWD_DIR} -GO_PATH=$(go env GOPATH) -#TODO: make this adapt to multi environment, mac, linux -${GO_PATH}/bin/allocs $TMP_DIR/xlayer-contracts/deployment/v2/genesis.json -mv allocs.json $PWD_DIR/config/dynamic-mynetwork-allocs.json - -cat > $PWD_DIR/config/dynamic-mynetwork-conf.json << EOF -{ - "root": "$GENESIS_VALUE", - "timestamp": $TIMESTAMP_VALUE, - "gasLimit": 0, - "difficulty": 0 -} -EOF -echo "dynamic-mynetwork-conf.json file updated" - -echo "Updating test.erigon.seq.config.yaml file..." -ERIGON_SEQ_CONFIG_FILE="${PWD_DIR}/config/test.erigon.seq.config.yaml" -sed_inplace "s|zkevm.address-zkevm: \"[^\"]*\"|zkevm.address-zkevm: \"$POE_ADDRESS\"|g" "$ERIGON_SEQ_CONFIG_FILE" -sed_inplace "s|zkevm.address-rollup: \"[^\"]*\"|zkevm.address-rollup: \"$ROLLUP_MANAGER_ADDRESS\"|g" "$ERIGON_SEQ_CONFIG_FILE" -sed_inplace "s|zkevm.address-ger-manager: \"[^\"]*\"|zkevm.address-ger-manager: \"$GLOBAL_EXIT_ROOT_ADDRESS\"|g" "$ERIGON_SEQ_CONFIG_FILE" -sed_inplace "s|zkevm.l1-first-block: [0-9]*|zkevm.l1-first-block: $L1_FIRST_BLOCK|g" "$ERIGON_SEQ_CONFIG_FILE" - -mkdir -p "$PWD_DIR/config" -jq '.firstBatchData' "$ROLLUP_OUTPUT_PATH" > "$PWD_DIR/config/first-batch-config.json" -echo "Successfully exported firstBatchData to $PWD_DIR/config/first-batch-config.json" - -echo "Updating parameter in aggkit.toml..." -CONFIG_FILE="${PWD_DIR}/config/aggkit.toml" -sed_inplace "s|polygonBridgeAddr = \"[^\"]*\"|polygonBridgeAddr = \"$BRIDGE_ADDRESS\"|" "$CONFIG_FILE" -sed_inplace "s|BridgeAddr = \"[^\"]*\"|BridgeAddr = \"$BRIDGE_ADDRESS\"|" "$CONFIG_FILE" -sed_inplace "s|BridgeAddrL2 = \"[^\"]*\"|BridgeAddrL2 = \"$BRIDGE_ADDRESS\"|" "$CONFIG_FILE" -sed_inplace "s|rollupCreationBlockNumber = \"[^\"]*\"|rollupCreationBlockNumber = \"$L1_FIRST_BLOCK\"|" "$CONFIG_FILE" -sed_inplace "s|rollupManagerCreationBlockNumber = \"[^\"]*\"|rollupManagerCreationBlockNumber = \"$L1_SECOND_BLOCK\"|" "$CONFIG_FILE" -sed_inplace "s|genesisBlockNumber = \"[^\"]*\"|genesisBlockNumber = \"$L1_FIRST_BLOCK\"|" "$CONFIG_FILE" -sed_inplace "s|polygonRollupManagerAddress = \"[^\"]*\"|polygonRollupManagerAddress = \"$ROLLUP_MANAGER_ADDRESS\"|" "$CONFIG_FILE" -sed_inplace "s|polygonZkEVMGlobalExitRootAddress = \"[^\"]*\"|polygonZkEVMGlobalExitRootAddress = \"$GLOBAL_EXIT_ROOT_ADDRESS\"|" "$CONFIG_FILE" -sed_inplace "s|polygonZkEVMAddress = \"[^\"]*\"|polygonZkEVMAddress = \"$POE_ADDRESS\"|" "$CONFIG_FILE" -echo "Successfully updated contract address parameters in aggkit.toml" - -echo "Updating contract address parameters in agglayer-config.toml..." -AGGLAYER_CONFIG_FILE="${PWD_DIR}/config/agglayer-config.toml" -sed_inplace "s|rollup-manager-contract = \"[^\"]*\"|rollup-manager-contract = \"$ROLLUP_MANAGER_ADDRESS\"|" "$AGGLAYER_CONFIG_FILE" -sed_inplace "s|polygon-zkevm-global-exit-root-v2-contract = \"[^\"]*\"|polygon-zkevm-global-exit-root-v2-contract = \"$GLOBAL_EXIT_ROOT_ADDRESS\"|" "$AGGLAYER_CONFIG_FILE" -GENESIS_CONFIG_FILE="${PWD_DIR}/config/test.genesis.config.json" -sed_inplace "s|\"genesisBlockNumber\": [0-9]*|\"genesisBlockNumber\": $L1_FIRST_BLOCK|" "$GENESIS_CONFIG_FILE" -sed_inplace "s|\"rollupCreationBlockNumber\": [0-9]*|\"rollupCreationBlockNumber\": $L1_SECOND_BLOCK|" "$GENESIS_CONFIG_FILE" -sed_inplace "s|\"rollupManagerCreationBlockNumber\": [0-9]*|\"rollupManagerCreationBlockNumber\": $L1_FIRST_BLOCK|" "$GENESIS_CONFIG_FILE" -AGGLAYER_CONFIG_FILE="${PWD_DIR}/config/agglayer-config.toml" -sed_inplace "s|polygon-zkevm-global-exit-root-v2-contract = \"[^\"]*\"|polygon-zkevm-global-exit-root-v2-contract = \"$GLOBAL_EXIT_ROOT_ADDRESS\"|" "$AGGLAYER_CONFIG_FILE" - -echo "Initialization script completed!" diff --git a/test-pp-op/l1-geth/consensus/config.yml b/test-pp-op/l1-geth/consensus/config.yml deleted file mode 100644 index cf6c353b902cd..0000000000000 --- a/test-pp-op/l1-geth/consensus/config.yml +++ /dev/null @@ -1,34 +0,0 @@ -CONFIG_NAME: interop -PRESET_BASE: interop - -# Genesis -GENESIS_FORK_VERSION: 0x20000089 - -# Altair -ALTAIR_FORK_EPOCH: 0 -ALTAIR_FORK_VERSION: 0x20000090 - -# Merge -BELLATRIX_FORK_EPOCH: 0 -BELLATRIX_FORK_VERSION: 0x20000091 -TERMINAL_TOTAL_DIFFICULTY: 0 - -# Capella -CAPELLA_FORK_EPOCH: 0 -CAPELLA_FORK_VERSION: 0x20000092 -MAX_WITHDRAWALS_PER_PAYLOAD: 16 - -# Deneb -DENEB_FORK_EPOCH: 0 -DENEB_FORK_VERSION: 0x20000093 - -# Electra -# ELECTRA_FORK_EPOCH: 0 -ELECTRA_FORK_VERSION: 0x15000000 - -# Time parameters -SECONDS_PER_SLOT: 2 -SLOTS_PER_EPOCH: 6 - -# Deposit contract -DEPOSIT_CONTRACT_ADDRESS: 0x4242424242424242424242424242424242424242 diff --git a/test-pp-op/l1-geth/execution/genesis-raw.json b/test-pp-op/l1-geth/execution/genesis-raw.json deleted file mode 100644 index 4f0447ea58cab..0000000000000 --- a/test-pp-op/l1-geth/execution/genesis-raw.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "config": { - "chainId": 1337, - "homesteadBlock": 0, - "daoForkSupport": true, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "arrowGlacierBlock": 0, - "grayGlacierBlock": 0, - "shanghaiTime": 0, - "cancunTime": 0, - "terminalTotalDifficulty": 0, - "terminalTotalDifficultyPassed": true, - "blobSchedule": { - "cancun": { - "target": 3, - "max": 6, - "baseFeeUpdateFraction": 3338477 - } - } - }, - "nonce": "0x0", - "timestamp": "0x68621d8d", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000123463a4b065722e99115d6c222f267d9cabb5240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x1c9c380", - "difficulty": "0x1", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "alloc": { - "123463a4b065722e99115d6c222f267d9cabb524": { - "balance": "0x43c33c1937564800000" - }, - "14dc79964da2c08b23698b3d3cc7ca32193d9955": { - "balance": "0x21e19e0c9bab2400000" - }, - "15d34aaf54267db7d7c367839aaf71a00a2c6a65": { - "balance": "0x21e19e0c9bab2400000" - }, - "1cbd3b2770909d4e10f157cabc84c7264073c9ec": { - "balance": "0x21e19e0c9bab2400000" - }, - "23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f": { - "balance": "0x21e19e0c9bab2400000" - }, - "2546bcd3c84621e976d8185a91a922ae77ecec30": { - "balance": "0x21e19e0c9bab2400000" - }, - "3c44cdddb6a900fa2b585dd299e03d12fa4293bc": { - "balance": "0x21e19e0c9bab2400000" - }, - "4242424242424242424242424242424242424242": { - "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100b6578063621fd130146101e3578063c5f2892f14610273575b600080fd5b34801561005057600080fd5b5061009c6004803603602081101561006757600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916906020019092919050505061029e565b604051808215151515815260200191505060405180910390f35b6101e1600480360360808110156100cc57600080fd5b81019080803590602001906401000000008111156100e957600080fd5b8201836020820111156100fb57600080fd5b8035906020019184600183028401116401000000008311171561011d57600080fd5b90919293919293908035906020019064010000000081111561013e57600080fd5b82018360208201111561015057600080fd5b8035906020019184600183028401116401000000008311171561017257600080fd5b90919293919293908035906020019064010000000081111561019357600080fd5b8201836020820111156101a557600080fd5b803590602001918460018302840111640100000000831117156101c757600080fd5b909192939192939080359060200190929190505050610370565b005b3480156101ef57600080fd5b506101f8610fd0565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561023857808201518184015260208101905061021d565b50505050905090810190601f1680156102655780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027f57600080fd5b50610288610fe2565b6040518082815260200191505060405180910390f35b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061036957507f85640907000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b603087879050146103cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806116ec6026913960400191505060405180910390fd5b60208585905014610428576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806116836036913960400191505060405180910390fd5b60608383905014610484576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018061175f6029913960400191505060405180910390fd5b670de0b6b3a76400003410156104e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806117396026913960400191505060405180910390fd5b6000633b9aca0034816104f457fe5b061461054b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806116b96033913960400191505060405180910390fd5b6000633b9aca00348161055a57fe5b04905067ffffffffffffffff80168111156105c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806117126027913960400191505060405180910390fd5b60606105cb82611314565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a610600602054611314565b60405180806020018060200180602001806020018060200186810386528e8e82818152602001925080828437600081840152601f19601f82011690508083019250505086810385528c8c82818152602001925080828437600081840152601f19601f82011690508083019250505086810384528a818151815260200191508051906020019080838360005b838110156106a657808201518184015260208101905061068b565b50505050905090810190601f1680156106d35780820380516001836020036101000a031916815260200191505b508681038352898982818152602001925080828437600081840152601f19601f820116905080830192505050868103825287818151815260200191508051906020019080838360005b8381101561073757808201518184015260208101905061071c565b50505050905090810190601f1680156107645780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b6040516020018084848082843780830192505050826fffffffffffffffffffffffffffffffff19166fffffffffffffffffffffffffffffffff1916815260100193505050506040516020818303038152906040526040518082805190602001908083835b6020831061080e57805182526020820191506020810190506020830392506107eb565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610850573d6000803e3d6000fd5b5050506040513d602081101561086557600080fd5b8101908080519060200190929190505050905060006002808888600090604092610891939291906115da565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108eb57805182526020820191506020810190506020830392506108c8565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa15801561092d573d6000803e3d6000fd5b5050506040513d602081101561094257600080fd5b8101908080519060200190929190505050600289896040908092610968939291906115da565b6000801b604051602001808484808284378083019250505082815260200193505050506040516020818303038152906040526040518082805190602001908083835b602083106109cd57805182526020820191506020810190506020830392506109aa565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610a0f573d6000803e3d6000fd5b5050506040513d6020811015610a2457600080fd5b810190808051906020019092919050505060405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b60208310610a8e5780518252602082019150602081019050602083039250610a6b565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610ad0573d6000803e3d6000fd5b5050506040513d6020811015610ae557600080fd5b810190808051906020019092919050505090506000600280848c8c604051602001808481526020018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610b615780518252602082019150602081019050602083039250610b3e565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610ba3573d6000803e3d6000fd5b5050506040513d6020811015610bb857600080fd5b8101908080519060200190929190505050600286600060401b866040516020018084805190602001908083835b60208310610c085780518252602082019150602081019050602083039250610be5565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610c935780518252602082019150602081019050602083039250610c70565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610cd5573d6000803e3d6000fd5b5050506040513d6020811015610cea57600080fd5b810190808051906020019092919050505060405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b60208310610d545780518252602082019150602081019050602083039250610d31565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610d96573d6000803e3d6000fd5b5050506040513d6020811015610dab57600080fd5b81019080805190602001909291905050509050858114610e16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252605481526020018061162f6054913960600191505060405180910390fd5b6001602060020a0360205410610e77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061160e6021913960400191505060405180910390fd5b60016020600082825401925050819055506000602054905060008090505b6020811015610fb75760018083161415610ec8578260008260208110610eb757fe5b018190555050505050505050610fc7565b600260008260208110610ed757fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b60208310610f335780518252602082019150602081019050602083039250610f10565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa158015610f75573d6000803e3d6000fd5b5050506040513d6020811015610f8a57600080fd5b8101908080519060200190929190505050925060028281610fa757fe5b0491508080600101915050610e95565b506000610fc057fe5b5050505050505b50505050505050565b6060610fdd602054611314565b905090565b6000806000602054905060008090505b60208110156111d057600180831614156110e05760026000826020811061101557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b60208310611071578051825260208201915060208101905060208303925061104e565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa1580156110b3573d6000803e3d6000fd5b5050506040513d60208110156110c857600080fd5b810190808051906020019092919050505092506111b6565b600283602183602081106110f057fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061114b5780518252602082019150602081019050602083039250611128565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa15801561118d573d6000803e3d6000fd5b5050506040513d60208110156111a257600080fd5b810190808051906020019092919050505092505b600282816111c057fe5b0491508080600101915050610ff2565b506002826111df602054611314565b600060401b6040516020018084815260200183805190602001908083835b6020831061122057805182526020820191506020810190506020830392506111fd565b6001836020036101000a0380198251168184511680821785525050505050509050018267ffffffffffffffff191667ffffffffffffffff1916815260180193505050506040516020818303038152906040526040518082805190602001908083835b602083106112a55780518252602082019150602081019050602083039250611282565b6001836020036101000a038019825116818451168082178552505050505050905001915050602060405180830381855afa1580156112e7573d6000803e3d6000fd5b5050506040513d60208110156112fc57600080fd5b81019080805190602001909291905050509250505090565b6060600867ffffffffffffffff8111801561132e57600080fd5b506040519080825280601f01601f1916602001820160405280156113615781602001600182028036833780820191505090505b50905060008260c01b90508060076008811061137957fe5b1a60f81b8260008151811061138a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806006600881106113c657fe5b1a60f81b826001815181106113d757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060056008811061141357fe5b1a60f81b8260028151811061142457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060046008811061146057fe5b1a60f81b8260038151811061147157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806003600881106114ad57fe5b1a60f81b826004815181106114be57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806002600881106114fa57fe5b1a60f81b8260058151811061150b57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060016008811061154757fe5b1a60f81b8260068151811061155857fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060006008811061159457fe5b1a60f81b826007815181106115a557fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b600080858511156115ea57600080fd5b838611156115f757600080fd5b600185028301915084860390509450949250505056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220230afd4b6e3551329e50f1239e08fa3ab7907b77403c4f237d9adf679e8e43cf64736f6c634300060b0033", - "balance": "0x0" - }, - "4e59b44847b379578588920ca78fbf26c0b4956c": { - "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3", - "balance": "0x0" - }, - "5678e9e827b3be0e3d4b910126a64a697a148267": { - "balance": "0x43c33c1937564800000" - }, - "70997970c51812dc3a010c7d01b50e0d17dc79c8": { - "balance": "0x21e19e0c9bab2400000" - }, - "71be63f3384f5fb98995898a86b02fb2426c5788": { - "balance": "0x21e19e0c9bab2400000" - }, - "8626f6940e2eb28930efb4cef49b2d1f2c9c1199": { - "balance": "0x21e19e0c9bab2400000" - }, - "90f79bf6eb2c4f870365e785982e1f101e93b906": { - "balance": "0x21e19e0c9bab2400000" - }, - "976ea74026e726554db657fa54763abd0c3a0aa9": { - "balance": "0x21e19e0c9bab2400000" - }, - "9965507d1a55bcc2695c58ba16fb37d819b0a4dc": { - "balance": "0x21e19e0c9bab2400000" - }, - "a0ee7a142d267c1f36714e4a8f75612f20a79720": { - "balance": "0x21e19e0c9bab2400000" - }, - "bcd4042de499d14e55001ccbb24a551f3b954096": { - "balance": "0x21e19e0c9bab2400000" - }, - "bda5747bfd65f08deb54cb465eb87d40e51b197e": { - "balance": "0x21e19e0c9bab2400000" - }, - "cd3b766ccdd6ae721141f452c550ca635964ce71": { - "balance": "0x21e19e0c9bab2400000" - }, - "dd2fd4581271e230360230f9337d5c0430bf44c0": { - "balance": "0x21e19e0c9bab2400000" - }, - "df3e18d64bc6a983f673ab319ccae4f1a57c7097": { - "balance": "0x21e19e0c9bab2400000" - }, - "f39fd6e51aad88f6f4ce6ab8827279cfffb92266": { - "balance": "0x21e19e0c9bab2400000" - }, - "fabb0ac9d68b0b445fb7357272ff202c5651694a": { - "balance": "0x21e19e0c9bab2400000" - } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "baseFeePerGas": null, - "excessBlobGas": null, - "blobGasUsed": null -} diff --git a/test-pp-op/l1-geth/execution/geth_password.txt b/test-pp-op/l1-geth/execution/geth_password.txt deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/test-pp-op/l1-geth/execution/jwtsecret b/test-pp-op/l1-geth/execution/jwtsecret deleted file mode 100755 index c4454fe4fa342..0000000000000 --- a/test-pp-op/l1-geth/execution/jwtsecret +++ /dev/null @@ -1 +0,0 @@ -0xfad2709d0bb03bf0e8ba3c99bea194575d3e98863133d1af638ed056d1d59345 \ No newline at end of file diff --git a/test-pp-op/l1-geth/execution/keystore/UTC--2022-08-19T17-38-31.257380510Z--123463a4b065722e99115d6c222f267d9cabb524 b/test-pp-op/l1-geth/execution/keystore/UTC--2022-08-19T17-38-31.257380510Z--123463a4b065722e99115d6c222f267d9cabb524 deleted file mode 100644 index 4794e82c2ba30..0000000000000 --- a/test-pp-op/l1-geth/execution/keystore/UTC--2022-08-19T17-38-31.257380510Z--123463a4b065722e99115d6c222f267d9cabb524 +++ /dev/null @@ -1 +0,0 @@ -{"address":"123463a4b065722e99115d6c222f267d9cabb524","crypto":{"cipher":"aes-128-ctr","ciphertext":"93b90389b855889b9f91c89fd15b9bd2ae95b06fe8e2314009fc88859fc6fde9","cipherparams":{"iv":"9dc2eff7967505f0e6a40264d1511742"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"c07503bb1b66083c37527cd8f06f8c7c1443d4c724767f625743bd47ae6179a4"},"mac":"6d359be5d6c432d5bbb859484009a4bf1bd71b76e89420c380bd0593ce25a817"},"id":"622df904-0bb1-4236-b254-f1b8dfdff1ec","version":3} \ No newline at end of file diff --git a/test-pp-op/l1-geth/execution/sk.json b/test-pp-op/l1-geth/execution/sk.json deleted file mode 100644 index 8fe79fab50958..0000000000000 --- a/test-pp-op/l1-geth/execution/sk.json +++ /dev/null @@ -1 +0,0 @@ -2e0834786285daccd064ca17f1654f67b4aef298acbb82cef9ec422fb4975622 diff --git a/test-pp-op/local.env b/test-pp-op/local.env deleted file mode 100644 index 83398254490e7..0000000000000 --- a/test-pp-op/local.env +++ /dev/null @@ -1,132 +0,0 @@ -ENV=local - -CONDUCTOR_ENABLED=true -OWNER_TYPE=transactor # transactor or safe -CGT_ENABLED=true - -CHAIN_ID=195 - -DOCKER_NETWORK=pp-op -CONFIG_DIR=config-op - -# Images -OP_GETH_MIGRATION_IMAGE_TAG=op-geth-migrate:latest -OP_GETH_IMAGE_TAG=op-geth:latest -OP_STACK_IMAGE_TAG=op-stack:latest -OP_CONTRACTS_IMAGE_TAG=op-contract:latest -XLAYER_BRIDGE_SERVICE_IMAGE_TAG=hermeznetwork/zkevm-bridge-service:v0.6.0-RC16-patch -CDK_ERIGON_IMAGE_TAG=cdk-erigon:latest - -OP_GETH_DATADIR=./data/op-geth-seq -OP_GETH_DATADIR2=./data/op-geth-seq2 -OP_GETH_DATADIR3=./data/op-geth-seq3 -OP_GETH_RPC_DATADIR=./data/op-geth-rpc - -# RPC endpoints -L1_RPC_URL=http://127.0.0.1:8545 -L2_RPC_URL=http://127.0.0.1:8124 -L2_ERIGON_RPC_URL=http://127.0.0.1:18124 -L2_OP_SEQ_WS_URL=ws://localhost:7546 -L1_RPC_URL_IN_DOCKER=http://l1-geth:8545 -L2_PP_SEQ_URL_IN_DOCKER=http://xlayer-seq:8545 -L2_PP_RPC_URL_IN_DOCKER=http://xlayer-rpc:8545 -L2_OP_RPC_URL_IN_DOCKER=http://op-geth-rpc:8545 -L1_BEACON_URL_IN_DOCKER=http://l1-beacon-chain:3500 -BRIDGE_SERVICE=http://127.0.0.1:8080 - -# Common addresses & keys - -OKB_TOKEN_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 - -RICH_ADDRESS=0x14dC79964da2C08b23698B3D3cc7Ca32193d9955 -RICH_PRIVATE_KEY=0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356 - -DEPLOYER_ADDRESS=0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534 -DEPLOYER_PRIVATE_KEY=0x815405dddb0e2a99b12af775fd2929e526704e1d1aea6a0b4e74dc33e2f7fcd2 -DEPLOYER_MNEMONIC="moment wine false celery win galaxy glide thumb tail setup choose city" - -SEQUENCER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -SEQUENCER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -SEQUENCER_P2P_KEY=0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba - -SYSTEM_CONFIG_OWNER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -OKB_ADAPTER_OWNER_ADDRESS=0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534 - -# PP addresses & keys -AGGREGATOR_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -AGGREGATOR_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d - -PP_VKEY=0x00d6e4bdab9cac75a50d58262bb4e60b3107a6b61131ccdff649576c624b6fb7 - -ORACLE_ADDRESS=0x70997970c51812dc3a010c7d01b50e0d17dc79c8 - -## Predeployed in PP -TIME_LOCK_ADDRESS=0x27284DBa79e6DF953Fbd232A9d8D87029F03BBf5 -GER_MANAGER_ADDRESS=0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa -BRIDGE_ADDRESS=0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851 - -L1_ETH_ADDRESS=0x0000000000000000000000000000000000000000 -L2_WETH=0xd80e5a44dc9628fae9b432eac67873238504ea29 - -# OP addresses & keys - -BATCHER_ADDRESS=0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC -OP_BATCHER_PRIVATE_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a - -## Same as aggregator -PROPOSER_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -OP_PROPOSER_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d - -OPTIMISM_PORTAL_PROXY_ADDRESS=0xc8e8b7b181db301f27aef90ed285787a3ce179e9 - -CHALLENGER_ADDRESS=0x7d18a1b858253b5588f61fb5739d52e4b84e2cda -OP_CHALLENGER_PRIVATE_KEY=0x8b3a350cf5c34c9194ca9aa3f146b2b9afed22cd83d3c5f6a3f2f243ce220c01 - -ADMIN_OWNER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -ADMIN_OWNER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 - -# Deployed and modified in 2-deploy-op-contracts.sh -TRANSACTOR=0x0000000000000000000000000000000000000000 -SAFE_ADDRESS=0x0000000000000000000000000000000000000000 -L2OO_ADDRESS=0x0000000000000000000000000000000000000000 -DISPUTE_GAME_FACTORY_ADDRESS=0x3281215007aad854b44b6dbdb0f429e81577497f -OPCM_IMPL_ADDRESS=0x3bc5388bd43977644f73fb75c7d8d6015be71e59 -SYSTEM_CONFIG_PROXY_ADDRESS=0xabd433c36f6b2809ce238044afeb2fc48f6e6ff0 -PROXY_ADMIN=0x88c87adaf76a638cd81286b23b5830a7d6ffb80d - -# Upgrade l2 ger contract -TIME_LOCK_DELAY=70 - -# Set initial bond -INITIAL_BOND=10000000000 - -# First game only for update anchor root -TEMP_MAX_CLOCK_DURATION=40 -TEMP_CLOCK_EXTENSION=5 -TEMP_GAME_WINDOW=60 - -# proof config -PROOF_MATURITY_DELAY_SECONDS=1800 - -# Game config -MAX_CLOCK_DURATION=1800 -CLOCK_EXTENSION=600 -GAME_WINDOW=10800 - -# AnchorStateRegistry config -DISPUTE_GAME_FINALITY_DELAY_SECONDS=5 - -# PreimageOracle config -CHALLENGE_PERIOD_SECONDS=30 - -# WETH config -WITHDRAWAL_DELAY_SECONDS=$MAX_CLOCK_DURATION - -# pebble by default -# if panic, try leveldb -DB_ENGINE="pebble" - -# Modified in in 5-2-migrate-op.sh -FORK_BLOCK=0 -PARENT_HASH=0x0000000000000000000000000000000000000000000000000000000000000000 -PP_RPC_URL=http://xlayer-rpc:8124 diff --git a/test-pp-op/m1-deploy-and-upload.sh b/test-pp-op/m1-deploy-and-upload.sh deleted file mode 100755 index 7582c56c5b822..0000000000000 --- a/test-pp-op/m1-deploy-and-upload.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash -set -e - -if [ ! -f .env ];then - echo "Please create .env file." - exit 1 -fi - -source .env -source tools.sh -source utils.sh - -UPLOAD_DIR="upload-to-oss" -IMAGE_NAME=$(echo "${OP_GETH_MIGRATION_IMAGE_TAG}" | cut -d':' -f1) -TAR_FILE="${UPLOAD_DIR}.tar.gz" -ARCH="linux/amd64" -SKIP_BUILD_GETH=false; [[ "$*" =~ --skip-geth ]] && SKIP_BUILD_GETH=true -SKIP_DEPLOY=false; [[ "$*" =~ --skip-deploy ]] && SKIP_DEPLOY=true - -echo "" -echo "==============================================" -echo "Step 1: Deploy OP Contracts" -echo "==============================================" -if [ "$SKIP_DEPLOY" = true ]; then - echo "⏭️ Skipping 2-deploy-op-contracts.sh (--skip-deploy flag detected)" -else - ./2-deploy-op-contracts.sh -fi - -echo "" -echo "==============================================" -echo "Step 2: Build op-migrate image" -echo "==============================================" - -# Remove previous uploads to keep size of docker image small. -echo "🗑️ Removing existing container ${UPLOAD_DIR}..." -rm -rf $UPLOAD_DIR ${UPLOAD_DIR}.tar.gz - -if [ "$SKIP_BUILD_GETH" = true ]; then - echo "⏭️ Skipping build_images.sh (--skip-geth flag detected)" -else - ./build_images.sh --op-geth-migrate --arch ${ARCH} --force -fi - -echo "" -echo "==============================================" -echo "Step 3: Save Docker image to tar.gz" -echo "==============================================" -docker save ${OP_GETH_MIGRATION_IMAGE_TAG} | gzip > ${IMAGE_NAME}.tar.gz -[ -n "$(docker images -q ${IMAGE_NAME})" ] || exit 1 -echo "✅ Image saved to ${IMAGE_NAME}.tar.gz" - -echo "" -echo "==============================================" -echo "Step 4: Create folder to store upload files" -echo "==============================================" -mkdir -p $UPLOAD_DIR -mv ${IMAGE_NAME}.tar.gz $UPLOAD_DIR -cp ./m2-migrate.sh $UPLOAD_DIR -cp ./m3-verify.sh $UPLOAD_DIR -tar -czvf $UPLOAD_DIR.tar.gz $UPLOAD_DIR -echo "✅ Upload file ${TAR_FILE} is created." - -echo "" -echo "==============================================" -echo "Step 5: Calculate MD5 hash" -echo "==============================================" -if [[ "$OSTYPE" == "darwin"* ]]; then - MD5_HASH=$(md5 -q ${TAR_FILE}) - echo "MD5 Hash: ${MD5_HASH}" -else - md5sum ${TAR_FILE} - MD5_HASH=$(md5sum ${TAR_FILE} | awk '{print $1}') -fi - -echo "" -echo "==============================================" -echo "Step 6: Upload to OSS" -echo "==============================================" -echo "Please create an OSS ticket using ${TAR_FILE} and its MD5 hash: ${MD5_HASH}." diff --git a/test-pp-op/m2-migrate.sh b/test-pp-op/m2-migrate.sh deleted file mode 100755 index cea40a2c8be89..0000000000000 --- a/test-pp-op/m2-migrate.sh +++ /dev/null @@ -1,630 +0,0 @@ -#!/bin/bash -set -e - -# Debug mode - set to true to enable verbose output -DEBUG=${DEBUG:-false} -if [ "$DEBUG" = "true" ]; then - set -x -fi - -FORK_BLOCK=$1 - -IMAGE_NAME="op-geth-migrate:latest" -CONTAINER_NAME="op-migrate-container" -RAMDISK_PATH="/mnt/ramdisk_op" -DATA_DIR="/data" -ERIGON_DATA_DIR="/data/erigon-data" -BACKUP_DIR="${DATA_DIR}/migration-backup-$(date +%Y%m%d)" -L2_RPC_URL="${L2_RPC_URL:-http://10.2.29.232:18545}" -ENV=${ENV:-mainnet} -# Set expected chain ID based on ENV variable -EXPECTED_CHAIN=$([ "$ENV" = "testnet" ] && echo "1952" || echo "196") -EXPECTED_L1_CHAIN_ID=$([ "$ENV" = "testnet" ] && echo "11155111" || ([ "$ENV" = "fakemainnet" ] && echo "11155111" || echo "1")) -CHECK_BLOCK=${CHECK_BLOCK:-true} - -# Check required tools -for cmd in docker jq curl sed grep; do - if ! command -v $cmd >/dev/null 2>&1; then - echo "❌ Error: Required tool '$cmd' is not installed" - exit 1 - fi -done - -# Prompt to delete ${BACKUP_DIR} contents -if [ -d $BACKUP_DIR ];then - echo "" - echo "=============================================" - echo "Existing ${BACKUP_DIR}" - echo "=============================================" - ls -la $BACKUP_DIR - echo "" - read -p "Do you want to delete the contents of ${BACKUP_DIR}? (y/n): " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "${BACKUP_DIR} contents are DELETED..." - rm -rf ${BACKUP_DIR}/* - else - echo "${BACKUP_DIR} contents are NOT deleted..." - fi -fi - -# Create and verify backup directory -mkdir -p ${BACKUP_DIR} -if ! touch ${BACKUP_DIR}/.write_test 2>/dev/null; then - echo "❌ Error: Cannot write to backup directory: ${BACKUP_DIR}" - exit 1 -fi -rm -f ${BACKUP_DIR}/.write_test - -# Function to fetch block data from RPC (executed on host) -fetch_block_data() { - local fork_block=$1 - - echo "Fetching block #$fork_block from RPC..." - echo "RPC URL: ${L2_RPC_URL}" - - # Convert to hex - local fork_block_hex=$(printf '0x%x' $fork_block) - - # Fetch block data from RPC (on host, not in container) - local block_data=$(curl -s --max-time 30 -X POST ${L2_RPC_URL} \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["'$fork_block_hex'",true],"id":1}') - - local curl_exit_code=$? - if [ $curl_exit_code -ne 0 ]; then - echo "❌ Error: Failed to fetch block data from RPC (curl exit code: $curl_exit_code)" - echo " RPC URL: ${L2_RPC_URL}" - echo " This may be due to network issues or RPC timeout." - echo " You can set L2_RPC_URL environment variable to customize." - exit 1 - fi - - # Extract hash and timestamp - local block_hash=$(echo "$block_data" | jq -r '.result.hash') - # max(old genesis timestamp, latest L2 block timestamp + 1) - local timestamp=$(echo "$block_data" | jq -r '.result.timestamp') - - echo "Block #$fork_block:" - echo " Hash: $block_hash" - echo " Timestamp: $timestamp" - - # Validate data - if [ "$block_hash" = "null" ] || [ -z "$block_hash" ]; then - echo "❌ Error: Failed to fetch block hash for block $fork_block" - echo " RPC Response: $block_data" - exit 1 - fi - - # Validate hash format (0x + 64 hex characters) - if ! [[ "$block_hash" =~ ^0x[0-9a-fA-F]{64}$ ]]; then - echo "❌ Error: Invalid block hash format: $block_hash" - echo " Expected: 0x followed by 64 hexadecimal characters" - exit 1 - fi - - if [ "$timestamp" = "null" ] || [ -z "$timestamp" ]; then - echo "❌ Error: Failed to fetch timestamp for block $fork_block" - echo " RPC Response: $block_data" - exit 1 - fi - - # Validate timestamp format (0x + hex number) - if ! [[ "$timestamp" =~ ^0x[0-9a-fA-F]+$ ]]; then - echo "❌ Error: Invalid timestamp format: $timestamp" - echo " Expected: 0x followed by hexadecimal number" - exit 1 - fi - - # Export for use by other functions - export FETCHED_BLOCK_HASH="$block_hash" - export FETCHED_TIMESTAMP="$timestamp" - export FETCHED_FORK_BLOCK="$fork_block" -} - -# Function to validate configuration (executed in container) -validate_configuration() { - local rpc_timestamp=$1 - - echo "" - echo "=============================================" - echo "Validating Configuration Files" - echo "=============================================" - - docker exec ${CONTAINER_NAME} bash -c " - set -e - cd /app/test-pp-op - - # 1. Validate .env - echo \"\" - echo \"[1/4] Validating .env...\" - ENV_CHAIN_ID=\$(grep '^CHAIN_ID=' .env | cut -d'=' -f2) - if [ -z \"\$ENV_CHAIN_ID\" ]; then - echo \" ❌ Error: CHAIN_ID not found in .env\" - echo \" Please ensure .env contains 'CHAIN_ID=$EXPECTED_CHAIN'\" - exit 1 - fi - echo \" CHAIN_ID: \$ENV_CHAIN_ID\" - if [ \"\$ENV_CHAIN_ID\" != \"$EXPECTED_CHAIN\" ]; then - echo \" ❌ Error: .env CHAIN_ID must be $EXPECTED_CHAIN, but got \$ENV_CHAIN_ID\" - exit 1 - fi - echo \" ✅ .env validation passed\" - - # 2. Validate genesis.json - echo \"\" - echo \"[2/4] Validating config-op/genesis.json...\" - if [ ! -f config-op/genesis.json ]; then - echo \" ❌ Error: config-op/genesis.json not found\" - exit 1 - fi - - CHAIN_ID=\$(jq -r '.config.chainId' config-op/genesis.json) - if [ -z \"\$CHAIN_ID\" ] || [ \"\$CHAIN_ID\" = \"null\" ]; then - echo \" ❌ Error: Failed to read .config.chainId from genesis.json\" - echo \" Response: \$CHAIN_ID\" - exit 1 - fi - echo \" config.chainId: \$CHAIN_ID\" - if [ \"\$CHAIN_ID\" != \"$EXPECTED_CHAIN\" ]; then - echo \" ❌ Error: Chain ID must be $EXPECTED_CHAIN, but got \$CHAIN_ID\" - exit 1 - fi - - # Validate timestamp: RPC timestamp must be < genesis.json timestamp - EXISTING_TIMESTAMP=\$(jq -r '.timestamp' config-op/genesis.json) - if [ -z \"\$EXISTING_TIMESTAMP\" ] || [ \"\$EXISTING_TIMESTAMP\" = \"null\" ]; then - echo \" ❌ Error: Failed to read .timestamp from genesis.json\" - exit 1 - fi - RPC_TS_DEC=\$(($rpc_timestamp)) - GENESIS_TS_DEC=\$((EXISTING_TIMESTAMP)) - echo \" genesis.json timestamp: \$EXISTING_TIMESTAMP (decimal: \$GENESIS_TS_DEC)\" - echo \" RPC timestamp: $rpc_timestamp (decimal: \$RPC_TS_DEC)\" - - #if [ \$RPC_TS_DEC -ge \$GENESIS_TS_DEC ]; then - # echo \" ❌ Error: RPC timestamp (\$RPC_TS_DEC) must be < genesis.json timestamp (\$GENESIS_TS_DEC)\" - # echo \" This indicates the fork block is at or after the genesis block.\" - # echo \" Please specify an earlier fork block number.\" - # exit 1 - #fi - #echo \" ✅ genesis.json timestamp validation passed (RPC < genesis)\" - - # 3. Validate intent.toml - echo \"\" - echo \"[3/4] Validating config-op/intent.toml...\" - if [ ! -f config-op/intent.toml ]; then - echo \" ❌ Error: config-op/intent.toml not found\" - exit 1 - fi - - L1_CHAIN_ID=\$(grep '^l1ChainID' config-op/intent.toml | head -1 | sed 's/.*=[[:space:]]*\\([0-9]*\\).*/\\1/') - if [ -z \"\$L1_CHAIN_ID\" ]; then - echo \" ❌ Error: Failed to extract l1ChainID from intent.toml\" - exit 1 - fi - echo \" l1ChainID: \$L1_CHAIN_ID\" - if [ \"\$L1_CHAIN_ID\" != \"$EXPECTED_L1_CHAIN_ID\" ]; then - echo \" ❌ Error: l1ChainID must be $EXPECTED_L1_CHAIN_ID, but got \$L1_CHAIN_ID\" - exit 1 - fi - - CHAIN_ID_HEX=\$(grep '^[[:space:]]*id[[:space:]]*=' config-op/intent.toml | head -1 | sed 's/.*\"\\(0x[0-9a-fA-F]*\\)\".*/\\1/') - if [ -z \"\$CHAIN_ID_HEX\" ]; then - echo \" ❌ Error: Failed to extract chains[0].id from intent.toml\" - exit 1 - fi - CHAIN_ID_DEC=\$((\$CHAIN_ID_HEX)) - echo \" chains[0].id: \$CHAIN_ID_HEX (decimal: \$CHAIN_ID_DEC)\" - if [ \"\$CHAIN_ID_DEC\" != \"$EXPECTED_CHAIN\" ]; then - echo \" ❌ Error: chains[0].id must be $EXPECTED_CHAIN, but got \$CHAIN_ID_DEC\" - exit 1 - fi - - echo \" ✅ intent.toml validation passed\" - - # 4. Validate rollup.json - echo \"\" - echo \"[4/4] Validating config-op/rollup.json...\" - if [ ! -f config-op/rollup.json ]; then - echo \" ❌ Error: config-op/rollup.json not found\" - exit 1 - fi - - ROLLUP_CHAIN_ID=\$(jq -r '.l2_chain_id' config-op/rollup.json) - if [ -z \"\$ROLLUP_CHAIN_ID\" ] || [ \"\$ROLLUP_CHAIN_ID\" = \"null\" ]; then - echo \" ❌ Error: Failed to read .l2_chain_id from rollup.json\" - exit 1 - fi - echo \" l2_chain_id: \$ROLLUP_CHAIN_ID\" - if [ \"\$ROLLUP_CHAIN_ID\" != \"$EXPECTED_CHAIN\" ]; then - echo \" ❌ Error: l2_chain_id must be $EXPECTED_CHAIN, but got \$ROLLUP_CHAIN_ID\" - exit 1 - fi - echo \" ✅ rollup.json validation passed\" - - echo \"\" - echo \"=============================================\" - echo \"✅ All Configuration Validations Passed\" - echo \"=============================================\" - " -} - -# Function to wait for Enter key -wait_for_enter() { - local prompt="$1" - echo "---" - read -n 1 -s -r -p "$prompt" key - echo "" - if [ "$key" != "" ]; then - echo "❌ Aborted by user" - exit 1 - fi -} - -# Function to extract and display configuration fields -extract_configuration_fields() { - local phase="$1" # "before" or "after" - - # Extract .env values - echo "=== .env Configuration ===" - docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ - echo 'CHAIN_ID='\$(grep '^CHAIN_ID=' .env | cut -d'=' -f2) && \ - echo 'OKB_TOKEN_ADDRESS='\$(grep '^OKB_TOKEN_ADDRESS=' .env | cut -d'=' -f2) && \ - echo 'BATCHER_ADDRESS='\$(grep '^BATCHER_ADDRESS=' .env | cut -d'=' -f2) && \ - echo 'PROPOSER_ADDRESS='\$(grep '^PROPOSER_ADDRESS=' .env | cut -d'=' -f2) && \ - echo 'CHALLENGER_ADDRESS='\$(grep '^CHALLENGER_ADDRESS=' .env | cut -d'=' -f2) && \ - echo 'ADMIN_OWNER_ADDRESS='\$(grep '^ADMIN_OWNER_ADDRESS=' .env | cut -d'=' -f2) && \ - echo 'TIME_LOCK_DELAY='\$(grep '^TIME_LOCK_DELAY=' .env | cut -d'=' -f2) && \ - echo 'TEMP_MAX_CLOCK_DURATION='\$(grep '^TEMP_MAX_CLOCK_DURATION=' .env | cut -d'=' -f2) && \ - echo 'TEMP_CLOCK_EXTENSION='\$(grep '^TEMP_CLOCK_EXTENSION=' .env | cut -d'=' -f2) && \ - echo 'PROOF_MATURITY_DELAY_SECONDS='\$(grep '^PROOF_MATURITY_DELAY_SECONDS=' .env | cut -d'=' -f2) && \ - echo 'MAX_CLOCK_DURATION='\$(grep '^MAX_CLOCK_DURATION=' .env | cut -d'=' -f2) && \ - echo 'CLOCK_EXTENSION='\$(grep '^CLOCK_EXTENSION=' .env | cut -d'=' -f2) && \ - echo 'DISPUTE_GAME_FINALITY_DELAY_SECONDS='\$(grep '^DISPUTE_GAME_FINALITY_DELAY_SECONDS=' .env | cut -d'=' -f2) && \ - echo 'CHALLENGE_PERIOD_SECONDS='\$(grep '^CHALLENGE_PERIOD_SECONDS=' .env | cut -d'=' -f2) && \ - echo 'WITHDRAWAL_DELAY_SECONDS='\$(grep '^WITHDRAWAL_DELAY_SECONDS=' .env | cut -d'=' -f2) && \ - echo 'DISPUTE_GAME_FACTORY_ADDRESS='\$(grep '^DISPUTE_GAME_FACTORY_ADDRESS=' .env | cut -d'=' -f2) && \ - echo 'TRANSACTOR='\$(grep '^TRANSACTOR=' .env | cut -d'=' -f2)" - - echo "" - echo "=== intent.toml Configuration ===" - docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ - echo 'l1ChainID='\$(grep '^l1ChainID' config-op/intent.toml | head -1 | sed 's/.*=[[:space:]]*\\([0-9]*\\).*/\\1/') && \ - echo 'opcmAddress='\$(grep '^opcmAddress' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'id='\$(grep '^[[:space:]]*id[[:space:]]*=' config-op/intent.toml | head -1 | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'baseFeeVaultRecipient='\$(grep 'baseFeeVaultRecipient' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'l1FeeVaultRecipient='\$(grep 'l1FeeVaultRecipient' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'sequencerFeeVaultRecipient='\$(grep 'sequencerFeeVaultRecipient' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'l2GenesisBlockGasLimit='\$(grep 'l2GenesisBlockGasLimit' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'l2GenesisBlockBaseFeePerGas='\$(grep 'l2GenesisBlockBaseFeePerGas' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'eip1559DenominatorCanyon='\$(grep 'eip1559DenominatorCanyon' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ - echo 'eip1559Denominator='\$(grep 'eip1559Denominator' config-op/intent.toml | head -1 | cut -d'=' -f2 | tr -d ' ') && \ - echo 'eip1559Elasticity='\$(grep 'eip1559Elasticity' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ - echo 'operatorFeeScalar='\$(grep 'operatorFeeScalar' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ - echo 'operatorFeeConstant='\$(grep 'operatorFeeConstant' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ - echo 'gasLimit='\$(grep 'gasLimit' config-op/intent.toml | cut -d'=' -f2 | tr -d ' ') && \ - echo 'l1ProxyAdminOwner='\$(grep 'l1ProxyAdminOwner' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'l2ProxyAdminOwner='\$(grep 'l2ProxyAdminOwner' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'systemConfigOwner='\$(grep 'systemConfigOwner' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'unsafeBlockSigner='\$(grep 'unsafeBlockSigner' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'batcher='\$(grep 'batcher' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'proposer='\$(grep 'proposer' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/') && \ - echo 'challenger='\$(grep 'challenger' config-op/intent.toml | sed 's/.*\"\\(.*\\)\".*/\\1/')" - - echo "" - echo "=== rollup.json Configuration ===" - docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ - echo 'hash='\$(jq -r '.genesis.l2.hash' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ - echo 'number='\$(jq -r '.genesis.l2.number' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ - echo 'l1_chain_id='\$(jq -r '.l1_chain_id' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ - echo 'l2_chain_id='\$(jq -r '.l2_chain_id' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ - echo 'batch_inbox_address='\$(jq -r '.batch_inbox_address' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ - echo 'deposit_contract_address='\$(jq -r '.deposit_contract_address' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ - echo 'l1_system_config_address='\$(jq -r '.l1_system_config_address' config-op/rollup.json 2>/dev/null || echo 'N/A') && \ - echo 'protocol_versions_address='\$(jq -r '.protocol_versions_address' config-op/rollup.json 2>/dev/null || echo 'N/A')" - - # Only show merged.genesis.json if it exists (after migration) - if [ "$phase" = "after" ]; then - echo "" - echo "=== merged.genesis.json Configuration ===" - docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ - echo 'chainId='\$(head -n 20 merged.genesis.json | grep -o '\"chainId\":[[:space:]]*[0-9]*' | cut -d':' -f2 | tr -d ' ' || echo 'N/A') && \ - echo 'legacyXLayerBlock='\$(head -n 20 merged.genesis.json | grep -o '\"legacyXLayerBlock\":[[:space:]]*[0-9]*' | cut -d':' -f2 | tr -d ' ' || echo 'N/A') && \ - echo 'eip1559Elasticity='\$(head -n 50 merged.genesis.json | grep 'eip1559Elasticity' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A') && \ - echo 'eip1559Denominator='\$(head -n 50 merged.genesis.json | grep 'eip1559Denominator' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A') && \ - echo 'eip1559DenominatorCanyon='\$(head -n 50 merged.genesis.json | grep 'eip1559DenominatorCanyon' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A') && \ - echo 'parentHash='\$(tail -n 20 merged.genesis.json | grep -o '\"parentHash\":[[:space:]]*\"0x[0-9a-fA-F]*\"' | cut -d':' -f2 | tr -d ' \"' || echo 'N/A') && \ - echo 'baseFeePerGas='\$(tail -n 20 merged.genesis.json | grep -o '\"baseFeePerGas\":[[:space:]]*\"0x[0-9a-fA-F]*\"' | cut -d':' -f2 | tr -d ' \"' || echo 'N/A') && \ - echo 'timestamp='\$(head -n 50 merged.genesis.json | grep 'timestamp' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A')" - - echo "" - echo "=== state.json Configuration ===" - docker exec ${CONTAINER_NAME} bash -c "set -e && cd /app/test-pp-op && \ - echo 'SystemConfigProxy='\$(head -n 200 config-op/state.json | grep 'SystemConfigProxy' | head -1 | cut -d':' -f2 | tr -d ' ,' || echo 'N/A')" - else - echo "" - echo "=== merged.genesis.json Configuration ===" - echo "⚠️ merged.genesis.json will be created during migration" - echo " This file contains the final genesis configuration after migration" - fi - - echo "" - echo "==============================================" - wait_for_enter "Press ENTER to continue..." - - echo "" - echo "✅ Configuration fields extracted and reviewed" -} - -# Function to execute migration -execute_migration() { - # Execute migration script inside container - if docker exec -i ${CONTAINER_NAME} bash -c " - set -e - cd /app/test-pp-op - ./4-migrate-op.sh - - if [ ! -f merged.genesis.json ]; then - echo \"❌ Error: merged.genesis.json not found after migration\" - exit 1 - fi - - # Copy files separately for better error handling - cp .env ${BACKUP_DIR}/ || exit 1 - cp merged.genesis.json ${BACKUP_DIR}/ || exit 1 - cp -rf config-op ${BACKUP_DIR}/config-op || exit 1 - - [ -f migrate.log ] && cp migrate.log ${BACKUP_DIR}/ - "; then - echo "" - echo "✅ Migration completed successfully inside container" - return 0 - else - local exit_code=$? - echo "" - echo "❌ Migration failed with exit code: ${exit_code}" - echo "" - read -p "Do you want to keep the container for debugging? (y/N): " KEEP_CONTAINER - if [[ ! "$KEEP_CONTAINER" =~ ^[Yy]$ ]]; then - echo "Stopping and removing container..." - docker stop ${CONTAINER_NAME} 2>/dev/null || true - docker rm ${CONTAINER_NAME} 2>/dev/null || true - else - echo "Container ${CONTAINER_NAME} kept for debugging" - echo "To enter the container: docker exec -it ${CONTAINER_NAME} bash" - fi - exit ${exit_code} - fi -} - -echo "==============================================" -echo "Step 1: Pre-flight checks" -echo "==============================================" - -# Check if ramdisk is mounted -if ! mountpoint -q ${RAMDISK_PATH}; then - echo "❌ Error: Ramdisk not mounted at ${RAMDISK_PATH}" - echo "Please run m2-download-image.sh first to setup ramdisk" - exit 1 -fi -echo "✅ Ramdisk is mounted at ${RAMDISK_PATH}" - -# Check if Docker image exists -if ! docker image inspect ${IMAGE_NAME} >/dev/null 2>&1; then - echo "❌ Error: Docker image ${IMAGE_NAME} not found" - echo "Please run m2-download-image.sh first to load the image" - exit 1 -fi - -# Check if erigon data directory exists -if [ ! -d "${ERIGON_DATA_DIR}" ]; then - echo "❌ Error: Erigon data directory ${ERIGON_DATA_DIR} not found" - exit 1 -fi - -echo "✅ All pre-flight checks passed" - -echo "" -echo "==============================================" -echo "Step 2: Start Docker container" -echo "==============================================" - -# Clean up any existing data from previous migrations -SOURCE_PATH="$RAMDISK_PATH/test-pp-op/data/op-geth-seq" -if [ -d "$SOURCE_PATH" ]; then - echo "🗑️ Removing contents from $SOURCE_PATH..." - rm -rf "$SOURCE_PATH"/* - echo "✅ Previous data contents cleaned up" -else - echo "✅ No existing data found at $SOURCE_PATH" -fi - -mkdir -p ${SOURCE_PATH} - -# Force remove existing container for clean migration -if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - echo "🗑️ Removing existing container ${CONTAINER_NAME} for clean migration..." - - # Stop container - if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - echo " Stopping container..." - docker stop ${CONTAINER_NAME} 2>/dev/null || true - fi - - docker rm ${CONTAINER_NAME} 2>/dev/null || true - echo "✅ Old container removed" -fi - -# Start container if not running -if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - echo "Starting container ${CONTAINER_NAME}..." - docker run \ - --name ${CONTAINER_NAME} \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v ${ERIGON_DATA_DIR}:/data/erigon-data \ - -v ${BACKUP_DIR}:${BACKUP_DIR} \ - -v ${RAMDISK_PATH}:${RAMDISK_PATH} \ - -v ${RAMDISK_PATH}/test-pp-op/data/op-geth-seq:/app/test-pp-op/data/op-geth-seq \ - -e DOCKER_HOST=unix:///var/run/docker.sock \ - -d ${IMAGE_NAME} sleep infinity - - echo "✅ Container started successfully" - - # Wait a moment for container to be ready - sleep 2 -else - echo "✅ Container ${CONTAINER_NAME} is already running" -fi - -echo "" -echo "==============================================" -echo "Step 3: Check configuration" -echo "==============================================" - -if [ "$CHECK_BLOCK" = "true" ]; then - if [ -z "$FORK_BLOCK" ]; then - echo "❌ Error: FORK_BLOCK not set. Pls specify ./m2-migrate.sh FORK_BLOCK" - exit 1 - fi - - # Fetch block data from RPC (on host) - fetch_block_data $FORK_BLOCK - # Validate all configurations (pass RPC timestamp for validation) - validate_configuration $FETCHED_TIMESTAMP -fi - -echo "" -echo "==============================================" -echo "Step 4: Review Configuration Before Migration" -echo "==============================================" -extract_configuration_fields "before" - -echo "" -echo "==============================================" -echo "Step 5: Execute Migration" -echo "==============================================" -echo "Executing ./4-migrate-op.sh inside container..." -echo "" -execute_migration - -echo "" -echo "==============================================" -echo "Step 6: Copy results to disk" -echo "==============================================" - -TEMP_DIR="${BACKUP_DIR}.tmp" - -# Verify source exists -if [ ! -d "$SOURCE_PATH" ]; then - echo "❌ Error: Source directory not found: $SOURCE_PATH" - echo " Expected migration output in ramdisk, but directory does not exist" - echo "" - echo " Checking alternative locations..." - - # Check if data might be elsewhere - if [ -d "$RAMDISK_PATH/test-pp-op/data" ]; then - echo " Contents of $RAMDISK_PATH/test-pp-op/data/:" - ls -la "$RAMDISK_PATH/test-pp-op/data/" 2>/dev/null || echo " (unable to list)" - fi - - echo "" - echo " Please verify:" - echo " 1. Migration script completed successfully" - echo " 2. Output was written to ramdisk" - echo " 3. Container volume mounts are correct" - exit 1 -fi - -# Verify source is not empty -SOURCE_SIZE=$(du -sb "$SOURCE_PATH" 2>/dev/null | awk '{print $1}') -if [ "$SOURCE_SIZE" -lt 1024 ]; then - echo "⚠️ Warning: Source directory is very small (${SOURCE_SIZE} bytes)" - echo " This may indicate migration did not complete properly" - read -p "Continue anyway? (y/N): " CONTINUE - if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then - echo "Aborted by user" - exit 1 - fi -fi - -echo "Source size: $(du -sh "$SOURCE_PATH" 2>/dev/null | awk '{print $1}')" - -echo "Backup directory: ${BACKUP_DIR}" -echo "Copying data from ramdisk to disk (using atomic operation)..." - -# Safety check for TEMP_DIR -if [ -z "$TEMP_DIR" ] || [ "$TEMP_DIR" = "/" ] || [ "$TEMP_DIR" = "/tmp" ]; then - echo "❌ Error: Invalid TEMP_DIR value: $TEMP_DIR" - exit 1 -fi - -# Use temporary directory for atomic copy -rm -rf "$TEMP_DIR" -mkdir -p "$TEMP_DIR" - -# Copy to temporary location -if ! cp -r "$SOURCE_PATH" "$TEMP_DIR/op-geth-seq"; then - echo "❌ Error: Failed to copy data to temporary directory" - rm -rf "$TEMP_DIR" - exit 1 -fi - -# Move to final location (atomic operation) -if ! mv "$TEMP_DIR/op-geth-seq" "$BACKUP_DIR/"; then - echo "❌ Error: Failed to move data to backup directory" - rm -rf "$TEMP_DIR" - exit 1 -fi - -# Clean up -rm -rf "$TEMP_DIR" - -echo "✅ Files copied successfully" - -echo "" -echo "==============================================" -echo "Step 7: Review Configuration After Copy" -echo "==============================================" -extract_configuration_fields "after" - -echo "" -echo "==============================================" -echo "Step 8: Copy diff.genesis.json from container" -echo "==============================================" - -# Check if diff.genesis.json exists in container -if docker exec ${CONTAINER_NAME} test -f /app/test-pp-op/diff.genesis.json; then - echo "Copying diff.genesis.json from container..." - if docker cp ${CONTAINER_NAME}:/app/test-pp-op/diff.genesis.json ${BACKUP_DIR}/diff.genesis.json; then - echo "✅ diff.genesis.json copied successfully to ${BACKUP_DIR}/diff.genesis.json" - else - echo "⚠️ Warning: Failed to copy diff.genesis.json" - fi -else - echo "⚠️ Warning: diff.genesis.json not found in container" - echo " Expected location: /app/test-pp-op/diff.genesis.json" -fi - -echo "" -echo "==============================================" -echo "Step 9: Check for differences between mounted data and backup" -echo "==============================================" - -diff -r $SOURCE_PATH $BACKUP_DIR/op-geth-seq # exit script on failure (set -e) -echo "✅ Contents of ${SOURCE_PATH} matches ${BACKUP_DIR}/op-geth-seq" - -echo "" -echo "==============================================" -echo "✅ Migration process completed successfully!" -echo "==============================================" -echo "Backup directory: ${BACKUP_DIR}" - -if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - echo "" - echo "Stopping migration container at last." - echo "" - docker stop ${CONTAINER_NAME} 2>/dev/null || true -fi - -echo "==============================================" diff --git a/test-pp-op/m3-verify.sh b/test-pp-op/m3-verify.sh deleted file mode 100755 index f97af85489ab9..0000000000000 --- a/test-pp-op/m3-verify.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -set -e -set -x - -IMAGE_NAME="op-geth-migrate:latest" -CONTAINER_NAME="op-verify-container" -RAMDISK_PATH="${RAMDISK_PATH:-/mnt/ramdisk_op}" -ERIGON_DATA_DIR="${ERIGON_DATA_DIR:-/data/erigon-data}" -OP_GETH_DATA_DIR="${RAMDISK_PATH}/test-pp-op/data/op-geth-seq" - -echo "Verifying migration in ramdisk..." -echo " Erigon: ${ERIGON_DATA_DIR}/chaindata" -echo " OP-Geth: ${OP_GETH_DATA_DIR}" - -# Basic checks -[ -d "${ERIGON_DATA_DIR}/chaindata" ] || { echo "❌ Erigon chaindata not found at ${ERIGON_DATA_DIR}/chaindata"; exit 1; } -[ -d "${OP_GETH_DATA_DIR}" ] || { echo "❌ OP-Geth data not found at ${OP_GETH_DATA_DIR}"; exit 1; } - -# Cleanup old container -docker rm -f ${CONTAINER_NAME} 2>/dev/null || true - -# Start container -docker run -d --name ${CONTAINER_NAME} \ - -v ${ERIGON_DATA_DIR}:/data/erigon-data \ - -v ${RAMDISK_PATH}:${RAMDISK_PATH} \ - ${IMAGE_NAME} sleep infinity - -sleep 2 - -# Run verification -echo "Running verification..." -docker exec -w /app/test-pp-op -it ${CONTAINER_NAME} geth verifyMigrate \ - --chaindata=/data/erigon-data/chaindata \ - --datadir=${OP_GETH_DATA_DIR} \ - --standalone-smt=true - -RESULT=$? - -# Cleanup -docker rm -f ${CONTAINER_NAME} 2>/dev/null || true - -exit $RESULT - diff --git a/test-pp-op/notes.txt b/test-pp-op/notes.txt deleted file mode 100644 index e5ade6a866676..0000000000000 --- a/test-pp-op/notes.txt +++ /dev/null @@ -1,28 +0,0 @@ -# op node -curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"opp2p_self","params":[],"id":1}' http://localhost:9545 - -curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"opp2p_peerStats","params":[],"id":1}' http://localhost:9545 - -curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_sequencerActive","params":[],"id":1}' http://localhost:9545 - -curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' http://localhost:9545 - -curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_overrideLeader","params":[],"id":1}' http://localhost:9545 - - - -# op conductor -curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' http://localhost:8547 - -curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_sequencerHealthy","params":[],"id":1}' http://localhost:8547 - -curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_paused","params":[],"id":1}' http://localhost:8547 - -curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_resume","params":[],"id":1}' http://localhost:8547 - - - - - - - diff --git a/test-pp-op/patch/op-geth-0001-support-load-genesis-at-a-given-number.patch b/test-pp-op/patch/op-geth-0001-support-load-genesis-at-a-given-number.patch deleted file mode 100644 index c44e001aa0fb7..0000000000000 --- a/test-pp-op/patch/op-geth-0001-support-load-genesis-at-a-given-number.patch +++ /dev/null @@ -1,187 +0,0 @@ -From c0308891304462768e9b1f662c35e77b614a427e Mon Sep 17 00:00:00 2001 -From: JimmyShi -Date: Tue, 8 Jul 2025 14:29:46 +0800 -Subject: [PATCH] support load genesis at a given number - ---- - core/blockchain_reader.go | 7 ++++++- - core/genesis.go | 13 ++++++++++--- - core/rawdb/accessors_chain.go | 17 +++++++++++++++++ - core/rawdb/chain_freezer.go | 6 ++++-- - core/rawdb/database.go | 36 ++++++++++++++++++++++++++++++----- - 5 files changed, 68 insertions(+), 11 deletions(-) - -diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go -index f53ddfa4c..1aa3caf90 100644 ---- a/core/blockchain_reader.go -+++ b/core/blockchain_reader.go -@@ -424,7 +424,12 @@ func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) { - func (bc *BlockChain) HistoryPruningCutoff() (uint64, common.Hash) { - pt := bc.historyPrunePoint.Load() - if pt == nil { -- return 0, bc.genesisBlock.Hash() -+ // get genesis block number -+ genesisHash := rawdb.ReadCanonicalHash(bc.db, 0) -+ genesisHeader := rawdb.ReadHeader(bc.db, genesisHash, 0) -+ genesisBlockNumber := genesisHeader.Number.Uint64() -+ -+ return genesisBlockNumber, genesisHash - } - return pt.BlockNumber, pt.BlockHash - } -diff --git a/core/genesis.go b/core/genesis.go -index 5db5c9813..33a0f1291 100644 ---- a/core/genesis.go -+++ b/core/genesis.go -@@ -683,9 +683,9 @@ func (g *Genesis) toBlockWithRoot(stateRoot, storageRootMessagePasser common.Has - // Commit writes the block and state of a genesis specification to the database. - // The block is committed as the canonical head block. - func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Block, error) { -- if g.Number != 0 { -- return nil, errors.New("can't commit genesis block with number > 0") -- } -+ // if g.Number != 0 { -+ // return nil, errors.New("can't commit genesis block with number > 0") -+ // } - config := g.Config - if config == nil { - return nil, errors.New("invalid genesis without chain config") -@@ -727,6 +727,13 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo - rawdb.WriteHeadFastBlockHash(batch, block.Hash()) - rawdb.WriteHeadHeaderHash(batch, block.Hash()) - rawdb.WriteChainConfig(batch, block.Hash(), config) -+ -+ if block.NumberU64() != 0 { -+ // Also write the genesis block as number 0 -+ rawdb.WriteCanonicalHash(batch, block.Hash(), 0) -+ rawdb.WriteGenesisHeader(batch, block.Header()) -+ } -+ - return block, batch.Write() - } - -diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go -index 59c73aa99..e77733f78 100644 ---- a/core/rawdb/accessors_chain.go -+++ b/core/rawdb/accessors_chain.go -@@ -404,6 +404,23 @@ func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) { - } - } - -+func WriteGenesisHeader(db ethdb.KeyValueWriter, header *types.Header) { -+ var ( -+ hash = header.Hash() -+ number = uint64(0) -+ ) -+ -+ // Write the encoded header -+ data, err := rlp.EncodeToBytes(header) -+ if err != nil { -+ log.Crit("Failed to RLP encode header", "err", err) -+ } -+ key := headerKey(number, hash) -+ if err := db.Put(key, data); err != nil { -+ log.Crit("Failed to store header", "err", err) -+ } -+} -+ - // DeleteHeader removes all block header data associated with a hash. - func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - deleteHeaderWithoutNumber(db, hash, number) -diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go -index f3c671f45..ebebc9c95 100644 ---- a/core/rawdb/chain_freezer.go -+++ b/core/rawdb/chain_freezer.go -@@ -212,7 +212,8 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) { - batch := db.NewBatch() - for i := 0; i < len(ancients); i++ { - // Always keep the genesis block in active database -- if first+uint64(i) != 0 { -+ trueGenesisNumber := getGenesisBlockNumber(db) -+ if first+uint64(i) != trueGenesisNumber { - DeleteBlockWithoutNumber(batch, ancients[i], first+uint64(i)) - DeleteCanonicalHash(batch, first+uint64(i)) - } -@@ -225,9 +226,10 @@ func (f *chainFreezer) freeze(db ethdb.KeyValueStore) { - // Wipe out side chains also and track dangling side chains - var dangling []common.Hash - frozen, _ = f.Ancients() // Needs reload after during freezeRange -+ trueGenesisNumber := getGenesisBlockNumber(db) - for number := first; number < frozen; number++ { - // Always keep the genesis block in active database -- if number != 0 { -+ if number != trueGenesisNumber { - dangling = ReadAllHashes(db, number) - for _, hash := range dangling { - log.Trace("Deleting side chain", "number", number, "hash", hash) -diff --git a/core/rawdb/database.go b/core/rawdb/database.go -index 7ab6dbdc6..835df8167 100644 ---- a/core/rawdb/database.go -+++ b/core/rawdb/database.go -@@ -28,10 +28,12 @@ import ( - "time" - - "github.com/ethereum/go-ethereum/common" -+ "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/ethdb/memorydb" - "github.com/ethereum/go-ethereum/log" -+ "github.com/ethereum/go-ethereum/rlp" - "github.com/olekukonko/tablewriter" - ) - -@@ -265,17 +267,19 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st - // store deletion, but that's fine). - } else { - // If the freezer is empty, ensure nothing was moved yet from the key-value -- // store, otherwise we'll end up missing data. We check block #1 to decide -- // if we froze anything previously or not, but do take care of databases with -- // only the genesis block. -+ // store, otherwise we'll end up missing data. We check the block after the -+ // true genesis block to decide if we froze anything previously or not. - if ReadHeadHeaderHash(db) != common.BytesToHash(kvgenesis) { - // Key-value store contains more data than the genesis block, make sure we - // didn't freeze anything yet. -- if kvblob, _ := db.Get(headerHashKey(1)); len(kvblob) == 0 { -+ trueGenesisNumber := getGenesisBlockNumber(db) -+ nextBlockNumber := trueGenesisNumber + 1 -+ -+ if kvblob, _ := db.Get(headerHashKey(nextBlockNumber)); len(kvblob) == 0 { - printChainMetadata(db) - return nil, errors.New("ancient chain segments already extracted, please set --datadir.ancient to the correct path") - } -- // Block #1 is still in the database, we're allowed to init a new freezer -+ // Block after true genesis is still in the database, we're allowed to init a new freezer - } - // Otherwise, the head header is still the genesis, we're allowed to init a new - // freezer. -@@ -680,3 +684,25 @@ func SafeDeleteRange(db ethdb.KeyValueStore, start, end []byte, hashScheme bool, - } - return batch.Write() - } -+ -+// getGenesisBlockNumber returns the actual genesis block number from the database. -+// This is needed for custom genesis logic where the genesis block might not be at block 0. -+func getGenesisBlockNumber(db ethdb.KeyValueStore) uint64 { -+ // First check if there's a genesis block at block 0 -+ if genesisHashData, _ := db.Get(headerHashKey(0)); len(genesisHashData) > 0 { -+ genesisHash := common.BytesToHash(genesisHashData) -+ // Try to read the block header to get the number -+ if headerData, _ := db.Get(headerKey(0, genesisHash)); len(headerData) > 0 { -+ var header types.Header -+ if err := rlp.DecodeBytes(headerData, &header); err == nil { -+ // Check if this block has a custom number field -+ if header.Number.Uint64() != 0 { -+ return header.Number.Uint64() -+ } -+ } -+ } -+ } -+ -+ // If no custom number found, return 0 as default -+ return 0 -+} --- -2.50.1 - diff --git a/test-pp-op/patch/optimism-0001-decompress-genesis.patch b/test-pp-op/patch/optimism-0001-decompress-genesis.patch deleted file mode 100644 index 9895f51016c6b..0000000000000 --- a/test-pp-op/patch/optimism-0001-decompress-genesis.patch +++ /dev/null @@ -1,65 +0,0 @@ -From e4dc440f1d47b95d2609bbe22e06d9878bcaa59c Mon Sep 17 00:00:00 2001 -From: "xingqiang.yuan" -Date: Tue, 19 Aug 2025 22:18:30 +0800 -Subject: [PATCH] decompress genesis - ---- - op-program/chainconfig/chaincfg.go | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/op-program/chainconfig/chaincfg.go b/op-program/chainconfig/chaincfg.go -index b4ae0ff95..58fa20dbf 100644 ---- a/op-program/chainconfig/chaincfg.go -+++ b/op-program/chainconfig/chaincfg.go -@@ -1,10 +1,15 @@ - package chainconfig - - import ( -+ "bytes" -+ "compress/gzip" -+ "crypto/md5" - "embed" - "encoding/json" - "errors" - "fmt" -+ "github.com/ethereum/go-ethereum/log" -+ "io" - "os" - "strings" - -@@ -87,6 +92,20 @@ func ChainConfigByChainID(chainID eth.ChainID) (*params.ChainConfig, error) { - return chainConfigByChainID(chainID, customChainConfigFS) - } - -+func decompressGzip(data []byte) ([]byte, error) { -+ reader, err := gzip.NewReader(bytes.NewReader(data)) -+ if err != nil { -+ return nil, err -+ } -+ defer reader.Close() -+ -+ var uncompressedData bytes.Buffer -+ if _, err := io.Copy(&uncompressedData, reader); err != nil { -+ return nil, err -+ } -+ return uncompressedData.Bytes(), nil -+} -+ - func chainConfigByChainID(chainID eth.ChainID, customChainFS embed.FS) (*params.ChainConfig, error) { - // Load from custom chain configs from embed FS - data, err := customChainFS.ReadFile(fmt.Sprintf("configs/%v-genesis-l2.json", chainID)) -@@ -95,6 +114,11 @@ func chainConfigByChainID(chainID eth.ChainID, customChainFS embed.FS) (*params. - } else if err != nil { - return nil, fmt.Errorf("failed to get chain config for chain ID %v: %w", chainID, err) - } -+ data, err = decompressGzip(data) -+ if err != nil { -+ return nil, fmt.Errorf("failed to decompress for chain ID %v: %w", chainID, err) -+ } -+ log.Info("decompress genesis", "chain id", chainID, "md5 hash", md5.Sum(data)) - var genesis core.Genesis - err = json.Unmarshal(data, &genesis) - if err != nil { --- -2.39.5 (Apple Git-154) - diff --git a/test-pp-op/patch/optimism-0001-support-regenesis-op-geth-prestate.patch b/test-pp-op/patch/optimism-0001-support-regenesis-op-geth-prestate.patch deleted file mode 100644 index ad0dffc4ffc92..0000000000000 --- a/test-pp-op/patch/optimism-0001-support-regenesis-op-geth-prestate.patch +++ /dev/null @@ -1,82 +0,0 @@ -diff --git a/Makefile b/Makefile -index b7e2e8102c..76f87fc9cf 100644 ---- a/Makefile -+++ b/Makefile -@@ -13,7 +13,7 @@ help: ## Prints this help message - build: build-go build-contracts ## Builds Go components and contracts-bedrock - .PHONY: build - --build-go: submodules op-node op-proposer op-batcher op-challenger op-dispute-mon op-program cannon ## Builds main Go components -+build-go: submodules op-node op-proposer op-batcher op-challenger op-dispute-mon op-program cannon withdrawal ## Builds main Go components - .PHONY: build-go - - build-contracts: -@@ -128,6 +128,10 @@ cannon: ## Builds cannon binary - make -C ./cannon cannon - .PHONY: cannon - -+withdrawal: ## Builds withdrawal binary -+ just $(JUSTFLAGS) ./op-chain-ops/withdrawal -+.PHONY: withdrawal -+ - reproducible-prestate: ## Builds reproducible-prestate binary - make -C ./op-program reproducible-prestate - .PHONY: reproducible-prestate -diff --git a/go.mod b/go.mod -index b09102566e..7a3fc16755 100644 ---- a/go.mod -+++ b/go.mod -@@ -304,9 +304,9 @@ require ( - rsc.io/tmplfunc v0.0.3 // indirect - ) - --replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101511.1-dev.1.0.20250608235258-6005dd53e1b5 -+// replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101511.1-dev.1.0.20250608235258-6005dd53e1b5 - --//replace github.com/ethereum/go-ethereum => ../op-geth -+replace github.com/ethereum/go-ethereum => ./op-geth - - // replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain - -diff --git a/op-chain-ops/justfile b/op-chain-ops/justfile -index ee7efe7d6c..82ddb5467a 100644 ---- a/op-chain-ops/justfile -+++ b/op-chain-ops/justfile -@@ -12,9 +12,12 @@ _LDFLAGSSTRING := "'" + trim( - # Build ecotone-scalar binary - ecotone-scalar: (go_build "./bin/ecotone-scalar" "./cmd/ecotone-scalar" "-ldflags" _LDFLAGSSTRING) - --# Build receipt-reference-builder binary -+# Build receipt-reference-builder binary - receipt-reference-builder: (go_build "./bin/receipt-reference-builder" "./cmd/receipt-reference-builder" "-ldflags" _LDFLAGSSTRING) - -+# Build withdrawal binary -+withdrawal: (go_build "./bin/withdrawal" "./cmd/withdrawal" "-ldflags" _LDFLAGSSTRING) -+ - # Run tests - test: (go_test "./...") - -diff --git a/op-program/Dockerfile.repro b/op-program/Dockerfile.repro -index 2f861f3b2f..b97057cd4e 100644 ---- a/op-program/Dockerfile.repro -+++ b/op-program/Dockerfile.repro -@@ -6,6 +6,7 @@ RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash just - - COPY ./go.mod /app/go.mod - COPY ./go.sum /app/go.sum -+COPY ./op-geth /app/op-geth - - WORKDIR /app - -diff --git a/op-program/Dockerfile.repro.dockerignore b/op-program/Dockerfile.repro.dockerignore -index 15d6cf7638..2844c7a062 100644 ---- a/op-program/Dockerfile.repro.dockerignore -+++ b/op-program/Dockerfile.repro.dockerignore -@@ -5,6 +5,7 @@ - # internal dependencies - !cannon/ - !op-alt-da/ -+!op-geth/ - !op-node/ - !op-preimage/ - !op-program/ diff --git a/test-pp-op/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch b/test-pp-op/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch deleted file mode 100644 index 989533773b258..0000000000000 --- a/test-pp-op/patch/xlayer-bridge-service-0001-support-sync-L2-block-at-given-number.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 8085cc9eae7a360862cf23472ed179cb14ab29c8 Mon Sep 17 00:00:00 2001 -From: JimmyShi -Date: Tue, 8 Jul 2025 14:27:45 +0800 -Subject: [PATCH] support sync L2 block at given number - ---- - cmd/run.go | 2 +- - config/network.go | 5 +++++ - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/cmd/run.go b/cmd/run.go -index a49c802..da7cf69 100644 ---- a/cmd/run.go -+++ b/cmd/run.go -@@ -109,7 +109,7 @@ func start(ctx *cli.Context) error { - chSyncedL2 := make(chan uint32) - chsExitRootEvent = append(chsExitRootEvent, chExitRootEventL2) - chsSyncedL2 = append(chsSyncedL2, chSyncedL2) -- go runSynchronizer(ctx.Context, 0, bridgeController, l2EthermanClient, c.Synchronizer, storage, zkEVMClient, chExitRootEventL2, nil, chSyncedL2, []uint32{}, c.NetworkConfig.RequireSovereignChainSmcs[i]) -+ go runSynchronizer(ctx.Context, c.NetworkConfig.L2GenBlockNumber, bridgeController, l2EthermanClient, c.Synchronizer, storage, zkEVMClient, chExitRootEventL2, nil, chSyncedL2, []uint32{}, c.NetworkConfig.RequireSovereignChainSmcs[i]) - } - chSynced := make(chan uint32) - go runSynchronizer(ctx.Context, c.NetworkConfig.GenBlockNumber, bridgeController, l1Etherman, c.Synchronizer, storage, nil, nil, chsExitRootEvent, chSynced, networkIDs, false) -diff --git a/config/network.go b/config/network.go -index 4edeb4f..ae332f9 100644 ---- a/config/network.go -+++ b/config/network.go -@@ -8,6 +8,7 @@ import ( - // NetworkConfig is the configuration struct for the different environments. - type NetworkConfig struct { - GenBlockNumber uint64 -+ L2GenBlockNumber uint64 - PolygonBridgeAddress common.Address - PolygonZkEVMGlobalExitRootAddress common.Address - PolygonRollupManagerAddress common.Address -@@ -26,6 +27,7 @@ var ( - networkConfigs = map[string]NetworkConfig{ - defaultNetwork: { - GenBlockNumber: 16896718, -+ L2GenBlockNumber: 0, - PolygonBridgeAddress: common.HexToAddress("0x2a3DD3EB832aF982ec71669E178424b10Dca2EDe"), - PolygonZkEVMGlobalExitRootAddress: common.HexToAddress("0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb"), - PolygonRollupManagerAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"), -@@ -37,6 +39,7 @@ var ( - - "testnet": { - GenBlockNumber: 8572995, -+ L2GenBlockNumber: 0, - PolygonBridgeAddress: common.HexToAddress("0xF6BEEeBB578e214CA9E23B0e9683454Ff88Ed2A7"), - PolygonZkEVMGlobalExitRootAddress: common.HexToAddress("0x4d9427DCA0406358445bC0a8F88C26b704004f74"), - PolygonRollupManagerAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"), -@@ -47,6 +50,7 @@ var ( - }, - "internaltestnet": { - GenBlockNumber: 7674349, -+ L2GenBlockNumber: 0, - PolygonBridgeAddress: common.HexToAddress("0x47c1090bc966280000Fe4356a501f1D0887Ce840"), - PolygonZkEVMGlobalExitRootAddress: common.HexToAddress("0xA379Dd55Eb12e8FCdb467A814A15DE2b29677066"), - PolygonRollupManagerAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"), -@@ -57,6 +61,7 @@ var ( - }, - "local": { - GenBlockNumber: 1, -+ L2GenBlockNumber: 0, - PolygonBridgeAddress: common.HexToAddress("0xFe12ABaa190Ef0c8638Ee0ba9F828BF41368Ca0E"), - PolygonZkEVMGlobalExitRootAddress: common.HexToAddress("0x8A791620dd6260079BF849Dc5567aDC3F2FdC318"), - PolygonRollupManagerAddress: common.HexToAddress("0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e"), --- -2.39.5 (Apple Git-154) - diff --git a/test-pp-op/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch b/test-pp-op/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch deleted file mode 100644 index c225790de1a45..0000000000000 --- a/test-pp-op/patch/xlayer-bridge-service-0002-skip-reorg-check-after-regenesis.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 3e3c4fa34b5e51e2436ae81faaf1fad90c136d39 Mon Sep 17 00:00:00 2001 -From: KyrinCode -Date: Sat, 13 Sep 2025 00:50:53 +0800 -Subject: [PATCH 1/2] skip reorg check after regenesis - ---- - synchronizer/synchronizer.go | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go -index 5708756..96088b0 100644 ---- a/synchronizer/synchronizer.go -+++ b/synchronizer/synchronizer.go -@@ -602,6 +602,13 @@ hash and has parent. This operation has to be done until a match is found. - */ - func (s *ClientSynchronizer) checkReorg(latestStoredBlock etherman.Block, syncedBlock *etherman.Block) (*etherman.Block, error) { - // This function only needs to worry about reorgs if some of the reorganized blocks contained rollup info. -+ -+ // Skip reorg check after a regenesis -+ if latestStoredBlock.BlockNumber < s.genBlockNumber { -+ log.Debugf("NetworkID: %d, skipping reorg check after a regenesis. Latest stored block: %d, genesis block: %d", s.networkID, latestStoredBlock.BlockNumber, s.genBlockNumber) -+ return nil, nil -+ } -+ - latestStoredEthBlock := latestStoredBlock - reorgedBlock := latestStoredBlock - var depth uint64 --- -2.39.5 (Apple Git-154) - diff --git a/test-pp-op/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch b/test-pp-op/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch deleted file mode 100644 index 2c105507b8897..0000000000000 --- a/test-pp-op/patch/xlayer-bridge-service-0003-skip-syncing-blocks-before-regenesis.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 98e29ad0cf2625914c1d3b56b6ebd8648f647d49 Mon Sep 17 00:00:00 2001 -From: KyrinCode -Date: Sat, 13 Sep 2025 00:51:47 +0800 -Subject: [PATCH 2/2] skip syncing blocks before regenesis - ---- - synchronizer/synchronizer.go | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go -index 96088b0..69d8224 100644 ---- a/synchronizer/synchronizer.go -+++ b/synchronizer/synchronizer.go -@@ -128,6 +128,14 @@ func (s *ClientSynchronizer) Sync() error { - return err - } - } -+ if lastBlockSynced.BlockNumber < s.genBlockNumber { -+ log.Debugf("networkID: %d, latest stored block is before regenesis block. Setting regenesis block", s.networkID) -+ lastBlockSynced = ðerman.Block{ -+ BlockNumber: s.genBlockNumber, -+ NetworkID: s.networkID, -+ } -+ } -+ - metrics.InitializationTime(time.Since(startInitialization)) - log.Debugf("NetworkID: %d, initial lastBlockSynced: %+v", s.networkID, lastBlockSynced) - for { --- -2.39.5 (Apple Git-154) - diff --git a/test-pp-op/scripts/active-sequencer.sh b/test-pp-op/scripts/active-sequencer.sh deleted file mode 100755 index 660143afeb01e..0000000000000 --- a/test-pp-op/scripts/active-sequencer.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/bash - -# Function to detect leader conductor and set ports -detect_leader() { - echo "Detecting leader conductor..." - - # Check all three conductors to find the leader - for i in 1 2 3; do - CONDUCTOR_PORT=$((8546 + i)) # 8547, 8548, 8549 - SEQUENCER_PORT=$((9544 + i)) # 9545, 9546, 9547 - - IS_LEADER=$(curl -sS -X POST -H "Content-Type: application/json" \ - --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ - http://localhost:$CONDUCTOR_PORT 2>/dev/null | jq -r '.result' 2>/dev/null) - - if [ "$IS_LEADER" = "true" ]; then - LEADER_CONDUCTOR_PORT=$CONDUCTOR_PORT - LEADER_SEQUENCER_PORT=$SEQUENCER_PORT - echo "Found leader: Conductor $i (conductor port: $LEADER_CONDUCTOR_PORT, sequencer port: $LEADER_SEQUENCER_PORT)" - return 0 - else - echo "Conductor $i (port $CONDUCTOR_PORT): not leader (result: $IS_LEADER)" - fi - done - - echo "Error: No leader conductor found!" - exit 1 -} - -# Detect leader conductor and set ports -detect_leader - -# 1. check connected peers -CONNECTED=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"opp2p_peerStats","params":[],"id":1}' http://localhost:$LEADER_SEQUENCER_PORT | jq .result.connected) -if (( CONNECTED < 2 )); then - echo "$CONNECTED peers connected, which is less than 2" - echo 1 -fi - -# 2. try to resume conductor if it is paused -PAUSED=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_paused","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq -r .result) -if [ $PAUSED = "true" ]; then - curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_resume","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT - PAUSED=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_paused","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq -r .result) - if [ $PAUSED = "true" ]; then - echo "conductor is paused due to resume failure" - exit 1 - fi -fi - -# 3. try to start sequencer if it is stopped -ACTIVE=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_sequencerActive","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq -r .result) -if [ $ACTIVE = "false" ]; then - BLOCK_HASH=$(curl -sS -X POST -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false],"id":1}' http://localhost:8123 | jq -r .result.hash) - if [ -z "$BLOCK_HASH" ] || [ "$BLOCK_HASH" = "null" ]; then - echo "Failed to get latest block hash" - exit 1 - fi - echo "Got latest block hash: $BLOCK_HASH" - - # 3. Start sequencer with the block hash - curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_startSequencer","params":["'"$BLOCK_HASH"'"],"id":1}' http://localhost:$LEADER_SEQUENCER_PORT - if [ $? -ne 0 ]; then - echo "Failed to start sequencer" - exit 1 - fi -fi - -# 4. verify sequencer is active -sleep 1 -ACTIVE=$(curl -sS -X POST -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","method":"admin_sequencerActive","params":[],"id":1}' http://localhost:$LEADER_SEQUENCER_PORT | jq -r .result) -if [ "$ACTIVE" != "true" ]; then - echo "Failed to activate sequencer" - exit 1 -fi - -echo "Sequencer successfully activated" - -# 5. try to add other two conductors to raft consensus cluster -SERVER_COUNT=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_clusterMembership","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq '.result.servers | length') -if (( $SERVER_COUNT < 3 )); then - curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_addServerAsVoter","params":["conductor-2", "op-conductor2:50050", 0],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT - curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_addServerAsVoter","params":["conductor-3", "op-conductor3:50050", 0],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT - SERVER_COUNT=$(curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_clusterMembership","params":[],"id":1}' http://localhost:$LEADER_CONDUCTOR_PORT | jq '.result.servers | length') - if (( $SERVER_COUNT != 3 )); then - echo "unexpected server count, expected: 3, real: $SERVER_COUNT" - exit 1 - fi - - echo "add 2 new voters to raft consensus cluster successfully!" -fi diff --git a/test-pp-op/scripts/add-game-type.sh b/test-pp-op/scripts/add-game-type.sh deleted file mode 100755 index 4ae3e209b6c6b..0000000000000 --- a/test-pp-op/scripts/add-game-type.sh +++ /dev/null @@ -1,192 +0,0 @@ -#!/bin/bash - -set -e - -# Source environment variables -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ENV_FILE="$(dirname "$SCRIPT_DIR")/.env" -source "$ENV_FILE" - -# Function to set respected game type -set_respected_game_type() { - local GAME_TYPE=${1:-0} # Default to game type 0 - - echo "=== Setting Respected Game Type to $GAME_TYPE ===" - - # Get contract addresses - echo " 📋 Gathering contract addresses..." - DISPUTE_GAME_FACTORY_ADDR=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'disputeGameFactory()(address)') - OPTIMISM_PORTAL_ADDR=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'optimismPortal()(address)') - ANCHOR_STATE_REGISTRY_ADDR=$(cast call --rpc-url $L1_RPC_URL $OPTIMISM_PORTAL_ADDR 'anchorStateRegistry()(address)') - GAME_ADDR=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY_ADDR 'gameImpls(uint32)(address)' $GAME_TYPE) - - echo "Contract addresses:" - echo " Dispute Game Factory: $DISPUTE_GAME_FACTORY_ADDR" - echo " Optimism Portal: $OPTIMISM_PORTAL_ADDR" - echo " Anchor State Registry: $ANCHOR_STATE_REGISTRY_ADDR" - echo " Game Implementation ($GAME_TYPE): $GAME_ADDR" - echo "" - - # Execute transaction and capture output - echo "Setting respected game type to $GAME_TYPE..." - # Use --legacy to force Type 0 transactions, avoiding EIP-1559 gas estimation issues on local testnet - TX_OUTPUT=$(cast send \ - --json \ - --legacy \ - --rpc-url $L1_RPC_URL \ - --private-key $DEPLOYER_PRIVATE_KEY \ - --from $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY) \ - $ANCHOR_STATE_REGISTRY_ADDR \ - 'setRespectedGameType(uint32)' \ - $GAME_TYPE) - - # Extract transaction hash and status - TX_HASH=$(echo "$TX_OUTPUT" | jq -r '.transactionHash // empty') - TX_STATUS=$(echo "$TX_OUTPUT" | jq -r '.status // empty') - - echo "Transaction sent, TX_HASH: $TX_HASH" - - # Check if transaction was successful - if [ "$TX_STATUS" = "0x1" ] || [ "$TX_STATUS" = "1" ]; then - echo " ✅ setRespectedGameType completed successfully" - else - echo " ❌ Transaction failed with status: $TX_STATUS" - echo "Full output: $TX_OUTPUT" - exit 1 - fi -} - -# Function to add game type via Transactor -add_game_type_via_transactor() { - # Check parameter count - if [ $# -ne 5 ]; then - echo "Error: add_game_type_via_transactor requires exactly 5 parameters" - echo "Usage: add_game_type_via_transactor " - echo "Example: add_game_type_via_transactor 2 true 600 1800 0x..." - return 1 - fi - - local GAME_TYPE=$1 - local IS_PERMISSIONED=$2 - local CLOCK_EXTENSION_VAL=$3 - local MAX_CLOCK_DURATION_VAL=$4 - local ABSOLUTE_PRESTATE_VAL=$5 - - echo "=== Adding Game Type $GAME_TYPE via Transactor ===" - echo " Game Type: $GAME_TYPE" - echo " Is Permissioned: $IS_PERMISSIONED" - echo " Clock Extension: $CLOCK_EXTENSION_VAL" - echo " Max Clock Duration: $MAX_CLOCK_DURATION_VAL" - echo "" - - # Get dispute game factory address - DISPUTE_GAME_FACTORY=$(cast call --rpc-url $L1_RPC_URL $SYSTEM_CONFIG_PROXY_ADDRESS 'disputeGameFactory()(address)') - - echo "Debug Info:" - echo " State JSON: $STATE_JSON_PATH" - echo " Dispute Game Factory: $DISPUTE_GAME_FACTORY" - echo " System Config: $SYSTEM_CONFIG_PROXY_ADDRESS" - echo " Proxy Admin: $PROXY_ADMIN" - echo " OPCM: $OPCM_IMPL_ADDRESS" - echo " Transactor: $TRANSACTOR" - echo " RPC URL: $L1_RPC_URL" - echo " Sender: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" - echo "" - - # Retrieve existing permissioned game implementation for parameters - echo "Retrieving permissioned game parameters..." - PERMISSIONED_GAME=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' 1) - echo "Permissioned Game Implementation: $PERMISSIONED_GAME" - - if [ "$PERMISSIONED_GAME" == "0x0000000000000000000000000000000000000000" ]; then - echo "Error: No permissioned game found. Cannot retrieve parameters." - exit 1 - fi - - # Retrieve parameters from existing permissioned game - ABSOLUTE_PRESTATE="$ABSOLUTE_PRESTATE_VAL" - MAX_GAME_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'maxGameDepth()') - SPLIT_DEPTH=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'splitDepth()') - VM=$(cast call --rpc-url $L1_RPC_URL $PERMISSIONED_GAME 'vm()(address)') - - echo "Retrieved parameters:" - echo " Absolute Prestate: $ABSOLUTE_PRESTATE" - echo " Max Game Depth: $MAX_GAME_DEPTH" - echo " Split Depth: $SPLIT_DEPTH" - echo " Clock Extension: $CLOCK_EXTENSION_VAL" - echo " Max Clock Duration: $MAX_CLOCK_DURATION_VAL" - echo " VM: $VM" - echo "" - - # Set constants - INITIAL_BOND='1000000000000000000' # 1 ETH in wei - SALT_MIXER='123' # Unique salt for game type - - echo "Creating addGameType calldata..." - - # Build game type parameters array (simplified) - GAME_PARAMS="[(\"$SALT_MIXER\",$SYSTEM_CONFIG_PROXY_ADDRESS,$PROXY_ADMIN,0x0000000000000000000000000000000000000000,$GAME_TYPE,$ABSOLUTE_PRESTATE,$MAX_GAME_DEPTH,$SPLIT_DEPTH,$CLOCK_EXTENSION_VAL,$MAX_CLOCK_DURATION_VAL,$INITIAL_BOND,$VM,$IS_PERMISSIONED)]" - - echo "Parameters prepared for addGameType" - - # Execute the transaction through Transactor - echo "Executing transaction via Transactor..." - echo "Target: $TRANSACTOR" - echo "From: $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY)" - - # Simplified DELEGATECALL - build calldata first, then call - ADDGAMETYPE_CALLDATA=$(cast calldata 'addGameType((string,address,address,address,uint32,bytes32,uint256,uint256,uint64,uint64,uint256,address,bool)[])' "$GAME_PARAMS") - - # Execute transaction and capture output - # Use --legacy to force Type 0 transactions, avoiding EIP-1559 gas estimation issues on local testnet - TX_OUTPUT=$(cast send \ - --json \ - --legacy \ - --rpc-url $L1_RPC_URL \ - --private-key $DEPLOYER_PRIVATE_KEY \ - --from $(cast wallet address --private-key $DEPLOYER_PRIVATE_KEY) \ - $TRANSACTOR \ - 'DELEGATECALL(address,bytes)' \ - $OPCM_IMPL_ADDRESS \ - $ADDGAMETYPE_CALLDATA) - - # Extract transaction hash and status - TX_HASH=$(echo "$TX_OUTPUT" | jq -r '.transactionHash // empty') - TX_STATUS=$(echo "$TX_OUTPUT" | jq -r '.status // empty') - - echo "" - echo "Transaction sent, TX_HASH: $TX_HASH" - - # Check if transaction was successful - if [ "$TX_STATUS" = "0x1" ] || [ "$TX_STATUS" = "1" ]; then - echo " ✅ Transaction successful!" - else - echo " ❌ Transaction failed with status: $TX_STATUS" - echo "Full output: $TX_OUTPUT" - exit 1 - fi - echo "" - - # Verify the new game type was added - echo "Verifying new game type was added..." - NEW_GAME_IMPL=$(cast call --rpc-url $L1_RPC_URL $DISPUTE_GAME_FACTORY 'gameImpls(uint32)(address)' $GAME_TYPE) - - if [ "$NEW_GAME_IMPL" != "0x0000000000000000000000000000000000000000" ]; then - echo " ✅ Success! New game type $GAME_TYPE added." - echo "Game Type $GAME_TYPE Implementation: $NEW_GAME_IMPL" - else - echo " ❌ Warning: Could not verify game type was added. Check transaction status." - fi - - echo " ✅ AddGameType operations completed successfully" - - # Set the newly added game type as respected - echo "" - set_respected_game_type "$GAME_TYPE" -} - -# Main execution -if [ "${BASH_SOURCE[0]}" == "${0}" ]; then - # Script is being executed directly - call the function - add_game_type_via_transactor "$@" -fi diff --git a/test-pp-op/scripts/deposit-from-banker.sh b/test-pp-op/scripts/deposit-from-banker.sh deleted file mode 100755 index db1e6601efc9f..0000000000000 --- a/test-pp-op/scripts/deposit-from-banker.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -set -e -set -x - -BANKER_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d -BANKER=$(cast wallet a $BANKER_PRIVATE_KEY) - -# Source environment variables -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ENV_FILE="$(dirname "$SCRIPT_DIR")/.env" -source "$ENV_FILE" - -TO_ADDRESS=0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534 -AMOUNT=1000000ether - -cast send $TO_ADDRESS --value $AMOUNT --legacy --rpc-url=$L2_RPC_URL --private-key=$BANKER_PRIVATE_KEY diff --git a/test-pp-op/scripts/deposit-from-l1.sh b/test-pp-op/scripts/deposit-from-l1.sh deleted file mode 100755 index e8cd0edc996fc..0000000000000 --- a/test-pp-op/scripts/deposit-from-l1.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -set -e - -# Source environment variables -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ENV_FILE="$(dirname "$SCRIPT_DIR")/.env" -source "$ENV_FILE" - -OP_PORTAL_ADDRESS=$(jq -r '.opChainDeployments[0].OptimismPortalProxy' config-op/state.json) -PRIVATE_KEY="0x815405dddb0e2a99b12af775fd2929e526704e1d1aea6a0b4e74dc33e2f7fcd2" -ADDRESS=$(cast wallet a $PRIVATE_KEY) #0x8f8E2d6cF621f30e9a11309D6A56A876281Fd534 -ETHER=1000000000000000000 -AMOUNT=$(python3 -c "print(3000 * $ETHER)") -AMOUNT_PLUS_FEE=$(python3 -c "print($AMOUNT + $ETHER)") - -cast send --private-key $RICH_L1_PRIVATE_KEY --value $AMOUNT_PLUS_FEE $ADDRESS --legacy --rpc-url $L1_RPC_URL - -PRE_BALANCE=$(cast balance $ADDRESS --rpc-url=$L2_RPC_URL) - -cast send \ - --legacy \ - --private-key $PRIVATE_KEY \ - --value $AMOUNT \ - $OP_PORTAL_ADDRESS \ - 'function depositTransaction(address _target, uint256 _value, uint64 _gasLimit, bool _isCreation, bytes _data)' \ - $ADDRESS $AMOUNT 100000 false 0x --rpc-url $L1_RPC_URL - -echo " 📋 Initial balance: $PRE_BALANCE" - -START_TIME=$(date +%s) - -while true; do - NEW_BALANCE=$(cast balance $ADDRESS --rpc-url=$L2_RPC_URL) - - if [ "$NEW_BALANCE" != "$PRE_BALANCE" ]; then - CURRENT_TIME=$(date +%s) - ELAPSED_TIME=$((CURRENT_TIME - START_TIME)) - echo " ✅ Balance changed!" - echo " 📋 Previous balance: $PRE_BALANCE" - echo " 📋 New balance: $NEW_BALANCE" - echo " ⏱️ Total wait time: ${ELAPSED_TIME}s" - break - fi - - echo " ⏳ waiting for change..." - sleep 3 -done diff --git a/test-pp-op/scripts/docker-install-start.sh b/test-pp-op/scripts/docker-install-start.sh deleted file mode 100755 index 27177b7171ce4..0000000000000 --- a/test-pp-op/scripts/docker-install-start.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# Install Docker in Docker and start Docker daemon - -# If default (rooted Docker) is used, just exit -if [ "$1" == "default" ]; then - exit 0 -fi - -# Otherwise (rootless Docker): remove docker.io, install and configure Docker in Docker -apt-get update -apt-get remove -y --purge docker.io - -curl -sSL https://get.docker.com/ | sh - -# The code below is taken from: https://github.com/moby/moby/blob/v26.0.1/hack/dind#L59 -# It is used to avoid the error: "docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: unable to apply cgroup configuration: cannot enter cgroupv2 "/sys/fs/cgroup/docker" with domain controllers -- it is in threaded mode: unknown." -# cgroup v2: enable nesting -if [ -f /sys/fs/cgroup/cgroup.controllers ]; then - # move the processes from the root group to the /init group, - # otherwise writing subtree_control fails with EBUSY. - # An error during moving non-existent process (i.e., "cat") is ignored. - mkdir -p /sys/fs/cgroup/init - xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : - # enable controllers - sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \ - > /sys/fs/cgroup/cgroup.subtree_control -fi - -# Start Docker daemon -dockerd > /dockerd.log 2>&1 & diff --git a/test-pp-op/scripts/gray-upgrade-simulation.sh b/test-pp-op/scripts/gray-upgrade-simulation.sh deleted file mode 100755 index 8bdcb60ab32bb..0000000000000 --- a/test-pp-op/scripts/gray-upgrade-simulation.sh +++ /dev/null @@ -1,309 +0,0 @@ -#!/bin/bash - -set -e - -BASE_CONDUCTOR_PORT=8547 -BASE_SEQUENCER_PORT=9545 -CURRENT_LEADER=0 -UPGRADED_SEQUENCER=0 - -# Function to check if a conductor is leader -check_leader() { - local conductor_id=$1 - local port=$((BASE_CONDUCTOR_PORT + conductor_id - 1)) - curl -s -X POST -H "Content-Type: application/json" \ - --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ - http://localhost:$port | jq -r .result -} - -# Function to stop containers -stop_containers() { - local sequencer_id=$1 - echo "Stopping containers for sequencer-$sequencer_id..." - - # Handle sequencer 1 (no suffix) vs others (with suffix) - if [ "$sequencer_id" = "1" ]; then - docker stop op-seq op-geth-seq 2>/dev/null || true - echo "Containers stopped: op-seq, op-geth-seq" - else - docker stop op-seq$sequencer_id op-geth-seq$sequencer_id 2>/dev/null || true - echo "Containers stopped: op-seq$sequencer_id, op-geth-seq$sequencer_id" - fi -} - -# Function to start containers -start_containers() { - local sequencer_id=$1 - echo "Starting containers for sequencer-$sequencer_id..." - - # Handle sequencer 1 (no suffix) vs others (with suffix) - if [ "$sequencer_id" = "1" ]; then - docker start op-seq op-geth-seq 2>/dev/null || true - echo "Containers started: op-seq, op-geth-seq" - else - docker start op-seq$sequencer_id op-geth-seq$sequencer_id 2>/dev/null || true - echo "Containers started: op-seq$sequencer_id, op-geth-seq$sequencer_id" - fi -} - -# Function to wait for service to be ready -wait_for_service() { - local port=$1 - local service_name=$2 - local max_attempts=30 - local attempt=0 - - echo "Waiting for $service_name to be ready on port $port..." - while [ $attempt -lt $max_attempts ]; do - if curl -s http://localhost:$port > /dev/null 2>&1; then - echo "$service_name is ready" - return 0 - fi - sleep 1 - ((attempt++)) - done - echo "Warning: $service_name not ready after $max_attempts seconds" - return 1 -} - -# Function to find current leader -find_current_leader() { - for i in {0..2}; do - local port=$((BASE_CONDUCTOR_PORT + i)) - local is_leader=$(check_leader $((i+1))) - - if [ "$is_leader" = "true" ]; then - CURRENT_LEADER=$((i+1)) - echo "conductor-$CURRENT_LEADER is current leader (port $port)" - return 0 - fi - done - echo "No leader found!" - return 1 -} - -# Function to extract block info from sequencer logs -extract_last_block_info() { - local sequencer_id=$1 - - # Handle sequencer 1 (no suffix) vs others (with suffix) - local container_name - if [ "$sequencer_id" = "1" ]; then - container_name="op-seq" - else - container_name="op-seq$sequencer_id" - fi - - echo "Extracting last block info from $container_name..." >&2 - - # Get the last "Sequencer inserted block" log entry - local last_block_log=$(docker logs $container_name 2>&1 | grep "Sequencer inserted block" | tail -1) - - if [ -z "$last_block_log" ]; then - echo "❌ No 'Sequencer inserted block' log found in $container_name" >&2 - return 1 - fi - - echo "Last block log: $last_block_log" >&2 - - # Extract block hash and number using regex - if [[ $last_block_log =~ block=([^[:space:]]+) ]]; then - local block_info="${BASH_REMATCH[1]}" - echo "Block info: $block_info" >&2 - - # Split block hash and number (format: hash:number) - if [[ $block_info =~ ^([^:]+):([0-9]+)$ ]]; then - local block_hash="${BASH_REMATCH[1]}" - local block_number="${BASH_REMATCH[2]}" - echo "Extracted - Block Hash: $block_hash, Block Number: $block_number" >&2 - echo "$block_hash:$block_number" - return 0 - else - echo "❌ Failed to parse block info format: $block_info" >&2 - return 1 - fi - else - echo "❌ Failed to extract block info from log: $last_block_log" >&2 - return 1 - fi -} - -# Function to check if new leader continues from previous block -check_block_continuity() { - local prev_sequencer_id=$1 - local new_sequencer_id=$2 - local prev_block_info=$3 - - echo "Checking block continuity from sequencer-$prev_sequencer_id to sequencer-$new_sequencer_id..." - echo "Previous block info: $prev_block_info" - - # Parse previous block info - local prev_block_hash=$(echo "$prev_block_info" | cut -d':' -f1) - local prev_block_number=$(echo "$prev_block_info" | cut -d':' -f2) - - echo "Looking for block with parent=$prev_block_hash:$prev_block_number in sequencer-$new_sequencer_id..." - - # Check if new sequencer has a block with the previous block as parent - local container_name - if [ "$new_sequencer_id" = "1" ]; then - container_name="op-seq" - else - container_name="op-seq$new_sequencer_id" - fi - local continuity_log=$(docker logs $container_name 2>&1 | grep "Sequencer inserted block" | grep "parent=$prev_block_hash:$prev_block_number" | tail -1) - - if [ -n "$continuity_log" ]; then - echo "✅ Block continuity verified!" - echo "Continuity log: $continuity_log" - - # Extract the new block info - if [[ $continuity_log =~ block=([^[:space:]]+) ]]; then - local new_block_info="${BASH_REMATCH[1]}" - echo "New block info: $new_block_info" - return 0 - fi - else - echo "❌ Block continuity check failed - no block found with parent=$prev_block_hash:$prev_block_number" - return 1 - fi -} - -# Function to transfer leadership -transfer_leadership() { - local from_conductor=$1 - local to_conductor=$2 - local from_port=$((BASE_CONDUCTOR_PORT + from_conductor - 1)) - - # Build target conductor address - local target_addr="op-conductor" - [ "$to_conductor" != "1" ] && target_addr="${target_addr}${to_conductor}" - target_addr="${target_addr}:50050" - - echo "Transferring leadership from conductor-$from_conductor to conductor-$to_conductor..." - curl -s -X POST -H "Content-Type: application/json" \ - --data "{\"jsonrpc\":\"2.0\",\"method\":\"conductor_transferLeaderToServer\",\"params\":[\"conductor-$to_conductor\", \"$target_addr\"],\"id\":1}" \ - http://localhost:$from_port > /dev/null - echo "Leadership transfer command sent" -} - -echo "=== Starting Gray Upgrade Simulation ===" - -# Step 1: Find current leader -echo "Step 1: Finding current leader..." -if ! find_current_leader; then - echo "Error: No leader found, exiting" - exit 1 -fi - -# Step 2: Select a follower sequencer for upgrade -echo "Step 2: Selecting a follower sequencer for upgrade..." -# Find a follower (non-leader) sequencer to upgrade -UPGRADED_SEQUENCER=0 -for i in {1..3}; do - if [ "$i" != "$CURRENT_LEADER" ]; then - UPGRADED_SEQUENCER=$i - echo "Selected sequencer-$UPGRADED_SEQUENCER for upgrade (current leader is sequencer-$CURRENT_LEADER)" - break - fi -done - -if [ "$UPGRADED_SEQUENCER" -eq 0 ]; then - echo "Error: No follower sequencer found for upgrade" - exit 1 -fi - -# Step 3: Stop containers for the selected follower sequencer -echo "Step 3: Stopping containers for sequencer-$UPGRADED_SEQUENCER (simulating shutdown for upgrade)..." -stop_containers $UPGRADED_SEQUENCER - -# Step 4: Wait 10 seconds (simulating upgrade time) -echo "Step 4: Waiting 10 seconds for upgrade simulation..." -sleep 10 - -# Step 5: Restart containers -echo "Step 5: Restarting containers for sequencer-$UPGRADED_SEQUENCER (simulating post-upgrade restart)..." -start_containers $UPGRADED_SEQUENCER - -# Step 6: Wait for services to be ready -echo "Step 6: Waiting for services to be ready..." -wait_for_service $((BASE_SEQUENCER_PORT + UPGRADED_SEQUENCER - 1)) "op-seq$UPGRADED_SEQUENCER" -wait_for_service $((BASE_CONDUCTOR_PORT + UPGRADED_SEQUENCER - 1)) "op-conductor$UPGRADED_SEQUENCER" - -# Step 7: Verify the upgraded sequencer is inactive -echo "Step 7: Verifying upgraded sequencer is inactive..." -sleep 5 # Give it time to sync -is_leader_after_restart=$(check_leader $UPGRADED_SEQUENCER) - -if [ "$is_leader_after_restart" = "false" ]; then - echo "✅ Verified: Upgraded sequencer-$UPGRADED_SEQUENCER is inactive (not leader)" -else - echo "❌ Error: Upgraded sequencer-$UPGRADED_SEQUENCER is unexpectedly still leader" - exit 1 -fi -# Step 8: Wait for the upgraded sequencer to sync with latest blocks -echo "Step 8: Waiting 30 seconds for upgraded sequencer to sync with latest blocks..." -sleep 30 - -# Step 9: Find current leader and transfer leadership -echo "Step 9: Finding current leader and transferring leadership to upgraded sequencer..." -if ! find_current_leader; then - echo "Error: No current leader found for transfer" - exit 1 -fi - -if [ "$CURRENT_LEADER" = "$UPGRADED_SEQUENCER" ]; then - echo "✅ Upgraded sequencer-$UPGRADED_SEQUENCER is already the leader, no transfer needed" -else - echo "Current leader is conductor-$CURRENT_LEADER, transferring to conductor-$UPGRADED_SEQUENCER" - - # Transfer leadership to the upgraded sequencer - transfer_leadership $CURRENT_LEADER $UPGRADED_SEQUENCER - - # Verify the transfer was successful - sleep 2 - echo "Verifying leadership transfer..." - is_transfer_successful=$(check_leader $UPGRADED_SEQUENCER) - if [ "$is_transfer_successful" = "true" ]; then - echo "✅ Leadership transfer successful: conductor-$CURRENT_LEADER -> conductor-$UPGRADED_SEQUENCER" - - # Extract block info from previous leader AFTER transfer is confirmed - echo "Extracting block info from previous leader (sequencer-$CURRENT_LEADER) after final transfer..." - if ! CURRENT_BLOCK_INFO=$(extract_last_block_info $CURRENT_LEADER); then - echo "Warning: Could not extract block info from sequencer-$CURRENT_LEADER, continuing without continuity check" - CURRENT_BLOCK_INFO="" - fi - - # Check block continuity if we have current block info - if [ -n "$CURRENT_BLOCK_INFO" ]; then - echo "Checking block continuity after leadership transfer..." - sleep 3 # Give some time for upgraded sequencer to produce blocks - if check_block_continuity $CURRENT_LEADER $UPGRADED_SEQUENCER "$CURRENT_BLOCK_INFO"; then - echo "✅ Block continuity verified after leadership transfer" - else - echo "⚠️ Block continuity check failed after transfer, but upgrade simulation continues" - fi - fi - else - echo "❌ Leadership transfer failed, trying to find current leader..." - if find_current_leader; then - echo "Current leader is now conductor-$CURRENT_LEADER" - else - echo "Error: No leader found after transfer attempt" - exit 1 - fi - fi -fi - -# Step 10: Final verification -echo "Step 10: Final verification of upgraded sequencer leadership..." -sleep 1 - -is_leader_final=$(check_leader $UPGRADED_SEQUENCER) -if [ "$is_leader_final" = "true" ]; then - echo "✅ SUCCESS: Upgraded sequencer-$UPGRADED_SEQUENCER is now the leader!" - echo "=== Gray Upgrade Simulation Completed Successfully ===" -else - echo "❌ FAILED: Upgraded sequencer-$UPGRADED_SEQUENCER did not become leader" - echo "Final leader status: $is_leader_final" - exit 1 -fi diff --git a/test-pp-op/scripts/replace-genesis.sh b/test-pp-op/scripts/replace-genesis.sh deleted file mode 100755 index e7817d13ae47f..0000000000000 --- a/test-pp-op/scripts/replace-genesis.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -set -e - -sed_inplace() { - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' "$@" - else - sed -i "$@" - fi -} - -ROOT_DIR=$(git rev-parse --show-toplevel) - -# TODO: change to the real location of genesis file -NEW_GENESIS_FILE="$ROOT_DIR/../genesis.json" - -TESTING_GENESIS_FILE="$ROOT_DIR/test/config-op/genesis.json" - -if [ -f ${TESTING_GENESIS_FILE} ]; then - mv ${TESTING_GENESIS_FILE} ${TESTING_GENESIS_FILE}.bak -fi - -cp ${NEW_GENESIS_FILE} ${TESTING_GENESIS_FILE} - -current_timestamp=$(date +%s) -hex_timestamp=$(printf "0x%x\n" "$current_timestamp") -echo "hex_timestamp: $hex_timestamp" - -sed_inplace "s/\"timestamp\": \"0x[0-9a-fA-F]*\"/\"timestamp\": \"$hex_timestamp\"/" ${TESTING_GENESIS_FILE} diff --git a/test-pp-op/scripts/set-init-bond.sh b/test-pp-op/scripts/set-init-bond.sh deleted file mode 100755 index cac10d0149acf..0000000000000 --- a/test-pp-op/scripts/set-init-bond.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/bin/bash - -set -e - -# Function to display usage -usage() { - echo "Usage: $0 [OPTIONS]" - echo "Options:" - echo " --game-type TYPE Game type (uint32) (required)" - echo " --init-bond WEI Initial bond amount in wei (required)" - echo " --transactor ADDRESS Transactor contract address (required)" - echo " --dispute-game-factory ADDRESS DisputeGameFactory contract address (required)" - echo " --private-key KEY Private key for transaction (required)" - echo " --rpc-url URL RPC URL (required)" - echo " --help Show this help message" - echo "" - echo "Example:" - echo " $0 --game-type 1 --init-bond 1000000000000000000 --transactor 0x456... --dispute-game-factory 0xabc... --private-key 0xdef... --rpc-url https://..." - exit 1 -} - -# Parse command line arguments -while [[ $# -gt 0 ]]; do - case $1 in - --game-type) - GAME_TYPE="$2" - shift 2 - ;; - --init-bond) - INIT_BOND="$2" - shift 2 - ;; - --transactor) - TRANSACTOR_ADDRESS="$2" - shift 2 - ;; - --dispute-game-factory) - DISPUTE_GAME_FACTORY="$2" - shift 2 - ;; - --private-key) - PRIVATE_KEY="$2" - shift 2 - ;; - --rpc-url) - RPC_URL="$2" - shift 2 - ;; - --help) - usage - ;; - *) - echo "Unknown option: $1" - usage - ;; - esac -done - -# Validate required parameters -if [[ -z "$GAME_TYPE" || -z "$INIT_BOND" || -z "$TRANSACTOR_ADDRESS" || -z "$DISPUTE_GAME_FACTORY" || -z "$PRIVATE_KEY" || -z "$RPC_URL" ]]; then - echo "Error: Missing required parameters" - echo "" - usage -fi - -echo "=== Setting Init Bond via Transactor ===" -echo "Game Type: $GAME_TYPE" -echo "Init Bond: $INIT_BOND wei" -echo "Dispute Game Factory: $DISPUTE_GAME_FACTORY" -echo "Transactor Address: $TRANSACTOR_ADDRESS" -echo "RPC URL: $RPC_URL" -echo "" - -# Get sender address from private key -SENDER_ADDRESS=$(cast wallet address --private-key $PRIVATE_KEY) -echo "Sender Address: $SENDER_ADDRESS" -echo "" - -# Check if game type exists -echo "Checking if game type exists..." -GAME_IMPL=$(cast call --rpc-url $RPC_URL $DISPUTE_GAME_FACTORY "gameImpls(uint32)(address)" $GAME_TYPE) -echo "Game Type $GAME_TYPE Implementation: $GAME_IMPL" - -if [ "$GAME_IMPL" == "0x0000000000000000000000000000000000000000" ]; then - echo "Error: Game type $GAME_TYPE does not exist. Cannot set init bond." - exit 1 -fi - -# Get current init bond for comparison -echo "Retrieving current init bond..." -CURRENT_INIT_BOND_RAW=$(cast call --rpc-url $RPC_URL $DISPUTE_GAME_FACTORY "initBonds(uint32)(uint256)" $GAME_TYPE) -CURRENT_INIT_BOND=$(echo $CURRENT_INIT_BOND_RAW | sed 's/\[.*\]//' | xargs) -echo "Current Init Bond: $CURRENT_INIT_BOND wei" - -if [ "$CURRENT_INIT_BOND" == "$INIT_BOND" ]; then - echo "Warning: New init bond is the same as current init bond. No change needed." - exit 0 -fi - -echo "Creating setInitBond calldata..." -echo "Game Type: $GAME_TYPE" -echo "New Init Bond: $INIT_BOND wei" - -# Create calldata for setInitBond function -SETINITBOND_CALLDATA=$(cast calldata "setInitBond(uint32,uint256)" $GAME_TYPE $INIT_BOND) - -echo "SetInitBond calldata: $SETINITBOND_CALLDATA" -echo "" - -# Create calldata for Transactor's DELEGATECALL function -echo "Creating Transactor CALL calldata..." -TRANSACTOR_CALLDATA=$(cast calldata "CALL(address,bytes,uint256)" $DISPUTE_GAME_FACTORY $SETINITBOND_CALLDATA 0) - -echo "Transactor calldata: $TRANSACTOR_CALLDATA" -echo "" - -# Execute the transaction through Transactor -echo "Executing transaction via Transactor..." -echo "Target: $TRANSACTOR_ADDRESS" -echo "From: $SENDER_ADDRESS" - -cast send \ - --rpc-url $RPC_URL \ - --private-key $PRIVATE_KEY \ - --from $SENDER_ADDRESS \ - $TRANSACTOR_ADDRESS \ - $TRANSACTOR_CALLDATA \ - --json |jq - -echo "" -echo "Transaction sent! Check the transaction hash above for confirmation." -echo "" - -# Verify the init bond was updated -echo "Verifying init bond was updated..." -NEW_INIT_BOND=$(cast call --rpc-url $RPC_URL $DISPUTE_GAME_FACTORY "initBonds(uint32)(uint256)" $GAME_TYPE) - -# Extract the numeric value from the response (remove scientific notation and trim spaces) -NEW_INIT_BOND_NUMERIC=$(echo $NEW_INIT_BOND | sed 's/\[.*\]//' | xargs) - -if [ "$NEW_INIT_BOND_NUMERIC" == "$INIT_BOND" ]; then - echo "✅ Success! Init bond updated successfully." - echo "Previous Init Bond: $CURRENT_INIT_BOND wei" - echo "Game Type $GAME_TYPE Init Bond updated to: $NEW_INIT_BOND_NUMERIC wei" -else - echo "❌ Warning: Init bond was not updated as expected." - echo "Expected: $INIT_BOND wei" - echo "Actual: $NEW_INIT_BOND_NUMERIC wei" -fi - -echo "" -echo "Script completed." diff --git a/test-pp-op/scripts/show-dev-accounts.sh b/test-pp-op/scripts/show-dev-accounts.sh deleted file mode 100755 index 40f4346e5b25b..0000000000000 --- a/test-pp-op/scripts/show-dev-accounts.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -echo "=== Optimism dev accounts ===" -echo "mnemonic: test test test test test test test test test test test junk" -echo "" - -for i in {0..29}; do - echo "path $i: m/44'/60'/0'/0/$i" - - private_key=$(cast wallet private-key --mnemonic "test test test test test test test test test test test junk" --mnemonic-derivation-path "m/44'/60'/0'/0/$i") - - address=$(cast wallet address --private-key "$private_key") - - echo "address: $address" - echo "private key: $private_key" - echo "---" -done diff --git a/test-pp-op/scripts/stop-leader-sequencer.sh b/test-pp-op/scripts/stop-leader-sequencer.sh deleted file mode 100755 index 99912e828fbaf..0000000000000 --- a/test-pp-op/scripts/stop-leader-sequencer.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -BASE_PORT=8547 -LEADER_PORT=0 -OLD_LEADER=0 - -# Find current leader -for i in {0..2}; do - PORT=$((BASE_PORT + i)) - IS_LEADER=$(curl -s -X POST -H "Content-Type: application/json" \ - --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ - http://localhost:$PORT | jq -r .result) - - if [ "$IS_LEADER" = "true" ]; then - LEADER_PORT=$PORT - OLD_LEADER=$((i+1)) - echo "conductor-$OLD_LEADER is current leader (port $PORT)" - break - fi -done - -# Stop leader's sequencer -if [ "$LEADER_PORT" != "0" ]; then - SEQUENCER_PORT=$((9545 + OLD_LEADER -1)) - curl -sS -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' http://localhost:$SEQUENCER_PORT > /dev/null - echo "sequencer stopped, waiting for leader transfer..." - - # Wait and check for leader change every second - echo "Waiting for leader transfer..." - MAX_SECONDS=10 - for ((second=1; second<=MAX_SECONDS; second++)); do - sleep 1 - NEW_LEADER=0 - for i in {0..2}; do - PORT=$((BASE_PORT + i)) - IS_LEADER=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' http://localhost:$PORT | jq -r .result) - if [ "$IS_LEADER" = "true" ]; then - NEW_LEADER=$((i+1)) - if [ "$NEW_LEADER" != "$OLD_LEADER" ]; then - echo "Leadership transferred: conductor-$OLD_LEADER -> conductor-$NEW_LEADER in (${second}s)" - exit 0 - fi - fi - done - done - echo "Warning: Leader transfer not detected after $MAX_SECONDS seconds" -fi diff --git a/test-pp-op/scripts/transfer-leader.sh b/test-pp-op/scripts/transfer-leader.sh deleted file mode 100755 index ef1a34eeb3f73..0000000000000 --- a/test-pp-op/scripts/transfer-leader.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -BASE_PORT=8547 -LEADER_PORT=0 -OLD_LEADER=0 - -# Find leader -for i in {0..2}; do - PORT=$((BASE_PORT + i)) - IS_LEADER=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' http://localhost:$PORT | jq -r .result) - if [ "$IS_LEADER" = "true" ]; then - LEADER_PORT=$PORT - OLD_LEADER=$((i+1)) - echo "conductor-$OLD_LEADER is leader (port $PORT)" - break - fi -done - -# Transfer leadership -if [ "$LEADER_PORT" != "0" ]; then - echo "Transferring leadership..." - if [ -n "$1" ] && [ "$1" -ge 1 ] && [ "$1" -le 3 ]; then - # Transfer to specific node - TARGET_NUM=$1 - # Check if target is current leader - if [ "$TARGET_NUM" = "$OLD_LEADER" ]; then - echo "Error: conductor-$TARGET_NUM is already the leader" - exit 1 - fi - ADDR="op-conductor" - [ "$TARGET_NUM" != "1" ] && ADDR="${ADDR}${TARGET_NUM}" - curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_transferLeaderToServer","params":["conductor-'$TARGET_NUM'", "'$ADDR':50050"],"id":1}' http://localhost:$LEADER_PORT >/dev/null - # Check if leader transferred to target node - sleep 1 - NEW_LEADER=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' http://localhost:$((BASE_PORT + TARGET_NUM - 1)) | jq -r .result) - if [ "$NEW_LEADER" = "true" ]; then - echo "Leadership transferred: conductor-$OLD_LEADER -> conductor-$TARGET_NUM" - else - echo "Failed to transfer leadership from conductor-$OLD_LEADER to conductor-$TARGET_NUM" - fi - else - # Auto select target node - curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"conductor_transferLeader","params":[],"id":1}' http://localhost:$LEADER_PORT > /dev/null - # Find new leader - sleep 1 - echo "Checking new leader..." - for i in {0..2}; do - PORT=$((BASE_PORT + i)) - IS_LEADER=$(curl -s -X POST -H "Content-Type: application/json" \ - --data '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ - http://localhost:$PORT | jq -r .result) - - if [ "$IS_LEADER" = "true" ]; then - echo "Leadership transferred: conductor-$OLD_LEADER -> conductor-$((i+1))" - break - fi - done - fi -fi diff --git a/test-pp-op/tools.sh b/test-pp-op/tools.sh deleted file mode 100644 index b3f3f6c7bb9a1..0000000000000 --- a/test-pp-op/tools.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# Strict mode: exit on command failure or undefined variable -set -eu - -# ============================================================================= -# This script performs checks tools required in linux/mac -# ============================================================================= - -# Check if jq is available for JSON parsing -if ! command -v jq >/dev/null 2>&1; then - echo "❌ jq is required but not installed. Please install jq to parse JSON config files." - exit 1 -fi - -# check md5sum -if [[ "$OSTYPE" == "darwin"* ]]; then - MD5SUM_CMD=md5 -else - MD5SUM_CMD=md5sum -fi - -if [ "$ENV" = "local" ]; then - COMPOSE_FILE=docker-compose-local.yml -else - COMPOSE_FILE=docker-compose.yml -fi - -echo "COMPOSE_FILE: ${COMPOSE_FILE}" -DOCKER_COMPOSE=$(docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose") -DOCKER_COMPOSE_CMD="${DOCKER_COMPOSE} -f ${COMPOSE_FILE}" -echo "DOCKER_COMPOSE_CMD: ${DOCKER_COMPOSE_CMD}" diff --git a/test-pp-op/utils.sh b/test-pp-op/utils.sh deleted file mode 100644 index 80eaaaf03b246..0000000000000 --- a/test-pp-op/utils.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -set -e - -# init-erigon.sh runs outside the container. -ROOT_DIR=$(which git &>/dev/null && git rev-parse --show-toplevel || echo "/data") -PWD_DIR="$(pwd)" -TMP_DIR="$PWD_DIR/tmp" - -sed_inplace() { - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' "$@" - else - sed -i "$@" - fi -} From 61f2ae8d705377aaca58505f3a4c788e7e0078c9 Mon Sep 17 00:00:00 2001 From: "jason.huang" <20609724+doutv@users.noreply.github.com> Date: Thu, 6 Nov 2025 14:14:26 +0800 Subject: [PATCH 26/26] remove unused --- test-pp-op/contracts/Transactor.sol | 51 ----------------------------- 1 file changed, 51 deletions(-) delete mode 100644 test-pp-op/contracts/Transactor.sol diff --git a/test-pp-op/contracts/Transactor.sol b/test-pp-op/contracts/Transactor.sol deleted file mode 100644 index e193db31e024f..0000000000000 --- a/test-pp-op/contracts/Transactor.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -// Contracts -import { Owned } from "@rari-capital/solmate/src/auth/Owned.sol"; - -/// @title Transactor -/// @notice Transactor is a minimal contract that can send transactions. -contract Transactor is Owned { - /// @param _owner Initial contract owner. - constructor(address _owner) Owned(_owner) { } - - /// @notice Sends a CALL to a target address. - /// @param _target Address to call. - /// @param _data Data to send with the call. - /// @param _value ETH value to send with the call. - /// @return success_ Boolean success value. - /// @return data_ Bytes data returned by the call. - function CALL( - address _target, - bytes memory _data, - uint256 _value - ) - external - payable - onlyOwner - returns (bool success_, bytes memory data_) - { - (success_, data_) = _target.call{ value: _value }(_data); - require(success_, "Transactor: CALL failed"); - } - - /// @notice Sends a DELEGATECALL to a target address. - /// @param _target Address to call. - /// @param _data Data to send with the call. - /// @return success_ Boolean success value. - /// @return data_ Bytes data returned by the call. - function DELEGATECALL( - address _target, - bytes memory _data - ) - external - payable - onlyOwner - returns (bool success_, bytes memory data_) - { - // slither-disable-next-line controlled-delegatecall - (success_, data_) = _target.delegatecall(_data); - require(success_, "Transactor: DELEGATECALL failed"); - } -}