Compare commits
28 Commits
865f80c56d
...
issue-848
| Author | SHA1 | Date | |
|---|---|---|---|
| defc60469b | |||
| 921fec2e86 | |||
| 70b8cce5af | |||
| d94213fd5c | |||
| fcf747c6ee | |||
| e56976adeb | |||
| 9d9da8342c | |||
| 99867025db | |||
| bf508e8b07 | |||
| 052e74a00d | |||
| 88bedb0956 | |||
| e571efbea1 | |||
| 58adc446e2 | |||
| 6c0df2bce5 | |||
| 8f57c8af68 | |||
| f8915ed59f | |||
| a98ced8af1 | |||
| 1c65fdb26f | |||
|
|
2fbf996857 | ||
|
|
3c8623531f | ||
| 27f10b29d3 | |||
| 23e9a5dcd5 | |||
| 14b115b7bd | |||
| cb7bb80490 | |||
| eda1068f45 | |||
| 75b931461d | |||
| 4d5d8f4be1 | |||
| 58d45c8576 |
@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
plume-mainnet-archive:
|
plume-mainnet-archive:
|
||||||
image: ${PLUME_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLUME_MAINNET_NITRO_VERSION:-v3.11.0-a618155}
|
image: ${PLUME_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLUME_MAINNET_NITRO_VERSION:-v3.11.1-8512b8c}
|
||||||
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
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
plume-mainnet-archive:
|
plume-mainnet-archive:
|
||||||
image: ${PLUME_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLUME_MAINNET_NITRO_VERSION:-v3.11.0-a618155}
|
image: ${PLUME_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLUME_MAINNET_NITRO_VERSION:-v3.11.1-8512b8c}
|
||||||
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
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
plume-mainnet:
|
plume-mainnet:
|
||||||
image: ${PLUME_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLUME_MAINNET_NITRO_VERSION:-v3.11.0-a618155}
|
image: ${PLUME_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLUME_MAINNET_NITRO_VERSION:-v3.11.1-8512b8c}
|
||||||
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
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
plume-mainnet:
|
plume-mainnet:
|
||||||
image: ${PLUME_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLUME_MAINNET_NITRO_VERSION:-v3.11.0-a618155}
|
image: ${PLUME_NITRO_IMAGE:-offchainlabs/nitro-node}:${PLUME_MAINNET_NITRO_VERSION:-v3.11.1-8512b8c}
|
||||||
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
|
||||||
|
|||||||
12
arc/arc-snapshot-init.Dockerfile
Normal file
12
arc/arc-snapshot-init.Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# One-shot Arc snapshot downloader for compose init containers.
|
||||||
|
# Wraps arc-snapshots with a shell entrypoint so operators can optionally
|
||||||
|
# override EL/CL snapshot URLs via environment variables.
|
||||||
|
ARG ARC_EXECUTION_IMAGE=docker.cloudsmith.io/circle/arc-network/arc-execution:0.7.2
|
||||||
|
FROM ${ARC_EXECUTION_IMAGE} AS arc-bin
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates libssl3 zlib1g \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
COPY --from=arc-bin /usr/local/bin/arc-snapshots /usr/local/bin/arc-snapshots
|
||||||
|
COPY scripts/snapshot-init.sh /usr/local/bin/snapshot-init.sh
|
||||||
|
RUN chmod +x /usr/local/bin/snapshot-init.sh
|
||||||
|
ENTRYPOINT ["/usr/local/bin/snapshot-init.sh"]
|
||||||
23
arc/scripts/snapshot-init.sh
Executable file
23
arc/scripts/snapshot-init.sh
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
CHAIN="${ARC_SNAPSHOT_CHAIN:-arc-testnet}"
|
||||||
|
EXEC_PATH="${ARC_SNAPSHOT_EXECUTION_PATH:-/data/execution}"
|
||||||
|
CONS_PATH="${ARC_SNAPSHOT_CONSENSUS_PATH:-/data/consensus}"
|
||||||
|
|
||||||
|
if [ -n "${ARC_SNAPSHOT_EXECUTION_URL:-}" ] && [ -n "${ARC_SNAPSHOT_CONSENSUS_URL:-}" ]; then
|
||||||
|
exec /usr/local/bin/arc-snapshots download \
|
||||||
|
--chain="${CHAIN}" \
|
||||||
|
--execution-path="${EXEC_PATH}" \
|
||||||
|
--consensus-path="${CONS_PATH}" \
|
||||||
|
--execution-url="${ARC_SNAPSHOT_EXECUTION_URL}" \
|
||||||
|
--consensus-url="${ARC_SNAPSHOT_CONSENSUS_URL}"
|
||||||
|
elif [ -n "${ARC_SNAPSHOT_EXECUTION_URL:-}" ] || [ -n "${ARC_SNAPSHOT_CONSENSUS_URL:-}" ]; then
|
||||||
|
echo "Both ARC_SNAPSHOT_EXECUTION_URL and ARC_SNAPSHOT_CONSENSUS_URL must be set together" >&2
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exec /usr/local/bin/arc-snapshots download \
|
||||||
|
--chain="${CHAIN}" \
|
||||||
|
--execution-path="${EXEC_PATH}" \
|
||||||
|
--consensus-path="${CONS_PATH}"
|
||||||
|
fi
|
||||||
@@ -25,6 +25,13 @@ else
|
|||||||
ct_log "already initialized, continuing"
|
ct_log "already initialized, continuing"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# v4.x start prompts for a BLS password if no key exists; RPC replicas never sign
|
||||||
|
# checkpoints, so pre-create an empty-password key before the first start.
|
||||||
|
if [ ! -f "$CONFIG_DIR/bls_key.json" ]; then
|
||||||
|
ct_log "pre-creating BLS key (no password — RPC replica)"
|
||||||
|
babylond create-bls-key --home "$HOME_DIR" --no-bls-password
|
||||||
|
fi
|
||||||
|
|
||||||
# Serve RPC on all interfaces (dshackle/traefik upstream); default is 127.0.0.1.
|
# Serve RPC on all interfaces (dshackle/traefik upstream); default is 127.0.0.1.
|
||||||
sed -i '/^\[rpc\]/,/^\[/{s|^laddr = .*|laddr = "tcp://0.0.0.0:26657"|}' "$CONFIG_DIR/config.toml"
|
sed -i '/^\[rpc\]/,/^\[/{s|^laddr = .*|laddr = "tcp://0.0.0.0:26657"|}' "$CONFIG_DIR/config.toml"
|
||||||
|
|
||||||
@@ -45,4 +52,4 @@ ct_configure_statesync "$CONFIG_DIR/config.toml" "$STATESYNC_RPC"
|
|||||||
ct_ensure_wasm "$HOME_DIR" "$WASM_SNAPSHOT_URL"
|
ct_ensure_wasm "$HOME_DIR" "$WASM_SNAPSHOT_URL"
|
||||||
ct_seed_priv_validator_state "$HOME_DIR"
|
ct_seed_priv_validator_state "$HOME_DIR"
|
||||||
|
|
||||||
exec babylond start --home "$HOME_DIR" --minimum-gas-prices "$MIN_GAS" "$@"
|
exec babylond start --home "$HOME_DIR" --minimum-gas-prices "$MIN_GAS" --no-bls-password "$@"
|
||||||
|
|||||||
@@ -1,10 +1,73 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Backup persistent compose volumes to /backup or WebDAV.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./backup-node.sh [--hot] [--force] <compose-name> [webdav-url]
|
||||||
|
#
|
||||||
|
# Lifecycle (default, omitted with --hot):
|
||||||
|
# stop services -> fence compose out of COMPOSE_FILE -> tar+zstd -> unfence+start (EXIT trap).
|
||||||
|
# Hot backups skip stop/fence; leveldb/pebble live tars are NOT restore-trustworthy.
|
||||||
|
#
|
||||||
|
# --force Allow backing up an existing but very small datadir (<1GB reported size).
|
||||||
|
# Does NOT bypass a missing volume path (always fatal).
|
||||||
|
|
||||||
BASEPATH="$(dirname "$0")"
|
BASEPATH="$(dirname "$0")"
|
||||||
source "$BASEPATH/volume-utils.sh"
|
source "$BASEPATH/volume-utils.sh"
|
||||||
backup_dir="/backup"
|
backup_dir="/backup"
|
||||||
|
|
||||||
remote_target="$2"
|
HOT_BACKUP=false
|
||||||
|
FORCE_SMALL=false
|
||||||
|
_pos=()
|
||||||
|
for _a in "$@"; do
|
||||||
|
case "$_a" in
|
||||||
|
--hot) HOT_BACKUP=true ;;
|
||||||
|
--force) FORCE_SMALL=true ;;
|
||||||
|
*) _pos+=("$_a") ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
set -- "${_pos[@]}"
|
||||||
|
|
||||||
|
if [ -z "${1:-}" ] || [ ! -f "/root/rpc/$1.yml" ]; then
|
||||||
|
echo "Error: Either no argument provided or /root/rpc/$1.yml does not exist."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
compose_name="$1"
|
||||||
|
remote_target="${2:-}"
|
||||||
|
lifecycle_active=false
|
||||||
|
fenced=false
|
||||||
|
stopped=false
|
||||||
|
|
||||||
|
backup_lifecycle_cleanup() {
|
||||||
|
local rc=$?
|
||||||
|
if [[ "$lifecycle_active" != true ]]; then
|
||||||
|
exit "$rc"
|
||||||
|
fi
|
||||||
|
if [[ "$fenced" == true ]]; then
|
||||||
|
unfence_compose_in_env "$compose_name" || true
|
||||||
|
fenced=false
|
||||||
|
fi
|
||||||
|
if [[ "$stopped" == true ]]; then
|
||||||
|
"$BASEPATH/start.sh" "$compose_name" || true
|
||||||
|
stopped=false
|
||||||
|
fi
|
||||||
|
exit "$rc"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "$HOT_BACKUP" == true ]]; then
|
||||||
|
echo "WARNING: --hot backup skips stop/fence; live leveldb/pebble archives may not restore cleanly"
|
||||||
|
else
|
||||||
|
trap backup_lifecycle_cleanup EXIT
|
||||||
|
lifecycle_active=true
|
||||||
|
echo "Stopping services for $compose_name before backup..."
|
||||||
|
"$BASEPATH/stop.sh" "$compose_name"
|
||||||
|
stopped=true
|
||||||
|
if fence_compose_in_env "$compose_name"; then
|
||||||
|
fenced=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -n "$remote_target" ]] && is_local_backup_url "$remote_target"; then
|
if [[ -n "$remote_target" ]] && is_local_backup_url "$remote_target"; then
|
||||||
echo "Target URL points to this server, using local /backup instead of $remote_target"
|
echo "Target URL points to this server, using local /backup instead of $remote_target"
|
||||||
remote_target=""
|
remote_target=""
|
||||||
@@ -62,13 +125,19 @@ generate_volume_metadata() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Read the JSON input and extract the list of keys
|
# Read the JSON input and extract the list of keys
|
||||||
keys=$(get_persistent_volume_keys "/root/rpc/$1.yml")
|
keys=$(get_persistent_volume_keys "/root/rpc/$compose_name.yml")
|
||||||
|
|
||||||
# Iterate over the list of keys
|
# Iterate over the list of keys
|
||||||
for key in $keys; do
|
for key in $keys; do
|
||||||
echo "Executing command with key: /var/lib/docker/volumes/rpc_$key/_data"
|
echo "Executing command with key: /var/lib/docker/volumes/rpc_$key/_data"
|
||||||
|
|
||||||
source_folder="/var/lib/docker/volumes/rpc_$key/_data"
|
source_folder="/var/lib/docker/volumes/rpc_$key/_data"
|
||||||
|
|
||||||
|
if [[ ! -d "$source_folder" ]]; then
|
||||||
|
echo "FATAL: volume data directory missing, refusing backup: $source_folder" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
folder_size=$(du -shL "$source_folder" | awk '{
|
folder_size=$(du -shL "$source_folder" | awk '{
|
||||||
size = $1
|
size = $1
|
||||||
sub(/[Kk]$/, "", size) # Remove 'K' suffix if present
|
sub(/[Kk]$/, "", size) # Remove 'K' suffix if present
|
||||||
@@ -86,6 +155,11 @@ for key in $keys; do
|
|||||||
}')
|
}')
|
||||||
|
|
||||||
folder_size_gb=$(printf "%.0f" "$folder_size")
|
folder_size_gb=$(printf "%.0f" "$folder_size")
|
||||||
|
|
||||||
|
if (( folder_size_gb < 1 )) && [[ "$FORCE_SMALL" != true ]]; then
|
||||||
|
echo "FATAL: existing datadir too small for backup (${folder_size_gb}G at $source_folder); use --force if intentional" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
timestamp=$(date +'%Y-%m-%d-%H-%M-%S')
|
timestamp=$(date +'%Y-%m-%d-%H-%M-%S')
|
||||||
target_file="rpc_$key-${timestamp}-${folder_size_gb}G.tar.zst"
|
target_file="rpc_$key-${timestamp}-${folder_size_gb}G.tar.zst"
|
||||||
@@ -119,5 +193,5 @@ done
|
|||||||
echo ""
|
echo ""
|
||||||
echo "=== Overall Size Summary ==="
|
echo "=== Overall Size Summary ==="
|
||||||
if [[ -f "$BASEPATH/show-size.sh" ]]; then
|
if [[ -f "$BASEPATH/show-size.sh" ]]; then
|
||||||
"$BASEPATH/show-size.sh" "$1" 2>&1
|
"$BASEPATH/show-size.sh" "$compose_name" 2>&1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
bitcoin-cash-mainnet:
|
bitcoin-cash-mainnet:
|
||||||
image: ${BITCOIN_CASH_BITCOIND_IMAGE:-bitcoinabc/bitcoin-abc}:${BITCOIN_CASH_MAINNET_BITCOIND_VERSION:-0.33.6}
|
image: ${BITCOIN_CASH_BITCOIND_IMAGE:-bitcoinabc/bitcoin-abc}:${BITCOIN_CASH_MAINNET_BITCOIND_VERSION:-0.33.7}
|
||||||
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
|
||||||
@@ -60,6 +60,7 @@ services:
|
|||||||
- -externalip=${IP}
|
- -externalip=${IP}
|
||||||
- -port=10863
|
- -port=10863
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
bitcoin-cash-testnet:
|
bitcoin-cash-testnet:
|
||||||
image: ${BITCOIN_CASH_BITCOIND_IMAGE:-bitcoinabc/bitcoin-abc}:${BITCOIN_CASH_TESTNET_BITCOIND_VERSION:-0.33.6}
|
image: ${BITCOIN_CASH_BITCOIND_IMAGE:-bitcoinabc/bitcoin-abc}:${BITCOIN_CASH_TESTNET_BITCOIND_VERSION:-0.33.7}
|
||||||
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
|
||||||
@@ -60,6 +60,7 @@ services:
|
|||||||
- -externalip=${IP}
|
- -externalip=${IP}
|
||||||
- -port=14363
|
- -port=14363
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ services:
|
|||||||
- -maxconnections=64
|
- -maxconnections=64
|
||||||
- -port=12518
|
- -port=12518
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ services:
|
|||||||
- -maxconnections=64
|
- -maxconnections=64
|
||||||
- -port=13668
|
- -port=13668
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
493
catchup.sh
493
catchup.sh
@@ -25,13 +25,502 @@ s_to_human_readable() {
|
|||||||
seconds=$((seconds % 3600))
|
seconds=$((seconds % 3600))
|
||||||
local minutes=$((seconds / 60))
|
local minutes=$((seconds / 60))
|
||||||
seconds=$((seconds % 60))
|
seconds=$((seconds % 60))
|
||||||
|
|
||||||
printf "%d days, %02d hours, %02d minutes, %02d seconds\n" $days $hours $minutes $seconds
|
printf "%d days, %02d hours, %02d minutes, %02d seconds\n" $days $hours $minutes $seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
BASEPATH="$(dirname "$0")"
|
BASEPATH="$(dirname "$0")"
|
||||||
source $BASEPATH/.env 2>/dev/null || true
|
source $BASEPATH/.env 2>/dev/null || true
|
||||||
|
|
||||||
|
compose_base="$1"
|
||||||
|
seconds_to_measure=${2:-10}
|
||||||
|
|
||||||
|
if [ -z "$compose_base" ]; then
|
||||||
|
echo -e "${RED}Error: compose file path (sans .yml) required${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
compose_yml="$BASEPATH/${compose_base}.yml"
|
||||||
|
if [ ! -f "$compose_yml" ]; then
|
||||||
|
echo -e "${RED}Error: compose file not found: $compose_yml${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$NO_SSL" ]; then
|
||||||
|
PROTO="http"
|
||||||
|
DOMAIN="${DOMAIN:-0.0.0.0}"
|
||||||
|
else
|
||||||
|
PROTO="https"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Resolve traefik RPC path from compose labels (first non-blacklisted path).
|
||||||
|
compose_rpc_path() {
|
||||||
|
local pathlist path
|
||||||
|
pathlist=$(grep -oP "stripprefix\.prefixes.*?/\K[^\"]+" "$compose_yml" 2>/dev/null)
|
||||||
|
for path in $pathlist; do
|
||||||
|
echo "$path"
|
||||||
|
return 0
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
compose_rpc_url() {
|
||||||
|
local path
|
||||||
|
path=$(compose_rpc_path) || return 1
|
||||||
|
echo "$PROTO://$DOMAIN/$path"
|
||||||
|
}
|
||||||
|
|
||||||
|
compose_chain_slug() {
|
||||||
|
grep -oP '^\s*chain:\s*\K\S+' "$compose_yml" 2>/dev/null | head -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Registry protocol via x-upstreams chain label; path-substring fallback for legacy composes.
|
||||||
|
resolve_protocol() {
|
||||||
|
local chain_slug protocol path
|
||||||
|
chain_slug=$(compose_chain_slug)
|
||||||
|
protocol=""
|
||||||
|
if [ -n "$chain_slug" ]; then
|
||||||
|
protocol=$($BASEPATH/reference-rpc-endpoint.sh --protocol "$chain_slug" 2>/dev/null) || protocol=""
|
||||||
|
fi
|
||||||
|
if [ -z "$protocol" ]; then
|
||||||
|
path=$(compose_rpc_path 2>/dev/null) || path=""
|
||||||
|
if echo "$path" | grep -qi "starknet"; then
|
||||||
|
protocol="starknet"
|
||||||
|
elif echo "$path" | grep -qi "aztec"; then
|
||||||
|
protocol="aztec"
|
||||||
|
elif echo "$path" | grep -qiE "bitcoin|digibyte|dogecoin|dash"; then
|
||||||
|
protocol="bitcoin"
|
||||||
|
elif echo "$path" | grep -qi "ripple"; then
|
||||||
|
protocol="ripple"
|
||||||
|
elif echo "$path" | grep -qiE "cosmos|babylon|haqq|gaiad|tac"; then
|
||||||
|
protocol="cosmos"
|
||||||
|
else
|
||||||
|
protocol="eth"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "$protocol"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Bitcoin-family RPC URL (traefik path) and basic-auth from x-upstreams (fallback username:password).
|
||||||
|
bitcoin_rpc_url() {
|
||||||
|
compose_rpc_url
|
||||||
|
}
|
||||||
|
|
||||||
|
bitcoin_rpc_auth() {
|
||||||
|
# Prefer creds from compose x-upstreams basic-auth; per-chain rpcauth may differ on-host.
|
||||||
|
local user pass
|
||||||
|
user=$(grep -A5 'basic-auth:' "$compose_yml" 2>/dev/null | grep -oP '^\s*username:\s*\K\S+' | head -1)
|
||||||
|
pass=$(grep -A5 'basic-auth:' "$compose_yml" 2>/dev/null | grep -oP '^\s*password:\s*\K\S+' | head -1)
|
||||||
|
[ -z "$user" ] && user="username"
|
||||||
|
[ -z "$pass" ] && pass="password"
|
||||||
|
echo "${user}:${pass}"
|
||||||
|
}
|
||||||
|
|
||||||
|
bitcoin_rpc_call() {
|
||||||
|
local method="$1"
|
||||||
|
local params="${2:-[]}"
|
||||||
|
local url auth
|
||||||
|
url=$(bitcoin_rpc_url) || return 1
|
||||||
|
auth=$(bitcoin_rpc_auth)
|
||||||
|
curl -L --ipv4 -m 5 -s -u "$auth" -X POST -H "Content-Type: application/json" \
|
||||||
|
--data "{\"jsonrpc\":\"1.0\",\"id\":1,\"method\":\"$method\",\"params\":$params}" "$url"
|
||||||
|
}
|
||||||
|
|
||||||
|
bitcoin_parse_blocks_headers() {
|
||||||
|
local info="$1"
|
||||||
|
local blocks headers
|
||||||
|
blocks=$(echo "$info" | jq -r '.result.blocks // empty' 2>/dev/null)
|
||||||
|
headers=$(echo "$info" | jq -r '.result.headers // empty' 2>/dev/null)
|
||||||
|
if [[ ! "$blocks" =~ ^[0-9]+$ ]] || [[ ! "$headers" =~ ^[0-9]+$ ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "$blocks $headers"
|
||||||
|
}
|
||||||
|
|
||||||
|
bitcoin_reference_height() {
|
||||||
|
local chain_slug="$1"
|
||||||
|
local ref_urls ref_url resp height
|
||||||
|
ref_urls=$($BASEPATH/reference-rpc-endpoint.sh --chain "$chain_slug" 2>/dev/null) || return 1
|
||||||
|
ref_url=$(echo "$ref_urls" | awk '{print $1}')
|
||||||
|
[ -z "$ref_url" ] && return 1
|
||||||
|
resp=$(curl -L --ipv4 -m 5 -s -X POST -H "Content-Type: application/json" \
|
||||||
|
--data '{"jsonrpc":"1.0","id":1,"method":"getblockcount","params":[]}' "$ref_url")
|
||||||
|
if [ -z "$resp" ] || echo "$resp" | grep -qi 'Unknown network'; then
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
height=$(echo "$resp" | jq -r '.result // empty' 2>/dev/null)
|
||||||
|
if [[ ! "$height" =~ ^[0-9]+$ ]]; then
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
echo "$height"
|
||||||
|
}
|
||||||
|
|
||||||
|
bitcoin_pick_seed_peer() {
|
||||||
|
local chain_slug="$1" path
|
||||||
|
path=$(compose_rpc_path 2>/dev/null) || path=""
|
||||||
|
if echo "$chain_slug $path" | grep -qi "digibyte"; then
|
||||||
|
echo "seed.digibyte.co:12024"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if echo "$chain_slug $path" | grep -qi "dogecoin"; then
|
||||||
|
# TODO: dogecoin wire seeds
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if echo "$chain_slug $path" | grep -qi "dash"; then
|
||||||
|
# TODO: dash wire seeds
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
# Bitcoin mainnet / testnet / cash family default
|
||||||
|
echo "seed.bitcoin.sipa.be:8333"
|
||||||
|
}
|
||||||
|
|
||||||
|
bitcoin_try_addnode() {
|
||||||
|
local chain_slug="$1" peer resp
|
||||||
|
peer=""
|
||||||
|
local ref_urls ref_url pinfo
|
||||||
|
ref_urls=$($BASEPATH/reference-rpc-endpoint.sh --chain "$chain_slug" 2>/dev/null) || ref_urls=""
|
||||||
|
ref_url=$(echo "$ref_urls" | awk '{print $1}')
|
||||||
|
if [ -n "$ref_url" ]; then
|
||||||
|
pinfo=$(curl -L --ipv4 -m 5 -s -X POST -H "Content-Type: application/json" \
|
||||||
|
--data '{"jsonrpc":"1.0","id":1,"method":"getpeerinfo","params":[]}' "$ref_url" 2>/dev/null)
|
||||||
|
peer=$(echo "$pinfo" | jq -r '.result[0].addr // empty' 2>/dev/null)
|
||||||
|
fi
|
||||||
|
if [ -z "$peer" ] || [ "$peer" = "null" ]; then
|
||||||
|
peer=$(bitcoin_pick_seed_peer "$chain_slug") || return 0
|
||||||
|
fi
|
||||||
|
resp=$(bitcoin_rpc_call "addnode" "[\"$peer\", \"onetry\"]")
|
||||||
|
if echo "$resp" | jq -e '.error == null' >/dev/null 2>&1; then
|
||||||
|
echo "Issued harmless addnode onetry to $peer"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
report_block_catchup_rate() {
|
||||||
|
local gap_change="$1"
|
||||||
|
local interval="$2"
|
||||||
|
local block_time_ms="$3"
|
||||||
|
local gap_remaining="$4"
|
||||||
|
local label="${5:-blocks}"
|
||||||
|
|
||||||
|
local block_time_sec realtime_units effective catchup_rate
|
||||||
|
block_time_sec=$(echo "scale=6; $block_time_ms / 1000" | bc)
|
||||||
|
realtime_units=$(echo "scale=6; $interval / $block_time_sec" | bc)
|
||||||
|
effective=$(echo "scale=6; $realtime_units - $gap_change" | bc)
|
||||||
|
catchup_rate=$(echo "scale=3; $effective / $realtime_units" | bc)
|
||||||
|
|
||||||
|
echo "First measurement: $label behind = $((gap_remaining - gap_change)) $label"
|
||||||
|
echo "Second measurement: $label behind = $gap_remaining $label"
|
||||||
|
echo "Gap change in $interval seconds: $gap_change $label"
|
||||||
|
echo "Calculated catchup rate: ${catchup_rate}x realtime"
|
||||||
|
|
||||||
|
if (( $(echo "$catchup_rate < 0" | bc -l) )); then
|
||||||
|
local falling_behind_rate
|
||||||
|
falling_behind_rate=$(echo "scale=2; -1 * $catchup_rate" | bc)
|
||||||
|
echo -e "${RED}Node is FALLING BEHIND by ${falling_behind_rate}x realtime${NC}"
|
||||||
|
echo -e "${RED}The gap increased by $gap_change $label over $interval seconds${NC}"
|
||||||
|
return 1
|
||||||
|
elif (( $(echo "$catchup_rate < 1" | bc -l) )); then
|
||||||
|
echo -e "${YELLOW}WARNING: Node is processing at ${catchup_rate}x realtime${NC}"
|
||||||
|
echo -e "${YELLOW}This is too slow - node will never catch up to chain head${NC}"
|
||||||
|
return 2
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}Node is processing at ${catchup_rate}x realtime${NC}"
|
||||||
|
local time_to_catchup
|
||||||
|
time_to_catchup=$(echo "scale=0; $gap_remaining * $block_time_sec / ($catchup_rate - 1)" | bc)
|
||||||
|
echo -e "${GREEN}Estimated time until synced:${NC}"
|
||||||
|
s_to_human_readable "$time_to_catchup"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
bitcoin_catchup() {
|
||||||
|
local chain_slug="$1"
|
||||||
|
local interval="$2"
|
||||||
|
local block_time_ms info1 info2 blocks1 headers1 blocks2 headers2
|
||||||
|
local ref1 ref2 use_pseudo=false gap1 gap2 gap_change
|
||||||
|
|
||||||
|
block_time_ms=$($BASEPATH/reference-rpc-endpoint.sh --block-time-ms "$chain_slug" 2>/dev/null) || block_time_ms="600000"
|
||||||
|
|
||||||
|
echo "Checking sync status for $compose_base (bitcoin-family)..."
|
||||||
|
info1=$(bitcoin_rpc_call "getblockchaininfo")
|
||||||
|
if [ -z "$info1" ]; then
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
read -r blocks1 headers1 < <(bitcoin_parse_blocks_headers "$info1") || {
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ref1=$(bitcoin_reference_height "$chain_slug")
|
||||||
|
local ref_rc1=$?
|
||||||
|
if [ "$ref_rc1" -eq 2 ]; then
|
||||||
|
use_pseudo=true
|
||||||
|
ref1=$headers1
|
||||||
|
echo "Reference RPC unavailable (Unknown network) — using local headers as pseudo-reference"
|
||||||
|
elif [ "$ref_rc1" -ne 0 ]; then
|
||||||
|
use_pseudo=true
|
||||||
|
ref1=$headers1
|
||||||
|
echo "Reference RPC unavailable — using local headers as pseudo-reference"
|
||||||
|
fi
|
||||||
|
|
||||||
|
gap1=$((ref1 - blocks1))
|
||||||
|
echo "Current chain head is $gap1 blocks behind reference"
|
||||||
|
s_to_human_readable $(echo "scale=0; $gap1 * $block_time_ms / 1000" | bc)
|
||||||
|
|
||||||
|
echo "Measuring progress over $interval seconds..."
|
||||||
|
sleep "$interval"
|
||||||
|
|
||||||
|
info2=$(bitcoin_rpc_call "getblockchaininfo")
|
||||||
|
if [ -z "$info2" ]; then
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
read -r blocks2 headers2 < <(bitcoin_parse_blocks_headers "$info2") || {
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if $use_pseudo; then
|
||||||
|
ref2=$headers2
|
||||||
|
else
|
||||||
|
ref2=$(bitcoin_reference_height "$chain_slug")
|
||||||
|
local ref_rc2=$?
|
||||||
|
if [ "$ref_rc2" -ne 0 ]; then
|
||||||
|
ref2=$headers2
|
||||||
|
use_pseudo=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
gap2=$((ref2 - blocks2))
|
||||||
|
gap_change=$((gap2 - gap1))
|
||||||
|
|
||||||
|
report_block_catchup_rate "$gap_change" "$interval" "$block_time_ms" "$gap2" "blocks"
|
||||||
|
local rc=$?
|
||||||
|
if [ "$rc" -eq 1 ] && [ -n "$chain_slug" ]; then
|
||||||
|
bitcoin_try_addnode "$chain_slug"
|
||||||
|
fi
|
||||||
|
exit "$rc"
|
||||||
|
}
|
||||||
|
|
||||||
|
ripple_rpc_call() {
|
||||||
|
local url
|
||||||
|
url=$(compose_rpc_url) || return 1
|
||||||
|
curl -L --ipv4 -m 5 -s -X POST -H "Content-Type: application/json" \
|
||||||
|
--data '{"method":"server_info"}' "$url"
|
||||||
|
}
|
||||||
|
|
||||||
|
ripple_validated_seq() {
|
||||||
|
local resp="$1" seq
|
||||||
|
seq=$(echo "$resp" | jq -r '.result.info.validated_ledger.seq // .info.validated_ledger.seq // empty' 2>/dev/null)
|
||||||
|
if [[ ! "$seq" =~ ^[0-9]+$ ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "$seq"
|
||||||
|
}
|
||||||
|
|
||||||
|
ripple_reference_seq() {
|
||||||
|
local chain_slug="$1" ref_urls ref_url resp
|
||||||
|
ref_urls=$($BASEPATH/reference-rpc-endpoint.sh --chain "$chain_slug" 2>/dev/null) || return 1
|
||||||
|
ref_url=$(echo "$ref_urls" | awk '{print $1}')
|
||||||
|
[ -z "$ref_url" ] && return 1
|
||||||
|
resp=$(curl -L --ipv4 -m 5 -s -X POST -H "Content-Type: application/json" \
|
||||||
|
--data '{"method":"server_info"}' "$ref_url")
|
||||||
|
ripple_validated_seq "$resp"
|
||||||
|
}
|
||||||
|
|
||||||
|
ripple_catchup() {
|
||||||
|
local chain_slug="$1"
|
||||||
|
local interval="$2"
|
||||||
|
local block_time_ms resp1 resp2 seq1 seq2 ref1 ref2 gap1 gap2 gap_change
|
||||||
|
|
||||||
|
block_time_ms=$($BASEPATH/reference-rpc-endpoint.sh --block-time-ms "$chain_slug" 2>/dev/null) || block_time_ms="4000"
|
||||||
|
|
||||||
|
echo "Checking sync status for $compose_base (ripple)..."
|
||||||
|
resp1=$(ripple_rpc_call)
|
||||||
|
if [ -z "$resp1" ]; then
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
seq1=$(ripple_validated_seq "$resp1") || {
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ref1=$(ripple_reference_seq "$chain_slug") || ref1=""
|
||||||
|
if [ -z "$ref1" ]; then
|
||||||
|
gap1=0
|
||||||
|
echo "Reference RPC unavailable — measuring local validated-ledger progress only"
|
||||||
|
else
|
||||||
|
gap1=$((ref1 - seq1))
|
||||||
|
echo "Current chain head is $gap1 ledgers behind reference"
|
||||||
|
s_to_human_readable $(echo "scale=0; $gap1 * $block_time_ms / 1000" | bc)
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Measuring progress over $interval seconds..."
|
||||||
|
sleep "$interval"
|
||||||
|
|
||||||
|
resp2=$(ripple_rpc_call)
|
||||||
|
if [ -z "$resp2" ]; then
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
seq2=$(ripple_validated_seq "$resp2") || {
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ref2=$(ripple_reference_seq "$chain_slug") || ref2=""
|
||||||
|
if [ -z "$ref1" ] || [ -z "$ref2" ]; then
|
||||||
|
local seq_gain=$((seq2 - seq1))
|
||||||
|
local realtime_units effective catchup_rate
|
||||||
|
realtime_units=$(echo "scale=6; $interval * 1000 / $block_time_ms" | bc)
|
||||||
|
effective=$(echo "scale=6; $seq_gain" | bc)
|
||||||
|
catchup_rate=$(echo "scale=3; $effective / $realtime_units" | bc)
|
||||||
|
echo "Validated ledger gain in $interval seconds: $seq_gain ledgers"
|
||||||
|
echo "Calculated catchup rate: ${catchup_rate}x realtime"
|
||||||
|
if (( $(echo "$catchup_rate < 1" | bc -l) )); then
|
||||||
|
if (( $(echo "$catchup_rate < 0" | bc -l) )); then
|
||||||
|
echo -e "${RED}Node is FALLING BEHIND${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -e "${YELLOW}WARNING: Node is processing at ${catchup_rate}x realtime${NC}"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
echo -e "${GREEN}Node is processing at ${catchup_rate}x realtime${NC}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
gap2=$((ref2 - seq2))
|
||||||
|
gap_change=$((gap2 - gap1))
|
||||||
|
|
||||||
|
report_block_catchup_rate "$gap_change" "$interval" "$block_time_ms" "$gap2" "ledgers"
|
||||||
|
exit $?
|
||||||
|
}
|
||||||
|
|
||||||
|
cosmos_catching_up() {
|
||||||
|
local url status catching_up
|
||||||
|
url=$(compose_rpc_url) || return 1
|
||||||
|
status=$(curl -L --ipv4 -m 5 -s -X POST -H "Content-Type: application/json" \
|
||||||
|
--data '{"jsonrpc":"2.0","id":1,"method":"status"}' "$url")
|
||||||
|
catching_up=$(echo "$status" | jq -r '.result.sync_info.catching_up // .sync_info.catching_up // empty' 2>/dev/null)
|
||||||
|
echo "$catching_up"
|
||||||
|
}
|
||||||
|
|
||||||
|
cosmos_catchup() {
|
||||||
|
local catching_up
|
||||||
|
|
||||||
|
echo "Checking sync status for $compose_base (cosmos/cometbft)..."
|
||||||
|
catching_up=$(cosmos_catching_up)
|
||||||
|
if [ "$catching_up" = "true" ]; then
|
||||||
|
echo "CometBFT reports catching_up=true (node is still syncing)"
|
||||||
|
elif [ -z "$catching_up" ]; then
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Standard timestamp-lag algorithm via timestamp.sh (cosmos /status source).
|
||||||
|
echo "Debug: Running ./timestamp.sh $compose_base"
|
||||||
|
timestamp_output=$(./timestamp.sh "$compose_base" 2>&1)
|
||||||
|
timestamp_exit_code=$?
|
||||||
|
|
||||||
|
echo "Debug: timestamp.sh output: '$timestamp_output'"
|
||||||
|
echo "Debug: timestamp.sh exit code: $timestamp_exit_code"
|
||||||
|
|
||||||
|
latest_block_timestamp_decimal=$(echo "$timestamp_output" | grep -o '[0-9]\+' | head -1)
|
||||||
|
|
||||||
|
if [[ $timestamp_exit_code -ne 0 || -z "$latest_block_timestamp_decimal" ]]; then
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_time=$(date +%s)
|
||||||
|
time_difference=$((current_time - latest_block_timestamp_decimal))
|
||||||
|
|
||||||
|
echo "Current chain head is $time_difference seconds behind real time"
|
||||||
|
if [ "$catching_up" = "true" ]; then
|
||||||
|
echo "(catching_up=true)"
|
||||||
|
fi
|
||||||
|
s_to_human_readable $time_difference
|
||||||
|
|
||||||
|
echo "Measuring progress over $seconds_to_measure seconds..."
|
||||||
|
sleep $seconds_to_measure
|
||||||
|
|
||||||
|
catching_up=$(cosmos_catching_up)
|
||||||
|
if [ "$catching_up" = "true" ]; then
|
||||||
|
echo "CometBFT still reports catching_up=true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Debug: Running ./timestamp.sh $compose_base (second measurement)"
|
||||||
|
timestamp_output=$(./timestamp.sh "$compose_base" 2>&1)
|
||||||
|
timestamp_exit_code=$?
|
||||||
|
|
||||||
|
echo "Debug: timestamp.sh output (second): '$timestamp_output'"
|
||||||
|
echo "Debug: timestamp.sh exit code (second): $timestamp_exit_code"
|
||||||
|
|
||||||
|
latest_block_timestamp2=$(echo "$timestamp_output" | grep -o '[0-9]\+' | head -1)
|
||||||
|
|
||||||
|
if [[ $timestamp_exit_code -ne 0 || -z "$latest_block_timestamp2" ]]; then
|
||||||
|
echo -e "${RED}rpc-not-open (expected mid-sync for stage-sync/bootstrap clients — avalanchego, erigon/reth stage-sync, statesync bootstraps); re-run at chainhead${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_time2=$(date +%s)
|
||||||
|
time_difference2=$((current_time2 - latest_block_timestamp2))
|
||||||
|
|
||||||
|
gap_change=$((time_difference2 - time_difference))
|
||||||
|
|
||||||
|
effective_catchup_seconds=$((seconds_to_measure - gap_change))
|
||||||
|
catchup_rate=$(echo "scale=3; $effective_catchup_seconds / $seconds_to_measure" | bc)
|
||||||
|
|
||||||
|
echo "First measurement: Time behind = $time_difference seconds"
|
||||||
|
echo "Second measurement: Time behind = $time_difference2 seconds"
|
||||||
|
if [ "$catching_up" = "true" ]; then
|
||||||
|
echo "(catching_up=true)"
|
||||||
|
fi
|
||||||
|
echo "Gap change in $seconds_to_measure seconds: $gap_change seconds"
|
||||||
|
echo "Calculated catchup rate: $catchup_rate× realtime"
|
||||||
|
|
||||||
|
if (( $(echo "$catchup_rate < 0" | bc -l) )); then
|
||||||
|
falling_behind_rate=$(echo "scale=2; -1 * $catchup_rate" | bc)
|
||||||
|
echo -e "${RED}Node is FALLING BEHIND by $falling_behind_rate× realtime${NC}"
|
||||||
|
echo -e "${RED}The gap increased by $gap_change seconds over $seconds_to_measure seconds${NC}"
|
||||||
|
exit 1
|
||||||
|
elif (( $(echo "$catchup_rate < 1" | bc -l) )); then
|
||||||
|
echo -e "${YELLOW}WARNING: Node is processing at $catchup_rate× realtime${NC}"
|
||||||
|
echo -e "${YELLOW}This is too slow - node will never catch up to chain head${NC}"
|
||||||
|
exit 2
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}Node is processing at $catchup_rate× realtime${NC}"
|
||||||
|
time_to_catchup=$(echo "scale=0; $time_difference2 / ($catchup_rate - 1)" | bc)
|
||||||
|
echo -e "${GREEN}Estimated time until synced:${NC}"
|
||||||
|
s_to_human_readable $time_to_catchup
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol=$(resolve_protocol)
|
||||||
|
chain_slug=$(compose_chain_slug)
|
||||||
|
|
||||||
|
case "$protocol" in
|
||||||
|
bitcoin)
|
||||||
|
bitcoin_catchup "$chain_slug" "$seconds_to_measure"
|
||||||
|
;;
|
||||||
|
ripple)
|
||||||
|
ripple_catchup "$chain_slug" "$seconds_to_measure"
|
||||||
|
;;
|
||||||
|
cosmos)
|
||||||
|
cosmos_catchup
|
||||||
|
;;
|
||||||
|
eth|starknet|aztec)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "unsupported protocol $protocol for catchup"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# --- eth / starknet / aztec: original timestamp-lag path (unchanged) ---
|
||||||
|
|
||||||
seconds_to_measure=${2:-10}
|
seconds_to_measure=${2:-10}
|
||||||
|
|
||||||
# First measurement
|
# First measurement
|
||||||
@@ -55,7 +544,7 @@ fi
|
|||||||
current_time=$(date +%s)
|
current_time=$(date +%s)
|
||||||
time_difference=$((current_time - latest_block_timestamp_decimal))
|
time_difference=$((current_time - latest_block_timestamp_decimal))
|
||||||
|
|
||||||
# Check for reasonable time difference
|
# Check for reasonable time difference
|
||||||
echo "Current chain head is $time_difference seconds behind real time"
|
echo "Current chain head is $time_difference seconds behind real time"
|
||||||
s_to_human_readable $time_difference
|
s_to_human_readable $time_difference
|
||||||
|
|
||||||
|
|||||||
@@ -380,6 +380,14 @@ if [ $? -eq 0 ]; then
|
|||||||
echo "unverified ($http_status_code2)"
|
echo "unverified ($http_status_code2)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
rm "$response_file2"
|
||||||
|
if [ $attempt -lt $MAX_RETRIES ]; then
|
||||||
|
attempt=$((attempt + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo "unverified (reference unreachable)"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
BASEPATH="$(cd "$(dirname "$0")" && pwd)"
|
BASEPATH="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
# shellcheck source=volume-utils.sh
|
||||||
|
source "$BASEPATH/volume-utils.sh"
|
||||||
BACKUP_DIR="${BACKUP_DIR:-/backup}"
|
BACKUP_DIR="${BACKUP_DIR:-/backup}"
|
||||||
TRASH_DIR="${TRASH_DIR:-$BACKUP_DIR/trash}"
|
TRASH_DIR="${TRASH_DIR:-$BACKUP_DIR/trash}"
|
||||||
KEEP_COUNT="${KEEP_COUNT:-3}"
|
KEEP_COUNT="${KEEP_COUNT:-3}"
|
||||||
@@ -163,6 +165,20 @@ cleanup_volume_backups() {
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! is_restorable_backup_archive "$file"; then
|
||||||
|
local near_size
|
||||||
|
near_size=$(backup_archive_size_bytes "$file")
|
||||||
|
local near_meta
|
||||||
|
near_meta=$(metadata_for_archive "$file")
|
||||||
|
add_trashed_bytes "$file"
|
||||||
|
trash_file "$file" "near-empty artifact (${near_size} bytes, excluded from KEEP_COUNT)"
|
||||||
|
if [[ -f "$near_meta" ]]; then
|
||||||
|
add_trashed_bytes "$near_meta"
|
||||||
|
trash_file "$near_meta" "metadata for near-empty artifact"
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
volume_files["$volume_key"]+="$file"$'\n'
|
volume_files["$volume_key"]+="$file"$'\n'
|
||||||
done < <(find "$BACKUP_DIR" -maxdepth 1 -type f -name 'rpc_*-*.tar.zst' -print0 2>/dev/null)
|
done < <(find "$BACKUP_DIR" -maxdepth 1 -type f -name 'rpc_*-*.tar.zst' -print0 2>/dev/null)
|
||||||
|
|
||||||
|
|||||||
@@ -294,11 +294,12 @@ transfer_backup() {
|
|||||||
local key=$1
|
local key=$1
|
||||||
local volume_name="rpc_$key"
|
local volume_name="rpc_$key"
|
||||||
|
|
||||||
# Find the newest backup file
|
# Find the newest restorable backup file (skip near-empty artifacts)
|
||||||
local backup_file=$(ls -1 "$backup_dir"/"${volume_name}"-[0-9]*G.tar.zst 2>/dev/null | sort | tail -n 1)
|
local backup_file
|
||||||
|
backup_file=$(select_newest_local_backup "$backup_dir" "$volume_name")
|
||||||
|
|
||||||
if [[ -z "$backup_file" ]] || [[ ! -f "$backup_file" ]]; then
|
if [[ -z "$backup_file" ]] || [[ ! -f "$backup_file" ]]; then
|
||||||
echo "Warning: No backup file found for $volume_name, skipping"
|
echo "Warning: No restorable backup file found for $volume_name, skipping"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -482,11 +483,12 @@ transfer_backup_ssh() {
|
|||||||
local key=$1
|
local key=$1
|
||||||
local volume_name="rpc_$key"
|
local volume_name="rpc_$key"
|
||||||
|
|
||||||
# Find the newest backup file
|
# Find the newest restorable backup file (skip near-empty artifacts)
|
||||||
local backup_file=$(ls -1 "$backup_dir"/"${volume_name}"-[0-9]*G.tar.zst 2>/dev/null | sort | tail -n 1)
|
local backup_file
|
||||||
|
backup_file=$(select_newest_local_backup "$backup_dir" "$volume_name")
|
||||||
|
|
||||||
if [[ -z "$backup_file" ]] || [[ ! -f "$backup_file" ]]; then
|
if [[ -z "$backup_file" ]] || [[ ! -f "$backup_file" ]]; then
|
||||||
echo "Warning: No backup file found for $volume_name, skipping"
|
echo "Warning: No restorable backup file found for $volume_name, skipping"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -61,10 +61,18 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- API=eth,txpool,net,debug,web3
|
- API=eth,txpool,net,debug,web3
|
||||||
- CHAINID=cronosmainnet_25-1
|
- CHAINID=cronosmainnet_25-1
|
||||||
- CHAINNAME=mainnet
|
- EVM_MAX_TX_GAS_WANTED=500000
|
||||||
|
- GENESIS_URL=https://raw.githubusercontent.com/crypto-org-chain/cronos-mainnet/master/cronosmainnet_25-1/genesis.json
|
||||||
- IP=${IP}
|
- IP=${IP}
|
||||||
|
- JSON_RPC_BLOCK_RANGE_CAP=10000
|
||||||
|
- JSON_RPC_ENABLE=true
|
||||||
|
- JSON_RPC_ENABLE_INDEXER=true
|
||||||
|
- JSON_RPC_FEEHISTORY_CAP=100
|
||||||
|
- JSON_RPC_HTTP_TIMEOUT=30s
|
||||||
|
- JSON_RPC_LOGS_CAP=10000
|
||||||
- MONIKER=d${DOMAIN:-local}
|
- MONIKER=d${DOMAIN:-local}
|
||||||
- P2P_PORT=10521
|
- P2P_PORT=10521
|
||||||
|
- SEEDS=0d5cf1394a1cfde28dc8f023567222abc0f47534@seed-0.cronos.com:26656,3032073adc06d710dd512240281637c1bd0c8a7b@seed-1.cronos.com:26656,04f43116b4c6c70054d9c2b7485383df5b1ed1da@seed-2.cronos.com:26656,337377dcda43d79c537d2c4d93ad3b698ce9452e@bd-cronos-mainnet-seed-node-01.bdnodes.net:26656
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
stop_grace_period: 5m
|
stop_grace_period: 5m
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@@ -1,69 +1,53 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# cronosd entrypoint — Cronos (Cosmos-SDK + embedded EVM). EVM JSON-RPC :8545 / WS :8546
|
||||||
set -e # Exit on failure
|
# are the dshackle/traefik upstream; CometBFT :26657 stays internal. Bootstrap params
|
||||||
|
# (chain_id, genesis_url, seeds, app.toml tunables) come from context.yml via env.
|
||||||
echo "MONIKER: $MONIKER"
|
set -e
|
||||||
|
|
||||||
CHAINID=${CHAINID:-cronosmainnet_25-1}
|
|
||||||
CHAINNAME=${CHAINNAME:-mainnet}
|
|
||||||
API=${API:-eth,txpool,net,debug,web3}
|
|
||||||
|
|
||||||
CONFIG_DIR="/root/.cronos/config"
|
|
||||||
|
|
||||||
# Create config directory
|
|
||||||
mkdir -p "$CONFIG_DIR"
|
|
||||||
|
|
||||||
P2P_STRING="tcp:\/\/0\.0\.0\.0\:${P2P_PORT:-10521}"
|
|
||||||
NAT_STRING="${IP}:${P2P_PORT:-10521}"
|
|
||||||
|
|
||||||
env
|
|
||||||
|
|
||||||
# this goes first because it won't overwrite shit
|
|
||||||
apk add curl jq
|
|
||||||
if [ $? -ne 0 ]; then exit 1; fi
|
|
||||||
|
|
||||||
# Source the shared CometBFT helpers
|
|
||||||
. /usr/local/bin/cometbft-common.sh
|
. /usr/local/bin/cometbft-common.sh
|
||||||
|
|
||||||
if cronosd init ${MONIKER} --chain-id ${CHAINID} --home /root/.cronos/; then
|
HOME_DIR="/root/.cronos"
|
||||||
# Define variables
|
CONFIG_DIR="$HOME_DIR/config"
|
||||||
GENESIS_URL="https://raw.githubusercontent.com/crypto-org-chain/cronos-mainnet/master/cronosmainnet_25-1/genesis.json"
|
CHAINID="${CHAINID:-cronosmainnet_25-1}"
|
||||||
SEEDS="0d5cf1394a1cfde28dc8f023567222abc0f47534@cronos-seed-0.crypto.org:26656,3032073adc06d710dd512240281637c1bd0c8a7b@cronos-seed-1.crypto.org:26656,04f43116b4c6c70054d9c2b7485383df5b1ed1da@cronos-seed-2.crypto.org:26656"
|
API="${API:-eth,txpool,net,debug,web3}"
|
||||||
|
GENESIS_URL="${GENESIS_URL:-https://raw.githubusercontent.com/crypto-org-chain/cronos-mainnet/master/cronosmainnet_25-1/genesis.json}"
|
||||||
# Download config files
|
SEEDS="${SEEDS:-0d5cf1394a1cfde28dc8f023567222abc0f47534@seed-0.cronos.com:26656,3032073adc06d710dd512240281637c1bd0c8a7b@seed-1.cronos.com:26656,04f43116b4c6c70054d9c2b7485383df5b1ed1da@seed-2.cronos.com:26656,337377dcda43d79c537d2c4d93ad3b698ce9452e@bd-cronos-mainnet-seed-node-01.bdnodes.net:26656}"
|
||||||
curl -sL "$GENESIS_URL" -o "$CONFIG_DIR/genesis.json"
|
JSON_RPC_ENABLE="${JSON_RPC_ENABLE:-true}"
|
||||||
|
JSON_RPC_ENABLE_INDEXER="${JSON_RPC_ENABLE_INDEXER:-true}"
|
||||||
# somehow it's better to make home static to /root
|
JSON_RPC_FEEHISTORY_CAP="${JSON_RPC_FEEHISTORY_CAP:-100}"
|
||||||
sed -i 's|~/|/root/|g' "$CONFIG_DIR/config.toml"
|
JSON_RPC_LOGS_CAP="${JSON_RPC_LOGS_CAP:-10000}"
|
||||||
sed -i 's|~/|/root/|g' "$CONFIG_DIR/app.toml"
|
JSON_RPC_BLOCK_RANGE_CAP="${JSON_RPC_BLOCK_RANGE_CAP:-10000}"
|
||||||
|
JSON_RPC_HTTP_TIMEOUT="${JSON_RPC_HTTP_TIMEOUT:-30s}"
|
||||||
|
EVM_MAX_TX_GAS_WANTED="${EVM_MAX_TX_GAS_WANTED:-500000}"
|
||||||
|
|
||||||
|
ct_apk curl jq
|
||||||
|
|
||||||
|
if cronosd init "${MONIKER:-rpc-node}" --chain-id "$CHAINID" --home "$HOME_DIR" >/dev/null 2>&1; then
|
||||||
|
ct_log "fresh init; fetching genesis"
|
||||||
|
ct_fetch "$GENESIS_URL" "$CONFIG_DIR/genesis.json" required
|
||||||
|
ct_localize_home "$CONFIG_DIR"
|
||||||
else
|
else
|
||||||
echo "Already initialized, continuing!" >&2
|
ct_log "already initialized, continuing"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Localize home directory paths
|
sed -i -e "s/^pruning *=.*/pruning = \"custom\"/" "$CONFIG_DIR/app.toml"
|
||||||
ct_localize_home /root/.cronos/config
|
sed -i -e "s/^pruning-keep-recent *=.*/pruning-keep-recent = \"100\"/" "$CONFIG_DIR/app.toml"
|
||||||
|
sed -i -e "s/^pruning-interval *=.*/pruning-interval = \"19\"/" "$CONFIG_DIR/app.toml"
|
||||||
# apply a port change to the config
|
sed -i -e "s/^indexer *=.*/indexer = \"null\"/" "$CONFIG_DIR/config.toml"
|
||||||
ct_patch_p2p "$CONFIG_DIR/config.toml" "$IP" "${P2P_PORT:-10521}"
|
|
||||||
|
|
||||||
sed -i -e "s/^pruning *=.*/pruning = \"custom\"/" $CONFIG_DIR/app.toml
|
|
||||||
sed -i -e "s/^pruning-keep-recent *=.*/pruning-keep-recent = \"100\"/" $CONFIG_DIR/app.toml
|
|
||||||
sed -i -e "s/^pruning-interval *=.*/pruning-interval = \"19\"/" $CONFIG_DIR/app.toml
|
|
||||||
sed -i -e "s/^indexer *=.*/indexer = \"null\"/" $CONFIG_DIR/config.toml
|
|
||||||
|
|
||||||
sed -i "/^\[json-rpc\]/,/^\[/{s|^address = .*|address = \"0.0.0.0:8545\"|}" "$CONFIG_DIR/app.toml"
|
sed -i "/^\[json-rpc\]/,/^\[/{s|^address = .*|address = \"0.0.0.0:8545\"|}" "$CONFIG_DIR/app.toml"
|
||||||
sed -i "/^\[json-rpc\]/,/^\[/{s|^ws-address = .*|ws-address = \"0.0.0.0:8546\"|}" "$CONFIG_DIR/app.toml"
|
sed -i "/^\[json-rpc\]/,/^\[/{s|^ws-address = .*|ws-address = \"0.0.0.0:8546\"|}" "$CONFIG_DIR/app.toml"
|
||||||
sed -i "/^\[json-rpc\]/,/^\[/{s|^api = .*|api = \"$API\"|}" "$CONFIG_DIR/app.toml"
|
sed -i "/^\[json-rpc\]/,/^\[/{s|^api = .*|api = \"$API\"|}" "$CONFIG_DIR/app.toml"
|
||||||
|
sed -i "/^\[json-rpc\]/,/^\[/{s|^enable = .*|enable = $JSON_RPC_ENABLE|}" "$CONFIG_DIR/app.toml"
|
||||||
|
sed -i "/^\[json-rpc\]/,/^\[/{s|^enable-indexer = .*|enable-indexer = $JSON_RPC_ENABLE_INDEXER|}" "$CONFIG_DIR/app.toml"
|
||||||
|
sed -i "/^\[json-rpc\]/,/^\[/{s|^feehistory-cap = .*|feehistory-cap = $JSON_RPC_FEEHISTORY_CAP|}" "$CONFIG_DIR/app.toml"
|
||||||
|
sed -i "/^\[json-rpc\]/,/^\[/{s|^logs-cap = .*|logs-cap = $JSON_RPC_LOGS_CAP|}" "$CONFIG_DIR/app.toml"
|
||||||
|
sed -i "/^\[json-rpc\]/,/^\[/{s|^block-range-cap = .*|block-range-cap = $JSON_RPC_BLOCK_RANGE_CAP|}" "$CONFIG_DIR/app.toml"
|
||||||
|
sed -i "/^\[json-rpc\]/,/^\[/{s|^http-timeout = .*|http-timeout = \"$JSON_RPC_HTTP_TIMEOUT\"|}" "$CONFIG_DIR/app.toml"
|
||||||
|
sed -i "/^\[evm\]/,/^\[/{s|^max-tx-gas-wanted = .*|max-tx-gas-wanted = $EVM_MAX_TX_GAS_WANTED|}" "$CONFIG_DIR/app.toml"
|
||||||
|
|
||||||
# Set seeds
|
ct_patch_p2p "$CONFIG_DIR/config.toml" "$IP" "${P2P_PORT:-10521}"
|
||||||
ct_set_persistent_peers "$CONFIG_DIR/config.toml" "$SEEDS"
|
ct_merge_seeds "$CONFIG_DIR/config.toml" "$SEEDS"
|
||||||
|
|
||||||
# Configure state sync using official RPC endpoints
|
|
||||||
ct_configure_statesync "$CONFIG_DIR/config.toml" "https://rpc-cronos.crypto.org:443,https://cronos-rpc.publicnode.com:443" 2000
|
ct_configure_statesync "$CONFIG_DIR/config.toml" "https://rpc-cronos.crypto.org:443,https://cronos-rpc.publicnode.com:443" 2000
|
||||||
|
ct_set_moniker "$CONFIG_DIR/config.toml" "${MONIKER:-rpc-node}"
|
||||||
|
|
||||||
# Update moniker if set
|
exec cronosd start --chain-id "$CHAINID" "$@"
|
||||||
if [ -n "$MONIKER" ] && [ -f "$CONFIG_DIR/config.toml" ]; then
|
|
||||||
ct_set_moniker "$CONFIG_DIR/config.toml" "$MONIKER"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec cronosd start --chain-id ${CHAINID} $@
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ services:
|
|||||||
- -externalip=${IP}
|
- -externalip=${IP}
|
||||||
- -port=11650
|
- -port=11650
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ services:
|
|||||||
- -externalip=${IP}
|
- -externalip=${IP}
|
||||||
- -port=11254
|
- -port=11254
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ services:
|
|||||||
- -externalip=${IP}
|
- -externalip=${IP}
|
||||||
- -port=12577
|
- -port=12577
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ services:
|
|||||||
- -externalip=${IP}
|
- -externalip=${IP}
|
||||||
- -port=10859
|
- -port=10859
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ services:
|
|||||||
- traefik.http.routers.ethereum-mainnet-besu-pruned-bonsai-ws.middlewares=ethereum-mainnet-besu-pruned-bonsai-stripprefix, ipallowlist
|
- traefik.http.routers.ethereum-mainnet-besu-pruned-bonsai-ws.middlewares=ethereum-mainnet-besu-pruned-bonsai-stripprefix, ipallowlist
|
||||||
|
|
||||||
ethereum-mainnet-besu-node:
|
ethereum-mainnet-besu-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 18205:18205
|
- 18205:18205
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ services:
|
|||||||
- traefik.http.routers.ethereum-hoodi-geth-pruned-pebble-path.middlewares=ethereum-hoodi-geth-pruned-pebble-path-stripprefix, ipallowlist
|
- traefik.http.routers.ethereum-hoodi-geth-pruned-pebble-path.middlewares=ethereum-hoodi-geth-pruned-pebble-path-stripprefix, ipallowlist
|
||||||
|
|
||||||
ethereum-hoodi-geth-node:
|
ethereum-hoodi-geth-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_HOODI_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_HOODI_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 16917:16917
|
- 16917:16917
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ services:
|
|||||||
- traefik.http.routers.ethereum-mainnet-geth-pruned-leveldb-hash-events.middlewares=ipallowlist
|
- traefik.http.routers.ethereum-mainnet-geth-pruned-leveldb-hash-events.middlewares=ipallowlist
|
||||||
|
|
||||||
ethereum-mainnet-geth-node:
|
ethereum-mainnet-geth-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 15455:15455
|
- 15455:15455
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ services:
|
|||||||
- traefik.http.routers.ethereum-mainnet-geth-pruned-pebble-path-events.middlewares=ipallowlist
|
- traefik.http.routers.ethereum-mainnet-geth-pruned-pebble-path-events.middlewares=ipallowlist
|
||||||
|
|
||||||
ethereum-mainnet-geth-node:
|
ethereum-mainnet-geth-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 17023:17023
|
- 17023:17023
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ services:
|
|||||||
- traefik.http.routers.ethereum-mainnet-geth-pruned-pebble-path.middlewares=ethereum-mainnet-geth-pruned-pebble-path-stripprefix, ipallowlist
|
- traefik.http.routers.ethereum-mainnet-geth-pruned-pebble-path.middlewares=ethereum-mainnet-geth-pruned-pebble-path-stripprefix, ipallowlist
|
||||||
|
|
||||||
ethereum-mainnet-geth-node:
|
ethereum-mainnet-geth-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 17023:17023
|
- 17023:17023
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ services:
|
|||||||
- traefik.http.routers.ethereum-sepolia-geth-pruned-pebble-path.middlewares=ethereum-sepolia-geth-pruned-pebble-path-stripprefix, ipallowlist
|
- traefik.http.routers.ethereum-sepolia-geth-pruned-pebble-path.middlewares=ethereum-sepolia-geth-pruned-pebble-path-stripprefix, ipallowlist
|
||||||
|
|
||||||
ethereum-sepolia-geth-node:
|
ethereum-sepolia-geth-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_SEPOLIA_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_SEPOLIA_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 19710:19710
|
- 19710:19710
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ services:
|
|||||||
- traefik.http.routers.ethereum-hoodie-nethermind-pruned-rocksdb-trace.middlewares=ethereum-hoodie-nethermind-pruned-rocksdb-trace-stripprefix, ipallowlist
|
- traefik.http.routers.ethereum-hoodie-nethermind-pruned-rocksdb-trace.middlewares=ethereum-hoodie-nethermind-pruned-rocksdb-trace-stripprefix, ipallowlist
|
||||||
|
|
||||||
ethereum-hoodie-nethermind-node:
|
ethereum-hoodie-nethermind-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_HOODIE_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_HOODIE_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 16214:16214
|
- 16214:16214
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ services:
|
|||||||
- traefik.http.routers.ethereum-mainnet-nethermind-pruned-rocksdb-trace.middlewares=ethereum-mainnet-nethermind-pruned-rocksdb-trace-stripprefix, ipallowlist
|
- traefik.http.routers.ethereum-mainnet-nethermind-pruned-rocksdb-trace.middlewares=ethereum-mainnet-nethermind-pruned-rocksdb-trace-stripprefix, ipallowlist
|
||||||
|
|
||||||
ethereum-mainnet-nethermind-node:
|
ethereum-mainnet-nethermind-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 17065:17065
|
- 17065:17065
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ services:
|
|||||||
- traefik.http.routers.ethereum-sepolia-nethermind-pruned-rocksdb-trace.middlewares=ethereum-sepolia-nethermind-pruned-rocksdb-trace-stripprefix, ipallowlist
|
- traefik.http.routers.ethereum-sepolia-nethermind-pruned-rocksdb-trace.middlewares=ethereum-sepolia-nethermind-pruned-rocksdb-trace-stripprefix, ipallowlist
|
||||||
|
|
||||||
ethereum-sepolia-nethermind-node:
|
ethereum-sepolia-nethermind-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_SEPOLIA_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_SEPOLIA_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 15835:15835
|
- 15835:15835
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ services:
|
|||||||
shm_size: 2gb
|
shm_size: 2gb
|
||||||
|
|
||||||
ethereum-mainnet-reth-node:
|
ethereum-mainnet-reth-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 19563:19563
|
- 19563:19563
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ services:
|
|||||||
- pruning
|
- pruning
|
||||||
|
|
||||||
ethereum-mainnet-reth-minimal-node:
|
ethereum-mainnet-reth-minimal-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 19286:19286
|
- 19286:19286
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ services:
|
|||||||
shm_size: 2gb
|
shm_size: 2gb
|
||||||
|
|
||||||
ethereum-mainnet-reth-pruned-node:
|
ethereum-mainnet-reth-pruned-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_MAINNET_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 15150:15150
|
- 15150:15150
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ services:
|
|||||||
shm_size: 2gb
|
shm_size: 2gb
|
||||||
|
|
||||||
ethereum-sepolia-reth-node:
|
ethereum-sepolia-reth-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_SEPOLIA_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_SEPOLIA_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 19330:19330
|
- 19330:19330
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ services:
|
|||||||
shm_size: 2gb
|
shm_size: 2gb
|
||||||
|
|
||||||
ethereum-sepolia-reth-pruned-node:
|
ethereum-sepolia-reth-pruned-node:
|
||||||
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_SEPOLIA_NIMBUS_VERSION:-multiarch-v26.6.0}
|
image: ${ETHEREUM_NIMBUS_IMAGE:-statusim/nimbus-eth2}:${ETHEREUM_SEPOLIA_NIMBUS_VERSION:-multiarch-v26.6.2}
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 17150:17150
|
- 17150:17150
|
||||||
|
|||||||
@@ -90,13 +90,26 @@ services:
|
|||||||
ulimits:
|
ulimits:
|
||||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||||
user: 1000:1000
|
user: 1000:1000
|
||||||
|
ports:
|
||||||
|
- 12008:19000
|
||||||
expose:
|
expose:
|
||||||
- 18100
|
- 18100
|
||||||
- 18200
|
- 18200
|
||||||
- 19000
|
- 19000
|
||||||
environment:
|
environment:
|
||||||
|
- ADVERTISE_NODE_IP=${IP}
|
||||||
|
- ADVERTISE_NODE_PORT=12008
|
||||||
- EXTERNAL_CLB_PRE_EXPOSERPC_URL=noise_tcp://47.83.131.74:52398?842016e6eb94da561b1b4c856e08bf71cd70c05ea847e934b8be1d5a74a979f8;noise_tcp://47.83.131.74:52399?ce08efde90a7970d18dd6763fdc68d19a24084fd7c8cf67a68a19e943b30c5e3
|
- EXTERNAL_CLB_PRE_EXPOSERPC_URL=noise_tcp://47.83.131.74:52398?842016e6eb94da561b1b4c856e08bf71cd70c05ea847e934b8be1d5a74a979f8;noise_tcp://47.83.131.74:52399?ce08efde90a7970d18dd6763fdc68d19a24084fd7c8cf67a68a19e943b30c5e3
|
||||||
- SEQUENCER_ADVERTISE_NODE_URL=alb-cnjrn9zqms3o5flehu.cn-hongkong.alb.aliyuncsslbintl.com:80
|
- SEQUENCER_ADVERTISE_NODE_URL=alb-cnjrn9zqms3o5flehu.cn-hongkong.alb.aliyuncsslbintl.com:80
|
||||||
|
entrypoint: [/tini, --, /bin/bash, -c]
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
cp /opt/l2_deploy/conf/VERSION /opt/l2_deploy/bin/VERSION
|
||||||
|
mkdir -p /opt/l2_deploy/light/log
|
||||||
|
touch /opt/l2_deploy/light/log/aldaba.log /opt/l2_deploy/light/log/cubenet.log
|
||||||
|
tail -n0 -F /opt/l2_deploy/light/log/aldaba.log /opt/l2_deploy/light/log/cubenet.log &
|
||||||
|
exec /opt/entry.sh
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
stop_grace_period: 5m
|
stop_grace_period: 5m
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -108,11 +121,6 @@ services:
|
|||||||
- ${JOVAY_MAINNET_ALDABA_PRUNED_CONF:-jovay-mainnet-aldaba-pruned_conf}:/opt/l2_deploy/conf
|
- ${JOVAY_MAINNET_ALDABA_PRUNED_CONF:-jovay-mainnet-aldaba-pruned_conf}:/opt/l2_deploy/conf
|
||||||
- ${JOVAY_MAINNET_ALDABA_PRUNED_DATA:-jovay-mainnet-aldaba-pruned}:/opt/l2_deploy/light/data
|
- ${JOVAY_MAINNET_ALDABA_PRUNED_DATA:-jovay-mainnet-aldaba-pruned}:/opt/l2_deploy/light/data
|
||||||
- ${JOVAY_MAINNET_ALDABA_PRUNED_LOG:-jovay-mainnet-aldaba-pruned_log}:/opt/l2_deploy/light/log
|
- ${JOVAY_MAINNET_ALDABA_PRUNED_LOG:-jovay-mainnet-aldaba-pruned_log}:/opt/l2_deploy/light/log
|
||||||
- type: volume
|
|
||||||
source: ${JOVAY_MAINNET_ALDABA_PRUNED_CONF:-jovay-mainnet-aldaba-pruned_conf}
|
|
||||||
target: /opt/l2_deploy/bin/VERSION
|
|
||||||
volume:
|
|
||||||
subpath: VERSION
|
|
||||||
- /slowdisk:/slowdisk
|
- /slowdisk:/slowdisk
|
||||||
logging: *logging-defaults
|
logging: *logging-defaults
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -90,13 +90,26 @@ services:
|
|||||||
ulimits:
|
ulimits:
|
||||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||||
user: 1000:1000
|
user: 1000:1000
|
||||||
|
ports:
|
||||||
|
- 13442:19000
|
||||||
expose:
|
expose:
|
||||||
- 18100
|
- 18100
|
||||||
- 18200
|
- 18200
|
||||||
- 19000
|
- 19000
|
||||||
environment:
|
environment:
|
||||||
|
- ADVERTISE_NODE_IP=${IP}
|
||||||
|
- ADVERTISE_NODE_PORT=13442
|
||||||
- EXTERNAL_CLB_PRE_EXPOSERPC_URL=noise_tcp://43.106.17.221:52399?2d655725a449ef9f5f1b048d596736c0e4aaaac3fd9b6bd3f7eef5dee8517d7d;noise_tcp://43.106.17.221:52398?c9664991ff25fd390f10d29c1e024594067f4e00ef470388e89f29bd9a403d23
|
- EXTERNAL_CLB_PRE_EXPOSERPC_URL=noise_tcp://43.106.17.221:52399?2d655725a449ef9f5f1b048d596736c0e4aaaac3fd9b6bd3f7eef5dee8517d7d;noise_tcp://43.106.17.221:52398?c9664991ff25fd390f10d29c1e024594067f4e00ef470388e89f29bd9a403d23
|
||||||
- SEQUENCER_ADVERTISE_NODE_URL=alb-ism8q21lfjeen07hq3.ap-southeast-1.alb.aliyuncsslbintl.com:80
|
- SEQUENCER_ADVERTISE_NODE_URL=alb-ism8q21lfjeen07hq3.ap-southeast-1.alb.aliyuncsslbintl.com:80
|
||||||
|
entrypoint: [/tini, --, /bin/bash, -c]
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
cp /opt/l2_deploy/conf/VERSION /opt/l2_deploy/bin/VERSION
|
||||||
|
mkdir -p /opt/l2_deploy/light/log
|
||||||
|
touch /opt/l2_deploy/light/log/aldaba.log /opt/l2_deploy/light/log/cubenet.log
|
||||||
|
tail -n0 -F /opt/l2_deploy/light/log/aldaba.log /opt/l2_deploy/light/log/cubenet.log &
|
||||||
|
exec /opt/entry.sh
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
stop_grace_period: 5m
|
stop_grace_period: 5m
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -108,11 +121,6 @@ services:
|
|||||||
- ${JOVAY_SEPOLIA_ALDABA_PRUNED_CONF:-jovay-sepolia-aldaba-pruned_conf}:/opt/l2_deploy/conf
|
- ${JOVAY_SEPOLIA_ALDABA_PRUNED_CONF:-jovay-sepolia-aldaba-pruned_conf}:/opt/l2_deploy/conf
|
||||||
- ${JOVAY_SEPOLIA_ALDABA_PRUNED_DATA:-jovay-sepolia-aldaba-pruned}:/opt/l2_deploy/light/data
|
- ${JOVAY_SEPOLIA_ALDABA_PRUNED_DATA:-jovay-sepolia-aldaba-pruned}:/opt/l2_deploy/light/data
|
||||||
- ${JOVAY_SEPOLIA_ALDABA_PRUNED_LOG:-jovay-sepolia-aldaba-pruned_log}:/opt/l2_deploy/light/log
|
- ${JOVAY_SEPOLIA_ALDABA_PRUNED_LOG:-jovay-sepolia-aldaba-pruned_log}:/opt/l2_deploy/light/log
|
||||||
- type: volume
|
|
||||||
source: ${JOVAY_SEPOLIA_ALDABA_PRUNED_CONF:-jovay-sepolia-aldaba-pruned_conf}
|
|
||||||
target: /opt/l2_deploy/bin/VERSION
|
|
||||||
volume:
|
|
||||||
subpath: VERSION
|
|
||||||
- /slowdisk:/slowdisk
|
- /slowdisk:/slowdisk
|
||||||
logging: *logging-defaults
|
logging: *logging-defaults
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ services:
|
|||||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||||
user: root
|
user: root
|
||||||
ports:
|
ports:
|
||||||
- 10127:9651
|
- 10127:10127
|
||||||
- 10127:9651/udp
|
- 10127:10127/udp
|
||||||
expose:
|
expose:
|
||||||
- 9650
|
- 9650
|
||||||
environment:
|
environment:
|
||||||
@@ -59,7 +59,7 @@ services:
|
|||||||
- AVAGO_NETWORK_ID=mainnet
|
- AVAGO_NETWORK_ID=mainnet
|
||||||
- AVAGO_PARTIAL_SYNC_PRIMARY_NETWORK=true
|
- AVAGO_PARTIAL_SYNC_PRIMARY_NETWORK=true
|
||||||
- AVAGO_PLUGIN_DIR=/plugins/
|
- AVAGO_PLUGIN_DIR=/plugins/
|
||||||
- AVAGO_STAKING_PORT=9651
|
- AVAGO_STAKING_PORT=10127
|
||||||
- AVAGO_TRACK_SUBNETS=21uUaTxVdR3Sp6SJhpcSrdH1g66aFoE8mPQDvwKJCjXNexo5y6
|
- AVAGO_TRACK_SUBNETS=21uUaTxVdR3Sp6SJhpcSrdH1g66aFoE8mPQDvwKJCjXNexo5y6
|
||||||
- KITE_CHAIN_ID=3USaEfTcoUhHxpKXvpAG916UKCUEyjrtkg2hBArBG3JyDP7my
|
- KITE_CHAIN_ID=3USaEfTcoUhHxpKXvpAG916UKCUEyjrtkg2hBArBG3JyDP7my
|
||||||
- PLUGIN_ID=pJhES6xZkqZxjxMqHiucbpBTTnB97EjL5aTYSynmWBoF26v9e
|
- PLUGIN_ID=pJhES6xZkqZxjxMqHiucbpBTTnB97EjL5aTYSynmWBoF26v9e
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
# ./list-restorable.sh <network> --all <chain> # --all can be in any position
|
# ./list-restorable.sh <network> --all <chain> # --all can be in any position
|
||||||
|
|
||||||
dir="$(dirname "$0")"
|
dir="$(dirname "$0")"
|
||||||
|
source "$dir/volume-utils.sh"
|
||||||
registry_file="${dir}/compose_registry.json"
|
registry_file="${dir}/compose_registry.json"
|
||||||
backup_dir="/backup"
|
backup_dir="/backup"
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ while IFS= read -r entry; do
|
|||||||
while IFS= read -r volume; do
|
while IFS= read -r volume; do
|
||||||
volume_name="rpc_${volume}"
|
volume_name="rpc_${volume}"
|
||||||
# Look for backup files matching pattern: rpc_${volume}-[0-9]*G.tar.zst
|
# Look for backup files matching pattern: rpc_${volume}-[0-9]*G.tar.zst
|
||||||
backup_file=$(ls -1 "$backup_dir"/"${volume_name}"-[0-9]*G.tar.zst 2>/dev/null | sort | tail -n 1)
|
backup_file=$(select_newest_local_backup "$backup_dir" "$volume_name")
|
||||||
|
|
||||||
if [ -z "$backup_file" ]; then
|
if [ -z "$backup_file" ]; then
|
||||||
all_backups_exist=false
|
all_backups_exist=false
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ services:
|
|||||||
- -externalip=${IP}
|
- -externalip=${IP}
|
||||||
- -port=10159
|
- -port=10159
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ services:
|
|||||||
- -externalip=${IP}
|
- -externalip=${IP}
|
||||||
- -port=10051
|
- -port=10051
|
||||||
- -printtoconsole
|
- -printtoconsole
|
||||||
|
- -rpcallowip=0.0.0.0/0
|
||||||
- -rpcallowip=::/0
|
- -rpcallowip=::/0
|
||||||
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
- -rpcauth=username:0b6623bdebb516ced10631668833e42a$$c478b38890678c51b9f013174a20addb317c2046b68c05e0250ff86e31a505f7
|
||||||
- -rpcbind=0.0.0.0
|
- -rpcbind=0.0.0.0
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ services:
|
|||||||
- traefik.http.routers.doma-mainnet-op-geth-pruned-pebble-path-node.middlewares=doma-mainnet-op-geth-pruned-pebble-path-node-stripprefix, ipallowlist
|
- traefik.http.routers.doma-mainnet-op-geth-pruned-pebble-path-node.middlewares=doma-mainnet-op-geth-pruned-pebble-path-node-stripprefix, ipallowlist
|
||||||
|
|
||||||
doma-mainnet-relay:
|
doma-mainnet-relay:
|
||||||
image: ${DOMA_OP_ALT_IMAGE:-ghcr.io/celestiaorg/op-alt-da}:${DOMA_MAINNET_OP_ALT_VERSION:-0.15.0}
|
image: ${DOMA_OP_ALT_IMAGE:-ghcr.io/celestiaorg/op-alt-da}:${DOMA_MAINNET_OP_ALT_VERSION:-0.16.0}
|
||||||
expose:
|
expose:
|
||||||
- 3100
|
- 3100
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
"graniteTime": 0,
|
"graniteTime": 0,
|
||||||
"holoceneTime": 0,
|
"holoceneTime": 0,
|
||||||
"isthmusTime": 1746806401,
|
"isthmusTime": 1746806401,
|
||||||
|
"pragueTime": 1746806401,
|
||||||
|
"osakaTime": 1773066601,
|
||||||
"jovianTime": 1773066601,
|
"jovianTime": 1773066601,
|
||||||
"terminalTotalDifficulty": 0,
|
"terminalTotalDifficulty": 0,
|
||||||
"terminalTotalDifficultyPassed": true,
|
"terminalTotalDifficultyPassed": true,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
katana-mainnet-archive:
|
katana-mainnet-archive:
|
||||||
image: ${KATANA_RETH_IMAGE:-us-docker.pkg.dev/oplabs-tools-artifacts/images/op-reth}:${KATANA_MAINNET_RETH_VERSION:-v2.3.3}
|
image: ${KATANA_RETH_IMAGE:-us-docker.pkg.dev/oplabs-tools-artifacts/images/op-reth}:${KATANA_MAINNET_RETH_VERSION:-develop}
|
||||||
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
|
||||||
@@ -46,6 +46,9 @@ services:
|
|||||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||||
memlock: -1 # Disable memory locking limits (for in-memory DBs like MDBX)
|
memlock: -1 # Disable memory locking limits (for in-memory DBs like MDBX)
|
||||||
user: root
|
user: root
|
||||||
|
ports:
|
||||||
|
- 14265:14265
|
||||||
|
- 14265:14265/udp
|
||||||
expose:
|
expose:
|
||||||
- 8545
|
- 8545
|
||||||
- 9001
|
- 9001
|
||||||
@@ -58,11 +61,12 @@ services:
|
|||||||
- --chain=/config/genesis.json
|
- --chain=/config/genesis.json
|
||||||
- --config=/config/reth/reth.toml
|
- --config=/config/reth/reth.toml
|
||||||
- --datadir=/root/.local/share/reth
|
- --datadir=/root/.local/share/reth
|
||||||
- --disable-discovery
|
|
||||||
- --engine.cross-block-cache-size=${KATANA_MAINNET_RETH_STATE_CACHE:-4096}
|
- --engine.cross-block-cache-size=${KATANA_MAINNET_RETH_STATE_CACHE:-4096}
|
||||||
- --max-inbound-peers=50
|
- --max-inbound-peers=50
|
||||||
- --max-outbound-peers=50
|
- --max-outbound-peers=50
|
||||||
- --metrics=0.0.0.0:9001
|
- --metrics=0.0.0.0:9001
|
||||||
|
- --nat=extip:${IP}
|
||||||
|
- --port=14265
|
||||||
- --rollup.sequencer-http=https://rpc.katana.network
|
- --rollup.sequencer-http=https://rpc.katana.network
|
||||||
- --rpc-cache.max-blocks=10000
|
- --rpc-cache.max-blocks=10000
|
||||||
- --rpc-cache.max-concurrent-db-requests=2048
|
- --rpc-cache.max-concurrent-db-requests=2048
|
||||||
@@ -108,7 +112,7 @@ services:
|
|||||||
shm_size: 2gb
|
shm_size: 2gb
|
||||||
|
|
||||||
katana-mainnet-archive-node:
|
katana-mainnet-archive-node:
|
||||||
image: ${KATANA_NODE_IMAGE:-us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node}:${KATANA_MAINNET_NODE_VERSION:-v1.19.0}
|
image: ${KATANA_NODE_IMAGE:-us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node}:${KATANA_MAINNET_NODE_VERSION:-v1.19.1}
|
||||||
ports:
|
ports:
|
||||||
- 19265:19265
|
- 19265:19265
|
||||||
- 19265:19265/udp
|
- 19265:19265/udp
|
||||||
@@ -138,7 +142,7 @@ services:
|
|||||||
- OP_NODE_RPC_ADDR=0.0.0.0
|
- OP_NODE_RPC_ADDR=0.0.0.0
|
||||||
- OP_NODE_RPC_PORT=9545
|
- OP_NODE_RPC_PORT=9545
|
||||||
- OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log
|
- OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log
|
||||||
- OP_NODE_SYNCMODE=consensus-layer
|
- OP_NODE_SYNCMODE=execution-layer
|
||||||
- OP_NODE_VERIFIER_L1_CONFS=0
|
- OP_NODE_VERIFIER_L1_CONFS=0
|
||||||
entrypoint: [op-node]
|
entrypoint: [op-node]
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ x-logging-defaults: &logging-defaults
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
katana-mainnet:
|
katana-mainnet:
|
||||||
image: ${KATANA_RETH_IMAGE:-us-docker.pkg.dev/oplabs-tools-artifacts/images/op-reth}:${KATANA_MAINNET_RETH_VERSION:-v2.3.3}
|
image: ${KATANA_RETH_IMAGE:-us-docker.pkg.dev/oplabs-tools-artifacts/images/op-reth}:${KATANA_MAINNET_RETH_VERSION:-develop}
|
||||||
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
|
||||||
@@ -46,6 +46,9 @@ services:
|
|||||||
nofile: 1048576 # Max open files (for RPC/WS connections)
|
nofile: 1048576 # Max open files (for RPC/WS connections)
|
||||||
memlock: -1 # Disable memory locking limits (for in-memory DBs like MDBX)
|
memlock: -1 # Disable memory locking limits (for in-memory DBs like MDBX)
|
||||||
user: root
|
user: root
|
||||||
|
ports:
|
||||||
|
- 13767:13767
|
||||||
|
- 13767:13767/udp
|
||||||
expose:
|
expose:
|
||||||
- 8545
|
- 8545
|
||||||
- 9001
|
- 9001
|
||||||
@@ -58,12 +61,13 @@ services:
|
|||||||
- --chain=/config/genesis.json
|
- --chain=/config/genesis.json
|
||||||
- --config=/config/reth/reth.toml
|
- --config=/config/reth/reth.toml
|
||||||
- --datadir=/root/.local/share/reth
|
- --datadir=/root/.local/share/reth
|
||||||
- --disable-discovery
|
|
||||||
- --engine.cross-block-cache-size=${KATANA_MAINNET_RETH_STATE_CACHE:-4096}
|
- --engine.cross-block-cache-size=${KATANA_MAINNET_RETH_STATE_CACHE:-4096}
|
||||||
- --full
|
- --full
|
||||||
- --max-inbound-peers=50
|
- --max-inbound-peers=50
|
||||||
- --max-outbound-peers=50
|
- --max-outbound-peers=50
|
||||||
- --metrics=0.0.0.0:9001
|
- --metrics=0.0.0.0:9001
|
||||||
|
- --nat=extip:${IP}
|
||||||
|
- --port=13767
|
||||||
- --rollup.sequencer-http=https://rpc.katana.network
|
- --rollup.sequencer-http=https://rpc.katana.network
|
||||||
- --rpc-cache.max-blocks=10000
|
- --rpc-cache.max-blocks=10000
|
||||||
- --rpc-cache.max-concurrent-db-requests=2048
|
- --rpc-cache.max-concurrent-db-requests=2048
|
||||||
@@ -109,7 +113,7 @@ services:
|
|||||||
shm_size: 2gb
|
shm_size: 2gb
|
||||||
|
|
||||||
katana-mainnet-node:
|
katana-mainnet-node:
|
||||||
image: ${KATANA_NODE_IMAGE:-us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node}:${KATANA_MAINNET_NODE_VERSION:-v1.19.0}
|
image: ${KATANA_NODE_IMAGE:-us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node}:${KATANA_MAINNET_NODE_VERSION:-v1.19.1}
|
||||||
ports:
|
ports:
|
||||||
- 18767:18767
|
- 18767:18767
|
||||||
- 18767:18767/udp
|
- 18767:18767/udp
|
||||||
@@ -139,7 +143,7 @@ services:
|
|||||||
- OP_NODE_RPC_ADDR=0.0.0.0
|
- OP_NODE_RPC_ADDR=0.0.0.0
|
||||||
- OP_NODE_RPC_PORT=9545
|
- OP_NODE_RPC_PORT=9545
|
||||||
- OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log
|
- OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log
|
||||||
- OP_NODE_SYNCMODE=consensus-layer
|
- OP_NODE_SYNCMODE=execution-layer
|
||||||
- OP_NODE_VERIFIER_L1_CONFS=0
|
- OP_NODE_VERIFIER_L1_CONFS=0
|
||||||
entrypoint: [op-node]
|
entrypoint: [op-node]
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ services:
|
|||||||
- OP_NODE_P2P_LISTEN_TCP_PORT=19792
|
- OP_NODE_P2P_LISTEN_TCP_PORT=19792
|
||||||
- OP_NODE_P2P_LISTEN_UDP_PORT=19792
|
- OP_NODE_P2P_LISTEN_UDP_PORT=19792
|
||||||
- OP_NODE_P2P_STATIC=/ip4/34.11.218.92/tcp/9222/p2p/16Uiu2HAm2wpj12oJjJJS3EwkpCMMJBw5FvbKivQLLC9TzMmh456G
|
- OP_NODE_P2P_STATIC=/ip4/34.11.218.92/tcp/9222/p2p/16Uiu2HAm2wpj12oJjJJS3EwkpCMMJBw5FvbKivQLLC9TzMmh456G
|
||||||
- OP_NODE_P2P_SYNC_ONLYREQTOSTATIC=true
|
- OP_NODE_P2P_SYNC_ONLYREQTOSTATIC=false
|
||||||
- OP_NODE_ROLLUP_CONFIG=/config/rollup.json
|
- OP_NODE_ROLLUP_CONFIG=/config/rollup.json
|
||||||
- OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true
|
- OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true
|
||||||
- OP_NODE_RPC_ADDR=0.0.0.0
|
- OP_NODE_RPC_ADDR=0.0.0.0
|
||||||
|
|||||||
@@ -3394,6 +3394,7 @@
|
|||||||
"lagging_lag": 20,
|
"lagging_lag": 20,
|
||||||
"syncing_lag": 40,
|
"syncing_lag": 40,
|
||||||
"urls": [
|
"urls": [
|
||||||
|
"https://rpc.mainnet.chain.robinhood.com",
|
||||||
"https://robinhood.drpc.org"
|
"https://robinhood.drpc.org"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -3409,7 +3410,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tac": {
|
"tac": {
|
||||||
"protocol": "eth",
|
"protocol": "cosmos",
|
||||||
"id": 239,
|
"id": 239,
|
||||||
"block_time_ms": 1000,
|
"block_time_ms": 1000,
|
||||||
"lagging_lag": 2,
|
"lagging_lag": 2,
|
||||||
@@ -3422,7 +3423,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tac-spb": {
|
"tac-spb": {
|
||||||
"protocol": "eth",
|
"protocol": "cosmos",
|
||||||
"id": 2391,
|
"id": 2391,
|
||||||
"block_time_ms": 1000,
|
"block_time_ms": 1000,
|
||||||
"lagging_lag": 2,
|
"lagging_lag": 2,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ set -- "${_pos[@]}"
|
|||||||
[ -f "$dir/.env" ] && source "$dir/.env"
|
[ -f "$dir/.env" ] && source "$dir/.env"
|
||||||
SLOWDISK="${SLOWDISK:-}"
|
SLOWDISK="${SLOWDISK:-}"
|
||||||
[ "$no_slowdisk_flag" = 1 ] && SLOWDISK=False
|
[ "$no_slowdisk_flag" = 1 ] && SLOWDISK=False
|
||||||
|
SLOWDISK_FLOOR_GB="${SLOWDISK_FLOOR_GB:-150}"
|
||||||
|
|
||||||
remote_source="$2"
|
remote_source="$2"
|
||||||
if [[ -n "$remote_source" ]] && is_local_backup_url "$remote_source"; then
|
if [[ -n "$remote_source" ]] && is_local_backup_url "$remote_source"; then
|
||||||
@@ -46,15 +47,71 @@ fi
|
|||||||
# GATED on SLOWDISK (see top): offload runs only when SLOWDISK is the Python-templated boolean
|
# GATED on SLOWDISK (see top): offload runs only when SLOWDISK is the Python-templated boolean
|
||||||
# "True" (set in the host .env on dedicated-extra-disk hosts) and the --no-slowdisk flag was
|
# "True" (set in the host .env on dedicated-extra-disk hosts) and the --no-slowdisk flag was
|
||||||
# not passed. Case matters — the value comes through as capitalized "True"/"False". Safe
|
# not passed. Case matters — the value comes through as capitalized "True"/"False". Safe
|
||||||
# fallbacks (normal extract): SLOWDISK not True, /slowdisk missing, no manifest, no static paths.
|
# fallbacks (normal extract): SLOWDISK not True, /slowdisk missing, no manifest, no static paths,
|
||||||
|
# or slowdisk free space below SLOWDISK_FLOOR_GB after projected static payload.
|
||||||
|
slowdisk_free_gb() {
|
||||||
|
local free
|
||||||
|
free=$(df -BG /slowdisk 2>/dev/null | awk 'NR==2 {gsub(/G/,"",$4); print $4}')
|
||||||
|
[ -n "$free" ] && [[ "$free" =~ ^[0-9]+$ ]] || return 1
|
||||||
|
echo "$free"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Best cheap size signal for incoming static payload: backup archive bytes (local stat or
|
||||||
|
# remote Content-Length). Archive is compressed (.tar.zst); treat size as a LOWER bound and
|
||||||
|
# assume ~2x when estimating uncompressed footprint on /slowdisk.
|
||||||
|
backup_archive_bytes() {
|
||||||
|
local newest_file=$1
|
||||||
|
if [[ -n "$remote_source" ]]; then
|
||||||
|
local cached="$backup_dir/$(basename "$newest_file")"
|
||||||
|
if [[ -f "$cached" && ! -e "${cached}.aria2" ]]; then
|
||||||
|
stat -c%s "$cached" 2>/dev/null && return 0
|
||||||
|
fi
|
||||||
|
curl --ipv4 -fsSI "${remote_source}${newest_file}" 2>/dev/null \
|
||||||
|
| awk -F': ' 'tolower($1)=="content-length" {gsub(/\r/,"",$2); print $2; exit}'
|
||||||
|
else
|
||||||
|
stat -c%s "$newest_file" 2>/dev/null
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pre-extract floor gate: return 0 if offload may proceed, 1 to fall back to primary extract.
|
||||||
|
slowdisk_floor_allows_offload() {
|
||||||
|
local newest_file=$1 archive_bytes need_gb free_gb floor_gb
|
||||||
|
floor_gb="${SLOWDISK_FLOOR_GB:-150}"
|
||||||
|
free_gb=$(slowdisk_free_gb) || return 0
|
||||||
|
archive_bytes=$(backup_archive_bytes "$newest_file")
|
||||||
|
if [[ -z "$archive_bytes" || ! "$archive_bytes" =~ ^[0-9]+$ ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
# ~2x uncompressed factor (archive is compressed zstd tar)
|
||||||
|
need_gb=$(( (archive_bytes * 2 + 1024*1024*1024 - 1) / (1024*1024*1024) ))
|
||||||
|
if (( free_gb - need_gb < floor_gb )); then
|
||||||
|
echo "slowdisk floor gate: skipping offload (free ${free_gb} GB, projected need ${need_gb} GB, floor ${floor_gb} GB) — extracting to primary"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
warn_slowdisk_floor_breach() {
|
||||||
|
local free_gb floor_gb
|
||||||
|
floor_gb="${SLOWDISK_FLOOR_GB:-150}"
|
||||||
|
free_gb=$(slowdisk_free_gb) || return 0
|
||||||
|
if (( free_gb < floor_gb )); then
|
||||||
|
echo "WARNING: slowdisk floor breach after static offload (free ${free_gb} GB < floor ${floor_gb} GB) — OS headroom compromised"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
prep_static_offload() {
|
prep_static_offload() {
|
||||||
local key=$1 meta=$2 data_dir=$3 rel target
|
local key=$1 meta=$2 data_dir=$3 newest_file=$4 rel target
|
||||||
case "$SLOWDISK" in
|
case "$SLOWDISK" in
|
||||||
True|true) ;; # offload enabled (Python "True"; also accept manual lowercase "true")
|
True|true) ;; # offload enabled (Python "True"; also accept manual lowercase "true")
|
||||||
*) echo " static offload disabled (SLOWDISK=$SLOWDISK) — normal extract"; return 0 ;;
|
*) echo " static offload disabled (SLOWDISK=$SLOWDISK) — normal extract"; return 0 ;;
|
||||||
esac
|
esac
|
||||||
[ -d /slowdisk ] || { echo " /slowdisk absent — no static offload"; return 0; }
|
[ -d /slowdisk ] || { echo " /slowdisk absent — no static offload"; return 0; }
|
||||||
[ -f "$meta" ] || { echo " no manifest ($meta) — no static offload"; return 0; }
|
[ -f "$meta" ] || { echo " no manifest ($meta) — no static offload"; return 0; }
|
||||||
|
if ! slowdisk_floor_allows_offload "$newest_file"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
static_offload_used=1
|
||||||
# manifest data lines (after the 3-line header) are "<size> <relpath>"
|
# manifest data lines (after the 3-line header) are "<size> <relpath>"
|
||||||
while IFS= read -r rel; do
|
while IFS= read -r rel; do
|
||||||
[ -z "$rel" ] && continue
|
[ -z "$rel" ] && continue
|
||||||
@@ -78,9 +135,9 @@ while IFS= read -r key; do
|
|||||||
declare newest_file
|
declare newest_file
|
||||||
|
|
||||||
if [[ -n "$remote_source" ]]; then
|
if [[ -n "$remote_source" ]]; then
|
||||||
newest_file=$($dir/list-backups.sh "$remote_source" | grep "rpc_$key-20" | sort | tail -n 1)
|
newest_file=$($dir/list-backups.sh "$remote_source" | select_newest_remote_backup_from_list "$remote_source" "rpc_$key")
|
||||||
else
|
else
|
||||||
newest_file=$(ls -1 "$backup_dir"/"rpc_$key"-[0-9]*G.tar.zst 2>/dev/null | sort | tail -n 1)
|
newest_file=$(select_newest_local_backup "$backup_dir" "rpc_$key")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$newest_file" ]; then
|
if [ -z "$newest_file" ]; then
|
||||||
@@ -89,6 +146,7 @@ while IFS= read -r key; do
|
|||||||
fi
|
fi
|
||||||
meta_file="${newest_file%.tar.zst}.txt"
|
meta_file="${newest_file%.tar.zst}.txt"
|
||||||
echo "=== restoring rpc_$key <- $newest_file ==="
|
echo "=== restoring rpc_$key <- $newest_file ==="
|
||||||
|
static_offload_used=0
|
||||||
|
|
||||||
# 1) wipe live data AND any /slowdisk static targets for this key (no leak on re-restore)
|
# 1) wipe live data AND any /slowdisk static targets for this key (no leak on re-restore)
|
||||||
delete_slowdisk_targets_for_key "$key"
|
delete_slowdisk_targets_for_key "$key"
|
||||||
@@ -108,7 +166,7 @@ while IFS= read -r key; do
|
|||||||
if [[ "$1" == *reth* ]]; then
|
if [[ "$1" == *reth* ]]; then
|
||||||
echo " reth node: static-file symlink offload disabled (reth broke whole-dir symlinks)"
|
echo " reth node: static-file symlink offload disabled (reth broke whole-dir symlinks)"
|
||||||
elif [ -n "$local_meta" ]; then
|
elif [ -n "$local_meta" ]; then
|
||||||
prep_static_offload "$key" "$local_meta" "$data_dir"
|
prep_static_offload "$key" "$local_meta" "$data_dir" "$newest_file"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 3) extract THROUGH the pre-created symlinks (keep them, don't clobber)
|
# 3) extract THROUGH the pre-created symlinks (keep them, don't clobber)
|
||||||
@@ -138,6 +196,9 @@ while IFS= read -r key; do
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if [ "$static_offload_used" = 1 ]; then
|
||||||
|
warn_slowdisk_floor_breach
|
||||||
|
fi
|
||||||
echo "Backup '$newest_file' restored"
|
echo "Backup '$newest_file' restored"
|
||||||
done <<< "$keys"
|
done <<< "$keys"
|
||||||
|
|
||||||
|
|||||||
13
start.sh
13
start.sh
@@ -5,4 +5,15 @@ if [ -z "$1" ] || [ ! -f "/root/rpc/$1.yml" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
docker compose up -d $(cat /root/rpc/$1.yml | yaml2json - | jq '.services' | jq -r 'keys[]' | tr '\n' ' ')
|
services=$(cat "/root/rpc/$1.yml" | yaml2json - | jq '.services' | jq -r 'keys[]' | tr '\n' ' ')
|
||||||
|
if [ -z "$services" ]; then
|
||||||
|
echo "FATAL: no services found in /root/rpc/$1.yml" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker compose -f /root/rpc/base.yml -f "/root/rpc/$1.yml" up -d $services
|
||||||
|
rc=$?
|
||||||
|
if [ $rc -ne 0 ]; then
|
||||||
|
echo "FATAL: docker compose up failed for $1 (exit $rc)" >&2
|
||||||
|
exit $rc
|
||||||
|
fi
|
||||||
|
|||||||
13
stop.sh
13
stop.sh
@@ -5,4 +5,15 @@ if [ -z "$1" ] || [ ! -f "/root/rpc/$1.yml" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
docker compose stop $(cat /root/rpc/$1.yml | yaml2json - | jq '.services' | jq -r 'keys[]' | tr '\n' ' ')
|
services=$(cat "/root/rpc/$1.yml" | yaml2json - | jq '.services' | jq -r 'keys[]' | tr '\n' ' ')
|
||||||
|
if [ -z "$services" ]; then
|
||||||
|
echo "FATAL: no services found in /root/rpc/$1.yml" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker compose -f /root/rpc/base.yml -f "/root/rpc/$1.yml" stop $services
|
||||||
|
rc=$?
|
||||||
|
if [ $rc -ne 0 ]; then
|
||||||
|
echo "FATAL: docker compose stop failed for $1 (exit $rc)" >&2
|
||||||
|
exit $rc
|
||||||
|
fi
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ HOME_DIR="/root/.tacchaind"
|
|||||||
CONFIG_DIR="$HOME_DIR/config"
|
CONFIG_DIR="$HOME_DIR/config"
|
||||||
CHAIN_ID="${CHAIN_ID:-tacchain_239-1}"
|
CHAIN_ID="${CHAIN_ID:-tacchain_239-1}"
|
||||||
GENESIS_URL="${GENESIS_URL:-https://raw.githubusercontent.com/TacBuild/tacchain/refs/heads/main/networks/tacchain_239-1/genesis.json}"
|
GENESIS_URL="${GENESIS_URL:-https://raw.githubusercontent.com/TacBuild/tacchain/refs/heads/main/networks/tacchain_239-1/genesis.json}"
|
||||||
STATESYNC_RPC="${STATESYNC_RPC:-https://tendermint.rpc.tac.build}"
|
STATESYNC_RPC="${STATESYNC_RPC:-https://tacchain-rpc.polkachu.com:443}"
|
||||||
MIN_GAS="${MIN_GAS:-25000000000utac}"
|
MIN_GAS="${MIN_GAS:-25000000000utac}"
|
||||||
API="${API:-eth,net,web3,txpool,debug}"
|
API="${API:-eth,net,web3,txpool,debug}"
|
||||||
MONIKER="${MONIKER:-rpc-node}"
|
MONIKER="${MONIKER:-rpc-node}"
|
||||||
@@ -24,7 +24,11 @@ else
|
|||||||
ct_log "already initialized, continuing"
|
ct_log "already initialized, continuing"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Serve CometBFT RPC on all interfaces (dshackle/traefik upstream); default is 127.0.0.1.
|
||||||
|
sed -i '/^\[rpc\]/,/^\[/{s|^laddr = .*|laddr = "tcp://0.0.0.0:26657"|}' "$CONFIG_DIR/config.toml"
|
||||||
|
|
||||||
ct_patch_p2p "$CONFIG_DIR/config.toml" "$IP" "${P2P_PORT:-26656}"
|
ct_patch_p2p "$CONFIG_DIR/config.toml" "$IP" "${P2P_PORT:-26656}"
|
||||||
|
ct_merge_seeds "$CONFIG_DIR/config.toml" "$SEEDS"
|
||||||
ct_set_persistent_peers "$CONFIG_DIR/config.toml" "$PERSISTENT_PEERS"
|
ct_set_persistent_peers "$CONFIG_DIR/config.toml" "$PERSISTENT_PEERS"
|
||||||
ct_set_moniker "$CONFIG_DIR/config.toml" "$MONIKER"
|
ct_set_moniker "$CONFIG_DIR/config.toml" "$MONIKER"
|
||||||
ct_configure_statesync "$CONFIG_DIR/config.toml" "$STATESYNC_RPC"
|
ct_configure_statesync "$CONFIG_DIR/config.toml" "$STATESYNC_RPC"
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ services:
|
|||||||
- 10283:10283
|
- 10283:10283
|
||||||
- 10283:10283/udp
|
- 10283:10283/udp
|
||||||
expose:
|
expose:
|
||||||
- 8545
|
- 26657
|
||||||
- 8546
|
|
||||||
- 6065
|
- 6065
|
||||||
environment:
|
environment:
|
||||||
- API=eth,net,web3,txpool,debug
|
- API=eth,net,web3,txpool,debug
|
||||||
@@ -64,8 +63,9 @@ services:
|
|||||||
- MIN_GAS=25000000000utac
|
- MIN_GAS=25000000000utac
|
||||||
- MONIKER=d${DOMAIN:-local}
|
- MONIKER=d${DOMAIN:-local}
|
||||||
- P2P_PORT=10283
|
- P2P_PORT=10283
|
||||||
- PERSISTENT_PEERS=d0a80c43a10a6b60475864728db6d9ba4ead42d2@107.6.113.60:58960,10550a03e4f7fa487c78fbd07e0770e2b0f085c7@64.46.115.78:58960,0efae9d157f0ef60ad7d25507d6939799f832e34@173.244.202.99:58960,78079166d06e345dbf4a5c932ee3c69a04148e92@107.6.91.38:58960
|
- PERSISTENT_PEERS=68b409519dea2a057d93ab6df436f6d519f13cb8@65.109.61.125:32156,186e207d2c95e94a44ff613770aa269dac876013@65.108.201.240:32156,c4410e765acead36188500ed75d5666aa209c93d@65.108.205.121:32156
|
||||||
- STATESYNC_RPC=https://tendermint.rpc.tac.build
|
- SEEDS=68b409519dea2a057d93ab6df436f6d519f13cb8@65.109.61.125:32156
|
||||||
|
- STATESYNC_RPC=https://tacchain-rpc.polkachu.com:443
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
stop_grace_period: 5m
|
stop_grace_period: 5m
|
||||||
networks:
|
networks:
|
||||||
@@ -81,7 +81,7 @@ services:
|
|||||||
- prometheus-scrape.path=/metrics
|
- prometheus-scrape.path=/metrics
|
||||||
- traefik.enable=true
|
- traefik.enable=true
|
||||||
- traefik.http.middlewares.tac-mainnet-tacchaind-pruned-stripprefix.stripprefix.prefixes=/tac-mainnet
|
- traefik.http.middlewares.tac-mainnet-tacchaind-pruned-stripprefix.stripprefix.prefixes=/tac-mainnet
|
||||||
- traefik.http.services.tac-mainnet-tacchaind-pruned.loadbalancer.server.port=8545
|
- traefik.http.services.tac-mainnet-tacchaind-pruned.loadbalancer.server.port=26657
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned.entrypoints=websecure}
|
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned.entrypoints=websecure}
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned.tls.certresolver=myresolver}
|
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned.tls.certresolver=myresolver}
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned.rule=Host(`$DOMAIN`) && (Path(`/tac-mainnet`) || Path(`/tac-mainnet/`))}
|
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned.rule=Host(`$DOMAIN`) && (Path(`/tac-mainnet`) || Path(`/tac-mainnet/`))}
|
||||||
@@ -89,14 +89,15 @@ services:
|
|||||||
- traefik.http.routers.tac-mainnet-tacchaind-pruned.middlewares=tac-mainnet-tacchaind-pruned-stripprefix, ipallowlist
|
- traefik.http.routers.tac-mainnet-tacchaind-pruned.middlewares=tac-mainnet-tacchaind-pruned-stripprefix, ipallowlist
|
||||||
- traefik.http.routers.tac-mainnet-tacchaind-pruned.priority=50 # gets any request that is not GET with UPGRADE header
|
- traefik.http.routers.tac-mainnet-tacchaind-pruned.priority=50 # gets any request that is not GET with UPGRADE header
|
||||||
- traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.priority=100 # answers GET requests first
|
- traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.priority=100 # answers GET requests first
|
||||||
- traefik.http.services.tac-mainnet-tacchaind-pruned-ws.loadbalancer.server.port=8546
|
- traefik.http.middlewares.tac-mainnet-tacchaind-pruned-set-ws-path.replacepath.path=/websocket
|
||||||
|
- traefik.http.services.tac-mainnet-tacchaind-pruned-ws.loadbalancer.server.port=26657
|
||||||
- traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.service=tac-mainnet-tacchaind-pruned-ws
|
- traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.service=tac-mainnet-tacchaind-pruned-ws
|
||||||
- traefik.http.routers.tac-mainnet-tacchaind-pruned.service=tac-mainnet-tacchaind-pruned
|
- traefik.http.routers.tac-mainnet-tacchaind-pruned.service=tac-mainnet-tacchaind-pruned
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.entrypoints=websecure}
|
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.entrypoints=websecure}
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.tls.certresolver=myresolver}
|
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.tls.certresolver=myresolver}
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.rule=Host(`$DOMAIN`) && (Path(`/tac-mainnet`) || Path(`/tac-mainnet/`)) && HeadersRegexp(`Upgrade`, `(?i)websocket`)}
|
- ${NO_SSL:-traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.rule=Host(`$DOMAIN`) && (Path(`/tac-mainnet`) || Path(`/tac-mainnet/`)) && HeadersRegexp(`Upgrade`, `(?i)websocket`)}
|
||||||
- ${NO_SSL:+traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.rule=(Path(`/tac-mainnet`) || Path(`/tac-mainnet/`)) && HeadersRegexp(`Upgrade`, `(?i)websocket`)}
|
- ${NO_SSL:+traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.rule=(Path(`/tac-mainnet`) || Path(`/tac-mainnet/`)) && HeadersRegexp(`Upgrade`, `(?i)websocket`)}
|
||||||
- traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.middlewares=tac-mainnet-tacchaind-pruned-stripprefix, ipallowlist
|
- traefik.http.routers.tac-mainnet-tacchaind-pruned-ws.middlewares=tac-mainnet-tacchaind-pruned-stripprefix, tac-mainnet-tacchaind-pruned-set-ws-path, ipallowlist
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
tac-mainnet-tacchaind-pruned:
|
tac-mainnet-tacchaind-pruned:
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ services:
|
|||||||
- 14331:14331
|
- 14331:14331
|
||||||
- 14331:14331/udp
|
- 14331:14331/udp
|
||||||
expose:
|
expose:
|
||||||
- 8545
|
- 26657
|
||||||
- 8546
|
|
||||||
- 6065
|
- 6065
|
||||||
environment:
|
environment:
|
||||||
- API=eth,net,web3,txpool,debug
|
- API=eth,net,web3,txpool,debug
|
||||||
@@ -81,7 +80,7 @@ services:
|
|||||||
- prometheus-scrape.path=/metrics
|
- prometheus-scrape.path=/metrics
|
||||||
- traefik.enable=true
|
- traefik.enable=true
|
||||||
- traefik.http.middlewares.tac-spb-tacchaind-pruned-stripprefix.stripprefix.prefixes=/tac-spb
|
- traefik.http.middlewares.tac-spb-tacchaind-pruned-stripprefix.stripprefix.prefixes=/tac-spb
|
||||||
- traefik.http.services.tac-spb-tacchaind-pruned.loadbalancer.server.port=8545
|
- traefik.http.services.tac-spb-tacchaind-pruned.loadbalancer.server.port=26657
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned.entrypoints=websecure}
|
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned.entrypoints=websecure}
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned.tls.certresolver=myresolver}
|
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned.tls.certresolver=myresolver}
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned.rule=Host(`$DOMAIN`) && (Path(`/tac-spb`) || Path(`/tac-spb/`))}
|
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned.rule=Host(`$DOMAIN`) && (Path(`/tac-spb`) || Path(`/tac-spb/`))}
|
||||||
@@ -89,14 +88,15 @@ services:
|
|||||||
- traefik.http.routers.tac-spb-tacchaind-pruned.middlewares=tac-spb-tacchaind-pruned-stripprefix, ipallowlist
|
- traefik.http.routers.tac-spb-tacchaind-pruned.middlewares=tac-spb-tacchaind-pruned-stripprefix, ipallowlist
|
||||||
- traefik.http.routers.tac-spb-tacchaind-pruned.priority=50 # gets any request that is not GET with UPGRADE header
|
- traefik.http.routers.tac-spb-tacchaind-pruned.priority=50 # gets any request that is not GET with UPGRADE header
|
||||||
- traefik.http.routers.tac-spb-tacchaind-pruned-ws.priority=100 # answers GET requests first
|
- traefik.http.routers.tac-spb-tacchaind-pruned-ws.priority=100 # answers GET requests first
|
||||||
- traefik.http.services.tac-spb-tacchaind-pruned-ws.loadbalancer.server.port=8546
|
- traefik.http.middlewares.tac-spb-tacchaind-pruned-set-ws-path.replacepath.path=/websocket
|
||||||
|
- traefik.http.services.tac-spb-tacchaind-pruned-ws.loadbalancer.server.port=26657
|
||||||
- traefik.http.routers.tac-spb-tacchaind-pruned-ws.service=tac-spb-tacchaind-pruned-ws
|
- traefik.http.routers.tac-spb-tacchaind-pruned-ws.service=tac-spb-tacchaind-pruned-ws
|
||||||
- traefik.http.routers.tac-spb-tacchaind-pruned.service=tac-spb-tacchaind-pruned
|
- traefik.http.routers.tac-spb-tacchaind-pruned.service=tac-spb-tacchaind-pruned
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned-ws.entrypoints=websecure}
|
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned-ws.entrypoints=websecure}
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned-ws.tls.certresolver=myresolver}
|
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned-ws.tls.certresolver=myresolver}
|
||||||
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned-ws.rule=Host(`$DOMAIN`) && (Path(`/tac-spb`) || Path(`/tac-spb/`)) && HeadersRegexp(`Upgrade`, `(?i)websocket`)}
|
- ${NO_SSL:-traefik.http.routers.tac-spb-tacchaind-pruned-ws.rule=Host(`$DOMAIN`) && (Path(`/tac-spb`) || Path(`/tac-spb/`)) && HeadersRegexp(`Upgrade`, `(?i)websocket`)}
|
||||||
- ${NO_SSL:+traefik.http.routers.tac-spb-tacchaind-pruned-ws.rule=(Path(`/tac-spb`) || Path(`/tac-spb/`)) && HeadersRegexp(`Upgrade`, `(?i)websocket`)}
|
- ${NO_SSL:+traefik.http.routers.tac-spb-tacchaind-pruned-ws.rule=(Path(`/tac-spb`) || Path(`/tac-spb/`)) && HeadersRegexp(`Upgrade`, `(?i)websocket`)}
|
||||||
- traefik.http.routers.tac-spb-tacchaind-pruned-ws.middlewares=tac-spb-tacchaind-pruned-stripprefix, ipallowlist
|
- traefik.http.routers.tac-spb-tacchaind-pruned-ws.middlewares=tac-spb-tacchaind-pruned-stripprefix, tac-spb-tacchaind-pruned-set-ws-path, ipallowlist
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
tac-spb-tacchaind-pruned:
|
tac-spb-tacchaind-pruned:
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ services:
|
|||||||
RETH_REPO: ${TAIKO_ALETHIA_RETH_REPO:-https://github.com/taikoxyz/alethia-reth}
|
RETH_REPO: ${TAIKO_ALETHIA_RETH_REPO:-https://github.com/taikoxyz/alethia-reth}
|
||||||
ARCH_TARGET: ${ARCH_TARGET:-native}
|
ARCH_TARGET: ${ARCH_TARGET:-native}
|
||||||
PROFILE: ${RETH_BUILD_PROFILE:-maxperf}
|
PROFILE: ${RETH_BUILD_PROFILE:-maxperf}
|
||||||
|
BUILD_ALETHIA_RETH: true
|
||||||
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
|
||||||
@@ -82,7 +83,7 @@ services:
|
|||||||
entrypoint: [reth, node]
|
entrypoint: [reth, node]
|
||||||
command:
|
command:
|
||||||
- --bootnodes=enode://266a8e3b5e44201eca9c368d58aa59a7750295397e77d5b32aea2644f9962cbc4e1cb0543aab0480995a209408174413f65e5ce253d60bb83d22d3b8ab12eb89@34.142.239.251:30303,enode://264a7fc4bd1ee16cfc6eb420c643407bfc61b9c9534c5a39ba6e68c8759beda2fbeccefee8677385e3d99691eeb218da4bce7f5207cf38594ac0f6a53c128b9b@35.247.159.156:30303,enode://2d4e5b7ec0c57f9def6ebe72f9bd1f65c33c87b7dc38875bbb147c10e8ec9a8cd157558b695f9a02ac6ad789f300fab4f1f19d41273956491372e96880a3459f@34.126.90.255:30303,enode://57f4b29cd8b59dc8db74be51eedc6425df2a6265fad680c843be113232bbe632933541678783c2a5759d65eac2e2241c45a34e1c36254bccfe7f72e52707e561@104.197.107.1:30303,enode://87a68eef46cc1fe862becef1185ac969dfbcc050d9304f6be21599bfdcb45a0eb9235d3742776bc4528ac3ab631eba6816e9b47f6ee7a78cc5fcaeb10cd32574@35.232.246.122:30303
|
- --bootnodes=enode://266a8e3b5e44201eca9c368d58aa59a7750295397e77d5b32aea2644f9962cbc4e1cb0543aab0480995a209408174413f65e5ce253d60bb83d22d3b8ab12eb89@34.142.239.251:30303,enode://264a7fc4bd1ee16cfc6eb420c643407bfc61b9c9534c5a39ba6e68c8759beda2fbeccefee8677385e3d99691eeb218da4bce7f5207cf38594ac0f6a53c128b9b@35.247.159.156:30303,enode://2d4e5b7ec0c57f9def6ebe72f9bd1f65c33c87b7dc38875bbb147c10e8ec9a8cd157558b695f9a02ac6ad789f300fab4f1f19d41273956491372e96880a3459f@34.126.90.255:30303,enode://57f4b29cd8b59dc8db74be51eedc6425df2a6265fad680c843be113232bbe632933541678783c2a5759d65eac2e2241c45a34e1c36254bccfe7f72e52707e561@104.197.107.1:30303,enode://87a68eef46cc1fe862becef1185ac969dfbcc050d9304f6be21599bfdcb45a0eb9235d3742776bc4528ac3ab631eba6816e9b47f6ee7a78cc5fcaeb10cd32574@35.232.246.122:30303
|
||||||
- --chain=alethia
|
- --chain=mainnet
|
||||||
- --datadir=/root/.local/share/reth
|
- --datadir=/root/.local/share/reth
|
||||||
- --discovery.port=11608
|
- --discovery.port=11608
|
||||||
- --engine.cross-block-cache-size=${TAIKO_ALETHIA_RETH_STATE_CACHE:-4096}
|
- --engine.cross-block-cache-size=${TAIKO_ALETHIA_RETH_STATE_CACHE:-4096}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ services:
|
|||||||
RETH_REPO: ${TAIKO_ALETHIA_RETH_REPO:-https://github.com/taikoxyz/alethia-reth}
|
RETH_REPO: ${TAIKO_ALETHIA_RETH_REPO:-https://github.com/taikoxyz/alethia-reth}
|
||||||
ARCH_TARGET: ${ARCH_TARGET:-native}
|
ARCH_TARGET: ${ARCH_TARGET:-native}
|
||||||
PROFILE: ${RETH_BUILD_PROFILE:-maxperf}
|
PROFILE: ${RETH_BUILD_PROFILE:-maxperf}
|
||||||
|
BUILD_ALETHIA_RETH: true
|
||||||
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
|
||||||
@@ -82,7 +83,7 @@ services:
|
|||||||
entrypoint: [reth, node]
|
entrypoint: [reth, node]
|
||||||
command:
|
command:
|
||||||
- --bootnodes=enode://266a8e3b5e44201eca9c368d58aa59a7750295397e77d5b32aea2644f9962cbc4e1cb0543aab0480995a209408174413f65e5ce253d60bb83d22d3b8ab12eb89@34.142.239.251:30303,enode://264a7fc4bd1ee16cfc6eb420c643407bfc61b9c9534c5a39ba6e68c8759beda2fbeccefee8677385e3d99691eeb218da4bce7f5207cf38594ac0f6a53c128b9b@35.247.159.156:30303,enode://2d4e5b7ec0c57f9def6ebe72f9bd1f65c33c87b7dc38875bbb147c10e8ec9a8cd157558b695f9a02ac6ad789f300fab4f1f19d41273956491372e96880a3459f@34.126.90.255:30303,enode://57f4b29cd8b59dc8db74be51eedc6425df2a6265fad680c843be113232bbe632933541678783c2a5759d65eac2e2241c45a34e1c36254bccfe7f72e52707e561@104.197.107.1:30303,enode://87a68eef46cc1fe862becef1185ac969dfbcc050d9304f6be21599bfdcb45a0eb9235d3742776bc4528ac3ab631eba6816e9b47f6ee7a78cc5fcaeb10cd32574@35.232.246.122:30303
|
- --bootnodes=enode://266a8e3b5e44201eca9c368d58aa59a7750295397e77d5b32aea2644f9962cbc4e1cb0543aab0480995a209408174413f65e5ce253d60bb83d22d3b8ab12eb89@34.142.239.251:30303,enode://264a7fc4bd1ee16cfc6eb420c643407bfc61b9c9534c5a39ba6e68c8759beda2fbeccefee8677385e3d99691eeb218da4bce7f5207cf38594ac0f6a53c128b9b@35.247.159.156:30303,enode://2d4e5b7ec0c57f9def6ebe72f9bd1f65c33c87b7dc38875bbb147c10e8ec9a8cd157558b695f9a02ac6ad789f300fab4f1f19d41273956491372e96880a3459f@34.126.90.255:30303,enode://57f4b29cd8b59dc8db74be51eedc6425df2a6265fad680c843be113232bbe632933541678783c2a5759d65eac2e2241c45a34e1c36254bccfe7f72e52707e561@104.197.107.1:30303,enode://87a68eef46cc1fe862becef1185ac969dfbcc050d9304f6be21599bfdcb45a0eb9235d3742776bc4528ac3ab631eba6816e9b47f6ee7a78cc5fcaeb10cd32574@35.232.246.122:30303
|
||||||
- --chain=alethia
|
- --chain=mainnet
|
||||||
- --datadir=/root/.local/share/reth
|
- --datadir=/root/.local/share/reth
|
||||||
- --discovery.port=13559
|
- --discovery.port=13559
|
||||||
- --engine.cross-block-cache-size=${TAIKO_ALETHIA_RETH_STATE_CACHE:-4096}
|
- --engine.cross-block-cache-size=${TAIKO_ALETHIA_RETH_STATE_CACHE:-4096}
|
||||||
|
|||||||
44
timestamp.sh
44
timestamp.sh
@@ -16,7 +16,15 @@ else
|
|||||||
PROTO="https"
|
PROTO="https"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pathlist=$(cat $BASEPATH/$1.yml | grep -oP "stripprefix\.prefixes.*?/\K[^\"]+")
|
compose_yml="$BASEPATH/$1.yml"
|
||||||
|
pathlist=$(cat "$compose_yml" | grep -oP "stripprefix\.prefixes.*?/\K[^\"]+")
|
||||||
|
|
||||||
|
# Resolve protocol from x-upstreams chain label (reuse sync-status / catchup idiom).
|
||||||
|
chain_slug=$(grep -oP '^\s*chain:\s*\K\S+' "$compose_yml" 2>/dev/null | head -1)
|
||||||
|
protocol=""
|
||||||
|
if [ -n "$chain_slug" ]; then
|
||||||
|
protocol=$($BASEPATH/reference-rpc-endpoint.sh --protocol "$chain_slug" 2>/dev/null) || protocol=""
|
||||||
|
fi
|
||||||
|
|
||||||
for path in $pathlist; do
|
for path in $pathlist; do
|
||||||
include=true
|
include=true
|
||||||
@@ -30,6 +38,40 @@ for path in $pathlist; do
|
|||||||
RPC_URL="$PROTO://$DOMAIN/$path"
|
RPC_URL="$PROTO://$DOMAIN/$path"
|
||||||
response_file=$(mktemp)
|
response_file=$(mktemp)
|
||||||
|
|
||||||
|
path_protocol="$protocol"
|
||||||
|
if [ -z "$path_protocol" ]; then
|
||||||
|
if echo "$path" | grep -qi "starknet"; then
|
||||||
|
path_protocol="starknet"
|
||||||
|
elif echo "$path" | grep -qi "aztec"; then
|
||||||
|
path_protocol="aztec"
|
||||||
|
elif echo "$path" | grep -qiE "cosmos|babylon|haqq|gaiad|tac"; then
|
||||||
|
path_protocol="cosmos"
|
||||||
|
else
|
||||||
|
path_protocol="eth"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$path_protocol" = "cosmos" ]; then
|
||||||
|
http_status_code=$(curl -L --ipv4 -m 1 -s -X POST -w "%{http_code}" -o "$response_file" \
|
||||||
|
-H "Content-Type: application/json" --data '{"jsonrpc":"2.0","id":1,"method":"status"}' "$RPC_URL")
|
||||||
|
if [ $? -eq 0 ] && [[ $http_status_code -eq 200 ]]; then
|
||||||
|
response=$(cat "$response_file")
|
||||||
|
latest_block_time=$(echo "$response" | jq -r '.result.sync_info.latest_block_time // .sync_info.latest_block_time' 2>/dev/null)
|
||||||
|
rm -f "$response_file"
|
||||||
|
if [ -z "$latest_block_time" ] || [ "$latest_block_time" = "null" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
latest_block_timestamp_decimal=$(date -d "$latest_block_time" +%s 2>/dev/null)
|
||||||
|
if [ -z "$latest_block_timestamp_decimal" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "$latest_block_timestamp_decimal"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
rm -f "$response_file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Detect Starknet vs Ethereum vs Aztec based on path
|
# Detect Starknet vs Ethereum vs Aztec based on path
|
||||||
if echo "$path" | grep -qi "starknet"; then
|
if echo "$path" | grep -qi "starknet"; then
|
||||||
rpc_method='{"jsonrpc":"2.0","method":"starknet_getBlockWithTxHashes","params":["latest"],"id":1}'
|
rpc_method='{"jsonrpc":"2.0","method":"starknet_getBlockWithTxHashes","params":["latest"],"id":1}'
|
||||||
|
|||||||
185
volume-utils.sh
185
volume-utils.sh
@@ -3,6 +3,191 @@
|
|||||||
# Shared helpers for compose volume operations.
|
# Shared helpers for compose volume operations.
|
||||||
# Ephemeral volumes (init-container config) are excluded from backup/restore/size.
|
# Ephemeral volumes (init-container config) are excluded from backup/restore/size.
|
||||||
|
|
||||||
|
# Minimum on-disk bytes for a backup archive to be considered restorable (near-empty
|
||||||
|
# zstd headers from purged/missing volumes must not win sort|tail newest selection).
|
||||||
|
MIN_RESTORABLE_BACKUP_BYTES=$((1024 * 1024))
|
||||||
|
|
||||||
|
RPC_ENV_FILE="/root/rpc/.env"
|
||||||
|
|
||||||
|
backup_archive_size_bytes() {
|
||||||
|
local file=$1
|
||||||
|
stat -c%s "$file" 2>/dev/null || echo 0
|
||||||
|
}
|
||||||
|
|
||||||
|
is_restorable_backup_archive() {
|
||||||
|
local file=$1
|
||||||
|
local size
|
||||||
|
[[ -f "$file" ]] || return 1
|
||||||
|
size=$(backup_archive_size_bytes "$file")
|
||||||
|
[[ "$size" =~ ^[0-9]+$ ]] && (( size >= MIN_RESTORABLE_BACKUP_BYTES ))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pick the lexicographically newest backup that is not near-empty (<1MB). Prints one
|
||||||
|
# skip line per rejected artifact; returns empty when none qualify.
|
||||||
|
select_newest_local_backup() {
|
||||||
|
local backup_dir=$1
|
||||||
|
local volume_name=$2
|
||||||
|
local pattern="${backup_dir}/${volume_name}"-[0-9]*G.tar.zst
|
||||||
|
local newest="" f size
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
local files=( $pattern )
|
||||||
|
shopt -u nullglob
|
||||||
|
if (( ${#files[@]} == 0 )); then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
IFS=$'\n' files=( $(printf '%s\n' "${files[@]}" | sort) )
|
||||||
|
unset IFS
|
||||||
|
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
size=$(backup_archive_size_bytes "$f")
|
||||||
|
if [[ ! "$size" =~ ^[0-9]+$ ]] || (( size < MIN_RESTORABLE_BACKUP_BYTES )); then
|
||||||
|
echo "skip near-empty backup artifact: $(basename "$f") (${size:-0} bytes)" >&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
newest="$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -n "$newest" ]]; then
|
||||||
|
echo "$newest"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
remote_backup_archive_size_bytes() {
|
||||||
|
local remote_source=$1
|
||||||
|
local archive_name=$2
|
||||||
|
curl --ipv4 -fsSI "${remote_source}${archive_name}" 2>/dev/null \
|
||||||
|
| awk -F': ' 'tolower($1)=="content-length" {gsub(/\r/,"",$2); print $2; exit}'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Newest restorable backup filename (not path) from a remote WebDAV listing on stdin.
|
||||||
|
select_newest_remote_backup_from_list() {
|
||||||
|
local remote_source=$1
|
||||||
|
local volume_name=$2
|
||||||
|
local newest="" f size
|
||||||
|
local -a files=()
|
||||||
|
|
||||||
|
while IFS= read -r f; do
|
||||||
|
[[ -n "$f" ]] && files+=("$f")
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( ${#files[@]} == 0 )); then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
IFS=$'\n' files=( $(printf '%s\n' "${files[@]}" | sort) )
|
||||||
|
unset IFS
|
||||||
|
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
[[ "$f" == "${volume_name}-"* ]] || continue
|
||||||
|
[[ "$f" == *.tar.zst ]] || continue
|
||||||
|
size=$(remote_backup_archive_size_bytes "$remote_source" "$f")
|
||||||
|
if [[ -z "$size" || ! "$size" =~ ^[0-9]+$ ]] || (( size < MIN_RESTORABLE_BACKUP_BYTES )); then
|
||||||
|
echo "skip near-empty backup artifact: $f (${size:-unknown} bytes)" >&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
newest="$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -n "$newest" ]]; then
|
||||||
|
echo "$newest"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
compose_fence_marker_path() {
|
||||||
|
local compose_name=$1
|
||||||
|
local env_dir
|
||||||
|
env_dir=$(dirname "$RPC_ENV_FILE")
|
||||||
|
echo "${env_dir}/.env.fence-$(echo "$compose_name" | tr '/' '_')"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove a compose yml segment from COMPOSE_FILE; store it in a sidecar marker for restore.
|
||||||
|
fence_compose_in_env() {
|
||||||
|
local compose_name=$1
|
||||||
|
local yml_segment="${compose_name}.yml"
|
||||||
|
local env_file="$RPC_ENV_FILE"
|
||||||
|
local marker
|
||||||
|
marker=$(compose_fence_marker_path "$compose_name")
|
||||||
|
|
||||||
|
[[ -f "$env_file" ]] || { echo "WARN: $env_file missing, cannot fence $compose_name" >&2; return 1; }
|
||||||
|
[[ -f "$marker" ]] && { echo "WARN: fence marker already exists: $marker" >&2; return 1; }
|
||||||
|
|
||||||
|
local line compose_file new_compose removed=0
|
||||||
|
line=$(grep -E '^COMPOSE_FILE=' "$env_file" | head -n 1)
|
||||||
|
[[ -n "$line" ]] || { echo "WARN: COMPOSE_FILE not found in $env_file" >&2; return 1; }
|
||||||
|
|
||||||
|
compose_file="${line#COMPOSE_FILE=}"
|
||||||
|
compose_file="${compose_file#\"}"
|
||||||
|
compose_file="${compose_file%\"}"
|
||||||
|
|
||||||
|
local part new_parts=()
|
||||||
|
IFS=':' read -ra parts <<< "$compose_file"
|
||||||
|
for part in "${parts[@]}"; do
|
||||||
|
if [[ "$part" == "$yml_segment" ]]; then
|
||||||
|
if ! printf '%s\n' "$part" > "$marker"; then
|
||||||
|
echo "WARN: failed to write fence marker $marker" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
removed=1
|
||||||
|
else
|
||||||
|
new_parts+=("$part")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
unset IFS
|
||||||
|
|
||||||
|
if (( removed == 0 )); then
|
||||||
|
echo "WARN: $yml_segment not present in COMPOSE_FILE (already fenced?)" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
new_compose=$(IFS=':'; echo "${new_parts[*]}")
|
||||||
|
if grep -q '^COMPOSE_FILE=' "$env_file"; then
|
||||||
|
sed -i "s|^COMPOSE_FILE=.*|COMPOSE_FILE=${new_compose}|" "$env_file"
|
||||||
|
else
|
||||||
|
echo "COMPOSE_FILE=${new_compose}" >> "$env_file"
|
||||||
|
fi
|
||||||
|
echo "Fenced $yml_segment from COMPOSE_FILE (marker: $marker)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore a fenced compose segment before service-scoped start (start needs the entry).
|
||||||
|
unfence_compose_in_env() {
|
||||||
|
local compose_name=$1
|
||||||
|
local yml_segment="${compose_name}.yml"
|
||||||
|
local env_file="$RPC_ENV_FILE"
|
||||||
|
local marker
|
||||||
|
marker=$(compose_fence_marker_path "$compose_name")
|
||||||
|
|
||||||
|
[[ -f "$marker" ]] || return 0
|
||||||
|
|
||||||
|
local segment line compose_file
|
||||||
|
segment=$(cat "$marker")
|
||||||
|
[[ -n "$segment" ]] || { rm -f "$marker"; return 0; }
|
||||||
|
|
||||||
|
if [[ -f "$env_file" ]]; then
|
||||||
|
line=$(grep -E '^COMPOSE_FILE=' "$env_file" | head -n 1)
|
||||||
|
compose_file="${line#COMPOSE_FILE=}"
|
||||||
|
compose_file="${compose_file#\"}"
|
||||||
|
compose_file="${compose_file%\"}"
|
||||||
|
case ":$compose_file:" in
|
||||||
|
*:"$segment":*) ;;
|
||||||
|
*)
|
||||||
|
if [[ -n "$compose_file" ]]; then
|
||||||
|
compose_file="${compose_file}:${segment}"
|
||||||
|
else
|
||||||
|
compose_file="$segment"
|
||||||
|
fi
|
||||||
|
sed -i "s|^COMPOSE_FILE=.*|COMPOSE_FILE=${compose_file}|" "$env_file"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
echo "COMPOSE_FILE=${segment}" > "$env_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$marker"
|
||||||
|
echo "Unfenced $yml_segment into COMPOSE_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
is_ephemeral_volume_key() {
|
is_ephemeral_volume_key() {
|
||||||
local key=$1
|
local key=$1
|
||||||
local compose_file=$2
|
local compose_file=$2
|
||||||
|
|||||||
Reference in New Issue
Block a user