Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import org.lfdecentralizedtrust.splice.util.{FrontendLoginUtil, WalletFrontendTe

import scala.concurrent.duration.*
import scala.sys.process.*
import java.io.{BufferedReader, InputStreamReader}
import scala.util.Try
import java.lang.ProcessBuilder
import scala.jdk.CollectionConverters.*

class DockerComposeFullNetworkFrontendIntegrationTest
extends FrontendIntegrationTest("frontend")
Expand Down Expand Up @@ -97,4 +101,55 @@ class DockerComposeFullNetworkFrontendIntegrationTest
}
}

def getPortBinding(containerName: String, internalPort: String): String = {
val command = Seq("docker", "port", containerName, internalPort)
val process = new ProcessBuilder(command.asJava).start()
val reader = new BufferedReader(new InputStreamReader(process.getInputStream))
val output = Try(reader.readLine()).toOption.getOrElse("")
if (process.waitFor() != 0 || output.isEmpty) {
fail(
s"Could not get port binding for $containerName:$internalPort. Is the container running?"
)
}
output
}

def withComposeFullNetwork[A](startFlags: Seq[String] = Seq.empty)(
test: () => A
): A = {
try {
val command =
(Seq("build-tools/splice-compose.sh", "start_network", "-w") ++ startFlags).asJava

val builder = new ProcessBuilder(command)
if (builder.! != 0) {
fail("Failed to start docker-compose full network")
}
test()
} finally {
Seq("build-tools/splice-compose.sh", "stop_network", "-D", "-f").!
}
}

"docker-compose networking bindings work" in { implicit env =>
registerHttpConnectionPoolsCleanup(env)

clue("full network (SV) stack should bind to localhost by default") {
withComposeFullNetwork() { () =>
var binding = getPortBinding("splice-sv-nginx-1", "80")
binding should startWith("127.0.0.1")
binding = getPortBinding("splice-validator-nginx-1", "80")
binding should startWith("127.0.0.1")
}
}
clue("full network (SV) stack should bind to 0.0.0.0 with -E flag") {
withComposeFullNetwork(startFlags = Seq("-E")) { () =>
var binding = getPortBinding("splice-sv-nginx-1", "80")
binding should startWith("0.0.0.0")
binding = getPortBinding("splice-validator-nginx-1", "80")
binding should startWith("0.0.0.0")
}
}
}

}
36 changes: 27 additions & 9 deletions build-tools/splice-compose.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ function _start_validator {
if [ "$trust_single" -eq 1 ]; then
extra_flags+=("-b")
fi
if [ "${external_access:-0}" -eq 1 ]; then
extra_flags+=("-E")
fi

secret_url="${sv_from_script}/api/sv/v0/devnet/onboard/validator/prepare"
_info "Curling ${secret_url} for the secret"
Expand Down Expand Up @@ -178,7 +181,9 @@ function subcmd_start {
party_hint="$(whoami)-composeValidator-1"
participant_id=""
trust_single=0
while getopts 'haldn:m:Mwt:i:p:P:b' arg; do
external_access=0

while getopts 'haldn:m:Mwt:i:p:P:bE' arg; do
case ${arg} in
h)
subcmd_help
Expand Down Expand Up @@ -221,6 +226,9 @@ function subcmd_start {
b)
trust_single=1
;;
E)
external_access=1
;;
?)
subcmd_help
exit 1
Expand Down Expand Up @@ -254,7 +262,7 @@ function subcmd_start {
fi
}
function usage_start {
_info " Options: [-a] [-l] [-d] [-n <network_name>] [-m <migration_id>] [-M] [-w] [-t <image_tag>] [-i <identities_dump>] [-p <party_hint>] [-P <participant_id>]"
_info " Options: [-a] [-l] [-d] [-n <network_name>] [-m <migration_id>] [-M] [-w] [-t <image_tag>] [-i <identities_dump>] [-p <party_hint>] [-P <participant_id>] [-b] [-E]"
_info " -a: Enable authentication"
_info " -l: Start the validator against a local SV (for integration tests). Default is against a cluster determined by GCP_CLUSTER_HOSTNAME"
_info " -d: Use images from the DA-internal repository (default: use locally built images)"
Expand All @@ -267,6 +275,7 @@ function usage_start {
_info " -p <party_hint>: party hint (by default, <local_user>-composeValidator-1)"
_info " -P <participant_id>: participant identifier (by default, identical to the party hint)"
_info " -b: Disable BFT reads&writes and trust a single SV."
_info " -E: Bind to 0.0.0.0 for external access."
}

subcommand_whitelist[stop]='stop a validator'
Expand Down Expand Up @@ -307,9 +316,9 @@ function usage_stop {

subcommand_whitelist[start_network]='Starts a full network (one SV + one validator)'
function subcmd_start_network {

external_access=0
wait=0
while getopts 'hw' arg; do
while getopts 'hwE' arg; do
case ${arg} in
h)
subcmd_help
Expand All @@ -318,6 +327,9 @@ function subcmd_start_network {
w)
wait=1
;;
E)
external_access=1
;;
?)
subcmd_help
exit 1
Expand All @@ -330,8 +342,13 @@ function subcmd_start_network {
# Locally built images (the default when using this script)
export IMAGE_REPO=""

sv_flags=()
if [ $external_access -eq 1 ]; then
sv_flags+=("-E")
fi

_info "Starting SV"
"${SV_DIR}/start.sh"
"${SV_DIR}/start.sh" "${sv_flags[@]}"

for c in validator participant scan sv-app sequencer-mediator nginx; do
docker logs -f splice-sv-${c}-1 >> "${SPLICE_ROOT}/log/compose-sv-${c}.clog" 2>&1 &
Expand All @@ -340,7 +357,7 @@ function subcmd_start_network {
# We must wait for the SV to be ready before starting the validator
# start.sh is idempotent, so running it again with -w should not interfere with the deployment, only wait for it to be ready
_info "Waiting for the SV to be ready"
"${SV_DIR}/start.sh" -w
"${SV_DIR}/start.sh" -w "${sv_flags[@]}"

get_secret_url="sv.localhost:8080/api/sv/v0/devnet/onboard/validator/prepare"
_info "Curling $get_secret_url for the secret"
Expand All @@ -365,13 +382,14 @@ function subcmd_start_network {
curl -sf "scan.localhost:8080/api/scan/readyz" || _error "Scan is not ready after 5 minutes" || exit 1

_info "Starting validator"
_do_start_validator -l -o "$secret" -p "local-composeValidator-1" -m 0
_do_start_validator -l -o "$secret" -p "local-composeValidator-1" -m 0 "${sv_flags[@]}"

_info "The full network is ready"
}
function usage_start_network {
_info " Options: [-w]"
_info " -w: Wait also for the validator to be ready (for the SV we must always wait before starting the validator)"
_info " Options: [-w] [-E]"
_info " -w: Wait also for the validator to be ready (for the SV we must always wait before starting the validator)"
_info " -E: Bind to 0.0.0.0 for external access."
}

subcommand_whitelist[stop_network]='Stop a full network, started with start_network'
Expand Down
6 changes: 3 additions & 3 deletions cluster/compose/localnet/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ services:
- ${LOCALNET_DIR}/conf/nginx/sv.conf:/etc/nginx/templates/sv.c${SV_PROFILE}f.template
- ${LOCALNET_DIR}/conf/nginx/swagger-ui:/etc/nginx/includes
ports:
- "${SV_UI_PORT}:${SV_UI_PORT}"
- "${APP_PROVIDER_UI_PORT}:${APP_PROVIDER_UI_PORT}"
- "${APP_USER_UI_PORT}:${APP_USER_UI_PORT}"
- "${HOST_BIND_IP:-127.0.0.1}:${SV_UI_PORT}:${SV_UI_PORT}"
- "${HOST_BIND_IP:-127.0.0.1}:${APP_PROVIDER_UI_PORT}:${APP_PROVIDER_UI_PORT}"
- "${HOST_BIND_IP:-127.0.0.1}:${APP_USER_UI_PORT}:${APP_USER_UI_PORT}"
depends_on:
wallet-web-ui-sv:
condition: service_healthy
Expand Down
2 changes: 1 addition & 1 deletion cluster/compose/sv/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ services:
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- 8080:80
- "${HOST_BIND_IP:-127.0.0.1}:8080:80"
depends_on:
- validator
- scan
Expand Down
13 changes: 11 additions & 2 deletions cluster/compose/sv/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ set -euo pipefail
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

function usage() {
echo "Usage: $0 -[h] [-w]"
echo "Usage: $0 -[h] [-w] [-E]"
echo " -h: Show this help message"
echo " -w: Wait for the SV node to be ready"
echo " -E: Use this flag to bind the Nginx proxy to 0.0.0.0 (external access) instead of 127.0.0.1 (default)."
}

# issue a user friendly red error
Expand All @@ -29,7 +30,9 @@ function _info(){
}

wait=0
while getopts "hw" opt; do
HOST_BIND_IP="127.0.0.1"

while getopts "hwE" opt; do
case ${opt} in
h)
usage
Expand All @@ -38,6 +41,9 @@ while getopts "hw" opt; do
w)
wait=1
;;
E)
HOST_BIND_IP="0.0.0.0"
;;
?)
usage
exit 1
Expand All @@ -60,4 +66,7 @@ extra_args=()
if [ $wait -eq 1 ]; then
extra_args+=("--wait" "--wait-timeout" "600")
fi

export HOST_BIND_IP

docker compose -f "${script_dir}/compose.yaml" up -d "${extra_args[@]}"
1 change: 1 addition & 0 deletions cluster/compose/sv/stop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function _info(){
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

export IMAGE_TAG=""
export HOST_BIND_IP=""

docker compose -f "$script_dir/compose.yaml" down

Expand Down
2 changes: 1 addition & 1 deletion cluster/compose/validator/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ services:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./nginx:/etc/nginx/includes
ports:
- 80:80
- "${HOST_BIND_IP:-127.0.0.1}:80:80"
depends_on:
- ans-web-ui
- wallet-web-ui
Expand Down
13 changes: 11 additions & 2 deletions cluster/compose/validator/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function _info(){
}

function usage() {
echo "Usage: $0 -s <sponsor_sv_address> -o <onboarding_secret> -p <party_hint> -m <migration_id> [-a] [-b] [-c <scan_address>] [-C <host_scan_address>] [-q <sequencer_address>] [-n <network_name>] [-M] [-i <identities_dump>] [-P <participant_id>] [-w] [-l]"
echo "Usage: $0 -s <sponsor_sv_address> -o <onboarding_secret> -p <party_hint> -m <migration_id> [-a] [-b] [-c <scan_address>] [-C <host_scan_address>] [-q <sequencer_address>] [-n <network_name>] [-M] [-i <identities_dump>] [-P <participant_id>] [-w] [-l] [-E]"
echo " -s <sponsor_sv_address>: The full URL of the sponsor SV"
echo " -o <onboarding_secret>: The onboarding secret to use. May be empty (\"\") if you are already onboarded."
echo " -p <party_hint>: The party hint to use for the validator operator, by default also your participant identifier."
Expand All @@ -43,6 +43,7 @@ function usage() {
echo " -b: Disable BFT reads&writes and trust a single SV."
echo " -c <scan_address>: The full URL of a Scan app. If not provided, it will be derived from the sponsor SV address."
echo " -q <sequencer_address>: The full URL of the sequencer. Must be provided if BFT reads&writes are disabled."
echo " -E: Use this flag to bind the Nginx proxy to 0.0.0.0 (external access) instead of 127.0.0.1 (default)."
}

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
Expand All @@ -62,7 +63,9 @@ participant_id=""
restore_identities_dump=""
local_compose_sv=0
wait=0
while getopts 'has:c:C:t:o:n:bq:m:Mp:P:i:wl' arg; do
HOST_BIND_IP="127.0.0.1"

while getopts 'has:c:C:t:o:n:bq:m:Mp:P:i:wlE' arg; do
case ${arg} in
h)
usage
Expand Down Expand Up @@ -113,6 +116,9 @@ while getopts 'has:c:C:t:o:n:bq:m:Mp:P:i:wl' arg; do
l)
local_compose_sv=1
;;
E)
HOST_BIND_IP="0.0.0.0"
;;
?)
usage
exit 1
Expand Down Expand Up @@ -264,4 +270,7 @@ extra_args=()
if [ $wait -eq 1 ]; then
extra_args+=("--wait" "--wait-timeout" "600")
fi

export HOST_BIND_IP

docker compose -f "${script_dir}/compose.yaml" "${extra_compose_files[@]}" up -d "${extra_args[@]}"
1 change: 1 addition & 0 deletions cluster/compose/validator/stop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export SPLICE_APP_UI_NAME_SERVICE_NAME=""
export SPLICE_APP_UI_NAME_SERVICE_NAME_ACRONYM=""
export VALIDATOR_PARTICIPANT_IDENTITIES_DUMP="v" # A non-empty dummy value, just to make the docker-compose spec valid
export VALIDATOR_NEW_PARTICIPANT_IDENTIFIER=""
export HOST_BIND_IP=""

# We include also compose-restore-from-id.yaml, so that if that was included in the start and created the init container,
# that container is also included in the down and removed
Expand Down
2 changes: 2 additions & 0 deletions docs/src/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Upcoming

- Replace ``-Dscala.concurrent.context.minThreads=8`` with ``-Dscala.concurrent.context.numThreads=8`` and set ``-XX:ActiveProcessorCount=8`` in the ``defaultJvmOptions`` for all the helm charts that deploy scala apps. This should ensure that the internal execution contexts spawn 8 threads to handle processing and that the JVM is configured for 8 CPUs as well. The previous behavior would spawn up to number of available processors, which can be up to the number of CPUs on the actual node if no CPU limit is set. This should avoid overloading the nodes during heavy processing.

- Docker-compose based deployments of LocalNet, validator, and SV expose only to 127.0.0.1 by default. If you want to expose externally, use ``-E`` in validator and superValidator ``start.sh``. For LocalNet, set ``export HOST_BIND_IP=0.0.0.0`` manually.

- SV

- UI
Expand Down
Loading