ripple: deployable mainnet + testnet rippled with health checks

Fix mainnet rippled.cfg (ws,http RPC, port_peer 13331), strip eth-isms
from x-upstreams, add testnet chain assets/compose, and wire --ripple
sync-status via check-health.sh server_info probe.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-02 11:46:03 +00:00
parent b8752b0c7e
commit 0c8a3cc4b0
8 changed files with 261 additions and 19 deletions

View File

@@ -10,10 +10,11 @@ fi
RPC_URL=$1
shift
# Check for --starknet / --aztec / --cosmos flag
# Check for --starknet / --aztec / --cosmos / --ripple flag
is_starknet=false
is_aztec=false
is_cosmos=false
is_ripple=false
if [ "$1" == "--starknet" ]; then
is_starknet=true
shift
@@ -23,6 +24,9 @@ elif [ "$1" == "--aztec" ]; then
elif [ "$1" == "--cosmos" ]; then
is_cosmos=true
shift
elif [ "$1" == "--ripple" ]; then
is_ripple=true
shift
fi
REF=""
@@ -59,6 +63,45 @@ if $is_cosmos; then
echo "online"; exit 0
fi
# XRPL rippled: server_info — server_state full/proposing + fresh validated ledger = online.
# Short-circuits here; the EVM/starknet/aztec block-comparison path below is not used.
if $is_ripple; then
status=$(curl -L --ipv4 -m $timeout -s -X POST -H "Content-Type: application/json" --data '{"method":"server_info"}' "$RPC_URL")
if [ $? -ne 0 ] || [ -z "$status" ]; then echo "error"; exit 1; fi
server_state=$(echo "$status" | jq -r '.result.info.server_state // .info.server_state' 2>/dev/null)
ledger_age=$(echo "$status" | jq -r '.result.info.validated_ledger.age // .info.validated_ledger.age' 2>/dev/null)
node_seq=$(echo "$status" | jq -r '.result.info.validated_ledger.seq // .info.validated_ledger.seq' 2>/dev/null)
if [ -z "$server_state" ] || [ "$server_state" = "null" ]; then echo "error"; exit 1; fi
case "$server_state" in
connected|syncing|tracking)
echo "syncing"; exit 1 ;;
full|proposing)
;;
*)
echo "error"; exit 1 ;;
esac
if [ -z "$ledger_age" ] || [ "$ledger_age" = "null" ] || [ "$ledger_age" -gt 20 ] 2>/dev/null; then
echo "behind"; exit 1
fi
if [ -n "$ref" ]; then
ref_status=$($BASEPATH/multicurl.sh -L --ipv4 -m $timeout -s -X POST -H "Content-Type: application/json" --data '{"method":"server_info"}' $ref)
ref_seq=$(echo "$ref_status" | jq -r '.result.info.validated_ledger.seq // .info.validated_ledger.seq' 2>/dev/null)
if [ -n "$ref_seq" ] && [ "$ref_seq" != "null" ] && [ "$ref_seq" -gt 0 ] 2>/dev/null && [ -n "$node_seq" ] && [ "$node_seq" != "null" ]; then
lag=$(( ref_seq - node_seq ))
lo=${LAGGING_LAG:-5}; hi=${SYNCING_LAG:-10}
if [ "$lo" -gt "$hi" ]; then tmp=$lo; lo=$hi; hi=$tmp; fi
if [ "$lag" -le "$lo" ]; then
echo "online"; exit 0
elif [ "$lag" -le "$hi" ]; then
echo "lagging"; exit 0
else
echo "syncing"; exit 1
fi
fi
fi
echo "online"; exit 0
fi
response_file=$(mktemp)
# Use appropriate RPC method based on chain type

View File

@@ -7901,6 +7901,22 @@
"ripple-mainnet-rippled-pruned-nudb"
]
},
{
"chain": "testnet",
"client": "rippled",
"compose_file": "ripple/rippled/ripple-testnet-rippled-pruned-nudb",
"features": [
"nudb"
],
"network": "ripple",
"node": null,
"relay": null,
"stack": null,
"type": "pruned",
"volumes": [
"ripple-testnet-rippled-pruned-nudb"
]
},
{
"chain": "mainnet",
"client": "ronin",

View File

@@ -1,8 +1,7 @@
[server]
port_rpc_admin_local
port_ws_public
# port_peer
port_peer
# port_ws_admin_local
# ssl_key = /etc/ssl/private/server.key
# ssl_cert = /etc/ssl/certs/server.crt
@@ -16,12 +15,12 @@ protocol = http
[port_ws_public]
port = 8545
ip = 0.0.0.0
protocol = ws
protocol = ws,http
# [port_peer]
# port = 51235
# ip = 0.0.0.0
# protocol = peer
[port_peer]
port = 13331
ip = 0.0.0.0
protocol = peer
# [port_ws_admin_local]
# port = 6006
@@ -83,4 +82,4 @@ validators.txt
# fatal
[ssl_verify]
1
1

View File

@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
services:
ripple-mainnet:
image: ${RIPPLE_RIPPLED_IMAGE:-xrpllabsofficial/xrpld}:${RIPPLE_MAINNET_RIPPLED_VERSION:-3.1.3}
image: ${RIPPLE_RIPPLED_IMAGE:-xrpllabsofficial/xrpld}:${RIPPLE_MAINNET_RIPPLED_VERSION:-3.2.0}
sysctls:
# TCP Performance
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
@@ -86,12 +86,4 @@ x-upstreams:
msgSize: 50Mb
url: $${WS_URL}
chain: ripple
method-groups:
enabled:
- debug
- filter
methods:
disabled:
enabled:
- name: txpool_content # TODO: should be disabled for rollup nodes
...

View File

@@ -0,0 +1,89 @@
---
x-logging-defaults: &logging-defaults
driver: json-file
options:
max-size: "10m"
max-file: "3"
# Usage:
#
# mkdir rpc && cd rpc
#
# git init
# git remote add origin https://github.com/StakeSquid/ethereum-rpc-docker.git
# git fetch origin vibe
# git checkout origin/vibe
#
# docker run --rm alpine sh -c "printf '0x'; head -c32 /dev/urandom | xxd -p -c 64" > .jwtsecret
#
# env
# ...
# IP=$(curl ipinfo.io/ip)
# DOMAIN=${IP}.traefik.me
# COMPOSE_FILE=base.yml:rpc.yml:ripple/rippled/ripple-testnet-rippled-pruned-nudb.yml
#
# docker compose up -d
#
# curl -X POST https://${IP}.traefik.me/ripple-testnet \
# -H "Content-Type: application/json" \
# --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
services:
ripple-testnet:
image: ${RIPPLE_RIPPLED_IMAGE:-xrpllabsofficial/xrpld}:${RIPPLE_TESTNET_RIPPLED_VERSION:-3.2.0}
sysctls:
# TCP Performance
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
net.ipv4.tcp_no_metrics_save: 1 # Disable metrics cache
net.ipv4.tcp_rmem: 4096 87380 16777216 # Increase TCP read buffers
net.ipv4.tcp_wmem: 4096 87380 16777216 # Increase TCP write buffers
net.core.somaxconn: 32768 # Higher connection queue
# Memory/Connection Management
# net.core.netdev_max_backlog: 50000 # Increase network buffer
net.ipv4.tcp_max_syn_backlog: 30000 # More SYN requests
net.ipv4.tcp_max_tw_buckets: 2000000 # Allow more TIME_WAIT sockets
ulimits:
nofile: 1048576 # Max open files (for RPC/WS connections)
user: root
ports:
- 12986:12986
- 12986:12986/udp
expose:
- 8545
restart: unless-stopped
stop_grace_period: 5m
networks:
- chains
volumes:
- ${RIPPLE_TESTNET_RIPPLED_PRUNED_NUDB_DATA:-ripple-testnet-rippled-pruned-nudb}:/var/lib/rippled/db
- ./ripple/testnet:/config
- /slowdisk:/slowdisk
logging: *logging-defaults
labels:
- prometheus-scrape.enabled=false
- traefik.enable=true
- traefik.http.middlewares.ripple-testnet-rippled-pruned-nudb-stripprefix.stripprefix.prefixes=/ripple-testnet
- traefik.http.services.ripple-testnet-rippled-pruned-nudb.loadbalancer.server.port=8545
- ${NO_SSL:-traefik.http.routers.ripple-testnet-rippled-pruned-nudb.entrypoints=websecure}
- ${NO_SSL:-traefik.http.routers.ripple-testnet-rippled-pruned-nudb.tls.certresolver=myresolver}
- ${NO_SSL:-traefik.http.routers.ripple-testnet-rippled-pruned-nudb.rule=Host(`$DOMAIN`) && (Path(`/ripple-testnet`) || Path(`/ripple-testnet/`))}
- ${NO_SSL:+traefik.http.routers.ripple-testnet-rippled-pruned-nudb.rule=Path(`/ripple-testnet`) || Path(`/ripple-testnet/`)}
- traefik.http.routers.ripple-testnet-rippled-pruned-nudb.middlewares=ripple-testnet-rippled-pruned-nudb-stripprefix, ipallowlist
volumes:
ripple-testnet-rippled-pruned-nudb:
x-upstreams:
- id: $${ID}
labels:
provider: $${PROVIDER}
connection:
generic:
rpc:
url: $${RPC_URL}
ws:
frameSize: 20Mb
msgSize: 50Mb
url: $${WS_URL}
chain: ripple-testnet
...

View File

@@ -0,0 +1,88 @@
[server]
port_rpc_admin_local
port_ws_public
port_peer
# port_ws_admin_local
# ssl_key = /etc/ssl/private/server.key
# ssl_cert = /etc/ssl/certs/server.crt
[port_rpc_admin_local]
port = 5005
ip = 127.0.0.1
admin = 127.0.0.1
protocol = http
[port_ws_public]
port = 8545
ip = 0.0.0.0
protocol = ws,http
[port_peer]
port = 12986
ip = 0.0.0.0
protocol = peer
# [port_ws_admin_local]
# port = 6006
# ip = 127.0.0.1
# admin = 127.0.0.1
# protocol = ws
[node_size]
small
# tiny
# small
# medium
# large
# huge
[node_db]
type=NuDB
path=/var/lib/rippled/db/nudb
advisory_delete=0
# How many ledgers do we want to keep (history)?
# Integer value that defines the number of ledgers
# between online deletion events
online_delete=256
[ledger_history]
# How many ledgers do we want to keep (history)?
# Integer value (ledger count)
# or (if you have lots of TB SSD storage): 'full'
256
[database_path]
/var/lib/rippled/db
[debug_logfile]
/var/lib/rippled/db/debug.log
[sntp_servers]
time.windows.com
time.apple.com
time.nist.gov
pool.ntp.org
[ips]
s.altnet.rippletest.net 51235
[network_id]
testnet
[validators_file]
validators.txt
[rpc_startup]
{ "command": "log_level", "severity": "info" }
# severity (order: lots of information .. only errors)
# debug
# info
# warn
# error
# fatal
[ssl_verify]
1

View File

@@ -0,0 +1,5 @@
[validator_list_sites]
https://vl.altnet.rippletest.net
[validator_list_keys]
ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860

View File

@@ -54,7 +54,7 @@ for path in $pathlist; do
fi
case "$protocol" in
eth|starknet|aztec|cosmos)
eth|starknet|aztec|cosmos|ripple)
;;
*)
# Protocol family known from the registry but no probe support
@@ -68,9 +68,11 @@ for path in $pathlist; do
is_starknet=false
is_aztec=false
is_cosmos=false
is_ripple=false
[ "$protocol" = "starknet" ] && is_starknet=true
[ "$protocol" = "aztec" ] && is_aztec=true
[ "$protocol" = "cosmos" ] && is_cosmos=true
[ "$protocol" = "ripple" ] && is_ripple=true
ref=''
if [ -n "$2" ]; then
@@ -135,6 +137,12 @@ for path in $pathlist; do
if [ -n "$chain_slug" ]; then
ref=$($BASEPATH/reference-rpc-endpoint.sh --chain "$chain_slug" 2>/dev/null) || ref=""
fi
elif $is_ripple; then
# XRPL: no chainid. Reference by drpc slug (optional — server_state is
# authoritative; ref only adds a validated-ledger seq gap check).
if [ -n "$chain_slug" ]; then
ref=$($BASEPATH/reference-rpc-endpoint.sh --chain "$chain_slug" 2>/dev/null) || ref=""
fi
else
# Ethereum chain ID detection
chain_id_response=$(curl -L --ipv4 -m 1 -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' $RPC_URL)
@@ -186,6 +194,8 @@ for path in $pathlist; do
timeout "$HC_TIMEOUT" $BASEPATH/check-health.sh "$RPC_URL" --starknet $ref
elif $is_cosmos; then
timeout "$HC_TIMEOUT" $BASEPATH/check-health.sh "$RPC_URL" --cosmos $ref
elif $is_ripple; then
timeout "$HC_TIMEOUT" $BASEPATH/check-health.sh "$RPC_URL" --ripple $ref
else
timeout "$HC_TIMEOUT" $BASEPATH/check-health.sh "$RPC_URL" $ref
fi