1174 lines
34 KiB
Bash
Executable File
1174 lines
34 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
IFS=$'\n\t'
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
DEFAULT_GO_VERSION="1.21.5"
|
|
DEFAULT_NODE_VERSION="24.19.0"
|
|
DEFAULT_BIND_ADDR="127.0.0.1:9067"
|
|
DEFAULT_HTTP_BIND_ADDR="127.0.0.1:9068"
|
|
DEFAULT_DATA_DIR="/var/lib/lightwalletd"
|
|
DEFAULT_P2P_PORT="45452"
|
|
DEFAULT_EXPLORER_PORT="3001"
|
|
DEFAULT_EXPLORER_ZMQ_PORT="28332"
|
|
# Pirate 6.0.0 is the Ironwood network-upgrade release. The corresponding
|
|
# lightwalletd revision includes the v6 transaction parser and Ironwood
|
|
# commitment-tree RPC support. Keep the pair pinned so a re-run is
|
|
# reproducible instead of silently changing with upstream master.
|
|
DEFAULT_PIRATE_REF="v6.0.0"
|
|
DEFAULT_LIGHTWALLETD_REF="43b29b4229cc68adae8a807931d26f9a5f5d98a6"
|
|
# Keep the optional public services reproducible too. These revisions are the
|
|
# current Pirate-maintained seed-node components tested with the v6 network.
|
|
DEFAULT_DNSSEED_REF="6d3ed9c6d188c01846bb2f4daf7d67b8b75ab218"
|
|
DEFAULT_BITCORE_NODE_REF="f08d0f3d3e158d7128e8e2d72e8fbb0db1f5c9e9"
|
|
DEFAULT_INSIGHT_API_REF="d7414b4f37c9fae937c2cfeb3c4ca33c33969821"
|
|
DEFAULT_INSIGHT_UI_REF="8fad6bc0109bce14475a9e9cd91368288a48b8d7"
|
|
|
|
script_name=$(basename "$0")
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $script_name [options]
|
|
|
|
Sets up the Pirate Chain daemon and ARRRwallet lightwalletd server on Ubuntu.
|
|
|
|
Options:
|
|
--hostname HOSTNAME Configure nginx for HOSTNAME + proxy lightwalletd (implies port 80)
|
|
--explorer-hostname HOSTNAME
|
|
Enable the HTTPS Insight block explorer at HOSTNAME
|
|
(requires --lets-encrypt and --email)
|
|
--email EMAIL Email address to register with certbot when --lets-encrypt is used
|
|
--lets-encrypt Run certbot against configured nginx hostname(s) (requires --email)
|
|
--tls-cert PATH Use a custom TLS certificate when not using nginx
|
|
--tls-key PATH Use a custom TLS key when not using nginx
|
|
--bind-addr HOST:PORT Lightwalletd gRPC bind address (default: $DEFAULT_BIND_ADDR)
|
|
--http-bind-addr HOST:PORT Lightwalletd HTTP bind address (default: $DEFAULT_HTTP_BIND_ADDR)
|
|
--go-version VERSION Go toolchain version to install (default: $DEFAULT_GO_VERSION)
|
|
--node-version VERSION Node.js version for the optional explorer (default: $DEFAULT_NODE_VERSION)
|
|
--data-dir DIR Lightwalletd data directory (default: $DEFAULT_DATA_DIR)
|
|
--pirate-ref REF Pirate source tag or commit (default: $DEFAULT_PIRATE_REF)
|
|
--lightwalletd-ref REF Lightwalletd source tag or commit (default: $DEFAULT_LIGHTWALLETD_REF)
|
|
--explorer-port PORT Local Insight web port (default: $DEFAULT_EXPLORER_PORT)
|
|
--explorer-zmq-port PORT Local pirated ZMQ port for Insight (default: $DEFAULT_EXPLORER_ZMQ_PORT)
|
|
--dnsseed-host HOSTNAME Authoritative DNS seed hostname, e.g. dnsseed.example.com
|
|
--dnsseed-ns HOSTNAME Nameserver hostname, e.g. ns-dnsseed.example.com
|
|
--dnsseed-mbox RNAME SOA contact, e.g. admin.example.com (not an email address)
|
|
--dnsseed-port PORT DNS seed UDP port (default: 53)
|
|
--p2p-port PORT Pirate P2P port to expose with a DNS seed (default: $DEFAULT_P2P_PORT)
|
|
--dnsseed-ref REF pirate-seeder source tag or commit (default: $DEFAULT_DNSSEED_REF)
|
|
--dnsseed-tor-proxy HOST:PORT
|
|
Optional SOCKS5 Tor proxy for crawling onion peers
|
|
--help|-h Show this message
|
|
EOF
|
|
}
|
|
|
|
log() {
|
|
printf "==> %s\n" "$*"
|
|
}
|
|
|
|
err() {
|
|
printf "ERROR: %s\n" "$*" >&2
|
|
}
|
|
|
|
if [ "$(id -u)" -eq 0 ]; then
|
|
sudo_cmd=""
|
|
else
|
|
sudo_cmd="sudo"
|
|
fi
|
|
|
|
TARGET_USER="${SUDO_USER:-${USER:-$(whoami)}}"
|
|
if [ -z "$TARGET_USER" ]; then
|
|
err "Unable to determine the target user"
|
|
exit 1
|
|
fi
|
|
|
|
TARGET_HOME="$(eval echo "~$TARGET_USER")"
|
|
if [ -z "$TARGET_HOME" ]; then
|
|
err "Unable to determine $TARGET_USER's home directory"
|
|
exit 1
|
|
fi
|
|
|
|
HOSTNAME=""
|
|
explorer_hostname=""
|
|
EMAIL=""
|
|
enable_lets_encrypt=false
|
|
tls_cert=""
|
|
tls_key=""
|
|
go_version="$DEFAULT_GO_VERSION"
|
|
node_version="$DEFAULT_NODE_VERSION"
|
|
bind_addr="$DEFAULT_BIND_ADDR"
|
|
http_bind_addr="$DEFAULT_HTTP_BIND_ADDR"
|
|
data_dir="$DEFAULT_DATA_DIR"
|
|
pirate_ref="$DEFAULT_PIRATE_REF"
|
|
lightwalletd_ref="$DEFAULT_LIGHTWALLETD_REF"
|
|
explorer_port="$DEFAULT_EXPLORER_PORT"
|
|
explorer_zmq_port="$DEFAULT_EXPLORER_ZMQ_PORT"
|
|
dnsseed_host=""
|
|
dnsseed_ns=""
|
|
dnsseed_mbox=""
|
|
dnsseed_port="53"
|
|
p2p_port="$DEFAULT_P2P_PORT"
|
|
dnsseed_ref="$DEFAULT_DNSSEED_REF"
|
|
dnsseed_tor_proxy=""
|
|
certbot_root="/var/www/certbot"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--hostname)
|
|
HOSTNAME="$2"
|
|
shift 2
|
|
;;
|
|
--explorer-hostname)
|
|
explorer_hostname="$2"
|
|
shift 2
|
|
;;
|
|
--email)
|
|
EMAIL="$2"
|
|
shift 2
|
|
;;
|
|
--lets-encrypt)
|
|
enable_lets_encrypt=true
|
|
shift
|
|
;;
|
|
--tls-cert)
|
|
tls_cert="$2"
|
|
shift 2
|
|
;;
|
|
--tls-key)
|
|
tls_key="$2"
|
|
shift 2
|
|
;;
|
|
--bind-addr)
|
|
bind_addr="$2"
|
|
shift 2
|
|
;;
|
|
--http-bind-addr)
|
|
http_bind_addr="$2"
|
|
shift 2
|
|
;;
|
|
--data-dir)
|
|
data_dir="$2"
|
|
shift 2
|
|
;;
|
|
--go-version)
|
|
go_version="$2"
|
|
shift 2
|
|
;;
|
|
--node-version)
|
|
node_version="$2"
|
|
shift 2
|
|
;;
|
|
--pirate-ref)
|
|
pirate_ref="$2"
|
|
shift 2
|
|
;;
|
|
--lightwalletd-ref)
|
|
lightwalletd_ref="$2"
|
|
shift 2
|
|
;;
|
|
--explorer-port)
|
|
explorer_port="$2"
|
|
shift 2
|
|
;;
|
|
--explorer-zmq-port)
|
|
explorer_zmq_port="$2"
|
|
shift 2
|
|
;;
|
|
--dnsseed-host)
|
|
dnsseed_host="$2"
|
|
shift 2
|
|
;;
|
|
--dnsseed-ns)
|
|
dnsseed_ns="$2"
|
|
shift 2
|
|
;;
|
|
--dnsseed-mbox)
|
|
dnsseed_mbox="$2"
|
|
shift 2
|
|
;;
|
|
--dnsseed-port)
|
|
dnsseed_port="$2"
|
|
shift 2
|
|
;;
|
|
--p2p-port)
|
|
p2p_port="$2"
|
|
shift 2
|
|
;;
|
|
--dnsseed-ref)
|
|
dnsseed_ref="$2"
|
|
shift 2
|
|
;;
|
|
--dnsseed-tor-proxy)
|
|
dnsseed_tor_proxy="$2"
|
|
shift 2
|
|
;;
|
|
--help|-h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
err "Unknown option: $1"
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ "$bind_addr" != *:* ]]; then
|
|
err "--bind-addr must include a port (e.g. 127.0.0.1:9067)"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$http_bind_addr" != *:* ]]; then
|
|
err "--http-bind-addr must include a port (e.g. 127.0.0.1:9068)"
|
|
exit 1
|
|
fi
|
|
|
|
if $enable_lets_encrypt && [ -z "$HOSTNAME" ] && [ -z "$explorer_hostname" ]; then
|
|
err "--lets-encrypt requires --hostname and/or --explorer-hostname"
|
|
exit 1
|
|
fi
|
|
|
|
if $enable_lets_encrypt && [ -z "$EMAIL" ]; then
|
|
err "--lets-encrypt requires --email"
|
|
exit 1
|
|
fi
|
|
|
|
if { [ -n "$tls_cert" ] && [ -z "$tls_key" ]; } || { [ -z "$tls_cert" ] && [ -n "$tls_key" ]; }; then
|
|
err "Both --tls-cert and --tls-key must be provided together"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -n "$tls_cert" ] && [ ! -f "$tls_cert" ]; then
|
|
err "TLS certificate $tls_cert does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -n "$tls_key" ] && [ ! -f "$tls_key" ]; then
|
|
err "TLS key $tls_key does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$data_dir" ]; then
|
|
err "--data-dir cannot be empty"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$pirate_ref" ] || [ -z "$lightwalletd_ref" ]; then
|
|
err "--pirate-ref and --lightwalletd-ref cannot be empty"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$node_version" ] || [ -z "$dnsseed_ref" ]; then
|
|
err "--node-version and --dnsseed-ref cannot be empty"
|
|
exit 1
|
|
fi
|
|
|
|
is_valid_port() {
|
|
[[ "$1" =~ ^[0-9]+$ ]] && [ "$1" -ge 1 ] && [ "$1" -le 65535 ]
|
|
}
|
|
|
|
if ! is_valid_port "$explorer_port"; then
|
|
err "--explorer-port must be an integer from 1 to 65535"
|
|
exit 1
|
|
fi
|
|
|
|
if ! is_valid_port "$explorer_zmq_port"; then
|
|
err "--explorer-zmq-port must be an integer from 1 to 65535"
|
|
exit 1
|
|
fi
|
|
|
|
if ! is_valid_port "$dnsseed_port"; then
|
|
err "--dnsseed-port must be an integer from 1 to 65535"
|
|
exit 1
|
|
fi
|
|
|
|
if ! is_valid_port "$p2p_port"; then
|
|
err "--p2p-port must be an integer from 1 to 65535"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -n "$explorer_hostname" ] && ! $enable_lets_encrypt; then
|
|
err "--explorer-hostname requires --lets-encrypt so nginx has a trusted certificate"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -n "$HOSTNAME" ] && [ "$HOSTNAME" = "$explorer_hostname" ]; then
|
|
err "--hostname and --explorer-hostname must be distinct hostnames"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -n "$dnsseed_host" ] || [ -n "$dnsseed_ns" ] || [ -n "$dnsseed_mbox" ] || [ -n "$dnsseed_tor_proxy" ]; then
|
|
if [ -z "$dnsseed_host" ] || [ -z "$dnsseed_ns" ] || [ -z "$dnsseed_mbox" ]; then
|
|
err "--dnsseed-host, --dnsseed-ns, and --dnsseed-mbox must be supplied together"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
ENABLE_EXPLORER=false
|
|
if [ -n "$explorer_hostname" ]; then
|
|
ENABLE_EXPLORER=true
|
|
fi
|
|
|
|
ENABLE_DNSSEED=false
|
|
if [ -n "$dnsseed_host" ]; then
|
|
ENABLE_DNSSEED=true
|
|
fi
|
|
|
|
USE_NGINX=false
|
|
if [ -n "$HOSTNAME" ] || $ENABLE_EXPLORER; then
|
|
USE_NGINX=true
|
|
fi
|
|
|
|
if [ -n "$tls_cert" ] && [ "$USE_NGINX" = "true" ]; then
|
|
log "Ignoring direct TLS settings because nginx will terminate TLS for $HOSTNAME"
|
|
tls_cert=""
|
|
tls_key=""
|
|
fi
|
|
lited_tls_args=(--no-tls-very-insecure)
|
|
if [ -n "$tls_cert" ] && [ -n "$tls_key" ]; then
|
|
lited_tls_args=(--tls-cert "$tls_cert" --tls-key "$tls_key")
|
|
fi
|
|
|
|
lited_port="${bind_addr##*:}"
|
|
pirate_dir="$TARGET_HOME/pirate"
|
|
lightwalletd_dir="$TARGET_HOME/lightwalletd"
|
|
conf_dir="$TARGET_HOME/.komodo/PIRATE"
|
|
conf_file="$conf_dir/PIRATE.conf"
|
|
log_dir="/var/log/lited"
|
|
explorer_dir="$TARGET_HOME/arrr-explorer"
|
|
explorer_config="$explorer_dir/bitcore-node.json"
|
|
explorer_node_bin=""
|
|
explorer_npm_bin=""
|
|
dnsseed_dir="$TARGET_HOME/pirate-seeder"
|
|
dnsseed_data_dir="/var/lib/pirate-seeder"
|
|
|
|
as_target_user() {
|
|
if [ "$(id -un)" = "$TARGET_USER" ]; then
|
|
"$@"
|
|
elif command -v sudo >/dev/null 2>&1; then
|
|
sudo -H -u "$TARGET_USER" "$@"
|
|
else
|
|
runuser -u "$TARGET_USER" -- "$@"
|
|
fi
|
|
}
|
|
|
|
install_base_packages() {
|
|
log "Installing build tooling and runtime dependencies"
|
|
packages=(
|
|
build-essential pkg-config libc6-dev m4 g++-multilib autoconf libtool
|
|
libncurses-dev unzip git python3 python-is-python3 zlib1g-dev wget bsdmainutils automake
|
|
libboost-all-dev libssl-dev libprotobuf-dev protobuf-compiler libqrencode-dev
|
|
libdb++-dev ntp ntpdate nano software-properties-common curl libevent-dev
|
|
libcurl4-gnutls-dev cmake clang libsodium-dev htop jq libcap2-bin
|
|
bison liblz4-dev python3-zmq zip
|
|
)
|
|
$sudo_cmd apt-get update
|
|
$sudo_cmd apt-get install -y "${packages[@]}"
|
|
}
|
|
|
|
install_optional_network() {
|
|
if [ "$USE_NGINX" = "true" ]; then
|
|
log "Installing nginx/certbot for reverse proxy configuration"
|
|
$sudo_cmd apt-get install -y nginx-full certbot python3-certbot-nginx
|
|
fi
|
|
}
|
|
|
|
install_optional_explorer_packages() {
|
|
if ! $ENABLE_EXPLORER; then
|
|
return
|
|
fi
|
|
|
|
# `zeromq` is the Node binding used by bitcore-node-pirate to consume
|
|
# pirated's raw-transaction and block notifications.
|
|
log "Installing Insight explorer build dependencies"
|
|
$sudo_cmd apt-get install -y libzmq3-dev
|
|
}
|
|
|
|
ensure_certbot_snippets() {
|
|
if [ "$USE_NGINX" != "true" ]; then
|
|
return
|
|
fi
|
|
|
|
local options_path="/etc/letsencrypt/options-ssl-nginx.conf"
|
|
local dhparam_path="/etc/letsencrypt/ssl-dhparams.pem"
|
|
|
|
if [ ! -f "$options_path" ]; then
|
|
log "Creating fallback Certbot nginx options snippet"
|
|
cat <<'EOF' | $sudo_cmd tee "$options_path" >/dev/null
|
|
ssl_session_cache shared:le_nginx_SSL:10m;
|
|
ssl_session_timeout 1440m;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_prefer_server_ciphers off;
|
|
ssl_ciphers 'ECDHE-ECDSA+AESGCM:ECDHE-RSA+AESGCM:ECDHE-ECDSA+CHACHA20:ECDHE-RSA+CHACHA20:ECDHE-ECDSA+AES256:ECDHE-RSA+AES256:DHE-RSA+AES256:AES256-GCM-SHA384:AES256-SHA';
|
|
ssl_ecdh_curve secp384r1;
|
|
ssl_stapling on;
|
|
ssl_stapling_verify on;
|
|
resolver 1.1.1.1 1.0.0.1 valid=300s;
|
|
resolver_timeout 10s;
|
|
EOF
|
|
fi
|
|
|
|
if [ ! -f "$dhparam_path" ]; then
|
|
log "Generating DH params for Certbot defaults (only once)"
|
|
$sudo_cmd openssl dhparam -out "$dhparam_path" 2048
|
|
fi
|
|
}
|
|
|
|
install_go() {
|
|
log "Installing Go $go_version"
|
|
case "$(uname -m)" in
|
|
x86_64|amd64)
|
|
go_arch="amd64"
|
|
;;
|
|
aarch64|arm64)
|
|
go_arch="arm64"
|
|
;;
|
|
*)
|
|
err "Unsupported CPU architecture for the official Go Linux archive: $(uname -m)"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
archive="go${go_version}.linux-${go_arch}.tar.gz"
|
|
url="https://go.dev/dl/${archive}"
|
|
|
|
tmpfile="/tmp/${archive}"
|
|
if command -v go >/dev/null 2>&1; then
|
|
current_version="$(go version | awk '{print $3}')"
|
|
log "Existing Go version detected: $current_version"
|
|
fi
|
|
|
|
curl -fsSL "$url" -o "$tmpfile"
|
|
$sudo_cmd rm -rf /usr/local/go
|
|
$sudo_cmd tar -C /usr/local -xzf "$tmpfile"
|
|
rm -f "$tmpfile"
|
|
|
|
cat <<'EOF' | $sudo_cmd tee /etc/profile.d/go.sh >/dev/null
|
|
export PATH=$PATH:/usr/local/go/bin
|
|
EOF
|
|
$sudo_cmd chmod 644 /etc/profile.d/go.sh
|
|
export PATH="/usr/local/go/bin:$PATH"
|
|
log "Go version: $(go version)"
|
|
}
|
|
|
|
install_explorer_node() {
|
|
if ! $ENABLE_EXPLORER; then
|
|
return
|
|
fi
|
|
|
|
log "Installing Node.js $node_version for the Insight explorer"
|
|
local nvm_dir="$TARGET_HOME/.nvm"
|
|
as_target_user env NVM_DIR="$nvm_dir" NODE_VERSION="$node_version" bash -s <<'EOF'
|
|
set -euo pipefail
|
|
|
|
if [ ! -s "$NVM_DIR/nvm.sh" ]; then
|
|
installer="$(mktemp)"
|
|
trap 'rm -f "$installer"' EXIT
|
|
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh -o "$installer"
|
|
bash "$installer"
|
|
fi
|
|
|
|
# shellcheck source=/dev/null
|
|
. "$NVM_DIR/nvm.sh"
|
|
nvm install "$NODE_VERSION"
|
|
nvm alias default "$NODE_VERSION"
|
|
EOF
|
|
|
|
explorer_node_bin="$nvm_dir/versions/node/v$node_version/bin/node"
|
|
explorer_npm_bin="$nvm_dir/versions/node/v$node_version/bin/npm"
|
|
if [ ! -x "$explorer_node_bin" ] || [ ! -x "$explorer_npm_bin" ]; then
|
|
err "Node.js $node_version was not installed under $nvm_dir"
|
|
exit 1
|
|
fi
|
|
|
|
local node_major
|
|
node_major="$("$explorer_node_bin" --version | sed -E 's/^v([0-9]+).*/\1/')"
|
|
if ! [[ "$node_major" =~ ^[0-9]+$ ]] || [ "$node_major" -lt 18 ]; then
|
|
err "Insight explorer requires Node.js 18 or newer; found $($explorer_node_bin --version)"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
sync_repo() {
|
|
local url="$1"
|
|
local dest="$2"
|
|
local ref="$3"
|
|
|
|
if [ -d "$dest/.git" ]; then
|
|
# The installer itself leaves untracked build outputs (notably `lited`) in
|
|
# this checkout. They are safe to retain because the build command
|
|
# overwrites them. Protect real source edits instead; `git checkout` still
|
|
# refuses any untracked path that would collide with the requested ref.
|
|
if ! as_target_user git -C "$dest" diff --quiet || \
|
|
! as_target_user git -C "$dest" diff --cached --quiet; then
|
|
err "Refusing to overwrite tracked changes in $dest; commit, stash, or revert them first"
|
|
exit 1
|
|
fi
|
|
log "Fetching $url into $dest"
|
|
as_target_user git -C "$dest" fetch --tags --prune origin
|
|
else
|
|
log "Cloning $url into $dest"
|
|
as_target_user git clone --no-checkout "$url" "$dest"
|
|
fi
|
|
|
|
as_target_user git -C "$dest" checkout --detach "$ref"
|
|
as_target_user git -C "$dest" submodule update --init --recursive
|
|
log "Using $(as_target_user git -C "$dest" rev-parse --short=12 HEAD) in $dest"
|
|
}
|
|
|
|
build_pirate() {
|
|
log "Building Pirate Chain daemon"
|
|
as_target_user env PIRATE_DIR="$pirate_dir" bash -s <<'EOF'
|
|
set -e
|
|
cd "$PIRATE_DIR"
|
|
|
|
# Pirate 6.0.0 fetches trusted parameters from the signed GitHub release and
|
|
# verifies their SHA-256 hashes. Do not weaken transport security with the
|
|
# legacy bootstrap.arrr.black HTTP fallback.
|
|
./zcutil/fetch-params.sh
|
|
|
|
./zcutil/build.sh -j$(nproc)
|
|
EOF
|
|
}
|
|
|
|
build_lightwalletd() {
|
|
log "Building ARRRwallet lightwalletd with Ironwood support"
|
|
export PATH="/usr/local/go/bin:$PATH"
|
|
as_target_user bash -lc "
|
|
set -e
|
|
cd \"$lightwalletd_dir\"
|
|
GO111MODULE=on /usr/local/go/bin/go build -buildvcs=false -mod=readonly -o lited .
|
|
"
|
|
}
|
|
|
|
link_binaries() {
|
|
log "Linking pirate binaries system-wide"
|
|
$sudo_cmd ln -sf "$pirate_dir/src/pirate-cli" /usr/local/bin/pirate-cli
|
|
$sudo_cmd ln -sf "$pirate_dir/src/pirated" /usr/local/bin/pirated
|
|
log "Linking lightwalletd binary"
|
|
$sudo_cmd ln -sf "$lightwalletd_dir/lited" /usr/local/bin/lited
|
|
}
|
|
|
|
create_pirate_conf() {
|
|
if [ -f "$conf_file" ]; then
|
|
log "PIRATE.conf already exists, skipping regeneration"
|
|
return
|
|
fi
|
|
|
|
log "Creating Pirate Chain configuration for lightwalletd"
|
|
mkdir -p "$conf_dir"
|
|
rpc_user="user$(openssl rand -hex 16)"
|
|
rpc_pass="pass$(openssl rand -hex 16)"
|
|
cat <<EOF > "$conf_file"
|
|
rpcuser=$rpc_user
|
|
rpcpassword=$rpc_pass
|
|
server=1
|
|
rpcbind=127.0.0.1
|
|
rpcport=45453
|
|
txindex=1
|
|
addressindex=1
|
|
timestampindex=1
|
|
spentindex=1
|
|
insightexplorer=1
|
|
experimentalfeatures=1
|
|
rpcallowip=127.0.0.1
|
|
EOF
|
|
chmod 600 "$conf_file"
|
|
chown -R "$TARGET_USER:$TARGET_USER" "$conf_dir"
|
|
}
|
|
|
|
check_pirate_v6_configuration() {
|
|
if [ ! -f "$conf_file" ]; then
|
|
return
|
|
fi
|
|
|
|
# These options were removed in Pirate 6.0.0. Leaving any of them in an
|
|
# existing operator-managed PIRATE.conf prevents pirated from starting, so
|
|
# report the migration before replacing the live daemon binary.
|
|
local legacy_options
|
|
legacy_options="$(awk -F= '
|
|
/^[[:space:]]*[#;]/ { next }
|
|
/^[[:space:]]*(consolidation|consolidationtxfee|consolidateaddress|sweepsaplingaddress|sweepironwoodaddress)[[:space:]]*=/ {
|
|
key=$1
|
|
sub(/^[[:space:]]*/, "", key)
|
|
sub(/[[:space:]]*$/, "", key)
|
|
print key
|
|
}
|
|
' "$conf_file")"
|
|
|
|
if [ -n "$legacy_options" ]; then
|
|
err "PIRATE.conf contains removed Pirate 6.0.0 option(s): ${legacy_options//$'\n'/, }"
|
|
err "Replace consolidation* with saplingconsolidation* or ironwoodconsolidation*,"
|
|
err "consolidateaddress with consolidate{sapling,ironwood}address, and"
|
|
err "sweepsaplingaddress/sweepironwoodaddress with sweepaddress; then rerun."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
pirate_conf_value() {
|
|
local key="$1"
|
|
awk -v wanted="$key" '
|
|
/^[[:space:]]*[#;]/ { next }
|
|
{
|
|
equals = index($0, "=")
|
|
if (!equals) next
|
|
option = substr($0, 1, equals - 1)
|
|
value = substr($0, equals + 1)
|
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", option)
|
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
|
|
if (option == wanted) result = value
|
|
}
|
|
END { print result }
|
|
' "$conf_file"
|
|
}
|
|
|
|
append_pirate_conf_option() {
|
|
local key="$1"
|
|
local value="$2"
|
|
printf '\n%s=%s\n' "$key" "$value" | $sudo_cmd tee -a "$conf_file" >/dev/null
|
|
$sudo_cmd chmod 600 "$conf_file"
|
|
$sudo_cmd chown "$TARGET_USER:$TARGET_USER" "$conf_file"
|
|
}
|
|
|
|
is_loopback_zmq_endpoint() {
|
|
[[ "$1" =~ ^tcp://(127\.0\.0\.1|localhost|\[::1\]):[0-9]+$ ]]
|
|
}
|
|
|
|
configure_explorer_pirate_conf() {
|
|
if ! $ENABLE_EXPLORER; then
|
|
return
|
|
fi
|
|
|
|
local rawtx_endpoint hashblock_endpoint default_endpoint endpoint_port
|
|
default_endpoint="tcp://127.0.0.1:$explorer_zmq_port"
|
|
rawtx_endpoint="$(pirate_conf_value zmqpubrawtx)"
|
|
hashblock_endpoint="$(pirate_conf_value zmqpubhashblock)"
|
|
|
|
if [ -z "$rawtx_endpoint" ] && [ -z "$hashblock_endpoint" ]; then
|
|
log "Enabling local ZMQ notifications for the Insight explorer"
|
|
append_pirate_conf_option zmqpubrawtx "$default_endpoint"
|
|
append_pirate_conf_option zmqpubhashblock "$default_endpoint"
|
|
rawtx_endpoint="$default_endpoint"
|
|
elif [ -z "$rawtx_endpoint" ]; then
|
|
log "Adding missing zmqpubrawtx setting for the Insight explorer"
|
|
append_pirate_conf_option zmqpubrawtx "$hashblock_endpoint"
|
|
rawtx_endpoint="$hashblock_endpoint"
|
|
elif [ -z "$hashblock_endpoint" ]; then
|
|
log "Adding missing zmqpubhashblock setting for the Insight explorer"
|
|
append_pirate_conf_option zmqpubhashblock "$rawtx_endpoint"
|
|
hashblock_endpoint="$rawtx_endpoint"
|
|
fi
|
|
|
|
if [ "$rawtx_endpoint" != "$hashblock_endpoint" ]; then
|
|
err "Insight requires zmqpubrawtx and zmqpubhashblock to use the same endpoint in $conf_file"
|
|
exit 1
|
|
fi
|
|
|
|
if ! is_loopback_zmq_endpoint "$rawtx_endpoint"; then
|
|
err "Insight requires its ZMQ endpoint to be loopback-only; found $rawtx_endpoint in $conf_file"
|
|
exit 1
|
|
fi
|
|
|
|
endpoint_port="${rawtx_endpoint##*:}"
|
|
if ! is_valid_port "$endpoint_port"; then
|
|
err "Invalid ZMQ port in $rawtx_endpoint"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
install_and_configure_explorer() {
|
|
if ! $ENABLE_EXPLORER; then
|
|
return
|
|
fi
|
|
|
|
local rpc_user rpc_pass rpc_port rawtx_endpoint
|
|
rpc_user="$(pirate_conf_value rpcuser)"
|
|
rpc_pass="$(pirate_conf_value rpcpassword)"
|
|
rpc_port="$(pirate_conf_value rpcport)"
|
|
rawtx_endpoint="$(pirate_conf_value zmqpubrawtx)"
|
|
|
|
if [ -z "$rpc_user" ] || [ -z "$rpc_pass" ] || [ -z "$rawtx_endpoint" ]; then
|
|
err "Insight requires rpcuser, rpcpassword, and zmqpubrawtx in $conf_file"
|
|
exit 1
|
|
fi
|
|
if [ -z "$rpc_port" ]; then
|
|
rpc_port="45453"
|
|
fi
|
|
if ! is_valid_port "$rpc_port"; then
|
|
err "Invalid rpcport in $conf_file: $rpc_port"
|
|
exit 1
|
|
fi
|
|
|
|
log "Installing pinned Pirate Insight explorer packages"
|
|
as_target_user mkdir -p "$explorer_dir"
|
|
as_target_user "$explorer_npm_bin" --prefix "$explorer_dir" install \
|
|
--omit=dev --no-audit --no-fund \
|
|
"git+https://github.com/PirateNetwork/bitcore-node-pirate.git#$DEFAULT_BITCORE_NODE_REF" \
|
|
"git+https://github.com/PirateNetwork/insight-api-pirate.git#$DEFAULT_INSIGHT_API_REF" \
|
|
"git+https://github.com/PirateNetwork/insight-ui-pirate.git#$DEFAULT_INSIGHT_UI_REF"
|
|
|
|
log "Writing Insight explorer configuration for the existing pirated service"
|
|
jq -n \
|
|
--arg rpc_user "$rpc_user" \
|
|
--arg rpc_pass "$rpc_pass" \
|
|
--arg rpc_port "$rpc_port" \
|
|
--arg zmq_endpoint "$rawtx_endpoint" \
|
|
--argjson web_port "$explorer_port" \
|
|
'{
|
|
network: "livenet",
|
|
port: $web_port,
|
|
services: ["bitcoind", "web", "insight-api-pirate", "insight-ui-pirate"],
|
|
servicesConfig: {
|
|
bitcoind: {
|
|
connect: [{
|
|
rpchost: "127.0.0.1",
|
|
rpcport: ($rpc_port | tonumber),
|
|
rpcuser: $rpc_user,
|
|
rpcpassword: $rpc_pass,
|
|
zmqpubrawtx: $zmq_endpoint
|
|
}]
|
|
},
|
|
"insight-api-pirate": {routePrefix: "insight-api-pirate"},
|
|
"insight-ui-pirate": {apiPrefix: "insight-api-pirate", routePrefix: ""}
|
|
}
|
|
}' | $sudo_cmd tee "$explorer_config" >/dev/null
|
|
$sudo_cmd chown "$TARGET_USER:$TARGET_USER" "$explorer_config"
|
|
$sudo_cmd chmod 600 "$explorer_config"
|
|
}
|
|
|
|
build_dnsseeder() {
|
|
if ! $ENABLE_DNSSEED; then
|
|
return
|
|
fi
|
|
|
|
sync_repo https://github.com/PirateNetwork/pirate-seeder "$dnsseed_dir" "$dnsseed_ref"
|
|
log "Building pirate-seeder"
|
|
as_target_user env DNSSEED_DIR="$dnsseed_dir" bash -s <<'EOF'
|
|
set -e
|
|
cd "$DNSSEED_DIR"
|
|
make -j"$(nproc)"
|
|
EOF
|
|
$sudo_cmd ln -sf "$dnsseed_dir/pirate-seeder" /usr/local/bin/pirate-seeder
|
|
$sudo_cmd mkdir -p "$dnsseed_data_dir"
|
|
$sudo_cmd chown "$TARGET_USER:$TARGET_USER" "$dnsseed_data_dir"
|
|
}
|
|
|
|
configure_optional_firewall() {
|
|
if ! command -v ufw >/dev/null 2>&1 || ! $sudo_cmd ufw status | grep -q "Status: active"; then
|
|
if $ENABLE_EXPLORER; then
|
|
log "UFW is not active; ensure your cloud/network firewall blocks TCP/$explorer_port so Insight is reachable only through nginx"
|
|
fi
|
|
return
|
|
fi
|
|
|
|
if [ "$USE_NGINX" = "true" ]; then
|
|
$sudo_cmd ufw allow 80/tcp >/dev/null
|
|
$sudo_cmd ufw allow 443/tcp >/dev/null
|
|
fi
|
|
if $ENABLE_EXPLORER; then
|
|
# bitcore-node-pirate listens on all interfaces, so nginx alone cannot
|
|
# prevent a direct HTTP listener from being reachable.
|
|
$sudo_cmd ufw deny "$explorer_port/tcp" >/dev/null
|
|
fi
|
|
if $ENABLE_DNSSEED; then
|
|
$sudo_cmd ufw allow "$dnsseed_port/udp" >/dev/null
|
|
$sudo_cmd ufw allow "$p2p_port/tcp" >/dev/null
|
|
fi
|
|
}
|
|
|
|
configure_nginx_minimal() {
|
|
if [ "$USE_NGINX" != "true" ]; then
|
|
return
|
|
fi
|
|
|
|
local server_names=""
|
|
if [ -n "$HOSTNAME" ]; then
|
|
server_names="$HOSTNAME"
|
|
fi
|
|
if $ENABLE_EXPLORER; then
|
|
server_names="${server_names:+$server_names }$explorer_hostname"
|
|
fi
|
|
|
|
log "Temporarily configuring nginx for Certbot challenge handling"
|
|
$sudo_cmd mkdir -p "$certbot_root"
|
|
$sudo_cmd chown -R "$TARGET_USER:$TARGET_USER" "$certbot_root"
|
|
cat <<EOF | $sudo_cmd tee /etc/nginx/sites-available/arrr-lightwalletd.conf >/dev/null
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name $server_names;
|
|
|
|
location ^~ /.well-known/acme-challenge/ {
|
|
root $certbot_root;
|
|
default_type "text/plain";
|
|
try_files \$uri =404;
|
|
}
|
|
|
|
location / {
|
|
return 301 https://\$host\$request_uri;
|
|
}
|
|
}
|
|
EOF
|
|
$sudo_cmd ln -sf /etc/nginx/sites-available/arrr-lightwalletd.conf /etc/nginx/sites-enabled/arrr-lightwalletd.conf
|
|
$sudo_cmd rm -f /etc/nginx/sites-enabled/default
|
|
$sudo_cmd nginx -t
|
|
$sudo_cmd systemctl reload nginx
|
|
}
|
|
|
|
configure_nginx_final() {
|
|
if [ "$USE_NGINX" != "true" ]; then
|
|
return
|
|
fi
|
|
|
|
local server_names=""
|
|
local lited_tls_block=""
|
|
local explorer_tls_block=""
|
|
if [ -n "$HOSTNAME" ]; then
|
|
server_names="$HOSTNAME"
|
|
fi
|
|
if $ENABLE_EXPLORER; then
|
|
server_names="${server_names:+$server_names }$explorer_hostname"
|
|
fi
|
|
|
|
log "Configuring nginx reverse proxy for $server_names"
|
|
$sudo_cmd mkdir -p "$certbot_root"
|
|
$sudo_cmd chown -R "$TARGET_USER:$TARGET_USER" "$certbot_root"
|
|
ensure_certbot_snippets
|
|
|
|
if [ -n "$HOSTNAME" ]; then
|
|
lited_tls_block="$(cat <<EOF
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name $HOSTNAME;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/$HOSTNAME/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/$HOSTNAME/privkey.pem;
|
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
|
|
grpc_connect_timeout 10s;
|
|
grpc_read_timeout 600s;
|
|
grpc_send_timeout 600s;
|
|
|
|
# --- Compatibility shim: old client -> new server
|
|
# Rewrite ONLY the gRPC :path (URI), leaving method name intact.
|
|
# OLD clients (cash.*) -> NEW server (pirate.*)
|
|
location ~ ^/cash\.z\.wallet\.sdk\.rpc\.CompactTxStreamer/(.*)$ {
|
|
rewrite ^/cash\.z\.wallet\.sdk\.rpc\.CompactTxStreamer/(.*)$ /pirate.wallet.sdk.rpc.CompactTxStreamer/\$1 break;
|
|
|
|
grpc_pass grpc://127.0.0.1:$lited_port;
|
|
grpc_set_header TE trailers;
|
|
|
|
grpc_set_header X-Real-IP \$remote_addr;
|
|
grpc_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
grpc_set_header X-Forwarded-Proto \$scheme;
|
|
}
|
|
|
|
# Native pirate namespace
|
|
location ^~ /pirate.wallet.sdk.rpc.CompactTxStreamer/ {
|
|
grpc_pass grpc://127.0.0.1:$lited_port;
|
|
grpc_set_header TE trailers;
|
|
|
|
grpc_set_header X-Real-IP \$remote_addr;
|
|
grpc_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
grpc_set_header X-Forwarded-Proto \$scheme;
|
|
}
|
|
|
|
# Catch-all: anything else passes through unchanged (reflection, health, etc.)
|
|
location / {
|
|
grpc_pass grpc://127.0.0.1:$lited_port;
|
|
|
|
grpc_set_header X-Real-IP \$remote_addr;
|
|
grpc_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
grpc_set_header X-Forwarded-Proto \$scheme;
|
|
grpc_set_header TE trailers;
|
|
}
|
|
|
|
location ^~ /.well-known/acme-challenge/ {
|
|
root $certbot_root;
|
|
default_type "text/plain";
|
|
try_files \$uri =404;
|
|
}
|
|
}
|
|
EOF
|
|
)"
|
|
fi
|
|
|
|
if $ENABLE_EXPLORER; then
|
|
explorer_tls_block="$(cat <<EOF
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name $explorer_hostname;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/$explorer_hostname/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/$explorer_hostname/privkey.pem;
|
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
|
|
location / {
|
|
proxy_pass http://127.0.0.1:$explorer_port;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host \$host;
|
|
proxy_set_header X-Real-IP \$remote_addr;
|
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
proxy_set_header Upgrade \$http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
}
|
|
|
|
location ^~ /.well-known/acme-challenge/ {
|
|
root $certbot_root;
|
|
default_type "text/plain";
|
|
try_files \$uri =404;
|
|
}
|
|
}
|
|
EOF
|
|
)"
|
|
fi
|
|
|
|
cat <<EOF | $sudo_cmd tee /etc/nginx/sites-available/arrr-lightwalletd.conf >/dev/null
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name $server_names;
|
|
|
|
location ^~ /.well-known/acme-challenge/ {
|
|
root $certbot_root;
|
|
default_type "text/plain";
|
|
try_files \$uri =404;
|
|
}
|
|
|
|
location / {
|
|
return 301 https://\$host\$request_uri;
|
|
}
|
|
}
|
|
$lited_tls_block
|
|
$explorer_tls_block
|
|
EOF
|
|
$sudo_cmd ln -sf /etc/nginx/sites-available/arrr-lightwalletd.conf /etc/nginx/sites-enabled/arrr-lightwalletd.conf
|
|
$sudo_cmd rm -f /etc/nginx/sites-enabled/default
|
|
$sudo_cmd nginx -t
|
|
$sudo_cmd systemctl reload nginx
|
|
}
|
|
|
|
obtain_letsencrypt_certificate() {
|
|
if ! $enable_lets_encrypt; then
|
|
return
|
|
fi
|
|
|
|
local certificate_hostname
|
|
local certificate_hostnames=()
|
|
if [ -n "$HOSTNAME" ]; then
|
|
certificate_hostnames+=("$HOSTNAME")
|
|
fi
|
|
if $ENABLE_EXPLORER; then
|
|
certificate_hostnames+=("$explorer_hostname")
|
|
fi
|
|
|
|
for certificate_hostname in "${certificate_hostnames[@]}"; do
|
|
if [ -f "/etc/letsencrypt/live/$certificate_hostname/fullchain.pem" ]; then
|
|
log "Let's Encrypt certificate already exists for $certificate_hostname"
|
|
continue
|
|
fi
|
|
log "Requesting Let's Encrypt certificate for $certificate_hostname"
|
|
$sudo_cmd certbot certonly --webroot --webroot-path "$certbot_root" \
|
|
--non-interactive --agree-tos --email "$EMAIL" -d "$certificate_hostname"
|
|
done
|
|
$sudo_cmd nginx -t
|
|
$sudo_cmd systemctl reload nginx
|
|
}
|
|
|
|
create_systemd_service() {
|
|
log "Writing systemd unit for pirated"
|
|
cat <<EOF | $sudo_cmd tee /etc/systemd/system/pirated.service >/dev/null
|
|
[Unit]
|
|
Description=Pirate Chain daemon
|
|
After=network.target
|
|
|
|
[Service]
|
|
User=$TARGET_USER
|
|
Group=$TARGET_USER
|
|
Environment=HOME=$TARGET_HOME
|
|
WorkingDirectory=$pirate_dir
|
|
ExecStart=/usr/local/bin/pirated
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
LimitNOFILE=8192
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
if $ENABLE_EXPLORER; then
|
|
log "Writing systemd unit for the Insight explorer"
|
|
cat <<EOF | $sudo_cmd tee /etc/systemd/system/arrr-explorer.service >/dev/null
|
|
[Unit]
|
|
Description=Pirate Chain Insight explorer
|
|
After=pirated.service network-online.target
|
|
Requires=pirated.service
|
|
|
|
[Service]
|
|
User=$TARGET_USER
|
|
Group=$TARGET_USER
|
|
Environment=HOME=$TARGET_HOME
|
|
Environment=NODE_ENV=production
|
|
WorkingDirectory=$explorer_dir
|
|
ExecStart=$explorer_node_bin $explorer_dir/node_modules/bitcore-node-pirate/bin/bitcore-node start --config "$explorer_dir"
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
LimitNOFILE=8192
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
fi
|
|
|
|
if $ENABLE_DNSSEED; then
|
|
local dnsseed_exec_args=""
|
|
local dnsseed_capabilities=""
|
|
local dnsseed_args=(
|
|
-h "$dnsseed_host"
|
|
-n "$dnsseed_ns"
|
|
-m "$dnsseed_mbox"
|
|
-p "$dnsseed_port"
|
|
--db "$dnsseed_data_dir/dnsseed.dat"
|
|
--pirate-conf "$conf_file"
|
|
)
|
|
if [ -n "$dnsseed_tor_proxy" ]; then
|
|
dnsseed_args+=(-o "$dnsseed_tor_proxy")
|
|
fi
|
|
printf -v dnsseed_exec_args ' %q' "${dnsseed_args[@]}"
|
|
if [ "$dnsseed_port" -lt 1024 ]; then
|
|
dnsseed_capabilities=$'CapabilityBoundingSet=CAP_NET_BIND_SERVICE\nAmbientCapabilities=CAP_NET_BIND_SERVICE'
|
|
fi
|
|
|
|
log "Writing systemd unit for pirate-seeder"
|
|
cat <<EOF | $sudo_cmd tee /etc/systemd/system/pirate-seeder.service >/dev/null
|
|
[Unit]
|
|
Description=Pirate Chain DNS seeder
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
User=$TARGET_USER
|
|
Group=$TARGET_USER
|
|
Environment=HOME=$TARGET_HOME
|
|
WorkingDirectory=$dnsseed_dir
|
|
ExecStart=/usr/local/bin/pirate-seeder$dnsseed_exec_args
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
LimitNOFILE=8192
|
|
$dnsseed_capabilities
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
fi
|
|
|
|
log "Writing systemd unit for lightwalletd"
|
|
$sudo_cmd mkdir -p "$log_dir"
|
|
$sudo_cmd chown "$TARGET_USER:$TARGET_USER" "$log_dir"
|
|
$sudo_cmd mkdir -p "$data_dir"
|
|
$sudo_cmd chown "$TARGET_USER:$TARGET_USER" "$data_dir"
|
|
printf -v lited_tls_flag_string ' %q' "${lited_tls_args[@]}"
|
|
cat <<EOF | $sudo_cmd tee /etc/systemd/system/lited.service >/dev/null
|
|
[Unit]
|
|
Description=ARRRwallet lightwalletd
|
|
After=pirated.service network.target
|
|
Requires=pirated.service
|
|
|
|
[Service]
|
|
User=$TARGET_USER
|
|
Group=$TARGET_USER
|
|
Environment=HOME=$TARGET_HOME
|
|
WorkingDirectory=$lightwalletd_dir
|
|
ExecStart=/usr/local/bin/lited --grpc-bind-addr "$bind_addr" --http-bind-addr "$http_bind_addr"${lited_tls_flag_string} --data-dir "$data_dir" --pirate-conf-path "$conf_file" --log-file "$log_dir/lited.log"
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
LimitNOFILE=8192
|
|
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
$sudo_cmd systemctl daemon-reload
|
|
$sudo_cmd systemctl enable pirated.service
|
|
$sudo_cmd systemctl enable lited.service
|
|
if $ENABLE_EXPLORER; then
|
|
$sudo_cmd systemctl enable arrr-explorer.service
|
|
fi
|
|
if $ENABLE_DNSSEED; then
|
|
$sudo_cmd systemctl enable pirate-seeder.service
|
|
fi
|
|
|
|
# `enable --now` does not restart an already-active service, which meant a
|
|
# previous version of this script could rebuild and relink binaries without
|
|
# actually applying an upgrade. Stop the dependent service first, then
|
|
# restart the daemon. Pirate 6.0.0 detects its raised minimum index version
|
|
# and automatically performs the required full reindex.
|
|
$sudo_cmd systemctl stop lited.service || true
|
|
if $ENABLE_EXPLORER; then
|
|
$sudo_cmd systemctl stop arrr-explorer.service || true
|
|
fi
|
|
$sudo_cmd systemctl restart pirated.service
|
|
$sudo_cmd systemctl restart lited.service
|
|
if $ENABLE_EXPLORER; then
|
|
$sudo_cmd systemctl restart arrr-explorer.service
|
|
fi
|
|
if $ENABLE_DNSSEED; then
|
|
$sudo_cmd systemctl restart pirate-seeder.service
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
install_base_packages
|
|
install_optional_network
|
|
install_optional_explorer_packages
|
|
configure_optional_firewall
|
|
install_go
|
|
install_explorer_node
|
|
sync_repo https://github.com/PirateNetwork/pirate "$pirate_dir" "$pirate_ref"
|
|
sync_repo https://github.com/PirateNetwork/lightwalletd "$lightwalletd_dir" "$lightwalletd_ref"
|
|
build_dnsseeder
|
|
build_pirate
|
|
link_binaries
|
|
create_pirate_conf
|
|
check_pirate_v6_configuration
|
|
configure_explorer_pirate_conf
|
|
install_and_configure_explorer
|
|
if [ "$USE_NGINX" = "true" ] && $enable_lets_encrypt; then
|
|
configure_nginx_minimal
|
|
fi
|
|
if $enable_lets_encrypt; then
|
|
obtain_letsencrypt_certificate
|
|
fi
|
|
if [ "$USE_NGINX" = "true" ]; then
|
|
configure_nginx_final
|
|
fi
|
|
build_lightwalletd
|
|
link_binaries
|
|
create_systemd_service
|
|
|
|
log "Setup completed. Pirate 6.0.0 will reindex existing chain data before it is fully synced."
|
|
if [ "$USE_NGINX" = "true" ]; then
|
|
if [ -n "$HOSTNAME" ]; then
|
|
log "nginx is proxying lightwalletd at $HOSTNAME. After DNS propagates, confirm certificates with 'sudo certbot certificates'."
|
|
fi
|
|
if $ENABLE_EXPLORER; then
|
|
log "Insight explorer is available at https://$explorer_hostname (service: arrr-explorer)."
|
|
fi
|
|
else
|
|
log "Lightwalletd gRPC is listening on $bind_addr and HTTP on $http_bind_addr; point clients at the matching endpoint."
|
|
fi
|
|
if $ENABLE_DNSSEED; then
|
|
log "DNS seeder is serving $dnsseed_host on UDP/$dnsseed_port (service: pirate-seeder)."
|
|
fi
|
|
}
|
|
|
|
main "$@"
|