From 0d7be3fe841166ab2b52428eda8448615c0660db Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 26 Nov 2025 11:12:34 +0800 Subject: [PATCH 1/9] update --- .gitignore | 1 + devnet/3-op-init.sh | 178 ++++++++- devnet/MAINNET_GENESIS_GUIDE.md | 339 ++++++++++++++++++ devnet/MAINNET_GENESIS_QUICKSTART.md | 110 ++++++ devnet/example.env | 20 ++ .../process-mainnet-genesis.cpython-314.pyc | Bin 0 -> 7546 bytes devnet/scripts/process-mainnet-genesis.py | 174 +++++++++ devnet/scripts/test-mainnet-genesis.sh | 183 ++++++++++ devnet/scripts/verify-mainnet-setup.sh | 218 +++++++++++ 9 files changed, 1213 insertions(+), 10 deletions(-) create mode 100644 devnet/MAINNET_GENESIS_GUIDE.md create mode 100644 devnet/MAINNET_GENESIS_QUICKSTART.md create mode 100644 devnet/scripts/__pycache__/process-mainnet-genesis.cpython-314.pyc create mode 100755 devnet/scripts/process-mainnet-genesis.py create mode 100755 devnet/scripts/test-mainnet-genesis.sh create mode 100755 devnet/scripts/verify-mainnet-setup.sh diff --git a/.gitignore b/.gitignore index 3490453..4ce5a33 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ devnet/saved-cannon-data devnet/init.log devnet/l1-geth/ profiling/ +devnet/test-pp-op \ No newline at end of file diff --git a/devnet/3-op-init.sh b/devnet/3-op-init.sh index 874350d..818ca75 100755 --- a/devnet/3-op-init.sh +++ b/devnet/3-op-init.sh @@ -12,6 +12,125 @@ sed_inplace() { fi } +# ======================================== +# Genesis Mode Detection +# ======================================== +detect_genesis_mode() { + if [ "$USE_MAINNET_GENESIS" = "true" ]; then + echo "🌐 Mainnet genesis mode enabled" + + # Enforce MIN_RUN requirement + if [ "$MIN_RUN" != "true" ]; then + echo "" + echo "❌ ERROR: Mainnet genesis requires MIN_RUN=true" + echo "" + echo "Reason:" + echo " • Mainnet genesis is too large (6.6GB+)" + echo " • Building op-program prestate would fail or timeout" + echo " • Dispute game features are not compatible with mainnet data" + echo "" + echo "Solution:" + echo " Set MIN_RUN=true in your .env file" + echo "" + exit 1 + fi + + echo "✅ MIN_RUN=true verified" + return 0 + else + echo "🔧 Using generated genesis mode" + return 1 + fi +} + +# ======================================== +# Prepare Mainnet Genesis +# ======================================== +prepare_mainnet_genesis() { + echo "" + echo "📦 Preparing mainnet genesis..." + + PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + + # Check if genesis file exists + if [ ! -f "$MAINNET_GENESIS_PATH" ]; then + echo "🔍 Genesis not found at: $MAINNET_GENESIS_PATH" + + # Try to extract from tar.gz + TAR_PATH="../rpc-setup/genesis-mainnet.tar.gz" + if [ -f "$TAR_PATH" ]; then + echo "📂 Extracting from $TAR_PATH..." + echo "⏳ This may take 2-5 minutes (1.6GB → 6.6GB)..." + + tar -xzf "$TAR_PATH" -C "$PWD_DIR" + + if [ -f "$PWD_DIR/merged.genesis.json" ]; then + mv "$PWD_DIR/merged.genesis.json" "$MAINNET_GENESIS_PATH" + echo "✅ Extracted successfully" + else + echo "❌ ERROR: Extraction failed (merged.genesis.json not found)" + exit 1 + fi + else + echo "❌ ERROR: Neither genesis file nor tar.gz found" + echo " Looking for:" + echo " - $MAINNET_GENESIS_PATH" + echo " - $TAR_PATH" + exit 1 + fi + fi + + # Verify file + GENESIS_SIZE_MB=$(du -m "$MAINNET_GENESIS_PATH" | cut -f1) + GENESIS_SIZE_GB=$(echo "scale=2; $GENESIS_SIZE_MB / 1024" | bc) + echo "✅ Found mainnet genesis ($GENESIS_SIZE_GB GB)" + + # Validate configuration + if [ -z "$FORK_BLOCK" ] || [ -z "$PARENT_HASH" ]; then + echo "❌ ERROR: FORK_BLOCK and PARENT_HASH must be set" + exit 1 + fi + + NEXT_BLOCK=$((FORK_BLOCK + 1)) + echo "🎯 Fork configuration:" + echo " • FORK_BLOCK: $FORK_BLOCK" + echo " • PARENT_HASH: $PARENT_HASH" + echo " • Next block: $NEXT_BLOCK" + + # Process genesis using Python (fast) + echo "" + echo "🔧 Processing genesis (this may take 1-2 minutes)..." + + mkdir -p "$CONFIG_DIR" + + # Prepare arguments + PROCESS_ARGS=( + "$MAINNET_GENESIS_PATH" + "$CONFIG_DIR/genesis.json" + "$NEXT_BLOCK" + "$PARENT_HASH" + ) + + # Add test account injection if enabled + if [ "$INJECT_L2_TEST_ACCOUNT" = "true" ]; then + echo "💰 Test account injection enabled" + PROCESS_ARGS+=("$TEST_ACCOUNT_ADDRESS" "$TEST_ACCOUNT_BALANCE") + fi + + # Run Python script + if ! python3 scripts/process-mainnet-genesis.py "${PROCESS_ARGS[@]}"; then + echo "❌ ERROR: Failed to process mainnet genesis" + exit 1 + fi + + echo "" + echo "✅ Mainnet genesis prepared" + echo " • Output: $CONFIG_DIR/genesis.json" + echo " • Reth version: $CONFIG_DIR/genesis-reth.json" + echo " • Accounts: $(python3 -c "import json; print(len(json.load(open('$CONFIG_DIR/genesis.json'))['alloc']))")" + echo "" +} + # Check if FORK_BLOCK is set if [ -z "$FORK_BLOCK" ]; then echo " ❌ FORK_BLOCK environment variable is not set" @@ -19,15 +138,29 @@ if [ -z "$FORK_BLOCK" ]; then exit 1 fi -FORK_BLOCK_HEX=$(printf "0x%x" "$FORK_BLOCK") -sed_inplace '/"config": {/,/}/ s/"optimism": {/"legacyXLayerBlock": '"$((FORK_BLOCK + 1))"',\n "optimism": {/' ./config-op/genesis.json -sed_inplace 's/"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"/"parentHash": "'"$PARENT_HASH"'"/' ./config-op/genesis.json -sed_inplace '/"70997970c51812dc3a010c7d01b50e0d17dc79c8": {/,/}/ s/"balance": "[^"]*"/"balance": "0x446c3b15f9926687d2c40534fdb564000000000000"/' ./config-op/genesis.json -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-reth.json -sed_inplace 's/"number": "0x0"/"number": "'"$NEXT_BLOCK_NUMBER_HEX"'"/' ./config-op/genesis-reth.json +# ======================================== +# Genesis Processing - Mode Selection +# ======================================== +if detect_genesis_mode; then + # Mainnet genesis mode + prepare_mainnet_genesis + + # Update rollup.json + NEXT_BLOCK_NUMBER=$((FORK_BLOCK + 1)) + sed_inplace 's/"number": 0/"number": '"$NEXT_BLOCK_NUMBER"'/' ./config-op/rollup.json + +else + # Generated genesis mode (original logic) + FORK_BLOCK_HEX=$(printf "0x%x" "$FORK_BLOCK") + sed_inplace '/"config": {/,/}/ s/"optimism": {/"legacyXLayerBlock": '"$((FORK_BLOCK + 1))"',\n "optimism": {/' ./config-op/genesis.json + sed_inplace 's/"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"/"parentHash": "'"$PARENT_HASH"'"/' ./config-op/genesis.json + sed_inplace '/"70997970c51812dc3a010c7d01b50e0d17dc79c8": {/,/}/ s/"balance": "[^"]*"/"balance": "0x446c3b15f9926687d2c40534fdb564000000000000"/' ./config-op/genesis.json + 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-reth.json + sed_inplace 's/"number": "0x0"/"number": "'"$NEXT_BLOCK_NUMBER_HEX"'"/' ./config-op/genesis-reth.json +fi # Extract contract addresses from state.json and update .env file echo "🔧 Extracting contract addresses from state.json..." @@ -202,8 +335,33 @@ gzip -c config-op/genesis.json > config-op/genesis.json.gz # Check if MIN_RUN mode is enabled if [ "$MIN_RUN" = "true" ]; then + echo "" echo "⚡ MIN_RUN mode enabled: Skipping op-program prestate build" - echo "✅ Initialization completed for minimal run (no dispute game support)" + + # Show mainnet-specific summary + if [ "$USE_MAINNET_GENESIS" = "true" ]; then + echo "" + echo "🌐 Mainnet Genesis Deployment Summary:" + echo " • Source: $MAINNET_GENESIS_PATH" + echo " • Starting block: $((FORK_BLOCK + 1))" + echo " • Genesis size: $(du -h $CONFIG_DIR/genesis.json | cut -f1)" + + if [ "$INJECT_L2_TEST_ACCOUNT" = "true" ]; then + echo " • Test account: $TEST_ACCOUNT_ADDRESS (injected)" + BALANCE_ETH=$(python3 -c "print(int('$TEST_ACCOUNT_BALANCE', 16) / 10**18)") + echo " • Test balance: $BALANCE_ETH ETH on L2" + fi + + echo " • Database: $(du -sh data/op-$SEQ_TYPE-seq 2>/dev/null | cut -f1 || echo 'initializing...')" + echo "" + echo "ℹ️ Notes:" + echo " • All mainnet accounts preserved in L2 genesis" + echo " • L1 accounts funded by 1-start-l1.sh (100 ETH each)" + echo " • Dispute game features skipped (not compatible with mainnet data)" + fi + + echo "" + echo "✅ Initialization completed for minimal run" exit 0 fi diff --git a/devnet/MAINNET_GENESIS_GUIDE.md b/devnet/MAINNET_GENESIS_GUIDE.md new file mode 100644 index 0000000..41d484a --- /dev/null +++ b/devnet/MAINNET_GENESIS_GUIDE.md @@ -0,0 +1,339 @@ +# Mainnet Genesis 部署指南 + +本指南说明如何使用主网 genesis 数据部署 OP Stack devnet 环境。 + +## 📋 功能特性 + +- ✅ 使用真实主网 genesis 数据(6.6GB+) +- ✅ 保留所有主网账户和合约状态 +- ✅ 自动注入测试账户到 L2 genesis(可选) +- ✅ 高性能 Python 脚本处理大 JSON(比 jq 快 5-10 倍) +- ✅ 低耦合设计,最小化对现有代码的修改 +- ✅ MIN_RUN 模式强制保障(跳过 prestate 构建) + +## 🚀 快速开始 + +### 1. 准备主网 Genesis 文件 + +确保你有以下文件之一: + +```bash +# 选项 A: 直接使用解压后的文件 +devnet/mainnet.genesis.json # 6.6GB + +# 选项 B: 使用压缩包(推荐) +rpc-setup/genesis-mainnet.tar.gz # 1.6GB (自动解压) +``` + +### 2. 配置环境变量 + +编辑 `devnet/.env` 或 `devnet/example.env`: + +```bash +# 启用主网 genesis 模式 +USE_MAINNET_GENESIS=true + +# Genesis 文件路径 +MAINNET_GENESIS_PATH=mainnet.genesis.json + +# 必须启用 MIN_RUN 模式 +MIN_RUN=true + +# Fork 配置(主网快照点) +FORK_BLOCK=8593920 +PARENT_HASH=0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a + +# L2 测试账户注入(可选,推荐开启) +INJECT_L2_TEST_ACCOUNT=true +TEST_ACCOUNT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 +TEST_ACCOUNT_BALANCE=0x52B7D2DCC80CD2E4000000 # 100,000 ETH +``` + +### 3. 执行部署 + +```bash +cd devnet + +# 一键部署 +./0-all.sh + +# 或分步执行 +./1-start-l1.sh # 启动 L1 + 充值账户 +./2-deploy-op-contracts.sh # 部署合约 +./3-op-init.sh # 初始化(使用主网 genesis) +./4-op-start-service.sh # 启动服务 +``` + +### 4. 验证部署 + +```bash +# 运行验证脚本 +./scripts/verify-mainnet-setup.sh + +# 检查 L2 区块高度 +cast block-number -r http://localhost:8123 +# 应该输出: 8593921 (FORK_BLOCK + 1) + +# 检查测试账户余额(如果启用了注入) +cast balance 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -r http://localhost:8123 +``` + +## 📊 配置说明 + +### 必需配置 + +| 配置项 | 说明 | 示例值 | +|--------|------|--------| +| `USE_MAINNET_GENESIS` | 启用主网 genesis 模式 | `true` | +| `MIN_RUN` | 必须为 true(主网数据太大) | `true` | +| `FORK_BLOCK` | 主网快照的区块号 | `8593920` | +| `PARENT_HASH` | 该区块的哈希值 | `0x6912fea5...` | + +### 可选配置 + +| 配置项 | 说明 | 默认值 | 推荐值 | +|--------|------|--------|--------| +| `MAINNET_GENESIS_PATH` | Genesis 文件路径 | `mainnet.genesis.json` | - | +| `INJECT_L2_TEST_ACCOUNT` | 注入测试账户到 L2 | `false` | `true` | +| `TEST_ACCOUNT_ADDRESS` | 测试账户地址 | - | `0x7099...79C8` | +| `TEST_ACCOUNT_BALANCE` | 测试账户余额(hex) | - | `0x52B7...` (100K ETH) | + +## 🔍 工作原理 + +### 处理流程 + +``` +1. 检测模式 + ├─ USE_MAINNET_GENESIS=true? + └─ MIN_RUN=true? (强制检查) + +2. 准备 Genesis + ├─ 查找 mainnet.genesis.json + ├─ 如果不存在,从 tar.gz 解压 + └─ 使用 Python 脚本处理(快速) + +3. 修改 Genesis + ├─ 更新 config.legacyXLayerBlock + ├─ 更新 number (区块号) + ├─ 更新 parentHash + ├─ 注入测试账户(可选) + └─ 生成 genesis-reth.json + +4. 初始化数据库 + ├─ op-geth init (约 5-8 分钟) + ├─ op-reth init (约 3-5 分钟) + └─ 复制到其他节点 + +5. 跳过 Prestate + └─ MIN_RUN=true 直接退出 +``` + +### Python 脚本优势 + +| 操作 | jq | Python | 性能提升 | +|------|-----|--------|---------| +| 读取 6.6GB JSON | ~2 分钟 | ~30 秒 | **4x** | +| 修改字段 | ~1 分钟 | ~5 秒 | **12x** | +| 写入文件 | ~1 分钟 | ~25 秒 | **2.4x** | +| **总计** | **~4 分钟** | **~1 分钟** | **4x** | + +## ⚠️ 重要限制 + +### MIN_RUN 模式限制 + +当 `USE_MAINNET_GENESIS=true` 时,**必须** `MIN_RUN=true`,这意味着: + +**❌ 不可用的功能:** +- op-program prestate 构建 +- op-proposer 争议游戏模式 +- op-challenger 服务 +- op-dispute-mon 监控 + +**✅ 可用的功能:** +- op-geth-seq / op-reth-seq (sequencer) +- op-node (L2 节点) +- op-batcher (批次提交) +- op-geth-rpc (RPC 节点) +- op-conductor (HA 集群) + +### 为什么有这些限制? + +```bash +# 原因 1: 文件太大 +mainnet.genesis.json: 6.6GB +压缩后: 155KB → 太大无法嵌入 Go 程序 + +# 原因 2: 构建时间 +make reproducible-prestate: 需要编译 op-program +包含 6.6GB genesis: 会导致 OOM 或超时 + +# 原因 3: 用途不匹配 +主网数据用于: 功能测试、状态验证 +不需要: 争议游戏、欺诈证明 +``` + +## 💡 使用场景 + +### 适合的场景 + +✅ **主网迁移测试** +```bash +# 测试从主网快照启动 +USE_MAINNET_GENESIS=true +FORK_BLOCK=<主网某个区块> +``` + +✅ **合约交互测试** +```bash +# 与已部署的主网合约交互 +cast call "someFunction()" -r http://localhost:8123 +``` + +✅ **账户状态验证** +```bash +# 验证主网账户余额和状态 +cast balance -r http://localhost:8123 +``` + +### 不适合的场景 + +❌ **争议游戏测试** → 使用 `USE_MAINNET_GENESIS=false` +❌ **欺诈证明测试** → 使用 `USE_MAINNET_GENESIS=false` +❌ **Proposer 完整流程** → 使用 `USE_MAINNET_GENESIS=false` + +## 🔧 故障排查 + +### 问题 1: "Mainnet genesis requires MIN_RUN=true" + +```bash +# 错误 +❌ ERROR: Mainnet genesis requires MIN_RUN=true + +# 解决方案 +vim .env +# 设置: MIN_RUN=true +``` + +### 问题 2: Genesis 文件未找到 + +```bash +# 错误 +❌ ERROR: Neither genesis file nor tar.gz found + +# 解决方案 +# 确保文件存在于以下位置之一: +ls -lh devnet/mainnet.genesis.json +ls -lh rpc-setup/genesis-mainnet.tar.gz +``` + +### 问题 3: Python 脚本执行慢 + +```bash +# 如果处理时间超过 5 分钟,检查: + +# 1. 磁盘性能 +iostat -x 1 + +# 2. 内存使用 +free -h + +# 3. Python 版本(需要 3.6+) +python3 --version +``` + +### 问题 4: 数据库初始化失败 + +```bash +# 检查磁盘空间 +df -h + +# 需要至少 50GB 可用空间 +# mainnet.genesis.json: 6.6GB +# op-geth-seq DB: 10-20GB +# op-geth-rpc DB: 10-20GB +``` + +## 📈 性能优化 + +### 建议配置 + +```bash +# Docker 资源 +Memory: 16GB+ +CPU: 4+ cores +Disk: SSD (强烈推荐) + +# 数据库引擎 +DB_ENGINE=pebble # 推荐,比 leveldb 快 +``` + +### 预期时间 + +| 步骤 | 时间 | 说明 | +|------|------|------| +| 解压 tar.gz | 2-3 分钟 | 如果使用压缩包 | +| 处理 genesis | 1-2 分钟 | Python 脚本 | +| init geth | 5-8 分钟 | 取决于磁盘速度 | +| init reth | 3-5 分钟 | 取决于磁盘速度 | +| 复制数据库 | 2-4 分钟 | 取决于磁盘速度 | +| **总计** | **15-25 分钟** | 在 SSD 上 | + +## 🎯 测试示例 + +### L2 交易测试 + +```bash +# 使用注入的测试账户发送交易 +cast send \ + --private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d \ + --value 1ether \ + 0x目标地址 \ + -r http://localhost:8123 + +# 检查交易 +cast tx -r http://localhost:8123 +``` + +### 读取主网合约 + +```bash +# 假设主网上有合约在某个地址 +CONTRACT=0x... # 主网合约地址 + +# 调用只读方法 +cast call $CONTRACT "balanceOf(address)(uint256)" \ + 0x你的地址 \ + -r http://localhost:8123 +``` + +### 查询主网账户 + +```bash +# 检查主网某个账户的余额 +MAINNET_ACCOUNT=0x... + +cast balance $MAINNET_ACCOUNT -r http://localhost:8123 +cast nonce $MAINNET_ACCOUNT -r http://localhost:8123 +cast code $MAINNET_ACCOUNT -r http://localhost:8123 +``` + +## 📚 相关文件 + +- `example.env` - 配置模板 +- `3-op-init.sh` - 初始化脚本(含 mainnet 支持) +- `scripts/process-mainnet-genesis.py` - Genesis 处理脚本 +- `scripts/verify-mainnet-setup.sh` - 验证脚本 +- `MAINNET_GENESIS_GUIDE.md` - 本文档 + +## 🆘 获取帮助 + +如果遇到问题: + +1. 运行验证脚本查看详细状态 +2. 检查日志:`docker logs op-geth-seq` +3. 参考故障排查章节 + +--- + +最后更新:2025-11-25 + diff --git a/devnet/MAINNET_GENESIS_QUICKSTART.md b/devnet/MAINNET_GENESIS_QUICKSTART.md new file mode 100644 index 0000000..1d4b586 --- /dev/null +++ b/devnet/MAINNET_GENESIS_QUICKSTART.md @@ -0,0 +1,110 @@ +# Mainnet Genesis 快速开始 + +## 🚀 5 分钟快速部署 + +### 1. 配置(30 秒) + +```bash +cd devnet +cp example.env .env +vim .env +``` + +修改以下配置: + +```bash +# 启用主网 genesis +USE_MAINNET_GENESIS=true + +# 必须启用 MIN_RUN +MIN_RUN=true + +# 注入测试账户(推荐) +INJECT_L2_TEST_ACCOUNT=true +TEST_ACCOUNT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 +TEST_ACCOUNT_BALANCE=0x52B7D2DCC80CD2E4000000 # 100K ETH + +# Fork 配置(使用你的主网快照点) +FORK_BLOCK=8593920 +PARENT_HASH=0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a +``` + +### 2. 部署(15-20 分钟) + +```bash +# 确保 genesis 文件存在 +ls -lh mainnet.genesis.json # 或 ../rpc-setup/genesis-mainnet.tar.gz + +# 一键部署 +./0-all.sh +``` + +### 3. 验证(1 分钟) + +```bash +# 运行验证 +./scripts/verify-mainnet-setup.sh + +# 检查 L2 状态 +cast block-number -r http://localhost:8123 +# 应该输出: 8593921 + +# 检查测试账户 +cast balance 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -r http://localhost:8123 +# 应该输出: 100000000000000000000000 (100K ETH) +``` + +### 4. 测试交易(可选) + +```bash +# 使用测试账户发送交易 +cast send \ + --private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d \ + --value 1ether \ + <目标地址> \ + -r http://localhost:8123 +``` + +## ⚠️ 重要提示 + +1. **必须 MIN_RUN=true** - 主网 genesis 太大,无法构建 prestate +2. **需要 50GB+ 磁盘空间** - genesis + 数据库 +3. **推荐 SSD** - 初始化速度快 3-5 倍 +4. **需要 16GB+ 内存** - Docker 配置 + +## 📖 完整文档 + +详细说明请查看:`MAINNET_GENESIS_GUIDE.md` + +## 🆘 故障排查 + +### 错误 1: "Mainnet genesis requires MIN_RUN=true" +```bash +# 解决:在 .env 中设置 +MIN_RUN=true +``` + +### 错误 2: Genesis 文件未找到 +```bash +# 解决:确保文件存在 +ls mainnet.genesis.json +# 或 +ls ../rpc-setup/genesis-mainnet.tar.gz +``` + +### 错误 3: 磁盘空间不足 +```bash +# 检查空间 +df -h +# 需要至少 50GB +``` + +## 🎉 完成! + +现在你可以: +- ✅ 与主网合约交互 +- ✅ 测试主网账户状态 +- ✅ 验证迁移逻辑 +- ✅ 进行功能测试 + +**注意:** 此模式不支持争议游戏和欺诈证明(需要完整模式) diff --git a/devnet/example.env b/devnet/example.env index c9ceed5..528eb70 100644 --- a/devnet/example.env +++ b/devnet/example.env @@ -134,6 +134,26 @@ FORK_BLOCK=8593920 PARENT_HASH="0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a" NEW_BLOCK_HASH=0xddb9bdc86631494bab4b4749c4575035e2383da7c96d32d31341de862b1dd6c9 +# ============================================================================== +# Mainnet Genesis Configuration +# ============================================================================== +# Use mainnet genesis instead of generating new one +# ⚠️ REQUIRES: MIN_RUN=true (mainnet genesis is too large to build prestate) +USE_MAINNET_GENESIS=false + +# Path to mainnet genesis file (relative to devnet directory) +# Supported formats: +# - Direct path: mainnet.genesis.json +# - Compressed: ../rpc-setup/genesis-mainnet.tar.gz (auto-extracts to merged.genesis.json) +MAINNET_GENESIS_PATH=mainnet.genesis.json + +# Inject test account balance into L2 genesis for testing convenience +# This account will be funded with TEST_ACCOUNT_BALANCE in L2 genesis +# Note: L1 accounts are still funded separately in 1-start-l1.sh +INJECT_L2_TEST_ACCOUNT=true +TEST_ACCOUNT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 +TEST_ACCOUNT_BALANCE=0x52B7D2DCC80CD2E4000000 # 100,000 ETH + # ============================================================================== # Other Configuration # ============================================================================== diff --git a/devnet/scripts/__pycache__/process-mainnet-genesis.cpython-314.pyc b/devnet/scripts/__pycache__/process-mainnet-genesis.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f8df57a5b9c5ea598f4fb063266b32e71757ea8b GIT binary patch literal 7546 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 bool: + """ + Process mainnet genesis file with minimal memory footprint + + Args: + input_file: Path to source genesis.json + output_file: Path to output genesis.json + next_block: Next block number (FORK_BLOCK + 1) + parent_hash: Parent block hash + test_account: Optional test account address to inject + test_balance: Optional balance for test account (hex) + + Returns: + True if successful + """ + print(f"📖 Loading genesis from {input_file}...") + print(f" File size: {os.path.getsize(input_file) / (1024**3):.2f} GB") + + try: + with open(input_file, 'r') as f: + genesis = json.load(f) + + print(f"✅ Loaded genesis with {len(genesis.get('alloc', {}))} accounts") + + # Update config fields + print(f"🔧 Updating genesis configuration...") + if 'config' not in genesis: + genesis['config'] = {} + + genesis['config']['legacyXLayerBlock'] = next_block + genesis['parentHash'] = parent_hash + # NOTE: Keep number as 0 for geth init (geth doesn't support number > 0) + # Reth version will have hex number, rollup.json will have the actual number + genesis['number'] = 0 + + # CRITICAL: Update timestamp to current time to avoid conductor "unsafe head falling behind" error + current_timestamp = int(time.time()) + old_timestamp = genesis.get('timestamp', 0) + genesis['timestamp'] = hex(current_timestamp) + + print(f" ✓ legacyXLayerBlock: {next_block}") + print(f" ✓ number: 0 (required for geth init)") + print(f" ✓ parentHash: {parent_hash}") + print(f" ✓ timestamp: {hex(current_timestamp)} (updated from {hex(old_timestamp) if isinstance(old_timestamp, int) else old_timestamp})") + + # Inject test account if requested + if test_account and test_balance: + if 'alloc' not in genesis: + genesis['alloc'] = {} + + account_key = test_account.lower() + if account_key.startswith('0x'): + account_key = account_key[2:] + + if account_key in genesis['alloc']: + print(f"⚠️ Account {test_account} already exists, updating balance...") + genesis['alloc'][account_key]['balance'] = test_balance + else: + print(f"💰 Injecting test account {test_account}...") + genesis['alloc'][account_key] = {"balance": test_balance} + + # Convert balance to decimal for display + balance_wei = int(test_balance, 16) + balance_eth = balance_wei / (10**18) + print(f" ✓ Balance: {balance_eth:,.0f} ETH") + + # Write output + print(f"💾 Writing to {output_file}...") + with open(output_file, 'w') as f: + # Use separators to minimize file size + json.dump(genesis, f, separators=(',', ':')) + + output_size = os.path.getsize(output_file) + print(f"✅ Successfully processed genesis ({output_size / (1024**3):.2f} GB)") + + return True + + except Exception as e: + print(f"❌ ERROR: {e}", file=sys.stderr) + return False + +def create_reth_version(genesis_file: str, reth_file: str, next_block_hex: str) -> bool: + """ + Create Reth-compatible genesis (number as hex string "0x0") + + Args: + genesis_file: Source genesis.json + reth_file: Output genesis-reth.json + next_block_hex: Block number in hex format (should be "0x0" for init) + + Returns: + True if successful + """ + print(f"🔧 Creating Reth-compatible genesis...") + + try: + with open(genesis_file, 'r') as f: + genesis = json.load(f) + + # Reth expects number as hex string "0x0" for init + genesis['number'] = "0x0" + + with open(reth_file, 'w') as f: + json.dump(genesis, f, separators=(',', ':')) + + print(f"✅ Created {reth_file} (number: 0x0 for reth init)") + return True + + except Exception as e: + print(f"❌ ERROR creating Reth genesis: {e}", file=sys.stderr) + return False + +def main(): + if len(sys.argv) < 5: + print("Usage: process-mainnet-genesis.py [test_account] [test_balance]") + print("") + print("Example:") + print(" process-mainnet-genesis.py mainnet.genesis.json genesis.json 8593921 0x6912... 0x7099... 0x52B7...") + sys.exit(1) + + input_file = sys.argv[1] + output_file = sys.argv[2] + next_block = int(sys.argv[3]) + parent_hash = sys.argv[4] + test_account = sys.argv[5] if len(sys.argv) > 5 else None + test_balance = sys.argv[6] if len(sys.argv) > 6 else None + + # Process main genesis + success = process_genesis( + input_file, + output_file, + next_block, + parent_hash, + test_account, + test_balance + ) + + if not success: + sys.exit(1) + + # Create Reth version (number must be "0x0" for init) + reth_file = output_file.replace('.json', '-reth.json') + + if not create_reth_version(output_file, reth_file, "0x0"): + sys.exit(1) + + print("") + print("🎉 Genesis processing complete!") + sys.exit(0) + +if __name__ == '__main__': + main() + diff --git a/devnet/scripts/test-mainnet-genesis.sh b/devnet/scripts/test-mainnet-genesis.sh new file mode 100755 index 0000000..01301f5 --- /dev/null +++ b/devnet/scripts/test-mainnet-genesis.sh @@ -0,0 +1,183 @@ +#!/bin/bash +# Quick test script for mainnet genesis functionality +# This script validates the changes without running the full deployment + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DEVNET_DIR="$(dirname "$SCRIPT_DIR")" + +echo "🧪 Testing mainnet genesis implementation..." +echo "" + +# Test 1: Check files exist +echo "1️⃣ Checking files..." +FILES=( + "$DEVNET_DIR/example.env" + "$DEVNET_DIR/3-op-init.sh" + "$SCRIPT_DIR/process-mainnet-genesis.py" + "$SCRIPT_DIR/verify-mainnet-setup.sh" +) + +for file in "${FILES[@]}"; do + if [ -f "$file" ]; then + echo " ✅ $(basename $file)" + else + echo " ❌ $(basename $file) not found" + exit 1 + fi +done + +echo "" + +# Test 2: Check configuration variables +echo "2️⃣ Checking configuration variables in example.env..." +VARS=( + "USE_MAINNET_GENESIS" + "MAINNET_GENESIS_PATH" + "INJECT_L2_TEST_ACCOUNT" + "TEST_ACCOUNT_ADDRESS" + "TEST_ACCOUNT_BALANCE" +) + +for var in "${VARS[@]}"; do + if grep -q "^$var=" "$DEVNET_DIR/example.env"; then + echo " ✅ $var" + else + echo " ❌ $var not found" + exit 1 + fi +done + +echo "" + +# Test 3: Check Python script syntax +echo "3️⃣ Checking Python script syntax..." +if python3 -m py_compile "$SCRIPT_DIR/process-mainnet-genesis.py" 2>/dev/null; then + echo " ✅ Python syntax valid" +else + echo " ❌ Python syntax error" + exit 1 +fi + +echo "" + +# Test 4: Check Python script help +echo "4️⃣ Testing Python script help..." +if python3 "$SCRIPT_DIR/process-mainnet-genesis.py" 2>&1 | grep -q "Usage"; then + echo " ✅ Help text displayed" +else + echo " ❌ Help text not working" + exit 1 +fi + +echo "" + +# Test 5: Check bash functions in 3-op-init.sh +echo "5️⃣ Checking bash functions..." +if grep -q "detect_genesis_mode()" "$DEVNET_DIR/3-op-init.sh"; then + echo " ✅ detect_genesis_mode() function added" +else + echo " ❌ detect_genesis_mode() function not found" + exit 1 +fi + +if grep -q "prepare_mainnet_genesis()" "$DEVNET_DIR/3-op-init.sh"; then + echo " ✅ prepare_mainnet_genesis() function added" +else + echo " ❌ prepare_mainnet_genesis() function not found" + exit 1 +fi + +echo "" + +# Test 6: Check mode selection logic +echo "6️⃣ Checking mode selection logic..." +if grep -q "if detect_genesis_mode; then" "$DEVNET_DIR/3-op-init.sh"; then + echo " ✅ Mode selection logic added" +else + echo " ❌ Mode selection logic not found" + exit 1 +fi + +echo "" + +# Test 7: Simulate configuration check +echo "7️⃣ Simulating configuration validation..." + +# Create temporary test env +TEST_ENV=$(mktemp) +cat > "$TEST_ENV" << 'EOF' +USE_MAINNET_GENESIS=true +MIN_RUN=true +FORK_BLOCK=8593920 +PARENT_HASH=0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a +MAINNET_GENESIS_PATH=mainnet.genesis.json +INJECT_L2_TEST_ACCOUNT=true +TEST_ACCOUNT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 +TEST_ACCOUNT_BALANCE=0x52B7D2DCC80CD2E4000000 +EOF + +source "$TEST_ENV" + +if [ "$USE_MAINNET_GENESIS" = "true" ] && [ "$MIN_RUN" = "true" ]; then + echo " ✅ Configuration validation logic works" +else + echo " ❌ Configuration validation failed" + rm "$TEST_ENV" + exit 1 +fi + +rm "$TEST_ENV" + +echo "" + +# Test 8: Test account address validation +echo "8️⃣ Validating test account address..." +EXPECTED_ADDR="0x70997970C51812dc3A010C7d01b50e0d17dc79C8" +if grep -q "$EXPECTED_ADDR" "$DEVNET_DIR/example.env"; then + echo " ✅ Test account address configured: $EXPECTED_ADDR" +else + echo " ⚠️ Test account address not found in example.env" +fi + +echo "" + +# Test 9: Check script permissions +echo "9️⃣ Checking script permissions..." +SCRIPTS=( + "$SCRIPT_DIR/process-mainnet-genesis.py" + "$SCRIPT_DIR/verify-mainnet-setup.sh" +) + +for script in "${SCRIPTS[@]}"; do + if [ -x "$script" ]; then + echo " ✅ $(basename $script) is executable" + else + echo " ⚠️ $(basename $script) is not executable (will be set)" + chmod +x "$script" + fi +done + +echo "" + +# Summary +echo "═══════════════════════════════════════" +echo "✅ All tests passed!" +echo "═══════════════════════════════════════" +echo "" +echo "📋 Implementation Summary:" +echo " • example.env: 5 new configuration variables" +echo " • 3-op-init.sh: 2 new functions, mode selection logic" +echo " • process-mainnet-genesis.py: High-performance JSON processor" +echo " • verify-mainnet-setup.sh: Comprehensive validation script" +echo "" +echo "🚀 Ready to test with mainnet genesis data!" +echo "" +echo "Next steps:" +echo "1. Set USE_MAINNET_GENESIS=true in .env" +echo "2. Ensure mainnet.genesis.json exists" +echo "3. Run: ./0-all.sh" +echo "4. Verify: ./scripts/verify-mainnet-setup.sh" +echo "" + diff --git a/devnet/scripts/verify-mainnet-setup.sh b/devnet/scripts/verify-mainnet-setup.sh new file mode 100755 index 0000000..06baa9b --- /dev/null +++ b/devnet/scripts/verify-mainnet-setup.sh @@ -0,0 +1,218 @@ +#!/bin/bash +set -e + +source .env + +echo "🔍 Verifying mainnet genesis deployment..." +echo "" + +# ======================================== +# 1. Configuration Check +# ======================================== +echo "1️⃣ Configuration Validation" +echo "───────────────────────────" + +if [ "$USE_MAINNET_GENESIS" = "true" ]; then + echo " ✅ Mainnet genesis mode: ENABLED" + + if [ "$MIN_RUN" = "true" ]; then + echo " ✅ MIN_RUN: true (required)" + else + echo " ❌ ERROR: MIN_RUN must be true for mainnet genesis" + exit 1 + fi + + if [ -n "$FORK_BLOCK" ] && [ -n "$PARENT_HASH" ]; then + echo " ✅ Fork block: $FORK_BLOCK" + echo " ✅ Parent hash: ${PARENT_HASH:0:20}..." + else + echo " ❌ ERROR: FORK_BLOCK and PARENT_HASH not configured" + exit 1 + fi +else + echo " ℹ️ Mainnet genesis mode: DISABLED (using generated genesis)" + echo " Skipping mainnet-specific checks..." + echo "" + exit 0 +fi + +echo "" + +# ======================================== +# 2. Genesis Files Check +# ======================================== +echo "2️⃣ Genesis Files" +echo "───────────────────────────" + +if [ -f "config-op/genesis.json" ]; then + GENESIS_SIZE=$(du -h config-op/genesis.json | cut -f1) + GENESIS_NUMBER=$(jq -r '.number' config-op/genesis.json 2>/dev/null || echo "error") + GENESIS_PARENT=$(jq -r '.parentHash' config-op/genesis.json 2>/dev/null || echo "error") + GENESIS_LEGACY=$(jq -r '.config.legacyXLayerBlock' config-op/genesis.json 2>/dev/null || echo "error") + GENESIS_ACCOUNTS=$(jq '.alloc | length' config-op/genesis.json 2>/dev/null || echo "error") + + echo " ✅ genesis.json exists ($GENESIS_SIZE)" + echo " • number: $GENESIS_NUMBER" + echo " • parentHash: ${GENESIS_PARENT:0:20}..." + echo " • legacyXLayerBlock: $GENESIS_LEGACY" + echo " • accounts: $GENESIS_ACCOUNTS" + + # Verify values match configuration + EXPECTED_BLOCK=$((FORK_BLOCK + 1)) + if [ "$GENESIS_NUMBER" != "$EXPECTED_BLOCK" ]; then + echo " ⚠️ WARNING: Genesis number mismatch!" + echo " Expected: $EXPECTED_BLOCK" + echo " Actual: $GENESIS_NUMBER" + fi + + if [ "$GENESIS_PARENT" != "$PARENT_HASH" ]; then + echo " ⚠️ WARNING: Parent hash mismatch!" + echo " Expected: $PARENT_HASH" + echo " Actual: $GENESIS_PARENT" + fi +else + echo " ❌ genesis.json not found" + exit 1 +fi + +if [ -f "config-op/genesis-reth.json" ]; then + echo " ✅ genesis-reth.json exists" +else + echo " ⚠️ genesis-reth.json not found" +fi + +echo "" + +# ======================================== +# 3. Rollup Configuration Check +# ======================================== +echo "3️⃣ Rollup Configuration" +echo "───────────────────────────" + +if [ -f "config-op/rollup.json" ]; then + ROLLUP_NUMBER=$(jq -r '.genesis.l2.number' config-op/rollup.json 2>/dev/null || echo "error") + ROLLUP_HASH=$(jq -r '.genesis.l2.hash' config-op/rollup.json 2>/dev/null || echo "error") + + echo " ✅ rollup.json exists" + echo " • genesis.l2.number: $ROLLUP_NUMBER" + echo " • genesis.l2.hash: ${ROLLUP_HASH:0:20}..." + + if [ "$ROLLUP_NUMBER" != "$EXPECTED_BLOCK" ]; then + echo " ⚠️ WARNING: Rollup number mismatch!" + echo " Expected: $EXPECTED_BLOCK" + echo " Actual: $ROLLUP_NUMBER" + fi +else + echo " ❌ rollup.json not found" + exit 1 +fi + +echo "" + +# ======================================== +# 4. Database Check +# ======================================== +echo "4️⃣ Initialized Databases" +echo "───────────────────────────" + +if [ -d "data/op-$SEQ_TYPE-seq/geth/chaindata" ] || [ -d "data/op-$SEQ_TYPE-seq/db" ]; then + DB_SIZE=$(du -sh data/op-$SEQ_TYPE-seq 2>/dev/null | cut -f1 || echo "unknown") + echo " ✅ op-$SEQ_TYPE-seq: $DB_SIZE" +else + echo " ⚠️ op-$SEQ_TYPE-seq database not initialized" +fi + +if [ -d "data/op-$RPC_TYPE-rpc/geth/chaindata" ] || [ -d "data/op-$RPC_TYPE-rpc/db" ]; then + RPC_SIZE=$(du -sh data/op-$RPC_TYPE-rpc 2>/dev/null | cut -f1 || echo "unknown") + echo " ✅ op-$RPC_TYPE-rpc: $RPC_SIZE" +else + echo " ℹ️ op-$RPC_TYPE-rpc database not initialized yet" +fi + +echo "" + +# ======================================== +# 5. L1 Account Balances +# ======================================== +echo "5️⃣ L1 Account Balances" +echo "───────────────────────────" + +if docker ps --format '{{.Names}}' | grep -q l1-geth; then + echo " ℹ️ Checking L1 balances..." + + PROPOSER_ADDR=$(cast wallet address $OP_PROPOSER_PRIVATE_KEY 2>/dev/null || echo "error") + BATCHER_ADDR=$(cast wallet address $OP_BATCHER_PRIVATE_KEY 2>/dev/null || echo "error") + + if [ "$PROPOSER_ADDR" != "error" ]; then + PROPOSER_BAL=$(cast balance $PROPOSER_ADDR -r $L1_RPC_URL 2>/dev/null || echo "0") + PROPOSER_ETH=$(cast to-unit $PROPOSER_BAL ether 2>/dev/null || echo "0") + echo " • Proposer ($PROPOSER_ADDR): $PROPOSER_ETH ETH" + fi + + if [ "$BATCHER_ADDR" != "error" ]; then + BATCHER_BAL=$(cast balance $BATCHER_ADDR -r $L1_RPC_URL 2>/dev/null || echo "0") + BATCHER_ETH=$(cast to-unit $BATCHER_BAL ether 2>/dev/null || echo "0") + echo " • Batcher ($BATCHER_ADDR): $BATCHER_ETH ETH" + fi +else + echo " ⚠️ L1 node not running (start with 1-start-l1.sh)" +fi + +echo "" + +# ======================================== +# 6. L2 Test Account +# ======================================== +if [ "$INJECT_L2_TEST_ACCOUNT" = "true" ]; then + echo "6️⃣ L2 Test Account" + echo "───────────────────────────" + + # Check in genesis + ACCOUNT_KEY=$(echo "$TEST_ACCOUNT_ADDRESS" | tr '[:upper:]' '[:lower:]' | sed 's/0x//') + GENESIS_BALANCE=$(jq -r ".alloc[\"$ACCOUNT_KEY\"].balance // \"not found\"" config-op/genesis.json 2>/dev/null) + + if [ "$GENESIS_BALANCE" != "not found" ]; then + BALANCE_WEI=$(python3 -c "print(int('$GENESIS_BALANCE', 16))" 2>/dev/null || echo "0") + BALANCE_ETH=$(python3 -c "print(int('$GENESIS_BALANCE', 16) / 10**18)" 2>/dev/null || echo "0") + echo " ✅ Test account in genesis: $TEST_ACCOUNT_ADDRESS" + echo " • Balance: $BALANCE_ETH ETH" + else + echo " ⚠️ Test account not found in genesis" + fi + + echo "" +fi + +# ======================================== +# 7. Prestate Files (Should NOT Exist) +# ======================================== +echo "7️⃣ Prestate Files (MIN_RUN Check)" +echo "───────────────────────────" + +if [ -f "config-op/genesis.json.gz" ]; then + echo " ℹ️ genesis.json.gz exists (not needed in MIN_RUN mode)" +else + echo " ✅ genesis.json.gz not present (correct for MIN_RUN)" +fi + +if [ -d "data/cannon-data" ]; then + echo " ℹ️ cannon-data directory exists (not needed in MIN_RUN mode)" +else + echo " ✅ cannon-data not present (correct for MIN_RUN)" +fi + +echo "" +echo "═══════════════════════════" +echo "✅ All verifications passed!" +echo "═══════════════════════════" +echo "" + +if docker ps --format '{{.Names}}' | grep -q op-geth-seq || docker ps --format '{{.Names}}' | grep -q op-reth-seq; then + echo "🚀 Services Status:" + docker ps --format 'table {{.Names}}\t{{.Status}}' | grep -E 'op-|l1-' || echo "No OP Stack services running" +else + echo "ℹ️ Services not yet started (run 4-op-start-service.sh)" +fi + +echo "" + From 151146c7600d5d535e7e9c0c4b736554c12afdd1 Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 3 Dec 2025 11:47:25 +0800 Subject: [PATCH 2/9] remove mainnet genesis docs --- devnet/MAINNET_GENESIS_GUIDE.md | 339 --------------------------- devnet/MAINNET_GENESIS_QUICKSTART.md | 110 --------- 2 files changed, 449 deletions(-) delete mode 100644 devnet/MAINNET_GENESIS_GUIDE.md delete mode 100644 devnet/MAINNET_GENESIS_QUICKSTART.md diff --git a/devnet/MAINNET_GENESIS_GUIDE.md b/devnet/MAINNET_GENESIS_GUIDE.md deleted file mode 100644 index 41d484a..0000000 --- a/devnet/MAINNET_GENESIS_GUIDE.md +++ /dev/null @@ -1,339 +0,0 @@ -# Mainnet Genesis 部署指南 - -本指南说明如何使用主网 genesis 数据部署 OP Stack devnet 环境。 - -## 📋 功能特性 - -- ✅ 使用真实主网 genesis 数据(6.6GB+) -- ✅ 保留所有主网账户和合约状态 -- ✅ 自动注入测试账户到 L2 genesis(可选) -- ✅ 高性能 Python 脚本处理大 JSON(比 jq 快 5-10 倍) -- ✅ 低耦合设计,最小化对现有代码的修改 -- ✅ MIN_RUN 模式强制保障(跳过 prestate 构建) - -## 🚀 快速开始 - -### 1. 准备主网 Genesis 文件 - -确保你有以下文件之一: - -```bash -# 选项 A: 直接使用解压后的文件 -devnet/mainnet.genesis.json # 6.6GB - -# 选项 B: 使用压缩包(推荐) -rpc-setup/genesis-mainnet.tar.gz # 1.6GB (自动解压) -``` - -### 2. 配置环境变量 - -编辑 `devnet/.env` 或 `devnet/example.env`: - -```bash -# 启用主网 genesis 模式 -USE_MAINNET_GENESIS=true - -# Genesis 文件路径 -MAINNET_GENESIS_PATH=mainnet.genesis.json - -# 必须启用 MIN_RUN 模式 -MIN_RUN=true - -# Fork 配置(主网快照点) -FORK_BLOCK=8593920 -PARENT_HASH=0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a - -# L2 测试账户注入(可选,推荐开启) -INJECT_L2_TEST_ACCOUNT=true -TEST_ACCOUNT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -TEST_ACCOUNT_BALANCE=0x52B7D2DCC80CD2E4000000 # 100,000 ETH -``` - -### 3. 执行部署 - -```bash -cd devnet - -# 一键部署 -./0-all.sh - -# 或分步执行 -./1-start-l1.sh # 启动 L1 + 充值账户 -./2-deploy-op-contracts.sh # 部署合约 -./3-op-init.sh # 初始化(使用主网 genesis) -./4-op-start-service.sh # 启动服务 -``` - -### 4. 验证部署 - -```bash -# 运行验证脚本 -./scripts/verify-mainnet-setup.sh - -# 检查 L2 区块高度 -cast block-number -r http://localhost:8123 -# 应该输出: 8593921 (FORK_BLOCK + 1) - -# 检查测试账户余额(如果启用了注入) -cast balance 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -r http://localhost:8123 -``` - -## 📊 配置说明 - -### 必需配置 - -| 配置项 | 说明 | 示例值 | -|--------|------|--------| -| `USE_MAINNET_GENESIS` | 启用主网 genesis 模式 | `true` | -| `MIN_RUN` | 必须为 true(主网数据太大) | `true` | -| `FORK_BLOCK` | 主网快照的区块号 | `8593920` | -| `PARENT_HASH` | 该区块的哈希值 | `0x6912fea5...` | - -### 可选配置 - -| 配置项 | 说明 | 默认值 | 推荐值 | -|--------|------|--------|--------| -| `MAINNET_GENESIS_PATH` | Genesis 文件路径 | `mainnet.genesis.json` | - | -| `INJECT_L2_TEST_ACCOUNT` | 注入测试账户到 L2 | `false` | `true` | -| `TEST_ACCOUNT_ADDRESS` | 测试账户地址 | - | `0x7099...79C8` | -| `TEST_ACCOUNT_BALANCE` | 测试账户余额(hex) | - | `0x52B7...` (100K ETH) | - -## 🔍 工作原理 - -### 处理流程 - -``` -1. 检测模式 - ├─ USE_MAINNET_GENESIS=true? - └─ MIN_RUN=true? (强制检查) - -2. 准备 Genesis - ├─ 查找 mainnet.genesis.json - ├─ 如果不存在,从 tar.gz 解压 - └─ 使用 Python 脚本处理(快速) - -3. 修改 Genesis - ├─ 更新 config.legacyXLayerBlock - ├─ 更新 number (区块号) - ├─ 更新 parentHash - ├─ 注入测试账户(可选) - └─ 生成 genesis-reth.json - -4. 初始化数据库 - ├─ op-geth init (约 5-8 分钟) - ├─ op-reth init (约 3-5 分钟) - └─ 复制到其他节点 - -5. 跳过 Prestate - └─ MIN_RUN=true 直接退出 -``` - -### Python 脚本优势 - -| 操作 | jq | Python | 性能提升 | -|------|-----|--------|---------| -| 读取 6.6GB JSON | ~2 分钟 | ~30 秒 | **4x** | -| 修改字段 | ~1 分钟 | ~5 秒 | **12x** | -| 写入文件 | ~1 分钟 | ~25 秒 | **2.4x** | -| **总计** | **~4 分钟** | **~1 分钟** | **4x** | - -## ⚠️ 重要限制 - -### MIN_RUN 模式限制 - -当 `USE_MAINNET_GENESIS=true` 时,**必须** `MIN_RUN=true`,这意味着: - -**❌ 不可用的功能:** -- op-program prestate 构建 -- op-proposer 争议游戏模式 -- op-challenger 服务 -- op-dispute-mon 监控 - -**✅ 可用的功能:** -- op-geth-seq / op-reth-seq (sequencer) -- op-node (L2 节点) -- op-batcher (批次提交) -- op-geth-rpc (RPC 节点) -- op-conductor (HA 集群) - -### 为什么有这些限制? - -```bash -# 原因 1: 文件太大 -mainnet.genesis.json: 6.6GB -压缩后: 155KB → 太大无法嵌入 Go 程序 - -# 原因 2: 构建时间 -make reproducible-prestate: 需要编译 op-program -包含 6.6GB genesis: 会导致 OOM 或超时 - -# 原因 3: 用途不匹配 -主网数据用于: 功能测试、状态验证 -不需要: 争议游戏、欺诈证明 -``` - -## 💡 使用场景 - -### 适合的场景 - -✅ **主网迁移测试** -```bash -# 测试从主网快照启动 -USE_MAINNET_GENESIS=true -FORK_BLOCK=<主网某个区块> -``` - -✅ **合约交互测试** -```bash -# 与已部署的主网合约交互 -cast call "someFunction()" -r http://localhost:8123 -``` - -✅ **账户状态验证** -```bash -# 验证主网账户余额和状态 -cast balance -r http://localhost:8123 -``` - -### 不适合的场景 - -❌ **争议游戏测试** → 使用 `USE_MAINNET_GENESIS=false` -❌ **欺诈证明测试** → 使用 `USE_MAINNET_GENESIS=false` -❌ **Proposer 完整流程** → 使用 `USE_MAINNET_GENESIS=false` - -## 🔧 故障排查 - -### 问题 1: "Mainnet genesis requires MIN_RUN=true" - -```bash -# 错误 -❌ ERROR: Mainnet genesis requires MIN_RUN=true - -# 解决方案 -vim .env -# 设置: MIN_RUN=true -``` - -### 问题 2: Genesis 文件未找到 - -```bash -# 错误 -❌ ERROR: Neither genesis file nor tar.gz found - -# 解决方案 -# 确保文件存在于以下位置之一: -ls -lh devnet/mainnet.genesis.json -ls -lh rpc-setup/genesis-mainnet.tar.gz -``` - -### 问题 3: Python 脚本执行慢 - -```bash -# 如果处理时间超过 5 分钟,检查: - -# 1. 磁盘性能 -iostat -x 1 - -# 2. 内存使用 -free -h - -# 3. Python 版本(需要 3.6+) -python3 --version -``` - -### 问题 4: 数据库初始化失败 - -```bash -# 检查磁盘空间 -df -h - -# 需要至少 50GB 可用空间 -# mainnet.genesis.json: 6.6GB -# op-geth-seq DB: 10-20GB -# op-geth-rpc DB: 10-20GB -``` - -## 📈 性能优化 - -### 建议配置 - -```bash -# Docker 资源 -Memory: 16GB+ -CPU: 4+ cores -Disk: SSD (强烈推荐) - -# 数据库引擎 -DB_ENGINE=pebble # 推荐,比 leveldb 快 -``` - -### 预期时间 - -| 步骤 | 时间 | 说明 | -|------|------|------| -| 解压 tar.gz | 2-3 分钟 | 如果使用压缩包 | -| 处理 genesis | 1-2 分钟 | Python 脚本 | -| init geth | 5-8 分钟 | 取决于磁盘速度 | -| init reth | 3-5 分钟 | 取决于磁盘速度 | -| 复制数据库 | 2-4 分钟 | 取决于磁盘速度 | -| **总计** | **15-25 分钟** | 在 SSD 上 | - -## 🎯 测试示例 - -### L2 交易测试 - -```bash -# 使用注入的测试账户发送交易 -cast send \ - --private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d \ - --value 1ether \ - 0x目标地址 \ - -r http://localhost:8123 - -# 检查交易 -cast tx -r http://localhost:8123 -``` - -### 读取主网合约 - -```bash -# 假设主网上有合约在某个地址 -CONTRACT=0x... # 主网合约地址 - -# 调用只读方法 -cast call $CONTRACT "balanceOf(address)(uint256)" \ - 0x你的地址 \ - -r http://localhost:8123 -``` - -### 查询主网账户 - -```bash -# 检查主网某个账户的余额 -MAINNET_ACCOUNT=0x... - -cast balance $MAINNET_ACCOUNT -r http://localhost:8123 -cast nonce $MAINNET_ACCOUNT -r http://localhost:8123 -cast code $MAINNET_ACCOUNT -r http://localhost:8123 -``` - -## 📚 相关文件 - -- `example.env` - 配置模板 -- `3-op-init.sh` - 初始化脚本(含 mainnet 支持) -- `scripts/process-mainnet-genesis.py` - Genesis 处理脚本 -- `scripts/verify-mainnet-setup.sh` - 验证脚本 -- `MAINNET_GENESIS_GUIDE.md` - 本文档 - -## 🆘 获取帮助 - -如果遇到问题: - -1. 运行验证脚本查看详细状态 -2. 检查日志:`docker logs op-geth-seq` -3. 参考故障排查章节 - ---- - -最后更新:2025-11-25 - diff --git a/devnet/MAINNET_GENESIS_QUICKSTART.md b/devnet/MAINNET_GENESIS_QUICKSTART.md deleted file mode 100644 index 1d4b586..0000000 --- a/devnet/MAINNET_GENESIS_QUICKSTART.md +++ /dev/null @@ -1,110 +0,0 @@ -# Mainnet Genesis 快速开始 - -## 🚀 5 分钟快速部署 - -### 1. 配置(30 秒) - -```bash -cd devnet -cp example.env .env -vim .env -``` - -修改以下配置: - -```bash -# 启用主网 genesis -USE_MAINNET_GENESIS=true - -# 必须启用 MIN_RUN -MIN_RUN=true - -# 注入测试账户(推荐) -INJECT_L2_TEST_ACCOUNT=true -TEST_ACCOUNT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -TEST_ACCOUNT_BALANCE=0x52B7D2DCC80CD2E4000000 # 100K ETH - -# Fork 配置(使用你的主网快照点) -FORK_BLOCK=8593920 -PARENT_HASH=0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a -``` - -### 2. 部署(15-20 分钟) - -```bash -# 确保 genesis 文件存在 -ls -lh mainnet.genesis.json # 或 ../rpc-setup/genesis-mainnet.tar.gz - -# 一键部署 -./0-all.sh -``` - -### 3. 验证(1 分钟) - -```bash -# 运行验证 -./scripts/verify-mainnet-setup.sh - -# 检查 L2 状态 -cast block-number -r http://localhost:8123 -# 应该输出: 8593921 - -# 检查测试账户 -cast balance 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -r http://localhost:8123 -# 应该输出: 100000000000000000000000 (100K ETH) -``` - -### 4. 测试交易(可选) - -```bash -# 使用测试账户发送交易 -cast send \ - --private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d \ - --value 1ether \ - <目标地址> \ - -r http://localhost:8123 -``` - -## ⚠️ 重要提示 - -1. **必须 MIN_RUN=true** - 主网 genesis 太大,无法构建 prestate -2. **需要 50GB+ 磁盘空间** - genesis + 数据库 -3. **推荐 SSD** - 初始化速度快 3-5 倍 -4. **需要 16GB+ 内存** - Docker 配置 - -## 📖 完整文档 - -详细说明请查看:`MAINNET_GENESIS_GUIDE.md` - -## 🆘 故障排查 - -### 错误 1: "Mainnet genesis requires MIN_RUN=true" -```bash -# 解决:在 .env 中设置 -MIN_RUN=true -``` - -### 错误 2: Genesis 文件未找到 -```bash -# 解决:确保文件存在 -ls mainnet.genesis.json -# 或 -ls ../rpc-setup/genesis-mainnet.tar.gz -``` - -### 错误 3: 磁盘空间不足 -```bash -# 检查空间 -df -h -# 需要至少 50GB -``` - -## 🎉 完成! - -现在你可以: -- ✅ 与主网合约交互 -- ✅ 测试主网账户状态 -- ✅ 验证迁移逻辑 -- ✅ 进行功能测试 - -**注意:** 此模式不支持争议游戏和欺诈证明(需要完整模式) From 7cc7e28fdfe8d1a30f3f9378577a3fc7cf101fff Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 3 Dec 2025 11:49:57 +0800 Subject: [PATCH 3/9] update --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 4ce5a33..87dddfe 100644 --- a/.gitignore +++ b/.gitignore @@ -35,5 +35,4 @@ devnet/data devnet/saved-cannon-data devnet/init.log devnet/l1-geth/ -profiling/ -devnet/test-pp-op \ No newline at end of file +profiling/ \ No newline at end of file From 4c8f69eff59f09e5f90a2a2e96224136eb2d0cbe Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 3 Dec 2025 11:54:02 +0800 Subject: [PATCH 4/9] update --- devnet/scripts/test-mainnet-genesis.sh | 183 --------------------- devnet/scripts/verify-mainnet-setup.sh | 218 ------------------------- 2 files changed, 401 deletions(-) delete mode 100755 devnet/scripts/test-mainnet-genesis.sh delete mode 100755 devnet/scripts/verify-mainnet-setup.sh diff --git a/devnet/scripts/test-mainnet-genesis.sh b/devnet/scripts/test-mainnet-genesis.sh deleted file mode 100755 index 01301f5..0000000 --- a/devnet/scripts/test-mainnet-genesis.sh +++ /dev/null @@ -1,183 +0,0 @@ -#!/bin/bash -# Quick test script for mainnet genesis functionality -# This script validates the changes without running the full deployment - -set -e - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DEVNET_DIR="$(dirname "$SCRIPT_DIR")" - -echo "🧪 Testing mainnet genesis implementation..." -echo "" - -# Test 1: Check files exist -echo "1️⃣ Checking files..." -FILES=( - "$DEVNET_DIR/example.env" - "$DEVNET_DIR/3-op-init.sh" - "$SCRIPT_DIR/process-mainnet-genesis.py" - "$SCRIPT_DIR/verify-mainnet-setup.sh" -) - -for file in "${FILES[@]}"; do - if [ -f "$file" ]; then - echo " ✅ $(basename $file)" - else - echo " ❌ $(basename $file) not found" - exit 1 - fi -done - -echo "" - -# Test 2: Check configuration variables -echo "2️⃣ Checking configuration variables in example.env..." -VARS=( - "USE_MAINNET_GENESIS" - "MAINNET_GENESIS_PATH" - "INJECT_L2_TEST_ACCOUNT" - "TEST_ACCOUNT_ADDRESS" - "TEST_ACCOUNT_BALANCE" -) - -for var in "${VARS[@]}"; do - if grep -q "^$var=" "$DEVNET_DIR/example.env"; then - echo " ✅ $var" - else - echo " ❌ $var not found" - exit 1 - fi -done - -echo "" - -# Test 3: Check Python script syntax -echo "3️⃣ Checking Python script syntax..." -if python3 -m py_compile "$SCRIPT_DIR/process-mainnet-genesis.py" 2>/dev/null; then - echo " ✅ Python syntax valid" -else - echo " ❌ Python syntax error" - exit 1 -fi - -echo "" - -# Test 4: Check Python script help -echo "4️⃣ Testing Python script help..." -if python3 "$SCRIPT_DIR/process-mainnet-genesis.py" 2>&1 | grep -q "Usage"; then - echo " ✅ Help text displayed" -else - echo " ❌ Help text not working" - exit 1 -fi - -echo "" - -# Test 5: Check bash functions in 3-op-init.sh -echo "5️⃣ Checking bash functions..." -if grep -q "detect_genesis_mode()" "$DEVNET_DIR/3-op-init.sh"; then - echo " ✅ detect_genesis_mode() function added" -else - echo " ❌ detect_genesis_mode() function not found" - exit 1 -fi - -if grep -q "prepare_mainnet_genesis()" "$DEVNET_DIR/3-op-init.sh"; then - echo " ✅ prepare_mainnet_genesis() function added" -else - echo " ❌ prepare_mainnet_genesis() function not found" - exit 1 -fi - -echo "" - -# Test 6: Check mode selection logic -echo "6️⃣ Checking mode selection logic..." -if grep -q "if detect_genesis_mode; then" "$DEVNET_DIR/3-op-init.sh"; then - echo " ✅ Mode selection logic added" -else - echo " ❌ Mode selection logic not found" - exit 1 -fi - -echo "" - -# Test 7: Simulate configuration check -echo "7️⃣ Simulating configuration validation..." - -# Create temporary test env -TEST_ENV=$(mktemp) -cat > "$TEST_ENV" << 'EOF' -USE_MAINNET_GENESIS=true -MIN_RUN=true -FORK_BLOCK=8593920 -PARENT_HASH=0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a -MAINNET_GENESIS_PATH=mainnet.genesis.json -INJECT_L2_TEST_ACCOUNT=true -TEST_ACCOUNT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -TEST_ACCOUNT_BALANCE=0x52B7D2DCC80CD2E4000000 -EOF - -source "$TEST_ENV" - -if [ "$USE_MAINNET_GENESIS" = "true" ] && [ "$MIN_RUN" = "true" ]; then - echo " ✅ Configuration validation logic works" -else - echo " ❌ Configuration validation failed" - rm "$TEST_ENV" - exit 1 -fi - -rm "$TEST_ENV" - -echo "" - -# Test 8: Test account address validation -echo "8️⃣ Validating test account address..." -EXPECTED_ADDR="0x70997970C51812dc3A010C7d01b50e0d17dc79C8" -if grep -q "$EXPECTED_ADDR" "$DEVNET_DIR/example.env"; then - echo " ✅ Test account address configured: $EXPECTED_ADDR" -else - echo " ⚠️ Test account address not found in example.env" -fi - -echo "" - -# Test 9: Check script permissions -echo "9️⃣ Checking script permissions..." -SCRIPTS=( - "$SCRIPT_DIR/process-mainnet-genesis.py" - "$SCRIPT_DIR/verify-mainnet-setup.sh" -) - -for script in "${SCRIPTS[@]}"; do - if [ -x "$script" ]; then - echo " ✅ $(basename $script) is executable" - else - echo " ⚠️ $(basename $script) is not executable (will be set)" - chmod +x "$script" - fi -done - -echo "" - -# Summary -echo "═══════════════════════════════════════" -echo "✅ All tests passed!" -echo "═══════════════════════════════════════" -echo "" -echo "📋 Implementation Summary:" -echo " • example.env: 5 new configuration variables" -echo " • 3-op-init.sh: 2 new functions, mode selection logic" -echo " • process-mainnet-genesis.py: High-performance JSON processor" -echo " • verify-mainnet-setup.sh: Comprehensive validation script" -echo "" -echo "🚀 Ready to test with mainnet genesis data!" -echo "" -echo "Next steps:" -echo "1. Set USE_MAINNET_GENESIS=true in .env" -echo "2. Ensure mainnet.genesis.json exists" -echo "3. Run: ./0-all.sh" -echo "4. Verify: ./scripts/verify-mainnet-setup.sh" -echo "" - diff --git a/devnet/scripts/verify-mainnet-setup.sh b/devnet/scripts/verify-mainnet-setup.sh deleted file mode 100755 index 06baa9b..0000000 --- a/devnet/scripts/verify-mainnet-setup.sh +++ /dev/null @@ -1,218 +0,0 @@ -#!/bin/bash -set -e - -source .env - -echo "🔍 Verifying mainnet genesis deployment..." -echo "" - -# ======================================== -# 1. Configuration Check -# ======================================== -echo "1️⃣ Configuration Validation" -echo "───────────────────────────" - -if [ "$USE_MAINNET_GENESIS" = "true" ]; then - echo " ✅ Mainnet genesis mode: ENABLED" - - if [ "$MIN_RUN" = "true" ]; then - echo " ✅ MIN_RUN: true (required)" - else - echo " ❌ ERROR: MIN_RUN must be true for mainnet genesis" - exit 1 - fi - - if [ -n "$FORK_BLOCK" ] && [ -n "$PARENT_HASH" ]; then - echo " ✅ Fork block: $FORK_BLOCK" - echo " ✅ Parent hash: ${PARENT_HASH:0:20}..." - else - echo " ❌ ERROR: FORK_BLOCK and PARENT_HASH not configured" - exit 1 - fi -else - echo " ℹ️ Mainnet genesis mode: DISABLED (using generated genesis)" - echo " Skipping mainnet-specific checks..." - echo "" - exit 0 -fi - -echo "" - -# ======================================== -# 2. Genesis Files Check -# ======================================== -echo "2️⃣ Genesis Files" -echo "───────────────────────────" - -if [ -f "config-op/genesis.json" ]; then - GENESIS_SIZE=$(du -h config-op/genesis.json | cut -f1) - GENESIS_NUMBER=$(jq -r '.number' config-op/genesis.json 2>/dev/null || echo "error") - GENESIS_PARENT=$(jq -r '.parentHash' config-op/genesis.json 2>/dev/null || echo "error") - GENESIS_LEGACY=$(jq -r '.config.legacyXLayerBlock' config-op/genesis.json 2>/dev/null || echo "error") - GENESIS_ACCOUNTS=$(jq '.alloc | length' config-op/genesis.json 2>/dev/null || echo "error") - - echo " ✅ genesis.json exists ($GENESIS_SIZE)" - echo " • number: $GENESIS_NUMBER" - echo " • parentHash: ${GENESIS_PARENT:0:20}..." - echo " • legacyXLayerBlock: $GENESIS_LEGACY" - echo " • accounts: $GENESIS_ACCOUNTS" - - # Verify values match configuration - EXPECTED_BLOCK=$((FORK_BLOCK + 1)) - if [ "$GENESIS_NUMBER" != "$EXPECTED_BLOCK" ]; then - echo " ⚠️ WARNING: Genesis number mismatch!" - echo " Expected: $EXPECTED_BLOCK" - echo " Actual: $GENESIS_NUMBER" - fi - - if [ "$GENESIS_PARENT" != "$PARENT_HASH" ]; then - echo " ⚠️ WARNING: Parent hash mismatch!" - echo " Expected: $PARENT_HASH" - echo " Actual: $GENESIS_PARENT" - fi -else - echo " ❌ genesis.json not found" - exit 1 -fi - -if [ -f "config-op/genesis-reth.json" ]; then - echo " ✅ genesis-reth.json exists" -else - echo " ⚠️ genesis-reth.json not found" -fi - -echo "" - -# ======================================== -# 3. Rollup Configuration Check -# ======================================== -echo "3️⃣ Rollup Configuration" -echo "───────────────────────────" - -if [ -f "config-op/rollup.json" ]; then - ROLLUP_NUMBER=$(jq -r '.genesis.l2.number' config-op/rollup.json 2>/dev/null || echo "error") - ROLLUP_HASH=$(jq -r '.genesis.l2.hash' config-op/rollup.json 2>/dev/null || echo "error") - - echo " ✅ rollup.json exists" - echo " • genesis.l2.number: $ROLLUP_NUMBER" - echo " • genesis.l2.hash: ${ROLLUP_HASH:0:20}..." - - if [ "$ROLLUP_NUMBER" != "$EXPECTED_BLOCK" ]; then - echo " ⚠️ WARNING: Rollup number mismatch!" - echo " Expected: $EXPECTED_BLOCK" - echo " Actual: $ROLLUP_NUMBER" - fi -else - echo " ❌ rollup.json not found" - exit 1 -fi - -echo "" - -# ======================================== -# 4. Database Check -# ======================================== -echo "4️⃣ Initialized Databases" -echo "───────────────────────────" - -if [ -d "data/op-$SEQ_TYPE-seq/geth/chaindata" ] || [ -d "data/op-$SEQ_TYPE-seq/db" ]; then - DB_SIZE=$(du -sh data/op-$SEQ_TYPE-seq 2>/dev/null | cut -f1 || echo "unknown") - echo " ✅ op-$SEQ_TYPE-seq: $DB_SIZE" -else - echo " ⚠️ op-$SEQ_TYPE-seq database not initialized" -fi - -if [ -d "data/op-$RPC_TYPE-rpc/geth/chaindata" ] || [ -d "data/op-$RPC_TYPE-rpc/db" ]; then - RPC_SIZE=$(du -sh data/op-$RPC_TYPE-rpc 2>/dev/null | cut -f1 || echo "unknown") - echo " ✅ op-$RPC_TYPE-rpc: $RPC_SIZE" -else - echo " ℹ️ op-$RPC_TYPE-rpc database not initialized yet" -fi - -echo "" - -# ======================================== -# 5. L1 Account Balances -# ======================================== -echo "5️⃣ L1 Account Balances" -echo "───────────────────────────" - -if docker ps --format '{{.Names}}' | grep -q l1-geth; then - echo " ℹ️ Checking L1 balances..." - - PROPOSER_ADDR=$(cast wallet address $OP_PROPOSER_PRIVATE_KEY 2>/dev/null || echo "error") - BATCHER_ADDR=$(cast wallet address $OP_BATCHER_PRIVATE_KEY 2>/dev/null || echo "error") - - if [ "$PROPOSER_ADDR" != "error" ]; then - PROPOSER_BAL=$(cast balance $PROPOSER_ADDR -r $L1_RPC_URL 2>/dev/null || echo "0") - PROPOSER_ETH=$(cast to-unit $PROPOSER_BAL ether 2>/dev/null || echo "0") - echo " • Proposer ($PROPOSER_ADDR): $PROPOSER_ETH ETH" - fi - - if [ "$BATCHER_ADDR" != "error" ]; then - BATCHER_BAL=$(cast balance $BATCHER_ADDR -r $L1_RPC_URL 2>/dev/null || echo "0") - BATCHER_ETH=$(cast to-unit $BATCHER_BAL ether 2>/dev/null || echo "0") - echo " • Batcher ($BATCHER_ADDR): $BATCHER_ETH ETH" - fi -else - echo " ⚠️ L1 node not running (start with 1-start-l1.sh)" -fi - -echo "" - -# ======================================== -# 6. L2 Test Account -# ======================================== -if [ "$INJECT_L2_TEST_ACCOUNT" = "true" ]; then - echo "6️⃣ L2 Test Account" - echo "───────────────────────────" - - # Check in genesis - ACCOUNT_KEY=$(echo "$TEST_ACCOUNT_ADDRESS" | tr '[:upper:]' '[:lower:]' | sed 's/0x//') - GENESIS_BALANCE=$(jq -r ".alloc[\"$ACCOUNT_KEY\"].balance // \"not found\"" config-op/genesis.json 2>/dev/null) - - if [ "$GENESIS_BALANCE" != "not found" ]; then - BALANCE_WEI=$(python3 -c "print(int('$GENESIS_BALANCE', 16))" 2>/dev/null || echo "0") - BALANCE_ETH=$(python3 -c "print(int('$GENESIS_BALANCE', 16) / 10**18)" 2>/dev/null || echo "0") - echo " ✅ Test account in genesis: $TEST_ACCOUNT_ADDRESS" - echo " • Balance: $BALANCE_ETH ETH" - else - echo " ⚠️ Test account not found in genesis" - fi - - echo "" -fi - -# ======================================== -# 7. Prestate Files (Should NOT Exist) -# ======================================== -echo "7️⃣ Prestate Files (MIN_RUN Check)" -echo "───────────────────────────" - -if [ -f "config-op/genesis.json.gz" ]; then - echo " ℹ️ genesis.json.gz exists (not needed in MIN_RUN mode)" -else - echo " ✅ genesis.json.gz not present (correct for MIN_RUN)" -fi - -if [ -d "data/cannon-data" ]; then - echo " ℹ️ cannon-data directory exists (not needed in MIN_RUN mode)" -else - echo " ✅ cannon-data not present (correct for MIN_RUN)" -fi - -echo "" -echo "═══════════════════════════" -echo "✅ All verifications passed!" -echo "═══════════════════════════" -echo "" - -if docker ps --format '{{.Names}}' | grep -q op-geth-seq || docker ps --format '{{.Names}}' | grep -q op-reth-seq; then - echo "🚀 Services Status:" - docker ps --format 'table {{.Names}}\t{{.Status}}' | grep -E 'op-|l1-' || echo "No OP Stack services running" -else - echo "ℹ️ Services not yet started (run 4-op-start-service.sh)" -fi - -echo "" - From 726c200aba858a14f727b6025d428c27fe92947d Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 3 Dec 2025 12:20:06 +0800 Subject: [PATCH 5/9] update --- devnet/3-op-init.sh | 173 +-------- devnet/example.env | 19 +- .../process-mainnet-genesis.cpython-314.pyc | Bin 7546 -> 0 bytes devnet/scripts/prepare-genesis.sh | 334 ++++++++++++++++++ devnet/scripts/process-mainnet-genesis.py | 174 --------- 5 files changed, 342 insertions(+), 358 deletions(-) delete mode 100644 devnet/scripts/__pycache__/process-mainnet-genesis.cpython-314.pyc create mode 100755 devnet/scripts/prepare-genesis.sh delete mode 100755 devnet/scripts/process-mainnet-genesis.py diff --git a/devnet/3-op-init.sh b/devnet/3-op-init.sh index 9d9d42f..86159c5 100755 --- a/devnet/3-op-init.sh +++ b/devnet/3-op-init.sh @@ -13,154 +13,10 @@ sed_inplace() { } # ======================================== -# Genesis Mode Detection +# Genesis Preparation (unified script) # ======================================== -detect_genesis_mode() { - if [ "$USE_MAINNET_GENESIS" = "true" ]; then - echo "🌐 Mainnet genesis mode enabled" - - # Enforce MIN_RUN requirement - if [ "$MIN_RUN" != "true" ]; then - echo "" - echo "❌ ERROR: Mainnet genesis requires MIN_RUN=true" - echo "" - echo "Reason:" - echo " • Mainnet genesis is too large (6.6GB+)" - echo " • Building op-program prestate would fail or timeout" - echo " • Dispute game features are not compatible with mainnet data" - echo "" - echo "Solution:" - echo " Set MIN_RUN=true in your .env file" - echo "" - exit 1 - fi - - echo "✅ MIN_RUN=true verified" - return 0 - else - echo "🔧 Using generated genesis mode" - return 1 - fi -} - -# ======================================== -# Prepare Mainnet Genesis -# ======================================== -prepare_mainnet_genesis() { - echo "" - echo "📦 Preparing mainnet genesis..." - - PWD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - - # Check if genesis file exists - if [ ! -f "$MAINNET_GENESIS_PATH" ]; then - echo "🔍 Genesis not found at: $MAINNET_GENESIS_PATH" - - # Try to extract from tar.gz - TAR_PATH="../rpc-setup/genesis-mainnet.tar.gz" - if [ -f "$TAR_PATH" ]; then - echo "📂 Extracting from $TAR_PATH..." - echo "⏳ This may take 2-5 minutes (1.6GB → 6.6GB)..." - - tar -xzf "$TAR_PATH" -C "$PWD_DIR" - - if [ -f "$PWD_DIR/merged.genesis.json" ]; then - mv "$PWD_DIR/merged.genesis.json" "$MAINNET_GENESIS_PATH" - echo "✅ Extracted successfully" - else - echo "❌ ERROR: Extraction failed (merged.genesis.json not found)" - exit 1 - fi - else - echo "❌ ERROR: Neither genesis file nor tar.gz found" - echo " Looking for:" - echo " - $MAINNET_GENESIS_PATH" - echo " - $TAR_PATH" - exit 1 - fi - fi - - # Verify file - GENESIS_SIZE_MB=$(du -m "$MAINNET_GENESIS_PATH" | cut -f1) - GENESIS_SIZE_GB=$(echo "scale=2; $GENESIS_SIZE_MB / 1024" | bc) - echo "✅ Found mainnet genesis ($GENESIS_SIZE_GB GB)" - - # Validate configuration - if [ -z "$FORK_BLOCK" ] || [ -z "$PARENT_HASH" ]; then - echo "❌ ERROR: FORK_BLOCK and PARENT_HASH must be set" - exit 1 - fi - - NEXT_BLOCK=$((FORK_BLOCK + 1)) - echo "🎯 Fork configuration:" - echo " • FORK_BLOCK: $FORK_BLOCK" - echo " • PARENT_HASH: $PARENT_HASH" - echo " • Next block: $NEXT_BLOCK" - - # Process genesis using Python (fast) - echo "" - echo "🔧 Processing genesis (this may take 1-2 minutes)..." - - mkdir -p "$CONFIG_DIR" - - # Prepare arguments - PROCESS_ARGS=( - "$MAINNET_GENESIS_PATH" - "$CONFIG_DIR/genesis.json" - "$NEXT_BLOCK" - "$PARENT_HASH" - ) - - # Add test account injection if enabled - if [ "$INJECT_L2_TEST_ACCOUNT" = "true" ]; then - echo "💰 Test account injection enabled" - PROCESS_ARGS+=("$TEST_ACCOUNT_ADDRESS" "$TEST_ACCOUNT_BALANCE") - fi - - # Run Python script - if ! python3 scripts/process-mainnet-genesis.py "${PROCESS_ARGS[@]}"; then - echo "❌ ERROR: Failed to process mainnet genesis" - exit 1 - fi - - echo "" - echo "✅ Mainnet genesis prepared" - echo " • Output: $CONFIG_DIR/genesis.json" - echo " • Reth version: $CONFIG_DIR/genesis-reth.json" - echo " • Accounts: $(python3 -c "import json; print(len(json.load(open('$CONFIG_DIR/genesis.json'))['alloc']))")" - echo "" -} - -# Check if FORK_BLOCK is set -if [ -z "$FORK_BLOCK" ]; then - echo " ❌ FORK_BLOCK environment variable is not set" - echo "Please set FORK_BLOCK in your .env file" - exit 1 -fi - -# ======================================== -# Genesis Processing - Mode Selection -# ======================================== -if detect_genesis_mode; then - # Mainnet genesis mode - prepare_mainnet_genesis - - # Update rollup.json - NEXT_BLOCK_NUMBER=$((FORK_BLOCK + 1)) - sed_inplace 's/"number": 0/"number": '"$NEXT_BLOCK_NUMBER"'/' ./config-op/rollup.json - -else - # Generated genesis mode (original logic) - FORK_BLOCK_HEX=$(printf "0x%x" "$FORK_BLOCK") - sed_inplace '/"config": {/,/}/ s/"optimism": {/"legacyXLayerBlock": '"$((FORK_BLOCK + 1))"',\n "optimism": {/' ./config-op/genesis.json - sed_inplace 's/"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"/"parentHash": "'"$PARENT_HASH"'"/' ./config-op/genesis.json - sed_inplace '/"70997970c51812dc3a010c7d01b50e0d17dc79c8": {/,/}/ s/"balance": "[^"]*"/"balance": "0x446c3b15f9926687d2c40534fdb564000000000000"/' ./config-op/genesis.json - 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-reth.json - sed_inplace 's/"number": "0x0"/"number": "'"$NEXT_BLOCK_NUMBER_HEX"'"/' ./config-op/genesis-reth.json -fi +source scripts/prepare-genesis.sh +prepare_genesis # Extract contract addresses from state.json and update .env file echo "🔧 Extracting contract addresses from state.json..." @@ -368,27 +224,8 @@ if [ "$MIN_RUN" = "true" ]; then echo "" echo "⚡ MIN_RUN mode enabled: Skipping op-program prestate build" - # Show mainnet-specific summary - if [ "$USE_MAINNET_GENESIS" = "true" ]; then - echo "" - echo "🌐 Mainnet Genesis Deployment Summary:" - echo " • Source: $MAINNET_GENESIS_PATH" - echo " • Starting block: $((FORK_BLOCK + 1))" - echo " • Genesis size: $(du -h $CONFIG_DIR/genesis.json | cut -f1)" - - if [ "$INJECT_L2_TEST_ACCOUNT" = "true" ]; then - echo " • Test account: $TEST_ACCOUNT_ADDRESS (injected)" - BALANCE_ETH=$(python3 -c "print(int('$TEST_ACCOUNT_BALANCE', 16) / 10**18)") - echo " • Test balance: $BALANCE_ETH ETH on L2" - fi - - echo " • Database: $(du -sh data/op-$SEQ_TYPE-seq 2>/dev/null | cut -f1 || echo 'initializing...')" - echo "" - echo "ℹ️ Notes:" - echo " • All mainnet accounts preserved in L2 genesis" - echo " • L1 accounts funded by 1-start-l1.sh (100 ETH each)" - echo " • Dispute game features skipped (not compatible with mainnet data)" - fi + # Show mainnet-specific summary (function from prepare-genesis.sh) + print_mainnet_summary echo "" echo "✅ Initialization completed for minimal run" diff --git a/devnet/example.env b/devnet/example.env index d54d459..7db0ccc 100644 --- a/devnet/example.env +++ b/devnet/example.env @@ -140,24 +140,11 @@ PARENT_HASH="0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a" NEW_BLOCK_HASH=0xddb9bdc86631494bab4b4749c4575035e2383da7c96d32d31341de862b1dd6c9 # ============================================================================== -# Mainnet Genesis Configuration +# Fake Mainnet Configuration # ============================================================================== -# Use mainnet genesis instead of generating new one +# Use mainnet genesis to simulate mainnet environment # ⚠️ REQUIRES: MIN_RUN=true (mainnet genesis is too large to build prestate) -USE_MAINNET_GENESIS=false - -# Path to mainnet genesis file (relative to devnet directory) -# Supported formats: -# - Direct path: mainnet.genesis.json -# - Compressed: ../rpc-setup/genesis-mainnet.tar.gz (auto-extracts to merged.genesis.json) -MAINNET_GENESIS_PATH=mainnet.genesis.json - -# Inject test account balance into L2 genesis for testing convenience -# This account will be funded with TEST_ACCOUNT_BALANCE in L2 genesis -# Note: L1 accounts are still funded separately in 1-start-l1.sh -INJECT_L2_TEST_ACCOUNT=true -TEST_ACCOUNT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -TEST_ACCOUNT_BALANCE=0x52B7D2DCC80CD2E4000000 # 100,000 ETH +USE_FAKE_MAINNET=false # ============================================================================== # Other Configuration diff --git a/devnet/scripts/__pycache__/process-mainnet-genesis.cpython-314.pyc b/devnet/scripts/__pycache__/process-mainnet-genesis.cpython-314.pyc deleted file mode 100644 index f8df57a5b9c5ea598f4fb063266b32e71757ea8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7546 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 6 and sys.argv[6] else None + test_balance = sys.argv[7] if len(sys.argv) > 7 and sys.argv[7] else None + + # Load genesis + file_size_gb = os.path.getsize(input_file) / (1024**3) + print(f" Loading genesis ({file_size_gb:.2f} GB)...") + + with open(input_file, 'r') as f: + genesis = json.load(f) + + account_count = len(genesis.get('alloc', {})) + print(f" ✓ Loaded {account_count:,} accounts") + + # Update config fields + if 'config' not in genesis: + genesis['config'] = {} + + # Replace chainId with configured value + old_chain_id = genesis['config'].get('chainId', 'unknown') + genesis['config']['chainId'] = chain_id + print(f" ✓ chainId: {old_chain_id} → {chain_id}") + + genesis['config']['legacyXLayerBlock'] = next_block + genesis['parentHash'] = parent_hash + genesis['number'] = 0 # Required for geth init + + # Update timestamp to current time (avoid conductor "unsafe head falling behind" error) + current_timestamp = int(time.time()) + genesis['timestamp'] = hex(current_timestamp) + + print(f" ✓ legacyXLayerBlock: {next_block}") + print(f" ✓ parentHash: {parent_hash[:20]}...") + print(f" ✓ number: 0 (required for geth init)") + print(f" ✓ timestamp: {hex(current_timestamp)}") + + # Inject test account (enabled by default in mainnet mode) + if test_account and test_balance: + if 'alloc' not in genesis: + genesis['alloc'] = {} + + account_key = test_account.lower() + if account_key.startswith('0x'): + account_key = account_key[2:] + + if account_key in genesis['alloc']: + print(f" ⚠️ Account {test_account} exists, updating balance...") + genesis['alloc'][account_key]['balance'] = test_balance + else: + print(f" 💰 Injecting test account {test_account}...") + genesis['alloc'][account_key] = {"balance": test_balance} + + balance_eth = int(test_balance, 16) / (10**18) + print(f" ✓ Test balance: {balance_eth:,.0f} ETH") + + # Write genesis.json + print(f" Writing genesis.json...") + with open(output_file, 'w') as f: + json.dump(genesis, f, separators=(',', ':')) + + # Create reth version (number as hex string "0x0") + reth_file = output_file.replace('.json', '-reth.json') + genesis['number'] = "0x0" + + print(f" Writing genesis-reth.json...") + with open(reth_file, 'w') as f: + json.dump(genesis, f, separators=(',', ':')) + + output_size_gb = os.path.getsize(output_file) / (1024**3) + print(f" ✓ Output size: {output_size_gb:.2f} GB") + +if __name__ == '__main__': + main() +PYTHON_EOF + + if [ $? -ne 0 ]; then + echo "❌ ERROR: Failed to process mainnet genesis" + exit 1 + fi + + # 5. Update rollup.json + _sed_inplace 's/"number": 0/"number": '"$NEXT_BLOCK"'/' ./config-op/rollup.json + + echo "" + echo "✅ Mainnet genesis prepared" + echo " • Output: $CONFIG_DIR/genesis.json" + echo " • Reth version: $CONFIG_DIR/genesis-reth.json" +} + +# ============================================================================== +# Generated Genesis Mode (Original Logic) +# ============================================================================== +_prepare_generated_genesis() { + echo "" + echo "🔧 Generated genesis mode" + + NEXT_BLOCK=$((FORK_BLOCK + 1)) + NEXT_BLOCK_HEX=$(printf "0x%x" "$NEXT_BLOCK") + + echo " • FORK_BLOCK: $FORK_BLOCK" + echo " • Next block: $NEXT_BLOCK" + + # Update genesis.json + _sed_inplace '/"config": {/,/}/ s/"optimism": {/"legacyXLayerBlock": '"$NEXT_BLOCK"',\n "optimism": {/' ./config-op/genesis.json + _sed_inplace 's/"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"/"parentHash": "'"$PARENT_HASH"'"/' ./config-op/genesis.json + _sed_inplace '/"70997970c51812dc3a010c7d01b50e0d17dc79c8": {/,/}/ s/"balance": "[^"]*"/"balance": "0x446c3b15f9926687d2c40534fdb564000000000000"/' ./config-op/genesis.json + + # Update rollup.json + _sed_inplace 's/"number": 0/"number": '"$NEXT_BLOCK"'/' ./config-op/rollup.json + + # Create reth version + cp ./config-op/genesis.json ./config-op/genesis-reth.json + _sed_inplace 's/"number": "0x0"/"number": "'"$NEXT_BLOCK_HEX"'"/' ./config-op/genesis-reth.json + + echo "✅ Generated genesis prepared" +} + +# ============================================================================== +# Print Mainnet Summary (for MIN_RUN mode) +# ============================================================================== +print_mainnet_summary() { + if [ "$USE_FAKE_MAINNET" != "true" ]; then + return + fi + + echo "" + echo "🌐 Mainnet Genesis Deployment Summary:" + echo " • Source: $MAINNET_GENESIS_PATH" + echo " • Chain ID: $CHAIN_ID" + echo " • Starting block: $((FORK_BLOCK + 1))" + echo " • Genesis size: $(du -h $CONFIG_DIR/genesis.json | cut -f1)" + echo " • Test account: $TEST_ACCOUNT_ADDRESS (injected)" + + BALANCE_ETH=$(python3 -c "print(int('$TEST_ACCOUNT_BALANCE', 16) / 10**18)") + echo " • Test balance: $BALANCE_ETH ETH on L2" + + echo " • Database: $(du -sh data/op-$SEQ_TYPE-seq 2>/dev/null | cut -f1 || echo 'initializing...')" + echo "" + echo "ℹ️ Notes:" + echo " • All mainnet accounts preserved in L2 genesis" + echo " • L1 accounts funded by 1-start-l1.sh (100 ETH each)" + echo " • Dispute game features skipped (not compatible with mainnet data)" +} + +# ============================================================================== +# Main Entry Point +# ============================================================================== +prepare_genesis() { + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📦 Preparing Genesis" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + # Validate FORK_BLOCK + if [ -z "$FORK_BLOCK" ]; then + echo "❌ ERROR: FORK_BLOCK environment variable is not set" + echo "Please set FORK_BLOCK in your .env file" + exit 1 + fi + + # Select mode and prepare + if [ "$USE_FAKE_MAINNET" = "true" ]; then + _prepare_mainnet_genesis + else + _prepare_generated_genesis + fi + + echo "" +} + +# Run if executed directly (not sourced) +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + prepare_genesis +fi diff --git a/devnet/scripts/process-mainnet-genesis.py b/devnet/scripts/process-mainnet-genesis.py deleted file mode 100755 index 0c1b4b3..0000000 --- a/devnet/scripts/process-mainnet-genesis.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env python3 -""" -Process mainnet genesis.json for OP Stack deployment -- Updates block number, parentHash, and config fields -- Optionally injects test account balance -- Optimized for large files (6.6GB+) -""" - -import json -import sys -import os -import time -from typing import Optional - -def process_genesis( - input_file: str, - output_file: str, - next_block: int, - parent_hash: str, - test_account: Optional[str] = None, - test_balance: Optional[str] = None -) -> bool: - """ - Process mainnet genesis file with minimal memory footprint - - Args: - input_file: Path to source genesis.json - output_file: Path to output genesis.json - next_block: Next block number (FORK_BLOCK + 1) - parent_hash: Parent block hash - test_account: Optional test account address to inject - test_balance: Optional balance for test account (hex) - - Returns: - True if successful - """ - print(f"📖 Loading genesis from {input_file}...") - print(f" File size: {os.path.getsize(input_file) / (1024**3):.2f} GB") - - try: - with open(input_file, 'r') as f: - genesis = json.load(f) - - print(f"✅ Loaded genesis with {len(genesis.get('alloc', {}))} accounts") - - # Update config fields - print(f"🔧 Updating genesis configuration...") - if 'config' not in genesis: - genesis['config'] = {} - - genesis['config']['legacyXLayerBlock'] = next_block - genesis['parentHash'] = parent_hash - # NOTE: Keep number as 0 for geth init (geth doesn't support number > 0) - # Reth version will have hex number, rollup.json will have the actual number - genesis['number'] = 0 - - # CRITICAL: Update timestamp to current time to avoid conductor "unsafe head falling behind" error - current_timestamp = int(time.time()) - old_timestamp = genesis.get('timestamp', 0) - genesis['timestamp'] = hex(current_timestamp) - - print(f" ✓ legacyXLayerBlock: {next_block}") - print(f" ✓ number: 0 (required for geth init)") - print(f" ✓ parentHash: {parent_hash}") - print(f" ✓ timestamp: {hex(current_timestamp)} (updated from {hex(old_timestamp) if isinstance(old_timestamp, int) else old_timestamp})") - - # Inject test account if requested - if test_account and test_balance: - if 'alloc' not in genesis: - genesis['alloc'] = {} - - account_key = test_account.lower() - if account_key.startswith('0x'): - account_key = account_key[2:] - - if account_key in genesis['alloc']: - print(f"⚠️ Account {test_account} already exists, updating balance...") - genesis['alloc'][account_key]['balance'] = test_balance - else: - print(f"💰 Injecting test account {test_account}...") - genesis['alloc'][account_key] = {"balance": test_balance} - - # Convert balance to decimal for display - balance_wei = int(test_balance, 16) - balance_eth = balance_wei / (10**18) - print(f" ✓ Balance: {balance_eth:,.0f} ETH") - - # Write output - print(f"💾 Writing to {output_file}...") - with open(output_file, 'w') as f: - # Use separators to minimize file size - json.dump(genesis, f, separators=(',', ':')) - - output_size = os.path.getsize(output_file) - print(f"✅ Successfully processed genesis ({output_size / (1024**3):.2f} GB)") - - return True - - except Exception as e: - print(f"❌ ERROR: {e}", file=sys.stderr) - return False - -def create_reth_version(genesis_file: str, reth_file: str, next_block_hex: str) -> bool: - """ - Create Reth-compatible genesis (number as hex string "0x0") - - Args: - genesis_file: Source genesis.json - reth_file: Output genesis-reth.json - next_block_hex: Block number in hex format (should be "0x0" for init) - - Returns: - True if successful - """ - print(f"🔧 Creating Reth-compatible genesis...") - - try: - with open(genesis_file, 'r') as f: - genesis = json.load(f) - - # Reth expects number as hex string "0x0" for init - genesis['number'] = "0x0" - - with open(reth_file, 'w') as f: - json.dump(genesis, f, separators=(',', ':')) - - print(f"✅ Created {reth_file} (number: 0x0 for reth init)") - return True - - except Exception as e: - print(f"❌ ERROR creating Reth genesis: {e}", file=sys.stderr) - return False - -def main(): - if len(sys.argv) < 5: - print("Usage: process-mainnet-genesis.py [test_account] [test_balance]") - print("") - print("Example:") - print(" process-mainnet-genesis.py mainnet.genesis.json genesis.json 8593921 0x6912... 0x7099... 0x52B7...") - sys.exit(1) - - input_file = sys.argv[1] - output_file = sys.argv[2] - next_block = int(sys.argv[3]) - parent_hash = sys.argv[4] - test_account = sys.argv[5] if len(sys.argv) > 5 else None - test_balance = sys.argv[6] if len(sys.argv) > 6 else None - - # Process main genesis - success = process_genesis( - input_file, - output_file, - next_block, - parent_hash, - test_account, - test_balance - ) - - if not success: - sys.exit(1) - - # Create Reth version (number must be "0x0" for init) - reth_file = output_file.replace('.json', '-reth.json') - - if not create_reth_version(output_file, reth_file, "0x0"): - sys.exit(1) - - print("") - print("🎉 Genesis processing complete!") - sys.exit(0) - -if __name__ == '__main__': - main() - From e1bd50f2e429fdc653ea4c66e8eaa341cfea679a Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 3 Dec 2025 12:22:33 +0800 Subject: [PATCH 6/9] update --- devnet/3-op-init.sh | 8 +------- devnet/scripts/prepare-genesis.sh | 27 --------------------------- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/devnet/3-op-init.sh b/devnet/3-op-init.sh index 86159c5..9596c20 100755 --- a/devnet/3-op-init.sh +++ b/devnet/3-op-init.sh @@ -221,14 +221,8 @@ gzip -c config-op/genesis.json > config-op/genesis.json.gz # Check if MIN_RUN mode is enabled if [ "$MIN_RUN" = "true" ]; then - echo "" echo "⚡ MIN_RUN mode enabled: Skipping op-program prestate build" - - # Show mainnet-specific summary (function from prepare-genesis.sh) - print_mainnet_summary - - echo "" - echo "✅ Initialization completed for minimal run" + echo "✅ Initialization completed for minimal run (no dispute game support)" exit 0 fi diff --git a/devnet/scripts/prepare-genesis.sh b/devnet/scripts/prepare-genesis.sh index b024b34..02934f7 100755 --- a/devnet/scripts/prepare-genesis.sh +++ b/devnet/scripts/prepare-genesis.sh @@ -276,33 +276,6 @@ _prepare_generated_genesis() { echo "✅ Generated genesis prepared" } -# ============================================================================== -# Print Mainnet Summary (for MIN_RUN mode) -# ============================================================================== -print_mainnet_summary() { - if [ "$USE_FAKE_MAINNET" != "true" ]; then - return - fi - - echo "" - echo "🌐 Mainnet Genesis Deployment Summary:" - echo " • Source: $MAINNET_GENESIS_PATH" - echo " • Chain ID: $CHAIN_ID" - echo " • Starting block: $((FORK_BLOCK + 1))" - echo " • Genesis size: $(du -h $CONFIG_DIR/genesis.json | cut -f1)" - echo " • Test account: $TEST_ACCOUNT_ADDRESS (injected)" - - BALANCE_ETH=$(python3 -c "print(int('$TEST_ACCOUNT_BALANCE', 16) / 10**18)") - echo " • Test balance: $BALANCE_ETH ETH on L2" - - echo " • Database: $(du -sh data/op-$SEQ_TYPE-seq 2>/dev/null | cut -f1 || echo 'initializing...')" - echo "" - echo "ℹ️ Notes:" - echo " • All mainnet accounts preserved in L2 genesis" - echo " • L1 accounts funded by 1-start-l1.sh (100 ETH each)" - echo " • Dispute game features skipped (not compatible with mainnet data)" -} - # ============================================================================== # Main Entry Point # ============================================================================== From e4eacf70eb1f25c2387975d03442cbb4ad4de16a Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 3 Dec 2025 12:24:32 +0800 Subject: [PATCH 7/9] update --- devnet/3-op-init.sh | 26 +++++++++++++-- devnet/scripts/prepare-genesis.sh | 54 ++----------------------------- 2 files changed, 25 insertions(+), 55 deletions(-) diff --git a/devnet/3-op-init.sh b/devnet/3-op-init.sh index 9596c20..a9113d6 100755 --- a/devnet/3-op-init.sh +++ b/devnet/3-op-init.sh @@ -13,10 +13,30 @@ sed_inplace() { } # ======================================== -# Genesis Preparation (unified script) +# Genesis Preparation # ======================================== -source scripts/prepare-genesis.sh -prepare_genesis +if [ "$USE_FAKE_MAINNET" = "true" ]; then + # Fake mainnet mode: use unified script with mainnet genesis + source scripts/prepare-genesis.sh + _prepare_mainnet_genesis +else + # Original generated genesis logic + if [ -z "$FORK_BLOCK" ]; then + echo " ❌ FORK_BLOCK environment variable is not set" + echo "Please set FORK_BLOCK in your .env file" + exit 1 + fi + + FORK_BLOCK_HEX=$(printf "0x%x" "$FORK_BLOCK") + sed_inplace '/"config": {/,/}/ s/"optimism": {/"legacyXLayerBlock": '"$((FORK_BLOCK + 1))"',\n "optimism": {/' ./config-op/genesis.json + sed_inplace 's/"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"/"parentHash": "'"$PARENT_HASH"'"/' ./config-op/genesis.json + sed_inplace '/"70997970c51812dc3a010c7d01b50e0d17dc79c8": {/,/}/ s/"balance": "[^"]*"/"balance": "0x446c3b15f9926687d2c40534fdb564000000000000"/' ./config-op/genesis.json + 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-reth.json + sed_inplace 's/"number": "0x0"/"number": "'"$NEXT_BLOCK_NUMBER_HEX"'"/' ./config-op/genesis-reth.json +fi # Extract contract addresses from state.json and update .env file echo "🔧 Extracting contract addresses from state.json..." diff --git a/devnet/scripts/prepare-genesis.sh b/devnet/scripts/prepare-genesis.sh index 02934f7..c3a08c3 100755 --- a/devnet/scripts/prepare-genesis.sh +++ b/devnet/scripts/prepare-genesis.sh @@ -249,59 +249,9 @@ PYTHON_EOF } # ============================================================================== -# Generated Genesis Mode (Original Logic) +# Standalone Execution # ============================================================================== -_prepare_generated_genesis() { - echo "" - echo "🔧 Generated genesis mode" - - NEXT_BLOCK=$((FORK_BLOCK + 1)) - NEXT_BLOCK_HEX=$(printf "0x%x" "$NEXT_BLOCK") - - echo " • FORK_BLOCK: $FORK_BLOCK" - echo " • Next block: $NEXT_BLOCK" - - # Update genesis.json - _sed_inplace '/"config": {/,/}/ s/"optimism": {/"legacyXLayerBlock": '"$NEXT_BLOCK"',\n "optimism": {/' ./config-op/genesis.json - _sed_inplace 's/"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"/"parentHash": "'"$PARENT_HASH"'"/' ./config-op/genesis.json - _sed_inplace '/"70997970c51812dc3a010c7d01b50e0d17dc79c8": {/,/}/ s/"balance": "[^"]*"/"balance": "0x446c3b15f9926687d2c40534fdb564000000000000"/' ./config-op/genesis.json - - # Update rollup.json - _sed_inplace 's/"number": 0/"number": '"$NEXT_BLOCK"'/' ./config-op/rollup.json - - # Create reth version - cp ./config-op/genesis.json ./config-op/genesis-reth.json - _sed_inplace 's/"number": "0x0"/"number": "'"$NEXT_BLOCK_HEX"'"/' ./config-op/genesis-reth.json - - echo "✅ Generated genesis prepared" -} - -# ============================================================================== -# Main Entry Point -# ============================================================================== -prepare_genesis() { - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "📦 Preparing Genesis" - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - - # Validate FORK_BLOCK - if [ -z "$FORK_BLOCK" ]; then - echo "❌ ERROR: FORK_BLOCK environment variable is not set" - echo "Please set FORK_BLOCK in your .env file" - exit 1 - fi - - # Select mode and prepare - if [ "$USE_FAKE_MAINNET" = "true" ]; then - _prepare_mainnet_genesis - else - _prepare_generated_genesis - fi - - echo "" -} - # Run if executed directly (not sourced) if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - prepare_genesis + _prepare_mainnet_genesis fi From c957dc16178876802e3d6224ff4a723606643c37 Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 3 Dec 2025 12:27:13 +0800 Subject: [PATCH 8/9] update --- devnet/scripts/prepare-genesis.sh | 35 ++++--------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/devnet/scripts/prepare-genesis.sh b/devnet/scripts/prepare-genesis.sh index c3a08c3..c11f277 100755 --- a/devnet/scripts/prepare-genesis.sh +++ b/devnet/scripts/prepare-genesis.sh @@ -16,29 +16,10 @@ set -e -# Get script directory -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DEVNET_DIR="$(dirname "$SCRIPT_DIR")" - -# Change to devnet directory if running standalone -if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - cd "$DEVNET_DIR" - source .env -fi - -# ============================================================================== -# Default Configuration (can be overridden by .env) -# ============================================================================== -# Remote URL for mainnet genesis download -MAINNET_GENESIS_URL="${MAINNET_GENESIS_URL:-https://okg-pub-hk.oss-cn-hongkong.aliyuncs.com/cdn/chain/xlayer/snapshot/merged.genesis.json.mainnet.tar.gz}" - -# Local path for mainnet genesis file -MAINNET_GENESIS_PATH="${MAINNET_GENESIS_PATH:-mainnet.genesis.json}" - -# Test account injection (enabled by default in mainnet mode) -# Anvil default account #1 -TEST_ACCOUNT_ADDRESS="${TEST_ACCOUNT_ADDRESS:-0x70997970C51812dc3A010C7d01b50e0d17dc79C8}" -TEST_ACCOUNT_BALANCE="${TEST_ACCOUNT_BALANCE:-0x52B7D2DCC80CD2E4000000}" # 100,000 ETH +MAINNET_GENESIS_URL="https://okg-pub-hk.oss-cn-hongkong.aliyuncs.com/cdn/chain/xlayer/snapshot/merged.genesis.json.mainnet.tar.gz" +MAINNET_GENESIS_PATH="mainnet.genesis.json" +TEST_ACCOUNT_ADDRESS="0x70997970C51812dc3A010C7d01b50e0d17dc79C8" +TEST_ACCOUNT_BALANCE="0x52B7D2DCC80CD2E4000000" # 100,000 ETH # ============================================================================== # Helper Functions @@ -247,11 +228,3 @@ PYTHON_EOF echo " • Output: $CONFIG_DIR/genesis.json" echo " • Reth version: $CONFIG_DIR/genesis-reth.json" } - -# ============================================================================== -# Standalone Execution -# ============================================================================== -# Run if executed directly (not sourced) -if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - _prepare_mainnet_genesis -fi From 1b911c66054601de48834d9ee81310fd8bee61e2 Mon Sep 17 00:00:00 2001 From: Barry Date: Wed, 3 Dec 2025 19:11:35 +0800 Subject: [PATCH 9/9] update --- .gitignore | 3 ++- devnet/example.env | 12 +++++------- devnet/scripts/prepare-genesis.sh | 9 ++++++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 87dddfe..cc91919 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,5 @@ devnet/data devnet/saved-cannon-data devnet/init.log devnet/l1-geth/ -profiling/ \ No newline at end of file +profiling/ +devnet/mainnet.genesis.json \ No newline at end of file diff --git a/devnet/example.env b/devnet/example.env index 7db0ccc..0033125 100644 --- a/devnet/example.env +++ b/devnet/example.env @@ -49,6 +49,11 @@ SKIP_BUILD_PRESTATE=false # Set to false if you need full mode with op-proposer, op-challenger, op-dispute-mon MIN_RUN=true +# ============================================================================== +# Fake Mainnet Configuration +# ============================================================================== +USE_FAKE_MAINNET=false + # ============================================================================== # Docker & Network Configuration # ============================================================================== @@ -139,13 +144,6 @@ FORK_BLOCK=8593920 PARENT_HASH="0x6912fea590fd46ca6a63ec02c6733f6ffb942b84cdf86f7894c21e1757a1f68a" NEW_BLOCK_HASH=0xddb9bdc86631494bab4b4749c4575035e2383da7c96d32d31341de862b1dd6c9 -# ============================================================================== -# Fake Mainnet Configuration -# ============================================================================== -# Use mainnet genesis to simulate mainnet environment -# ⚠️ REQUIRES: MIN_RUN=true (mainnet genesis is too large to build prestate) -USE_FAKE_MAINNET=false - # ============================================================================== # Other Configuration # ============================================================================== diff --git a/devnet/scripts/prepare-genesis.sh b/devnet/scripts/prepare-genesis.sh index c11f277..e6c034f 100755 --- a/devnet/scripts/prepare-genesis.sh +++ b/devnet/scripts/prepare-genesis.sh @@ -164,17 +164,20 @@ def main(): print(f" ✓ chainId: {old_chain_id} → {chain_id}") genesis['config']['legacyXLayerBlock'] = next_block + genesis['config']['jovianTime'] = 0 # Enable Jovian upgrade genesis['parentHash'] = parent_hash genesis['number'] = 0 # Required for geth init - # Update timestamp to current time (avoid conductor "unsafe head falling behind" error) - current_timestamp = int(time.time()) + # Update timestamp to 15 minutes in the future (avoid conductor "unsafe head falling behind" error) + # This gives buffer time between init and service startup + current_timestamp = int(time.time()) + 15 * 60 # +15 minutes genesis['timestamp'] = hex(current_timestamp) print(f" ✓ legacyXLayerBlock: {next_block}") + print(f" ✓ jovianTime: 0 (Jovian upgrade enabled)") print(f" ✓ parentHash: {parent_hash[:20]}...") print(f" ✓ number: 0 (required for geth init)") - print(f" ✓ timestamp: {hex(current_timestamp)}") + print(f" ✓ timestamp: {hex(current_timestamp)} (+15min from now)") # Inject test account (enabled by default in mainnet mode) if test_account and test_balance: