From 8a358123d8f996bf56ae4f08e6f0851fc5596bf5 Mon Sep 17 00:00:00 2001 From: auricom <27022259+auricom@users.noreply.github.com> Date: Wed, 2 Jul 2025 17:27:48 +0200 Subject: [PATCH 1/3] feat: evm reth state backup --- .vitepress/config.ts | 4 + guides/evm-reth-backup.md | 220 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 guides/evm-reth-backup.md diff --git a/.vitepress/config.ts b/.vitepress/config.ts index a9fd5cf89..f04d190b4 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -328,6 +328,10 @@ function sidebarHome() { text: "EVM Based Sequencer", link: "/guides/evm-based", }, + { + text: "EVM reth state backup", + link: "/guides/evm-reth-backup", + }, { text: "Metrics", link: "/guides/metrics", diff --git a/guides/evm-reth-backup.md b/guides/evm-reth-backup.md new file mode 100644 index 000000000..1ff516478 --- /dev/null +++ b/guides/evm-reth-backup.md @@ -0,0 +1,220 @@ +# Rollkit EVM reth State Backup Guide + +## Introduction + +This guide covers how to backup the reth state of a Rollkit EVM based blockchain. This implementation provides a production-ready approach to data protection. + +## Prerequisites + +Before starting, ensure you have: + +- A running Rollkit full node - Follow the [Rollkit Full Node Setup Guide](https://rollkit.dev/guides/full-node) to set up your node +- Zstandard (zstd) compression tool installed +- Administrative access to the Docker host +- Sufficient disk space for backups (at least 2x the current volume size) +- Access to remote backup storage (optional but recommended) +- Basic understanding of Docker volumes + +## Key Component to Backup + +Reth datadir : contains the entire EVM state and node data. + +## Performing manual backup + +### 1. Verify Node Synchronization + +```bash +# Check Rollkit node status +curl -sX POST \ + -H "Content-Type: application/json" \ + -H "Connect-Protocol-Version: 1" \ + -d "{}" \ + http://:/rollkit.v1.HealthService/Livez + +# Verify reth sync status +curl -sX POST \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \ + http://: + +# Expected response for a fully synced node: +# {"jsonrpc":"2.0","id":1,"result":false} +``` + +### 2. Stop Services Gracefully + +You will need to stop both rollkit and reth-rollkit on the fullnode stack, according to your setup. + +Example for docker-compose based setup: +```bash +# Stop services in correct order +docker compose stop rollkit-evm-single +docker compose stop rollkit-reth + +# Verify all containers are stopped +docker compose ps +``` + +### 3. Create Backup + +```bash +# Create backup directory +BACKUP_BASE_DIR="" +mkdir -p "${BACKUP_BASE_DIR}" + +# Set backup timestamp +BACKUP_DATE=$(date +%Y%m%d_%H%M%S) + +# Backup reth-rollkit datadir using zstandard compression +tar cf - -C "${RETH_ROLLKIT_DATADIR}" . | zstd -3 > "${BACKUP_BASE_DIR}/reth_state_${BACKUP_DATE}.tar.zst" + +# Generate checksum +sha256sum "${BACKUP_BASE_DIR}/reth_state_${BACKUP_DATE}.tar.zst" > "${BACKUP_BASE_DIR}/reth_state_${BACKUP_DATE}.tar.zst.sha256" +``` + +### 4. Restart services + +You will need to stop both rollkit and reth-rollkit on the fullnode stack, according to your setup. + +Example for docker-compose based setup: +```bash +# Start services +docker compose up -d + +# Monitor startup +docker compose logs -f +``` + +## Automated backup + +### 1. Create the Backup Script + +```bash +sudo nano /usr/local/bin/rollkit-backup.sh +``` +Add the following content + +```bash +#!/bin/bash +# Reth-Rollkit Backup Script with Zstandard Compression + +set -euo pipefail + +# Configuration +RETH_ROLLKIT_DATADIR="" +BACKUP_BASE_DIR="${BACKUP_BASE_DIR:-/backup/rollkit}" +REMOTE_BACKUP="${REMOTE_BACKUP:-backup-server:/backups/rollkit}" +RETENTION_DAYS="${RETENTION_DAYS:-7}" +COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}" +ZSTD_LEVEL="${ZSTD_LEVEL:-3}" +ZSTD_THREADS="${ZSTD_THREADS:-0}" # 0 = auto-detect +FULLNODE_IP="${FULLNODE_IP:-localhost}" +FULLNODE_RPC_PORT="${FULLNODE_RPC_PORT:-7331}" +FULLNODE_RETH_IP="${FULLNODE_RETH_IP:-localhost}" +FULLNODE_RETH_PORT="${FULLNODE_RETH_PORT:-8545}" + +# Functions +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" +} + +check_sync_status() { + # Check Rollkit node health + local rollkit_status=$(curl -sX POST \ + -H "Content-Type: application/json" \ + -H "Connect-Protocol-Version: 1" \ + -d "{}" \ + http://${FULLNODE_IP}:${FULLNODE_RPC_PORT}/rollkit.v1.HealthService/Livez) + + # Check reth sync status + local sync_status=$(curl -sX POST \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \ + http://${FULLNODE_RETH_IP}:${FULLNODE_RETH_PORT} | jq -r '.result') + + if [ "$sync_status" != "false" ]; then + log "WARNING: Node is still syncing. Backup may be incomplete." + fi +} + +# Main backup process +main() { + log "Starting Rollkit backup process" + + # Setup + BACKUP_DATE=$(date +%Y%m%d_%H%M%S) + BACKUP_DIR="${BACKUP_BASE_DIR}" + + # Create backup directory + mkdir -p "${BACKUP_DIR}" + + # Check sync status + check_sync_status + + # Stop services + log "Stopping Rollkit services" + docker compose -f ${COMPOSE_FILE} stop fullnode + docker compose -f ${COMPOSE_FILE} stop reth-rollkit + + # Backup reth state using zstandard compression + log "Backing up reth state with zstandard compression" + tar cf - -C ${RETH_ROLLKIT_DATADIR} . | zstd -${ZSTD_LEVEL} -T${ZSTD_THREADS} > "${BACKUP_DIR}/reth_state_${BACKUP_DATE}.tar.zst" + + # Generate checksum + sha256sum "${BACKUP_DIR}/reth_state_${BACKUP_DATE}.tar.zst" > "${BACKUP_DIR}/reth_state_${BACKUP_DATE}.tar.zst.sha256" + + # Transfer to remote storage + if [ -n "${REMOTE_BACKUP:-}" ]; then + log "Transferring backup to remote storage" + rsync -avz "${BACKUP_DIR}/reth_state_${BACKUP_DATE}.tar.zst*" "${REMOTE_BACKUP}/" || log "WARNING: Remote transfer failed" + fi + + # Restart services + log "Restarting services" + docker compose -f ${COMPOSE_FILE} up -d + + # Cleanup old backups + log "Cleaning up old backups" + find "${BACKUP_BASE_DIR}" -name "reth_state_*.tar.zst" -mtime +${RETENTION_DAYS} -delete + find "${BACKUP_BASE_DIR}" -name "reth_state_*.tar.zst.sha256" -mtime +${RETENTION_DAYS} -delete + + log "Backup completed successfully" +} + +# Run backup +main "$@" +``` + +### 2. Make Script Executable' + +```bash +sudo chmod +x /usr/local/bin/rollkit-backup.sh +``` + +### 3. Schedule Automated Backups + +```bash +# Edit crontab +sudo crontab -e + +# Add daily backup at 2 AM +0 2 * * * /usr/local/bin/rollkit-backup.sh >> /var/log/rollkit-backup.log 2>&1 +``` + +## Best practices + +### Backup Strategy + +1. Schedule regular backups - Daily backups during low-activity periods +2. Implement retention policies - Keep x days of local backups, y days remote +3. Test restoration procedures - Monthly restoration drills in test environment +4. Monitor backup jobs - Set up alerts for failed backups +5. Use appropriate compression levels - Balance between compression ratio and speed + +### Zstandard Compression Levels + +| Level | Speed | Compression Ratio | Use Case | +|-------|---------|-------------------|---------------------| +| 3 | Default | Balanced | Standard backups | +| 9 | Slower | Better | Long-term archives | +| 19 | Slowest | Best | Maximum compression | From b77d95bc32e0ef12bd709b99df348af2c95e4c49 Mon Sep 17 00:00:00 2001 From: auricom <27022259+auricom@users.noreply.github.com> Date: Thu, 3 Jul 2025 09:25:54 +0200 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- guides/evm-reth-backup.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/guides/evm-reth-backup.md b/guides/evm-reth-backup.md index 1ff516478..1b2cf8ec6 100644 --- a/guides/evm-reth-backup.md +++ b/guides/evm-reth-backup.md @@ -48,8 +48,8 @@ You will need to stop both rollkit and reth-rollkit on the fullnode stack, accor Example for docker-compose based setup: ```bash # Stop services in correct order -docker compose stop rollkit-evm-single -docker compose stop rollkit-reth +docker compose stop fullnode +docker compose stop reth-rollkit # Verify all containers are stopped docker compose ps @@ -59,7 +59,10 @@ docker compose ps ```bash # Create backup directory -BACKUP_BASE_DIR="" +# Create backup directory +# IMPORTANT: Set your backup base directory and reth-rollkit data directory paths +BACKUP_BASE_DIR="/path/to/backups" +RETH_ROLLKIT_DATADIR="/path/to/reth-rollkit/datadir" mkdir -p "${BACKUP_BASE_DIR}" # Set backup timestamp @@ -74,7 +77,7 @@ sha256sum "${BACKUP_BASE_DIR}/reth_state_${BACKUP_DATE}.tar.zst" > "${BACKUP_BAS ### 4. Restart services -You will need to stop both rollkit and reth-rollkit on the fullnode stack, according to your setup. +You will need to restart both rollkit and reth-rollkit on the fullnode stack, according to your setup. Example for docker-compose based setup: ```bash @@ -101,7 +104,7 @@ Add the following content set -euo pipefail # Configuration -RETH_ROLLKIT_DATADIR="" +RETH_ROLLKIT_DATADIR="" # IMPORTANT: Set this to your reth-rollkit data directory path BACKUP_BASE_DIR="${BACKUP_BASE_DIR:-/backup/rollkit}" REMOTE_BACKUP="${REMOTE_BACKUP:-backup-server:/backups/rollkit}" RETENTION_DAYS="${RETENTION_DAYS:-7}" @@ -120,11 +123,12 @@ log() { check_sync_status() { # Check Rollkit node health - local rollkit_status=$(curl -sX POST \ + # Check Rollkit node health + curl -fsX POST \ -H "Content-Type: application/json" \ -H "Connect-Protocol-Version: 1" \ -d "{}" \ - http://${FULLNODE_IP}:${FULLNODE_RPC_PORT}/rollkit.v1.HealthService/Livez) + "http://${FULLNODE_IP}:${FULLNODE_RPC_PORT}/rollkit.v1.HealthService/Livez" > /dev/null # Check reth sync status local sync_status=$(curl -sX POST \ From e2ffa45b0b27f09140f1009eb6789d02f818f591 Mon Sep 17 00:00:00 2001 From: auricom <27022259+auricom@users.noreply.github.com> Date: Thu, 3 Jul 2025 09:33:55 +0200 Subject: [PATCH 3/3] jq + deps --- guides/evm-reth-backup.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/guides/evm-reth-backup.md b/guides/evm-reth-backup.md index 1b2cf8ec6..768f6e57a 100644 --- a/guides/evm-reth-backup.md +++ b/guides/evm-reth-backup.md @@ -10,11 +10,27 @@ Before starting, ensure you have: - A running Rollkit full node - Follow the [Rollkit Full Node Setup Guide](https://rollkit.dev/guides/full-node) to set up your node - Zstandard (zstd) compression tool installed +- jq JSON processor installed - Administrative access to the Docker host - Sufficient disk space for backups (at least 2x the current volume size) - Access to remote backup storage (optional but recommended) - Basic understanding of Docker volumes +## Installing Dependencies + +For Ubuntu/Debian-based Linux distributions, install the required dependencies: +```bash +# Update package list +sudo apt update + +# Install required tools +sudo apt install -y zstd jq + +# Verify installations +zstd --version +jq --version +``` + ## Key Component to Backup Reth datadir : contains the entire EVM state and node data. @@ -122,7 +138,6 @@ log() { } check_sync_status() { - # Check Rollkit node health # Check Rollkit node health curl -fsX POST \ -H "Content-Type: application/json" \