diff --git a/test-pp-op/7-setup-fraud-proof.sh b/test-pp-op/10-setup-fraud-proof.sh similarity index 100% rename from test-pp-op/7-setup-fraud-proof.sh rename to test-pp-op/10-setup-fraud-proof.sh diff --git a/test-pp-op/8-prepare-tests.sh b/test-pp-op/11-prepare-tests.sh similarity index 100% rename from test-pp-op/8-prepare-tests.sh rename to test-pp-op/11-prepare-tests.sh diff --git a/test-pp-op/2-deploy-op-contracts.sh b/test-pp-op/2-deploy-op-contracts.sh index a9bd6038bc2e3..5776b6a7bd8c9 100755 --- a/test-pp-op/2-deploy-op-contracts.sh +++ b/test-pp-op/2-deploy-op-contracts.sh @@ -97,7 +97,7 @@ deploy_transactor() { 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 \ + src/periphery/Transactor.sol:Transactor \ --constructor-args $ADMIN_OWNER_ADDRESS" echo "🔧 Executing Docker command..." diff --git a/test-pp-op/3-stop-erigon.sh b/test-pp-op/3-stop-erigon.sh index 5a6b2845f2b53..2f7da12d5441a 100755 --- a/test-pp-op/3-stop-erigon.sh +++ b/test-pp-op/3-stop-erigon.sh @@ -10,7 +10,7 @@ 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-rpc ${DOCKER_COMPOSE_CMD} stop xlayer-bridge-service ${DOCKER_COMPOSE_CMD} stop xlayer-bridge-ui ${DOCKER_COMPOSE_CMD} stop xlayer-agg-sender diff --git a/test-pp-op/6-upgrade-ger-contract.sh b/test-pp-op/6-upgrade-ger-contract.sh new file mode 100755 index 0000000000000..a826bc09a1466 --- /dev/null +++ b/test-pp-op/6-upgrade-ger-contract.sh @@ -0,0 +1,47 @@ +package test_pp_op + + +set -e +set -x +source .env +source ./utils.sh + +cast send $TIMELOCK_OVERRIDE_PROPOSER_ADDRESS --value 1ether --from $DEPLOYER_ADDRESS --private-key $DEPLOYER_PRIVATE_KEY --rpc-url $L2_SEQ_URL +cast send $TIMELOCK_OVERRIDE_EXECUTOR_ADDRESS --value 1ether --from $DEPLOYER_ADDRESS --private-key $DEPLOYER_PRIVATE_KEY --rpc-url $L2_SEQ_URL + + +cd $TMP_DIR/xlayer-contracts/ + +cd upgrade/upgradeToV2 + +echo "Creating upgrade_parameters.json..." +cat > upgrade_parameters.json << EOF +{ + "timelockDelay": $TIME_LOCK_DELAY, + "timelockSalt": "", + "globalExitRootUpdater": "$ORACLE_ADDRESS", + "globalExitRootRemover": "$ORACLE_ADDRESS" +} +EOF + +cp ../../deployment/v2/deploy_parameters.json ./deploy_parameters.json +cp ../../deployment/v2/deploy_output.json ./deploy_output.json + +sed_inplace '1s/{/{\n "polygonZkEVMGlobalExitRootL2Address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa",/' deploy_output.json + +cd ../../ + +hardhat_output=$(npm run upgradeL2GER:timelock:l2localhost) +echo "hardhat_output: $hardhat_output" + +schedule_data=$(echo "$hardhat_output" | awk -F"'" '/scheduleData:/ {print $2}') +execute_data=$(echo "$hardhat_output" | awk -F"'" '/executeData:/ {print $2}') +echo "schedule_data: $schedule_data" +echo "execute_data: $execute_data" + +cast send --rpc-url "$L2_SEQ_URL" -f $TIMELOCK_OVERRIDE_PROPOSER_ADDRESS --private-key "$TIMELOCK_OVERRIDE_PROPOSER_PRIVATE_KEY" "$TIME_LOCK_ADDRESS" "$schedule_data" + +sleep $TIME_LOCK_DELAY +cast send --rpc-url "$L2_SEQ_URL" -f $TIMELOCK_OVERRIDE_EXECUTOR_ADDRESS --private-key "$TIMELOCK_OVERRIDE_EXECUTOR_PRIVATE_KEY" "$TIME_LOCK_ADDRESS" "$execute_data" +sleep 5 +cast call --rpc-url "$L2_SEQ_URL" $GER_MANAGER_ADDRESS 'GER_SOVEREIGN_VERSION()(string)' diff --git a/test-pp-op/7-start-agg-bridge.sh b/test-pp-op/7-start-agg-bridge.sh new file mode 100755 index 0000000000000..dac09c7821dac --- /dev/null +++ b/test-pp-op/7-start-agg-bridge.sh @@ -0,0 +1,40 @@ +set -e +set -x +source .env +source tools.sh +source utils.sh + +# fund the oracle +cast send -f $DEPLOYER_ADDRESS --private-key $DEPLOYER_PRIVATE_KEY --value 1ether $ORACLE_ADDRESS --rpc-url $L2_SEQ_URL + +cd $PWD_DIR + +sed_inplace 's/http:\/\/xlayer-rpc:8545/http:\/\/op-geth-seq:8545/' config/agglayer-config.toml +sed_inplace 's/http:\/\/xlayer-rpc:8545/http:\/\/op-geth-seq:8545/' config/aggkit.toml +sed_inplace '/\[BridgeL2Sync\]/a\ +InitialBlockNum = '$FORK_BLOCK' +' config/aggkit.toml +sed_inplace 's/http:\/\/xlayer-rpc:8545/http:\/\/op-geth-seq:8545/' config/test.bridge.config.toml +sed_inplace 's/RequireSovereignChainSmcs = \[false\]/RequireSovereignChainSmcs = \[true\]/' config/test.bridge.config.toml +sed_inplace '/\[NetworkConfig\]/a\ +L2GenBlockNumber = '$FORK_BLOCK' +' config/test.bridge.config.toml + +while true; do + sleep 10 + L2_BLOCK_HEIGHT=$(cast block-number --rpc-url $L2_SEQ_URL) + if [ "$L2_BLOCK_HEIGHT" -ge "$FORK_BLOCK" ]; then + echo "L2 block height $L2_BLOCK_HEIGHT has reached fork block $FORK_BLOCK" + sleep 10 + break + fi + echo "Waiting for L2 block height to reach $FORK_BLOCK (current: $L2_BLOCK_HEIGHT)" +done + +${DOCKER_COMPOSE_CMD} up -d xlayer-oracle +sleep 5 +${DOCKER_COMPOSE_CMD} up -d xlayer-bridge-service +sleep 10 +docker rm xlayer-bridge-ui +${DOCKER_COMPOSE_CMD} up -d xlayer-bridge-ui +${DOCKER_COMPOSE_CMD} up -d xlayer-agg-sender diff --git a/test-pp-op/8-test-agg-bridge.sh b/test-pp-op/8-test-agg-bridge.sh new file mode 100755 index 0000000000000..5e1f503808b38 --- /dev/null +++ b/test-pp-op/8-test-agg-bridge.sh @@ -0,0 +1,171 @@ +#!/bin/bash +set -e +set -x +source .env + +BRIDGE_VALUE_BIG="1000000000000000000" # 1 ETH in wei +BRIDGE_VALUE_SMALL="100000000000000000" # 0.1 ETH in wei + +# Get Global Exit Root Manager address +GER_MGR=$(cast call "$BRIDGE_ADDRESS" "globalExitRootManager()(address)" --rpc-url "$L1_RPC_URL") +L2GER_MGR1=$(cast call "$BRIDGE_ADDRESS" "globalExitRootManager()(address)" --rpc-url "$L2_SEQ_URL") +echo "GlobalExitRootManager Address:" +echo " L1 ==> $GER_MGR" +echo " L2 ==> $L2GER_MGR1" + +# Get initial Global Exit Root +GER=$(cast call "$GER_MGR" "getLastGlobalExitRoot()" --rpc-url "$L1_RPC_URL") +echo "Initial GER on L1: $GER" + +# ============================================================================= +# Bridge from L1 to L2 +# ============================================================================= + +# Check balance before bridging +L2_BALANCE_BEFORE_BRIDGE=$(cast call "$L2_WETH" "balanceOf(address)(uint256)" "$DEPLOYER_ADDRESS" --rpc-url "$L2_SEQ_URL" | awk '{print $1}') + +cast send \ + --legacy \ + --rpc-url $L1_RPC_URL \ + --private-key $DEPLOYER_PRIVATE_KEY \ + --value $BRIDGE_VALUE_BIG \ + $BRIDGE_ADDRESS \ + 'function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) returns()' \ + 1 $DEPLOYER_ADDRESS $BRIDGE_VALUE_BIG $L1_ETH_ADDRESS true 0x + +# Wait for GER update on L1 +echo "Waiting for GER to be updated on L1..." +while true; do + GER_NEW=$(cast call "$GER_MGR" "getLastGlobalExitRoot()" --rpc-url "$L1_RPC_URL") + if [ "$GER_NEW" != "$GER" ]; then + GER=$GER_NEW + echo "GER updated to $GER on L1" + break + fi + sleep 10 +done + +# Wait for GER to sync to L2 +echo "Waiting for GER to sync to L2..." +start_time=$(date +%s) +while true; do + timestamp=$(cast call "$L2GER_MGR1" "globalExitRootMap(bytes32)(uint256)" "$GER" --rpc-url "$L2_SEQ_URL") + if [ "$timestamp" != "0" ]; then + break + fi + sleep 15 +done +end_time=$(date +%s) +total_elapsed=$((end_time - start_time)) +echo "GER synced to L2, took $total_elapsed seconds" + +# Wait for assets to be claimed automatically by sponsor +echo "Waiting for assets to be claimed by sponsor..." +start_time=$(date +%s) +while true; do + sleep 60 + balance=$(cast call "$L2_WETH" "balanceOf(address)(uint256)" "$DEPLOYER_ADDRESS" --rpc-url "$L2_SEQ_URL" | awk '{print $1}') + balance=${balance:-0} + increment=$(echo "$balance - $L2_BALANCE_BEFORE_BRIDGE" | bc) + echo "Current balance on L2: $balance (increment: $increment)" + if [ "$increment" -gt 0 ]; then + echo "Assets successfully claimed on L2" + break + fi +done +end_time=$(date +%s) +total_elapsed=$((end_time - start_time)) +echo "Balance on L2 is $balance, claim took $total_elapsed seconds" + +# Check balance after bridging +L2_BALANCE_AFTER_BRIDGE=$(cast balance "$DEPLOYER_ADDRESS" --rpc-url "$L2_SEQ_URL") +echo "Balance on L2(ETH):" +echo " Before bridge = $L2_BALANCE_BEFORE_BRIDGE" +echo " After bridge = $L2_BALANCE_AFTER_BRIDGE" + +# ============================================================================= +# Bridge from L2 to L1 +# ============================================================================= +echo -e "\n========== Bridging Assets: L2 -> L1 BRIDGE_VALUE_SMALL ==========" + +# Approve token +echo "Approving token..." +cast send \ + --legacy \ + --rpc-url $L2_SEQ_URL \ + --private-key $DEPLOYER_PRIVATE_KEY \ + "$L2_WETH" \ + "function approve(address spender, uint256 amount) returns (bool)" \ + $BRIDGE_ADDRESS \ + $BRIDGE_VALUE_BIG + +# Initiate bridging transaction +TX_HASH=$(cast send \ + --legacy \ + --private-key $DEPLOYER_PRIVATE_KEY \ + --rpc-url $L2_SEQ_URL \ + --json \ + $BRIDGE_ADDRESS \ + 'function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) returns()' \ + 0 $DEPLOYER_ADDRESS $BRIDGE_VALUE_SMALL $L2_WETH true "0x" \ + | jq -r ' .transactionHash') +echo "Bridge transaction hash: $TX_HASH" + +# Wait for GER update on L1 +echo "Waiting for GER to be updated on L1..." +start_time=$(date +%s) +while true; do + GER_NEW=$(cast call "$GER_MGR" "getLastGlobalExitRoot()" --rpc-url "$L1_RPC_URL") + if [ "$GER_NEW" != "$GER" ]; then + GER=$GER_NEW + break + fi + sleep 10 +done +end_time=$(date +%s) +total_elapsed=$((end_time - start_time)) +echo "GER updated to $GER on L1, took $total_elapsed seconds" + +sleep 40 +echo "Getting deposit count and network ID from bridge service..." +result=$(curl -s "$BRIDGE_SERVICE/bridges/$DEPLOYER_ADDRESS?limit=20000&offset=0" | \ + jq -r '.deposits[] | select(.ready_for_claim == true and .claim_tx_hash == "" and .tx_hash=="'$TX_HASH'")') +DEPOSIT_CNT=$(echo "$result" | jq -r '.deposit_cnt') +NETWORK_ID=$(echo "$result" | jq -r '.network_id') +GLOBAL_INDEX=$(echo "$result" | jq -r '.global_index') +ORINGIN_NETWORK=$(echo "$result" | jq -r '.orig_net') +ORINGIN_ADDRESS=$(echo "$result" | jq -r '.orig_addr') +DESTINATION_NETWORK=$(echo "$result" | jq -r '.dest_net') +IN_AMOUNT=$(echo "$result" | jq -r '.amount') +METADATA=$(echo "$result" | jq -r '.metadata') +echo "Deposit Count: $DEPOSIT_CNT" +echo "Network ID: $NETWORK_ID" +echo "Global Index: $GLOBAL_INDEX" +echo "Origin Network: $ORINGIN_NETWORK" +echo "Origin Address: $ORINGIN_ADDRESS" +echo "Destination Network: $DESTINATION_NETWORK" +echo "In Amount: $IN_AMOUNT" +echo "Metadata: $METADATA" + +proof=$(curl -s "$BRIDGE_SERVICE/merkle-proof?deposit_cnt=$DEPOSIT_CNT&net_id=$NETWORK_ID" | jq -r '.') +MERKLE_PROOF=$(echo "$proof" | jq -r -c '.proof | .merkle_proof' | tr -d '"') +ROLLUP_MERKLE_PROOF=$(echo "$proof" | jq -r -c '.proof | .rollup_merkle_proof' | tr -d '"') +MER=$(echo "$proof" | jq -r '.proof | .main_exit_root') +RER=$(echo "$proof" | jq -r '.proof | .rollup_exit_root') +echo "Merkle Proof: $MERKLE_PROOF" +echo "Rollup Merkle Proof: $ROLLUP_MERKLE_PROOF" +echo "Main Exit Root: $MER" +echo "Rollup Exit Root: $RER" + +# Claim assets on L1 +echo "Claiming assets on L1..." +L1_BALANCE_BEFORE_CLAIM=$(cast balance "$DEPLOYER_ADDRESS" --rpc-url "$L1_RPC_URL") +cmd="cast send --legacy --rpc-url $L1_RPC_URL --private-key $DEPLOYER_PRIVATE_KEY $BRIDGE_ADDRESS 'claimAsset(bytes32[32],bytes32[32],uint256,bytes32,bytes32,uint32,address,uint32,address,uint256,bytes)' $MERKLE_PROOF $ROLLUP_MERKLE_PROOF $GLOBAL_INDEX $MER $RER $ORINGIN_NETWORK $ORINGIN_ADDRESS $DESTINATION_NETWORK $DEPLOYER_ADDRESS $IN_AMOUNT $METADATA" + +echo "Warning!!!!!!!!!! Claim asset on L1, Executing: $cmd" +eval "$cmd" + +L1_BALANCE_AFTER_CLAIM=$(cast balance "$DEPLOYER_ADDRESS" --rpc-url "$L1_RPC_URL") +echo "Balance on L1:" +echo " Before claiming: $L1_BALANCE_BEFORE_CLAIM" +echo " After claiming: $L1_BALANCE_AFTER_CLAIM" diff --git a/test-pp-op/6-build-op-program.sh b/test-pp-op/9-build-op-program.sh similarity index 100% rename from test-pp-op/6-build-op-program.sh rename to test-pp-op/9-build-op-program.sh diff --git a/test-pp-op/Makefile b/test-pp-op/Makefile index e3bcf091c2529..e7355ce3120be 100644 --- a/test-pp-op/Makefile +++ b/test-pp-op/Makefile @@ -148,6 +148,7 @@ clean: stop rm -rf config-op/196-* rm -rf config-op/195-* rm -rf config-op/1952-* + rm -rf config/genesis.json rm -rf l1-geth/consensus/beacondata/ rm -rf l1-geth/consensus/genesis.ssz rm -rf l1-geth/consensus/validatordata/ diff --git a/test-pp-op/build_images.sh b/test-pp-op/build_images.sh index 11a598914a708..10f74958e13ae 100755 --- a/test-pp-op/build_images.sh +++ b/test-pp-op/build_images.sh @@ -137,18 +137,12 @@ 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 + rm -rf $PWD_DIR/tmp/xlayer-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 + git clone -b add-patch https://github.com/okx/xlayer-bridge-service # 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 - + cd xlayer-bridge-service docker build --platform $ARCH -t $XLAYER_BRIDGE_SERVICE_IMAGE_TAG . cd $PWD_DIR } diff --git a/test-pp-op/config-op/aggkit.toml b/test-pp-op/config-op/aggkit.toml new file mode 100644 index 0000000000000..b98c31dd8096f --- /dev/null +++ b/test-pp-op/config-op/aggkit.toml @@ -0,0 +1,129 @@ +PathRWData = "/tmp/" +L1URL="http://l1-geth:8545" + +L2URL="http://op-geth-seq:8545" + +AggLayerURL="xlayer-agglayer:4443" + +ForkId = 13 +ContractVersions = "banana" +IsValidiumMode = false +NetworkID = 1 + +L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" +SequencerPrivateKeyPath = "/etc/keystore/sequencer.keystore" +SequencerPrivateKeyPassword = "testonly" + +AggregatorPrivateKeyPath = "/etc/keystore/aggregator.keystore" +AggregatorPrivateKeyPassword = "testonly" +SenderProofToL1Addr = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" +polygonBridgeAddr = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" + +rollupCreationBlockNumber = "156" +rollupManagerCreationBlockNumber = "162" +genesisBlockNumber = "156" + +[Common] +NetworkID = 1 +IsValidiumMode = false +ContractVersions = "banana" +# TODO, should we config with base +L2RPC = { Mode = "basic", URL = "{{L2URL}}", OpNodeURL = "http://op-seq: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/keystore/sequencer.keystore", Password = "testonly"} +CheckStatusCertificateInterval = "1s" +Mode="PessimisticProof" +UseAgglayerTLS = false +MaxCertSize = 0 +MaxL2BlockNumber = 0 +StopOnFinishedSendingAllCertificates = false + +[AggSender.MaxSubmitCertificateRate] +NumRequests = 20 +Interval = "1m" +BlockFinality = "FinalizedBlock" +SaveCertificatesToFilesPath = "/tmp/certificates" +KeepCertificatesHistory = true +[AggOracle] +BlockFinality = "FinalizedBlock" +WaitPeriodNextGER = "10s" + +[AggOracle.EVMSender] +GlobalExitRootL2 = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" +WaitPeriodMonitorTx = "10s" + +[AggOracle.EVMSender.EthTxManager] +PrivateKeys = [{Path = "/etc/keystore/aggoracle.keystore", Password = "testonly"}] +[AggOracle.EVMSender.EthTxManager.Etherman] +L1ChainID = "195" + +[BridgeL1Sync] +BlockFinality = "FinalizedBlock" + +[BridgeL2Sync] +BridgeAddr = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" + +DBPath = "/tmp/bridgel2sync.sqlite" +BlockFinality = "FinalizedBlock" + +SyncBlockChunkSize = 1000 + +[ReorgDetectorL1] +DBPath = "/tmp/reorgdetectorl1.sqlite" +FinalizedBlock="FinalizedBlock" + +[ReorgDetectorL2] +DBPath = "/tmp/reorgdetectorl2.sqlite" +FinalizedBlock="FinalizedBlock" + +[L1InfoTreeSync] +InitialBlock = "36" +BlockFinality = "FinalizedBlock" + +[LastGERSync] +BlockFinality = "FinalizedBlock" + +[ClaimSponsor] +DBPath = "/tmp/claimsponsor.sqlite" +Enabled = false + +SenderAddr = "0x5f5dB0D4D58310F53713eF4Df80ba6717868A9f8" + +BridgeAddrL2 = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" + +[ClaimSponsor.EthTxManager] +PrivateKeys = [ + {Path = "/etc/keystore/claimtxmanager.keystore", Password = ""}, +] + +StoragePath = "" + +[ClaimSponsor.EthTxManager.Etherman] +URL = "" + +L1ChainID = "195" + +[Profiling] +ProfilingHost = "0.0.0.0" + +ProfilingPort = 6060 diff --git a/test-pp-op/config/aggkit.toml b/test-pp-op/config/aggkit.toml index 3740349a09bcd..648db729de216 100644 --- a/test-pp-op/config/aggkit.toml +++ b/test-pp-op/config/aggkit.toml @@ -1,7 +1,7 @@ PathRWData = "/tmp/" L1URL="http://l1-geth:8545" -L2URL="http://xlayer-rpc:8545" +L2URL="http://op-geth-rpc:8545" AggLayerURL="xlayer-agglayer:4443" @@ -11,17 +11,17 @@ IsValidiumMode = false NetworkID = 1 L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" -SequencerPrivateKeyPath = "/etc/aggkit/sequencer.keystore" +SequencerPrivateKeyPath = "/etc/keystore/sequencer.keystore" SequencerPrivateKeyPassword = "testonly" -AggregatorPrivateKeyPath = "/etc/aggkit/aggregator.keystore" +AggregatorPrivateKeyPath = "/etc/keystore/aggregator.keystore" AggregatorPrivateKeyPassword = "testonly" SenderProofToL1Addr = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" polygonBridgeAddr = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" -rollupCreationBlockNumber = "91" -rollupManagerCreationBlockNumber = "100" -genesisBlockNumber = "91" +rollupCreationBlockNumber = "95" +rollupManagerCreationBlockNumber = "105" +genesisBlockNumber = "95" [Common] NetworkID = 1 @@ -50,7 +50,7 @@ Port = 5576 [AggSender] StoragePath = "/tmp/aggsender.sqlite" -AggsenderPrivateKey = {Path = "/etc/aggkit/sequencer.keystore", Password = "testonly"} +AggsenderPrivateKey = {Path = "/etc/keystore/sequencer.keystore", Password = "testonly"} CheckStatusCertificateInterval = "1s" Mode="PessimisticProof" UseAgglayerTLS = false @@ -73,7 +73,7 @@ GlobalExitRootL2 = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" WaitPeriodMonitorTx = "10s" [AggOracle.EVMSender.EthTxManager] -PrivateKeys = [{Path = "/etc/aggkit/aggoracle.keystore", Password = "testonly"}] +PrivateKeys = [{Path = "/etc/keystore/aggoracle.keystore", Password = "testonly"}] [AggOracle.EVMSender.EthTxManager.Etherman] L1ChainID = "195" @@ -81,6 +81,8 @@ L1ChainID = "195" BlockFinality = "LatestBlock" [BridgeL2Sync] +InitialBlockNum = 183 + BridgeAddr = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" DBPath = "/tmp/bridgel2sync.sqlite" @@ -113,7 +115,7 @@ BridgeAddrL2 = "0xb2fAc1CE54bb9BF77A7FE106fA69F81453b72851" [ClaimSponsor.EthTxManager] PrivateKeys = [ - {Path = "/etc/aggkit/claimtxmanager.keystore", Password = ""}, + {Path = "/etc/keystore/claimtxmanager.keystore", Password = ""}, ] StoragePath = "" @@ -126,4 +128,4 @@ L1ChainID = "195" [Profiling] ProfilingHost = "0.0.0.0" -ProfilingPort = 6060 \ No newline at end of file +ProfilingPort = 6060 diff --git a/test-pp-op/config/dynamic-mynetwork-conf.json b/test-pp-op/config/dynamic-mynetwork-conf.json index 9ce28d4252cc1..9a76b16e6ca81 100644 --- a/test-pp-op/config/dynamic-mynetwork-conf.json +++ b/test-pp-op/config/dynamic-mynetwork-conf.json @@ -1,6 +1,6 @@ { "root": "0x6565265b546acdc3b714218d5bdb667725002a6fa07b5045f5ed4ad7595ebd62", - "timestamp": 1760602860, + "timestamp": 1761297167, "gasLimit": 0, "difficulty": 0 } diff --git a/test-pp-op/config/first-batch-config.json b/test-pp-op/config/first-batch-config.json index f622df8200c75..c8947a14ecc70 100644 --- a/test-pp-op/config/first-batch-config.json +++ b/test-pp-op/config/first-batch-config.json @@ -1,9 +1,9 @@ { "batchL2Data": "0xf901e480808401c9c38094b2fac1ce54bb9bf77a7fe106fa69f81453b7285180b901c4f811bff700000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000084f4b42546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034f4b42000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005ca1ab1e0000000000000000000000000000000000000000000000000000000005ca1ab1e1bff", "globalExitRoot": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", - "timestamp": 1760602860, + "timestamp": 1761297167, "sequencer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "l1BlockNumber": 100, - "l1BlockHash": "0xfbd5bff822e23e6864b1185686864ac8bc9a7645756dce00586ed909b9f3c78e", - "l1ParentHash": "0xd3bf883426e5f8f374ed2699fc9c9026d136e212c57f4fc48288f8c2d189fadd" + "l1BlockNumber": 105, + "l1BlockHash": "0xce6148b8f249363fcc35c083f306df0acda81e863931b50f136a46025cbc7adc", + "l1ParentHash": "0xfbd4deb77115a7088bc925c1f15273dc27ca428b12b89f1d03826be5c3c5e1ed" } diff --git a/test-pp-op/config/test.bridge.config.toml b/test-pp-op/config/test.bridge.config.toml index 87b7fc7e05729..39a68c08c7969 100644 --- a/test-pp-op/config/test.bridge.config.toml +++ b/test-pp-op/config/test.bridge.config.toml @@ -32,7 +32,7 @@ Database = "postgres" # 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"] +L2URLs = ["http://op-geth-rpc:8545"] # Synchronization Settings # This section defines the parameters for synchronizing data, including @@ -85,6 +85,8 @@ MaxPageLimit = 1000 # This section contains settings related to the network, including smart contract addresses and # L1 bridge genesis block. [NetworkConfig] +L2GenBlockNumber = 183 + # 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 @@ -98,7 +100,7 @@ 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] +RequireSovereignChainSmcs = [true] # List of global exit root addresses for Layer 2. Same length as L2PolygonBridgeAddresses L2PolygonZkEVMGlobalExitRootAddresses = ["0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa"] @@ -112,7 +114,7 @@ Enabled = true # Frequency to monitor transactions FrequencyToMonitorTxs = "5s" # Path and password for the private key -PrivateKey = {Path = "/pk/keystore.claimtxmanager", Password = "testonly"} +PrivateKey = {Path = "/pk/claimtxmanager.keystore", Password = "testonly"} # Interval between retries RetryInterval = "1s" # Number of retry attempts diff --git a/test-pp-op/config/test.erigon.seq.config.yaml b/test-pp-op/config/test.erigon.seq.config.yaml index 44c8a3a7a6fe1..edbd563883a9f 100644 --- a/test-pp-op/config/test.erigon.seq.config.yaml +++ b/test-pp-op/config/test.erigon.seq.config.yaml @@ -16,7 +16,7 @@ zkevm.address-rollup: "0xE96dBF374555C6993618906629988d39184716B3" zkevm.address-ger-manager: "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" zkevm.l1-rollup-id: 1 -zkevm.l1-first-block: 91 +zkevm.l1-first-block: 95 zkevm.l1-block-range: 10 zkevm.l1-query-delay: 6000 zkevm.rpc-ratelimit: 0 diff --git a/test-pp-op/config/test.genesis.config.json b/test-pp-op/config/test.genesis.config.json index dca366627bfdc..7366a15b923e7 100644 --- a/test-pp-op/config/test.genesis.config.json +++ b/test-pp-op/config/test.genesis.config.json @@ -6,9 +6,9 @@ "polTokenAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "polygonZkEVMGlobalExitRootAddress": "0xB8cedD4B9eF683f0887C44a6E4312dC7A6e2fcdB" }, - "genesisBlockNumber": 91, - "rollupCreationBlockNumber": 100, - "rollupManagerCreationBlockNumber": 91, + "genesisBlockNumber": 95, + "rollupCreationBlockNumber": 105, + "rollupManagerCreationBlockNumber": 95, "root": "0xef7bb96e820d4d8440f9bae6b1d58427c06e324ac9d5f7a5156438dd42e837c5", "genesis": [ { diff --git a/test-pp-op/docker-compose-local.yml b/test-pp-op/docker-compose-local.yml index 34f1d842c85e5..a35d1e37cdebc 100644 --- a/test-pp-op/docker-compose-local.yml +++ b/test-pp-op/docker-compose-local.yml @@ -242,7 +242,7 @@ services: image: ${XLAYER_BRIDGE_SERVICE_IMAGE_TAG} ports: - 8080:8080 - - 9090:9090 + - 9099:9090 environment: - ZKEVM_BRIDGE_DATABASE_USER=test_user - ZKEVM_BRIDGE_DATABASE_PASSWORD=test_password @@ -250,13 +250,12 @@ services: - ZKEVM_BRIDGE_DATABASE_HOST=xlayer-bridge-db - ZKEVM_BRIDGE_DATABASE_PORT=5432 volumes: - - ./keystore/sequencer.keystore:/pk/keystore.claimtxmanager + - ./keystore/:/pk/ - ./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 @@ -320,9 +319,8 @@ services: 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 + - ./keystore/:/etc/keystore/ + - ./config/:/etc/aggkit/ - ./config/test.genesis.config.json:/etc/aggkit/genesis.json ports: - 5576:5576 @@ -410,12 +408,13 @@ services: image: aggkit:local volumes: - ./data/oracle:/tmp - - ./keystore/aggoracle.keystore:/etc/aggkit/aggoracle.keystore - - ./config-op/aggkit.toml:/etc/aggkit/aggkit.toml + - ./keystore/:/etc/keystore/ + - ./config-op/:/etc/aggkit/ - ./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 @@ -438,7 +437,6 @@ services: - --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 @@ -466,7 +464,6 @@ services: - --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}" @@ -715,7 +712,6 @@ services: - --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 @@ -829,7 +825,6 @@ services: - --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 diff --git a/test-pp-op/keystore/agglayer.keystore b/test-pp-op/keystore/agglayer.keystore new file mode 100644 index 0000000000000..36adf8bc3f156 --- /dev/null +++ b/test-pp-op/keystore/agglayer.keystore @@ -0,0 +1 @@ +{"version":3,"id":"71b028b6-9b1d-4f4c-9e66-31c94a6eb679","address":"70997970c51812dc3a010c7d01b50e0d17dc79c8","crypto":{"ciphertext":"985d5dc5f7750fc4ad0ad0d370486870016bb97e00ef1f7b146d6ad95d456861","cipherparams":{"iv":"f51b18b9f45872f71c3578513fca6cb0"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6253e2d8a71e4808dd11143329cfea467cabb37ac1e1e55dbc0dd90ff22524a7","n":8192,"r":8,"p":1},"mac":"922f741e84201fc7c17bbf9fae5dba6c04a2a99a7268998b5a0268aa690004be"}} \ No newline at end of file diff --git a/test-pp-op/keystore/aggoracle.keystore b/test-pp-op/keystore/aggoracle.keystore new file mode 100644 index 0000000000000..36adf8bc3f156 --- /dev/null +++ b/test-pp-op/keystore/aggoracle.keystore @@ -0,0 +1 @@ +{"version":3,"id":"71b028b6-9b1d-4f4c-9e66-31c94a6eb679","address":"70997970c51812dc3a010c7d01b50e0d17dc79c8","crypto":{"ciphertext":"985d5dc5f7750fc4ad0ad0d370486870016bb97e00ef1f7b146d6ad95d456861","cipherparams":{"iv":"f51b18b9f45872f71c3578513fca6cb0"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6253e2d8a71e4808dd11143329cfea467cabb37ac1e1e55dbc0dd90ff22524a7","n":8192,"r":8,"p":1},"mac":"922f741e84201fc7c17bbf9fae5dba6c04a2a99a7268998b5a0268aa690004be"}} \ No newline at end of file diff --git a/test-pp-op/keystore/aggregator.keystore b/test-pp-op/keystore/aggregator.keystore new file mode 100644 index 0000000000000..36adf8bc3f156 --- /dev/null +++ b/test-pp-op/keystore/aggregator.keystore @@ -0,0 +1 @@ +{"version":3,"id":"71b028b6-9b1d-4f4c-9e66-31c94a6eb679","address":"70997970c51812dc3a010c7d01b50e0d17dc79c8","crypto":{"ciphertext":"985d5dc5f7750fc4ad0ad0d370486870016bb97e00ef1f7b146d6ad95d456861","cipherparams":{"iv":"f51b18b9f45872f71c3578513fca6cb0"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6253e2d8a71e4808dd11143329cfea467cabb37ac1e1e55dbc0dd90ff22524a7","n":8192,"r":8,"p":1},"mac":"922f741e84201fc7c17bbf9fae5dba6c04a2a99a7268998b5a0268aa690004be"}} \ No newline at end of file diff --git a/test-pp-op/keystore/claimtxmanager.keystore b/test-pp-op/keystore/claimtxmanager.keystore new file mode 100644 index 0000000000000..96b662b7eb1e4 --- /dev/null +++ b/test-pp-op/keystore/claimtxmanager.keystore @@ -0,0 +1 @@ +{"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"d005030a7684f3adad2447cbb27f63039eec2224c451eaa445de0d90502b9f3d","cipherparams":{"iv":"dc07a54bc7e388efa89c34d42f2ebdb4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"cf2ec55ecae11171de575112cfb16963570533a9c46fb774473ceb11519eb24a"},"mac":"3eb180d405a5da6e462b2adc00091c14856c91d574bf27348714506357d6e177"},"id":"035454db-6b6d-477f-8a79-ce24c10b185f","version":3} \ No newline at end of file diff --git a/test-pp-op/keystore/da.permit.keystore b/test-pp-op/keystore/da.permit.keystore new file mode 100644 index 0000000000000..36adf8bc3f156 --- /dev/null +++ b/test-pp-op/keystore/da.permit.keystore @@ -0,0 +1 @@ +{"version":3,"id":"71b028b6-9b1d-4f4c-9e66-31c94a6eb679","address":"70997970c51812dc3a010c7d01b50e0d17dc79c8","crypto":{"ciphertext":"985d5dc5f7750fc4ad0ad0d370486870016bb97e00ef1f7b146d6ad95d456861","cipherparams":{"iv":"f51b18b9f45872f71c3578513fca6cb0"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"6253e2d8a71e4808dd11143329cfea467cabb37ac1e1e55dbc0dd90ff22524a7","n":8192,"r":8,"p":1},"mac":"922f741e84201fc7c17bbf9fae5dba6c04a2a99a7268998b5a0268aa690004be"}} \ No newline at end of file diff --git a/test-pp-op/keystore/sequencer.keystore b/test-pp-op/keystore/sequencer.keystore new file mode 100644 index 0000000000000..96b662b7eb1e4 --- /dev/null +++ b/test-pp-op/keystore/sequencer.keystore @@ -0,0 +1 @@ +{"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"d005030a7684f3adad2447cbb27f63039eec2224c451eaa445de0d90502b9f3d","cipherparams":{"iv":"dc07a54bc7e388efa89c34d42f2ebdb4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"cf2ec55ecae11171de575112cfb16963570533a9c46fb774473ceb11519eb24a"},"mac":"3eb180d405a5da6e462b2adc00091c14856c91d574bf27348714506357d6e177"},"id":"035454db-6b6d-477f-8a79-ce24c10b185f","version":3} \ No newline at end of file diff --git a/test-pp-op/keystore/test-member.keystore b/test-pp-op/keystore/test-member.keystore new file mode 100644 index 0000000000000..96b662b7eb1e4 --- /dev/null +++ b/test-pp-op/keystore/test-member.keystore @@ -0,0 +1 @@ +{"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"d005030a7684f3adad2447cbb27f63039eec2224c451eaa445de0d90502b9f3d","cipherparams":{"iv":"dc07a54bc7e388efa89c34d42f2ebdb4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"cf2ec55ecae11171de575112cfb16963570533a9c46fb774473ceb11519eb24a"},"mac":"3eb180d405a5da6e462b2adc00091c14856c91d574bf27348714506357d6e177"},"id":"035454db-6b6d-477f-8a79-ce24c10b185f","version":3} \ No newline at end of file diff --git a/test-pp-op/local.env b/test-pp-op/local.env index e49725db66b62..13112ff416910 100644 --- a/test-pp-op/local.env +++ b/test-pp-op/local.env @@ -25,6 +25,7 @@ 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_SEQ_URL=http://127.0.0.1:8123 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 @@ -85,6 +86,12 @@ OP_CHALLENGER_PRIVATE_KEY=0x8b3a350cf5c34c9194ca9aa3f146b2b9afed22cd83d3c5f6a3f2 ADMIN_OWNER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 ADMIN_OWNER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +TIMELOCK_OVERRIDE_PROPOSER_ADDRESS=0x290b70aFAC486770266DF93A4b88BB9F91862909 +TIMELOCK_OVERRIDE_PROPOSER_PRIVATE_KEY=0x41f30d29511fedb5eeda6157cd447778f762b39af9557e45d688994c679349a6 + +TIMELOCK_OVERRIDE_EXECUTOR_ADDRESS=0x290b70aFAC486770266DF93A4b88BB9F91862909 +TIMELOCK_OVERRIDE_EXECUTOR_PRIVATE_KEY=0x41f30d29511fedb5eeda6157cd447778f762b39af9557e45d688994c679349a6 + # Deployed and modified in 2-deploy-op-contracts.sh TRANSACTOR=0x0000000000000000000000000000000000000000 SAFE_ADDRESS=0x0000000000000000000000000000000000000000 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) -