Skip to main content

Dockerfiles

Here are the Docker files for Sentinel Mainnet and Sentinel Testnets, available with and without Cosmovisor.

Sentinel Mainnet (sentinelhub-2)

For Mainnet, you can customize your setup based on whether you want to use Cosmovisor or not.

Dockerfile

#Import the latest ubuntu image which is 24.04 (Noble)
FROM ubuntu:latest

# Credit to TrinityStake for the great documentation to help make this possible
# Dockerfile Contents authored by Misfits (The Expanse)


# Set the working directory to root
WORKDIR /

# Install all of the basics we need to perform the install includes wget, nano, curl, git, jq, make, unzip and gcc
RUN apt-get update -y &&\
apt-get install software-properties-common -y &&\
apt-get install nano -y &&\
apt-get install wget -y &&\
apt-get install curl git jq make unzip gcc -y


# Perform some user housekeeping. Please change these if you use this image in production
RUN echo 'root:sentinelhub' | chpasswd &&\
useradd -ms /bin/bash sentinel &&\
echo 'sentinel:sentinel' | chpasswd

# Switch directory to sentinel home
WORKDIR /home/sentinel

# Install Golang and put variables in .bashrc
RUN yes '' | add-apt-repository ppa:longsleep/golang-backports &&\
apt-get install golang-go -y &&\
echo 'export GOROOT=/usr/lib/go' >> .bashrc &&\
echo 'export GOPATH=${HOME}/go' >> .bashrc &&\
echo 'export GOBIN=${GOPATH}/bin' >> .bashrc &&\
echo 'export PATH=${PATH}:${GOROOT}/bin:${GOBIN}' >> .bashrc


# Install Sentinel Hub
# Must be sentinel or make install executes incorrectly
USER sentinel
RUN git clone https://github.com/sentinel-official/sentinelhub.git "/home/sentinel/sentinelhub"

WORKDIR /home/sentinel/sentinelhub

RUN git checkout v0.11.5 &&\
make install

#root must perform the symlink to enable sentinelhub commands
USER root
RUN ln -s "/home/sentinel/go/bin/sentinelhub" /usr/bin/sentinelhub

USER sentinel

# Initialize the chain and replace the genesis file
RUN sentinelhub init --chain-id sentinelhub-2 "Mainnet | Docker" &&\
curl -fsLS -o "/home/sentinel/genesis.zip" "https://raw.githubusercontent.com/sentinel-official/networks/main/sentinelhub-2/genesis.zip" &&\
echo 'All' | unzip -d "/home/sentinel/.sentinelhub/config/" "/home/sentinel/genesis.zip" &&\
rm "${HOME}/genesis.zip"

# Configure Sentinel Hub
WORKDIR /home/sentinel/.sentinelhub/config

# Replace seeds, peers with sentinelhub ones, enable state-sync, multiple chunk fetches, and add gas prices
RUN sed -i 's/seeds = ""/seeds = "[email protected]:26656,[email protected]:26656,[email protected]:56656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:28685,[email protected]:26656,[email protected]:36656,[email protected]:26656,[email protected]:26656,[email protected]:56656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:28685,[email protected]:26656,[email protected]:36656,ebc272824924ea1a27ea3183dd0b9ba713494f83@sentinel.mainnet.peer.autostake.net:26706,[email protected]:23956"/g' config.toml &&\
sed -i 's/persistent_peers = ""/persistent_peers = "[email protected]:14656,[email protected]:26556,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:50656,[email protected]:26656,[email protected]:26656,[email protected]:29656,[email protected]:26656,[email protected]:26656,[email protected]:53656,[email protected]:26656,[email protected]:50656,[email protected]:26706,[email protected]:23956,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:10001,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26706,[email protected]:26656,[email protected]:16604,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:14656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:23956,[email protected]:26656,[email protected]:27156,[email protected]:26686,[email protected]:26656,[email protected]:26630,[email protected]:26103,[email protected]:26656,[email protected]:27057,[email protected]:23956,[email protected]:23956,[email protected]:26656,[email protected]:25656,[email protected]:26656,[email protected]:33656,[email protected]:26656,[email protected]:26656,[email protected]:50656,[email protected]:26656,[email protected]:26656,[email protected]:26796,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:21656,[email protected]:51656,[email protected]:26706,[email protected]:26609,[email protected]:26656,[email protected]:26656,[email protected]:31981,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26686,[email protected]:26656,[email protected]:26656,[email protected]:26796,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26706,[email protected]:23956,[email protected]:17256,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656"/g' config.toml &&\
sed -i 's/enable = false/enable = true/g' config.toml &&\
sed -i 's/pruning = "default"/pruning = "custom"/g' config.toml &&\
sed -i 's/pruning-keep-recent = "0"/pruning-keep-recent = "2"/g' config.toml &&\
sed -i 's/pruning-interval = "0"/pruning-interval = "1000"/g' config.toml &&\
sed -i 's/chunk_fetchers = "4"/chunk_fetchers = "42"/g' config.toml &&\
sed -i 's/indexer = "kv"/indexer = "null"/g' config.toml &&\
sed -i 's/prometheus = false/prometheus = true/g' config.toml &&\
sed -i 's/minimum-gas-prices = "0.1udvpn"/minimum-gas-prices = "0.01ibc\/31FEE1A2A9F9C01113F90BD0BBCCE8FD6BBB8585FAF109A2101827DD1D5B95B8,0.1udvpn,0.01ibc\/B1C0DDB14F25279A2026BC8794E12B259F8BDA546A3C5132CCAEE4431CE36783,0.01ibc\/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518,0.01ibc\/A8C2D23A1E6F95DA4E48BA349667E322BD7A6C996D8A4AAE8BA72E190F3D1477"/g' app.toml

# Replicate the state-sync-sentinel script for mainnet
COPY state-sync-sentinel.sh /home/sentinel/sentinelhub
WORKDIR /home/sentinel/sentinelhub

# Modify permissions to enable script run
USER root
RUN chown sentinel state-sync-sentinel.sh &&\
chmod 700 state-sync-sentinel.sh

USER sentinel

State Sync Mainnet

#!/bin/bash

# Script framework credit to Busurnode other contents authored by Misfits (The Expanse)
# Service Name
SERVICE_NAME=sentinelhub

# RPC Endpoints for the network
SNAP_RPC1="https://rpc-sentinel.busurnode.com:443"
SNAP_RPC2="https://na-rpc-sentinel.busurnode.com:443"

# Fetch block data from RPC
echo "Fetching trusted block data from RPC..."
LATEST_HEIGHT=$(curl -s $SNAP_RPC1/block | jq -r .result.block.header.height); \
BLOCK_HEIGHT=$((LATEST_HEIGHT - 2000)); \
TRUST_HASH=$(curl -s "$SNAP_RPC1/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash)

echo "Update config with latest block from RPC..."
sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \
s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$SNAP_RPC1,$SNAP_RPC2\"| ; \
s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \
s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"|" $HOME/.sentinelhub/config/config.toml

# Stop the sentinel service
echo "Stopping the sentinel service..."

# Find the PID of the process
pid=$(pgrep -f "$SERVICE_NAME")

# Check if the process is running
if [ -n "$pid" ]; then
# Kill the process
kill "$pid"
echo "Process $SERVICE_NAME killed successfully."
else
echo "Process $SERVICE_NAME not running."
fi

# Copy the validator state JSON file
echo "Backing up validator state..."
cd $HOME/sentinelhub
cp ~/.sentinelhub/data/priv_validator_state.json ~/.sentinelhub/priv_validator_state.json

# Reset Tendermint state
sentinelhub tendermint unsafe-reset-all --home $HOME/.sentinelhub --keep-addr-book

# Replace priv_validator_state from backup
echo "Recover validator state from backup..."
cp ~/.sentinelhub/priv_validator_state.json ~/.sentinelhub/data/priv_validator_state.json

# Start the sentinel service
echo "Starting the sentinel service..."
nohup $SERVICE_NAME start &
echo "Process complete."
echo "****To see the status of the process type cat nohup****"

Dockerfile with Cosmovisor

#Import the latest ubuntu image which is 24.04 (Noble)
FROM ubuntu:latest

# Credit to TrinityStake for the great documentation to help make this possible
# Dockerfile Contents authored by Misfits (The Expanse)

# Set the working directory to root
WORKDIR /

# Install all of the basics we need to perform the install includes wget, nano, curl, git, jq, make, unzip and gcc
RUN apt-get update -y &&\
apt-get install software-properties-common -y &&\
apt-get install nano -y &&\
apt-get install wget -y &&\
apt-get install curl git jq make unzip gcc -y


# Perform some user housekeeping. Please change these if you use this image in production
RUN echo 'root:sentinelhub' | chpasswd &&\
useradd -ms /bin/bash sentinel &&\
echo 'sentinel:sentinel' | chpasswd

# Switch directory to sentinel home
WORKDIR /home/sentinel

# Install Golang and put variables in .bashrc
RUN yes '' | add-apt-repository ppa:longsleep/golang-backports &&\
apt-get install golang-go -y &&\
echo 'export GOROOT=/usr/lib/go' >> .bashrc &&\
echo 'export GOPATH=${HOME}/go' >> .bashrc &&\
echo 'export GOBIN=${GOPATH}/bin' >> .bashrc &&\
echo 'export PATH=${PATH}:${GOROOT}/bin:${GOBIN}' >> .bashrc


# Install Sentinel Hub
# Must be sentinel or make install executes incorrectly
USER sentinel
RUN git clone https://github.com/sentinel-official/sentinelhub.git "/home/sentinel/sentinelhub"

WORKDIR /home/sentinel/sentinelhub

RUN git checkout v0.11.5 &&\
make install

#root must perform the symlink to enable sentinelhub commands
USER root
RUN ln -s "/home/sentinel/go/bin/sentinelhub" /usr/bin/sentinelhub

USER sentinel

# Initialize the chain and replace the genesis file
RUN sentinelhub init --chain-id sentinelhub-2 "Mainnet | Docker" &&\
curl -fsLS -o "/home/sentinel/genesis.zip" "https://raw.githubusercontent.com/sentinel-official/networks/main/sentinelhub-2/genesis.zip" &&\
echo 'All' | unzip -d "/home/sentinel/.sentinelhub/config/" "/home/sentinel/genesis.zip" &&\
rm "${HOME}/genesis.zip"

# Configure Sentinel Hub
WORKDIR /home/sentinel/.sentinelhub/config

# Replace seeds, peers with sentinelhub ones, enable state-sync, multiple chunk fetches, and add gas prices
RUN sed -i 's/seeds = ""/seeds = "[email protected]:26656,[email protected]:26656,[email protected]:56656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:28685,[email protected]:26656,[email protected]:36656,[email protected]:26656,[email protected]:26656,[email protected]:56656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:28685,[email protected]:26656,[email protected]:36656,ebc272824924ea1a27ea3183dd0b9ba713494f83@sentinel.mainnet.peer.autostake.net:26706,[email protected]:23956"/g' config.toml &&\
sed -i 's/persistent_peers = ""/persistent_peers = "[email protected]:14656,[email protected]:26556,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:50656,[email protected]:26656,[email protected]:26656,[email protected]:29656,[email protected]:26656,[email protected]:26656,[email protected]:53656,[email protected]:26656,[email protected]:50656,[email protected]:26706,[email protected]:23956,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:10001,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26706,[email protected]:26656,[email protected]:16604,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:14656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:23956,[email protected]:26656,[email protected]:27156,[email protected]:26686,[email protected]:26656,[email protected]:26630,[email protected]:26103,[email protected]:26656,[email protected]:27057,[email protected]:23956,[email protected]:23956,[email protected]:26656,[email protected]:25656,[email protected]:26656,[email protected]:33656,[email protected]:26656,[email protected]:26656,[email protected]:50656,[email protected]:26656,[email protected]:26656,[email protected]:26796,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:21656,[email protected]:51656,[email protected]:26706,[email protected]:26609,[email protected]:26656,[email protected]:26656,[email protected]:31981,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26686,[email protected]:26656,[email protected]:26656,[email protected]:26796,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26706,[email protected]:23956,[email protected]:17256,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656,[email protected]:26656"/g' config.toml &&\
sed -i 's/enable = false/enable = true/g' config.toml &&\
sed -i 's/pruning = "default"/pruning = "custom"/g' config.toml &&\
sed -i 's/pruning-keep-recent = "0"/pruning-keep-recent = "2"/g' config.toml &&\
sed -i 's/pruning-interval = "0"/pruning-interval = "1000"/g' config.toml &&\
sed -i 's/chunk_fetchers = "4"/chunk_fetchers = "42"/g' config.toml &&\
sed -i 's/indexer = "kv"/indexer = "null"/g' config.toml &&\
sed -i 's/prometheus = false/prometheus = true/g' config.toml &&\
sed -i 's/minimum-gas-prices = "0.1udvpn"/minimum-gas-prices = "0.01ibc\/31FEE1A2A9F9C01113F90BD0BBCCE8FD6BBB8585FAF109A2101827DD1D5B95B8,0.1udvpn,0.01ibc\/B1C0DDB14F25279A2026BC8794E12B259F8BDA546A3C5132CCAEE4431CE36783,0.01ibc\/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518,0.01ibc\/A8C2D23A1E6F95DA4E48BA349667E322BD7A6C996D8A4AAE8BA72E190F3D1477"/g' app.toml

# Replicate the state-sync-sentvisor script for mainnet
COPY state-sync-sentvisor.sh /home/sentinel/sentinelhub
WORKDIR /home/sentinel/sentinelhub

# Modify permissions to enable script run
USER root
RUN chown sentinel state-sync-sentvisor.sh &&\
chmod 700 state-sync-sentvisor.sh &&\
ln -s /home/sentinel/go/bin/cosmovisor /usr/local/bin/

USER sentinel

# Install Cosmovisor
RUN go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest &&\
mkdir -p ~/.sentinelhub/cosmovisor &&\
mkdir -p ~/.sentinelhub/cosmovisor/genesis &&\
mkdir -p ~/.sentinelhub/cosmovisor/genesis/bin &&\
mkdir -p ~/.sentinelhub/cosmovisor/upgrades &&\
echo "# Cosmovisor Environmental Variables" >> ~/.bashrc &&\
echo "export DAEMON_NAME=sentinelhub" >> ~/.bashrc &&\
echo "export DAEMON_HOME=$HOME/.sentinelhub" >> ~/.bashrc &&\
echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=false" >> ~/.bashrc &&\
echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc &&\
echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc &&\
echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc &&\
cp /home/sentinel/go/bin/sentinelhub ~/.sentinelhub/cosmovisor/genesis/bin

State Sync Mainnet with Cosmovisor

#!/bin/bash

# Script framework credit to Busurnode other contents authored by Misfits (The Expanse)
# Service Name

SERVICE_NAME=cosmovisor

# RPC Endpoints for the network
SNAP_RPC1="https://rpc-sentinel.busurnode.com:443"
SNAP_RPC2="https://na-rpc-sentinel.busurnode.com:443"

# Fetch block data from RPC
echo "Fetching trusted block data from RPC..."
LATEST_HEIGHT=$(curl -s $SNAP_RPC1/block | jq -r .result.block.header.height); \
BLOCK_HEIGHT=$((LATEST_HEIGHT - 2000)); \
TRUST_HASH=$(curl -s "$SNAP_RPC1/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash)

echo "Update config with latest block from RPC..."
sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \
s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$SNAP_RPC1,$SNAP_RPC2\"| ; \
s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \
s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"|" $HOME/.sentinelhub/config/config.toml

# Stop the cosmovisor service
echo "Stopping the cosmovisor service..."
# Find the PID of the process
pid=$(pgrep -f "$SERVICE_NAME")

# Check if the process is running
if [ -n "$pid" ]; then
# Kill the process
kill "$pid"
echo "Process $SERVICE_NAME killed successfully."
else
echo "Process $SERVICE_NAME not running."
fi

# Copy the validator state JSON file
echo "Backing up validator state..."
cd $HOME/sentinelhub
cp ~/.sentinelhub/data/priv_validator_state.json ~/.sentinelhub/priv_validator_state.json

# Reset Tendermint state
sentinelhub tendermint unsafe-reset-all --home $HOME/.sentinelhub --keep-addr-book

# Replace priv_validator_state from backup
echo "Recover validator state from backup..."
cp ~/.sentinelhub/priv_validator_state.json ~/.sentinelhub/data/priv_validator_state.json

# Start the cosmovisor service
echo "Starting the cosmovisor service..."
nohup $SERVICE_NAME run start &
echo "Process complete."
echo "****To see the status of the process type cat nohup****"

Sentinel Testnet (bluenet-2-1)

For Testnet, you can customize your setup based on whether you want to use Cosmovisor or not.

Dockerfile

#Import the latest ubuntu image which is 24.04 (Noble)
FROM ubuntu:latest

# Credit to TrinityStake for the great documentation to help make this possible
# Dockerfile Contents authored by Misfits (The Expanse)

# Set the working directory to root
WORKDIR /

# Install all of the basics we need to perform the install includes wget, nano, curl, git, jq, make, unzip and gcc
RUN apt-get update -y &&\
apt-get install software-properties-common -y &&\
apt-get install nano -y &&\
apt-get install wget -y &&\
apt-get install curl git jq make unzip gcc -y


# Perform some user housekeeping. Please change these if you use this image in production
RUN echo 'root:sentinelhub' | chpasswd &&\
useradd -ms /bin/bash sentinel &&\
echo 'sentinel:sentinel' | chpasswd

# Switch directory to sentinel home
WORKDIR /home/sentinel

# Install Golang
RUN yes '' | add-apt-repository ppa:longsleep/golang-backports &&\
apt-get install golang-go -y &&\
echo 'export GOROOT=/usr/lib/go' >> .bashrc &&\
echo 'export GOPATH=${HOME}/go' >> .bashrc &&\
echo 'export GOBIN=${GOPATH}/bin' >> .bashrc &&\
echo 'export PATH=${PATH}:${GOROOT}/bin:${GOBIN}' >> .bashrc


# Install Sentinel Hub please note the version is v12 here the current testnet version
# Must be sentinel or make install executes incorrectly
USER sentinel
RUN git clone https://github.com/sentinel-official/sentinelhub.git "/home/sentinel/sentinelhub"

WORKDIR /home/sentinel/sentinelhub

RUN git checkout v12.0.0-rc10 &&\
make install

# root must perform the symlink
USER root
RUN ln -s "/home/sentinel/go/bin/sentinelhub" /usr/bin/sentinelhub


USER sentinel

# Initialize the chain and replace the genesis file
RUN sentinelhub init --chain-id bluenet-2-1 "Bluenet | Docker" &&\
curl -fsLS -o "${HOME}/genesis.json" "https://raw.githubusercontent.com/sentinel-official/networks/main/bluenet-2-1/genesis.json" &&\
cp "${HOME}/genesis.json" "${HOME}/.sentinelhub/config/genesis.json" &&\
rm "${HOME}/genesis.json"

# Configure Sentinel Hub
WORKDIR /home/sentinel/.sentinelhub/config

# Replace seeds, peers with sentinelhub ones, enable state-sync, multiple chunk fetches, and add gas prices
RUN sed -i 's/seeds = ""/seeds = ""/g' config.toml &&\
sed -i 's/persistent_peers = ""/persistent_peers = "[email protected]:51056,[email protected]:51056,[email protected]:26656,[email protected]:26656"/g' config.toml &&\
sed -i 's/enable = false/enable = true/g' config.toml &&\
sed -i 's/chunk_fetchers = "4"/chunk_fetchers = "42"/g' config.toml &&\
sed -i 's/minimum-gas-prices = "0.1udvpn"/minimum-gas-prices = "0.01ibc\/31FEE1A2A9F9C01113F90BD0BBCCE8FD6BBB8585FAF109A2101827DD1D5B95B8,0.1udvpn,0.01ibc\/B1C0DDB14F25279A2026BC8794E12B259F8BDA546A3C5132CCAEE4431CE36783,0.01ibc\/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518,0.01ibc\/A8C2D23A1E6F95DA4E48BA349667E322BD7A6C996D8A4AAE8BA72E190F3D1477"/g' app.toml

# Replicate the state-sync-blue script for bluenet
COPY state-sync-blue.sh /home/sentinel/sentinelhub
WORKDIR /home/sentinel/sentinelhub

# Modify permissions to enable script run
USER root
RUN chown sentinel state-sync-blue.sh &&\
chmod 700 state-sync-blue.sh
USER sentinel

State Sync Testnet

#!/bin/bash

# Service Name (update this if you use service name other than 'sentinelhub', such as 'cosmovisor')
SERVICE_NAME=sentinelhub

SNAP_RPC1="https://rpc-sentinel-testnet.busurnode.com:443"
SNAP_RPC2="https://rpc-sentinel-testnet.busurnode.com:443"

# Fetch block data from RPC
echo "Fetching trusted block data from RPC..."
LATEST_HEIGHT=$(curl -s $SNAP_RPC1/block | jq -r .result.block.header.height); \
BLOCK_HEIGHT=$((LATEST_HEIGHT - 2000)); \
TRUST_HASH=$(curl -s "$SNAP_RPC1/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash)

echo "Update config with latest block from RPC..."
sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \
s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$SNAP_RPC1,$SNAP_RPC2\"| ; \
s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \
s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"|" $HOME/.sentinelhub/config/config.toml

# Stop the sentinel service
#echo "Stopping the sentinel service..."
#sudo service $SERVICE_NAME stop

# Copy the validator state JSON file
echo "Backing up validator state..."
cd $HOME
cp ~/.sentinelhub/data/priv_validator_state.json ~/.sentinelhub/priv_validator_state.json

# Reset Tendermint state
sentinelhub tendermint unsafe-reset-all --home $HOME/.sentinelhub --keep-addr-book

# Replace priv_validator_state from backup
echo "Recover validator state from backup..."
cp ~/.sentinelhub/priv_validator_state.json ~/.sentinelhub/data/priv_validator_state.json

# Start the sentinel service
echo "Starting the sentinel service..."
nohup $SERVICE_NAME start &
echo "Process complete."

Dockerfile with Cosmovisor

#Import the latest ubuntu image which is 24.04 (Noble)
FROM ubuntu:latest

# Credit to TrinityStake for the great documentation to help make this possible
# Dockerfile Contents authored by Misfits (The Expanse)

WORKDIR /

# Install all of the basics we need to perform the install
RUN apt-get update -y &&\
apt-get install software-properties-common -y &&\
apt-get install nano -y &&\
apt-get install wget -y &&\
apt-get install curl git jq make unzip gcc -y


# Perform some user housekeeping. Please change these if you use this image in production
RUN echo 'root:sentinelhub' | chpasswd &&\
useradd -ms /bin/bash sentinel &&\
echo 'sentinel:sentinel' | chpasswd

# Switch directory to sentinel home
WORKDIR /home/sentinel

# Install Golang
RUN yes '' | add-apt-repository ppa:longsleep/golang-backports &&\
apt-get install golang-go -y &&\
echo 'export GOROOT=/usr/lib/go' >> .bashrc &&\
echo 'export GOPATH=${HOME}/go' >> .bashrc &&\
echo 'export GOBIN=${GOPATH}/bin' >> .bashrc &&\
echo 'export PATH=${PATH}:${GOROOT}/bin:${GOBIN}' >> .bashrc


# Install Sentinel Hub please note the version is v12 here the current testnet version
# Must be sentinel or make install executes incorrectly
USER sentinel
RUN git clone https://github.com/sentinel-official/sentinelhub.git "/home/sentinel/sentinelhub"

WORKDIR /home/sentinel/sentinelhub

RUN git checkout v12.0.0-rc10 &&\
make install

#root must perform the symlink
USER root
RUN ln -s "/home/sentinel/go/bin/sentinelhub" /usr/bin/sentinelhub


USER sentinel

# Initialize the chain and replace the genesis file
RUN sentinelhub init --chain-id bluenet-2-1 "Bluenet | Docker" &&\
curl -fsLS -o "${HOME}/genesis.json" "https://raw.githubusercontent.com/sentinel-official/networks/main/bluenet-2-1/genesis.json" &&\
cp "${HOME}/genesis.json" "${HOME}/.sentinelhub/config/genesis.json" &&\
rm "${HOME}/genesis.json"

# Configure Sentinel Hub
WORKDIR /home/sentinel/.sentinelhub/config

# Replace seeds, peers with sentinelhub ones, enable state-sync, multiple chunk fetches, and add gas prices
RUN sed -i 's/seeds = ""/seeds = ""/g' config.toml &&\
sed -i 's/persistent_peers = ""/persistent_peers = "[email protected]:51056,[email protected]:51056,[email protected]:26656,[email protected]:26656"/g' config.toml &&\
sed -i 's/enable = false/enable = true/g' config.toml &&\
sed -i 's/chunk_fetchers = "4"/chunk_fetchers = "42"/g' config.toml &&\
sed -i 's/minimum-gas-prices = "0.1udvpn"/minimum-gas-prices = "0.01ibc\/31FEE1A2A9F9C01113F90BD0BBCCE8FD6BBB8585FAF109A2101827DD1D5B95B8,0.1udvpn,0.01ibc\/B1C0DDB14F25279A2026BC8794E12B259F8BDA546A3C5132CCAEE4431CE36783,0.01ibc\/ED07A3391A112B175915CD8FAF43A2DA8E4790EDE12566649D0C2F97716B8518,0.01ibc\/A8C2D23A1E6F95DA4E48BA349667E322BD7A6C996D8A4AAE8BA72E190F3D1477"/g' app.toml

# Replicate the state-sync-bluevisor script for bluenet
COPY state-sync-bluevisor.sh /home/sentinel/sentinelhub
WORKDIR /home/sentinel/sentinelhub

# Modify permissions to enable script run
USER root
RUN chown sentinel state-sync-bluevisor.sh &&\
chmod 700 state-sync-bluevisor.sh &&\
ln -s /home/sentinel/go/bin/cosmovisor /usr/local/bin/

USER sentinel

# Install Cosmovisor
RUN go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest &&\
mkdir -p ~/.sentinelhub/cosmovisor &&\
mkdir -p ~/.sentinelhub/cosmovisor/genesis &&\
mkdir -p ~/.sentinelhub/cosmovisor/genesis/bin &&\
mkdir -p ~/.sentinelhub/cosmovisor/upgrades &&\
echo "# Cosmovisor Environmental Variables" >> ~/.bashrc &&\
echo "export DAEMON_NAME=sentinelhub" >> ~/.bashrc &&\
echo "export DAEMON_HOME=$HOME/.sentinelhub" >> ~/.bashrc &&\
echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=false" >> ~/.bashrc &&\
echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc &&\
echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc &&\
echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc &&\
cp /home/sentinel/go/bin/sentinelhub ~/.sentinelhub/cosmovisor/genesis/bin

State Sync Testnet with Cosmovisor

#!/bin/bash

# Script framework credit to Busurnode other contents authored by Misfits (The Expanse)
# Service Name

SERVICE_NAME=cosmovisor

# RPC Endpoints for the network
SNAP_RPC1="https://rpc-sentinel.busurnode.com:443"
SNAP_RPC2="https://na-rpc-sentinel.busurnode.com:443"

# Fetch block data from RPC
echo "Fetching trusted block data from RPC..."
LATEST_HEIGHT=$(curl -s $SNAP_RPC1/block | jq -r .result.block.header.height); \
BLOCK_HEIGHT=$((LATEST_HEIGHT - 2000)); \
TRUST_HASH=$(curl -s "$SNAP_RPC1/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash)

echo "Update config with latest block from RPC..."
sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \
s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$SNAP_RPC1,$SNAP_RPC2\"| ; \
s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \
s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"|" $HOME/.sentinelhub/config/config.toml

# Stop the cosmovisor service
echo "Stopping the cosmovisor service..."
# Find the PID of the process
pid=$(pgrep -f "$SERVICE_NAME")

# Check if the process is running
if [ -n "$pid" ]; then
# Kill the process
kill "$pid"
echo "Process $SERVICE_NAME killed successfully."
else
echo "Process $SERVICE_NAME not running."
fi

# Copy the validator state JSON file
echo "Backing up validator state..."
cd $HOME/sentinelhub
cp ~/.sentinelhub/data/priv_validator_state.json ~/.sentinelhub/priv_validator_state.json

# Reset Tendermint state
sentinelhub tendermint unsafe-reset-all --home $HOME/.sentinelhub --keep-addr-book

# Replace priv_validator_state from backup
echo "Recover validator state from backup..."
cp ~/.sentinelhub/priv_validator_state.json ~/.sentinelhub/data/priv_validator_state.json

# Start the cosmovisor service
echo "Starting the cosmovisor service..."
nohup $SERVICE_NAME run start &
echo "Process complete."
echo "****To see the status of the process type cat nohup****"