diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1d9260826d..9c3c46e5eb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -45,6 +45,9 @@ jobs: with: go-version: '${{ env.GO_VERSION }}' + - name: Check default values in sample-btcwallet.conf file + run: make sample-conf-check + - name: Check code format run: make fmt-check diff --git a/Makefile b/Makefile index 20e34a84e7..ff113ebc36 100644 --- a/Makefile +++ b/Makefile @@ -131,6 +131,11 @@ lint: $(LINT_BIN) @$(call print, "Linting source.") $(LINT) +#? sample-conf-check: Make sure default values in the sample-btcwallet.conf file are set correctly +sample-conf-check: install + @$(call print, "Checking that default values in the sample-btcwallet.conf file are set correctly") + scripts/check-sample-btcwallet-conf.sh + #? clean: Clean source clean: @$(call print, "Cleaning source.$(NC)") @@ -155,6 +160,7 @@ tidy-module-check: tidy-module fmt \ fmt-check \ lint \ + sample-conf-check \ clean #? help: Get more info on make commands diff --git a/sample-btcwallet.conf b/sample-btcwallet.conf index 6371ae782c..cddd939135 100644 --- a/sample-btcwallet.conf +++ b/sample-btcwallet.conf @@ -21,6 +21,9 @@ ; used in this directory for mainnet and testnet wallets, respectively. ; appdata=~/.btcwallet +; DEPRECATED -- use appdata instead. +; datadir= + ; ------------------------------------------------------------------------------ ; RPC client settings @@ -64,14 +67,15 @@ ; modified by some options such as 'testnet', so it is recommended to not ; specify a port and allow a proper default to be chosen unless you have a ; specific reason to do otherwise. -; rpclisten= ; all interfaces on default port +; Default: +; rpclisten= ; rpclisten=0.0.0.0 ; all ipv4 interfaces on default port ; rpclisten=:: ; all ipv6 interfaces on default port ; rpclisten=:8332 ; all interfaces on port 8332 ; rpclisten=0.0.0.0:8332 ; all ipv4 interfaces on port 8332 ; rpclisten=[::]:8332 ; all ipv6 interfaces on port 8332 -; rpclisten=127.0.0.1:8332 ; only ipv4 localhost on port 8332 (this is a default) -; rpclisten=[::1]:8332 ; only ipv6 localhost on port 8332 (this is a default) +; rpclisten=127.0.0.1:8332 ; only ipv4 localhost on port 8332 +; rpclisten=[::1]:8332 ; only ipv6 localhost on port 8332 ; rpclisten=127.0.0.1:8337 ; only ipv4 localhost on non-standard port 8337 ; rpclisten=:8337 ; all interfaces on non-standard port 8337 ; rpclisten=0.0.0.0:8337 ; all ipv4 interfaces on non-standard port 8337 @@ -116,3 +120,87 @@ ; be disabled if this option is not specified. The profile information can be ; accessed at http://localhost:/debug/pprof once running. ; profile=6062 + +; Directory to log output. +; logdir=~/.btcwallet/logs + + +; ------------------------------------------------------------------------------ +; Wallet settings +; ------------------------------------------------------------------------------ + +; The timeout value to use when opening the wallet database. +; dbtimeout=1m + +; The public wallet password -- Only required if the wallet was created with one. +; walletpass= + +; Create the wallet if it does not exist. +; create=0 + +; Create a temporary simulation wallet (pass=password) in the data directory indicated. +; createtemp=0 + +; Defer wallet creation/opening on startup and enable loading wallets over RPC. +; noinitialload=0 + + +; ------------------------------------------------------------------------------ +; Peer-to-peer networking +; ------------------------------------------------------------------------------ + +; Enables the experimental use of SPV rather than RPC for chain synchronization. +; usespv=0 + +; Add a peer to connect with at startup. +; addpeer= + +; Connect only to the specified peers at startup. +; connect= + +; Max number of inbound and outbound peers. +; maxpeers=125 + +; How long to ban misbehaving peers. Valid time units are {s, m, h}. +; banduration=24h + +; Maximum allowed ban score before disconnecting and banning misbehaving peers. +; banthreshold=100 + + +; ------------------------------------------------------------------------------ +; Alternative networks +; ------------------------------------------------------------------------------ + +; Use the signet test network. +; signet=0 + +; Connect to a custom signet network defined by this challenge instead of using +; the global default signet test network. +; signetchallenge= + +; Specify a seed node for the signet network instead of using the global default +; signet network seed nodes. +; signetseednode= + + +; ------------------------------------------------------------------------------ +; Advanced RPC settings +; ------------------------------------------------------------------------------ + +; Disable TLS for the RPC client -- NOTE: This is only allowed if the RPC client +; is connecting to localhost. +; noclienttls=0 + +; Disable TLS for the RPC server -- NOTE: This is only allowed if the RPC server +; is bound to localhost. +; noservertls=0 + +; Max number of legacy RPC clients for standard connections. +; rpcmaxclients=10 + +; Max number of legacy RPC websocket connections. +; rpcmaxwebsockets=25 + +; Listen for RPC connections on this interface/port. +; experimentalrpclisten= diff --git a/scripts/check-sample-btcwallet-conf.sh b/scripts/check-sample-btcwallet-conf.sh new file mode 100755 index 0000000000..73072dab5b --- /dev/null +++ b/scripts/check-sample-btcwallet-conf.sh @@ -0,0 +1,163 @@ +#!/bin/bash + +# This script performs different checks on the sample-btcwallet.conf file: +# 1. Checks that all relevant options of btcwallet are included. +# 2. Verifies that defaults are labeled if there are also further examples. +# 3. Checks that all default values of btcwallet are mentioned correctly, +# including empty defaults and booleans which are set to false by default. + +set -e + +CONF_FILE=${1:-sample-btcwallet.conf} + +# Get the directory containing this script. +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_DIR="$(dirname "$SCRIPT_DIR")" +SAMPLE_CONF="$REPO_DIR/$CONF_FILE" + +# Check if sample config file exists. +if [ ! -f "$SAMPLE_CONF" ]; then + echo "ERROR: $CONF_FILE not found at $SAMPLE_CONF" + exit 1 +fi + +BTCWALLET_BIN="btcwallet" + +# Get btcwallet help output. +FILE_TMP=$(mktemp) +"$BTCWALLET_BIN" --help > "$FILE_TMP" 2>&1 || true +BTCWALLET_HELP="$(cat $FILE_TMP) --end" + +# BTCWALLET_OPTIONS is a list of all options of btcwallet including the equal +# sign, which is needed to distinguish between booleans and other variables. It +# is created by reading the first two columns of btcwallet --help. +BTCWALLET_OPTIONS="$(cat $FILE_TMP | \ + awk '{ + option=""; + if ($1 ~ /^--/){option=$1}; + if ($2 ~ /^--/){option=$2}; + if (match(option, /--[^=]+[=]*/)) + {printf "%s ", substr(option, RSTART, RLENGTH)} + } + END { printf "%s", "--end"}')" +rm $FILE_TMP + +# OPTIONS_NO_CONF is a list of all options without any expected entries in +# sample-btcwallet.conf. There's no validation needed for these options. +OPTIONS_NO_CONF="help version configfile end" + +# OPTIONS_NO_BTCWALLET_DEFAULT_VALUE_CHECK is a list of options with default +# values set, but there aren't any returned defaults by btcwallet --help. +# Defaults have to be included in sample-btcwallet.conf but no further checks +# are performed. +OPTIONS_NO_BTCWALLET_DEFAULT_VALUE_CHECK="rpclisten legacyrpclisten experimentalrpclisten profile rpcconnect cafile proxy" + +# EXITCODE is returned at the end after all checks are performed and set to 1 if +# a validation error occurs. COUNTER counts the checked options. +EXITCODE=0 +COUNTER=0 + +echo "Checking $CONF_FILE..." + +for OPTION in $BTCWALLET_OPTIONS; do + # Determination of the clean name of the option without leading -- and + # possible = at the end. + OPTION_NAME=${OPTION##--} + OPTION_NAME=${OPTION_NAME%=} + + # Skip if there is no expected entry in sample-btcwallet.conf. + echo "$OPTIONS_NO_CONF" | grep -qw $OPTION_NAME && continue + COUNTER=$((COUNTER+1)) + + # Determine the default value of btcwallet. If the option has no equal sign, + # it is boolean and set to false. + # For other options we grep the text between the current option and the next + # option from BTCWALLET_HELP. The default value is given in brackets + # (default: xx) In the case of durations expressed in hours or minutes, the + # indications of '0m0s' and '0s' are removed, as they provide redundant + # information. HOME is replaced with general values. + if [[ "$OPTION" == *"="* ]]; then + OPTION_NEXT="$(echo "$BTCWALLET_OPTIONS" | sed -E -e "s/.*$OPTION //" \ + -e "s/([^ ]*).*/\1/")" + DEFAULT_VALUE_BTCWALLET="$(echo $BTCWALLET_HELP | \ + sed -E -e "s/.*--${OPTION##--}//" \ + -e "s/--${OPTION_NEXT##--}.*//" \ + -e '/(default:.*)/ {' \ + -e 's/.*\(default: ([^)]*)\).*/\1/' -e 't end' -e '}' \ + -e 's/.*//' -e ':end' \ + -e "s#m0s#m#g" \ + -e "s#h0m#h#g" \ + -e "s#$HOME#~#g")" + else + DEFAULT_VALUE_BTCWALLET="false" + fi + + # An option is considered included in the sample-btcwallet.conf if there is + # a match of the following regex. + OPTION_REGEX="^;[ ]*$OPTION_NAME=[^ ]*$" + + # Perform the different checks now. If one fails we move to the next option. + # 1. check if the option is included in the sample-btcwallet.conf. + if [ $(grep -c "$OPTION_REGEX" $SAMPLE_CONF) -eq 0 ]; then + echo "Option $OPTION_NAME: no default or example included in $CONF_FILE" + EXITCODE=1 + continue + fi + + # Skip if no default value check should be performed. + echo "$OPTIONS_NO_BTCWALLET_DEFAULT_VALUE_CHECK" | grep -wq $OPTION_NAME && continue + + # 2. Check that the default value is labeled if it is included multiple + # times. + if [ $(grep -c "$OPTION_REGEX" $SAMPLE_CONF) -ge 2 ]; then + # For one option there has to be a preceding line "; Default:" + # If it matches we grep the default value from the file. + if grep -A 1 "^; Default:" $SAMPLE_CONF | grep -q "$OPTION_REGEX"; then + DEFAULT_VALUE_CONF="$(grep -A 1 "^; Default:" $SAMPLE_CONF | \ + grep "$OPTION_REGEX" | cut -d= -f2)" + + else + echo "Option $OPTION_NAME: mentioned multiple times in $CONF_FILE but without a default value" + EXITCODE=1 + continue + fi + else + # If there is only one entry in sample-btcwallet.conf we grep the + # default value. + DEFAULT_VALUE_CONF=$(grep "$OPTION_REGEX" $SAMPLE_CONF | cut -d= -f2) + fi + + # 3. Compare the default value of btcwallet --help with the value in the + # sample-btcwallet.conf file. If btcwallet doesn't provide a default value, + # it is allowed for the value in the file to be '0' or '0s'. For boolean + # options, allow both 'false' and '0' representations. + if [ ! "$DEFAULT_VALUE_BTCWALLET" == "$DEFAULT_VALUE_CONF" ]; then + + if [ -z "$DEFAULT_VALUE_BTCWALLET" ] && [ "$DEFAULT_VALUE_CONF" == "0" ]; then + true + + elif [ -z "$DEFAULT_VALUE_BTCWALLET" ] && [ "$DEFAULT_VALUE_CONF" == "0s" ]; then + true + + elif [ "$DEFAULT_VALUE_BTCWALLET" == "false" ] && [ "$DEFAULT_VALUE_CONF" == "0" ]; then + true + + else + echo "Option $OPTION_NAME: defaults don't match - $CONF_FILE: '$DEFAULT_VALUE_CONF', btcwallet: '$DEFAULT_VALUE_BTCWALLET'" + EXITCODE=1 + continue + fi + fi + +done + +echo "$COUNTER options were checked" + +if [ $EXITCODE -eq 0 ]; then + echo "SUCCESS: All btcwallet configuration options are present and correctly configured in $CONF_FILE" + echo "$CONF_FILE validation completed successfully!" +else + echo "ERROR: Configuration validation failed" +fi + +exit $EXITCODE \ No newline at end of file