2022-11-14 19:56:59 -08:00
|
|
|
|
#!/usr/bin/env bash
|
2015-12-15 00:26:04 -08:00
|
|
|
|
|
2020-10-28 06:13:40 -07:00
|
|
|
|
export LC_ALL=C
|
2015-12-15 00:26:04 -08:00
|
|
|
|
set -eu
|
|
|
|
|
|
2022-11-14 11:35:48 -08:00
|
|
|
|
SCRIPT_NAME=$(basename $0)
|
|
|
|
|
|
2023-01-26 13:31:09 -08:00
|
|
|
|
if [[ -z "${XDG_CACHE_HOME:+x}" ]]; then
|
|
|
|
|
XDG_CACHE_HOME="${HOME}/.cache"
|
|
|
|
|
fi
|
|
|
|
|
|
2022-11-14 11:35:48 -08:00
|
|
|
|
# We don’t care too much about most of the properties of `XDG_RUNTIME_DIR` in
|
|
|
|
|
# this script, so we just fall back to `XDG_CACHE_HOME`.
|
2023-01-26 13:31:09 -08:00
|
|
|
|
if [[ -z "${XDG_RUNTIME_DIR:+x}" ]]; then
|
|
|
|
|
XDG_RUNTIME_DIR="${XDG_CACHE_HOME}";
|
|
|
|
|
fi
|
2022-11-14 11:35:48 -08:00
|
|
|
|
|
2018-02-09 11:33:20 -08:00
|
|
|
|
uname_S=$(uname -s 2>/dev/null || echo not)
|
|
|
|
|
|
|
|
|
|
if [ "$uname_S" = "Darwin" ]; then
|
2017-12-17 09:18:03 -08:00
|
|
|
|
PARAMS_DIR="$HOME/Library/Application Support/ZcashParams"
|
|
|
|
|
else
|
|
|
|
|
PARAMS_DIR="$HOME/.zcash-params"
|
|
|
|
|
fi
|
2015-12-15 00:26:04 -08:00
|
|
|
|
|
2020-11-09 15:20:39 -08:00
|
|
|
|
# Commented out because these are unused; see below.
|
|
|
|
|
#SPROUT_PKEY_NAME='sprout-proving.key'
|
|
|
|
|
#SPROUT_VKEY_NAME='sprout-verifying.key'
|
2018-08-04 15:28:39 -07:00
|
|
|
|
SAPLING_SPEND_NAME='sapling-spend.params'
|
|
|
|
|
SAPLING_OUTPUT_NAME='sapling-output.params'
|
|
|
|
|
SAPLING_SPROUT_GROTH16_NAME='sprout-groth16.params'
|
2023-02-15 18:07:33 -08:00
|
|
|
|
DOWNLOAD_URL="${ALTERNATIVE_DOWNLOAD_URL:-https://download.z.cash/downloads}"
|
2019-09-12 20:30:31 -07:00
|
|
|
|
IPFS_HASH="/ipfs/QmXRHVGLQBiKwvNq7c2vPxAKz1zRVmMYbmt7G5TQss7tY7"
|
2016-01-19 08:17:04 -08:00
|
|
|
|
|
2016-10-24 14:39:52 -07:00
|
|
|
|
SHA256CMD="$(command -v sha256sum || echo shasum)"
|
2021-12-16 13:54:48 -08:00
|
|
|
|
SHA256ARGS="$(command -v sha256sum >/dev/null || echo '-a 256')"
|
2016-10-24 14:39:52 -07:00
|
|
|
|
|
2017-08-27 14:46:24 -07:00
|
|
|
|
WGETCMD="$(command -v wget || echo '')"
|
|
|
|
|
IPFSCMD="$(command -v ipfs || echo '')"
|
2017-12-17 08:30:19 -08:00
|
|
|
|
CURLCMD="$(command -v curl || echo '')"
|
2017-08-27 14:46:24 -07:00
|
|
|
|
|
|
|
|
|
# fetch methods can be disabled with ZC_DISABLE_SOMETHING=1
|
|
|
|
|
ZC_DISABLE_WGET="${ZC_DISABLE_WGET:-}"
|
|
|
|
|
ZC_DISABLE_IPFS="${ZC_DISABLE_IPFS:-}"
|
2017-12-17 08:30:19 -08:00
|
|
|
|
ZC_DISABLE_CURL="${ZC_DISABLE_CURL:-}"
|
2017-08-27 14:46:24 -07:00
|
|
|
|
|
2022-11-14 11:35:48 -08:00
|
|
|
|
LOCK_DIR="${XDG_RUNTIME_DIR}/zcash"
|
|
|
|
|
mkdir -p "${LOCK_DIR}"
|
|
|
|
|
LOCKFILE="${LOCK_DIR}/fetch-params.lock"
|
2021-03-31 18:28:41 -07:00
|
|
|
|
|
2018-02-09 11:33:20 -08:00
|
|
|
|
fetch_wget() {
|
2022-08-19 15:40:02 -07:00
|
|
|
|
if [ -z "$WGETCMD" ] || [ -n "$ZC_DISABLE_WGET" ]; then
|
2017-08-27 14:46:24 -07:00
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
cat <<EOF
|
|
|
|
|
|
2021-03-31 18:28:41 -07:00
|
|
|
|
Retrieving (wget): $DOWNLOAD_URL/$1
|
2017-08-27 14:46:24 -07:00
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
wget \
|
|
|
|
|
--progress=dot:giga \
|
2021-03-31 18:28:41 -07:00
|
|
|
|
--output-document="$2" \
|
2017-08-27 14:46:24 -07:00
|
|
|
|
--continue \
|
|
|
|
|
--retry-connrefused --waitretry=3 --timeout=30 \
|
2021-03-31 18:28:41 -07:00
|
|
|
|
"$DOWNLOAD_URL/$1"
|
2017-08-27 14:46:24 -07:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-09 11:33:20 -08:00
|
|
|
|
fetch_ipfs() {
|
2022-08-19 15:40:02 -07:00
|
|
|
|
if [ -z "$IPFSCMD" ] || [ -n "$ZC_DISABLE_IPFS" ]; then
|
2017-08-27 14:46:24 -07:00
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
cat <<EOF
|
|
|
|
|
|
2021-03-31 18:28:41 -07:00
|
|
|
|
Retrieving (ipfs): $IPFS_HASH/$1
|
2017-08-27 14:46:24 -07:00
|
|
|
|
EOF
|
|
|
|
|
|
2021-03-31 18:28:41 -07:00
|
|
|
|
ipfs get --output "$2" "$IPFS_HASH/$1"
|
2017-08-27 14:46:24 -07:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-09 11:33:20 -08:00
|
|
|
|
fetch_curl() {
|
2022-08-19 15:40:02 -07:00
|
|
|
|
if [ -z "$CURLCMD" ] || [ -n "$ZC_DISABLE_CURL" ]; then
|
2017-12-17 08:30:19 -08:00
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
cat <<EOF
|
|
|
|
|
|
2021-03-31 18:28:41 -07:00
|
|
|
|
Retrieving (curl): $DOWNLOAD_URL/$1
|
2017-12-17 08:30:19 -08:00
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
curl \
|
2021-03-31 18:28:41 -07:00
|
|
|
|
--output "$2" \
|
2017-12-17 08:30:19 -08:00
|
|
|
|
-# -L -C - \
|
2021-03-31 18:28:41 -07:00
|
|
|
|
"$DOWNLOAD_URL/$1"
|
2017-12-17 08:30:19 -08:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-09 11:33:20 -08:00
|
|
|
|
fetch_failure() {
|
2017-08-27 14:46:24 -07:00
|
|
|
|
cat >&2 <<EOF
|
|
|
|
|
|
|
|
|
|
Failed to fetch the Zcash zkSNARK parameters!
|
|
|
|
|
Try installing one of the following programs and make sure you're online:
|
|
|
|
|
|
|
|
|
|
* ipfs
|
|
|
|
|
* wget
|
2017-12-17 08:30:19 -08:00
|
|
|
|
* curl
|
2017-08-27 14:46:24 -07:00
|
|
|
|
|
|
|
|
|
EOF
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-09 11:33:20 -08:00
|
|
|
|
fetch_params() {
|
2021-03-31 18:28:41 -07:00
|
|
|
|
# We only set these variables inside this function,
|
|
|
|
|
# and unset them at the end of the function.
|
|
|
|
|
filename="$1"
|
|
|
|
|
output="$2"
|
|
|
|
|
dlname="${output}.dl"
|
|
|
|
|
expectedhash="$3"
|
2016-01-22 09:37:24 -08:00
|
|
|
|
|
2016-01-28 13:38:30 -08:00
|
|
|
|
if ! [ -f "$output" ]
|
2015-12-15 00:26:04 -08:00
|
|
|
|
then
|
2019-08-13 16:38:26 -07:00
|
|
|
|
for i in 1 2
|
|
|
|
|
do
|
|
|
|
|
for method in wget ipfs curl failure; do
|
|
|
|
|
if "fetch_$method" "${filename}.part.${i}" "${dlname}.part.${i}"; then
|
|
|
|
|
echo "Download of part ${i} successful!"
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
for i in 1 2
|
|
|
|
|
do
|
|
|
|
|
if ! [ -f "${dlname}.part.${i}" ]
|
|
|
|
|
then
|
|
|
|
|
fetch_failure
|
2017-08-27 14:46:24 -07:00
|
|
|
|
fi
|
|
|
|
|
done
|
2016-01-22 09:37:24 -08:00
|
|
|
|
|
2019-08-13 16:38:26 -07:00
|
|
|
|
cat "${dlname}.part.1" "${dlname}.part.2" > "${dlname}"
|
|
|
|
|
rm "${dlname}.part.1" "${dlname}.part.2"
|
|
|
|
|
|
2023-02-16 16:55:59 -08:00
|
|
|
|
set +e
|
2016-11-20 10:04:51 -08:00
|
|
|
|
"$SHA256CMD" $SHA256ARGS -c <<EOF
|
2016-10-03 14:58:02 -07:00
|
|
|
|
$expectedhash $dlname
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
# Check the exit code of the shasum command:
|
|
|
|
|
CHECKSUM_RESULT=$?
|
2023-02-16 16:55:59 -08:00
|
|
|
|
set -e
|
2016-10-03 14:58:02 -07:00
|
|
|
|
if [ $CHECKSUM_RESULT -eq 0 ]; then
|
|
|
|
|
mv -v "$dlname" "$output"
|
|
|
|
|
else
|
2017-08-27 14:46:24 -07:00
|
|
|
|
echo "Failed to verify parameter checksums!" >&2
|
|
|
|
|
exit 1
|
2016-10-03 14:58:02 -07:00
|
|
|
|
fi
|
2015-12-15 00:26:04 -08:00
|
|
|
|
fi
|
2021-03-31 18:28:41 -07:00
|
|
|
|
|
|
|
|
|
unset -v filename
|
|
|
|
|
unset -v output
|
|
|
|
|
unset -v dlname
|
|
|
|
|
unset -v expectedhash
|
2015-12-15 00:26:04 -08:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-16 17:01:14 -08:00
|
|
|
|
check_and_fetch_params() {
|
|
|
|
|
# We only set these variables inside this function,
|
|
|
|
|
# and unset them at the end of the function.
|
|
|
|
|
filename="$1"
|
|
|
|
|
output="$2"
|
|
|
|
|
expectedhash="$3"
|
|
|
|
|
|
|
|
|
|
if ! [ -f "$output" ]
|
|
|
|
|
then
|
|
|
|
|
fetch_params "$filename" "$output" "$expectedhash"
|
|
|
|
|
else
|
|
|
|
|
# The file in question exists, so we verify its checksum.
|
|
|
|
|
# If it's not valid, we delete it and fetch it
|
|
|
|
|
set +e
|
|
|
|
|
"$SHA256CMD" $SHA256ARGS -c <<EOF
|
|
|
|
|
$expectedhash $output
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
# Check the exit code of the shasum command:
|
|
|
|
|
CHECKSUM_RESULT=$?
|
|
|
|
|
set -e
|
|
|
|
|
if [ $CHECKSUM_RESULT -eq 0 ]; then
|
|
|
|
|
echo "Parameter file ${filename} has a valid checksum, continuing."
|
|
|
|
|
else
|
|
|
|
|
echo "Parameter file ${filename} has a invalid checksum, deleting and re-downloading." >&2
|
|
|
|
|
rm "$output"
|
|
|
|
|
fetch_params "$filename" "$output" "$expectedhash"
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
unset -v filename
|
|
|
|
|
unset -v output
|
|
|
|
|
unset -v expectedhash
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-22 03:08:42 -07:00
|
|
|
|
# Use flock to prevent parallel execution.
|
2018-02-09 11:33:20 -08:00
|
|
|
|
lock() {
|
|
|
|
|
if [ "$uname_S" = "Darwin" ]; then
|
2021-03-31 18:28:41 -07:00
|
|
|
|
if shlock -f ${LOCKFILE} -p $$; then
|
2017-12-17 09:18:03 -08:00
|
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
# create lock file
|
2021-03-31 18:28:41 -07:00
|
|
|
|
eval "exec 9>$LOCKFILE"
|
2017-12-17 09:18:03 -08:00
|
|
|
|
# acquire the lock
|
2018-02-09 11:33:20 -08:00
|
|
|
|
flock -n 9 \
|
2017-12-17 09:18:03 -08:00
|
|
|
|
&& return 0 \
|
|
|
|
|
|| return 1
|
|
|
|
|
fi
|
2016-09-22 03:08:42 -07:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-09 11:33:20 -08:00
|
|
|
|
exit_locked_error() {
|
2022-11-14 11:35:48 -08:00
|
|
|
|
echo "Only one instance of ${SCRIPT_NAME} can be run at a time." >&2
|
|
|
|
|
echo "If you are certain no other instance is running, you can try removing" >&2
|
|
|
|
|
echo "${LOCKFILE}" >&2
|
2016-09-22 03:08:42 -07:00
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-09 11:33:20 -08:00
|
|
|
|
main() {
|
2016-09-22 03:08:42 -07:00
|
|
|
|
|
2022-11-14 11:35:48 -08:00
|
|
|
|
lock \
|
2016-09-22 03:08:42 -07:00
|
|
|
|
|| exit_locked_error
|
|
|
|
|
|
|
|
|
|
cat <<EOF
|
2022-11-14 11:35:48 -08:00
|
|
|
|
Zcash - ${SCRIPT_NAME}
|
2015-12-15 00:26:04 -08:00
|
|
|
|
|
2016-11-02 11:06:55 -07:00
|
|
|
|
This script will fetch the Zcash zkSNARK parameters and verify their
|
|
|
|
|
integrity with sha256sum.
|
|
|
|
|
|
2023-02-16 17:01:14 -08:00
|
|
|
|
If the files are already present and have the correct sha256sum, no
|
|
|
|
|
networking is used. Parameter files with incorrect sha256sums are
|
|
|
|
|
deleted and re-downloaded.
|
|
|
|
|
|
2015-12-15 00:26:04 -08:00
|
|
|
|
EOF
|
|
|
|
|
|
2016-09-22 03:08:42 -07:00
|
|
|
|
# Now create PARAMS_DIR and insert a README if necessary:
|
|
|
|
|
if ! [ -d "$PARAMS_DIR" ]
|
|
|
|
|
then
|
|
|
|
|
mkdir -p "$PARAMS_DIR"
|
|
|
|
|
README_PATH="$PARAMS_DIR/README"
|
|
|
|
|
cat >> "$README_PATH" <<EOF
|
|
|
|
|
This directory stores common Zcash zkSNARK parameters. Note that it is
|
2015-12-15 00:26:04 -08:00
|
|
|
|
distinct from the daemon's -datadir argument because the parameters are
|
|
|
|
|
large and may be shared across multiple distinct -datadir's such as when
|
|
|
|
|
setting up test networks.
|
|
|
|
|
EOF
|
|
|
|
|
|
2016-09-22 03:08:42 -07:00
|
|
|
|
# This may be the first time the user's run this script, so give
|
|
|
|
|
# them some info, especially about bandwidth usage:
|
|
|
|
|
cat <<EOF
|
2022-12-05 23:08:08 -08:00
|
|
|
|
The complete parameters are currently just under 800MB in size, so plan
|
|
|
|
|
accordingly for your bandwidth constraints. If the files are already
|
|
|
|
|
present and have the correct sha256sum, no networking is used.
|
2015-12-15 00:26:04 -08:00
|
|
|
|
|
|
|
|
|
Creating params directory. For details about this directory, see:
|
|
|
|
|
$README_PATH
|
|
|
|
|
|
|
|
|
|
EOF
|
2016-09-22 03:08:42 -07:00
|
|
|
|
fi
|
2015-12-15 00:26:04 -08:00
|
|
|
|
|
2016-09-22 03:08:42 -07:00
|
|
|
|
cd "$PARAMS_DIR"
|
2016-01-28 13:38:30 -08:00
|
|
|
|
|
2018-08-04 15:28:39 -07:00
|
|
|
|
# Sprout parameters:
|
2019-09-17 04:00:03 -07:00
|
|
|
|
# Commented out because they are unneeded, but we will eventually update
|
|
|
|
|
# this to delete the parameters if possible.
|
|
|
|
|
#fetch_params "$SPROUT_PKEY_NAME" "$PARAMS_DIR/$SPROUT_PKEY_NAME" "8bc20a7f013b2b58970cddd2e7ea028975c88ae7ceb9259a5344a16bc2c0eef7"
|
|
|
|
|
#fetch_params "$SPROUT_VKEY_NAME" "$PARAMS_DIR/$SPROUT_VKEY_NAME" "4bd498dae0aacfd8e98dc306338d017d9c08dd0918ead18172bd0aec2fc5df82"
|
2018-04-17 13:44:53 -07:00
|
|
|
|
|
2018-08-04 15:28:39 -07:00
|
|
|
|
# Sapling parameters:
|
2023-02-16 17:01:14 -08:00
|
|
|
|
check_and_fetch_params "$SAPLING_SPEND_NAME" "$PARAMS_DIR/$SAPLING_SPEND_NAME" "8e48ffd23abb3a5fd9c5589204f32d9c31285a04b78096ba40a79b75677efc13"
|
|
|
|
|
check_and_fetch_params "$SAPLING_OUTPUT_NAME" "$PARAMS_DIR/$SAPLING_OUTPUT_NAME" "2f0ebbcbb9bb0bcffe95a397e7eba89c29eb4dde6191c339db88570e3f3fb0e4"
|
|
|
|
|
check_and_fetch_params "$SAPLING_SPROUT_GROTH16_NAME" "$PARAMS_DIR/$SAPLING_SPROUT_GROTH16_NAME" "b685d700c60328498fbde589c8c7c484c722b788b265b72af448a5bf0ee55b50"
|
2016-09-22 03:08:42 -07:00
|
|
|
|
}
|
2016-01-19 08:17:04 -08:00
|
|
|
|
|
2022-11-14 19:56:59 -08:00
|
|
|
|
if [ "${1:-}" = '--testnet' ]
|
2018-08-22 12:19:10 -07:00
|
|
|
|
then
|
|
|
|
|
echo "NOTE: testnet now uses the mainnet parameters, so the --testnet argument"
|
|
|
|
|
echo "is no longer needed (ignored)"
|
|
|
|
|
echo ""
|
|
|
|
|
fi
|
|
|
|
|
|
2018-08-04 15:28:39 -07:00
|
|
|
|
main
|
2021-03-31 18:28:41 -07:00
|
|
|
|
rm -f $LOCKFILE
|
2016-09-22 03:08:42 -07:00
|
|
|
|
exit 0
|