Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 60731ad2d4 |
@@ -25,7 +25,7 @@ Steps to reproduce the behaviour, if you're familiar with BDD syntax, please wri
|
|||||||
|
|
||||||
*An example:*
|
*An example:*
|
||||||
- Given I was setting up a mix-node following the instructions in the docs
|
- Given I was setting up a mix-node following the instructions in the docs
|
||||||
- And I successfully bonded my node via the wallet
|
- And I successfully bonded my node via the the wallet
|
||||||
- When I went to start my mixnode
|
- When I went to start my mixnode
|
||||||
- Then I was presented with an error
|
- Then I was presented with an error
|
||||||
|
|
||||||
|
|||||||
Generated
+18
-55
@@ -1259,7 +1259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3970,7 +3970,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4657,6 +4657,17 @@ dependencies = [
|
|||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.27.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.1",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.29.0"
|
version = "0.29.0"
|
||||||
@@ -4670,18 +4681,6 @@ dependencies = [
|
|||||||
"memoffset",
|
"memoffset",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nix"
|
|
||||||
version = "0.30.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.9.1",
|
|
||||||
"cfg-if",
|
|
||||||
"cfg_aliases",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "no-std-compat"
|
name = "no-std-compat"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@@ -6294,23 +6293,6 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nym-mixnet-contract"
|
|
||||||
version = "1.5.1"
|
|
||||||
dependencies = [
|
|
||||||
"bs58",
|
|
||||||
"cosmwasm-std",
|
|
||||||
"cw-controllers",
|
|
||||||
"cw-storage-plus",
|
|
||||||
"cw2",
|
|
||||||
"nym-contracts-common",
|
|
||||||
"nym-contracts-common-testing",
|
|
||||||
"nym-mixnet-contract-common",
|
|
||||||
"nym-vesting-contract-common",
|
|
||||||
"semver 1.0.26",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-mixnet-contract-common"
|
name = "nym-mixnet-contract-common"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@@ -6830,25 +6812,6 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nym-performance-contract"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"cosmwasm-schema",
|
|
||||||
"cosmwasm-std",
|
|
||||||
"cw-controllers",
|
|
||||||
"cw-storage-plus",
|
|
||||||
"cw2",
|
|
||||||
"nym-contracts-common",
|
|
||||||
"nym-contracts-common-testing",
|
|
||||||
"nym-crypto",
|
|
||||||
"nym-mixnet-contract",
|
|
||||||
"nym-mixnet-contract-common",
|
|
||||||
"nym-performance-contract-common",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-performance-contract-common"
|
name = "nym-performance-contract-common"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -7771,7 +7734,7 @@ dependencies = [
|
|||||||
"hex",
|
"hex",
|
||||||
"humantime",
|
"humantime",
|
||||||
"humantime-serde",
|
"humantime-serde",
|
||||||
"nix 0.30.1",
|
"nix 0.27.1",
|
||||||
"nym-async-file-watcher",
|
"nym-async-file-watcher",
|
||||||
"nym-bin-common",
|
"nym-bin-common",
|
||||||
"nym-config",
|
"nym-config",
|
||||||
@@ -8763,7 +8726,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"socket2 0.5.10",
|
"socket2 0.5.10",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -9212,7 +9175,7 @@ dependencies = [
|
|||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.4.15",
|
"linux-raw-sys 0.4.15",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -10539,7 +10502,7 @@ dependencies = [
|
|||||||
"getrandom 0.3.3",
|
"getrandom 0.3.3",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.0.8",
|
"rustix 1.0.8",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -12393,7 +12356,7 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
+1
-2
@@ -34,7 +34,6 @@ members = [
|
|||||||
"common/nym-common",
|
"common/nym-common",
|
||||||
"common/config",
|
"common/config",
|
||||||
"common/cosmwasm-smart-contracts/coconut-dkg",
|
"common/cosmwasm-smart-contracts/coconut-dkg",
|
||||||
"contracts/performance",
|
|
||||||
"common/cosmwasm-smart-contracts/contracts-common",
|
"common/cosmwasm-smart-contracts/contracts-common",
|
||||||
"common/cosmwasm-smart-contracts/contracts-common-testing",
|
"common/cosmwasm-smart-contracts/contracts-common-testing",
|
||||||
"common/cosmwasm-smart-contracts/easy_addr",
|
"common/cosmwasm-smart-contracts/easy_addr",
|
||||||
@@ -295,7 +294,7 @@ ledger-transport-hid = "0.10.0"
|
|||||||
log = "0.4"
|
log = "0.4"
|
||||||
mime = "0.3.17"
|
mime = "0.3.17"
|
||||||
moka = { version = "0.12", features = ["future"] }
|
moka = { version = "0.12", features = ["future"] }
|
||||||
nix = "0.30.1"
|
nix = "0.27.1"
|
||||||
notify = "5.1.0"
|
notify = "5.1.0"
|
||||||
once_cell = "1.21.3"
|
once_cell = "1.21.3"
|
||||||
opentelemetry = "0.19.0"
|
opentelemetry = "0.19.0"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
ansible_ssh_private_key_file: ~/.ssh/<SSH_KEY>
|
ansible_ssh_private_key_file: ~/.ssh/<SSH_KEY>
|
||||||
|
|
||||||
# nym_version: "v2025.21-mozzarella"
|
# nym_version: "v2025.21-mozzarella"
|
||||||
#
|
#
|
||||||
# NOTE:
|
# NOTE:
|
||||||
# if you want to pin Nym to a specific version instead of using the
|
# if you want to pin Nym to a specific version instead of using the
|
||||||
# latest release from GitHub in /tasks/main.yml then
|
# latest release from GitHub in /tasks/main.yml then
|
||||||
@@ -13,17 +13,17 @@ tunnel_manager_url: "https://github.com/nymtech/nym/raw/refs/heads/develop/scrip
|
|||||||
quic_bridge_deployment_url: "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/quic_bridge_deployment.sh"
|
quic_bridge_deployment_url: "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/quic_bridge_deployment.sh"
|
||||||
|
|
||||||
# NOTE: These values will be used globally unless overwritten per node in inventory/all
|
# NOTE: These values will be used globally unless overwritten per node in inventory/all
|
||||||
ansible_user: root # used for ssh, like `ssh root@nym-exit.ch-1.mynodes.net`
|
ansible_user: root # used for ssh, like `ssh root@nym-exit.ch-1.mynodes.net`
|
||||||
email: "<EMAIL>" # used in certbot, description.toml and landing page
|
email: "<EMAIL>" # used in certbot, description.toml and landing page
|
||||||
website: "<WEBSITE>" # it is used in the description.toml
|
website: "<WEBSITE>" # it is used in the description.toml
|
||||||
description: "<NODE_PUBLIC_DESCRIPTION>" # or define per node in inventory/all
|
description: "<NODE_PUBLIC_DESCRIPTION>" # or define per node in inventory/all
|
||||||
|
|
||||||
# NOTE: Set these vars if you want them globally for all nodes
|
# NOTE: Set these vars if you want them globally for all nodes
|
||||||
# Per node changes in inventory/all will overwrite these global ones:
|
# Per node changes in inventory/all will overwrite these global ones:
|
||||||
hostname: "" # this is a fallback, keep it and setup hostname per node in inventory/all
|
hostname: "" # this is a fallback, keep it and setup hostname per node in inventory/all
|
||||||
# moniker: "<MONIKER>" # if not setup here not in inventory/all it get's derived from the hostname
|
# moniker: "<MONIKER>" # if not setup here not in inventory/all it get's derived from the hostname
|
||||||
# mode: <MODE> # entry-gateway/exit-gateway/mixnode
|
# mode: <MODE> # entry-gateway/exit-gateway/mixnode
|
||||||
# wireguard_enabled: <WIREGUARD_ENABLED> # true/false
|
# wireguard_enabled: <WIREGUARD_ENABLED> # true/false
|
||||||
|
|
||||||
# NOTE: Possible vars to incule on landing page, etc.
|
# NOTE: Possible vars to incule on landing page, etc.
|
||||||
# operator_name: "<OPERATOR_NAME>"
|
# operator_name: "<OPERATOR_NAME>"
|
||||||
@@ -41,4 +41,4 @@ packages:
|
|||||||
- ca-certificates
|
- ca-certificates
|
||||||
- jq
|
- jq
|
||||||
- wget
|
- wget
|
||||||
- ufw
|
- ufw
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
---
|
|
||||||
- name: Set hostname
|
- name: Set hostname
|
||||||
hostname:
|
hostname:
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
when: hostname is defined and hostname | length > 0
|
when: hostname is defined and hostname | length > 0
|
||||||
|
|
||||||
- name: Install aptitude
|
- name: Install aptitude
|
||||||
apt:
|
apt:
|
||||||
name: aptitude
|
name: aptitude
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
@@ -15,9 +14,9 @@
|
|||||||
apt:
|
apt:
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
upgrade: yes
|
upgrade: yes
|
||||||
|
|
||||||
- name: Install essential packages
|
- name: Install essential packages
|
||||||
package:
|
package:
|
||||||
name: "{{ packages }}"
|
name: "{{ packages }}"
|
||||||
state: latest
|
state: latest
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Reload nginx
|
|
||||||
service:
|
|
||||||
name: nginx
|
|
||||||
state: reloaded
|
|
||||||
|
|
||||||
- name: Restart nginx
|
|
||||||
service:
|
|
||||||
name: nginx
|
|
||||||
state: restarted
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
---
|
|
||||||
- name: Install nginx and certbot
|
- name: Install nginx and certbot
|
||||||
apt:
|
apt:
|
||||||
name:
|
name:
|
||||||
@@ -6,168 +5,57 @@
|
|||||||
- certbot
|
- certbot
|
||||||
- python3-certbot-nginx
|
- python3-certbot-nginx
|
||||||
state: present
|
state: present
|
||||||
update_cache: yes
|
|
||||||
|
|
||||||
- name: Ensure nginx snippets directory exists
|
- name: Create web root directory
|
||||||
file:
|
|
||||||
path: /etc/nginx/snippets
|
|
||||||
state: directory
|
|
||||||
mode: "0755"
|
|
||||||
|
|
||||||
# own SSL defaults - don't rely on certbot files
|
|
||||||
- name: Install Nym SSL options snippet
|
|
||||||
copy:
|
|
||||||
dest: /etc/nginx/snippets/nym-ssl-options.conf
|
|
||||||
mode: "0644"
|
|
||||||
content: |
|
|
||||||
ssl_session_cache shared:NYMSSL:10m;
|
|
||||||
ssl_session_timeout 1d;
|
|
||||||
ssl_session_tickets off;
|
|
||||||
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_prefer_server_ciphers off;
|
|
||||||
|
|
||||||
# Reasonable modern cipher set (works across Ubuntu nginx builds)
|
|
||||||
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305";
|
|
||||||
|
|
||||||
# OCSP stapling is nice but can break if resolver isn't set; keep minimal here.
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
- name: Ensure web root directory exists
|
|
||||||
file:
|
file:
|
||||||
path: "/var/www/{{ hostname }}"
|
path: "/var/www/{{ hostname }}"
|
||||||
state: directory
|
state: directory
|
||||||
mode: "0755"
|
mode: "0755"
|
||||||
|
|
||||||
- name: Deploy landing page
|
- name: Create landing page template
|
||||||
|
tags: landing
|
||||||
template:
|
template:
|
||||||
src: landing.html.j2
|
src: landing.html.j2
|
||||||
dest: "/var/www/{{ hostname }}/index.html"
|
dest: "/var/www/{{ hostname }}/index.html"
|
||||||
mode: "0644"
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
# remove default site - safe on fresh + redeploy
|
- name: Remove default nginx site
|
||||||
- name: Disable default nginx site symlink
|
|
||||||
file:
|
file:
|
||||||
path: /etc/nginx/sites-enabled/default
|
path: /etc/nginx/sites-enabled/default
|
||||||
state: absent
|
state: absent
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
- name: Remove default nginx site definition if present
|
- name: Add bare-bones nginx template
|
||||||
file:
|
|
||||||
path: /etc/nginx/sites-available/default
|
|
||||||
state: absent
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
# always deploy/enable HTTP vhost
|
|
||||||
- name: Deploy HTTP vhost
|
|
||||||
template:
|
template:
|
||||||
src: nginx-site.conf.j2
|
src: nginx-site.conf.j2
|
||||||
dest: "/etc/nginx/sites-available/{{ hostname }}"
|
dest: "/etc/nginx/sites-available/{{ hostname }}"
|
||||||
mode: "0644"
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
- name: Enable HTTP vhost (force correct symlink)
|
- name: Enable nginx config
|
||||||
file:
|
file:
|
||||||
src: "/etc/nginx/sites-available/{{ hostname }}"
|
src: "/etc/nginx/sites-available/{{ hostname }}"
|
||||||
dest: "/etc/nginx/sites-enabled/{{ hostname }}"
|
dest: "/etc/nginx/sites-enabled/{{ hostname }}"
|
||||||
state: link
|
state: link
|
||||||
force: true
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
# detect if cert exists already
|
- name: Validate nginx configuration
|
||||||
- name: Check whether certificate exists
|
|
||||||
stat:
|
|
||||||
path: "/etc/letsencrypt/live/{{ hostname }}/fullchain.pem"
|
|
||||||
register: le_cert
|
|
||||||
|
|
||||||
# if cert does NOT exist yet, ensure SSL/WSS are NOT enabled
|
|
||||||
- name: Ensure SSL and WSS vhosts are disabled until cert exists
|
|
||||||
file:
|
|
||||||
path: "{{ item }}"
|
|
||||||
state: absent
|
|
||||||
loop:
|
|
||||||
- "/etc/nginx/sites-enabled/{{ hostname }}-ssl"
|
|
||||||
- "/etc/nginx/sites-enabled/nym-wss-config"
|
|
||||||
when: not le_cert.stat.exists
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
- name: Ensure nginx is enabled and running (needed for ACME http-01)
|
|
||||||
service:
|
|
||||||
name: nginx
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
|
|
||||||
- name: Validate nginx configuration (HTTP stage)
|
|
||||||
command: nginx -t
|
command: nginx -t
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Flush handlers (ensure HTTP is active before certbot)
|
- name: Obtain SSL certificate
|
||||||
meta: flush_handlers
|
|
||||||
|
|
||||||
# certbot strategy:
|
|
||||||
# - if cert exists: webroot - doesn't touch nginx
|
|
||||||
# - else: --nginx works first-time; may touch nginx
|
|
||||||
- name: Obtain/renew certificate
|
|
||||||
command:
|
command:
|
||||||
cmd: >-
|
cmd: "certbot --nginx --non-interactive --agree-tos --redirect -m {{ email }} -d {{ hostname }}"
|
||||||
{% if le_cert.stat.exists %}
|
|
||||||
certbot certonly --webroot
|
|
||||||
-w /var/www/{{ hostname }}
|
|
||||||
--non-interactive --agree-tos --keep-until-expiring
|
|
||||||
-m {{ email }} -d {{ hostname }}
|
|
||||||
{% else %}
|
|
||||||
certbot --nginx
|
|
||||||
--non-interactive --agree-tos --redirect
|
|
||||||
-m {{ email }} -d {{ hostname }}
|
|
||||||
{% endif %}
|
|
||||||
register: certbot_result
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
# re-check cert after certbot attempt
|
- name: Add wss config from nginx template
|
||||||
- name: Re-check whether certificate exists after certbot
|
|
||||||
stat:
|
|
||||||
path: "/etc/letsencrypt/live/{{ hostname }}/fullchain.pem"
|
|
||||||
register: le_cert_after
|
|
||||||
|
|
||||||
# only deploy/enable SSL & WSS if cert exists
|
|
||||||
- name: Deploy HTTPS vhost for {{ hostname }}
|
|
||||||
template:
|
|
||||||
src: nginx-site-ssl.conf.j2
|
|
||||||
dest: "/etc/nginx/sites-available/{{ hostname }}-ssl"
|
|
||||||
mode: "0644"
|
|
||||||
when: le_cert_after.stat.exists
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
- name: Enable HTTPS vhost (force correct symlink)
|
|
||||||
file:
|
|
||||||
src: "/etc/nginx/sites-available/{{ hostname }}-ssl"
|
|
||||||
dest: "/etc/nginx/sites-enabled/{{ hostname }}-ssl"
|
|
||||||
state: link
|
|
||||||
force: true
|
|
||||||
when: le_cert_after.stat.exists
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
- name: Deploy WSS vhost
|
|
||||||
template:
|
template:
|
||||||
src: wss-config.conf.j2
|
src: wss-config.conf.j2
|
||||||
dest: "/etc/nginx/sites-available/nym-wss-config"
|
dest: "/etc/nginx/sites-available/nym-wss-config"
|
||||||
mode: "0644"
|
|
||||||
when: le_cert_after.stat.exists
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
- name: Enable WSS vhost (force correct symlink)
|
- name: Enable WSS config
|
||||||
file:
|
file:
|
||||||
src: "/etc/nginx/sites-available/nym-wss-config"
|
src: "/etc/nginx/sites-available/nym-wss-config"
|
||||||
dest: "/etc/nginx/sites-enabled/nym-wss-config"
|
dest: "/etc/nginx/sites-enabled/nym-wss-config"
|
||||||
state: link
|
state: link
|
||||||
force: true
|
|
||||||
when: le_cert_after.stat.exists
|
|
||||||
notify: Restart nginx
|
|
||||||
|
|
||||||
- name: Validate nginx configuration (final)
|
- name: Validate nginx config after wss
|
||||||
command: nginx -t
|
command: nginx -t
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Flush handlers (apply restart after successful tests)
|
- name: Restart nginx to apply changes
|
||||||
meta: flush_handlers
|
service: name=nginx state=restarted enabled=yes
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name {{ hostname }};
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/{{ hostname }}/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/{{ hostname }}/privkey.pem;
|
|
||||||
include /etc/nginx/snippets/nym-ssl-options.conf;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:8080;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,15 +4,10 @@ server {
|
|||||||
|
|
||||||
server_name {{ hostname }};
|
server_name {{ hostname }};
|
||||||
|
|
||||||
root /var/www/{{ hostname }};
|
|
||||||
index index.html;
|
|
||||||
|
|
||||||
location ^~ /.well-known/acme-challenge/ {
|
|
||||||
default_type "text/plain";
|
|
||||||
try_files $uri =404;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
return 301 https://$host$request_uri;
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,10 @@ server {
|
|||||||
|
|
||||||
server_name {{ hostname }};
|
server_name {{ hostname }};
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/{{ hostname }}/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/{{ hostname }}/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/{{ hostname }}/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/{{ hostname }}/privkey.pem;
|
||||||
include /etc/nginx/snippets/nym-ssl-options.conf;
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||||
|
|
||||||
access_log /var/log/nginx/access.log;
|
access_log /var/log/nginx/access.log;
|
||||||
error_log /var/log/nginx/error.log;
|
error_log /var/log/nginx/error.log;
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ nym_install_dir: /root/nym-binaries
|
|||||||
http_bind_address: "0.0.0.0:8080" # maps to --http-bind-address
|
http_bind_address: "0.0.0.0:8080" # maps to --http-bind-address
|
||||||
mixnet_bind_address: "0.0.0.0:1789" # maps to --mixnet-bind-address
|
mixnet_bind_address: "0.0.0.0:1789" # maps to --mixnet-bind-address
|
||||||
|
|
||||||
|
|
||||||
|
# WireGuard boolean
|
||||||
|
wireguard_enabled: "{{ wireguard_enabled | default(false) | bool }}"
|
||||||
|
|
||||||
# Landing page base dir, hostname is appended in the task
|
# Landing page base dir, hostname is appended in the task
|
||||||
landing_page_assets_base_dir: "/var/www"
|
landing_page_assets_base_dir: "/var/www"
|
||||||
|
|
||||||
@@ -33,4 +37,4 @@ nym_ufw_rules:
|
|||||||
- { port: 8080, proto: tcp }
|
- { port: 8080, proto: tcp }
|
||||||
- { port: 9000, proto: tcp }
|
- { port: 9000, proto: tcp }
|
||||||
- { port: 9001, proto: tcp }
|
- { port: 9001, proto: tcp }
|
||||||
- { port: 51822, proto: udp }
|
- { port: 51822, proto: udp }
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
---
|
|
||||||
- name: Reload systemd
|
- name: Reload systemd
|
||||||
systemd:
|
systemd:
|
||||||
daemon_reload: yes
|
daemon_reload: yes
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
# useful when the host is behind a NAT
|
# Useful when the host is behind a NAT
|
||||||
- name: Fetch the public IP address
|
- name: Fetch the public IP address
|
||||||
command: "curl -4 canhazip.com"
|
command: "curl -4 canhazip.com"
|
||||||
register: ipv4
|
register: ipv4
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
public_ip: "{{ ipv4.stdout | default(ansible_default_ipv4.address) }}"
|
public_ip: "{{ ipv4.stdout | default(ansible_default_ipv4.address) }}"
|
||||||
|
|
||||||
- name: Initialize nym node
|
- name: Initialize nym node
|
||||||
# delete the part from --hostname onward if you run mode=mixnode only
|
# Delete the part from --hostname onward if you run mode=mixnode only
|
||||||
command:
|
command:
|
||||||
cmd: >
|
cmd: >
|
||||||
{{ nym_install_dir }}/nym-node run
|
{{ nym_install_dir }}/nym-node run
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
{{ nym_extra_flags }}
|
{{ nym_extra_flags }}
|
||||||
|
|
||||||
--hostname {{ hostname }}
|
--hostname {{ hostname }}
|
||||||
--wireguard-enabled {{ (wireguard_enabled | default('false') | bool) | ternary('true','false') }}
|
--wireguard-enabled {{ wireguard_enabled }}
|
||||||
--landing-page-assets-path {{ landing_page_assets_base_dir }}/{{ hostname }}/
|
--landing-page-assets-path {{ landing_page_assets_base_dir }}/{{ hostname }}/
|
||||||
{% if nym_write_flag %}-w{% endif %}
|
{% if nym_write_flag %}-w{% endif %}
|
||||||
{% if nym_init_only_flag %}--init-only{% endif %}
|
{% if nym_init_only_flag %}--init-only{% endif %}
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
---
|
|
||||||
- name: Ensure UFW is installed
|
|
||||||
apt:
|
|
||||||
name: ufw
|
|
||||||
state: present
|
|
||||||
update_cache: yes
|
|
||||||
when: nym_ufw_enable
|
|
||||||
|
|
||||||
|
|
||||||
- name: Configure UFW rules
|
- name: Configure UFW rules
|
||||||
ufw:
|
ufw:
|
||||||
rule: allow
|
rule: allow
|
||||||
@@ -23,10 +14,9 @@
|
|||||||
- name: Allow bandwidth/topup rule inside WG tunnel
|
- name: Allow bandwidth/topup rule inside WG tunnel
|
||||||
command: >
|
command: >
|
||||||
ufw allow in on nymwg to any port 51830 proto tcp comment 'bandwidth queries/topup'
|
ufw allow in on nymwg to any port 51830 proto tcp comment 'bandwidth queries/topup'
|
||||||
changed_when: false
|
|
||||||
when:
|
when:
|
||||||
- nym_ufw_enable
|
- nym_ufw_enable
|
||||||
- (wireguard_enabled | default(false) | bool)
|
- (wireguard_enabled | bool)
|
||||||
|
|
||||||
- name: Enable UFW
|
- name: Enable UFW
|
||||||
ufw:
|
ufw:
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ StartLimitBurst=10
|
|||||||
[Service]
|
[Service]
|
||||||
User={{ ansible_user }}
|
User={{ ansible_user }}
|
||||||
LimitNOFILE=65536
|
LimitNOFILE=65536
|
||||||
ExecStart=/root/nym-binaries/nym-node run --mode {{ mode }} --accept-operator-terms-and-conditions --wireguard-enabled {{ (wireguard_enabled | default(false) | bool) | ternary('true','false') }}
|
ExecStart=/root/nym-binaries/nym-node run --mode {{ mode }} --accept-operator-terms-and-conditions --wireguard-enabled {{ wireguard_enabled }}
|
||||||
KillSignal=SIGINT
|
KillSignal=SIGINT
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=30
|
RestartSec=30
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
---
|
- name: Download network-tunnel-manager.sh
|
||||||
|
tags: network tunnel manager
|
||||||
|
get_url:
|
||||||
|
url: "{{ tunnel_manager_url }}"
|
||||||
|
dest: "/root/nym-binaries/network-tunnel-manager.sh"
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
- name: Configure tunnel manager
|
- name: Configure tunnel manager
|
||||||
tags:
|
tags: network tunnel manager
|
||||||
- network_tunnel_manager
|
|
||||||
become: true
|
become: true
|
||||||
command:
|
command:
|
||||||
cmd: "/root/nym-binaries/network-tunnel-manager.sh {{ item }}"
|
cmd: "/root/nym-binaries/network-tunnel-manager.sh {{ item }}"
|
||||||
loop:
|
loop:
|
||||||
- complete_networking_configuration
|
- complete_networking_configuration
|
||||||
register: tunnel_mgr
|
|
||||||
failed_when: false
|
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
when: not ansible_check_mode and (upgrade_ok | default(false)) == false
|
when: not ansible_check_mode and (upgrade_ok | default(false)) == false
|
||||||
|
|
||||||
# optional: hard-fail the play for CI environments
|
# optional: hard-fail the play for CI environments
|
||||||
#- name: fail the play to signal upgrade failure
|
#- name: Fail the play to signal upgrade failure
|
||||||
# fail:
|
# fail:
|
||||||
# msg: "nym-node upgrade failed; rolled back to previous binary."
|
# msg: "nym-node upgrade failed; rolled back to previous binary."
|
||||||
# when: not ansible_check_mode and (upgrade_ok | default(false)) == false
|
# when: not ansible_check_mode and (upgrade_ok | default(false)) == false
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ pub use nym_performance_contract_common::{
|
|||||||
EpochMeasurementsPagedResponse, EpochNodePerformance, EpochPerformancePagedResponse,
|
EpochMeasurementsPagedResponse, EpochNodePerformance, EpochPerformancePagedResponse,
|
||||||
FullHistoricalPerformancePagedResponse, HistoricalPerformance, LastSubmission,
|
FullHistoricalPerformancePagedResponse, HistoricalPerformance, LastSubmission,
|
||||||
NetworkMonitorInformation, NetworkMonitorsPagedResponse, NodeId, NodeMeasurement,
|
NetworkMonitorInformation, NetworkMonitorsPagedResponse, NodeId, NodeMeasurement,
|
||||||
NodeMeasurementsPerKindResponse, NodePerformance, NodePerformancePagedResponse,
|
NodeMeasurementsResponse, NodePerformance, NodePerformancePagedResponse,
|
||||||
NodePerformanceResponse, RetiredNetworkMonitor, RetiredNetworkMonitorsPagedResponse,
|
NodePerformanceResponse, RetiredNetworkMonitor, RetiredNetworkMonitorsPagedResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ pub trait PerformanceQueryClient {
|
|||||||
&self,
|
&self,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
) -> Result<NodeMeasurementsPerKindResponse, NyxdError> {
|
) -> Result<NodeMeasurementsResponse, NyxdError> {
|
||||||
self.query_performance_contract(PerformanceQueryMsg::NodeMeasurements { epoch_id, node_id })
|
self.query_performance_contract(PerformanceQueryMsg::NodeMeasurements { epoch_id, node_id })
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ pub(crate) enum CommonConfigsWrapper {
|
|||||||
// nym-api
|
// nym-api
|
||||||
NymApi(NymApiConfigLight),
|
NymApi(NymApiConfigLight),
|
||||||
|
|
||||||
// anything else that might get introduced
|
// anything else that might get get introduced
|
||||||
Unknown(UnknownConfigWrapper),
|
Unknown(UnknownConfigWrapper),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ pub mod storage_keys {
|
|||||||
pub const AUTHORISED_COUNT: &str = "authorised-count";
|
pub const AUTHORISED_COUNT: &str = "authorised-count";
|
||||||
pub const AUTHORISED: &str = "authorised";
|
pub const AUTHORISED: &str = "authorised";
|
||||||
pub const RETIRED: &str = "retired";
|
pub const RETIRED: &str = "retired";
|
||||||
pub const PERFORMANCE_RESULTS_PER_KIND: &str = "performance-results-per-kind";
|
pub const PERFORMANCE_RESULTS: &str = "performance-results";
|
||||||
pub const PERFORMANCE_DEFINED_KINDS: &str = "performance-defined-kinds";
|
|
||||||
|
|
||||||
pub const SUBMISSION_METADATA: &str = "submission-metadata";
|
pub const SUBMISSION_METADATA: &str = "submission-metadata";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,15 +23,6 @@ pub enum NymPerformanceContractError {
|
|||||||
#[error("{address} is not an authorised network monitor")]
|
#[error("{address} is not an authorised network monitor")]
|
||||||
NotAuthorised { address: Addr },
|
NotAuthorised { address: Addr },
|
||||||
|
|
||||||
#[error("{kind} not a valid measurement kind")]
|
|
||||||
UnsupportedMeasurementKind { kind: String },
|
|
||||||
|
|
||||||
#[error("Measurement {kind} already defined")]
|
|
||||||
MeasurementAlreadyDefined { kind: String },
|
|
||||||
|
|
||||||
#[error("Invalid input: {0}")]
|
|
||||||
InvalidInput(String),
|
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"attempted to submit performance data for epoch {epoch_id} and node {node_id} whilst last submitted was {last_epoch_id} for node {last_node_id}"
|
"attempted to submit performance data for epoch {epoch_id} and node {node_id} whilst last submitted was {last_epoch_id} for node {last_node_id}"
|
||||||
)]
|
)]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use cosmwasm_schema::cw_serde;
|
|||||||
use crate::types::{
|
use crate::types::{
|
||||||
EpochMeasurementsPagedResponse, EpochPerformancePagedResponse,
|
EpochMeasurementsPagedResponse, EpochPerformancePagedResponse,
|
||||||
FullHistoricalPerformancePagedResponse, LastSubmission, NetworkMonitorResponse,
|
FullHistoricalPerformancePagedResponse, LastSubmission, NetworkMonitorResponse,
|
||||||
NetworkMonitorsPagedResponse, NodeMeasurementsPerKindResponse, NodePerformancePagedResponse,
|
NetworkMonitorsPagedResponse, NodeMeasurementsResponse, NodePerformancePagedResponse,
|
||||||
NodePerformanceResponse, RetiredNetworkMonitorsPagedResponse,
|
NodePerformanceResponse, RetiredNetworkMonitorsPagedResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,14 +35,6 @@ pub enum ExecuteMsg {
|
|||||||
data: Vec<NodePerformance>,
|
data: Vec<NodePerformance>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Measurement kind needs to be defined by the admin before measurements of
|
|
||||||
/// that kind can be submitted.
|
|
||||||
DefineMeasurementKind { measurement_kind: String },
|
|
||||||
|
|
||||||
/// After this action is done, measurements of this kind aren't returned on the API anymore
|
|
||||||
/// New measurements of this kind cannot be submitted
|
|
||||||
RetireMeasurementKind { measurement_kind: String },
|
|
||||||
|
|
||||||
/// Attempt to authorise new network monitor for submitting performance data
|
/// Attempt to authorise new network monitor for submitting performance data
|
||||||
AuthoriseNetworkMonitor { address: String },
|
AuthoriseNetworkMonitor { address: String },
|
||||||
|
|
||||||
@@ -77,16 +69,9 @@ pub enum QueryMsg {
|
|||||||
limit: Option<u32>,
|
limit: Option<u32>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Returns all measurements of a specific kind for the particular node
|
/// Returns all submitted measurements for the particular node
|
||||||
#[cfg_attr(feature = "schema", returns(NodeMeasurementsResponse))]
|
#[cfg_attr(feature = "schema", returns(NodeMeasurementsResponse))]
|
||||||
NodeMeasurements {
|
NodeMeasurements { epoch_id: EpochId, node_id: NodeId },
|
||||||
epoch_id: EpochId,
|
|
||||||
node_id: NodeId,
|
|
||||||
kind: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "schema", returns(NodeMeasurementsResponse))]
|
|
||||||
AllNodeMeasurements { epoch_id: EpochId, node_id: NodeId },
|
|
||||||
|
|
||||||
/// Returns (paged) measurements for particular epoch
|
/// Returns (paged) measurements for particular epoch
|
||||||
#[cfg_attr(feature = "schema", returns(EpochMeasurementsPagedResponse))]
|
#[cfg_attr(feature = "schema", returns(EpochMeasurementsPagedResponse))]
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use cosmwasm_schema::cw_serde;
|
use cosmwasm_schema::cw_serde;
|
||||||
use cosmwasm_std::{Addr, Env, Timestamp};
|
use cosmwasm_std::{Addr, Env, Timestamp};
|
||||||
use nym_contracts_common::Percent;
|
use nym_contracts_common::Percent;
|
||||||
@@ -51,13 +49,11 @@ pub struct RetiredNetworkMonitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
|
#[derive(Copy)]
|
||||||
pub struct NodePerformance {
|
pub struct NodePerformance {
|
||||||
#[serde(rename = "n")]
|
#[serde(rename = "n")]
|
||||||
pub node_id: NodeId,
|
pub node_id: NodeId,
|
||||||
|
|
||||||
#[serde(rename = "m")]
|
|
||||||
pub measurement_kind: MeasurementKind,
|
|
||||||
|
|
||||||
// note: value is rounded to 2 decimal places.
|
// note: value is rounded to 2 decimal places.
|
||||||
#[serde(rename = "p")]
|
#[serde(rename = "p")]
|
||||||
pub performance: Percent,
|
pub performance: Percent,
|
||||||
@@ -101,35 +97,25 @@ impl NodeResults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn inner(&self) -> &[Percent] {
|
pub fn inner(&self) -> &[Percent] {
|
||||||
&self.0.as_slice()
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type MeasurementKind = String;
|
|
||||||
|
|
||||||
/// maps measurement kind to the value of that measurement for a node
|
|
||||||
/// (present only if measured)
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct NodePerformanceResponse {
|
pub struct NodePerformanceResponse {
|
||||||
pub performance: HashMap<MeasurementKind, Percent>,
|
pub performance: Option<Percent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct NodeMeasurementsPerKindResponse {
|
pub struct NodeMeasurementsResponse {
|
||||||
pub measurements: Option<NodeResults>,
|
pub measurements: Option<NodeResults>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct AllNodeMeasurementsResponse {
|
#[derive(Copy)]
|
||||||
// Option is used because if a measurement has been defined, that doesn't
|
|
||||||
// mean the node had actually been measured at the time of the query
|
|
||||||
pub measurements: HashMap<MeasurementKind, Option<NodeResults>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cw_serde]
|
|
||||||
pub struct EpochNodePerformance {
|
pub struct EpochNodePerformance {
|
||||||
pub epoch: EpochId,
|
pub epoch: EpochId,
|
||||||
pub performance: HashMap<MeasurementKind, Percent>,
|
pub performance: Option<Percent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
@@ -147,23 +133,24 @@ pub struct EpochPerformancePagedResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct NodeMeasurements {
|
pub struct NodeMeasurement {
|
||||||
pub node_id: NodeId,
|
pub node_id: NodeId,
|
||||||
pub measurements_per_kind: HashMap<String, NodeResults>,
|
pub measurements: NodeResults,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
pub struct EpochMeasurementsPagedResponse {
|
pub struct EpochMeasurementsPagedResponse {
|
||||||
pub epoch_id: EpochId,
|
pub epoch_id: EpochId,
|
||||||
pub measurements: Vec<NodeMeasurements>,
|
pub measurements: Vec<NodeMeasurement>,
|
||||||
pub start_next_after: Option<NodeId>,
|
pub start_next_after: Option<NodeId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
|
#[derive(Copy)]
|
||||||
pub struct HistoricalPerformance {
|
pub struct HistoricalPerformance {
|
||||||
pub epoch_id: EpochId,
|
pub epoch_id: EpochId,
|
||||||
pub node_id: NodeId,
|
pub node_id: NodeId,
|
||||||
pub performance: HashMap<MeasurementKind, Percent>,
|
pub performance: Percent,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
@@ -200,14 +187,11 @@ pub struct RemoveEpochMeasurementsResponse {
|
|||||||
pub additional_entries_to_remove_remaining: bool,
|
pub additional_entries_to_remove_remaining: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return details about submissions: whether they were accepted, or why they
|
|
||||||
/// were rejected
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct BatchSubmissionResult {
|
pub struct BatchSubmissionResult {
|
||||||
pub accepted_scores: u64,
|
pub accepted_scores: u64,
|
||||||
pub non_existent_nodes: Vec<NodeId>,
|
pub non_existent_nodes: Vec<NodeId>,
|
||||||
pub non_existent_measurement_kind: Vec<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use nym_sdk::mixnet::{MixnetClientSender, Recipient};
|
|||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
// Import these here for all modules to use, to keep the version consistent
|
// Import these here for for all modules to use, to keep the version consistent
|
||||||
pub(crate) use nym_ip_packet_requests::v8 as nym_ip_packet_requests_current;
|
pub(crate) use nym_ip_packet_requests::v8 as nym_ip_packet_requests_current;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
|
|||||||
@@ -2,20 +2,19 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::queries::{
|
use crate::queries::{
|
||||||
query_admin, query_all_node_measurements, query_epoch_measurements_paged,
|
query_admin, query_epoch_measurements_paged, query_epoch_performance_paged,
|
||||||
query_epoch_performance_paged, query_full_historical_performance_paged, query_last_submission,
|
query_full_historical_performance_paged, query_last_submission, query_network_monitor_details,
|
||||||
query_network_monitor_details, query_network_monitors_paged, query_node_measurements_for_kind,
|
query_network_monitors_paged, query_node_measurements, query_node_performance,
|
||||||
query_node_performance, query_node_performance_paged, query_retired_network_monitors_paged,
|
query_node_performance_paged, query_retired_network_monitors_paged,
|
||||||
};
|
};
|
||||||
use crate::storage::NYM_PERFORMANCE_CONTRACT_STORAGE;
|
use crate::storage::NYM_PERFORMANCE_CONTRACT_STORAGE;
|
||||||
use crate::transactions::{
|
use crate::transactions::{
|
||||||
try_authorise_network_monitor, try_batch_submit_performance_results,
|
try_authorise_network_monitor, try_batch_submit_performance_results,
|
||||||
try_define_measurement_kind, try_remove_epoch_measurements, try_remove_node_measurements,
|
try_remove_epoch_measurements, try_remove_node_measurements, try_retire_network_monitor,
|
||||||
try_retire_measurement_kind, try_retire_network_monitor, try_submit_performance_results,
|
try_submit_performance_results, try_update_contract_admin,
|
||||||
try_update_contract_admin,
|
|
||||||
};
|
};
|
||||||
use cosmwasm_std::{
|
use cosmwasm_std::{
|
||||||
Binary, Deps, DepsMut, Env, MessageInfo, Response, entry_point, to_json_binary,
|
entry_point, to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response,
|
||||||
};
|
};
|
||||||
use nym_contracts_common::set_build_information;
|
use nym_contracts_common::set_build_information;
|
||||||
use nym_performance_contract_common::{
|
use nym_performance_contract_common::{
|
||||||
@@ -63,20 +62,12 @@ pub fn execute(
|
|||||||
ExecuteMsg::BatchSubmit { epoch, data } => {
|
ExecuteMsg::BatchSubmit { epoch, data } => {
|
||||||
try_batch_submit_performance_results(deps, env, info, epoch, data)
|
try_batch_submit_performance_results(deps, env, info, epoch, data)
|
||||||
}
|
}
|
||||||
ExecuteMsg::DefineMeasurementKind { measurement_kind } => {
|
|
||||||
try_define_measurement_kind(deps, &info.sender, measurement_kind)
|
|
||||||
}
|
|
||||||
ExecuteMsg::RetireMeasurementKind { measurement_kind } => {
|
|
||||||
try_retire_measurement_kind(deps, &info.sender, measurement_kind)
|
|
||||||
}
|
|
||||||
ExecuteMsg::AuthoriseNetworkMonitor { address } => {
|
ExecuteMsg::AuthoriseNetworkMonitor { address } => {
|
||||||
try_authorise_network_monitor(deps, env, info, address)
|
try_authorise_network_monitor(deps, env, info, address)
|
||||||
}
|
}
|
||||||
ExecuteMsg::RetireNetworkMonitor { address } => {
|
ExecuteMsg::RetireNetworkMonitor { address } => {
|
||||||
try_retire_network_monitor(deps, env, info, address)
|
try_retire_network_monitor(deps, env, info, address)
|
||||||
}
|
}
|
||||||
// TODO dz removing measurement for only a certain node shouldn't be allowed
|
|
||||||
// remove this message and corresponding path
|
|
||||||
ExecuteMsg::RemoveNodeMeasurements { epoch_id, node_id } => {
|
ExecuteMsg::RemoveNodeMeasurements { epoch_id, node_id } => {
|
||||||
try_remove_node_measurements(deps, info, epoch_id, node_id)
|
try_remove_node_measurements(deps, info, epoch_id, node_id)
|
||||||
}
|
}
|
||||||
@@ -125,17 +116,9 @@ pub fn query(deps: Deps, _: Env, msg: QueryMsg) -> Result<Binary, NymPerformance
|
|||||||
QueryMsg::RetiredNetworkMonitorsPaged { start_after, limit } => Ok(to_json_binary(
|
QueryMsg::RetiredNetworkMonitorsPaged { start_after, limit } => Ok(to_json_binary(
|
||||||
&query_retired_network_monitors_paged(deps, start_after, limit)?,
|
&query_retired_network_monitors_paged(deps, start_after, limit)?,
|
||||||
)?),
|
)?),
|
||||||
QueryMsg::NodeMeasurements {
|
QueryMsg::NodeMeasurements { epoch_id, node_id } => Ok(to_json_binary(
|
||||||
epoch_id,
|
&query_node_measurements(deps, epoch_id, node_id)?,
|
||||||
node_id,
|
|
||||||
kind,
|
|
||||||
} => Ok(to_json_binary(&query_node_measurements_for_kind(
|
|
||||||
deps, epoch_id, node_id, kind,
|
|
||||||
)?)?),
|
|
||||||
QueryMsg::AllNodeMeasurements { epoch_id, node_id } => Ok(to_json_binary(
|
|
||||||
&query_all_node_measurements(deps, epoch_id, node_id)?,
|
|
||||||
)?),
|
)?),
|
||||||
|
|
||||||
QueryMsg::EpochMeasurementsPaged {
|
QueryMsg::EpochMeasurementsPaged {
|
||||||
epoch_id,
|
epoch_id,
|
||||||
start_after,
|
start_after,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use cosmwasm_std::{Binary, CustomQuery, QuerierWrapper, StdError, StdResult, from_json};
|
use cosmwasm_std::{from_json, Binary, CustomQuery, QuerierWrapper, StdError, StdResult};
|
||||||
use cw_storage_plus::{Key, Namespace, Path, PrimaryKey};
|
use cw_storage_plus::{Key, Namespace, Path, PrimaryKey};
|
||||||
use nym_mixnet_contract_common::{Interval, NymNodeBond};
|
use nym_mixnet_contract_common::{Interval, NymNodeBond};
|
||||||
use nym_performance_contract_common::{EpochId, NodeId};
|
use nym_performance_contract_common::{EpochId, NodeId};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,35 +3,35 @@
|
|||||||
|
|
||||||
use crate::contract::{execute, instantiate, migrate, query};
|
use crate::contract::{execute, instantiate, migrate, query};
|
||||||
use crate::helpers::MixnetContractQuerier;
|
use crate::helpers::MixnetContractQuerier;
|
||||||
use crate::storage::{MeasurementKind, NYM_PERFORMANCE_CONTRACT_STORAGE};
|
use crate::storage::NYM_PERFORMANCE_CONTRACT_STORAGE;
|
||||||
use cosmwasm_std::testing::{MockApi, message_info, mock_env};
|
use cosmwasm_std::testing::{message_info, mock_env, MockApi};
|
||||||
use cosmwasm_std::{
|
use cosmwasm_std::{
|
||||||
Addr, ContractInfo, Deps, DepsMut, Env, MessageInfo, QuerierWrapper, StdError, StdResult, coin,
|
coin, coins, Addr, ContractInfo, Deps, DepsMut, Env, MessageInfo, QuerierWrapper, StdError,
|
||||||
coins,
|
StdResult,
|
||||||
};
|
};
|
||||||
use mixnet_contract::testable_mixnet_contract::MixnetContract;
|
use mixnet_contract::testable_mixnet_contract::MixnetContract;
|
||||||
use nym_contracts_common::Percent;
|
|
||||||
use nym_contracts_common::signing::{ContractMessageContent, MessageSignature};
|
use nym_contracts_common::signing::{ContractMessageContent, MessageSignature};
|
||||||
|
use nym_contracts_common::Percent;
|
||||||
use nym_contracts_common_testing::{
|
use nym_contracts_common_testing::{
|
||||||
AdminExt, ArbitraryContractStorageReader, ArbitraryContractStorageWriter, BankExt, ChainOpts,
|
addr, AdminExt, ArbitraryContractStorageReader, ArbitraryContractStorageWriter, BankExt,
|
||||||
CommonStorageKeys, ContractFn, ContractOpts, ContractStorageWrapper, ContractTester,
|
ChainOpts, CommonStorageKeys, ContractFn, ContractOpts, ContractStorageWrapper, ContractTester,
|
||||||
ContractTesterBuilder, DenomExt, PermissionedFn, QueryFn, RandExt, TEST_DENOM,
|
ContractTesterBuilder, DenomExt, PermissionedFn, QueryFn, RandExt, TestableNymContract,
|
||||||
TestableNymContract, addr,
|
TEST_DENOM,
|
||||||
};
|
};
|
||||||
use nym_crypto::asymmetric::ed25519;
|
use nym_crypto::asymmetric::ed25519;
|
||||||
use nym_mixnet_contract_common::nym_node::{NodeDetailsResponse, NodeOwnershipResponse, Role};
|
use nym_mixnet_contract_common::nym_node::{NodeDetailsResponse, NodeOwnershipResponse, Role};
|
||||||
use nym_mixnet_contract_common::{
|
use nym_mixnet_contract_common::{
|
||||||
CurrentIntervalResponse, DEFAULT_INTERVAL_OPERATING_COST_AMOUNT, DEFAULT_PROFIT_MARGIN_PERCENT,
|
CurrentIntervalResponse, EpochId, Interval, NodeCostParams, NymNode, NymNodeBondingPayload,
|
||||||
EpochId, Interval, NodeCostParams, NymNode, NymNodeBondingPayload, RoleAssignment,
|
RoleAssignment, SignableNymNodeBondingMsg, DEFAULT_INTERVAL_OPERATING_COST_AMOUNT,
|
||||||
SignableNymNodeBondingMsg,
|
DEFAULT_PROFIT_MARGIN_PERCENT,
|
||||||
};
|
};
|
||||||
use nym_performance_contract_common::constants::storage_keys;
|
use nym_performance_contract_common::constants::storage_keys;
|
||||||
use nym_performance_contract_common::{
|
use nym_performance_contract_common::{
|
||||||
EpochNodePerformance, ExecuteMsg, InstantiateMsg, MigrateMsg, NodeId, NodePerformance,
|
ExecuteMsg, InstantiateMsg, MigrateMsg, NodeId, NodePerformance, NodeResults,
|
||||||
NodeResults, NymPerformanceContractError, QueryMsg,
|
NymPerformanceContractError, QueryMsg,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
use serde::Serialize;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub struct PerformanceContract;
|
pub struct PerformanceContract;
|
||||||
@@ -94,20 +94,6 @@ pub fn init_contract_tester() -> ContractTester<PerformanceContract> {
|
|||||||
.with_common_storage_key(CommonStorageKeys::Admin, storage_keys::CONTRACT_ADMIN)
|
.with_common_storage_key(CommonStorageKeys::Admin, storage_keys::CONTRACT_ADMIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
// shorthand factory to avoid verbosity in tests
|
|
||||||
pub(crate) fn epoch_node_performance_unchecked(
|
|
||||||
epoch: EpochId,
|
|
||||||
measurement_kind: MeasurementKind,
|
|
||||||
performance: &str,
|
|
||||||
) -> EpochNodePerformance {
|
|
||||||
let performance = performance.parse().unwrap();
|
|
||||||
EpochNodePerformance {
|
|
||||||
epoch,
|
|
||||||
performance: [(measurement_kind, performance)].into_iter().collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to be able to test instantiation, but for that we require
|
// we need to be able to test instantiation, but for that we require
|
||||||
// deps in a state that already includes instantiated mixnet contract
|
// deps in a state that already includes instantiated mixnet contract
|
||||||
pub(crate) struct PreInitContract {
|
pub(crate) struct PreInitContract {
|
||||||
@@ -372,33 +358,11 @@ pub(crate) trait PerformanceContractTesterExt:
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dummy_measurement_kind(&mut self) -> MeasurementKind {
|
|
||||||
String::from("dummy")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn define_dummy_measurement_kind(
|
|
||||||
&mut self,
|
|
||||||
) -> Result<MeasurementKind, NymPerformanceContractError> {
|
|
||||||
let admin = self.admin_unchecked();
|
|
||||||
let measurement_kind = self.dummy_measurement_kind();
|
|
||||||
|
|
||||||
self.execute_raw(
|
|
||||||
admin,
|
|
||||||
ExecuteMsg::DefineMeasurementKind {
|
|
||||||
measurement_kind: measurement_kind.clone(),
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(measurement_kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dummy_node_performance(&mut self) -> NodePerformance {
|
fn dummy_node_performance(&mut self) -> NodePerformance {
|
||||||
let node_id = self.bond_dummy_nymnode().unwrap();
|
let node_id = self.bond_dummy_nymnode().unwrap();
|
||||||
let measurement_kind = self.dummy_measurement_kind();
|
|
||||||
NodePerformance {
|
NodePerformance {
|
||||||
node_id,
|
node_id,
|
||||||
performance: Percent::from_percentage_value(69).unwrap(),
|
performance: Percent::from_percentage_value(69).unwrap(),
|
||||||
measurement_kind,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,7 +382,6 @@ pub(crate) trait PerformanceContractTesterExt:
|
|||||||
addr: &Addr,
|
addr: &Addr,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
measurement_kind: MeasurementKind,
|
|
||||||
performance: Percent,
|
performance: Percent,
|
||||||
) -> Result<(), NymPerformanceContractError> {
|
) -> Result<(), NymPerformanceContractError> {
|
||||||
let env = self.env();
|
let env = self.env();
|
||||||
@@ -430,7 +393,6 @@ pub(crate) trait PerformanceContractTesterExt:
|
|||||||
NodePerformance {
|
NodePerformance {
|
||||||
node_id,
|
node_id,
|
||||||
performance,
|
performance,
|
||||||
measurement_kind,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -439,12 +401,11 @@ pub(crate) trait PerformanceContractTesterExt:
|
|||||||
&mut self,
|
&mut self,
|
||||||
addr: &Addr,
|
addr: &Addr,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
measurement_kind: MeasurementKind,
|
|
||||||
performance: Percent,
|
performance: Percent,
|
||||||
) -> Result<(), NymPerformanceContractError> {
|
) -> Result<(), NymPerformanceContractError> {
|
||||||
let epoch_id = self.current_mixnet_epoch()?;
|
let epoch_id = self.current_mixnet_epoch()?;
|
||||||
|
|
||||||
self.insert_epoch_performance(addr, epoch_id, node_id, measurement_kind, performance)
|
self.insert_epoch_performance(addr, epoch_id, node_id, performance)
|
||||||
}
|
}
|
||||||
|
|
||||||
// makes testing easier
|
// makes testing easier
|
||||||
@@ -452,13 +413,11 @@ pub(crate) trait PerformanceContractTesterExt:
|
|||||||
&mut self,
|
&mut self,
|
||||||
addr: &Addr,
|
addr: &Addr,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
measurement_kind: MeasurementKind,
|
|
||||||
raw: &str,
|
raw: &str,
|
||||||
) -> Result<(), NymPerformanceContractError> {
|
) -> Result<(), NymPerformanceContractError> {
|
||||||
self.insert_performance(
|
self.insert_performance(
|
||||||
addr,
|
addr,
|
||||||
node_id,
|
node_id,
|
||||||
measurement_kind,
|
|
||||||
Percent::from_str(raw).map_err(|err| {
|
Percent::from_str(raw).map_err(|err| {
|
||||||
NymPerformanceContractError::StdErr(StdError::parse_err("Percent", err.to_string()))
|
NymPerformanceContractError::StdErr(StdError::parse_err("Percent", err.to_string()))
|
||||||
})?,
|
})?,
|
||||||
@@ -469,12 +428,11 @@ pub(crate) trait PerformanceContractTesterExt:
|
|||||||
&self,
|
&self,
|
||||||
epoch_id: EpochId,
|
epoch_id: EpochId,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
measurement_kind: MeasurementKind,
|
|
||||||
) -> Result<NodeResults, NymPerformanceContractError> {
|
) -> Result<NodeResults, NymPerformanceContractError> {
|
||||||
let scores = NYM_PERFORMANCE_CONTRACT_STORAGE
|
let scores = NYM_PERFORMANCE_CONTRACT_STORAGE
|
||||||
.performance_results
|
.performance_results
|
||||||
.results
|
.results
|
||||||
.load(self.deps().storage, (epoch_id, node_id, measurement_kind))?;
|
.load(self.deps().storage, (epoch_id, node_id))?;
|
||||||
Ok(scores)
|
Ok(scores)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::storage::{MeasurementKind, NYM_PERFORMANCE_CONTRACT_STORAGE};
|
use crate::storage::NYM_PERFORMANCE_CONTRACT_STORAGE;
|
||||||
use cosmwasm_std::{Addr, DepsMut, Env, Event, MessageInfo, Response, to_json_binary};
|
use cosmwasm_std::{to_json_binary, DepsMut, Env, Event, MessageInfo, Response};
|
||||||
use nym_performance_contract_common::{
|
use nym_performance_contract_common::{
|
||||||
EpochId, NodeId, NodePerformance, NymPerformanceContractError,
|
EpochId, NodeId, NodePerformance, NymPerformanceContractError,
|
||||||
};
|
};
|
||||||
@@ -21,62 +21,6 @@ pub fn try_update_contract_admin(
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_define_measurement_kind(
|
|
||||||
deps: DepsMut<'_>,
|
|
||||||
sender: &Addr,
|
|
||||||
measurement_kind: MeasurementKind,
|
|
||||||
) -> Result<Response, NymPerformanceContractError> {
|
|
||||||
NYM_PERFORMANCE_CONTRACT_STORAGE
|
|
||||||
.contract_admin
|
|
||||||
.assert_admin(deps.as_ref(), sender)?;
|
|
||||||
|
|
||||||
validate_measurement_kind(&measurement_kind)?;
|
|
||||||
|
|
||||||
NYM_PERFORMANCE_CONTRACT_STORAGE
|
|
||||||
.performance_results
|
|
||||||
.define_new_measurement_kind(deps.storage, measurement_kind)?;
|
|
||||||
|
|
||||||
Ok(Response::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// error out if validation fails, Ok otherwise
|
|
||||||
fn validate_measurement_kind(measurement_kind: &str) -> Result<(), NymPerformanceContractError> {
|
|
||||||
const MIN_LENGTH: usize = 2;
|
|
||||||
const MAX_LENGTH: usize = 32;
|
|
||||||
let error = if measurement_kind.len() < MIN_LENGTH || measurement_kind.len() > MAX_LENGTH {
|
|
||||||
format!(
|
|
||||||
"Length should be between {} and {} chars (exclusive)",
|
|
||||||
MIN_LENGTH, MAX_LENGTH
|
|
||||||
)
|
|
||||||
} else if !measurement_kind.is_ascii() {
|
|
||||||
"Only ASCII symbols allowed".to_string()
|
|
||||||
} else if measurement_kind.contains(char::is_whitespace) {
|
|
||||||
"No whitespaces allowed in measurement name".to_string()
|
|
||||||
} else if !measurement_kind.starts_with(char::is_alphanumeric) {
|
|
||||||
"Name needs to start with alphanumeric character(s)".to_string()
|
|
||||||
} else {
|
|
||||||
return Ok(());
|
|
||||||
};
|
|
||||||
|
|
||||||
Err(NymPerformanceContractError::InvalidInput(error))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn try_retire_measurement_kind(
|
|
||||||
deps: DepsMut<'_>,
|
|
||||||
sender_addr: &Addr,
|
|
||||||
measurement_kind: MeasurementKind,
|
|
||||||
) -> Result<Response, NymPerformanceContractError> {
|
|
||||||
NYM_PERFORMANCE_CONTRACT_STORAGE
|
|
||||||
.contract_admin
|
|
||||||
.assert_admin(deps.as_ref(), sender_addr)?;
|
|
||||||
|
|
||||||
NYM_PERFORMANCE_CONTRACT_STORAGE
|
|
||||||
.performance_results
|
|
||||||
.retire_measurement_kind(deps.storage, measurement_kind)?;
|
|
||||||
|
|
||||||
Ok(Response::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn try_submit_performance_results(
|
pub fn try_submit_performance_results(
|
||||||
deps: DepsMut<'_>,
|
deps: DepsMut<'_>,
|
||||||
env: Env,
|
env: Env,
|
||||||
@@ -117,10 +61,6 @@ pub fn try_batch_submit_performance_results(
|
|||||||
.add_attribute(
|
.add_attribute(
|
||||||
"non_existent_nodes",
|
"non_existent_nodes",
|
||||||
format!("{:?}", res.non_existent_nodes),
|
format!("{:?}", res.non_existent_nodes),
|
||||||
)
|
|
||||||
.add_attribute(
|
|
||||||
"non_existent_measurement_kinds",
|
|
||||||
format!("{:?}", res.non_existent_measurement_kind),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
Ok(response)
|
Ok(response)
|
||||||
@@ -190,7 +130,7 @@ pub fn try_remove_epoch_measurements(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::storage::retrieval_limits;
|
use crate::storage::retrieval_limits;
|
||||||
use crate::testing::{PerformanceContractTesterExt, init_contract_tester};
|
use crate::testing::{init_contract_tester, PerformanceContractTesterExt};
|
||||||
use cosmwasm_std::from_json;
|
use cosmwasm_std::from_json;
|
||||||
use nym_contracts_common_testing::{AdminExt, ContractOpts};
|
use nym_contracts_common_testing::{AdminExt, ContractOpts};
|
||||||
use nym_performance_contract_common::RemoveEpochMeasurementsResponse;
|
use nym_performance_contract_common::RemoveEpochMeasurementsResponse;
|
||||||
@@ -282,24 +222,20 @@ mod tests {
|
|||||||
let env = test.env();
|
let env = test.env();
|
||||||
let admin = test.admin_msg();
|
let admin = test.admin_msg();
|
||||||
|
|
||||||
assert!(
|
assert!(try_authorise_network_monitor(
|
||||||
try_authorise_network_monitor(
|
test.deps_mut(),
|
||||||
test.deps_mut(),
|
env.clone(),
|
||||||
env.clone(),
|
admin.clone(),
|
||||||
admin.clone(),
|
bad_address
|
||||||
bad_address
|
)
|
||||||
)
|
.is_err());
|
||||||
.is_err()
|
assert!(try_authorise_network_monitor(
|
||||||
);
|
test.deps_mut(),
|
||||||
assert!(
|
env,
|
||||||
try_authorise_network_monitor(
|
admin,
|
||||||
test.deps_mut(),
|
good_address.to_string()
|
||||||
env,
|
)
|
||||||
admin,
|
.is_ok());
|
||||||
good_address.to_string()
|
|
||||||
)
|
|
||||||
.is_ok()
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -308,7 +244,7 @@ mod tests {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod retiring_network_monitor {
|
mod retiring_network_monitor {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::testing::{PerformanceContractTesterExt, init_contract_tester};
|
use crate::testing::{init_contract_tester, PerformanceContractTesterExt};
|
||||||
use nym_contracts_common_testing::{AdminExt, ContractOpts, RandExt};
|
use nym_contracts_common_testing::{AdminExt, ContractOpts, RandExt};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -322,19 +258,20 @@ mod tests {
|
|||||||
let env = test.env();
|
let env = test.env();
|
||||||
let admin = test.admin_msg();
|
let admin = test.admin_msg();
|
||||||
|
|
||||||
assert!(
|
assert!(try_retire_network_monitor(
|
||||||
try_retire_network_monitor(
|
test.deps_mut(),
|
||||||
test.deps_mut(),
|
env.clone(),
|
||||||
env.clone(),
|
admin.clone(),
|
||||||
admin.clone(),
|
bad_address
|
||||||
bad_address
|
)
|
||||||
)
|
.is_err());
|
||||||
.is_err()
|
assert!(try_retire_network_monitor(
|
||||||
);
|
test.deps_mut(),
|
||||||
assert!(
|
env,
|
||||||
try_retire_network_monitor(test.deps_mut(), env, admin, good_address.to_string())
|
admin,
|
||||||
.is_ok()
|
good_address.to_string()
|
||||||
);
|
)
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -348,14 +285,11 @@ mod tests {
|
|||||||
|
|
||||||
let nm = tester.addr_make("network-monitor");
|
let nm = tester.addr_make("network-monitor");
|
||||||
tester.authorise_network_monitor(&nm)?;
|
tester.authorise_network_monitor(&nm)?;
|
||||||
tester.define_dummy_measurement_kind()?;
|
|
||||||
|
|
||||||
tester.advance_mixnet_epoch()?;
|
tester.advance_mixnet_epoch()?;
|
||||||
|
|
||||||
let measurement_kind = tester.dummy_measurement_kind();
|
|
||||||
for _ in 0..2 * retrieval_limits::EPOCH_PERFORMANCE_PURGE_LIMIT {
|
for _ in 0..2 * retrieval_limits::EPOCH_PERFORMANCE_PURGE_LIMIT {
|
||||||
let node_id = tester.bond_dummy_nymnode()?;
|
let node_id = tester.bond_dummy_nymnode()?;
|
||||||
tester.insert_raw_performance(&nm, node_id, measurement_kind.clone(), "0.42")?;
|
tester.insert_raw_performance(&nm, node_id, "0.42")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let admin = tester.admin_msg();
|
let admin = tester.admin_msg();
|
||||||
@@ -377,242 +311,4 @@ mod tests {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
mod measurement_kind_authorization {
|
|
||||||
use cosmwasm_std::testing::message_info;
|
|
||||||
use nym_contracts_common_testing::{AdminExt, ContractOpts};
|
|
||||||
use nym_performance_contract_common::NymPerformanceContractError;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
storage::MeasurementKind,
|
|
||||||
testing::{PerformanceContractTesterExt, init_contract_tester},
|
|
||||||
transactions::{
|
|
||||||
try_define_measurement_kind, try_retire_measurement_kind,
|
|
||||||
try_submit_performance_results,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
#[test]
|
|
||||||
fn add_requires_admin() {
|
|
||||||
let mut tester = init_contract_tester();
|
|
||||||
let admin = tester.admin_msg();
|
|
||||||
let new_measurement = MeasurementKind::from("new-measurement");
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
try_define_measurement_kind(
|
|
||||||
tester.deps_mut(),
|
|
||||||
&admin.sender,
|
|
||||||
new_measurement.clone()
|
|
||||||
)
|
|
||||||
.is_ok()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
#[test]
|
|
||||||
fn retire_requires_admin() {
|
|
||||||
let mut tester = init_contract_tester();
|
|
||||||
let admin = tester.admin_msg();
|
|
||||||
let new_measurement = MeasurementKind::from("new-measurement");
|
|
||||||
|
|
||||||
try_define_measurement_kind(tester.deps_mut(), &admin.sender, new_measurement.clone())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let unauthorized_addr = tester.addr_make("unauthorized-addr");
|
|
||||||
let unauthorized = try_retire_measurement_kind(
|
|
||||||
tester.deps_mut(),
|
|
||||||
&unauthorized_addr,
|
|
||||||
new_measurement.clone(),
|
|
||||||
);
|
|
||||||
assert!(matches!(
|
|
||||||
unauthorized,
|
|
||||||
Err(NymPerformanceContractError::Admin { .. })
|
|
||||||
));
|
|
||||||
|
|
||||||
let authorized = try_retire_measurement_kind(
|
|
||||||
tester.deps_mut(),
|
|
||||||
&admin.sender,
|
|
||||||
new_measurement.clone(),
|
|
||||||
);
|
|
||||||
assert!(authorized.is_ok());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
#[test]
|
|
||||||
fn cannot_add_existing() {
|
|
||||||
let mut tester = init_contract_tester();
|
|
||||||
let admin = tester.admin_msg();
|
|
||||||
let new_measurement = MeasurementKind::from("new-measurement");
|
|
||||||
|
|
||||||
let first_attempt = try_define_measurement_kind(
|
|
||||||
tester.deps_mut(),
|
|
||||||
&admin.sender,
|
|
||||||
new_measurement.clone(),
|
|
||||||
);
|
|
||||||
assert!(first_attempt.is_ok());
|
|
||||||
|
|
||||||
let second_attempt =
|
|
||||||
try_define_measurement_kind(tester.deps_mut(), &admin.sender, new_measurement);
|
|
||||||
assert!(matches!(
|
|
||||||
second_attempt,
|
|
||||||
Err(NymPerformanceContractError::MeasurementAlreadyDefined { .. })
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
#[test]
|
|
||||||
fn cannot_retire_nonexistent() {
|
|
||||||
let mut tester = init_contract_tester();
|
|
||||||
let admin = tester.admin_msg();
|
|
||||||
let nonexistent = MeasurementKind::from("nonexistent");
|
|
||||||
|
|
||||||
let err = try_retire_measurement_kind(tester.deps_mut(), &admin.sender, nonexistent);
|
|
||||||
|
|
||||||
assert!(matches!(
|
|
||||||
err,
|
|
||||||
Err(NymPerformanceContractError::UnsupportedMeasurementKind { .. })
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
#[test]
|
|
||||||
fn cannot_submit_undefined() {
|
|
||||||
let mut tester = init_contract_tester();
|
|
||||||
let env = tester.env();
|
|
||||||
let admin = tester.admin_msg();
|
|
||||||
let dummy_perf = tester.dummy_node_performance();
|
|
||||||
let nm = tester.addr_make("network-monitor");
|
|
||||||
tester.authorise_network_monitor(&nm).unwrap();
|
|
||||||
|
|
||||||
let dummy_measurement = dummy_perf.measurement_kind.clone();
|
|
||||||
|
|
||||||
let first_attempt = try_submit_performance_results(
|
|
||||||
tester.deps_mut(),
|
|
||||||
env.clone(),
|
|
||||||
// network monitor submits
|
|
||||||
message_info(&nm, &[]),
|
|
||||||
0,
|
|
||||||
dummy_perf.clone(),
|
|
||||||
);
|
|
||||||
assert!(matches!(
|
|
||||||
first_attempt,
|
|
||||||
Err(NymPerformanceContractError::UnsupportedMeasurementKind { .. })
|
|
||||||
));
|
|
||||||
|
|
||||||
try_define_measurement_kind(
|
|
||||||
tester.deps_mut(),
|
|
||||||
// admin defines
|
|
||||||
&admin.sender,
|
|
||||||
dummy_measurement.clone(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let second_attempt = try_submit_performance_results(
|
|
||||||
tester.deps_mut(),
|
|
||||||
env,
|
|
||||||
// network monitor submits
|
|
||||||
message_info(&nm, &[]),
|
|
||||||
0,
|
|
||||||
dummy_perf,
|
|
||||||
);
|
|
||||||
assert!(second_attempt.is_ok());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
#[test]
|
|
||||||
fn cannot_submit_retired() {
|
|
||||||
let mut tester = init_contract_tester();
|
|
||||||
let env = tester.env();
|
|
||||||
let admin = tester.admin_msg();
|
|
||||||
let dummy_perf = tester.dummy_node_performance();
|
|
||||||
let nm = tester.addr_make("network-monitor");
|
|
||||||
tester.authorise_network_monitor(&nm).unwrap();
|
|
||||||
|
|
||||||
let dummy_measurement = dummy_perf.measurement_kind.clone();
|
|
||||||
|
|
||||||
try_define_measurement_kind(
|
|
||||||
tester.deps_mut(),
|
|
||||||
// admin defines
|
|
||||||
&admin.sender,
|
|
||||||
dummy_measurement.clone(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let defined_ok = try_submit_performance_results(
|
|
||||||
tester.deps_mut(),
|
|
||||||
env.clone(),
|
|
||||||
// network monitor submits
|
|
||||||
message_info(&nm, &[]),
|
|
||||||
0,
|
|
||||||
dummy_perf.clone(),
|
|
||||||
);
|
|
||||||
assert!(defined_ok.is_ok());
|
|
||||||
|
|
||||||
// can't submit for the same node in the same epoch again
|
|
||||||
tester.advance_mixnet_epoch().unwrap();
|
|
||||||
|
|
||||||
try_retire_measurement_kind(
|
|
||||||
tester.deps_mut(),
|
|
||||||
// admin defines
|
|
||||||
&admin.sender,
|
|
||||||
dummy_measurement.clone(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let retired_err = try_submit_performance_results(
|
|
||||||
tester.deps_mut(),
|
|
||||||
env,
|
|
||||||
// network monitor submits
|
|
||||||
message_info(&nm, &[]),
|
|
||||||
1,
|
|
||||||
dummy_perf,
|
|
||||||
);
|
|
||||||
println!("{:#?}", retired_err);
|
|
||||||
assert!(matches!(
|
|
||||||
retired_err,
|
|
||||||
Err(NymPerformanceContractError::UnsupportedMeasurementKind { .. })
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod measurement_kind_validation {
|
|
||||||
use nym_performance_contract_common::NymPerformanceContractError;
|
|
||||||
|
|
||||||
use crate::transactions::validate_measurement_kind;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn invalid_names() {
|
|
||||||
let invalid_names = [
|
|
||||||
"a",
|
|
||||||
"NameLongerThanTheUpperLimitForContract",
|
|
||||||
"contains spaces",
|
|
||||||
"nonaščii",
|
|
||||||
"-+*/",
|
|
||||||
// starts with a symbol
|
|
||||||
"+-*/invalid",
|
|
||||||
];
|
|
||||||
|
|
||||||
for kind in invalid_names {
|
|
||||||
let err = validate_measurement_kind(kind);
|
|
||||||
assert!(matches!(
|
|
||||||
err,
|
|
||||||
Err(NymPerformanceContractError::InvalidInput(..))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn valid_names() {
|
|
||||||
let valid_names = [
|
|
||||||
"ascii-symbols",
|
|
||||||
"UpperLowerCase",
|
|
||||||
// starts with an alphanumeric char
|
|
||||||
"valid-+*/",
|
|
||||||
];
|
|
||||||
|
|
||||||
for kind in valid_names {
|
|
||||||
let err = validate_measurement_kind(kind);
|
|
||||||
assert!(matches!(err, Ok(())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
[RDP](https://rdp.sh),"Netherlands, USA, Poland","Yes, on by default",Yes,"German provider. Exit nodes are allowed, policy is here https://rdp.sh/docs/faq/tor ports 25,465,587 must be closed. Make sure you open a ticket before running an exit node.",07/2024
|
[RDP](https://rdp.sh),"Netherlands, USA, Poland","Yes, on by default",Yes,"German provider. Exit nodes are allowed, policy is here https://rdp.sh/docs/faq/tor ports 25,465,587 must be closed. Make sure you open a ticket before running an exit node.",07/2024
|
||||||
[Lowendbox](https://lowendbox.com/category/dedicated-servers), , , ,Just an aggregator with good offers,07/2025
|
[Lowendbox](https://lowendbox.com/category/dedicated-servers), , , ,Just an aggregator with good offers,07/2025
|
||||||
[Thundervm](https://thundervm.com/en/hosting/dedicated-server),"USA, UK, France, Italy, Switzerland, Netherlands",,Yes, ,07/2025
|
[Thundervm](https://thundervm.com/en/hosting/dedicated-server),"USA, UK, France, Italy, Switzerland, Netherlands",,Yes, ,07/2025
|
||||||
[OVH](https://us.ovhcloud.com/bare-metal/rise/rise-3/),"USA, DE, FR, UK, PL, CA", ,No,"Exit nodes not allowed on VPS offering, see their [Service Specific Terms](https://us.ovhcloud.com/legal/service-specific-terms/). Not all locations always available",09/2025
|
[OVH](https://us.ovhcloud.com/bare-metal/rise/rise-3/),"USA, DE, FR, UK, PL, CA", ,No,Not all locations always available,07/2025
|
||||||
[Mebilcom](https://www.melbicom.net/dedicatedserver/),"NL, US, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL",,No,,07/2025
|
[Mebilcom](https://www.melbicom.net/dedicatedserver/),"NL, USA, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL",,No,,07/2025
|
||||||
[Servermania](https://www.servermania.com/dedicated-servers-hosting.htm),"USA, Canada",,No,,07/2025
|
[Servermania](https://www.servermania.com/dedicated-servers-hosting.htm),"USA, Canada",,No,,07/2025
|
||||||
[Oneprovider](https://oneprovider.com/en/dedicated-servers/ipv6),"PL, FR, NL, UA, USA, BG, RO, DK, ESP, NO, CZ, RS, IE, IT, UK, HU, CH, SK, AT, BE, BA, HK, JP, SG, LU, AU, SWE, UAE, BR, CR, MX, GR, CL, MA, AR",Yes,No,,07/2025
|
[Oneprovider](https://oneprovider.com/en/dedicated-servers/ipv6),"PL, FR, NL, UA, USA, BG, RO, DK, ESP, NO, CZ, RS, IE, IT, UK, HU, CH, SK, AT, BE, BA, HK, JP, SG, LU, AU, SWE, UAE, BR, CR, MX, GR, CL, MA, AR",Yes,No,,07/2025
|
||||||
[Ionos](https://www.ionos.com/servers/amd-servers),"USA, DE, UK, ESP, FR",,No,,07/2025
|
[Ionos](https://www.ionos.com/servers/amd-servers),"USA, DE, UK, ESP, FR",,No,,07/2025
|
||||||
|
|||||||
|
-10
@@ -332,13 +332,3 @@ wscat -c wss://<HOSTNAME>:<WSS_PORT>
|
|||||||
```
|
```
|
||||||
|
|
||||||
- Check Swagger API of your node using the hostname: `https://<HOSTNAME>/api/v1/swagger/#/`
|
- Check Swagger API of your node using the hostname: `https://<HOSTNAME>/api/v1/swagger/#/`
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
In some cases Nginx may cache expired certificates, old configurations and other snippets creating confussion in a proper routing of your server. To purge this cache you can run:
|
|
||||||
```sh
|
|
||||||
apt purge nginx nginx-common
|
|
||||||
apt install nginx
|
|
||||||
service nginx reload && service nginx restart
|
|
||||||
```
|
|
||||||
This will pickup only the current configuration.
|
|
||||||
@@ -803,44 +803,3 @@ ssh root@<IPv4> -i ~/.ssh/your_ssh_key
|
|||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
Now your VM is almost ready for `nym-node` [setup](../../nym-node/setup). Before you proceed, ssh in and [configure all prerequisities](../vps-setup#vps-configuration) needed for `nym-node` installation and operation.
|
Now your VM is almost ready for `nym-node` [setup](../../nym-node/setup). Before you proceed, ssh in and [configure all prerequisities](../vps-setup#vps-configuration) needed for `nym-node` installation and operation.
|
||||||
|
|
||||||
## Removing Virtual Machines
|
|
||||||
|
|
||||||
If you setup your VM in a wrong way, or you simply don't use it anymore, you can remove it.
|
|
||||||
|
|
||||||
<Callout type="warning" emoji="⚠️">
|
|
||||||
**These commands will erase everything on the VM, make sure to backup everything you may need in the future bewfore executing this!**
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
<Steps>
|
|
||||||
###### 1. SSH to the host server
|
|
||||||
|
|
||||||
###### 2. List all VMs
|
|
||||||
```sh
|
|
||||||
virsh list --all
|
|
||||||
```
|
|
||||||
|
|
||||||
###### 3. Shut down and remove VM
|
|
||||||
- To remove a VM run this sequence
|
|
||||||
```sh
|
|
||||||
# shutdown
|
|
||||||
virsh shutdown <VM_NAME>
|
|
||||||
sleep 10
|
|
||||||
|
|
||||||
# destroy
|
|
||||||
virsh destroy <VM_NAME>
|
|
||||||
|
|
||||||
# undefine and purge storage
|
|
||||||
virsh undefine <VM_NAME> --remove-all-storage
|
|
||||||
|
|
||||||
# ensure the storage is deleted
|
|
||||||
rm /var/lib/libvirt/images/<VM_NAME>.img
|
|
||||||
```
|
|
||||||
|
|
||||||
###### 4. List all VMs again
|
|
||||||
|
|
||||||
- The list should not contain the VM that you just deleted:
|
|
||||||
```sh
|
|
||||||
virsh list --all
|
|
||||||
```
|
|
||||||
</ Steps>
|
|
||||||
@@ -80,6 +80,7 @@ impl AuthenticatorClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn send_request(&self, message: &ClientMessage) -> Result<u64> {
|
async fn send_request(&self, message: &ClientMessage) -> Result<u64> {
|
||||||
|
debug!("Request that will be sent : {:#?}", message);
|
||||||
let serialised = message.bytes(self.our_nym_address)?;
|
let serialised = message.bytes(self.our_nym_address)?;
|
||||||
let data = serialised.bytes;
|
let data = serialised.bytes;
|
||||||
let request_id = serialised.request_id;
|
let request_id = serialised.request_id;
|
||||||
@@ -97,6 +98,7 @@ impl AuthenticatorClient {
|
|||||||
IncludedSurbs::ExposeSelfAddress
|
IncludedSurbs::ExposeSelfAddress
|
||||||
};
|
};
|
||||||
let input_message = helpers::create_input_message(self.auth_recipient, data, surbs);
|
let input_message = helpers::create_input_message(self.auth_recipient, data, surbs);
|
||||||
|
debug!("Message that will be sent : {:#?}", input_message);
|
||||||
|
|
||||||
self.mixnet_sender
|
self.mixnet_sender
|
||||||
.send(input_message)
|
.send(input_message)
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ use crate::daemon::Daemon;
|
|||||||
use crate::error::NymvisorError;
|
use crate::error::NymvisorError;
|
||||||
use crate::upgrades::download::download_upgrade_binary;
|
use crate::upgrades::download::download_upgrade_binary;
|
||||||
use crate::upgrades::types::{CurrentVersionInfo, UpgradeHistory, UpgradePlan};
|
use crate::upgrades::types::{CurrentVersionInfo, UpgradeHistory, UpgradePlan};
|
||||||
use nix::fcntl::{Flock, FlockArg};
|
use nix::fcntl::{FlockArg, flock};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
use std::os::fd::AsRawFd;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
@@ -57,15 +58,15 @@ pub(crate) async fn perform_upgrade(config: &Config) -> Result<UpgradeResult, Ny
|
|||||||
path: lock_path.clone(),
|
path: lock_path.clone(),
|
||||||
source,
|
source,
|
||||||
})?;
|
})?;
|
||||||
|
let lock_fd = lock_file.as_raw_fd();
|
||||||
|
|
||||||
debug!("attempting to acquire the lock");
|
debug!("attempting to acquire the lock");
|
||||||
let _locked_file =
|
if let Err(err) = flock(lock_fd, FlockArg::LockExclusiveNonblock) {
|
||||||
Flock::lock(lock_file, FlockArg::LockExclusiveNonblock).map_err(|(_lock_file, err)| {
|
return Err(NymvisorError::UnableToAcquireUpgradePlanLock {
|
||||||
NymvisorError::UnableToAcquireUpgradePlanLock {
|
lock_path,
|
||||||
lock_path: lock_path.clone(),
|
libc_code: err,
|
||||||
libc_code: err,
|
});
|
||||||
}
|
}
|
||||||
})?;
|
|
||||||
|
|
||||||
let upgrade_binary_path = config.upgrade_binary(&upgrade_name);
|
let upgrade_binary_path = config.upgrade_binary(&upgrade_name);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user