Files
solana/multinode-demo/fullnode.sh
Michael Vines f93c9f052f Ensure genesis ledger directory is populated on all validator nodes
This allows all nodes to serve the genesis ledger over rsync instead of
just the bootstrap leader
2019-03-21 15:55:12 -07:00

200 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Start a full node
#
here=$(dirname "$0")
# shellcheck source=multinode-demo/common.sh
source "$here"/common.sh
# shellcheck source=scripts/oom-score-adj.sh
source "$here"/../scripts/oom-score-adj.sh
if [[ $1 = -h ]]; then
fullnode_usage "$@"
fi
gossip_port=9000
extra_fullnode_args=()
self_setup=0
setup_stakes=true
while [[ ${1:0:1} = - ]]; do
if [[ $1 = -X ]]; then
self_setup=1
self_setup_label=$2
shift 2
elif [[ $1 = -x ]]; then
self_setup=1
self_setup_label=$$
shift
elif [[ $1 = --blockstream ]]; then
extra_fullnode_args+=("$1" "$2")
shift 2
elif [[ $1 = --enable-rpc-exit ]]; then
extra_fullnode_args+=("$1")
shift
elif [[ $1 = --init-complete-file ]]; then
extra_fullnode_args+=("$1" "$2")
shift 2
elif [[ $1 = --only-bootstrap-stake ]]; then
setup_stakes=false
shift
elif [[ $1 = --public-address ]]; then
extra_fullnode_args+=("$1")
shift
elif [[ $1 = --no-voting ]]; then
extra_fullnode_args+=("$1")
shift
elif [[ $1 = --rpc-port ]]; then
extra_fullnode_args+=("$1" "$2")
shift 2
else
echo "Unknown argument: $1"
exit 1
fi
done
if [[ -n $3 ]]; then
fullnode_usage "$@"
fi
find_leader() {
declare leader leader_address
declare shift=0
if [[ -z $1 ]]; then
leader=${here}/.. # Default to local tree for rsync
leader_address=127.0.0.1:8001 # Default to local leader
elif [[ -z $2 ]]; then
leader=$1
declare leader_ip
if [[ $leader =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then
leader_ip=$leader
else
leader_ip=$(dig +short "${leader%:*}" | head -n1)
if [[ -z $leader_ip ]]; then
usage "Error: unable to resolve IP address for $leader"
fi
fi
leader_address=$leader_ip:8001
shift=1
else
leader=$1
leader_address=$2
shift=2
fi
echo "$leader" "$leader_address" "$shift"
}
read -r leader leader_address shift < <(find_leader "${@:1:2}")
shift "$shift"
if [[ -n $SOLANA_CUDA ]]; then
program=$solana_fullnode_cuda
else
program=$solana_fullnode
fi
if ((!self_setup)); then
[[ -f $SOLANA_CONFIG_DIR/fullnode-id.json ]] || {
echo "$SOLANA_CONFIG_DIR/fullnode-id.json not found, create it by running:"
echo
echo " ${here}/setup.sh"
exit 1
}
fullnode_id_path=$SOLANA_CONFIG_DIR/fullnode-id.json
fullnode_staker_id_path=$SOLANA_CONFIG_DIR/fullnode-staker-id.json
ledger_config_dir=$SOLANA_CONFIG_DIR/fullnode-ledger
accounts_config_dir=$SOLANA_CONFIG_DIR/fullnode-accounts
else
mkdir -p "$SOLANA_CONFIG_DIR"
fullnode_id_path=$SOLANA_CONFIG_DIR/fullnode-id-x$self_setup_label.json
fullnode_staker_id_path=$SOLANA_CONFIG_DIR/fullnode-staker-id-x$self_setup_label.json
[[ -f "$fullnode_id_path" ]] || $solana_keygen -o "$fullnode_id_path"
[[ -f "$fullnode_staker_id_path" ]] || $solana_keygen -o "$fullnode_staker_id_path"
echo "Finding a port.."
# Find an available port in the range 9100-9899
(( gossip_port = 9100 + ($$ % 800) ))
while true; do
(( gossip_port = gossip_port >= 9900 ? 9100 : ++gossip_port ))
echo "Testing $gossip_port"
if ! nc -w 10 -z 127.0.0.1 $gossip_port; then
echo "Selected gossip_port $gossip_port"
break;
fi
echo "Port $gossip_port is in use"
done
ledger_config_dir=$SOLANA_CONFIG_DIR/fullnode-ledger-x$self_setup_label
accounts_config_dir=$SOLANA_CONFIG_DIR/fullnode-accounts-x$self_setup_label
fi
fullnode_id=$($solana_wallet --keypair "$fullnode_id_path" address)
fullnode_staker_id=$($solana_wallet --keypair "$fullnode_staker_id_path" address)
[[ -r $fullnode_id_path ]] || {
echo "$fullnode_id_path does not exist"
exit 1
}
tune_system
rsync_url() { # adds the 'rsync://` prefix to URLs that need it
declare url="$1"
if [[ $url =~ ^.*:.*$ ]]; then
# assume remote-shell transport when colon is present, use $url unmodified
echo "$url"
return 0
fi
if [[ -d $url ]]; then
# assume local directory if $url is a valid directory, use $url unmodified
echo "$url"
return 0
fi
# Default to rsync:// URL
echo "rsync://$url"
}
rsync_leader_url=$(rsync_url "$leader")
set -ex
if [[ ! -d "$SOLANA_RSYNC_CONFIG_DIR"/ledger ]]; then
$rsync -vPr "$rsync_leader_url"/config/ledger "$SOLANA_RSYNC_CONFIG_DIR"/ledger
fi
if [[ ! -d "$ledger_config_dir" ]]; then
cp -ra "$SOLANA_RSYNC_CONFIG_DIR"/ledger "$ledger_config_dir"
$solana_ledger_tool --ledger "$ledger_config_dir" verify
fi
trap 'kill "$pid" && wait "$pid"' INT TERM ERR
$program \
--gossip-port "$gossip_port" \
--identity "$fullnode_id_path" \
--voting-keypair "$fullnode_staker_id_path" \
--staking-account "$fullnode_staker_id" \
--network "$leader_address" \
--ledger "$ledger_config_dir" \
--accounts "$accounts_config_dir" \
--rpc-drone-address "${leader_address%:*}:9900" \
"${extra_fullnode_args[@]}" \
> >($fullnode_logger) 2>&1 &
pid=$!
oom_score_adj "$pid" 1000
if [[ $setup_stakes = true ]]; then
setup_fullnode_staking "${leader_address%:*}" "$fullnode_id_path" "$fullnode_staker_id_path"
fi
wait "$pid"