From 790acf92f0a43819f7cdd1950a2dbb469342fa13 Mon Sep 17 00:00:00 2001 From: Xavier Romero Date: Fri, 17 Jan 2025 09:19:22 +0100 Subject: [PATCH] Forkid ugprade script --- .github/workflows/lint.yml | 2 +- scripts/README.md | 22 ++++ scripts/upgrade_forkid.sh | 250 +++++++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 scripts/README.md create mode 100755 scripts/upgrade_forkid.sh diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0dd622b89..90614ef78 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -50,7 +50,7 @@ jobs: run: find . -type f -name '*.Dockerfile' | sort | xargs -I {} hadolint --config ${{ github.workspace }}/.hadolint.yml {} - name: Run shellcheck - run: find . -type f -name '*.sh' | grep -v "./docs" | sort | xargs -I {} shellcheck {} + run: find . -type f -name '*.sh' | grep -v "./docs" | grep -v "/upgrade_forkid.sh" | sort | xargs -I {} shellcheck {} check-test-combinations-and-cdk-version-matrix: runs-on: ubuntu-latest diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 000000000..e0cd05394 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,22 @@ +# Scripts + +## upgrade_forkid.sh +The main purpose of this script is to test Erigon behavior when upgrading forkid, and it can be taken as example/guide of required steps to upgrade an existing network. +The script itself takes care of deploying the Kurtosis CDK stack, halt sequencer and check it's in a right status, upgrading contracts, starting sequencer again, check it process the new forkid, and then removing the whole stack. +You can not use it as is to upgrade your existing stack, but you can easily adapt it for your context. + +### Usage +From the root of repo, run: +```bash +./scripts/upgrade_forkid.sh 11 13 +``` + +This would deploy a forkid 11 stack and then upgrade it to forkid 13. + +These are the tested/supported combinations so far: +- Upgrading from forkid 12 to 13 +- Upgrading from forkid 11 to 12 +- Upgrading from forkid 11 to 13 +- Upgrading from forkid 9 to 11 +- Upgrading from forkid 9 to 12 +- Upgrading from forkid 9 to 13 diff --git a/scripts/upgrade_forkid.sh b/scripts/upgrade_forkid.sh new file mode 100755 index 000000000..9563d3890 --- /dev/null +++ b/scripts/upgrade_forkid.sh @@ -0,0 +1,250 @@ +#!/bin/bash + +# Tested/supported combinations so far: +# rollup 11 -> 12 +# rollup 11 -> 13 +# rollup 12 -> 13 +# rollup 9 -> 11 +# rollup 9 -> 12 +# rollup 9 -> 13 + +# Check we receive 2 params +if [ "$#" -ne 2 ]; then + echo "Usage: upgrade_forkid.sh " + exit 1 +elif ! [[ $1 =~ ^[0-9]+$ ]] || ! [[ $2 =~ ^[0-9]+$ ]]; then + echo "Forkids must be integers" + exit 1 +# check source forkid is 9, 11 or 12 +elif [ "$1" -ne "9" ] && [ "$1" -ne "11" ] && [ "$1" -ne "12" ]; then + echo "Source forkid must be 9, 11 or 12" + exit 1 +# check target forkid is 11, 12 or 13 +elif [ "$2" -ne "11" ] && [ "$2" -ne "12" ] && [ "$2" -ne "13" ]; then + echo "Target forkid must be 11, 12 or 13" + exit 1 +# check target forkid is greater than source forkid +elif [ "$1" -ge "$2" ]; then + echo "Target forkid must be greater than source forkid" + exit 1 +fi + +SOURCE_FORKID=$1 +TARGET_FORKID=$2 +ERIGON_IMAGE=hermeznetwork/cdk-erigon:v2.61.4-RC1 +STACK_NAME=upgradeCDK-$(tr -dc A-Za-z0-9 > "$KURTOSIS_CONFIG" + +# DEPLOY STACK +kurtosis run --enclave "$STACK_NAME" --args-file "$KURTOSIS_CONFIG" . + +# SERVICE NAMES +SVC_SEQUENCER=cdk-erigon-sequencer-001 +SVC_RPC=cdk-erigon-rpc-001 +SVC_CONTRACTS=contracts-001 +SVC_SLESS_EXECUTOR=zkevm-stateless-executor-001 +SVC_BRIDGE=zkevm-bridge-service-001 +SVC_PROVER=zkevm-prover-001 +SVC_CDKNODE=cdk-node-001 + +# send test tx +PRIV_KEY=0x12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625 +cast send --rpc-url $(kurtosis port print "$STACK_NAME" $SVC_RPC rpc) --legacy --private-key $PRIV_KEY --value 0.01ether 0x0000000000000000000000000000000000000000 + +# Halt sequencer +echo "Halting sequencer..." +kurtosis service exec "$STACK_NAME" $SVC_SEQUENCER \ + "HALTON=\$(printf \"%d\\n\" \$((\$(curl -s -X POST -H \"Content-Type: application/json\" -d '{\"method\":\"zkevm_batchNumber\",\"id\":1,\"jsonrpc\":\"2.0\"}' http://localhost:8123 | jq -r .result)+2))); \ + sed -i 's/zkevm.sequencer-halt-on-batch-number: 0/zkevm.sequencer-halt-on-batch-number: '\$HALTON'/' /etc/cdk-erigon/config.yaml" + # echo \"zkevm.sequencer-halt-on-batch-number: \$HALTON\" >> /etc/erigon/erigon-sequencer.yaml" +kurtosis service stop "$STACK_NAME" $SVC_SEQUENCER +kurtosis service start "$STACK_NAME" $SVC_SEQUENCER + +# Wait for sequencer to be halted +while ! kurtosis service logs -n 1 "$STACK_NAME" $SVC_SEQUENCER | grep -q "Halt sequencer on batch"; do + echo "Waiting for sequencer to halt" + sleep 3 +done +echo "Sequencer halted !" + +# Update contracts folder +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "cd /opt/zkevm-contracts && git stash && git checkout main && git pull && git checkout $TAG_TARGET_FORKID" + +# create env file for the commands we need to execute on contracts service +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "echo 'cd /opt' > /opt/commands.sh" +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "echo 'export ETH_RPC_URL=http://el-1-geth-lighthouse:8545' >> /opt/commands.sh" +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "echo 'ROLLUP_MAN=\$(cat zkevm/combined.json | jq -r .polygonRollupManagerAddress)' >> /opt/commands.sh" +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "echo 'ROLLUP=\$(cat zkevm/combined.json | jq -r .rollupAddress)' >> /opt/commands.sh" +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "echo 'GENESIS=\$(cat zkevm/combined.json | jq -r .genesis)' >> /opt/commands.sh" +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "echo \"CONSENSUS=\\\$(cast call \\\$ROLLUP_MAN 'rollupTypeMap(uint32)(address,address,uint64,uint8,bool,bytes32)' 1 | head -1)\" >> /opt/commands.sh" +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "echo PRIV_KEY=0x12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625 >> /opt/commands.sh" +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "echo 'cd /opt/zkevm-contracts && git checkout $TAG_TARGET_FORKID' >> /opt/commands.sh" +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS "chmod +x /opt/commands.sh" + +# wait for batches to be verified on sequencer +echo "Waiting for everything to verify and sync on sequencer" +DONE=0 +while [ $DONE -ne 1 ]; do + TRUSTED__ON_SEQCR=$(printf "%d" $(cast rpc --json --rpc-url $(kurtosis port print "$STACK_NAME" $SVC_SEQUENCER rpc) zkevm_batchNumber | jq -r)) + VERIFIED_ON_SEQCR=$(printf "%d" $(cast rpc --json --rpc-url $(kurtosis port print "$STACK_NAME" $SVC_SEQUENCER rpc) zkevm_verifiedBatchNumber | jq -r)) + VERIFIED_ON_CHAIN=$(kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS ". /opt/commands.sh && cast call \$ROLLUP_MAN \"rollupIDToRollupData(uint32)(address,uint64,address,uint64,bytes32,uint64,uint64,uint64,uint64,uint64,uint64,uint8)\" 1 | head -6 | tail -1" | tail -2 | head -1) + echo "Trusted batch number on sequencer: $TRUSTED__ON_SEQCR, Verified batch number on sequencer: $VERIFIED_ON_SEQCR, Verified batch number on chain: $VERIFIED_ON_CHAIN" + if [ "$TRUSTED__ON_SEQCR" -ne "$VERIFIED_ON_SEQCR" ] || [ "$TRUSTED__ON_SEQCR" -ne "$VERIFIED_ON_CHAIN" ]; then + sleep 5 + else + DONE=1 + fi +done +echo "DONE: Sequencer status is up to date" + +# wait for rpc to sync +echo "Waiting for RPC to be totally synced" +DONE=0 +while [ $DONE -ne 1 ]; do + TRUSTED__ON_RPC=$(printf "%d" $(cast rpc --json --rpc-url $(kurtosis port print "$STACK_NAME" $SVC_RPC rpc) zkevm_batchNumber | jq -r)) + VERIFIED_ON_RPC=$(printf "%d" $(cast rpc --json --rpc-url $(kurtosis port print "$STACK_NAME" $SVC_RPC rpc) zkevm_verifiedBatchNumber | jq -r)) + VERIFIED_ON_CHAIN=$(kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS ". /opt/commands.sh && cast call \$ROLLUP_MAN \"rollupIDToRollupData(uint32)(address,uint64,address,uint64,bytes32,uint64,uint64,uint64,uint64,uint64,uint64,uint8)\" 1 | head -6 | tail -1" | tail -2 | head -1) + echo "Trusted batch number on rpc: $TRUSTED__ON_RPC, Verified batch number on rpc: $VERIFIED_ON_RPC, Verified batch number on chain: $VERIFIED_ON_CHAIN" + if [ "$TRUSTED__ON_RPC" -ne "$VERIFIED_ON_RPC" ] || [ "$TRUSTED__ON_RPC" -ne "$VERIFIED_ON_CHAIN" ]; then + sleep 5 + else + DONE=1 + fi +done +echo "DONE: RPC status is up to date" + +# Stop services +echo "Stopping services..." +kurtosis service stop "$STACK_NAME" $SVC_CDKNODE +kurtosis service stop "$STACK_NAME" $SVC_PROVER +kurtosis service stop "$STACK_NAME" $SVC_BRIDGE +kurtosis service stop "$STACK_NAME" $SVC_RPC +kurtosis service stop "$STACK_NAME" $SVC_SEQUENCER +kurtosis service stop "$STACK_NAME" $SVC_SLESS_EXECUTOR + +# Depoly verifier +echo "Deploying verifier..." +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS \ + ". /opt/commands.sh && \ + forge create \ + --broadcast \ + --json \ + --private-key \$PRIV_KEY \ + /opt/zkevm-contracts/contracts/mocks/VerifierRollupHelperMock.sol:VerifierRollupHelperMock > /opt/verifier-out.json" + +# Add new rollup type +echo "Adding new rollup type..." +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS \ + ". /opt/commands.sh && \ + cast send \ + --json \ + --private-key \$PRIV_KEY \ + \$ROLLUP_MAN \ + 'addNewRollupType(address,address,uint64,uint8,bytes32,string)' \ + \$CONSENSUS \ + \"\$(jq -r '.deployedTo' /opt/verifier-out.json)\" \ + $TARGET_FORKID 0 \$GENESIS 'new_forkid_$TARGET_FORKID' > /opt/add-rollup-type-out.json" + + +# Update rollup +echo "Updating rollup..." +kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS \ + ". /opt/commands.sh && \ + cast send \ + --json \ + --private-key \$PRIV_KEY \ + \$ROLLUP_MAN \ + 'updateRollup(address,uint32,bytes)' \ + \$ROLLUP \ + \$(printf \"%d\\n\" \$(jq -r '.logs[0].topics[1]' /opt/add-rollup-type-out.json)) \ + 0x > /opt/update-rollup-type-out.json" + +# Verify forkid on chain +echo "Checking on chain forkid..." +FORKID_ON_CHAIN=$(kurtosis service exec "$STACK_NAME" $SVC_CONTRACTS ". /opt/commands.sh && cast call \$ROLLUP_MAN \"rollupIDToRollupData(uint32)(address,uint64,address,uint64,bytes32,uint64,uint64,uint64,uint64,uint64,uint64,uint8)\" 1 | head -4 | tail -1" | tail -2 | head -1) +if [ "$FORKID_ON_CHAIN" -ne "$TARGET_FORKID" ]; then + echo "KO: Forkid not updated on chain!" + exit 1 +else + echo "OK: Forkid on chain: $FORKID_ON_CHAIN" +fi + +# Unhalt sequencer +echo "Unhalting sequencer..." +kurtosis service start "$STACK_NAME" $SVC_SEQUENCER +kurtosis service exec "$STACK_NAME" $SVC_SEQUENCER \ + "sed -ni '/zkevm.sequencer-halt-on-batch-number/"\!"p' /etc/cdk-erigon/config.yaml; \ + echo \"zkevm.sequencer-halt-on-batch-number: 0\" >> /etc/cdk-erigon/config.yaml" +kurtosis service stop "$STACK_NAME" $SVC_SEQUENCER +kurtosis service start "$STACK_NAME" $SVC_SEQUENCER + +# Wait for sequencer to become responsive +echo "Waiting for Sequencer's rpc port to become available" +until cast rpc --json --rpc-url $(kurtosis port print "$STACK_NAME" "$SVC_SEQUENCER" rpc) zkevm_getForkId &> /dev/null; do + printf '.' + sleep 3 +done +echo + +# Check forkid on Sequencer +FORKID=$SOURCE_FORKID +while [ "$FORKID" -ne "$TARGET_FORKID" ]; do + FORKID=$(printf "%d" $(cast rpc --json --rpc-url $(kurtosis port print "$STACK_NAME" "$SVC_SEQUENCER" rpc) zkevm_getForkId | jq -r)) + echo "Current Sequencer forkid: $FORKID" + sleep 3 +done +echo "SEQUENCER SUCCESSFULLY UPGRADED TO FORKID $TARGET_FORKID" + +# Start RPC as well +kurtosis service start "$STACK_NAME" $SVC_RPC + +# Wait for rpc to become responsive +echo "Waiting for RPC's rpc port to become available" +until cast rpc --json --rpc-url $(kurtosis port print "$STACK_NAME" "$SVC_RPC" rpc) zkevm_getForkId &> /dev/null; do + printf '.' + sleep 3 +done +echo + +# Check forkid on RPC +FORKID=$SOURCE_FORKID +COUNTER=0 +MAX_RETRIES=25 +while [ "$FORKID" -ne "$TARGET_FORKID" ]; do + ((COUNTER++)) + FORKID=$(printf "%d" $(cast rpc --json --rpc-url $(kurtosis port print "$STACK_NAME" "$SVC_RPC" rpc) zkevm_getForkId | jq -r)) + echo "Current RPC forkid: $FORKID" + if [[ $COUNTER -ge $MAX_RETRIES ]]; then + FORKID=$TARGET_FORKID # To break the loop + else + sleep 3 + fi +done +# If we reached max_retries on counter, it didn't succeed +if [[ $COUNTER -ge $MAX_RETRIES ]]; then + echo "ERROR: RPC NOT ABLE to DETECT NEW FORKID $TARGET_FORKID" +else + echo "SUCCESS: RPC ALSO ON FORKID $TARGET_FORKID" +fi + +# clean up +echo "Cleaning up deployed enclave..." +rm "$KURTOSIS_CONFIG" +kurtosis enclave stop "$STACK_NAME" +kurtosis enclave rm "$STACK_NAME" + +exit 0