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:
@@ -10,10 +10,11 @@ fi
|
|||||||
RPC_URL=$1
|
RPC_URL=$1
|
||||||
shift
|
shift
|
||||||
|
|
||||||
# Check for --starknet / --aztec / --cosmos flag
|
# Check for --starknet / --aztec / --cosmos / --ripple flag
|
||||||
is_starknet=false
|
is_starknet=false
|
||||||
is_aztec=false
|
is_aztec=false
|
||||||
is_cosmos=false
|
is_cosmos=false
|
||||||
|
is_ripple=false
|
||||||
if [ "$1" == "--starknet" ]; then
|
if [ "$1" == "--starknet" ]; then
|
||||||
is_starknet=true
|
is_starknet=true
|
||||||
shift
|
shift
|
||||||
@@ -23,6 +24,9 @@ elif [ "$1" == "--aztec" ]; then
|
|||||||
elif [ "$1" == "--cosmos" ]; then
|
elif [ "$1" == "--cosmos" ]; then
|
||||||
is_cosmos=true
|
is_cosmos=true
|
||||||
shift
|
shift
|
||||||
|
elif [ "$1" == "--ripple" ]; then
|
||||||
|
is_ripple=true
|
||||||
|
shift
|
||||||
fi
|
fi
|
||||||
|
|
||||||
REF=""
|
REF=""
|
||||||
@@ -59,6 +63,45 @@ if $is_cosmos; then
|
|||||||
echo "online"; exit 0
|
echo "online"; exit 0
|
||||||
fi
|
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)
|
response_file=$(mktemp)
|
||||||
|
|
||||||
# Use appropriate RPC method based on chain type
|
# Use appropriate RPC method based on chain type
|
||||||
|
|||||||
@@ -7901,6 +7901,22 @@
|
|||||||
"ripple-mainnet-rippled-pruned-nudb"
|
"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",
|
"chain": "mainnet",
|
||||||
"client": "ronin",
|
"client": "ronin",
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
[server]
|
[server]
|
||||||
port_rpc_admin_local
|
port_rpc_admin_local
|
||||||
port_ws_public
|
port_ws_public
|
||||||
|
port_peer
|
||||||
# port_peer
|
|
||||||
# port_ws_admin_local
|
# port_ws_admin_local
|
||||||
# ssl_key = /etc/ssl/private/server.key
|
# ssl_key = /etc/ssl/private/server.key
|
||||||
# ssl_cert = /etc/ssl/certs/server.crt
|
# ssl_cert = /etc/ssl/certs/server.crt
|
||||||
@@ -16,12 +15,12 @@ protocol = http
|
|||||||
[port_ws_public]
|
[port_ws_public]
|
||||||
port = 8545
|
port = 8545
|
||||||
ip = 0.0.0.0
|
ip = 0.0.0.0
|
||||||
protocol = ws
|
protocol = ws,http
|
||||||
|
|
||||||
# [port_peer]
|
[port_peer]
|
||||||
# port = 51235
|
port = 13331
|
||||||
# ip = 0.0.0.0
|
ip = 0.0.0.0
|
||||||
# protocol = peer
|
protocol = peer
|
||||||
|
|
||||||
# [port_ws_admin_local]
|
# [port_ws_admin_local]
|
||||||
# port = 6006
|
# port = 6006
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
ripple-mainnet:
|
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:
|
sysctls:
|
||||||
# TCP Performance
|
# TCP Performance
|
||||||
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
net.ipv4.tcp_slow_start_after_idle: 0 # Disable slow start after idle
|
||||||
@@ -86,12 +86,4 @@ x-upstreams:
|
|||||||
msgSize: 50Mb
|
msgSize: 50Mb
|
||||||
url: $${WS_URL}
|
url: $${WS_URL}
|
||||||
chain: ripple
|
chain: ripple
|
||||||
method-groups:
|
|
||||||
enabled:
|
|
||||||
- debug
|
|
||||||
- filter
|
|
||||||
methods:
|
|
||||||
disabled:
|
|
||||||
enabled:
|
|
||||||
- name: txpool_content # TODO: should be disabled for rollup nodes
|
|
||||||
...
|
...
|
||||||
89
ripple/rippled/ripple-testnet-rippled-pruned-nudb.yml
Normal file
89
ripple/rippled/ripple-testnet-rippled-pruned-nudb.yml
Normal 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
|
||||||
|
...
|
||||||
88
ripple/testnet/rippled.cfg
Normal file
88
ripple/testnet/rippled.cfg
Normal 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
|
||||||
5
ripple/testnet/validators.txt
Normal file
5
ripple/testnet/validators.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[validator_list_sites]
|
||||||
|
https://vl.altnet.rippletest.net
|
||||||
|
|
||||||
|
[validator_list_keys]
|
||||||
|
ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860
|
||||||
@@ -54,7 +54,7 @@ for path in $pathlist; do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
case "$protocol" in
|
case "$protocol" in
|
||||||
eth|starknet|aztec|cosmos)
|
eth|starknet|aztec|cosmos|ripple)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Protocol family known from the registry but no probe support
|
# Protocol family known from the registry but no probe support
|
||||||
@@ -68,9 +68,11 @@ for path in $pathlist; do
|
|||||||
is_starknet=false
|
is_starknet=false
|
||||||
is_aztec=false
|
is_aztec=false
|
||||||
is_cosmos=false
|
is_cosmos=false
|
||||||
|
is_ripple=false
|
||||||
[ "$protocol" = "starknet" ] && is_starknet=true
|
[ "$protocol" = "starknet" ] && is_starknet=true
|
||||||
[ "$protocol" = "aztec" ] && is_aztec=true
|
[ "$protocol" = "aztec" ] && is_aztec=true
|
||||||
[ "$protocol" = "cosmos" ] && is_cosmos=true
|
[ "$protocol" = "cosmos" ] && is_cosmos=true
|
||||||
|
[ "$protocol" = "ripple" ] && is_ripple=true
|
||||||
|
|
||||||
ref=''
|
ref=''
|
||||||
if [ -n "$2" ]; then
|
if [ -n "$2" ]; then
|
||||||
@@ -135,6 +137,12 @@ for path in $pathlist; do
|
|||||||
if [ -n "$chain_slug" ]; then
|
if [ -n "$chain_slug" ]; then
|
||||||
ref=$($BASEPATH/reference-rpc-endpoint.sh --chain "$chain_slug" 2>/dev/null) || ref=""
|
ref=$($BASEPATH/reference-rpc-endpoint.sh --chain "$chain_slug" 2>/dev/null) || ref=""
|
||||||
fi
|
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
|
else
|
||||||
# Ethereum chain ID detection
|
# 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)
|
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
|
timeout "$HC_TIMEOUT" $BASEPATH/check-health.sh "$RPC_URL" --starknet $ref
|
||||||
elif $is_cosmos; then
|
elif $is_cosmos; then
|
||||||
timeout "$HC_TIMEOUT" $BASEPATH/check-health.sh "$RPC_URL" --cosmos $ref
|
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
|
else
|
||||||
timeout "$HC_TIMEOUT" $BASEPATH/check-health.sh "$RPC_URL" $ref
|
timeout "$HC_TIMEOUT" $BASEPATH/check-health.sh "$RPC_URL" $ref
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user