Skip to content

Instantly share code, notes, and snippets.

@Commoneffort
Last active October 13, 2024 21:29
Show Gist options
  • Save Commoneffort/ffeee28f1129867377bfbd8dc29066de to your computer and use it in GitHub Desktop.
Save Commoneffort/ffeee28f1129867377bfbd8dc29066de to your computer and use it in GitHub Desktop.
X1 validator installation and setup
#!/bin/bash
# Exit on any error
set -e
# Define variables
RELEASE_TAG="v1.18.23"
BIN_DIR="$HOME/.local/share/solana/bin"
SOLANA_INSTALL_DIR="$HOME/.local/share/solana/install/active_release"
SYSCTL_CONF_FILE="/etc/sysctl.d/21-solana-validator.conf"
LIMITS_CONF_FILE="/etc/security/limits.d/90-solana-nofiles.conf"
SOLANA_INSTALL_SCRIPT="https://release.solana.com/v1.18.23/install"
GIT_REPO="https://github.com/jacklevin74/xolana.git"
GIT_DIR="$HOME/xolana"
LEDGER_DIR="$HOME/ledger"
KEYPAIR_PATH="$HOME/.config/solana/id.json"
MAX_ATTEMPTS=3
CATCHUP_TIMEOUT=60 # 1 minute in seconds
# Function to display errors
err() {
echo "$1" >&2
exit 1
}
# Update package list and install necessary packages
echo "Updating package list..."
sudo apt-get update
echo "Installing build dependencies..."
sudo apt-get install -y \
gcc \
make \
curl \
wget \
pkg-config \
libudev-dev \
rustc \
cargo \
clang \
libclang-dev \
protobuf-compiler \
libssl-dev \
zlib1g-dev \
llvm \
cmake \
libprotobuf-dev \
libprotobuf-c-dev
# Create directory for Solana binary if it doesn't exist
mkdir -p "$BIN_DIR"
# Update PATH for Solana build
echo "Updating PATH for Solana build..."
export PATH="$BIN_DIR:$PATH"
if ! grep -q 'export PATH="$HOME/.local/share/solana/bin:$PATH"' ~/.bashrc; then
echo 'export PATH="$HOME/.local/share/solana/bin:$PATH"' >> ~/.bashrc
fi
source ~/.bashrc
# Install Solana Release
echo "Installing Solana release v1.18.23..."
sh -c "$(curl -sSfL $SOLANA_INSTALL_SCRIPT)"
# Update PATH for Solana release
echo "Updating PATH for Solana release..."
export PATH="$SOLANA_INSTALL_DIR/bin:$PATH"
if ! grep -q "export PATH=\"$SOLANA_INSTALL_DIR/bin:$PATH\"" ~/.bashrc; then
echo "export PATH=\"$SOLANA_INSTALL_DIR/bin:$PATH\"" >> ~/.bashrc
fi
source ~/.bashrc
# System Tuning (Skip if setrlimit fails)
echo "Optimizing sysctl knobs..."
sudo bash -c "cat > $SYSCTL_CONF_FILE <<EOF
# Increase UDP buffer sizes
net.core.rmem_default = 134217728
net.core.rmem_max = 134217728
net.core.wmem_default = 134217728
net.core.wmem_max = 134217728
# Increase memory mapped files limit
vm.max_map_count = 1000000
# Increase number of allowed open file descriptors
fs.nr_open = 1000000
EOF" || echo "Failed to apply sysctl knobs. Skipping..."
sudo sysctl -p $SYSCTL_CONF_FILE || echo "Failed to apply sysctl knobs. Skipping..."
# Increase session file limits only (ignore systemd settings)
echo "Increasing session file limits..."
sudo bash -c "cat > $LIMITS_CONF_FILE <<EOF
# Increase process file descriptor count limit
* soft nofile 1000000
* hard nofile 1000000
EOF" || echo "Failed to increase session file limits. Skipping..."
# Optional: Building from Source
echo "Optional: Building from source..."
# Clone the repository or pull the latest changes
if [ ! -d "$GIT_DIR" ]; then
echo "Cloning the repository..."
git clone "$GIT_REPO"
else
echo "Repository directory already exists, pulling latest changes..."
cd "$GIT_DIR" || err "Failed to change directory to $GIT_DIR"
git pull
fi
# Switch to the xolana directory
echo "Switching to the xolana directory..."
cd "$GIT_DIR" || err "Failed to change directory to $GIT_DIR"
git checkout xolana || err "Failed to switch branch to 'xolana'"
echo "Current directory: $(pwd)"
# Check if Rust is already installed
echo "Checking for Rust installation..."
if ! command -v rustc &> /dev/null; then
echo "Rust is not installed, installing Rust..."
curl https://sh.rustup.rs -sSf | sh -s -- -y
source $HOME/.cargo/env
rustup component add rustfmt
rustup update
else
echo "Rust is already installed, skipping installation..."
fi
cargo build --release || err "Failed to build the project with cargo"
# Check version
echo "Checking Solana Validator version..."
./target/release/solana-validator -V || err "Failed to check Solana validator version"
# Create key-pairs if they don't already exist
echo "Creating key-pairs..."
# Check if files already exist and skip creating them if they do
if [ ! -f "$HOME/.config/solana/id.json" ]; then
echo "Creating $HOME/.config/solana/id.json..."
solana-keygen new --no-passphrase -o $HOME/.config/solana/id.json
else
echo "$HOME/.config/solana/id.json already exists, skipping creation..."
fi
if [ ! -f "identity.json" ]; then
echo "Creating identity.json..."
solana-keygen new --no-passphrase -o identity.json
else
echo "identity.json already exists, skipping creation..."
fi
if [ ! -f "vote.json" ]; then
echo "Creating vote.json..."
solana-keygen new --no-passphrase -o vote.json
else
echo "vote.json already exists, skipping creation..."
fi
if [ ! -f "withdrawer.json" ]; then
echo "Creating withdrawer.json..."
solana-keygen new --no-passphrase -o withdrawer.json
else
echo "withdrawer.json already exists, skipping creation..."
fi
if [ ! -f "stake.json" ]; then
echo "Creating stake.json..."
solana-keygen new --no-passphrase -o stake.json
else
echo "stake.json already exists, skipping creation..."
fi
# Airdrop using Xen Faucet API
echo "Configuring Solana and requesting airdrop via Xen faucet..."
solana config set -u https://xolana.xen.network
# Check if the keypair path is valid
if [ -f "$KEYPAIR_PATH" ]; then
echo "Keypair file found at $KEYPAIR_PATH"
else
echo "Keypair file not found at $KEYPAIR_PATH. Please ensure your Solana CLI is configured correctly."
exit 1
fi
# Extract the public key from the keypair file
pubkey=$(solana-keygen pubkey "$KEYPAIR_PATH")
echo "Public key: $pubkey"
# Proceed with the rest of the script, such as requesting the airdrop
response=$(curl -X POST https://xolana.xen.network/faucet \
-H "Content-Type: application/json" \
-d "{\"pubkey\":\"$pubkey\"}")
echo "Airdrop response: $response"
# Transfer 1 SOL to identity account
echo "Transferring 1 SOL to identity account..."
solana transfer identity.json 1 --allow-unfunded-recipient
# Create Stake Account
echo "Creating stake account..."
if ! solana stake-account stake.json &>/dev/null; then
solana create-stake-account stake.json 3
else
echo "Stake account already exists, skipping creation..."
fi
# Create Vote Account
echo "Creating vote account..."
if ! solana vote-account vote.json &>/dev/null; then
solana create-vote-account vote.json identity.json withdrawer.json --commission 10
else
echo "Vote account already exists, skipping creation..."
fi
# Stake
echo "Staking SOL..."
solana transfer stake.json 1 || echo "Failed to transfer SOL, continuing..."
solana delegate-stake stake.json vote.json || echo "Failed to delegate stake, continuing..."
# Open necessary ports and enable the firewall
echo "Opening required ports and enabling the firewall..."
{
sudo ufw allow 8000:10000/tcp || echo "Failed to allow TCP port range 8000-10000"
sudo ufw allow 8000:10000/udp || echo "Failed to allow port 8000:10000/udp"
} || true
# Enable and reload the firewall
echo "Enabling the firewall..."
sudo ufw enable || echo "Failed to enable the firewall, continuing..."
echo "Reloading firewall rules..."
sudo ufw reload || echo "Failed to reload firewall rules, continuing..."
echo "Checking firewall status..."
sudo ufw status verbose || echo "Failed to check firewall status, continuing..."
# Run Validator
echo "Running validator..."
if [ -f "./target/release/solana-validator" ]; then
nohup ./target/release/solana-validator \
--identity identity.json \
--limit-ledger-size 50000000 \
--rpc-port 8899 \
--entrypoint xolana.xen.network:8001 \
--entrypoint 216.202.227.220:8001 \
--full-rpc-api \
--log - \
--vote-account vote.json \
--max-genesis-archive-unpacked-size 1073741824 \
--no-incremental-snapshots \
--maximum-snapshots-to-retain 5 \
--snapshot-compression lz4 \
--require-tower \
--enable-rpc-transaction-history \
--enable-extended-tx-metadata-storage \
--skip-startup-ledger-verification &
else
echo "solana-validator binary not found in ./target/release/. Please ensure it is built correctly."
fi
sleep 100 # Give some time for the validator to start
# Check Catchup Status
echo "Checking catchup status..."
attempts=0
while (( attempts < MAX_ATTEMPTS )); do
echo "Checking catchup status... (Attempt $((attempts+1))/$MAX_ATTEMPTS)"
CATCHUP_STATUS=$(solana catchup --our-localhost)
if echo "$CATCHUP_STATUS" | grep -q "has caught up"; then
echo "Validator has caught up with the network."
break
else
echo "Validator has not caught up. Retrying..."
sleep $CATCHUP_TIMEOUT
((attempts++))
if (( attempts == MAX_ATTEMPTS )); then
echo "Validator failed to catch up. Stopping and restarting..."
pkill -f solana-validator
rm -rf $LEDGER_DIR # Delete ledger
nohup ./target/release/solana-validator \
--identity identity.json \
--limit-ledger-size 50000000 \
--rpc-port 8899 \
--entrypoint xolana.xen.network:8001 \
--full-rpc-api \
--log - \
--vote-account vote.json \
--max-genesis-archive-unpacked-size 1073741824 \
--no-incremental-snapshots \
--require-tower \
--enable-rpc-transaction-history \
--enable-extended-tx-metadata-storage \
--skip-startup-ledger-verification \ &
fi
fi
done
# Check status
echo "Checking logs and validator status..."
tail -f nohup.out &
solana leader-schedule | grep identity.json
solana gossip
solana validators
solana block-production
solana epoch-info
# End script with validator still running
echo "Setup complete. Validator is running."
echo "To stop the validator, use 'pkill -f solana-validator'."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment