diff --git a/.github/workflows/bump.yml b/.github/workflows/bump.yml new file mode 100644 index 0000000..b1c8458 --- /dev/null +++ b/.github/workflows/bump.yml @@ -0,0 +1,65 @@ +name: Bump packages +on: + repository_dispatch: + types: [bump] + workflow_dispatch: + inputs: + hoprd_version: + description: 'Version of hoprd to build' + required: false +permissions: + contents: read + +jobs: + bump: + name: Bump docker images + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + - name: Set up Docker Compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose + - name: Setup variables + id: setup + run: | + default_hoprd_version=$(yq -r '.services.node.build.args.UPSTREAM_VERSION' docker-compose.yml) + default_hoprd_version=$(echo $default_hoprd_version | cut -d@ -f1) + hoprd_version="${HOPRD_VERSION:-$default_hoprd_version}" + docker pull "${DOCKER_REGISTRY}/hoprd:${hoprd_version#v}" + digest=$(docker inspect --format='{{index .RepoDigests 0}}' "${DOCKER_REGISTRY}/hoprd:${hoprd_version#v}" | cut -d@ -f2) + echo "HOPRD_VERSION=${hoprd_version}@${digest}" | tee -a "${GITHUB_OUTPUT}" + + env: + DOCKER_REGISTRY: ${{ vars.DOCKER_REGISTRY }} + HOPRD_VERSION: ${{ github.event.inputs.hoprd_version || github.event.client_payload.hoprd_version }} + - name: Update docker-compose.yml + run: | + yq -i '.services.node.build.args.UPSTREAM_VERSION = strenv(HOPRD_VERSION)' docker-compose.yml + env: + DOCKER_REGISTRY: ${{ vars.DOCKER_REGISTRY }} + HOPRD_VERSION: ${{ steps.setup.outputs.HOPRD_VERSION }} + - name: Install dependencies + run: | + npm install + - name: Build + run: | + npx @dappnode/dappnodesdk build \ + --provider "remote" \ + --verbose | tee build.log + - name: Create Pull Request + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 + with: + commit-message: "ci: Update docker images" + title: "ci: Update docker images" + body: "This pull request updates the docker images to:\n- hoprd: ${{ steps.setup.outputs.HOPRD_VERSION }}\n\nThis PR was automatically generated by the bump workflow." + branch: bot/update-${{ github.run_id}} + delete-branch: true + assignees: ${{ github.actor }} + reviewers: "ausias-armesto,tolbrino,NumberFour8,Teebor-Choka,QYuQianchen,jeandemeusy,majchrzamemil,Jaguaras,mjadach-iv" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index dac25ce..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Build (experimental package) - -on: - pull_request: - push: - branches: - - develop - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Set up Docker Compose - run: | - sudo apt-get update - sudo apt-get install -y docker-compose - - - name: Build and upload to IPFS - run: | - npm install - npx @dappnode/dappnodesdk build \ - --provider "remote" \ - --verbose | tee build.log - - echo "DNP (DAppNode Package) built and uploaded" >> $GITHUB_STEP_SUMMARY - grep "ipfs" build.log >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/merge.yaml b/.github/workflows/merge.yaml new file mode 100644 index 0000000..6001484 --- /dev/null +++ b/.github/workflows/merge.yaml @@ -0,0 +1,41 @@ +name: Merge + +on: + pull_request: + types: [closed] + +permissions: + contents: read + +jobs: + publish-ipfs: + name: Publish merged build to IPFS + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.base.ref }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set up Docker Compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose + + - name: Install dependencies + run: npm ci + + - name: Build and upload to IPFS + run: | + npx @dappnode/dappnodesdk build \ + --provider "remote" \ + --verbose | tee build.log + + ipfs_hash=$(grep -oP 'Release hash *: \K/ipfs/\w+' build.log) + + echo "### DNP (DAppNode Package) built and uploaded" >> "$GITHUB_STEP_SUMMARY" + echo "Merged build published to IPFS: \`${ipfs_hash}\`" >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml new file mode 100644 index 0000000..444739e --- /dev/null +++ b/.github/workflows/pr.yaml @@ -0,0 +1,63 @@ +name: PR + +on: + pull_request: + types: [opened, synchronize, reopened, labeled] +permissions: + contents: read + +jobs: + test: + name: Test package + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Validate hoprd.cfg.yaml + run: ./test/validate-hoprd-config.sh + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set up Docker Compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose + + - name: Install dependencies + run: npm ci + + - name: Build package (validate manifest and compose file) + run: npx @dappnode/dappnodesdk build --skip_upload --verbose + + publish-ipfs: + name: Publish test build to IPFS + needs: test + if: contains(github.event.pull_request.labels.*.name, 'publish-ipfs') + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set up Docker Compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose + + - name: Install dependencies + run: npm ci + + - name: Build and upload to IPFS + run: | + npx @dappnode/dappnodesdk build \ + --provider "remote" \ + --verbose | tee build.log + + ipfs_hash=$(grep -oP 'Release hash *: \K/ipfs/\w+' build.log) + + echo "### DNP (DAppNode Package) built and uploaded" >> "$GITHUB_STEP_SUMMARY" + echo "Test build published to IPFS: \`${ipfs_hash}\`" >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..3c6cf35 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,102 @@ +name: Release + +on: + workflow_dispatch: + inputs: + release_type: + description: Version type for this release + required: true + type: choice + default: "patch" + options: + - patch + - minor + - major + +concurrency: + group: release + cancel-in-progress: false + +jobs: + release: + name: Release + runs-on: ubuntu-latest + permissions: + contents: write + env: + # `secrets` isn't a valid context inside `if:` (only env/github/inputs/... are) - see + # the "Notify Zulip" step below, which needs these to decide whether to run at all. + ZULIP_EMAIL: ${{ secrets.ZULIP_EMAIL }} + ZULIP_API_KEY: ${{ secrets.ZULIP_API_KEY }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set up Docker Compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose + + - name: Install dependencies + run: npm ci + + - name: Generate release notes + uses: hoprnet/hopr-workflows/actions/generate-release-notes@c20a995078b3a9a66ae9e6689d08d38ea37b5a0b # generate-release-notes-v1.0.1 + with: + source_branch: ${{ github.ref_name }} + format: github + release_notes_file: ./release-notes.md + + - name: Add release notes to summary + run: | + echo "### Release notes" >> "$GITHUB_STEP_SUMMARY" + cat release-notes.md >> "$GITHUB_STEP_SUMMARY" + + - name: Build and publish to package repository + id: publish + run: | + npx @dappnode/dappnodesdk publish "${{ inputs.release_type }}" \ + --provider "remote" \ + --upload_to "ipfs" \ + --verbose \ + --github_release | tee build.log + + new_version=$(jq -r '.version' dappnode_package.json) + ipfs_hash=$(grep -oP 'Release hash *: \K/ipfs/\w+' build.log) + + echo "### DNP (DAppNode Package) built and uploaded" >> "$GITHUB_STEP_SUMMARY" + echo "- Version: \`${new_version}\`" >> "$GITHUB_STEP_SUMMARY" + echo "- IPFS Hash: \`${ipfs_hash}\`" >> "$GITHUB_STEP_SUMMARY" + + echo "new_version=$new_version" >> "$GITHUB_OUTPUT" + echo "ipfs_hash=$ipfs_hash" >> "$GITHUB_OUTPUT" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DEVELOPER_ADDRESS: "0x7305356ad936A06c4ea5DF45AD5E5C3ff9Db818E" + + - name: Add release notes to the Github release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + tag="v${{ steps.publish.outputs.new_version }}" + gh release edit "$tag" --repo "${{ github.repository }}" --notes-file release-notes.md + + - name: Notify Zulip + if: ${{ env.ZULIP_EMAIL != '' && env.ZULIP_API_KEY != '' }} + uses: zulip/github-actions-zulip/send-message@v1 + with: + api-key: ${{ env.ZULIP_API_KEY }} + email: ${{ env.ZULIP_EMAIL }} + organization-url: "https://hopr.zulipchat.com" + type: "stream" + to: HOPRd + topic: Releases + content: | + A new hoprd dAppNode package version v${{ steps.publish.outputs.new_version }} is available. + - IPFS Hash: ${{ steps.publish.outputs.ipfs_hash }} + Access your dAppNode and check for updates. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 8f444f7..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Build (release package) - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Set up Docker Compose - run: | - sudo apt-get update - sudo apt-get install -y docker-compose - - - name: Build and publish to package repository - id: publish - run: | - npm install - npx @dappnode/dappnodesdk publish patch \ - --provider "remote" \ - --upload_to "ipfs" \ - --verbose \ - --github_release | tee build.log - - echo "DNP (DAppNode Package) built and uploaded" >> $GITHUB_STEP_SUMMARY - grep "ipfs" build.log >> $GITHUB_STEP_SUMMARY - ipfs_hash=$(grep -oP 'Release hash : \K/ipfs/\w+' build.log) - echo "ipfs_hash=$ipfs_hash" >> $GITHUB_OUTPUT - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DEVELOPER_ADDRESS: "0x7305356ad936A06c4ea5DF45AD5E5C3ff9Db818E" - - - name: Send message to Zulip - uses: zulip/github-actions-zulip/send-message@v1 - with: - api-key: ${{ secrets.ZULIP_API_KEY }} - email: ${{ secrets.ZULIP_EMAIL }} - organization-url: "https://hopr.zulipchat.com" - type: "stream" - to: "HOPRd" - topic: "Releases" - content: | - A new hoprd dAppNode package (dufour) version is available. - - IPFS Hash: ${{ steps.publish.outputs.ipfs_hash }} - Access to your dAppNode and check for the updates \ No newline at end of file diff --git a/.gitignore b/.gitignore index c020e32..7157aeb 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ /.direnv # Node.js -/node_modules/ \ No newline at end of file +/node_modules/ + +build.log diff --git a/dappnode_package.json b/dappnode_package.json index 5293c6f..adbc0ae 100644 --- a/dappnode_package.json +++ b/dappnode_package.json @@ -1,7 +1,7 @@ { "name": "hopr.public.dappnode.eth", "version": "1.0.19", - "upstreamVersion": "kaunas", + "upstreamVersion": "5.0.0-rc.1", "description": "The HOPR protocol ensures everyone has control of their privacy, data, and identity. By running a HOPR Node, you can obtain HOPR tokens by relaying data and connect to the HOPR Network.", "type": "service", "architectures": [ @@ -18,12 +18,6 @@ "Communications", "Economic incentive" ], - "links": { - "homepage": "https://hoprnet.org/", - "ui": "http://admin.hopr.public.dappnode:4677/?apiEndpoint=http://hopr.public.dappnode:3001", - "api": "http://hopr.public.dappnode:3001/swagger-ui/index.html", - "docs": "https://docs.hoprnet.org" - }, "repository": { "type": "git", "url": "git+https://github.com/dappnode/DAppNodePackage-Hopr" @@ -35,12 +29,6 @@ "minimumDappnodeVersion": "0.2.56" }, "exposable": [ - { - "name": "HOPR Admin UI", - "description": "Port for HOPR Admin UI console", - "port": 3000, - "serviceName": "admin" - }, { "name": "HOPR REST API", "description": "Port for HOPR node REST API", @@ -108,7 +96,7 @@ "serviceName": "node" } ], - "license": "GLP-3.0", + "license": "GPL-3.0", "backup": [ { "name": "data", @@ -128,5 +116,10 @@ "node" ] } - ] + ], + "links": { + "homepage": "https://hoprnet.org/", + "api": "http://hopr.public.dappnode:3001/swagger-ui/index.html", + "docs": "https://docs.hoprnet.org" + } } diff --git a/docker-compose.yml b/docker-compose.yml index b36ca01..43f36b6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,9 +5,8 @@ services: build: context: . args: - # see https://console.cloud.google.com/artifacts/docker/hoprassociation/europe-west3/docker-images/hoprd?inv=1&invt=AbqEGg&project=hoprassociation&pli=1 - UPSTREAM_VERSION: >- - 3.0.2@sha256:9956ce16721b34298b009e48d1f3560fab798c2fccc5b8bcd0a4d4dcedf0f006 + # see https://console.cloud.google.com/artifacts/docker/hoprassociation/europe-west3/docker-images/hoprd + UPSTREAM_VERSION: 5.0.0-rc.1 ports: - "1422:1422/udp" - "1422:1422/tcp" @@ -33,21 +32,27 @@ services: - "10000-10100:10000-10100/tcp" - "10000-10100:10000-10100/udp" volumes: - - "data:/app/hoprd/data" - - "conf:/app/hoprd/conf" + - "node-data:/app/hoprd/data" + - "node-conf:/app/hoprd/conf" security_opt: - "seccomp:unconfined" environment: RUST_LOG: info HOPRD_CONFIGURATION_FILE_PATH: /app/hoprd/conf/hoprd.cfg.yaml + HOPRD_IDENTITY: /app/hoprd/conf/hopr.id + HOPRD_DATA: /app/hoprd/data HOPRD_HOST: "127.0.0.1:9091" - HOPRD_SAFE_ADDRESS: 0x - HOPRD_MODULE_ADDRESS: 0x + # Count flags, not booleans: "0" = off, "1" = on ("true"/"false" fail to parse). + HOPRD_ANNOUNCE: "1" + HOPRD_API: "1" + HOPRD_API_HOST: "0.0.0.0" + HOPRD_SAFE_ADDRESS: "0x0000000000000000000000000000000000000000" + HOPRD_MODULE_ADDRESS: "0x0000000000000000000000000000000000000000" HOPRD_PASSWORD: "" - HOPRD_PROVIDER: "" + HOPRD_API_TOKEN: "" + # Set this to override the value in hoprd.cfg.yaml + HOPRD_BLOKLI_URL: "" HOPRD_SESSION_PORT_RANGE: "10000:10100" - HOPRD_MAX_BLOCK_RANGE: 100 - HOPRD_MAX_RPC_REQUESTS_PER_SEC: 10 HOPRD_NAT: "true" ADDITIONAL_CMDLINE_ARGS: "" ADDITIONAL_ENVIRONMENT_VARS: "" @@ -56,20 +61,6 @@ services: resources: limits: memory: 2G - admin: - # The actual image name will be set automatically by the sdk. - # This tag only serves to pull the correct image during build. - build: - context: ./hopr-admin - image: >- - europe-west3-docker.pkg.dev/hoprassociation/docker-images/hopr-admin:3.0.3 - ports: - - "3000:4677" - restart: unless-stopped - deploy: - resources: - limits: - memory: 256M volumes: - data: {} - conf: {} + node-data: {} + node-conf: {} diff --git a/entrypoint.sh b/entrypoint.sh index 3c9a90e..0802680 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,3 +1,10 @@ #!/bin/bash +set -euo pipefail -env ${ADDITIONAL_ENVIRONMENT_VARS} /bin/docker-entrypoint.sh ${ADDITIONAL_CMDLINE_ARGS} +# hoprd's --blokliUrl rejects an explicit empty string - unset it so the value in +# hoprd.cfg.yaml wins, unless the setup wizard actually provided one. +if [ -z "${HOPRD_BLOKLI_URL:-}" ]; then + unset HOPRD_BLOKLI_URL +fi + +env ${ADDITIONAL_ENVIRONMENT_VARS:-} /bin/docker-entrypoint.sh ${ADDITIONAL_CMDLINE_ARGS:-} diff --git a/hopr-admin/Dockerfile b/hopr-admin/Dockerfile deleted file mode 100644 index c12708d..0000000 --- a/hopr-admin/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM europe-west3-docker.pkg.dev/hoprassociation/docker-images/hopr-admin:3.0.3 - -ENTRYPOINT ["nginx", "-g", "daemon off;"] diff --git a/hoprd.cfg.yaml b/hoprd.cfg.yaml index 96ec9dd..582d7a1 100644 --- a/hoprd.cfg.yaml +++ b/hoprd.cfg.yaml @@ -1,35 +1,70 @@ --- +blokli_url: https://blokli-piz-palu.prod.hoprnet.link hopr: - db: - data: /app/hoprd/data - initialize: true - force_initialize: false - strategy: - on_fail_continue: true - allow_recursive: true - strategies: - - !AutoRedeeming - redeem_only_aggregated: false - minimum_redeem_ticket_value: "1 wxHOPR" - - !ClosureFinalizer - max_closure_overdue: 300 - chain: - announce: true - network: dufour - keep_logs: true - fast_sync: true - safe_module: - safe_transaction_service_provider: https://safe-transaction.prod.hoprnet.link/ - transport: - announce_local_addresses: false - prefer_local_addresses: false -identity: - file: /app/hoprd/conf/hopr.id -api: - enable: true - host: - address: !IPv4 0.0.0.0 - port: 3001 -session_ip_forwarding: - target_allow_list: [] - + network: + pix: + num_ssa_parts: 4096 + ssa_part_size: 64 + additional_shares: 20 + max_ssas_per_request: 3 + incoming_session_pix: + enforce_pix: false + max_ssa_delivery_time: 20s + max_deposit_wait: 60s + ssas_per_request: 1 +strategy: + allow_recursive: false + execution_interval: 15s + strategies: + - ChannelLifecycle: + population: + min_open_channels: 10 + target_open_channels: 40 + eligibility: + require_currently_connected: true + min_peer_quality_score: 0.5 + peer_quality_weight: 0.6 + ticket_activity_weight: 0.4 + require_observed_since_start: true + allowlist: ~ + blocklist: [] + # Channel funding is expressed as data capacity; the node resolves each + # capacity to wxHOPR every tick using live ticket economics. Since + # hopr-strategy 0.25 the hop count is fixed at ASSUMED_HOPS = 3 and the + # assumed_hops key is rejected outright (deny_unknown_fields): + # N = ceil(capacity_bytes / 1038) # HoprPacket::PAYLOAD_SIZE + # F = ticket_price * 3 / winning_prob # one winning ticket + # E = N * 3 * ticket_price # mean drain + # stake = whole_tickets(max(F, E)) # sizing_mode: deterministic + # + # Every capacity is floored at one winning ticket and then rounded up to + # a whole number of them, so the tiers below only stay distinct while + # they sit above that floor. Note deterministic changed meaning in 0.23: + # it is the mean drain floored at one ticket, no longer a worst case. + # ticket_price = 1e-16 wxHOPR, winning_prob = 1.25e-4 + # => F = 2.4e-12 wxHOPR (2400000 wei); the floor binds below ~8.3 MB. + # stake (initial_capacity) = 1 GiB -> 130 tickets -> 312000000 wei + # topup (topup_capacity) = 1 GiB -> 130 tickets -> 312000000 wei + # floor (lower_capacity_threshold) = 512 MiB -> 65 tickets -> 156000000 wei topup trigger + funding: + initial_capacity: "1 GiB" + topup_capacity: "1 GiB" + lower_capacity_threshold: "512 MiB" + proactive_funding: + enabled: true + safety_margin: 1.5 + balance_drain_weight: 1.0 + ticket_index_drain_weight: 1.0 + closure: + close_below_quality_score: 0.3 + close_when_drained_below: "0 wxHOPR" + close_max_concurrent: 2 + finalizer: + enabled: true + finalize_max_concurrent: 30 + restart: {} + concurrency: + max_concurrent_actions: 30 + selector: default + - AutoRedeeming: + minimum_redeem_ticket_value: "1 wei wxHOPR" diff --git a/justfile b/justfile index ca5f078..2a2f1be 100644 --- a/justfile +++ b/justfile @@ -1,3 +1,7 @@ -# build the dappnode package +# Build the DAppNode package build: - npx @dappnode/dappnodesdk build + npx @dappnode/dappnodesdk build + +# Re-validate hoprd.cfg.yaml against the real hoprd config parser +validate-config: + ./test/validate-hoprd-config.sh diff --git a/setup-wizard.yml b/setup-wizard.yml index 5aa2208..3f9fcb6 100644 --- a/setup-wizard.yml +++ b/setup-wizard.yml @@ -24,21 +24,20 @@ fields: Secret token to the REST API exposed by the node. Set this value **only if** you don't want to use the DMS metrics for the HOPR node - *or* if you plan to expose your REST API (port 3001) or HOPR Admin UI (port 3000) to the public. + *or* if you plan to expose your REST API (port 3001) to the public. secret: true - - id: HOPRD_PROVIDER + - id: HOPRD_BLOKLI_URL target: type: environment - name: HOPRD_PROVIDER + name: HOPRD_BLOKLI_URL service: node - title: RPC Provider URL + title: Blokli URL required: false description: |- - URL to the custom RPC provider this HOPR node should use. Supports simple query strings. - If your DAppnode is running a Gnosis Chain RPC endpoint, it is **strongly recommended** to use it here. + URL to the Blokli provider this HOPR node should use. - *Example:* `http://nethermind-xdai.dappnode:8545` + *Example:* `https://blokli-piz-palu.prod.hoprnet.link` secret: false # Regular expression for matching URLs with simple query strings # @@ -53,14 +52,7 @@ fields: # - (:[0-9]{2,5})? : Optional port number (10-99999) # Examples: :80, :8080, :44300 # - # - (/[a-z0-9.-/_]*)? : Optional URL path - # Allows: slashes, lowercase letters, numbers, dots, hyphens, underscores - # Examples: /path, /path/to/resource, /api/v1/endpoint - # - # - (\?[a-z0-9._=&-]*)? : Optional query string - # Allows: lowercase letters, numbers, dots, underscores, equals signs, ampersands, hyphens - # Examples: ?param=value, ?id=123&type=test, ?user.name=john_doe - pattern: ^http[s]{0,1}:\/\/[a-z0-9.-]{3,}(:[0-9]{2,5})?(\/[a-z0-9.-/_]*)?(\?[a-z0-9._=&-]*)?$ + pattern: ^http[s]{0,1}:\/\/[a-z0-9.-]{3,}(:[0-9]{2,5})?$ patternErrorMessage: Must be a valid url starting with `http://` or `https://` # - id: IDENTITY @@ -137,7 +129,7 @@ fields: *Example (dynDNS entry):* `abcd1234.dyndns.dappnode.io:9091` secret: false - pattern: ^[a-z0-9.-]{3,}:909[1-9]$ + pattern: "^[a-z0-9.-]{3,}:909[1-9]$" patternErrorMessage: Must be in correct host:port format! - id: HOPRD_NAT @@ -148,9 +140,9 @@ fields: title: Enable NAT mode required: false description: |- - By default the HOPR node assumes that it is running behind a NAT when run on a dappnode. - If your DAppNode is connected directly to the modem, set this option to `false`. - If it’s connected through a router (behind NAT), leave it as `true`. + By default the HOPR node assumes that it is running behind a NAT on a + dappnode. If this is not the case or proper port forwarding has been + set up this option can be set to `false` to disable NAT mode. secret: false pattern: ^(true|false)$ patternErrorMessage: Must be either `true` or `false`! diff --git a/test/validate-hoprd-config.sh b/test/validate-hoprd-config.sh new file mode 100755 index 0000000..d700854 --- /dev/null +++ b/test/validate-hoprd-config.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Validates hoprd.cfg.yaml against the real hoprd binary's own config parser +# (`hoprd-cfg --validate-args`), the same check hoprd effectively runs before launching. +# The image tag is read from docker-compose.yml's UPSTREAM_VERSION. +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +HOPRD_VERSION="$(sed -n 's/^ *UPSTREAM_VERSION: *\([^ @]*\).*/\1/p' docker-compose.yml)" +HOPRD_IMAGE="europe-west3-docker.pkg.dev/hoprassociation/docker-images/hoprd:${HOPRD_VERSION}" + +docker pull "${HOPRD_IMAGE}" >/dev/null +docker run --rm \ + -v "$(pwd)/hoprd.cfg.yaml:/app/hoprd.cfg.yaml:ro" \ + --entrypoint /bin/hoprd-cfg \ + "${HOPRD_IMAGE}" \ + --validate-args -- \ + --identity /app/hopr.id \ + --data /app/data \ + --password validation-password \ + --apiToken validation-token-123456 \ + --safeAddress 0x0000000000000000000000000000000000000001 \ + --moduleAddress 0x0000000000000000000000000000000000000002 \ + --host 1.2.3.4:9091 \ + --configurationFilePath /app/hoprd.cfg.yaml + +echo "hoprd.cfg.yaml is a valid config for ${HOPRD_IMAGE}."