init.sh
Overview
`init.sh` is a shell script designed to initialize and run the Heimdall node software on a Unix-like system (typically within a containerized environment). Heimdall is a component of the Polygon blockchain architecture that acts as a consensus and validator layer.
The script automates environment setup, dependency installation, configuration initialization, optional snapshot restoration, and node startup with proper signal handling for graceful shutdowns.
Detailed Explanation
Environment Setup and Dependency Installation
set -e
apk add bash curl jq wget zstd tar pv aria2
[ "$DEBUG" = "true" ] && set -x
set -e: Immediately exits the script if any command returns a non-zero status, preventing cascading failures.Installs necessary packages using Alpine Linux's package manager
apk:bash— shell interpreter.curl— data transfer tool.jq— JSON processor.wget— file downloader.zstd— compression utility.tar— archive utility.pv— monitors the progress of data through a pipeline.aria2— lightweight multi-protocol & multi-source command-line download utility.
If
DEBUGenvironment variable is set to"true", enables shell debugging mode (set -x) to print commands as they are executed.
Directory Variables
HOME_DIR=/root/.heimdalld
CONFIG_DIR=$HOME_DIR/config
HOME_DIR: Defines the base directory for Heimdall data and config.CONFIG_DIR: Configuration directory under the home directory.
Snapshot Restoration Logic
if [ -n "$SNAPSHOT" ] && [ ! -f "$HOME_DIR/data/priv_validator_state.json" ]; then
rm -rf $HOME_DIR/data;
mkdir -p $HOME_DIR/data;
curl -L $SNAPSHOT | bash -s -- --network mainnet --client heimdall --extract-dir $HOME_DIR/data --validate-checksum true
fi
If the environment variable
SNAPSHOTis set (non-empty) and the validator state file does not exist, the script:Clears any existing data directory.
Creates a fresh data directory.
Downloads and extracts a snapshot provided by Polygon (URL specified in
SNAPSHOT), using the snapshot's own installation script (bash -s -- ...).The snapshot is validated with checksum verification.
This enables faster node sync by restoring data from a known snapshot.
Configuration Initialization
if [ ! -d "$CONFIG_DIR" ]; then
heimdalld init --home $HOME_DIR
cp /var/lib/heimdall/genesis-mainnet-v1.json $CONFIG_DIR/genesis.json
fi
If the configuration directory does not exist, it:
Initializes Heimdall configuration with
heimdalld init.Copies a pre-defined genesis file for the mainnet into configuration directory to define the blockchain's initial state.
Functions
start()
Starts the Heimdall node with configured options.
start() {
heimdalld start \
--home $HOME_DIR \
--chain mainnet \
--rpc.laddr tcp://0.0.0.0:26657 \
--bor_rpc_url http://localhost:8545 \
--eth_rpc_url $ETH_RPC_URL \
--p2p.seeds '[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656' \
--rest-server \
--node "tcp://localhost:26657" &
PID="$!"
}
Runs
heimdalld startwith:--home $HOME_DIR: Specifies the data directory.--chain mainnet: Runs on mainnet chain.--rpc.laddr: Listens for RPC connections on all interfaces at port 26657.--bor_rpc_url: Connects to local Bor node at port 8545.--eth_rpc_url: Uses Ethereum RPC URL from environment variableETH_RPC_URL.--p2p.seeds: Specifies a hardcoded list of seed nodes for peer discovery.--rest-server: Enables REST API server.--node: Connects to local Tendermint RPC node.
Runs in background (
&), and stores its process ID inPID.
**Usage example:**
start
echo "Heimdall started with PID $PID"
stop()
Gracefully stops the Heimdall process.
stop() {
echo "Catching signal and sending to PID: $PID" && kill $PID
while $(kill -0 $PID 2>/dev/null); do sleep 1; done
}
Sends
SIGTERMto the Heimdall process.Waits in a loop until the process is completely stopped.
Ensures clean shutdown on receiving termination signals.
Signal Trapping and Main Execution
trap 'stop' TERM INT
start
wait $PID
Sets up traps to catch
TERMandINTsignals (e.g., Ctrl+C or container shutdown).On these signals, calls
stop()function to gracefully terminate Heimdall.Starts the Heimdall node (
start).Waits for the
heimdalldprocess to exit.
Important Implementation Details
Robust startup: Uses
set -eto prevent partial or corrupted initialization.Snapshot restoration: Supports faster node syncing by restoring a snapshot if provided.
Configuration persistence: Only initializes configuration once, avoiding overwriting user data.
Graceful shutdown: Uses signal trapping to ensure resources are cleanly released.
Background process management: Manages the Heimdall process ID for lifecycle control.
Seed nodes: Hardcoded P2P seeds ensure initial peer discovery in the network.
Interactions with Other System Components
Heimdall binary (
heimdalld): The script acts as a wrapper to invoke and manage this executable, which handles consensus and validator duties.Polygon snapshot service: Downloads snapshots from Polygon's snapshot URL when
SNAPSHOTis set.Bor node: Communicates with a local Bor node via RPC on
http://localhost:8545.Ethereum RPC node: Uses Ethereum RPC URL provided via environment variable
ETH_RPC_URL.Configuration files: Uses genesis file located at
/var/lib/heimdall/genesis-mainnet-v1.json.Container environment: Typically this script is run inside a container where required binaries and dependencies are installed.
Visual Diagram
flowchart TD
StartScript([Start Script])
StartScript --> InstallDeps[Install Dependencies (apk add)]
InstallDeps --> CheckSnapshot{Is $SNAPSHOT set and \npriv_validator_state.json missing?}
CheckSnapshot -- Yes --> RemoveData[Remove Existing Data Dir]
RemoveData --> CreateDataDir[Create Data Dir]
CreateDataDir --> DownloadSnapshot[Download & Extract Snapshot]
DownloadSnapshot --> CheckConfigDir
CheckSnapshot -- No --> CheckConfigDir{Does $CONFIG_DIR exist?}
CheckConfigDir -- No --> InitConfig[Run heimdalld init]
InitConfig --> CopyGenesis[Copy genesis-mainnet-v1.json]
CopyGenesis --> StartHeimdall
CheckConfigDir -- Yes --> StartHeimdall[Start heimdalld Process (Background)]
StartHeimdall --> SetPID[Store PID of heimdalld]
SetPID --> TrapSignal[Set trap for TERM and INT signals]
TrapSignal --> WaitPID[Wait for PID exit]
WaitPID -->|On SIGTERM or SIGINT| StopHeimdall[Stop heimdalld gracefully]
StopHeimdall --> WaitStop[Wait until process ends]
WaitStop --> EndScript([End])
Summary
`init.sh` is a robust, production-grade initialization and startup script for the Heimdall node in the Polygon blockchain ecosystem. It ensures all prerequisites are installed, optionally restores fast sync snapshots, initializes configuration only once, and manages the node lifecycle with graceful shutdown handling. Its design supports running in containerized environments and integrates tightly with other Polygon components such as Bor and Ethereum RPC nodes.
This script is typically part of a container image's entrypoint or startup routine in a larger orchestrated blockchain infrastructure stack.