ghost-node/scripts/rpc-tester.sh
Uncle Stretch a7d3a3fee8
update RPC scripts to support weaver
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-10-30 14:56:23 +03:00

206 lines
5.7 KiB
Bash
Executable File

#!/bin/bash
SEPOLIA_RPC=(
"https://sepolia.drpc.org"
"https://sepolia.gateway.tenderly.co"
"https://api.zan.top/eth-sepolia"
"https://rpc.sepolia.ethpandaops.io"
"https://ethereum-sepolia-rpc.publicnode.com"
"https://1rpc.io/sepolia"
"https://0xrpc.io/sep"
"https://eth-sepolia.api.onfinality.io/public"
)
MORDOR_RPC=(
"https://0xrpc.io/mordor"
"https://geth-mordor.etc-network.info"
"https://rpc.mordor.etccooperative.org"
)
HOODI_RPC=(
"https://rpc.hoodi.ethpandaops.io"
"https://0xrpc.io/hoodi"
"https://ethereum-hoodi.gateway.tatum.io"
"https://rpc.sentio.xyz/hoodi"
)
HOODI_GATEKEEPER="0xc9D5f50e17eeEAF39E0D0cDbbcF4B04FA4A4Bbd6"
show_help() {
cat << EOF
Usage: $(basename "$0") [OPTIONS]
Options:
--chain <name> Specify network: 'sepolia', 'hoodi' or 'mordor'. If omitted, checks all.
--output <dir> Base directory to save results. Creates a subfolder with Unix Timestamp.
--rpcs <urls> Comma-separated list of custom RPC endpoints. Disables default networks lists.
--help Show this help message.
Example:
$0 --chain sepolia --output ./logs
EOF
exit 0
}
spinner() {
local pid=$1
local net_name=$2
local delay=0.1
local spinstr='|/-\'
tput civis
while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
local temp=${spinstr#?}
printf "\r [%c] Checking %s... " "$spinstr" "$net_name"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
done
printf " \r"
tput cnorm
}
pad32() {
local h="$1"
h="${h#0x}"
printf "%064s" "$h" | tr ' ' '0'
}
build_calldata() {
local selector="$1"
local at_block="$2"
local s_hex
local b_hex
s_hex=$(printf "%x" 0)
b_hex=$(printf "%x" "$at_block")
echo "0x${selector#0x}$(pad32 "$s_hex")$(pad32 "$b_hex")"
}
decode_get_root() {
local res_json="$1"
local hex
hex=$(echo "$res_json" | grep -o '"result":"[^"]*' | cut -d'"' -f4)
if [[ -z "$hex" || "$hex" == "null" ]]; then
echo "ERROR"
return
fi
hex="${hex#0x}"
if (( ${#hex} < 128 )); then
echo "ERROR"
return
fi
local word1="${hex:0:64}"
local word2="${hex:64:64}"
local num
num=$(printf "%d" "0x$word2" 2>/dev/null)
[[ -z "$num" ]] && num="$word2"
echo "0x${word1} ${num}"
}
check_network() {
local name=$1
local gatekeeper=$2
shift 2
local rpcs=("$@")
local target_dir="${OUT_DIR:-/tmp}"
local tmp_file="${target_dir}/$(date +%s)_${name,,}"
local root_width=66
local sess_width=6
local max_len=0
for e in "${rpcs[@]}"; do (( ${#e} > max_len )) && max_len=${#e}; done
[[ $max_len -lt 20 ]] && max_len=20
local total_width=$(( max_len + 95 ))
local line=$(printf "%.0s-" $(seq 1 $total_width))
local header_fmt="| %-${max_len}s | %-10s | %-${root_width}s | %-${sess_width}s |\n"
(
for endpoint in "${rpcs[@]}"; do
res_b=$(curl -s -X POST -H "Content-Type: application/json" --max-time 10 \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' "$endpoint")
hex=$(echo "$res_b" | grep -o '"result":"[^"]*' | cut -d'"' -f4)
[[ -n "$hex" && "$hex" != "null" ]] && blk=$(printf "%d" "$hex") || blk="ERROR"
root="N/A"
if [[ -n "$blk" && "$blk" != "ERROR" ]]; then
calldata=$(build_calldata "$SELECTOR" "$blk")
payload=$(printf '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"%s","data":"%s"},"latest"],"id":1}' "$gatekeeper" "$calldata")
res_c=$(curl -s -X POST -H "Content-Type: application/json" --max-time 10 --data "$payload" "$endpoint")
root=$(decode_get_root "$res_c")
fi
echo "$endpoint|$blk|$root"
done
) > "$tmp_file" &
local worker_pid=$!
if [[ -z "$OUT_DIR" ]]; then
spinner $worker_pid "$name"
local table_output="$line\n"
table_output+=$(printf "$header_fmt" "Endpoint" "Block" "Merkle Root" "Session")"\n"
table_output+="$line\n"
while IFS="|" read -r url blk root; do
if [[ "$root" == *" "* ]]; then
hash="${root%% *}"
sess="${root##* }"
else
hash="$root"
sess="-"
fi
table_output+=$(printf "$header_fmt" "$url" "$blk" "$hash" "$sess")"\n"
done < "$tmp_file"
table_output+="$line"
echo -e "$table_output"
rm "$tmp_file"
else
wait $worker_pid
fi
}
CHOSEN_CHAIN=""
BASE_OUT_DIR=""
CUSTOM_RPCS=""
SELECTOR="d4be7935"
while [[ $# -gt 0 ]]; do
case "$1" in
--help) show_help ;;
--chain) CHOSEN_CHAIN="$2"; shift 2 ;;
--output) BASE_OUT_DIR="$2"; shift 2 ;;
--rpcs) CUSTOM_RPCS="$2"; shift 2 ;;
*) echo "Unknown option: $1. Use --help for usage."; exit 1 ;;
esac
done
if [[ -n "$BASE_OUT_DIR" ]]; then
OUT_DIR="${BASE_OUT_DIR}"
mkdir -p "$OUT_DIR"
fi
if [[ -n "$CUSTOM_RPCS" ]]; then
IFS=',' read -r -a USER_RPC_ARRAY <<< "$CUSTOM_RPCS"
check_network "Custom" "${USER_RPC_ARRAY[@]}"
else
if [ "$CHOSEN_CHAIN" == "sepolia" ]; then
check_network "Sepolia" "$SEPOLIA_GATEKEEPER" "${HOODI_RPC[@]}"
elif [ "$CHOSEN_CHAIN" == "mordor" ]; then
check_network "Mordor" "$MORDOR_GATEKEEPER" "${HOODI_RPC[@]}"
elif [ "$CHOSEN_CHAIN" == "hoodi" ]; then
check_network "Hoodi" "$HOODI_GATEKEEPER" "${HOODI_RPC[@]}"
else
check_network "Sepolia" "$SEPOLIA_GATEKEEPER" "${SEPOLIA_RPC[@]}"
check_network "Mordor" "$MORDOR_GATEKEEPER" "${MORDOR_RPC[@]}"
check_network "Hoodi" "$HOODI_GATEKEEPER" "${HOODI_RPC[@]}"
fi
fi