diff --git a/connect-peers.sh b/connect-peers.sh index dc1c4216..e091037b 100755 --- a/connect-peers.sh +++ b/connect-peers.sh @@ -318,12 +318,19 @@ check_rpc_success() { return 1 } -# Function to detect client type from node name +# Function to detect client type from node name (+ optional compose path hint). +# op-geth often still reports admin_nodeInfo.name as "Geth/…", so the compose +# path (…/op-geth/… or *-op-geth-*) is the reliable signal. detect_client_type() { local node_name="$1" + local compose_hint="${2:-}" local name_lower=$(echo "$node_name" | tr '[:upper:]' '[:lower:]') - - if [[ "$name_lower" == *"geth"* ]]; then + local hint_lower=$(echo "$compose_hint" | tr '[:upper:]' '[:lower:]') + + # op-geth lacks admin_addStaticPeer — must use admin_addPeer + if [[ "$name_lower" == *"op-geth"* ]] || [[ "$hint_lower" == *"op-geth"* ]]; then + echo "op-geth" + elif [[ "$name_lower" == *"geth"* ]]; then echo "geth" elif [[ "$name_lower" == *"reth"* ]]; then echo "reth" @@ -346,12 +353,12 @@ add_static_peer() { local response local method - # Determine which method to try first based on client type + # Determine which method to try first based on client type. + # Only vanilla geth supports admin_addStaticPeer; op-geth does not. if [[ "$client_type" == "geth" ]]; then - # Geth supports admin_addStaticPeer method="admin_addStaticPeer" else - # Reth and most other clients use admin_addPeer + # op-geth, reth, and most other clients use admin_addPeer method="admin_addPeer" fi @@ -364,10 +371,11 @@ add_static_peer() { return 1 } - # Check if method not found, try fallback - if echo "$response" | grep -qi "method not found"; then + # Fallback when the primary method is unsupported. go-ethereum-style errors + # say "the method X does not exist/is not available", not "method not found". + if echo "$response" | grep -qiE 'method not found|does not exist|not available|-32601'; then if [[ "$method" == "admin_addStaticPeer" ]]; then - # Try admin_addPeer as fallback + # Try admin_addPeer as fallback (required for op-geth) method="admin_addPeer" response=$(curl --ipv4 -s -X POST "$url" \ -H "Content-Type: application/json" \ @@ -425,7 +433,7 @@ echo -e "${GREEN}OK${NC}" SOURCE_ENODE=$(extract_enode "$SOURCE_INFO") SOURCE_NAME=$(extract_name "$SOURCE_INFO") SOURCE_PUBKEY=$(echo "$SOURCE_ENODE" | sed -E 's|enode://([^@]+)@.*|\1|') -SOURCE_CLIENT=$(detect_client_type "$SOURCE_NAME") +SOURCE_CLIENT=$(detect_client_type "$SOURCE_NAME" "$COMPOSE_FILE") if [[ -z "$SOURCE_ENODE" ]]; then echo -e "${RED}Could not extract enode from source${NC}" @@ -457,7 +465,7 @@ echo -e "${GREEN}OK${NC}" TARGET_ENODE=$(extract_enode "$TARGET_INFO") TARGET_NAME=$(extract_name "$TARGET_INFO") TARGET_PUBKEY=$(echo "$TARGET_ENODE" | sed -E 's|enode://([^@]+)@.*|\1|') -TARGET_CLIENT=$(detect_client_type "$TARGET_NAME") +TARGET_CLIENT=$(detect_client_type "$TARGET_NAME" "$TARGET_COMPOSE_FILE") if [[ -z "$TARGET_ENODE" ]]; then echo -e "${RED}Could not extract enode from target${NC}" diff --git a/peer-capture.sh b/peer-capture.sh index bd627d9d..ae78ee90 100755 --- a/peer-capture.sh +++ b/peer-capture.sh @@ -78,16 +78,21 @@ CLIENT_NAME="$(echo "$INFO" | jq -r '.result.name // empty' 2>/dev/null || true) PEERS_JSON="$(rpc admin_peers)" PEER_COUNT="$(echo "$PEERS_JSON" | jq -r '.result | length' 2>/dev/null || echo 0)" -# Detect client type (connect-peers.sh logic) +# Detect client type (connect-peers.sh logic). +# op-geth often still reports as "Geth/…" — prefer compose path for op-geth. NAME_LC="$(echo "$CLIENT_NAME" | tr '[:upper:]' '[:lower:]')" CLIENT_TYPE="unknown" case "$NAME_LC" in + *op-geth*) CLIENT_TYPE="op-geth" ;; *geth*) CLIENT_TYPE="geth" ;; *reth*) CLIENT_TYPE="reth" ;; *erigon*) CLIENT_TYPE="erigon" ;; *nethermind*) CLIENT_TYPE="nethermind" ;; *besu*) CLIENT_TYPE="besu" ;; esac +case "$COMPOSE_PATH" in + *op-geth*) CLIENT_TYPE="op-geth" ;; +esac TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)" echo "$PEERS_JSON" | jq -c --arg path "$COMPOSE_PATH" --arg ts "$TS" \ diff --git a/peer-reinject.sh b/peer-reinject.sh index 7643bbe7..dfcb5378 100755 --- a/peer-reinject.sh +++ b/peer-reinject.sh @@ -1,7 +1,8 @@ #!/bin/bash # peer-reinject.sh — generic .after-start hook: re-seed peers from peer-capture state. -# Uses admin_addStaticPeer for geth, admin_addPeer otherwise (connect-peers.sh). -# In-network vantage (rpc_chains). Idempotent; best-effort (never fails the restart). +# Uses admin_addStaticPeer for vanilla geth, admin_addPeer for op-geth and others +# (connect-peers.sh). In-network vantage (rpc_chains). Idempotent; best-effort +# (never fails the restart). # # Seed order (one path for us and customers): # 1. Own persisted peerset (peer-state/.json from peer-capture) @@ -68,6 +69,12 @@ if [ "${#ENODES[@]}" -eq 0 ]; then exit 0 fi +# op-geth lacks admin_addStaticPeer; compose path wins over stale capture state +# that classified the node as plain "geth" (admin_nodeInfo often still says Geth). +case "$COMPOSE_PATH" in + *op-geth*) CLIENT_TYPE="op-geth" ;; +esac + BASE="$(basename "$COMPOSE_PATH" | sed 's/--.*//')" EL="" # wait briefly for container after recreate @@ -120,6 +127,7 @@ done add_peer() { local enode="$1" local method + # Only vanilla geth supports admin_addStaticPeer; op-geth must use admin_addPeer if [ "$CLIENT_TYPE" = "geth" ]; then method="admin_addStaticPeer" else @@ -132,7 +140,8 @@ add_peer() { resp="$(docker exec peer-hook-probe curl -s --max-time 8 -X POST \ -H 'Content-Type: application/json' --data "$payload" \ "http://${IP}:8545" 2>/dev/null || true)" - if echo "$resp" | grep -qi 'method not found'; then + # go-ethereum-style: "the method X does not exist/is not available" (not "method not found") + if echo "$resp" | grep -qiE 'method not found|does not exist|not available|-32601'; then if [ "$method" = "admin_addStaticPeer" ]; then method="admin_addPeer" else