diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index af43531b303..54529dd9487 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -35,13 +35,13 @@ set -o pipefail # if ${RPC_PORT} is not set and ${FEATURES} contains getblocktemplate-rpcs, # set ${RPC_PORT} to the default value for the current network if [[ -z "${RPC_PORT}" ]]; then - if [[ " ${FEATURES} " =~ " getblocktemplate-rpcs " ]]; then - if [[ "${NETWORK}" = "Mainnet" ]]; then - : "${RPC_PORT:=8232}" - elif [[ "${NETWORK}" = "Testnet" ]]; then - : "${RPC_PORT:=18232}" - fi + if [[ " ${FEATURES} " =~ " getblocktemplate-rpcs " ]]; then + if [[ "${NETWORK}" = "Mainnet" ]]; then + : "${RPC_PORT:=8232}" + elif [[ "${NETWORK}" = "Testnet" ]]; then + : "${RPC_PORT:=18232}" fi + fi fi #### @@ -69,7 +69,7 @@ fi # Configuration file path if [[ -n "${ZEBRA_CONF_DIR}" ]] && [[ -n "${ZEBRA_CONF_FILE}" ]]; then - ZEBRA_CONF_PATH="${ZEBRA_CONF_DIR}/${ZEBRA_CONF_FILE}" + ZEBRA_CONF_PATH="${ZEBRA_CONF_DIR}/${ZEBRA_CONF_FILE}" fi # Populate `zebrad.toml` before starting zebrad, using the environmental @@ -78,11 +78,11 @@ fi # We disable most ports by default, so the default config is secure. # Users have to opt-in to additional functionality by setting environmental variables. if [[ -n "${ZEBRA_CONF_PATH}" ]] && [[ ! -f "${ZEBRA_CONF_PATH}" ]]; then - # Create the conf path and file - mkdir -p "${ZEBRA_CONF_DIR}" || { echo "Error creating directory ${ZEBRA_CONF_DIR}"; exit 1; } - touch "${ZEBRA_CONF_PATH}" || { echo "Error creating file ${ZEBRA_CONF_PATH}"; exit 1; } - # Populate the conf file - cat < "${ZEBRA_CONF_PATH}" + # Create the conf path and file + mkdir -p "${ZEBRA_CONF_DIR}" || { echo "Error creating directory ${ZEBRA_CONF_DIR}"; exit 1; } + touch "${ZEBRA_CONF_PATH}" || { echo "Error creating file ${ZEBRA_CONF_PATH}"; exit 1; } + # Populate the conf file + cat < "${ZEBRA_CONF_PATH}" [network] network = "${NETWORK}" listen_addr = "${ZEBRA_LISTEN_ADDR}" @@ -90,56 +90,56 @@ listen_addr = "${ZEBRA_LISTEN_ADDR}" cache_dir = "${ZEBRA_CACHED_STATE_DIR}" EOF - if [[ " ${FEATURES} " =~ " prometheus " ]]; then # spaces are important here to avoid partial matches - cat <> "${ZEBRA_CONF_PATH}" + if [[ " ${FEATURES} " =~ " prometheus " ]]; then # spaces are important here to avoid partial matches + cat <> "${ZEBRA_CONF_PATH}" [metrics] endpoint_addr = "${METRICS_ENDPOINT_ADDR}:${METRICS_ENDPOINT_PORT}" EOF - fi + fi - if [[ -n "${RPC_PORT}" ]]; then - cat <> "${ZEBRA_CONF_PATH}" + if [[ -n "${RPC_PORT}" ]]; then + cat <> "${ZEBRA_CONF_PATH}" [rpc] listen_addr = "${RPC_LISTEN_ADDR}:${RPC_PORT}" EOF - fi + fi - if [[ -n "${LOG_FILE}" ]] || [[ -n "${LOG_COLOR}" ]] || [[ -n "${TRACING_ENDPOINT_ADDR}" ]]; then - cat <> "${ZEBRA_CONF_PATH}" + if [[ -n "${LOG_FILE}" ]] || [[ -n "${LOG_COLOR}" ]] || [[ -n "${TRACING_ENDPOINT_ADDR}" ]]; then + cat <> "${ZEBRA_CONF_PATH}" [tracing] EOF - if [[ " ${FEATURES} " =~ " filter-reload " ]]; then # spaces are important here to avoid partial matches - cat <> "${ZEBRA_CONF_PATH}" + if [[ " ${FEATURES} " =~ " filter-reload " ]]; then # spaces are important here to avoid partial matches + cat <> "${ZEBRA_CONF_PATH}" endpoint_addr = "${TRACING_ENDPOINT_ADDR}:${TRACING_ENDPOINT_PORT}" EOF - fi - # Set this to log to a file, if not set, logs to standard output - if [[ -n "${LOG_FILE}" ]]; then - mkdir -p "$(dirname "${LOG_FILE}")" - cat <> "${ZEBRA_CONF_PATH}" + fi + # Set this to log to a file, if not set, logs to standard output + if [[ -n "${LOG_FILE}" ]]; then + mkdir -p "$(dirname "${LOG_FILE}")" + cat <> "${ZEBRA_CONF_PATH}" log_file = "${LOG_FILE}" EOF - fi - # Zebra automatically detects if it is attached to a terminal, and uses colored output. - # Set this to 'true' to force using color even if the output is not a terminal. - # Set this to 'false' to disable using color even if the output is a terminal. - if [[ "${LOG_COLOR}" = "true" ]]; then - cat <> "${ZEBRA_CONF_PATH}" + fi + # Zebra automatically detects if it is attached to a terminal, and uses colored output. + # Set this to 'true' to force using color even if the output is not a terminal. + # Set this to 'false' to disable using color even if the output is a terminal. + if [[ "${LOG_COLOR}" = "true" ]]; then + cat <> "${ZEBRA_CONF_PATH}" force_use_color = true EOF - elif [[ "${LOG_COLOR}" = "false" ]]; then - cat <> "${ZEBRA_CONF_PATH}" + elif [[ "${LOG_COLOR}" = "false" ]]; then + cat <> "${ZEBRA_CONF_PATH}" use_color = false EOF - fi fi + fi - if [[ -n "${MINER_ADDRESS}" ]]; then - cat <> "${ZEBRA_CONF_PATH}" + if [[ -n "${MINER_ADDRESS}" ]]; then + cat <> "${ZEBRA_CONF_PATH}" [mining] miner_address = "${MINER_ADDRESS}" EOF - fi + fi fi echo "Using zebrad.toml:" @@ -147,137 +147,146 @@ cat "${ZEBRA_CONF_PATH}" # Function to list directory list_directory() { - local dir="$1" - # Using find instead of ls to better handle non-alphanumeric filenames, which also requires `-exec +` - find "${dir}" -type f -print0 | xargs -0 -I {} ls -lh "{}" || { echo "No files in ${dir}"; find "${dir}" -type d -exec ls -lhR {} + | head -50 || echo "No ${dir} directory"; } + local dir="$1" + # Using find instead of ls to better handle non-alphanumeric filenames, which also requires `-exec +` + find "${dir}" -type f -print0 | xargs -0 -I {} ls -lh "{}" || { echo "No files in ${dir}"; find "${dir}" -type d -exec ls -lhR {} + | head -50 || echo "No ${dir} directory"; } } # Function to run cargo test run_cargo_test() { - cargo test --locked --release --features "$1" --package zebrad --test acceptance -- --nocapture --include-ignored "$2" || { echo "Cargo test failed"; exit 1; } + cargo test --locked --release --features "$1" --package zebrad --test acceptance -- --nocapture --include-ignored "$2" || { echo "Cargo test failed"; exit 1; } } case "$1" in - --* | -*) - if [[ -n "${ZEBRA_CONF_PATH}" ]]; then - exec zebrad -c "${ZEBRA_CONF_PATH}" "$@" || { echo "Execution with custom configuration failed"; exit 1; } - else - exec zebrad "$@" || { echo "Execution failed"; exit 1; } - fi - ;; - "") - if [[ -n "${ZEBRA_CONF_PATH}" ]]; then - exec zebrad -c "${ZEBRA_CONF_PATH}" || { echo "Execution with custom configuration failed"; exit 1; } - else - exec zebrad || { echo "Execution with default configuration failed"; exit 1; } - fi - ;; - *) - if [[ -n "${ENTRYPOINT_FEATURES}" ]]; then - # Validate the test variables - # For these tests, we activate the test features to avoid recompiling `zebrad`, - # but we don't actually run any gRPC tests. - if [[ "${RUN_ALL_TESTS}" -eq "1" ]]; then - # Run all the available tests for the current environment. - # If the lightwalletd environmental variables are set, we will also run those tests. - cargo test --locked --release --features "${ENTRYPOINT_FEATURES}" --workspace -- --nocapture --include-ignored + --* | -*) + if [[ -n "${ZEBRA_CONF_PATH}" ]]; then + exec zebrad -c "${ZEBRA_CONF_PATH}" "$@" || { echo "Execution with custom configuration failed"; exit 1; } + else + exec zebrad "$@" || { echo "Execution failed"; exit 1; } + fi + ;; + "") + if [[ -n "${ZEBRA_CONF_PATH}" ]]; then + exec zebrad -c "${ZEBRA_CONF_PATH}" || { echo "Execution with custom configuration failed"; exit 1; } + else + exec zebrad || { echo "Execution with default configuration failed"; exit 1; } + fi + ;; + *) + if [[ -n "${ENTRYPOINT_FEATURES}" ]]; then + # Validate the test variables + # For these tests, we activate the test features to avoid recompiling `zebrad`, + # but we don't actually run any gRPC tests. + if [[ "${RUN_ALL_TESTS}" -eq "1" ]]; then + # Run all the available tests for the current environment. + # If the lightwalletd environmental variables are set, we will also run those tests. + cargo test --locked --release --features "${ENTRYPOINT_FEATURES}" --workspace -- --nocapture --include-ignored + + # For these tests, we activate the gRPC feature to avoid recompiling `zebrad`, + # but we don't actually run any gRPC tests. + elif [[ -n "${FULL_SYNC_MAINNET_TIMEOUT_MINUTES}" ]]; then + # Run a Zebra full sync test on mainnet. + run_cargo_test "${ENTRYPOINT_FEATURES}" "full_sync_mainnet" + # List directory generated by test + # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows + list_directory "/zebrad-cache" + + elif [[ -n "${FULL_SYNC_TESTNET_TIMEOUT_MINUTES}" ]]; then + # Run a Zebra full sync test on testnet. + run_cargo_test "${ENTRYPOINT_FEATURES}" "full_sync_testnet" + # List directory generated by test + # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows + list_directory "/zebrad-cache" - # For these tests, we activate the gRPC feature to avoid recompiling `zebrad`, - # but we don't actually run any gRPC tests. - elif [[ -n "${FULL_SYNC_MAINNET_TIMEOUT_MINUTES}" ]]; then - # Run a Zebra full sync test on mainnet. - run_cargo_test "${ENTRYPOINT_FEATURES}" "full_sync_mainnet" - # List directory generated by test - # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows - list_directory "/zebrad-cache" - elif [[ -n "${FULL_SYNC_TESTNET_TIMEOUT_MINUTES}" ]]; then - # Run a Zebra full sync test on testnet. - run_cargo_test "${ENTRYPOINT_FEATURES}" "full_sync_testnet" - # List directory generated by test - # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows - list_directory "/zebrad-cache" - elif [[ "${TEST_DISK_REBUILD}" -eq "1" ]]; then - # Run a Zebra sync up to the mandatory checkpoint. - # - # TODO: use environmental variables instead of Rust features (part of #2995) - run_cargo_test "test_sync_to_mandatory_checkpoint_${NETWORK,,},${ENTRYPOINT_FEATURES}" "sync_to_mandatory_checkpoint_${NETWORK,,}" - # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows - list_directory "/zebrad-cache" - elif [[ "${TEST_UPDATE_SYNC}" -eq "1" ]]; then - # Run a Zebra sync starting at the cached tip, and syncing to the latest tip. - # - # List directory used by test - list_directory "${ZEBRA_CACHED_STATE_DIR}" - run_cargo_test "${ENTRYPOINT_FEATURES}" "zebrad_update_sync" - elif [[ "${TEST_CHECKPOINT_SYNC}" -eq "1" ]]; then - # Run a Zebra sync starting at the cached mandatory checkpoint, and syncing past it. - # - # List directory used by test - # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows - list_directory "/zebrad-cache" - # TODO: use environmental variables instead of Rust features (part of #2995) - run_cargo_test "test_sync_to_mandatory_checkpoint_${NETWORK,,},${ENTRYPOINT_FEATURES}" "sync_past_mandatory_checkpoint_${NETWORK,,}" + elif [[ "${TEST_DISK_REBUILD}" -eq "1" ]]; then + # Run a Zebra sync up to the mandatory checkpoint. + # + # TODO: use environmental variables instead of Rust features (part of #2995) + run_cargo_test "test_sync_to_mandatory_checkpoint_${NETWORK,,},${ENTRYPOINT_FEATURES}" "sync_to_mandatory_checkpoint_${NETWORK,,}" + # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows + list_directory "/zebrad-cache" - elif [[ "${GENERATE_CHECKPOINTS_MAINNET}" -eq "1" ]]; then - # Generate checkpoints after syncing Zebra from a cached state on mainnet. - # - # TODO: disable or filter out logs like: - # test generate_checkpoints_mainnet has been running for over 60 seconds - # - # List directory used by test - list_directory "${ZEBRA_CACHED_STATE_DIR}" - run_cargo_test "${ENTRYPOINT_FEATURES}" "generate_checkpoints_mainnet" - elif [[ "${GENERATE_CHECKPOINTS_TESTNET}" -eq "1" ]]; then - # Generate checkpoints after syncing Zebra on testnet. - # - # This test might fail if testnet is unstable. - # - # List directory used by test - list_directory "${ZEBRA_CACHED_STATE_DIR}" - run_cargo_test "${ENTRYPOINT_FEATURES}" "generate_checkpoints_testnet" + elif [[ "${TEST_UPDATE_SYNC}" -eq "1" ]]; then + # Run a Zebra sync starting at the cached tip, and syncing to the latest tip. + # + # List directory used by test + list_directory "${ZEBRA_CACHED_STATE_DIR}" + run_cargo_test "${ENTRYPOINT_FEATURES}" "zebrad_update_sync" - elif [[ "${TEST_LWD_RPC_CALL}" -eq "1" ]]; then - # Starting at a cached Zebra tip, test a JSON-RPC call to Zebra. - list_directory "${ZEBRA_CACHED_STATE_DIR}" - # Run both the fully synced RPC test and the subtree snapshot test, one test at a time. - # Since these tests use the same cached state, a state problem in the first test can fail the second test. - run_cargo_test "${ENTRYPOINT_FEATURES}" "fully_synced_rpc_" - elif [[ "${TEST_LWD_FULL_SYNC}" -eq "1" ]]; then - # Starting at a cached Zebra tip, run a lightwalletd sync to tip. - list_directory "${ZEBRA_CACHED_STATE_DIR}" - run_cargo_test "${ENTRYPOINT_FEATURES}" "lightwalletd_full_sync" - list_directory "${LIGHTWALLETD_DATA_DIR}/db" - elif [[ "${TEST_LWD_UPDATE_SYNC}" -eq "1" ]]; then - # Starting with a cached Zebra and lightwalletd tip, run a quick update sync. - list_directory "${ZEBRA_CACHED_STATE_DIR}" - list_directory "${LIGHTWALLETD_DATA_DIR}/db" - run_cargo_test "${ENTRYPOINT_FEATURES}" "lightwalletd_update_sync" + elif [[ "${TEST_CHECKPOINT_SYNC}" -eq "1" ]]; then + # Run a Zebra sync starting at the cached mandatory checkpoint, and syncing past it. + # + # List directory used by test + # TODO: replace with ${ZEBRA_CACHED_STATE_DIR} in Rust and workflows + list_directory "/zebrad-cache" + # TODO: use environmental variables instead of Rust features (part of #2995) + run_cargo_test "test_sync_to_mandatory_checkpoint_${NETWORK,,},${ENTRYPOINT_FEATURES}" "sync_past_mandatory_checkpoint_${NETWORK,,}" - # These tests actually use gRPC. - elif [[ "${TEST_LWD_GRPC}" -eq "1" ]]; then - # Starting with a cached Zebra and lightwalletd tip, test all gRPC calls to lightwalletd, which calls Zebra. - list_directory "${ZEBRA_CACHED_STATE_DIR}" - list_directory "${LIGHTWALLETD_DATA_DIR}/db" - run_cargo_test "${ENTRYPOINT_FEATURES}" "lightwalletd_wallet_grpc_tests" - elif [[ "${TEST_LWD_TRANSACTIONS}" -eq "1" ]]; then - # Starting with a cached Zebra and lightwalletd tip, test sending transactions gRPC call to lightwalletd, which calls Zebra. - list_directory "${ZEBRA_CACHED_STATE_DIR}" - list_directory "${LIGHTWALLETD_DATA_DIR}/db" - run_cargo_test "${ENTRYPOINT_FEATURES}" "sending_transactions_using_lightwalletd" + elif [[ "${GENERATE_CHECKPOINTS_MAINNET}" -eq "1" ]]; then + # Generate checkpoints after syncing Zebra from a cached state on mainnet. + # + # TODO: disable or filter out logs like: + # test generate_checkpoints_mainnet has been running for over 60 seconds + # + # List directory used by test + list_directory "${ZEBRA_CACHED_STATE_DIR}" + run_cargo_test "${ENTRYPOINT_FEATURES}" "generate_checkpoints_mainnet" - # These tests use mining code, but don't use gRPC. - # We add the mining feature here because our other code needs to pass tests without it. - elif [[ "${TEST_GET_BLOCK_TEMPLATE}" -eq "1" ]]; then - # Starting with a cached Zebra tip, test getting a block template from Zebra's RPC server. - list_directory "${ZEBRA_CACHED_STATE_DIR}" - run_cargo_test "getblocktemplate-rpcs,${ENTRYPOINT_FEATURES}" "get_block_template" - elif [[ "${TEST_SUBMIT_BLOCK}" -eq "1" ]]; then - # Starting with a cached Zebra tip, test sending a block to Zebra's RPC port. - list_directory "${ZEBRA_CACHED_STATE_DIR}" - run_cargo_test "getblocktemplate-rpcs,${ENTRYPOINT_FEATURES}" "submit_block" + elif [[ "${GENERATE_CHECKPOINTS_TESTNET}" -eq "1" ]]; then + # Generate checkpoints after syncing Zebra on testnet. + # + # This test might fail if testnet is unstable. + # + # List directory used by test + list_directory "${ZEBRA_CACHED_STATE_DIR}" + run_cargo_test "${ENTRYPOINT_FEATURES}" "generate_checkpoints_testnet" - else - exec "$@" - fi - fi + elif [[ "${TEST_LWD_RPC_CALL}" -eq "1" ]]; then + # Starting at a cached Zebra tip, test a JSON-RPC call to Zebra. + list_directory "${ZEBRA_CACHED_STATE_DIR}" + # Run both the fully synced RPC test and the subtree snapshot test, one test at a time. + # Since these tests use the same cached state, a state problem in the first test can fail the second test. + run_cargo_test "${ENTRYPOINT_FEATURES}" "fully_synced_rpc_" + + elif [[ "${TEST_LWD_FULL_SYNC}" -eq "1" ]]; then + # Starting at a cached Zebra tip, run a lightwalletd sync to tip. + list_directory "${ZEBRA_CACHED_STATE_DIR}" + run_cargo_test "${ENTRYPOINT_FEATURES}" "lightwalletd_full_sync" + list_directory "${LIGHTWALLETD_DATA_DIR}/db" + + elif [[ "${TEST_LWD_UPDATE_SYNC}" -eq "1" ]]; then + # Starting with a cached Zebra and lightwalletd tip, run a quick update sync. + list_directory "${ZEBRA_CACHED_STATE_DIR}" + list_directory "${LIGHTWALLETD_DATA_DIR}/db" + run_cargo_test "${ENTRYPOINT_FEATURES}" "lightwalletd_update_sync" + + # These tests actually use gRPC. + elif [[ "${TEST_LWD_GRPC}" -eq "1" ]]; then + # Starting with a cached Zebra and lightwalletd tip, test all gRPC calls to lightwalletd, which calls Zebra. + list_directory "${ZEBRA_CACHED_STATE_DIR}" + list_directory "${LIGHTWALLETD_DATA_DIR}/db" + run_cargo_test "${ENTRYPOINT_FEATURES}" "lightwalletd_wallet_grpc_tests" + + elif [[ "${TEST_LWD_TRANSACTIONS}" -eq "1" ]]; then + # Starting with a cached Zebra and lightwalletd tip, test sending transactions gRPC call to lightwalletd, which calls Zebra. + list_directory "${ZEBRA_CACHED_STATE_DIR}" + list_directory "${LIGHTWALLETD_DATA_DIR}/db" + run_cargo_test "${ENTRYPOINT_FEATURES}" "sending_transactions_using_lightwalletd" + + # These tests use mining code, but don't use gRPC. + # We add the mining feature here because our other code needs to pass tests without it. + elif [[ "${TEST_GET_BLOCK_TEMPLATE}" -eq "1" ]]; then + # Starting with a cached Zebra tip, test getting a block template from Zebra's RPC server. + list_directory "${ZEBRA_CACHED_STATE_DIR}" + run_cargo_test "getblocktemplate-rpcs,${ENTRYPOINT_FEATURES}" "get_block_template" + + elif [[ "${TEST_SUBMIT_BLOCK}" -eq "1" ]]; then + # Starting with a cached Zebra tip, test sending a block to Zebra's RPC port. + list_directory "${ZEBRA_CACHED_STATE_DIR}" + run_cargo_test "getblocktemplate-rpcs,${ENTRYPOINT_FEATURES}" "submit_block" + + else + exec "$@" + fi + fi esac