Skip to content

Instantly share code, notes, and snippets.

@AshwinSekar
Created June 8, 2026 18:31
Show Gist options
  • Select an option

  • Save AshwinSekar/d73ddd98e2657811dbf7543d324267d4 to your computer and use it in GitHub Desktop.

Select an option

Save AshwinSekar/d73ddd98e2657811dbf7543d324267d4 to your computer and use it in GitHub Desktop.
Check cluster to see what % of stake has set their BLS pubkey
#!/usr/bin/env bash
set -euo pipefail
SOLANA_BIN="${SOLANA_BIN:-$HOME/agave/bin/solana}"
RPC_URL="${RPC_URL:-l}"
shopt -s expand_aliases
alias solana="$SOLANA_BIN -u $RPC_URL"
if [[ ! -x "$SOLANA_BIN" ]]; then
echo "error: Solana CLI not found or not executable: $SOLANA_BIN" >&2
exit 1
fi
if ! command -v jq >/dev/null 2>&1; then
echo "error: jq is required to parse solana CLI JSON output" >&2
exit 1
fi
is_unset_bls_pubkey() {
local value="${1:-}"
[[ -z "$value" || "$value" == "null" || "$value" =~ ^1+$ ]]
}
lamports_to_sol() {
local lamports="${1:-0}"
awk -v lamports="$lamports" 'BEGIN { printf "%.9f", lamports / 1000000000 }'
}
stake_percent() {
local stake="${1:-0}"
local total="${2:-0}"
awk -v stake="$stake" -v total="$total" 'BEGIN {
if (total == 0) {
printf "0.00"
} else {
printf "%.2f", (stake / total) * 100
}
}'
}
main() {
local validators_json
if ! validators_json="$(solana validators --output json)"; then
echo "error: failed to fetch validators from $RPC_URL" >&2
exit 1
fi
local total
total="$(jq '.validators | length' <<<"$validators_json")"
local checked=0
local set_count=0
local unset_count=0
local error_count=0
local total_active_stake_lamports=0
local unset_stake_lamports=0
local error_stake_lamports=0
local missing=()
local errors=()
while IFS=$'\t' read -r identity vote_account activated_stake; do
if [[ ! "$activated_stake" =~ ^[0-9]+$ ]]; then
activated_stake=0
fi
total_active_stake_lamports=$((total_active_stake_lamports + activated_stake))
local vote_json
if ! vote_json="$(solana vote-account "$vote_account" --output json 2>&1)"; then
((error_count += 1))
error_stake_lamports=$((error_stake_lamports + activated_stake))
errors+=("$identity"$'\t'"$(head -n 1 <<<"$vote_json")")
continue
fi
((checked += 1))
local bls_pubkey
bls_pubkey="$(jq -r '.blsPubkeyCompressed // .blsPubkey // .blsPublicKey // ""' <<<"$vote_json")"
if is_unset_bls_pubkey "$bls_pubkey"; then
((unset_count += 1))
unset_stake_lamports=$((unset_stake_lamports + activated_stake))
if [[ -z "$bls_pubkey" ]]; then
bls_pubkey="<missing>"
fi
missing+=("$identity")
else
((set_count += 1))
fi
done < <(jq -r '.validators[] | [.identityPubkey, .voteAccountPubkey, ((.activatedStake // 0) | tostring)] | @tsv' <<<"$validators_json")
echo "Validators discovered: $total"
echo "Vote accounts checked: $checked"
echo "BLS pubkey set: $set_count"
echo "BLS pubkey unset: $unset_count"
echo "Total active stake: $(lamports_to_sol "$total_active_stake_lamports") SOL"
echo "Stake with BLS pubkey unset: $(lamports_to_sol "$unset_stake_lamports") SOL ($(stake_percent "$unset_stake_lamports" "$total_active_stake_lamports")%)"
if ((error_count > 0)); then
echo "Vote-account query failures: $error_count"
echo "Stake not checked due vote-account query failures: $(lamports_to_sol "$error_stake_lamports") SOL ($(stake_percent "$error_stake_lamports" "$total_active_stake_lamports")%)"
fi
if ((unset_count > 0)); then
echo
echo "Validators without a BLS pubkey:"
printf "%s\n" "${missing[@]}"
fi
if ((error_count > 0)); then
echo
echo "Vote accounts that could not be checked:"
printf "%-44s %s\n" "IDENTITY" "ERROR"
printf "%-44s %s\n" "--------" "-----"
printf "%s\n" "${errors[@]}" | while IFS=$'\t' read -r identity error; do
printf "%-44s %s\n" "$identity" "$error"
done
fi
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment