init.sh
Overview
`init.sh` is a shell script designed to initialize and run an Ethereum-compatible blockchain node using the `geth` client. It automates the setup of the node's data directory, handles optional snapshot restoration for faster synchronization, configures essential runtime parameters, and manages the lifecycle of the `geth` process including graceful shutdown on termination signals.
Key functionalities include:
Restoring blockchain data from compressed snapshots (supporting
.tar.lz4and.tar.zstformats).Initializing the blockchain data directory if it does not exist.
Ensuring specific configuration parameters are set (
StateScheme = "path").Starting the
gethclient with a comprehensive set of flags to expose HTTP and WebSocket APIs with broad access.Handling termination signals (
TERM,INT) to stop thegethprocess cleanly.
This script is typically used in containerized or automated environments where rapid node startup and proper signal handling are critical.
Detailed Explanation
Environment Variables and Constants
DEBUG: If set to"true", enables shell debugging mode (set -x), printing each command before execution.DATA_DIR: Root directory for blockchain data, defaulting to/data.CHAINDATA_DIR: Path to thegethblockchain chaindata directory (/data/geth/chaindata).SNAPSHOT: URL to a snapshot archive for restoring blockchain data (optional).
Main Script Flow
Error Handling and Debugging
set -e [ "$DEBUG" == "true" ] && set -xset -e: Immediately exits the script if any command returns a non-zero status.If
DEBUGis enabled, prints each command before execution.
Snapshot Restoration
if [[ -n $SNAPSHOT && ! -d "$CHAINDATA_DIR" ]]; then ... fiChecks if
SNAPSHOTis set and the chaindata directory does not exist.Installs necessary tools (
wget, pluslz4orzstddepending on snapshot format).Removes any existing
gethdata directory.Downloads and extracts the snapshot directly into the data directory.
Supports two snapshot compression formats:
.tar.lz4: Useslz4CLI for decompression..tar.zst: UseszstdCLI for decompression.
Genesis Initialization
if [[ ! -d "$CHAINDATA_DIR" ]]; then geth init --datadir $DATA_DIR genesis.json fiIf the chaindata directory still does not exist after snapshot restoration, initializes the blockchain using a
genesis.jsonfile.
Configuration Adjustment
if ! grep -q 'StateScheme = "path"' config.toml; then sed -i '/^\[Eth\]/a StateScheme = "path"' config.toml fiChecks if the
StateSchemeis set to"path"in theconfig.tomlfile.If not present, inserts the line immediately after the
[Eth]section header.This setting influences how the Ethereum state is stored on disk.
Functions
start()
Starts the `geth` node with specified options.
start() {
geth \
--config config.toml \
--datadir $DATA_DIR \
--syncmode full \
--db.engine pebble \
--http \
--http.addr 0.0.0.0 \
--http.port 8545 \
--http.api eth,net,web3,debug,txpool \
--http.vhosts '*' \
--http.corsdomain '*' \
--ws \
--ws.addr 0.0.0.0 \
--ws.port 8546 \
--ws.api eth,net,web3,debug,txpool \
--ws.origins '*' \
--state.scheme path \
--rpc.allow-unprotected-txs \
--history.transactions 0 \
--nat none &
PID="$!"
}
**Parameters:** None
**Returns:** None (runs `geth` in the background and stores its PID in `PID`)
**Details:**
--config config.toml: Uses the provided config file.--datadir $DATA_DIR: Location of blockchain data.--syncmode full: Full node synchronization mode.--db.engine pebble: Uses Pebble key-value store for the database backend.Enables HTTP and WebSocket RPC endpoints bound to all interfaces (
0.0.0.0), exposing APIs:eth,net,web3,debug,txpool.Sets permissive CORS and virtual host settings (
*) to allow cross-origin requests.--state.scheme path: Matches the configuration inserted earlier, sets state storage scheme.--rpc.allow-unprotected-txs: Allows sending transactions without protection (use carefully).Disables historical transaction indexing (
--history.transactions 0) to optimize storage.--nat none: Disables NAT traversal.
**Usage Example:**
start
Starts the `geth` node in the background and captures its process ID.
stop()
Gracefully stops the running `geth` process.
stop() {
echo "Catching signal and sending to PID: $PID" && kill $PID
while $(kill -0 $PID 2>/dev/null); do sleep 1; done
}
**Parameters:** None
**Returns:** None
**Details:**
Sends a termination signal to the
gethprocess identified byPID.Waits in a loop until the process has exited before proceeding.
Provides a message indicating signal forwarding.
**Usage Example:**
stop
Stops the running `geth` node gracefully.
Signal Handling
trap 'stop' TERM INT
Registers the
stopfunction to be called when the script receivesSIGTERMorSIGINTsignals.Ensures that the
gethprocess is properly terminated on container shutdown or Ctrl+C.
Process Control
start
wait $PID
Starts the
gethprocess.Waits for the
gethprocess to exit, keeping the script running until termination.
Implementation Details and Algorithms
Snapshot Restoration: The script uses streaming decompression and extraction to avoid writing large temporary files. This is achieved by piping the output of
wgetdirectly intolz4orzstd, and then intotarfor extraction.Conditional Installation: Uses Alpine's package manager (
apk) to install required tools only at runtime if snapshot restoration is needed.Signal Trapping: Ensures that the script responds correctly to termination signals and does not leave orphaned processes.
Configuration Injection: Uses
sedto programmatically insert configuration lines, ensuring idempotency by first checking if the line exists.
Interaction with Other System Components
genesis.json: This file must be present in the same context as the script to initialize the blockchain if no snapshot is restored.config.toml: Thegethconfiguration file that influences node behavior; the script modifies it to set the state scheme.gethexecutable: The core Ethereum client binary that runs the node.External Snapshots: URLs provided via
SNAPSHOTenvironment variable allow the script to restore blockchain state quickly from pre-synced snapshots.System packages: Uses
apkto install utilities (wget,lz4,zstd) dynamically, assuming an Alpine Linux environment.
This script is typically part of a containerized deployment, such as a Docker container, where it serves as the entrypoint or startup script.
Visual Diagram
flowchart TD
StartScript["Start init.sh script"]
CheckDebug["Check DEBUG env"]
SetErrorExit["set -e"]
CheckSnapshot["Is SNAPSHOT set and chaindata dir missing?"]
InstallWget["Install wget"]
RemoveOldData["Remove old geth data"]
CheckLZ4["Is snapshot .tar.lz4?"]
InstallLZ4["Install lz4"]
DownloadLZ4["Download & extract snapshot (lz4)"]
CheckZST["Is snapshot .tar.zst?"]
InstallZST["Install zstd"]
DownloadZST["Download & extract snapshot (zstd)"]
CheckChainData["Does chaindata dir exist?"]
InitGenesis["Run geth init with genesis.json"]
CheckConfig["Check 'StateScheme = \"path\"' in config.toml"]
UpdateConfig["Insert StateScheme = \"path\" if missing"]
DefineStartFunc["Define start() function"]
DefineStopFunc["Define stop() function"]
SetupTrap["Setup trap for TERM and INT signals"]
StartGeth["Call start()"]
WaitPID["wait for geth process"]
StartScript --> SetErrorExit
SetErrorExit --> CheckDebug
CheckDebug --> CheckSnapshot
CheckSnapshot -->|Yes| InstallWget
CheckSnapshot -->|No| CheckChainData
InstallWget --> RemoveOldData
RemoveOldData --> CheckLZ4
CheckLZ4 -->|Yes| InstallLZ4
CheckLZ4 -->|No| CheckZST
InstallLZ4 --> DownloadLZ4
DownloadLZ4 --> CheckChainData
CheckZST -->|Yes| InstallZST
CheckZST -->|No| CheckChainData
InstallZST --> DownloadZST
DownloadZST --> CheckChainData
CheckChainData -->|No| InitGenesis
CheckChainData -->|Yes| CheckConfig
InitGenesis --> CheckConfig
CheckConfig -->|No| UpdateConfig
CheckConfig -->|Yes| DefineStartFunc
UpdateConfig --> DefineStartFunc
DefineStartFunc --> DefineStopFunc
DefineStopFunc --> SetupTrap
SetupTrap --> StartGeth
StartGeth --> WaitPID
Summary
`init.sh` is a robust initialization and startup script for a `geth` Ethereum node, optimized for containerized deployments. It supports fast snapshot-based restoration, configuration management, and graceful shutdown handling. The script ensures the node is properly configured and started with a comprehensive RPC API surface, facilitating blockchain interaction via HTTP and WebSocket protocols.
By automating these setup steps, the script reduces manual intervention and accelerates deployment times for blockchain nodes in development, testing, or production environments.