From 64553c26bc1ddd3e020c0932e7ba72bd01629b1c Mon Sep 17 00:00:00 2001 From: GitGab19 Date: Thu, 5 Sep 2024 18:28:03 +0200 Subject: [PATCH 1/8] common-template-provider-builder addition + healthcheck fix + update-mainnet-chainstate.sh script addition healthcheck.sh comments translation --- containers-scripts/healthcheck.sh | 26 +++++ .../update-mainnet-chainstate.sh | 88 +++++++++++++++ docker-compose-config-a.yaml | 103 ++++++++---------- docker-compose-config-c.yaml | 80 ++++++-------- 4 files changed, 190 insertions(+), 107 deletions(-) create mode 100755 containers-scripts/healthcheck.sh create mode 100755 containers-scripts/update-mainnet-chainstate.sh diff --git a/containers-scripts/healthcheck.sh b/containers-scripts/healthcheck.sh new file mode 100755 index 0000000..6a6ae17 --- /dev/null +++ b/containers-scripts/healthcheck.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +URL=$1 + +# Execute the call and save the response +RESPONSE=$(curl -s --user username:password --data-binary '{"jsonrpc":"1.0","id":"curltest","method":"getblockchaininfo","params":[]}' -H 'content-type:text/plain;' $URL) + +# Check if the response contains an error +if echo "$RESPONSE" | jq -e '.error != null' > /dev/null; then + ERROR_MESSAGE=$(echo "$RESPONSE" | jq -r '.error.message') + echo "Error: $ERROR_MESSAGE" + exit 1 +fi + +# Extract the number of headers and blocks +HEADERS=$(echo "$RESPONSE" | jq -r '.result.headers') +BLOCKS=$(echo "$RESPONSE" | jq -r '.result.blocks') + +# Check if the number of blocks is equal to the number of headers +if [ "$HEADERS" -eq "$BLOCKS" ]; then + echo "Node is fully synchronized" + exit 0 +else + echo "Node is not fully synchronized" + exit 1 +fi \ No newline at end of file diff --git a/containers-scripts/update-mainnet-chainstate.sh b/containers-scripts/update-mainnet-chainstate.sh new file mode 100755 index 0000000..eb3457d --- /dev/null +++ b/containers-scripts/update-mainnet-chainstate.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +NETWORK=$1 +TIMESTAMP_FILE="/root/.bitcoin/last_download_timestamp" +BACKUP_BASE_URL="http://75.119.150.111/backup" +DOWNLOAD_INTERVAL_DAYS=1 # 1 day = 24 hours +CHAINSTATE_DIR="/root/.bitcoin/chainstate" +MAX_RETRIES=30 # Number of attempts (1 per minute for 30 minutes) +RETRY_INTERVAL=60 # 60 seconds (1 minute) between attempts + +if [ "$NETWORK" = "" ]; then + echo "Checking if mainnet snapshot update is needed..." + + # Check if the chainstate directory exists + if [ -d "$CHAINSTATE_DIR" ]; then + CHAINSTATE_MOD_TIME=$(stat -c %Y "$CHAINSTATE_DIR") # Last modification time of chainstate directory + CURRENT_TIME=$(date +%s) # Current timestamp + TIME_DIFF=$(( (CURRENT_TIME - CHAINSTATE_MOD_TIME) / 86400 )) # Difference in days + + # Check if the chainstate directory was updated more than 24 hours ago + if [ "$TIME_DIFF" -ge "$DOWNLOAD_INTERVAL_DAYS" ]; then + echo "It has been more than $DOWNLOAD_INTERVAL_DAYS day(s) since the last node run. Proceeding with download..." + else + echo "Node has run recently (within $DOWNLOAD_INTERVAL_DAYS day(s)). Skipping download." + exit 0 + fi + else + echo "Chainstate directory $CHAINSTATE_DIR does not exist. This is a new node. Proceeding with download." + fi + + # Get current UTC date and time in the format used by the backup files + CURRENT_UTC=$(date -u +"%Y-%m-%d_%H-UTC") + BACKUP_FILE_NAME="backup_mainnet_blocks_chainstate_$CURRENT_UTC.tar.gz" + BACKUP_URL="$BACKUP_BASE_URL/$BACKUP_FILE_NAME" + BACKUP_HASH_URL="$BACKUP_URL.sha256" + + # Paths for files + BACKUP_FILE="/tmp/$BACKUP_FILE_NAME" + BACKUP_HASH_FILE="/tmp/$BACKUP_FILE_NAME.sha256" + + retry_count=0 + success=0 + + # Retry downloading the backup every minute for up to MAX_RETRIES (30 minutes) + while [ $retry_count -lt $MAX_RETRIES ]; do + echo "Attempt $((retry_count + 1)) of $MAX_RETRIES to download the backup..." + + # Try to download the backup file + if wget $BACKUP_URL -O $BACKUP_FILE && wget $BACKUP_HASH_URL -O $BACKUP_HASH_FILE; then + echo "Download succeeded. Verifying the downloaded snapshot..." + + cd /tmp/ + # Check the hash + if sha256sum -c $BACKUP_HASH_FILE; then + echo "Hash verification succeeded." + success=1 + break + else + echo "Hash verification failed! Retrying..." + rm -f $BACKUP_FILE $BACKUP_HASH_FILE + fi + else + echo "Download failed! Retrying in $RETRY_INTERVAL seconds..." + fi + + retry_count=$((retry_count + 1)) + sleep $RETRY_INTERVAL + done + + if [ $success -eq 0 ]; then + echo "Failed to download the backup after $MAX_RETRIES attempts. Aborting." + exit 1 + fi + + echo "Extracting the snapshot into the bitcoin directory..." + + tar -xzvf $BACKUP_FILE -C /root/.bitcoin + + # Remove the downloaded files to save space + rm -f $BACKUP_FILE $BACKUP_HASH_FILE + + # Update the timestamp file to the current time + touch $TIMESTAMP_FILE + + echo "Update completed." +else + echo "NETWORK is not set to 'mainnet'. Skipping update." +fi diff --git a/docker-compose-config-a.yaml b/docker-compose-config-a.yaml index df05825..14683d6 100644 --- a/docker-compose-config-a.yaml +++ b/docker-compose-config-a.yaml @@ -17,6 +17,13 @@ networks: gateway: 10.5.0.1 services: + common-template-provider-builder: + build: + dockerfile: ./template-provider.dockerfile + container_name: common-template-provider-builder + image: template-provider-builder-image + command: echo "common-template-provider build completed" + sv2-roles-builder: build: dockerfile: ./sv2-roles.dockerfile @@ -53,116 +60,93 @@ services: command: echo "pools-latency-calculator build completed" template-provider-pool-side: - build: - dockerfile: ./template-provider.dockerfile labels: logging: "config-a" - image: sv2-template-provider - command: - [ - "/bitcoin/bin/bitcoind", - "-${NETWORK}", - "-sv2", - "-sv2port=8442", - "-sv2interval=${SV2_INTERVAL}", - "-sv2feedelta=0", - "-debug=sv2", - "-loglevel=sv2:trace", - "-sv2bind=0.0.0.0", - ] + image: template-provider-builder-image + entrypoint: ["/bin/sh", "-c", "./scripts/update-mainnet-chainstate.sh ${NETWORK} && /bitcoin/bin/bitcoind -sv2 -sv2port=8442 -sv2interval=${SV2_INTERVAL} -sv2feedelta=0 -debug=sv2 -loglevel=sv2:trace -sv2bind=0.0.0.0 -${NETWORK}"] ports: - "8442:8442" - "18333:48333" - "8332:8332" - "18332:18332" container_name: sv2-tp-pool-side + depends_on: + - common-template-provider-builder volumes: - bitcoin_pool_side_data:/root/.bitcoin - ./custom-configs/sri-roles/bitcoin-tp-pool.conf:/root/.bitcoin/bitcoin.conf + - ./containers-scripts:/scripts restart: unless-stopped networks: sv2-net: ipv4_address: 10.5.0.2 healthcheck: - test: ["CMD-SHELL", "curl --silent --user username:password --data-binary '{\"jsonrpc\":\"1.0\",\"id\":\"healthcheck\",\"method\":\"getblockchaininfo\",\"params\":[]}' -H 'Content-Type: application/json' http://10.5.0.2:18332/ | jq -e '.result.initialblockdownload == false' || exit 1"] - interval: 30s - timeout: 10s - retries: 10 - start_period: 10s + test: ["CMD", "./scripts/healthcheck.sh", "http://127.0.0.1:18332"] + interval: 2m + timeout: 30s + retries: 100 + start_period: 1m template-provider-miner-side: - build: - dockerfile: ./template-provider.dockerfile labels: logging: "config-a" - image: sv2-template-provider - command: - [ - "/bitcoin/bin/bitcoind", - "-${NETWORK}", - "-sv2", - "-sv2port=8443", - "-sv2interval=${SV2_INTERVAL}", - "-sv2feedelta=0", - "-debug=sv2", - "-loglevel=sv2:trace", - "-sv2bind=0.0.0.0", - ] + image: template-provider-builder-image + entrypoint: ["/bin/sh", "-c", "./scripts/update-mainnet-chainstate.sh ${NETWORK} && /bitcoin/bin/bitcoind -sv2 -sv2port=8443 -sv2interval=${SV2_INTERVAL} -sv2feedelta=0 -debug=sv2 -loglevel=sv2:trace -sv2bind=0.0.0.0 -${NETWORK}"] ports: - "8443:8443" - "28333:18333" container_name: sv2-tp-miner-side + depends_on: + - common-template-provider-builder volumes: - bitcoin_miner_side_data:/root/.bitcoin - ./custom-configs/sri-roles/bitcoin-tp-miner.conf:/root/.bitcoin/bitcoin.conf + - ./containers-scripts:/scripts restart: unless-stopped networks: sv2-net: ipv4_address: 10.5.0.3 healthcheck: - test: ["CMD-SHELL", "curl --silent --user username:password --data-binary '{\"jsonrpc\":\"1.0\",\"id\":\"healthcheck\",\"method\":\"getblockchaininfo\",\"params\":[]}' -H 'Content-Type: application/json' http://10.5.0.3:18332/ | jq -e '.result.initialblockdownload == false' || exit 1"] - interval: 30s - timeout: 10s - retries: 10 - start_period: 10s + test: ["CMD", "./scripts/healthcheck.sh", "http://127.0.0.1:18332"] + interval: 2m + timeout: 30s + retries: 100 + start_period: 1m sv1-node-pool-side: - build: - dockerfile: ./template-provider.dockerfile labels: logging: "config-a" - image: sv2-template-provider - command: ["/bitcoin/bin/bitcoind", "-${NETWORK}"] + image: template-provider-builder-image + entrypoint: ["/bin/sh", "-c", "./scripts/update-mainnet-chainstate.sh ${NETWORK} && /bitcoin/bin/bitcoind -${NETWORK}"] ports: - "38333:18333" - "28332:18332" - "18443:18443" container_name: sv1-node-pool-side + depends_on: + - common-template-provider-builder volumes: - bitcoin_sv1_pool_side_data:/root/.bitcoin - ./custom-configs/sri-roles/bitcoin-sv1-node-pool.conf:/root/.bitcoin/bitcoin.conf + - ./containers-scripts:/scripts restart: unless-stopped networks: sv2-net: ipv4_address: 10.5.0.16 + environment: + - NETWORK=${NETWORK} healthcheck: - test: ["CMD-SHELL", "curl --silent --user username:password --data-binary '{\"jsonrpc\":\"1.0\",\"id\":\"healthcheck\",\"method\":\"getblockchaininfo\",\"params\":[]}' -H 'Content-Type: application/json' http://10.5.0.16:18332/ | jq -e '.result.initialblockdownload == false' || exit 1"] - interval: 30s - timeout: 10s - retries: 10 - start_period: 10s + test: ["CMD", "./scripts/healthcheck.sh", "http://127.0.0.1:18332"] + interval: 2m + timeout: 30s + retries: 100 + start_period: 1m pool: image: sv2-roles-builder-image labels: logging: "config-a" command: ["/bin/bash", "-c", "/usr/local/bin/monitor_and_apply_latency.sh 10.5.0.6 2 & exec ./target/release/pool_sv2 -c pool/config-examples/pool-config-a-docker-example.toml"] - #command: - #[ - #"./target/release/pool_sv2", - #"-c", - #"pool/config-examples/pool-config-a-docker-example.toml", - #] ports: - "34254:34254" container_name: sv2-pool @@ -191,7 +175,6 @@ services: "-c", "/usr/local/bin/monitor_and_apply_latency.sh 10.5.0.6 2 & exec ./target/release/jd_server -c jd-server/config-examples/jds-config-a-docker-example.toml", ] - #command: ["./target/release/jd_server", "-c", "jd-server/config-examples/jds-config-a-docker-example.toml"] ports: - "34264:34264" container_name: sv2-jds @@ -432,7 +415,7 @@ services: - "--web.enable-lifecycle" - "--web.enable-admin-api" ports: - - 9090:9090 + - "9090:9090" container_name: prometheus depends_on: - cadvisor @@ -460,7 +443,7 @@ services: - --collector.filesystem.ignored-mount-points - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)" ports: - - 9100:9100 + - "9100:9100" container_name: node-exporter networks: sv2-net: @@ -479,7 +462,7 @@ services: - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro ports: - - 8080:8080 + - "8080:8080" container_name: cadvisor networks: sv2-net: @@ -494,7 +477,7 @@ services: depends_on: - prometheus ports: - - 3000:3000 + - "3000:3000" environment: GF_USERS_ALLOW_SIGN_UP: "false" GF_AUTH_DISABLE_LOGIN_FORM: "true" diff --git a/docker-compose-config-c.yaml b/docker-compose-config-c.yaml index cf2d552..0f067bc 100644 --- a/docker-compose-config-c.yaml +++ b/docker-compose-config-c.yaml @@ -16,6 +16,13 @@ networks: gateway: 10.5.0.1 services: + common-template-provider-builder: + build: + dockerfile: ./template-provider.dockerfile + container_name: common-template-provider-builder + image: template-provider-builder-image + command: echo "common-template-provider build completed" + sv2-roles-builder: build: dockerfile: ./sv2-roles.dockerfile @@ -52,79 +59,64 @@ services: command: echo "pools-latency-calculator build completed" template-provider-pool-side: - build: - dockerfile: ./template-provider.dockerfile labels: logging: "config-c" - image: sv2-template-provider - command: - [ - "/bitcoin/bin/bitcoind", - "-${NETWORK}", - "-sv2", - "-sv2port=8442", - "-sv2interval=${SV2_INTERVAL}", - "-sv2feedelta=0", - "-debug=sv2", - "-loglevel=sv2:trace", - "-sv2bind=0.0.0.0", - ] + image: template-provider-builder-image + entrypoint: ["/bin/sh", "-c", "./scripts/update-mainnet-chainstate.sh ${NETWORK} && /bitcoin/bin/bitcoind -sv2 -sv2port=8442 -sv2interval=${SV2_INTERVAL} -sv2feedelta=0 -debug=sv2 -loglevel=sv2:trace -sv2bind=0.0.0.0 -${NETWORK}"] ports: - "8442:8442" - "18333:48333" - "8332:8332" - "18332:18332" container_name: sv2-tp-pool-side + depends_on: + - common-template-provider-builder volumes: - bitcoin_pool_side_data:/root/.bitcoin - ./custom-configs/sri-roles/bitcoin-tp-pool.conf:/root/.bitcoin/bitcoin.conf + - ./containers-scripts:/scripts restart: unless-stopped networks: sv2-net: ipv4_address: 10.5.0.2 healthcheck: - test: ["CMD-SHELL", "curl --silent --user username:password --data-binary '{\"jsonrpc\":\"1.0\",\"id\":\"healthcheck\",\"method\":\"getblockchaininfo\",\"params\":[]}' -H 'Content-Type: application/json' http://10.5.0.2:18332/ | jq -e '.result.initialblockdownload == false' || exit 1"] - interval: 30s - timeout: 10s - retries: 10 - start_period: 10s + test: [ "CMD", "./scripts/healthcheck.sh", "http://127.0.0.1:18332" ] + interval: 2m + timeout: 30s + retries: 100 + start_period: 1m sv1-node-pool-side: - build: - dockerfile: ./template-provider.dockerfile labels: - logging: "config-c" - image: sv2-template-provider - command: ["/bitcoin/bin/bitcoind", "-${NETWORK}"] + logging: "config-c" + image: template-provider-builder-image + entrypoint: ["/bin/sh", "-c", "./scripts/update-mainnet-chainstate.sh ${NETWORK} && /bitcoin/bin/bitcoind -${NETWORK}"] ports: - "38333:18333" - "28332:18332" - "18443:18443" container_name: sv1-node-pool-side + depends_on: + - common-template-provider-builder volumes: - bitcoin_sv1_pool_side_data:/root/.bitcoin - ./custom-configs/sri-roles/bitcoin-sv1-node-pool.conf:/root/.bitcoin/bitcoin.conf + - ./containers-scripts:/scripts restart: unless-stopped networks: sv2-net: ipv4_address: 10.5.0.16 healthcheck: - test: ["CMD-SHELL", "curl --silent --user username:password --data-binary '{\"jsonrpc\":\"1.0\",\"id\":\"healthcheck\",\"method\":\"getblockchaininfo\",\"params\":[]}' -H 'Content-Type: application/json' http://10.5.0.16:18332/ | jq -e '.result.initialblockdownload == false' || exit 1"] - interval: 30s - timeout: 10s - retries: 10 - start_period: 10s + test: [ "CMD", "./scripts/healthcheck.sh", "http://127.0.0.1:18332" ] + interval: 2m + timeout: 30s + retries: 100 + start_period: 1m pool: image: sv2-roles-builder-image labels: logging: "config-c" - #command: - #[ - #"/bin/bash", - #"-c", - #"/usr/local/bin/monitor_and_apply_latency.sh 10.5.0.17 1 & exec ./target/release/pool_sv2 -c pool/config-examples/pool-config-c-docker-example.toml", - #] command: [ "./target/release/pool_sv2", @@ -156,11 +148,6 @@ services: "-c", "/usr/local/bin/monitor_and_apply_latency.sh 10.5.0.23 2 & exec ./target/release/translator_sv2 -c translator/config-examples/tproxy-config-c-docker-example.toml", ] - #[ - #"./target/release/translator_sv2", - #"-c", - #"translator/config-examples/tproxy-config-c-docker-example.toml", - #] ports: - "34256:34256" container_name: sv2-translator @@ -178,8 +165,7 @@ services: sv2-pool-translator-proxy: image: sv2-custom-proxy-builder-image labels: - logging: "config-c" - #command: ["./target/release/sv2-custom-proxy"] + logging: "config-c" command: [ "/bin/bash", @@ -354,7 +340,7 @@ services: - "--web.enable-lifecycle" - "--web.enable-admin-api" ports: - - 9090:9090 + - "9090:9090" container_name: prometheus depends_on: - cadvisor @@ -382,7 +368,7 @@ services: - --collector.filesystem.ignored-mount-points - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)" ports: - - 9100:9100 + - "9100:9100" container_name: node-exporter networks: sv2-net: @@ -401,7 +387,7 @@ services: - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro ports: - - 8080:8080 + - "8080:8080" container_name: cadvisor networks: sv2-net: @@ -417,7 +403,7 @@ services: - prometheus - loki ports: - - 3000:3000 + - "3000:3000" environment: GF_USERS_ALLOW_SIGN_UP: "false" GF_AUTH_DISABLE_LOGIN_FORM: "true" From 50bff5ffc591e13959fb3f9f70312725f8073d87 Mon Sep 17 00:00:00 2001 From: GitGab19 Date: Thu, 5 Sep 2024 18:24:49 +0200 Subject: [PATCH 2/8] dbcache removal + binding port 18332 for rpc calls (healthcheck) --- custom-configs/sri-roles/bitcoin-sv1-node-pool.conf | 1 - custom-configs/sri-roles/bitcoin-tp-miner.conf | 3 ++- custom-configs/sri-roles/bitcoin-tp-pool.conf | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/custom-configs/sri-roles/bitcoin-sv1-node-pool.conf b/custom-configs/sri-roles/bitcoin-sv1-node-pool.conf index 8d0f246..5f6a591 100644 --- a/custom-configs/sri-roles/bitcoin-sv1-node-pool.conf +++ b/custom-configs/sri-roles/bitcoin-sv1-node-pool.conf @@ -3,7 +3,6 @@ prune=1024 listen=1 discover=1 par=16 -dbcache=5000 maxmempool=4096 mempoolexpiry=999999 mempoolfullrbf=1 diff --git a/custom-configs/sri-roles/bitcoin-tp-miner.conf b/custom-configs/sri-roles/bitcoin-tp-miner.conf index b050886..a6a23cc 100644 --- a/custom-configs/sri-roles/bitcoin-tp-miner.conf +++ b/custom-configs/sri-roles/bitcoin-tp-miner.conf @@ -3,13 +3,14 @@ prune=1024 listen=1 discover=1 par=16 -dbcache=5000 maxmempool=4096 mempoolexpiry=999999 mempoolfullrbf=1 maxconnections=100 rpcuser=username rpcpassword=password +rpcbind=0.0.0.0:18332 +rpcallowip=0.0.0.0/0 [testnet4] rpcbind=10.5.0.3:18332 diff --git a/custom-configs/sri-roles/bitcoin-tp-pool.conf b/custom-configs/sri-roles/bitcoin-tp-pool.conf index 8d0f246..5f6a591 100644 --- a/custom-configs/sri-roles/bitcoin-tp-pool.conf +++ b/custom-configs/sri-roles/bitcoin-tp-pool.conf @@ -3,7 +3,6 @@ prune=1024 listen=1 discover=1 par=16 -dbcache=5000 maxmempool=4096 mempoolexpiry=999999 mempoolfullrbf=1 From 7bee7c926d60761f4bb9ee72f97f9b4e52374eec Mon Sep 17 00:00:00 2001 From: GitGab19 Date: Thu, 5 Sep 2024 20:39:27 +0200 Subject: [PATCH 3/8] dependencies added on sv2-translator-miner-proxy and sv1-pool + deprecated version removal --- docker-compose-config-a.yaml | 2 -- docker-compose-config-c.yaml | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docker-compose-config-a.yaml b/docker-compose-config-a.yaml index 14683d6..a275e59 100644 --- a/docker-compose-config-a.yaml +++ b/docker-compose-config-a.yaml @@ -1,5 +1,3 @@ -version: "3" - volumes: prometheus_data_config_a: grafana_data_config_a: diff --git a/docker-compose-config-c.yaml b/docker-compose-config-c.yaml index 0f067bc..375be35 100644 --- a/docker-compose-config-c.yaml +++ b/docker-compose-config-c.yaml @@ -1,5 +1,3 @@ -version: "3" - volumes: prometheus_data_config_c: grafana_data_config_c: @@ -236,6 +234,7 @@ services: container_name: sv2-translator-miner-proxy depends_on: - sv1-custom-proxy-builder + - translator restart: unless-stopped networks: sv2-net: @@ -258,6 +257,8 @@ services: restart: unless-stopped environment: - NODE_ENV=production + depends_on: + - sv1-node-pool-proxy networks: sv2-net: ipv4_address: 10.5.0.8 From 12cce12afdd752847ae3e8bc800ca228a9a81773 Mon Sep 17 00:00:00 2001 From: GitGab19 Date: Thu, 5 Sep 2024 22:05:58 +0200 Subject: [PATCH 4/8] rpcbind to 0.0.0.0:18332 (for the healthcheck.sh script) --- custom-configs/sri-roles/bitcoin-tp-miner.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom-configs/sri-roles/bitcoin-tp-miner.conf b/custom-configs/sri-roles/bitcoin-tp-miner.conf index a6a23cc..5f6a591 100644 --- a/custom-configs/sri-roles/bitcoin-tp-miner.conf +++ b/custom-configs/sri-roles/bitcoin-tp-miner.conf @@ -13,8 +13,8 @@ rpcbind=0.0.0.0:18332 rpcallowip=0.0.0.0/0 [testnet4] -rpcbind=10.5.0.3:18332 -rpcallowip=10.5.0.0/24 +rpcbind=0.0.0.0:18332 +rpcallowip=0.0.0.0/0 bind=0.0.0.0:18333 bind=[::]:18333 From 8f339ee58861ab2ff7415ede047f5a81aeef7a20 Mon Sep 17 00:00:00 2001 From: Gabriele Vernetti Date: Thu, 19 Sep 2024 19:55:55 +0200 Subject: [PATCH 5/8] Docker compose - errors check addition --- run-benchmarking-tool.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/run-benchmarking-tool.sh b/run-benchmarking-tool.sh index 3f8c448..1f9b8e0 100755 --- a/run-benchmarking-tool.sh +++ b/run-benchmarking-tool.sh @@ -14,6 +14,21 @@ DEFAULT_INTERVAL_C="60" # Path to .env file ENV_FILE=".env" +# Function to clean up Docker containers on error +cleanup() { + echo "" + echo "An error occurred during the setup process." + echo "Stopping any running Docker containers..." + docker compose -f "docker-compose-config-${CONFIG_LOWER}.yaml" down + echo "Docker containers stopped." + echo "Please try running the tool again with the command: ./run-benchmarking-tool.sh" + echo "🚨If the issue persists, please contact the support team for assistance on Discord: https://discord.com/channels/950687892169195530/1107964065936060467" + exit 1 +} + +# Set up trap to catch errors and call cleanup +trap 'cleanup' ERR + # Display a note about the configurations bold=$(tput bold) underline=$(tput smul) @@ -189,6 +204,7 @@ fi # Convert CONFIG to lowercase for the filename CONFIG_LOWER=$(echo "$CONFIG" | tr '[:upper:]' '[:lower:]') + # Start docker container with the appropriate compose file docker compose -f "docker-compose-config-${CONFIG_LOWER}.yaml" up -d From 1d731ef48b00912340e0372b4d20e9d54b708fc9 Mon Sep 17 00:00:00 2001 From: Gabriele Vernetti Date: Wed, 25 Sep 2024 19:04:21 +0200 Subject: [PATCH 6/8] Shared mainnet snapshot volume + TP version bump to 0.1.9 + adjustments in dashboards --- .../update-mainnet-chainstate.sh | 210 ++++++++++++------ docker-compose-config-a.yaml | 4 + docker-compose-config-c.yaml | 5 + ...r Prometheus Monitoring-1571332751387.json | 128 +++++------ ...r Prometheus Monitoring-1571332751387.json | 117 +++++++--- template-provider.dockerfile | 2 +- 6 files changed, 294 insertions(+), 172 deletions(-) diff --git a/containers-scripts/update-mainnet-chainstate.sh b/containers-scripts/update-mainnet-chainstate.sh index eb3457d..c65d944 100755 --- a/containers-scripts/update-mainnet-chainstate.sh +++ b/containers-scripts/update-mainnet-chainstate.sh @@ -1,88 +1,158 @@ #!/bin/sh +# Input parameter for network (used for future expansion) NETWORK=$1 -TIMESTAMP_FILE="/root/.bitcoin/last_download_timestamp" + +# If NETWORK is not mainnet (""), exit the script +if [ "$NETWORK" != "" ]; then + echo "Script should only run when NETWORK is mainnet. Exiting." + exit 0 +fi + +# Shared volume path for snapshot storage +SNAPSHOT_DIR="/shared_volume" + +# Paths for chainstate directory in each container +CHAINSTATE_DIR="/root/.bitcoin/chainstate" + +# Paths for the timestamp file that marks when the snapshot was last downloaded +TIMESTAMP_FILE="$SNAPSHOT_DIR/last_download_timestamp" + +# Backup URL and interval settings BACKUP_BASE_URL="http://75.119.150.111/backup" DOWNLOAD_INTERVAL_DAYS=1 # 1 day = 24 hours -CHAINSTATE_DIR="/root/.bitcoin/chainstate" -MAX_RETRIES=30 # Number of attempts (1 per minute for 30 minutes) -RETRY_INTERVAL=60 # 60 seconds (1 minute) between attempts -if [ "$NETWORK" = "" ]; then - echo "Checking if mainnet snapshot update is needed..." +# Maximum retries for downloading +MAX_RETRIES=30 +RETRY_INTERVAL=60 # 1 minute retry interval - # Check if the chainstate directory exists - if [ -d "$CHAINSTATE_DIR" ]; then - CHAINSTATE_MOD_TIME=$(stat -c %Y "$CHAINSTATE_DIR") # Last modification time of chainstate directory - CURRENT_TIME=$(date +%s) # Current timestamp - TIME_DIFF=$(( (CURRENT_TIME - CHAINSTATE_MOD_TIME) / 86400 )) # Difference in days +# Check if the local chainstate directory is updated for this container +if [ -d "$CHAINSTATE_DIR" ]; then + CHAINSTATE_MOD_TIME=$(stat -c %Y "$CHAINSTATE_DIR") + CURRENT_TIME=$(date +%s) + TIME_DIFF=$(( (CURRENT_TIME - CHAINSTATE_MOD_TIME) / 86400 )) - # Check if the chainstate directory was updated more than 24 hours ago - if [ "$TIME_DIFF" -ge "$DOWNLOAD_INTERVAL_DAYS" ]; then - echo "It has been more than $DOWNLOAD_INTERVAL_DAYS day(s) since the last node run. Proceeding with download..." - else - echo "Node has run recently (within $DOWNLOAD_INTERVAL_DAYS day(s)). Skipping download." - exit 0 + # Skip download if chainstate was updated recently + if [ "$TIME_DIFF" -lt "$DOWNLOAD_INTERVAL_DAYS" ]; then + echo "Container chainstate updated recently. Skipping download." + exit 0 fi - else - echo "Chainstate directory $CHAINSTATE_DIR does not exist. This is a new node. Proceeding with download." - fi - - # Get current UTC date and time in the format used by the backup files - CURRENT_UTC=$(date -u +"%Y-%m-%d_%H-UTC") - BACKUP_FILE_NAME="backup_mainnet_blocks_chainstate_$CURRENT_UTC.tar.gz" - BACKUP_URL="$BACKUP_BASE_URL/$BACKUP_FILE_NAME" - BACKUP_HASH_URL="$BACKUP_URL.sha256" - - # Paths for files - BACKUP_FILE="/tmp/$BACKUP_FILE_NAME" - BACKUP_HASH_FILE="/tmp/$BACKUP_FILE_NAME.sha256" - - retry_count=0 - success=0 - - # Retry downloading the backup every minute for up to MAX_RETRIES (30 minutes) - while [ $retry_count -lt $MAX_RETRIES ]; do - echo "Attempt $((retry_count + 1)) of $MAX_RETRIES to download the backup..." - - # Try to download the backup file - if wget $BACKUP_URL -O $BACKUP_FILE && wget $BACKUP_HASH_URL -O $BACKUP_HASH_FILE; then - echo "Download succeeded. Verifying the downloaded snapshot..." - - cd /tmp/ - # Check the hash - if sha256sum -c $BACKUP_HASH_FILE; then - echo "Hash verification succeeded." - success=1 - break - else - echo "Hash verification failed! Retrying..." - rm -f $BACKUP_FILE $BACKUP_HASH_FILE - fi - else - echo "Download failed! Retrying in $RETRY_INTERVAL seconds..." +else + echo "No local chainstate found. Proceeding with snapshot download check." +fi + +# Shared download logic - checking the shared snapshot area +CURRENT_UTC=$(date -u +"%Y-%m-%d_%H-UTC") +BACKUP_FILE_NAME="backup_mainnet_blocks_chainstate_$CURRENT_UTC.tar.gz" +BACKUP_URL="$BACKUP_BASE_URL/$BACKUP_FILE_NAME" +BACKUP_HASH_URL="$BACKUP_URL.sha256" + +BACKUP_FILE="$SNAPSHOT_DIR/$BACKUP_FILE_NAME" +BACKUP_HASH_FILE="$SNAPSHOT_DIR/$BACKUP_FILE_NAME.sha256" + +# Create a lock file to prevent concurrent downloads +LOCK_FILE="$SNAPSHOT_DIR/download.lock" + +# Function to clean up the lock file +cleanup() { + rm -rf "$LOCK_FILE" +} + +# Trap to ensure the lock file is removed on exit +trap cleanup EXIT + +# Check if there is an existing backup file in the shared volume +LATEST_BACKUP_FILE=$(find /shared_volume -maxdepth 1 -name "backup_mainnet_blocks_chainstate_*.tar.gz" -type f -printf "%T@ %p\n" | sort -n | tail -1 | cut -d' ' -f2) + +if [ -f "$TIMESTAMP_FILE" ]; then + TIMESTAMP_MOD_TIME=$(stat -c %Y "$TIMESTAMP_FILE") + TIME_DIFF=$(( (CURRENT_TIME - TIMESTAMP_MOD_TIME) / 86400 )) + + if [ "$TIME_DIFF" -lt "$DOWNLOAD_INTERVAL_DAYS" ]; then + # Check if the latest backup file exists before extraction + if [ -f "$LATEST_BACKUP_FILE" ]; then + echo "Snapshot was downloaded recently. Proceeding to extraction for this container." + tar -xzvf "$LATEST_BACKUP_FILE" -C /root/.bitcoin + echo "Extraction complete." + exit 0 + else + echo "Warning: No backup file found. Unable to proceed with extraction." + exit 1 + fi + fi +fi + +# Acquire the lock before downloading +if mkdir "$LOCK_FILE" 2>/dev/null; then + echo "Lock acquired. Proceeding with snapshot download..." + + # Remove any old backup files in the shared volume + echo "Removing old backup files from the shared volume..." + rm -f "$SNAPSHOT_DIR/backup_mainnet_blocks_chainstate_*.tar.gz" + rm -f "$SNAPSHOT_DIR/backup_mainnet_blocks_chainstate_*.tar.gz.sha256" + + # Retry downloading until successful or until maximum retries are reached + retry_count=0 + success=0 + + while [ $retry_count -lt $MAX_RETRIES ]; do + echo "Attempt $((retry_count + 1)) of $MAX_RETRIES to download the snapshot..." + + if wget "$BACKUP_URL" -O "$BACKUP_FILE" && wget "$BACKUP_HASH_URL" -O "$BACKUP_HASH_FILE"; then + echo "Download succeeded. Verifying the snapshot hash..." + + cd "$SNAPSHOT_DIR" + if sha256sum -c "$BACKUP_HASH_FILE"; then + echo "Hash verification succeeded." + success=1 + break + else + echo "Hash verification failed! Retrying..." + rm -f "$BACKUP_FILE" "$BACKUP_HASH_FILE" + fi + else + echo "Download failed! Retrying in $RETRY_INTERVAL seconds..." + fi + + retry_count=$((retry_count + 1)) + sleep $RETRY_INTERVAL + done + + if [ $success -eq 0 ]; then + echo "Failed to download the snapshot after $MAX_RETRIES attempts. Aborting." + cleanup # Clean up the lock file + exit 1 fi - retry_count=$((retry_count + 1)) - sleep $RETRY_INTERVAL - done + cleanup # Clean up the lock file - if [ $success -eq 0 ]; then - echo "Failed to download the backup after $MAX_RETRIES attempts. Aborting." - exit 1 - fi + # Extract the snapshot to the container's local chainstate directory + echo "Extracting the snapshot to the container's local chainstate..." + tar -xzvf "$BACKUP_FILE" -C /root/.bitcoin - echo "Extracting the snapshot into the bitcoin directory..." + # Update the timestamp file to mark the download time + touch "$TIMESTAMP_FILE" - tar -xzvf $BACKUP_FILE -C /root/.bitcoin + echo "Update and extraction completed successfully." +else + echo "Another container is currently downloading the snapshot. Waiting for it to complete..." - # Remove the downloaded files to save space - rm -f $BACKUP_FILE $BACKUP_HASH_FILE + # Wait for the download to finish and the lock to be released + while [ -d "$LOCK_FILE" ]; do + sleep 5 # Check every 5 seconds + done - # Update the timestamp file to the current time - touch $TIMESTAMP_FILE + # After the download, proceed with extraction + echo "Snapshot downloaded by another container. Checking for backup file..." - echo "Update completed." -else - echo "NETWORK is not set to 'mainnet'. Skipping update." + if [ -f "$BACKUP_HASH_FILE" ]; then + echo "Proceeding to extraction for this container." + tar -xzvf "$BACKUP_FILE" -C /root/.bitcoin + echo "Extraction complete." + else + echo "Expected backup file $BACKUP_FILE does not exist. Unable to proceed with extraction." + exit 1 + fi fi + +cleanup # Clean up the lock file if it was acquired diff --git a/docker-compose-config-a.yaml b/docker-compose-config-a.yaml index a275e59..a393df6 100644 --- a/docker-compose-config-a.yaml +++ b/docker-compose-config-a.yaml @@ -4,6 +4,7 @@ volumes: bitcoin_pool_side_data: bitcoin_miner_side_data: bitcoin_sv1_pool_side_data: + shared-mainnet-snapshot-volume: networks: monitor-net: @@ -72,6 +73,7 @@ services: - common-template-provider-builder volumes: - bitcoin_pool_side_data:/root/.bitcoin + - shared-mainnet-snapshot-volume:/shared_volume # Shared volume for mainnet snapshot - ./custom-configs/sri-roles/bitcoin-tp-pool.conf:/root/.bitcoin/bitcoin.conf - ./containers-scripts:/scripts restart: unless-stopped @@ -98,6 +100,7 @@ services: - common-template-provider-builder volumes: - bitcoin_miner_side_data:/root/.bitcoin + - shared-mainnet-snapshot-volume:/shared_volume # Shared volume for mainnet snapshot - ./custom-configs/sri-roles/bitcoin-tp-miner.conf:/root/.bitcoin/bitcoin.conf - ./containers-scripts:/scripts restart: unless-stopped @@ -125,6 +128,7 @@ services: - common-template-provider-builder volumes: - bitcoin_sv1_pool_side_data:/root/.bitcoin + - shared-mainnet-snapshot-volume:/shared_volume # Shared volume for mainnet snapshot - ./custom-configs/sri-roles/bitcoin-sv1-node-pool.conf:/root/.bitcoin/bitcoin.conf - ./containers-scripts:/scripts restart: unless-stopped diff --git a/docker-compose-config-c.yaml b/docker-compose-config-c.yaml index 375be35..cd1c210 100644 --- a/docker-compose-config-c.yaml +++ b/docker-compose-config-c.yaml @@ -3,6 +3,7 @@ volumes: grafana_data_config_c: bitcoin_pool_side_data: bitcoin_sv1_pool_side_data: + shared-mainnet-snapshot-volume: networks: monitor-net: @@ -71,6 +72,7 @@ services: - common-template-provider-builder volumes: - bitcoin_pool_side_data:/root/.bitcoin + - shared-mainnet-snapshot-volume:/shared_volume # Shared volume for mainnet snapshot - ./custom-configs/sri-roles/bitcoin-tp-pool.conf:/root/.bitcoin/bitcoin.conf - ./containers-scripts:/scripts restart: unless-stopped @@ -98,12 +100,15 @@ services: - common-template-provider-builder volumes: - bitcoin_sv1_pool_side_data:/root/.bitcoin + - shared-mainnet-snapshot-volume:/shared_volume # Shared volume for mainnet snapshot - ./custom-configs/sri-roles/bitcoin-sv1-node-pool.conf:/root/.bitcoin/bitcoin.conf - ./containers-scripts:/scripts restart: unless-stopped networks: sv2-net: ipv4_address: 10.5.0.16 + environment: + - NETWORK=${NETWORK} healthcheck: test: [ "CMD", "./scripts/healthcheck.sh", "http://127.0.0.1:18332" ] interval: 2m diff --git a/grafana/provisioning/dashboards/config-a/Docker Prometheus Monitoring-1571332751387.json b/grafana/provisioning/dashboards/config-a/Docker Prometheus Monitoring-1571332751387.json index 29904b0..dad87d8 100644 --- a/grafana/provisioning/dashboards/config-a/Docker Prometheus Monitoring-1571332751387.json +++ b/grafana/provisioning/dashboards/config-a/Docker Prometheus Monitoring-1571332751387.json @@ -76,6 +76,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -286,7 +287,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.1.3", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -325,6 +326,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -535,7 +537,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.1.3", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -574,6 +576,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -698,6 +701,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -822,6 +826,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -963,6 +968,7 @@ }, { "datasource": { + "default": true, "type": "prometheus", "uid": "PBFA97CFB590B2093" }, @@ -978,6 +984,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1087,7 +1094,7 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "last_sv2_template_value > 0", + "expr": "last_sv2_template_value", "hide": false, "interval": "", "intervalFactor": 1, @@ -1103,7 +1110,7 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "(last_sv2_template_value > 0 - last_block_mined_value) / last_block_mined_value * 100", + "expr": "(last_sv2_template_value - last_block_mined_value) / last_block_mined_value * 100", "hide": false, "interval": "", "intervalFactor": 1, @@ -1145,6 +1152,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1255,6 +1263,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1366,6 +1375,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1477,6 +1487,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1588,6 +1599,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1699,6 +1711,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1810,6 +1823,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1921,6 +1935,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -2099,8 +2114,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2242,8 +2256,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2398,8 +2411,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2522,8 +2534,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2683,8 +2694,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2806,8 +2816,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2955,8 +2964,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -3095,8 +3103,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -3248,8 +3255,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -3385,8 +3391,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -3540,8 +3545,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -3676,8 +3680,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -3825,8 +3828,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -3965,8 +3967,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -4118,8 +4119,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -4250,8 +4250,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -4382,8 +4381,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -4514,8 +4512,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -4672,8 +4669,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -4788,8 +4784,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -4904,8 +4899,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -5020,8 +5014,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -5136,8 +5129,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -5252,8 +5244,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -5368,8 +5359,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -5484,8 +5474,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -5599,8 +5588,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -5678,8 +5666,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -5760,8 +5747,7 @@ "mode": "absolute", "steps": [ { - "color": "rgba(50, 172, 45, 0.97)", - "value": null + "color": "rgba(50, 172, 45, 0.97)" }, { "color": "rgba(237, 129, 40, 0.89)", @@ -5846,8 +5832,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -5927,8 +5912,7 @@ "mode": "absolute", "steps": [ { - "color": "rgba(50, 172, 45, 0.97)", - "value": null + "color": "rgba(50, 172, 45, 0.97)" }, { "color": "rgba(237, 129, 40, 0.89)", @@ -6013,8 +5997,7 @@ "mode": "absolute", "steps": [ { - "color": "rgba(50, 172, 45, 0.97)", - "value": null + "color": "rgba(50, 172, 45, 0.97)" }, { "color": "rgba(237, 129, 40, 0.89)", @@ -6119,8 +6102,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -6226,7 +6208,7 @@ "list": [] }, "time": { - "from": "now-15m", + "from": "now-5m", "to": "now" }, "timepicker": { @@ -6257,6 +6239,6 @@ "timezone": "browser", "title": "SRI benchmarking tool", "uid": "64nrElFmk", - "version": 34, + "version": 1, "weekStart": "" -} +} \ No newline at end of file diff --git a/grafana/provisioning/dashboards/config-c/Docker Prometheus Monitoring-1571332751387.json b/grafana/provisioning/dashboards/config-c/Docker Prometheus Monitoring-1571332751387.json index 6b737d5..2abab52 100644 --- a/grafana/provisioning/dashboards/config-c/Docker Prometheus Monitoring-1571332751387.json +++ b/grafana/provisioning/dashboards/config-c/Docker Prometheus Monitoring-1571332751387.json @@ -78,6 +78,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -288,7 +289,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.1.3", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -327,6 +328,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -537,7 +539,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.1.3", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -576,6 +578,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -686,6 +689,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -796,6 +800,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -924,6 +929,7 @@ }, { "datasource": { + "default": true, "type": "prometheus", "uid": "PBFA97CFB590B2093" }, @@ -939,6 +945,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1048,7 +1055,7 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "last_sv2_template_value > 0", + "expr": "last_sv2_template_value ", "hide": false, "interval": "", "intervalFactor": 1, @@ -1064,7 +1071,7 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "(last_sv2_template_value > 0 - last_block_mined_value) / last_block_mined_value * 100", + "expr": "(last_sv2_template_value - last_block_mined_value) / last_block_mined_value * 100", "hide": false, "interval": "", "intervalFactor": 1, @@ -1108,6 +1115,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1218,6 +1226,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1329,6 +1338,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1440,6 +1450,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1551,6 +1562,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1662,6 +1674,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1773,6 +1786,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -1884,6 +1898,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -2027,6 +2042,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -2170,6 +2186,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -2326,6 +2343,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -2450,6 +2468,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -2574,6 +2593,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -2697,6 +2717,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -2820,6 +2841,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -2960,6 +2982,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -3113,6 +3136,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -3254,6 +3278,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -3397,6 +3422,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -3537,6 +3563,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -3677,6 +3704,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -3817,6 +3845,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -3970,6 +3999,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -4102,6 +4132,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -4234,6 +4265,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -4366,6 +4398,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -4524,6 +4557,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -4559,7 +4593,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -4639,6 +4674,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -4674,7 +4710,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -4754,6 +4791,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -4789,7 +4827,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -4869,6 +4908,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -4904,7 +4944,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -4984,6 +5025,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -5019,7 +5061,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -5099,6 +5142,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -5134,7 +5178,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -5214,6 +5259,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -5249,7 +5295,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -5329,6 +5376,7 @@ "axisLabel": "", "axisPlacement": "left", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "opacity", @@ -5364,7 +5412,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -5478,7 +5527,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -5503,6 +5553,7 @@ "graphMode": "none", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -5514,7 +5565,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -5555,7 +5606,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -5580,6 +5632,7 @@ "graphMode": "none", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -5591,7 +5644,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -5635,7 +5688,8 @@ "mode": "absolute", "steps": [ { - "color": "rgba(50, 172, 45, 0.97)" + "color": "rgba(50, 172, 45, 0.97)", + "value": null }, { "color": "rgba(237, 129, 40, 0.89)", @@ -5674,7 +5728,7 @@ "showThresholdMarkers": true, "sizing": "auto" }, - "pluginVersion": "11.0.0", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -5720,7 +5774,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -5745,6 +5800,7 @@ "graphMode": "none", "justifyMode": "auto", "orientation": "horizontal", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -5756,7 +5812,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.0.0", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -5799,7 +5855,8 @@ "mode": "absolute", "steps": [ { - "color": "rgba(50, 172, 45, 0.97)" + "color": "rgba(50, 172, 45, 0.97)", + "value": null }, { "color": "rgba(237, 129, 40, 0.89)", @@ -5838,7 +5895,7 @@ "showThresholdMarkers": true, "sizing": "auto" }, - "pluginVersion": "11.0.0", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -5884,7 +5941,8 @@ "mode": "absolute", "steps": [ { - "color": "rgba(50, 172, 45, 0.97)" + "color": "rgba(50, 172, 45, 0.97)", + "value": null }, { "color": "rgba(237, 129, 40, 0.89)", @@ -5923,7 +5981,7 @@ "showThresholdMarkers": true, "sizing": "auto" }, - "pluginVersion": "11.0.0", + "pluginVersion": "11.2.0", "targets": [ { "datasource": { @@ -5958,6 +6016,7 @@ "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 30, "gradientMode": "none", @@ -5989,7 +6048,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -6083,6 +6143,7 @@ "type": "timeseries" } ], + "refresh": "5s", "schemaVersion": 39, "tags": [ "docker", @@ -6094,7 +6155,7 @@ "list": [] }, "time": { - "from": "now-15m", + "from": "now-5m", "to": "now" }, "timepicker": { @@ -6125,6 +6186,6 @@ "timezone": "browser", "title": "SRI benchmarking tool", "uid": "64nrElFmk", - "version": 45, + "version": 1, "weekStart": "" -} +} \ No newline at end of file diff --git a/template-provider.dockerfile b/template-provider.dockerfile index 3bac126..f89c2e3 100644 --- a/template-provider.dockerfile +++ b/template-provider.dockerfile @@ -7,7 +7,7 @@ RUN apt-get update && apt-get upgrade -y RUN apt-get install -y wget tar curl jq # Set environment variables for Bitcoin Core version and installation directory -ENV BITCOIN_VERSION=sv2-tp-0.1.3 +ENV BITCOIN_VERSION=sv2-tp-0.1.9 ENV BITCOIN_DIR=/bitcoin # Create the directory where Bitcoin Core will be installed From 4cc2cce823babb2f6579f570174ee8da9a84b944 Mon Sep 17 00:00:00 2001 From: Gabriele Vernetti Date: Mon, 30 Sep 2024 18:23:59 +0200 Subject: [PATCH 7/8] Use flock to avoid lock file stalling --- .../update-mainnet-chainstate.sh | 86 ++++++++----------- 1 file changed, 36 insertions(+), 50 deletions(-) diff --git a/containers-scripts/update-mainnet-chainstate.sh b/containers-scripts/update-mainnet-chainstate.sh index c65d944..f936ca9 100755 --- a/containers-scripts/update-mainnet-chainstate.sh +++ b/containers-scripts/update-mainnet-chainstate.sh @@ -11,20 +11,26 @@ fi # Shared volume path for snapshot storage SNAPSHOT_DIR="/shared_volume" - # Paths for chainstate directory in each container CHAINSTATE_DIR="/root/.bitcoin/chainstate" - # Paths for the timestamp file that marks when the snapshot was last downloaded TIMESTAMP_FILE="$SNAPSHOT_DIR/last_download_timestamp" - # Backup URL and interval settings BACKUP_BASE_URL="http://75.119.150.111/backup" DOWNLOAD_INTERVAL_DAYS=1 # 1 day = 24 hours - # Maximum retries for downloading MAX_RETRIES=30 RETRY_INTERVAL=60 # 1 minute retry interval +# Lock settings +LOCK_FILE="$SNAPSHOT_DIR/download.lock" + +# Function to clean up the lock file +cleanup() { + rm -f "$LOCK_FILE" +} + +# Trap to ensure the lock file is removed on exit +trap cleanup EXIT # Check if the local chainstate directory is updated for this container if [ -d "$CHAINSTATE_DIR" ]; then @@ -46,23 +52,11 @@ CURRENT_UTC=$(date -u +"%Y-%m-%d_%H-UTC") BACKUP_FILE_NAME="backup_mainnet_blocks_chainstate_$CURRENT_UTC.tar.gz" BACKUP_URL="$BACKUP_BASE_URL/$BACKUP_FILE_NAME" BACKUP_HASH_URL="$BACKUP_URL.sha256" - BACKUP_FILE="$SNAPSHOT_DIR/$BACKUP_FILE_NAME" BACKUP_HASH_FILE="$SNAPSHOT_DIR/$BACKUP_FILE_NAME.sha256" -# Create a lock file to prevent concurrent downloads -LOCK_FILE="$SNAPSHOT_DIR/download.lock" - -# Function to clean up the lock file -cleanup() { - rm -rf "$LOCK_FILE" -} - -# Trap to ensure the lock file is removed on exit -trap cleanup EXIT - # Check if there is an existing backup file in the shared volume -LATEST_BACKUP_FILE=$(find /shared_volume -maxdepth 1 -name "backup_mainnet_blocks_chainstate_*.tar.gz" -type f -printf "%T@ %p\n" | sort -n | tail -1 | cut -d' ' -f2) +LATEST_BACKUP_FILE=$(find "$SNAPSHOT_DIR" -maxdepth 1 -name "backup_mainnet_blocks_chainstate_*.tar.gz" -type f -printf "%T@ %p\n" | sort -n | tail -1 | cut -d' ' -f2) if [ -f "$TIMESTAMP_FILE" ]; then TIMESTAMP_MOD_TIME=$(stat -c %Y "$TIMESTAMP_FILE") @@ -75,15 +69,27 @@ if [ -f "$TIMESTAMP_FILE" ]; then tar -xzvf "$LATEST_BACKUP_FILE" -C /root/.bitcoin echo "Extraction complete." exit 0 - else - echo "Warning: No backup file found. Unable to proceed with extraction." - exit 1 fi fi fi -# Acquire the lock before downloading -if mkdir "$LOCK_FILE" 2>/dev/null; then +# Use flock for the lock file to prevent concurrent downloads +{ + flock -n 9 || { + echo "Another container is currently downloading the snapshot. Waiting for download to finish..." + # Wait for the download to complete + while [ -f "$LOCK_FILE" ]; do + sleep 5 # Wait for 5 seconds before checking again + done + echo "Download finished. Proceeding to extraction." + # Check again if the backup file exists after the wait + if [ -f "$LATEST_BACKUP_FILE" ]; then + tar -xzvf "$LATEST_BACKUP_FILE" -C /root/.bitcoin + echo "Extraction complete." + exit 0 + fi + } + echo "Lock acquired. Proceeding with snapshot download..." # Remove any old backup files in the shared volume @@ -120,39 +126,19 @@ if mkdir "$LOCK_FILE" 2>/dev/null; then if [ $success -eq 0 ]; then echo "Failed to download the snapshot after $MAX_RETRIES attempts. Aborting." - cleanup # Clean up the lock file exit 1 fi - cleanup # Clean up the lock file - - # Extract the snapshot to the container's local chainstate directory - echo "Extracting the snapshot to the container's local chainstate..." - tar -xzvf "$BACKUP_FILE" -C /root/.bitcoin - # Update the timestamp file to mark the download time touch "$TIMESTAMP_FILE" - echo "Update and extraction completed successfully." -else - echo "Another container is currently downloading the snapshot. Waiting for it to complete..." - - # Wait for the download to finish and the lock to be released - while [ -d "$LOCK_FILE" ]; do - sleep 5 # Check every 5 seconds - done + # Release the lock file to allow other containers to start extracting +} 9>"$LOCK_FILE" # Using file descriptor 9 for the lock file - # After the download, proceed with extraction - echo "Snapshot downloaded by another container. Checking for backup file..." - - if [ -f "$BACKUP_HASH_FILE" ]; then - echo "Proceeding to extraction for this container." - tar -xzvf "$BACKUP_FILE" -C /root/.bitcoin - echo "Extraction complete." - else - echo "Expected backup file $BACKUP_FILE does not exist. Unable to proceed with extraction." - exit 1 - fi -fi +# Extract the downloaded snapshot +echo "Extracting the downloaded snapshot..." +tar -xzvf "$BACKUP_FILE" -C /root/.bitcoin +echo "Extraction complete." -cleanup # Clean up the lock file if it was acquired +# If we reach here, the download was successful, and other containers can now extract the snapshot +echo "Update and extraction completed successfully." From 30066b267bf553943570249fdbb0fa1cdad19d5c Mon Sep 17 00:00:00 2001 From: Gabriele Vernetti Date: Mon, 7 Oct 2024 21:28:07 +0200 Subject: [PATCH 8/8] reorganization in functions commented code removal --- .../update-mainnet-chainstate.sh | 185 ++++++++++-------- template-provider.dockerfile | 5 +- 2 files changed, 107 insertions(+), 83 deletions(-) diff --git a/containers-scripts/update-mainnet-chainstate.sh b/containers-scripts/update-mainnet-chainstate.sh index f936ca9..8d434e9 100755 --- a/containers-scripts/update-mainnet-chainstate.sh +++ b/containers-scripts/update-mainnet-chainstate.sh @@ -13,8 +13,10 @@ fi SNAPSHOT_DIR="/shared_volume" # Paths for chainstate directory in each container CHAINSTATE_DIR="/root/.bitcoin/chainstate" -# Paths for the timestamp file that marks when the snapshot was last downloaded -TIMESTAMP_FILE="$SNAPSHOT_DIR/last_download_timestamp" +# Path for the extraction completion flag +EXTRACTION_COMPLETION_FLAG="/root/.bitcoin/extraction_completion.flag" +# Path for the integrity flag +INTEGRITY_FLAG="$SNAPSHOT_DIR/integrity.flag" # Backup URL and interval settings BACKUP_BASE_URL="http://75.119.150.111/backup" DOWNLOAD_INTERVAL_DAYS=1 # 1 day = 24 hours @@ -32,44 +34,107 @@ cleanup() { # Trap to ensure the lock file is removed on exit trap cleanup EXIT -# Check if the local chainstate directory is updated for this container +# Function to download the snapshot and verify it +download_snapshot() { + echo "Downloading snapshot..." + + retry_count=0 + + # Remove old backup files + echo "Removing old backup files from the shared volume..." + rm -f "$SNAPSHOT_DIR"/backup_mainnet_blocks_chainstate_*.tar.gz + rm -f "$SNAPSHOT_DIR"/backup_mainnet_blocks_chainstate_*.tar.gz.sha256 + echo "false" > "$INTEGRITY_FLAG" + + while [ $retry_count -lt $MAX_RETRIES ]; do + echo "Attempt $((retry_count + 1)) of $MAX_RETRIES to download the snapshot..." + + BACKUP_FILE_NAME="backup_mainnet_blocks_chainstate_$(date -u +"%Y-%m-%d_%H-UTC").tar.gz" + BACKUP_HASH_FILE_NAME="$BACKUP_FILE_NAME.sha256" + BACKUP_URL="$BACKUP_BASE_URL/$BACKUP_FILE_NAME" + BACKUP_HASH_URL="$BACKUP_URL.sha256" + BACKUP_FILE="$SNAPSHOT_DIR/$BACKUP_FILE_NAME" + BACKUP_HASH_FILE="$SNAPSHOT_DIR/$BACKUP_HASH_FILE_NAME" + + if wget "$BACKUP_URL" -O "$BACKUP_FILE" && wget "$BACKUP_HASH_URL" -O "$BACKUP_HASH_FILE"; then + echo "Download succeeded. Verifying the snapshot hash..." + + cd "$SNAPSHOT_DIR" || exit + if sha256sum -c "$BACKUP_HASH_FILE"; then + # Set the integrity flag and release the lock immediately after integrity check + echo "true" > "$INTEGRITY_FLAG" + echo "Snapshot integrity verified. Releasing lock for other containers to proceed with extraction." + return 0 # Successful download and verification + else + echo "Hash verification failed! Retrying..." + rm -f "$BACKUP_FILE" "$BACKUP_HASH_FILE" + fi + else + echo "Download failed! Retrying in $RETRY_INTERVAL seconds..." + fi + + retry_count=$((retry_count + 1)) + sleep $RETRY_INTERVAL + done + + echo "Failed to download the snapshot after $MAX_RETRIES attempts. Aborting." + return 1 # Unsuccessful download +} + +# Function to handle extraction +extract_snapshot() { + echo "Cleaning up the chainstate directory..." + rm -rf "$CHAINSTATE_DIR"/* + echo "$LATEST_BACKUP_FILE" + echo "Extracting the downloaded snapshot..." + if tar -xzvf "$LATEST_BACKUP_FILE" -C /root/.bitcoin; then + # Set the extraction completion flag to true after successful extraction + echo "true" > "$EXTRACTION_COMPLETION_FLAG" + echo "Extraction completed successfully." + else + # Set the extraction completion flag to false if extraction fails + echo "false" > "$EXTRACTION_COMPLETION_FLAG" + echo "Extraction failed!" + exit 1 # Exit the script with error code + fi +} + +# Check if the local chainstate directory is updated and integrity verified for this container if [ -d "$CHAINSTATE_DIR" ]; then CHAINSTATE_MOD_TIME=$(stat -c %Y "$CHAINSTATE_DIR") CURRENT_TIME=$(date +%s) TIME_DIFF=$(( (CURRENT_TIME - CHAINSTATE_MOD_TIME) / 86400 )) - # Skip download if chainstate was updated recently - if [ "$TIME_DIFF" -lt "$DOWNLOAD_INTERVAL_DAYS" ]; then - echo "Container chainstate updated recently. Skipping download." - exit 0 + if [ "$TIME_DIFF" -lt "$DOWNLOAD_INTERVAL_DAYS" ] && [ -f "$EXTRACTION_COMPLETION_FLAG" ]; then + FLAG_VALUE=$(cat "$EXTRACTION_COMPLETION_FLAG" | tr -d '\n') + if [ "$FLAG_VALUE" = "true" ]; then + echo "Container chainstate is updated and extraction is complete. Exiting." + exit 0 + else + echo "EXTRACTION_COMPLETION_FLAG is not set to true. Proceeding with further checks." + fi fi + else echo "No local chainstate found. Proceeding with snapshot download check." fi -# Shared download logic - checking the shared snapshot area -CURRENT_UTC=$(date -u +"%Y-%m-%d_%H-UTC") -BACKUP_FILE_NAME="backup_mainnet_blocks_chainstate_$CURRENT_UTC.tar.gz" -BACKUP_URL="$BACKUP_BASE_URL/$BACKUP_FILE_NAME" -BACKUP_HASH_URL="$BACKUP_URL.sha256" -BACKUP_FILE="$SNAPSHOT_DIR/$BACKUP_FILE_NAME" -BACKUP_HASH_FILE="$SNAPSHOT_DIR/$BACKUP_FILE_NAME.sha256" - -# Check if there is an existing backup file in the shared volume +# Check if a recent and verified snapshot already exists LATEST_BACKUP_FILE=$(find "$SNAPSHOT_DIR" -maxdepth 1 -name "backup_mainnet_blocks_chainstate_*.tar.gz" -type f -printf "%T@ %p\n" | sort -n | tail -1 | cut -d' ' -f2) -if [ -f "$TIMESTAMP_FILE" ]; then - TIMESTAMP_MOD_TIME=$(stat -c %Y "$TIMESTAMP_FILE") - TIME_DIFF=$(( (CURRENT_TIME - TIMESTAMP_MOD_TIME) / 86400 )) +if [ -f "$LATEST_BACKUP_FILE" ]; then + BACKUP_MOD_TIME=$(stat -c %Y "$LATEST_BACKUP_FILE") + TIME_DIFF=$(( (CURRENT_TIME - BACKUP_MOD_TIME) / 86400 )) - if [ "$TIME_DIFF" -lt "$DOWNLOAD_INTERVAL_DAYS" ]; then - # Check if the latest backup file exists before extraction - if [ -f "$LATEST_BACKUP_FILE" ]; then - echo "Snapshot was downloaded recently. Proceeding to extraction for this container." - tar -xzvf "$LATEST_BACKUP_FILE" -C /root/.bitcoin - echo "Extraction complete." - exit 0 - fi + if [ "$TIME_DIFF" -lt "$DOWNLOAD_INTERVAL_DAYS" ] && [ -f "$INTEGRITY_FLAG" ] && grep -q "true" "$INTEGRITY_FLAG"; then + echo "Recent snapshot with verified integrity found. Proceeding to extraction." + + # Set the extraction completion flag to false before extraction + echo "false" > "$EXTRACTION_COMPLETION_FLAG" + extract_snapshot + exit 0 + else + echo "No recent or verified snapshot found. Proceeding with download." fi fi @@ -77,68 +142,30 @@ fi { flock -n 9 || { echo "Another container is currently downloading the snapshot. Waiting for download to finish..." - # Wait for the download to complete while [ -f "$LOCK_FILE" ]; do sleep 5 # Wait for 5 seconds before checking again done - echo "Download finished. Proceeding to extraction." - # Check again if the backup file exists after the wait - if [ -f "$LATEST_BACKUP_FILE" ]; then - tar -xzvf "$LATEST_BACKUP_FILE" -C /root/.bitcoin - echo "Extraction complete." + echo "Download finished. Checking integrity..." + LATEST_BACKUP_FILE=$(find "$SNAPSHOT_DIR" -maxdepth 1 -name "backup_mainnet_blocks_chainstate_*.tar.gz" -type f -printf "%T@ %p\n" | sort -n | tail -1 | cut -d' ' -f2) + if [ -f "$INTEGRITY_FLAG" ] && grep -q "true" "$INTEGRITY_FLAG"; then + echo "Snapshot integrity verified. Proceeding to extraction." + extract_snapshot exit 0 + else + echo "Integrity flag not set or snapshot corrupted. Exiting." + exit 1 fi } echo "Lock acquired. Proceeding with snapshot download..." + touch "$LOCK_FILE" # Create the lock file - # Remove any old backup files in the shared volume - echo "Removing old backup files from the shared volume..." - rm -f "$SNAPSHOT_DIR/backup_mainnet_blocks_chainstate_*.tar.gz" - rm -f "$SNAPSHOT_DIR/backup_mainnet_blocks_chainstate_*.tar.gz.sha256" - - # Retry downloading until successful or until maximum retries are reached - retry_count=0 - success=0 - - while [ $retry_count -lt $MAX_RETRIES ]; do - echo "Attempt $((retry_count + 1)) of $MAX_RETRIES to download the snapshot..." - - if wget "$BACKUP_URL" -O "$BACKUP_FILE" && wget "$BACKUP_HASH_URL" -O "$BACKUP_HASH_FILE"; then - echo "Download succeeded. Verifying the snapshot hash..." - - cd "$SNAPSHOT_DIR" - if sha256sum -c "$BACKUP_HASH_FILE"; then - echo "Hash verification succeeded." - success=1 - break - else - echo "Hash verification failed! Retrying..." - rm -f "$BACKUP_FILE" "$BACKUP_HASH_FILE" - fi - else - echo "Download failed! Retrying in $RETRY_INTERVAL seconds..." - fi - - retry_count=$((retry_count + 1)) - sleep $RETRY_INTERVAL - done - - if [ $success -eq 0 ]; then - echo "Failed to download the snapshot after $MAX_RETRIES attempts. Aborting." - exit 1 - fi - - # Update the timestamp file to mark the download time - touch "$TIMESTAMP_FILE" - - # Release the lock file to allow other containers to start extracting + download_snapshot || exit 1 # Exit if download fails + # Here, we release the lock so other containers can download or extract if needed + cleanup } 9>"$LOCK_FILE" # Using file descriptor 9 for the lock file -# Extract the downloaded snapshot -echo "Extracting the downloaded snapshot..." -tar -xzvf "$BACKUP_FILE" -C /root/.bitcoin -echo "Extraction complete." +LATEST_BACKUP_FILE=$(find "$SNAPSHOT_DIR" -maxdepth 1 -name "backup_mainnet_blocks_chainstate_*.tar.gz" -type f -printf "%T@ %p\n" | sort -n | tail -1 | cut -d' ' -f2) +extract_snapshot -# If we reach here, the download was successful, and other containers can now extract the snapshot echo "Update and extraction completed successfully." diff --git a/template-provider.dockerfile b/template-provider.dockerfile index f89c2e3..6235abc 100644 --- a/template-provider.dockerfile +++ b/template-provider.dockerfile @@ -27,7 +27,4 @@ RUN ARCH=$(dpkg --print-architecture) && \ RUN tar -xzvf /tmp/bitcoin.tar.gz -C $BITCOIN_DIR --strip-components=1 # Cleanup -RUN rm /tmp/bitcoin.tar.gz - -# Create a volume for blockchain data and configuration files -VOLUME ["/root/.bitcoin"] \ No newline at end of file +RUN rm /tmp/bitcoin.tar.gz \ No newline at end of file