Compare commits

...

27 Commits

Author SHA1 Message Date
Jon Häggblad b7f445a330 Delete wireguard feature flag altogether 2023-11-17 09:41:02 +01:00
Jon Häggblad 360c7fda57 Update ci-build 2023-11-17 09:37:21 +01:00
Jon Häggblad 2cbb2d8327 gateway: enable wireguard at runtime 2023-11-17 09:35:23 +01:00
Jon Häggblad 808e3f0562 Merge pull request #4154 from nymtech/jon/clippy
Fix clippy for latest rustc
2023-11-17 09:19:02 +01:00
Jon Häggblad f0dade3c5b Fix clippy in ephemera 2023-11-17 09:15:42 +01:00
Jon Häggblad 0a3c2b3cca Upgrade to safer-ffi 0.1.4 for clippy 2023-11-17 09:06:12 +01:00
Jon Häggblad ac66906980 IPR: add exit policy (#4127)
* Copy over request_filter

* Comment out stuff we don't need

* Delete unused allowed_hosts

* Delete unused code in request_filter

* Setup request filter

* Handle address checks

* rustfmt

* Tweak errors

* clippy

* allow dead code for non-linux

* inline log_msg

* Add ParsedPacket type
2023-11-16 14:13:13 +01:00
Gala afd9f823d8 Merge pull request #4151 from nymtech/feat/explorer-vpnsite-buttom
Feat/explorer vpnsite buttom
2023-11-16 13:08:06 +01:00
serinko d818448848 DOC: hotfix 2023-11-16 12:07:20 +00:00
Gala a9a1ba2847 please lint.. 2023-11-16 12:50:10 +01:00
Drazen Urch 2708c0ce10 Feature/deb package (#4153)
* Add debian scaffolding, allow specifying home_dir in env

* Run as nym user
2023-11-16 12:35:02 +01:00
Gala bb3e9b3d4e remove non used variable 2023-11-16 12:33:43 +01:00
Gala e624f42ad5 fixing build 2023-11-16 12:03:23 +01:00
mx 7da83397dd Merge pull request #4152 from nymtech/feature/docs/sort-info
DOCs: Operators - create tables to clarify Smoosh progress
2023-11-16 10:18:00 +00:00
serinko 26d0b4b159 create tables to clarify Smoosh progress 2023-11-16 11:12:40 +01:00
mx b74490dc50 Merge pull request #4150 from nymtech/feature/ts-sdk-fixes
adding SURBs info to mixfetch
2023-11-15 17:19:59 +00:00
Jędrzej Stuczyński 8113095ff5 remove needless borrow (#4149) 2023-11-15 16:34:32 +01:00
Gala 8339d6ab49 nymvpn link on footer 2023-11-15 16:20:14 +01:00
Gala f037b2ae68 adding nymvpn link to explorer 2023-11-15 15:58:31 +01:00
Zane Schepke 2a4c1d96a4 Update README.md 2023-11-15 09:37:21 -05:00
Lorexia ed04ddf1c4 adding SURBs info to mixfetch 2023-11-15 15:35:10 +01:00
Zane Schepke 34b5d66df6 Update README.md 2023-11-15 09:35:04 -05:00
Tommy Verrall 0a1a5c25f7 Merge pull request #4148 from nymtech/chore/add-update-cost-params
Add update cost params to the NYM-CLI
2023-11-15 13:58:07 +00:00
Jędrzej Stuczyński 6bdba7046f Bugfix/prerelease versionbump (#4145)
* prerelease updating rc suffix

* added post-run summary

* updated error message
2023-11-15 13:58:21 +01:00
Tommy Verrall 428d91a536 fmt 2023-11-15 12:37:01 +00:00
Tommy Verrall 88e0eaafcb update args to pass through correctly 2023-11-15 12:32:23 +00:00
Tommy Verrall dd19cabf15 adding the cost parameter update to the nym-cli 2023-11-15 12:30:02 +00:00
28 changed files with 595 additions and 114 deletions
+6 -7
View File
@@ -75,29 +75,28 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
# Enable wireguard by default on linux only
args: --workspace --features wireguard
args: --workspace
- name: Build all examples
if: matrix.os == 'custom-linux'
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --examples --features wireguard
args: --workspace --examples
- name: Run all tests
if: matrix.os == 'custom-linux'
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --features wireguard
args: --workspace
- name: Run expensive tests
if: (github.ref == 'refs/heads/develop' || github.event.pull_request.base.ref == 'develop' || github.event.pull_request.base.ref == 'master') && matrix.os == 'custom-linux'
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --features wireguard -- --ignored
args: --workspace -- --ignored
- name: Annotate with clippy checks
if: matrix.os == 'custom-linux'
@@ -105,10 +104,10 @@ jobs:
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --workspace --features wireguard
args: --workspace
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --workspace --all-targets --features wireguard -- -D warnings
args: --workspace --all-targets -- -D warnings
Generated
+7 -4
View File
@@ -6667,12 +6667,15 @@ dependencies = [
"nym-bin-common",
"nym-client-core",
"nym-config",
"nym-exit-policy",
"nym-network-requester",
"nym-sdk",
"nym-service-providers-common",
"nym-sphinx",
"nym-task",
"nym-wireguard",
"nym-wireguard-types",
"reqwest",
"serde",
"serde_json",
"tap",
@@ -9439,9 +9442,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "safer-ffi"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9c1d19b288ca9898cd421c7b105fb7269918a7f8e9253a991e228981ca421ad"
checksum = "395ace5aff9629c7268ca8255aceb945525b2cb644015f3caec5131a6a537c11"
dependencies = [
"inventory",
"libc",
@@ -9456,9 +9459,9 @@ dependencies = [
[[package]]
name = "safer_ffi-proc_macros"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d7a04caa3ca2224f5ea4ddd850e2629c3b36b2b83621f87a8303bf41020110"
checksum = "9255504d5467bae9e07d58b8de446ba6739b29bf72e1fa35b2387e30d29dcbfe"
dependencies = [
"macro_rules_attribute",
"prettyplease",
@@ -4,6 +4,7 @@
use clap::{Args, Subcommand};
pub mod update_config;
pub mod update_cost_params;
pub mod vesting_update_config;
#[derive(Debug, Args)]
@@ -20,7 +21,5 @@ pub enum MixnetOperatorsMixnodeSettingsCommands {
/// Update mixnode configuration for a mixnode bonded with locked tokens
VestingUpdateConfig(vesting_update_config::Args),
/// Update mixnode cost parameters
UpdateCostParameters,
/// Update mixnode cost parameters for a mixnode bonded with locked tokens
VestingUpdateCostParameters,
UpdateCostParameters(update_cost_params::Args),
}
@@ -0,0 +1,48 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::context::SigningClient;
use clap::Parser;
use cosmwasm_std::Uint128;
use log::info;
use nym_mixnet_contract_common::{MixNodeCostParams, Percent};
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
use nym_validator_client::nyxd::CosmWasmCoin;
#[derive(Debug, Parser)]
pub struct Args {
#[clap(
long,
help = "input your profit margin as follows; (so it would be 10, rather than 0.1)"
)]
pub profit_margin_percent: Option<u8>,
#[clap(
long,
help = "operating cost in current DENOMINATION (so it would be 'unym', rather than 'nym')"
)]
pub interval_operating_cost: Option<u128>,
}
pub async fn update_cost_params(args: Args, client: SigningClient) {
let denom = client.current_chain_details().mix_denom.base.as_str();
let cost_params = MixNodeCostParams {
profit_margin_percent: Percent::from_percentage_value(
args.profit_margin_percent.unwrap_or(10) as u64,
)
.unwrap(),
interval_operating_cost: CosmWasmCoin {
denom: denom.into(),
amount: Uint128::new(args.interval_operating_cost.unwrap_or(40_000_000)),
},
};
info!("Starting mixnode params updating!");
let res = client
.update_mixnode_cost_params(cost_params, None)
.await
.expect("failed to update cost params");
info!("Cost params result: {:?}", res)
}
+10 -2
View File
@@ -25,12 +25,20 @@ pub const DEFAULT_CONFIG_FILENAME: &str = "config.toml";
#[cfg(feature = "dirs")]
pub fn must_get_home() -> PathBuf {
dirs::home_dir().expect("Failed to evaluate $HOME value")
if let Some(home_dir) = std::env::var_os("NYM_HOME_DIR") {
home_dir.into()
} else {
dirs::home_dir().expect("Failed to evaluate $HOME value")
}
}
#[cfg(feature = "dirs")]
pub fn may_get_home() -> Option<PathBuf> {
dirs::home_dir()
if let Some(home_dir) = std::env::var_os("NYM_HOME_DIR") {
Some(home_dir.into())
} else {
dirs::home_dir()
}
}
pub trait NymConfigTemplate: Serialize {
+16 -11
View File
@@ -22,14 +22,17 @@ As we shared in our blog post article [*What does it take to build the wolds mos
### What are the changes?
Project smoosh will have three steps:
Project Smoosh will have four steps, please follow the table below to track the dynamic progress:
1. Combine the `nym-gateway` and `nym-network-requester` into one binary ✅
2. Create [Exit Gateway](../legal/exit-gateway.md): Take the `nym-gateway` binary including `nym-network-requester` combined in \#1 and switch from [`allowed.list`](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) to a new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) ✅
3. Combine all the nodes in the Nym Mixnet into one binary, that is `nym-mixnode`, `nym-gateway` (entry and exit) and `nym-network-requester`.
| **Step** | **Status** |
| :--- | :--- |
| **1.** Combine the `nym-gateway` and `nym-network-requester` into one binary | ✅ done |
| **2.** Create [Exit Gateway](../legal/exit-gateway.md): Take the `nym-gateway` binary including `nym-network-requester` combined in \#1 and switch from [`allowed.list`](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) to a new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) | ✅ done |
| **3.** Combine all the nodes in the Nym Mixnet into one binary, that is `nym-mixnode`, `nym-gateway` (entry and exit) and `nym-network-requester`. | 🛠️ in progress |
| **4.** Adjust reward scheme to incentivise and reward Exit Gateways as a part of `nym-node` binary, implementing [zkNym credentials](https://youtu.be/nLmdsZ1BsQg?t=1717). | 🛠️ in progress |
These three steps will be staggered over time - period of several months, and will be implemented one by one with enough time to take in feedback and fix bugs in between.
Generally, the software will be the same, just instead of multiple binaries, there will be one Nym Mixnet node binary. Delegations will remain on as they are now, per our token economics (staking, saturation etc)
These steps will be staggered over time - period of several months, and will be implemented one by one with enough time to take in feedback and fix bugs in between.
Generally, the software will be the same, just instead of multiple binaries, there will be one Nym Node (`nym-node`) binary. Delegations will remain on as they are now, per our token economics (staking, saturation etc)
### What does it mean for Nym nodes operators?
@@ -49,13 +52,15 @@ The operators running Gateways would have to “open” their nodes to a wider r
### How will the Exit policy be implemented?
The progression of exit policy on Gateways will have three steps:
Follow the dynamic progress of exit policy implementation on Gateways below:
1. By default the [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) filtering will be disabled and the current [`allowed.list`](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) filtering is going to continue be used. This is to prevent operators getting surprised by upgrading their Gateways (or Network Requesters) and suddenly be widely open to the internet. To enable the new exit policy, operators must use `--with-exit-policy` flag or modify the `config.toml` file. ✅
2. Relatively soon the exit policy will be part of the Gateway setup by default. To disable this exit policy, operators must use `--disable-exit-policy` flag.
3. Further down the line, it will be the only option. Then the `allowed.list` will be completely removed.
| **Step** | **Status** |
| :--- | :--- |
| **1.** By default the [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) filtering is disabled and the [`allowed.list`](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) filtering is going to continue be used. This is to prevent operators getting surprised by upgrading their Gateways (or Network Requesters) and suddenly be widely open to the internet. To enable the new exit policy, operators must use `--with-exit-policy` flag or modify the `config.toml` file. | ✅ done |
| **2.** The exit policy is part of the Gateway setup by default. To disable this exit policy, operators must use `--disable-exit-policy` flag. | 🛠️ in progress |
| **3.** The exit policy is the only option. The `allowed.list` is completely removed. | 🛠️ in progress |
Keep in mind this only relates to changes happening on Gateway and Network Requester side. Whether this will be optional or mandatory depends on the chosen [design](./smoosh-faq.md#what-does-it-mean-for-nym-nodes-operators).
Keep in mind the table above only relates to changes happening on Gateways. For the Project Smoosh progress refer to the [table above](./smoosh-faq.md#what-are-the-changes). Whether Exit Gateway functionality will be optional or mandatory part of every active Nym Node depends on the chosen [design](./smoosh-faq.md#what-does-it-mean-for-nym-nodes-operators).
### Can I run a Mix Node only?
@@ -29,15 +29,14 @@ Follow these steps to upgrade your Node binary and update its config file:
- if you run it as `systemd` service, run: `systemctl stop nym-<NODE>.service`
* Replace the existing `<NODE>` binary with the newest binary (which you can either [compile yourself](https://nymtech.net/docs/binaries/building-nym.html) or grab from our [releases page](https://github.com/nymtech/nym/releases)).
* Re-run `init` with the same values as you used initially for your `<NODE>` ([Mix Node](./mix-node-setup.md#initialising-your-mix-node), [Gateway](./gateway-setup.md#initialising-your-gateway)) . **This will just update the config file, it will not overwrite existing keys**.
* Restart your node process with the new binary.
- if you automatized (recommended) run:
* Restart your node process with the new binary:
- if your node is not automitized, just `run` your `<NODE>` with `./nym-<NODE> run --id <ID>`. Here are exact guidelines for [Mix Node](./mix-node-setup.md#running-your-mix-node) and [Gateway](./gateway-setup.md#running-your-gateway).
- if you automatized your node via systemd (recommended) run:
```sh
systemctl daemon-reload # to pickup the new unit file
systemctl start nym-<NODE>.service
journalctl -f -u <NODE>.service # to monitor log of you node
```
- if your node is not automitized, just `run` your `<NODE>` with `./nym-<NODE> run --id <ID>`. Here are exact guidelines for [Mix Node](./mix-node-setup.md#running-your-mix-node) and [Gateway](./gateway-setup.md#running-your-gateway).
If these steps are too difficult and you prefer to just run a script, you can use [ExploreNYM script](https://github.com/ExploreNYM/bash-tool) or one done by [Nym developers](https://gist.github.com/tommyv1987/4dca7cc175b70742c9ecb3d072eb8539).
+3 -1
View File
@@ -580,7 +580,9 @@ mod test {
}
#[tokio::test]
#[should_panic]
#[should_panic(
expected = "Received committed block which isn't last produced block, this is a bug!"
)]
async fn test_on_committed_with_invalid_pending_block() {
let (mut manager, _) = block_manager_with_defaults();
+8 -2
View File
@@ -1,8 +1,11 @@
import * as React from 'react';
import React from 'react';
import Box from '@mui/material/Box';
import { Typography } from '@mui/material';
import MuiLink from '@mui/material/Link';
import { Link } from 'react-router-dom';
import Typography from '@mui/material/Typography';
import { Socials } from './Socials';
import { useIsMobile } from '../hooks/useIsMobile';
import { NymVpnIcon } from '../icons/NymVpn';
export const Footer: FCWithChildren = () => {
const isMobile = useIsMobile();
@@ -31,6 +34,9 @@ export const Footer: FCWithChildren = () => {
mb: 2,
}}
>
<MuiLink component={Link} to="http://nymvpn.com" target="_blank" underline="none" marginRight={1}>
<NymVpnIcon />
</MuiLink>
<Socials isFooter />
</Box>
)}
+4
View File
@@ -22,6 +22,7 @@ import { useMainContext } from '../context/main';
import { MobileDrawerClose } from '../icons/MobileDrawerClose';
import { Socials } from './Socials';
import { Footer } from './Footer';
import { NymVpnIcon } from '../icons/NymVpn';
import { DarkLightSwitchDesktop } from './Switch';
import { NavOptionType } from '../context/nav';
@@ -341,6 +342,9 @@ export const Nav: FCWithChildren = ({ children }) => {
alignItems: 'center',
}}
>
<MuiLink component={Link} to="http://nymvpn.com" target="_blank" underline="none" marginRight={1}>
<NymVpnIcon />
</MuiLink>
<Socials />
<DarkLightSwitchDesktop defaultChecked />
</Box>
+56
View File
@@ -0,0 +1,56 @@
import * as React from 'react';
interface DiscordIconProps {
size?: { width: number; height: number };
}
export const NymVpnIcon: FCWithChildren<DiscordIconProps> = ({ size }) => (
<svg width={size?.width} height={size?.height} viewBox="0 0 170 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M19.6118 0.128906H19.5405V0.187854V20.7961L10.7849 0.164277L10.773 0.128906H10.7255H5.75959H0.187819H0.128418V0.187854V23.8142V23.8732H0.187819H5.75959H5.81899V23.8142V3.17063L14.6103 23.8378L14.6222 23.8732H14.6697H19.6118H25.1717H25.2311V23.8142V0.187854V0.128906H25.1717H19.6118Z"
fill="white"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M19.4121 0H25.3603V24H14.5297L14.4901 23.8819L5.94824 3.80121V24H0V0H10.8663L10.906 0.118132L19.4121 20.1621V0ZM19.5409 20.7951L10.7853 0.163225L10.7734 0.127854H0.128835V23.8721H5.81941V3.16958L14.6107 23.8368L14.6226 23.8721H25.2315V0.127854H19.5409V20.7951Z"
fill="white"
/>
<path
d="M89.8116 0.128906H79.1908H79.1314L79.1195 0.176068L73.6784 20.8904L68.2255 0.176068L68.2136 0.128906H68.1661H57.5215H57.4502V0.187854V23.8142V23.8732H57.5215H63.0814H63.1408V23.8142V3.33568L68.5225 23.826L68.5343 23.8732H68.5937H78.7394H78.7869L78.7988 23.826L84.1804 3.33568V23.8142V23.8732H84.2398H89.8116H89.871V23.8142V0.187854V0.128906H89.8116Z"
fill="white"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M79.0312 0H90.0003V24H84.052V4.33208L78.9242 23.856L78.9238 23.8572L78.8879 24H68.4342L68.3982 23.8572L68.3979 23.856L63.27 4.33208V24H57.3218V0H68.3146L68.3505 0.142699L68.3509 0.144015L73.6787 20.383L78.9949 0.144015L78.9953 0.142765L79.0312 0ZM73.6788 20.8894L68.2259 0.175015L68.214 0.127854H57.4506V23.8721H63.1412V3.33463L68.5229 23.825L68.5348 23.8721H78.7873L78.7992 23.825L84.1809 3.33463V23.8721H89.8714V0.127854H79.1318L79.1199 0.175015L73.6788 20.8894Z"
fill="white"
/>
<path
d="M48.2909 0.128906H48.2553L48.2434 0.152487L41.4836 11.8124L34.6882 0.152487L34.6763 0.128906H34.6407H28.2135H28.0947L28.1541 0.223225L38.6205 18.2142V23.8142V23.8732H38.6799H44.2517H44.3111V23.8142V18.2142L54.7775 0.223225L54.8369 0.128906H54.7181H48.2909Z"
fill="white"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M48.1757 0H55.0693L54.8879 0.288036L44.4399 18.2474V24H38.4917V18.2474L28.0437 0.288036L27.8623 0H34.756L34.8017 0.0907854L41.4833 11.5555L48.1299 0.0909153L48.1757 0ZM48.2434 0.151434L41.4836 11.8114L34.6882 0.151434L34.6763 0.127854H28.0948L28.1542 0.222173L38.6205 18.2131V23.8721H44.3111V18.2131L54.7775 0.222173L54.8369 0.127854H48.2553L48.2434 0.151434Z"
fill="white"
/>
<path
d="M169.238 0V24H166.422C166.006 24 165.654 23.9341 165.366 23.8023C165.088 23.6596 164.811 23.418 164.534 23.0776L153.542 8.76321C153.584 9.19149 153.611 9.60878 153.622 10.0151C153.643 10.4104 153.654 10.7838 153.654 11.1352V24H148.886V0H151.734C151.968 0 152.166 0.0109813 152.326 0.032944C152.486 0.0549066 152.63 0.0988326 152.758 0.164722C152.886 0.219629 153.008 0.30199 153.126 0.411805C153.243 0.521619 153.376 0.669869 153.526 0.856553L164.614 15.2697C164.56 14.8085 164.523 14.3638 164.502 13.9355C164.48 13.4962 164.47 13.0844 164.47 12.7001V0H169.238Z"
fill="#A8A6A6"
/>
<path
d="M134.206 11.7776C135.614 11.7776 136.627 11.4317 137.246 10.7399C137.865 10.048 138.174 9.08167 138.174 7.84077C138.174 7.29169 138.094 6.79204 137.934 6.3418C137.774 5.89156 137.529 5.50721 137.198 5.18874C136.878 4.8593 136.467 4.60673 135.966 4.43102C135.475 4.25532 134.889 4.16747 134.206 4.16747H131.39V11.7776H134.206ZM134.206 0C135.849 0 137.257 0.203157 138.43 0.609471C139.614 1.0048 140.585 1.55388 141.342 2.25669C142.11 2.95951 142.675 3.78861 143.038 4.74399C143.401 5.69938 143.582 6.73164 143.582 7.84077C143.582 9.03775 143.395 10.1359 143.022 11.1352C142.649 12.1345 142.078 12.9911 141.31 13.7049C140.542 14.4187 139.566 14.9787 138.382 15.385C137.209 15.7804 135.817 15.978 134.206 15.978H131.39V24H125.982V0H134.206Z"
fill="#A8A6A6"
/>
<path
d="M121.584 0L112.24 24H107.344L98 0H102.352C102.821 0 103.2 0.115305 103.488 0.345915C103.776 0.565545 103.995 0.851064 104.144 1.20247L108.656 14.0508C108.869 14.6108 109.077 15.2258 109.28 15.8957C109.483 16.5546 109.675 17.2464 109.856 17.9712C110.005 17.2464 110.171 16.5546 110.352 15.8957C110.544 15.2258 110.747 14.6108 110.96 14.0508L115.44 1.20247C115.557 0.894989 115.765 0.620452 116.064 0.378861C116.373 0.126287 116.752 0 117.2 0H121.584Z"
fill="#A8A6A6"
/>
</svg>
);
NymVpnIcon.defaultProps = {
size: { width: 80, height: 12 },
};
+1 -4
View File
@@ -76,7 +76,7 @@ nym-statistics-common = { path = "../common/statistics" }
nym-task = { path = "../common/task" }
nym-types = { path = "../common/types" }
nym-validator-client = { path = "../common/client-libs/validator-client" }
nym-wireguard = { path = "../common/wireguard", optional = true }
nym-wireguard = { path = "../common/wireguard" }
nym-ip-packet-router = { path = "../service-providers/ip-packet-router" }
[dev-dependencies]
@@ -92,6 +92,3 @@ sqlx = { version = "0.5", features = [
"macros",
"migrate",
] }
[features]
wireguard = ["nym-wireguard"]
+12 -10
View File
@@ -200,7 +200,6 @@ impl<St> Gateway<St> {
mixnet_handling::Listener::new(listening_address, shutdown).start(connection_handler);
}
#[cfg(feature = "wireguard")]
async fn start_wireguard(
&self,
shutdown: TaskClient,
@@ -520,15 +519,18 @@ impl<St> Gateway<St> {
Arc::new(coconut_verifier),
);
// Once this is a bit more mature, make this a commandline flag instead of a compile time
// flag
#[cfg(feature = "wireguard")]
if let Err(err) = self
.start_wireguard(shutdown.subscribe().named("wireguard"))
.await
{
// that's a nasty workaround, but anyhow errors are generally nicer, especially on exit
bail!("{err}")
// TODO: later we'll make this a commandline flag
let wireguard_enabled = std::env::var("NYM_ENABLE_WIREGUARD")
.map(|v| v == "1")
.unwrap_or(false);
if wireguard_enabled {
if let Err(err) = self
.start_wireguard(shutdown.subscribe().named("wireguard"))
.await
{
// that's a nasty workaround, but anyhow errors are generally nicer, especially on exit
bail!("{err}")
}
}
info!("Finished nym gateway startup procedure - it should now be able to receive mix and client traffic!");
+5
View File
@@ -81,3 +81,8 @@ cpucycles = [
"opentelemetry",
"nym-bin-common/tracing",
]
[package.metadata.deb]
name = "nym-mixnode"
maintainer-scripts = "debian"
systemd-units = { enable = false }
+6
View File
@@ -0,0 +1,6 @@
#DEBHELPER#
useradd nym
mkdir -p /etc/nym
chown -R nym /etc/nym
su nym -c 'NYM_HOME_DIR=/etc/nym nym-mixnode init --host 0.0.0.0 --id nym-mixnode'
+11
View File
@@ -0,0 +1,11 @@
[Unit]
Description=Nym Mixnode
After=network-online.target
[Service]
ExecStart=/usr/bin/nym-mixnode run --id nym-mixnode
User=nym
Environment="NYM_HOME_DIR=/etc/nym"
[Install]
WantedBy=multi-user.target
+1 -1
View File
@@ -13,7 +13,7 @@ This is the application UI layer for the next NymVPN clients.
Some system libraries are required depending on the host platform.
Follow the instructions for your specific OS [here](https://tauri.app/v1/guides/getting-started/prerequisites)
To install run
To install:
```
yarn
+1 -1
View File
@@ -28,7 +28,7 @@ tokio = { workspace = true, features = ["sync", "time"] }
log = "0.4.17"
rand = "0.7.3"
safer-ffi = { version = "0.1.0-rc1" }
safer-ffi = { version = "0.1.4" }
[target.'cfg(target_os="android")'.dependencies]
jni = { version = "0.21", default-features = false }
@@ -16,6 +16,8 @@ in combination with their own configuration. If you are trying to access somethi
3. If you are using `mixFetch` in a web app with HTTPS you will need to use a gateway that has Secure Websockets to
avoid getting a [mixed content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content) error.
4. For now, mixfetch doesn't work with SURBS, altough this may change in the future.
Read [this article](https://blog.nymtech.net/mixfetch-like-the-fetch-api-but-via-the-mixnet-82acfd435c62) to learn more about mixFetch.
@@ -15,12 +15,15 @@ log = { workspace = true }
nym-bin-common = { path = "../../common/bin-common" }
nym-client-core = { path = "../../common/client-core" }
nym-config = { path = "../../common/config" }
nym-exit-policy = { path = "../../common/exit-policy" }
nym-network-requester = { path = "../network-requester" }
nym-sdk = { path = "../../sdk/rust/nym-sdk" }
nym-service-providers-common = { path = "../common" }
nym-sphinx = { path = "../../common/nymsphinx" }
nym-task = { path = "../../common/task" }
nym-wireguard = { path = "../../common/wireguard" }
nym-wireguard-types = { path = "../../common/wireguard-types" }
reqwest.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
tap.workspace = true
@@ -1,4 +1,7 @@
use std::net::SocketAddr;
pub use nym_client_core::error::ClientCoreError;
use nym_exit_policy::PolicyError;
#[derive(thiserror::Error, Debug)]
pub enum IpPacketRouterError {
@@ -31,5 +34,29 @@ pub enum IpPacketRouterError {
PacketParseFailed { source: etherparse::ReadError },
#[error("parsed packet is missing IP header")]
PacketMissingHeader,
PacketMissingIpHeader,
#[error("parsed packet is missing transport header")]
PacketMissingTransportHeader,
#[error("the provided socket address, '{addr}' is not covered by the exit policy!")]
AddressNotCoveredByExitPolicy { addr: SocketAddr },
#[error("failed filter check: '{addr}'")]
AddressFailedFilterCheck { addr: SocketAddr },
#[error("failed to apply the exit policy: {source}")]
ExitPolicyFailure {
#[from]
source: PolicyError,
},
#[error("the url provided for the upstream exit policy source is malformed: {source}")]
MalformedExitPolicyUpstreamUrl {
#[source]
source: reqwest::Error,
},
#[error("can't setup an exit policy without any upstream urls")]
NoUpstreamExitPolicy,
}
+105 -24
View File
@@ -1,4 +1,9 @@
use std::{net::IpAddr, path::Path};
#![cfg_attr(not(target_os = "linux"), allow(dead_code))]
use std::{
net::{IpAddr, SocketAddr},
path::Path,
};
use error::IpPacketRouterError;
use futures::{channel::oneshot, StreamExt};
@@ -12,6 +17,7 @@ use nym_sdk::{
};
use nym_sphinx::receiver::ReconstructedMessage;
use nym_task::{connections::TransmissionLane, TaskClient, TaskHandle};
use request_filter::RequestFilter;
use tap::TapFallible;
use crate::config::BaseClientConfig;
@@ -20,6 +26,7 @@ pub use crate::config::Config;
pub mod config;
pub mod error;
mod request_filter;
// The interface used to route traffic
pub const TUN_BASE_NAME: &str = "nymtun";
@@ -29,11 +36,16 @@ pub const TUN_DEVICE_NETMASK: &str = "255.255.255.0";
pub struct OnStartData {
// to add more fields as required
pub address: Recipient,
pub request_filter: RequestFilter,
}
impl OnStartData {
pub fn new(address: Recipient) -> Self {
Self { address }
pub fn new(address: Recipient, request_filter: RequestFilter) -> Self {
Self {
address,
request_filter,
}
}
}
@@ -139,9 +151,12 @@ impl IpPacketRouterBuilder {
);
tun.start();
let request_filter = request_filter::RequestFilter::new(&self.config).await?;
request_filter.start_update_tasks().await;
let ip_packet_router_service = IpPacketRouter {
_config: self.config,
// tun,
request_filter: request_filter.clone(),
tun_task_tx,
tun_task_response_rx,
mixnet_client,
@@ -152,7 +167,10 @@ impl IpPacketRouterBuilder {
log::info!("All systems go. Press CTRL-C to stop the server.");
if let Some(on_start) = self.on_start {
if on_start.send(OnStartData::new(self_address)).is_err() {
if on_start
.send(OnStartData::new(self_address, request_filter))
.is_err()
{
// the parent has dropped the channel before receiving the response
return Err(IpPacketRouterError::DisconnectedParent);
}
@@ -165,7 +183,7 @@ impl IpPacketRouterBuilder {
#[allow(unused)]
struct IpPacketRouter {
_config: Config,
// tun: nym_wireguard::tun_device::TunDevice,
request_filter: request_filter::RequestFilter,
tun_task_tx: nym_wireguard::tun_task_channel::TunTaskTx,
tun_task_response_rx: nym_wireguard::tun_task_channel::TunTaskResponseRx,
mixnet_client: nym_sdk::mixnet::MixnetClient,
@@ -235,26 +253,38 @@ impl IpPacketRouter {
) -> Result<(), IpPacketRouterError> {
log::info!("Received message: {:?}", reconstructed.sender_tag);
let headers = etherparse::SlicedPacket::from_ip(&reconstructed.message).map_err(|err| {
log::warn!("Received non-IP packet: {err}");
IpPacketRouterError::PacketParseFailed { source: err }
})?;
// We don't forward packets that we are not able to parse. BUT, there might be a good
// reason to still forward them.
//
// For example, if we are running in a mode where we are only supposed to forward
// packets to a specific destination, we might want to forward them anyway.
//
// TODO: look into this
let ParsedPacket {
packet_type,
src_addr,
dst_addr,
dst,
} = parse_packet(&reconstructed.message)?;
let (src_addr, dst_addr): (IpAddr, IpAddr) = match headers.ip {
Some(etherparse::InternetSlice::Ipv4(ipv4_header, _)) => (
ipv4_header.source_addr().into(),
ipv4_header.destination_addr().into(),
),
Some(etherparse::InternetSlice::Ipv6(ipv6_header, _)) => (
ipv6_header.source_addr().into(),
ipv6_header.destination_addr().into(),
),
None => {
log::warn!("Received non-IP packet");
return Err(IpPacketRouterError::PacketMissingHeader);
let dst_str = dst.map_or(dst_addr.to_string(), |dst| dst.to_string());
log::info!("Received packet: {packet_type}: {src_addr} -> {dst_str}");
// Filter check
if let Some(dst) = dst {
if !self.request_filter.check_address(&dst).await {
log::warn!("Failed filter check: {dst}");
// TODO: send back a response here
return Err(IpPacketRouterError::AddressFailedFilterCheck { addr: dst });
}
};
log::info!("Received packet: {src_addr} -> {dst_addr}");
} else {
// TODO: are we always allowing packets without port numbers?
log::warn!(
"Ignoring filter check for packet without port number! (TODO: is this correct?)"
);
}
// TODO: set the tag correctly. Can we just reuse sender_tag?
let peer_tag = 0;
@@ -270,6 +300,57 @@ impl IpPacketRouter {
}
}
struct ParsedPacket<'a> {
packet_type: &'a str,
src_addr: IpAddr,
dst_addr: IpAddr,
dst: Option<SocketAddr>,
}
fn parse_packet(packet: &[u8]) -> Result<ParsedPacket, IpPacketRouterError> {
let headers = etherparse::SlicedPacket::from_ip(packet).map_err(|err| {
log::warn!("Unable to parse incoming data as IP packet: {err}");
IpPacketRouterError::PacketParseFailed { source: err }
})?;
let (packet_type, dst_port) = match headers.transport {
Some(etherparse::TransportSlice::Udp(header)) => ("ipv4", Some(header.destination_port())),
Some(etherparse::TransportSlice::Tcp(header)) => ("ipv6", Some(header.destination_port())),
Some(etherparse::TransportSlice::Icmpv4(_)) => ("icpv4", None),
Some(etherparse::TransportSlice::Icmpv6(_)) => ("icmpv6", None),
Some(etherparse::TransportSlice::Unknown(_)) => ("unknown", None),
None => {
log::warn!("Received packet missing transport header");
return Err(IpPacketRouterError::PacketMissingTransportHeader);
}
};
let (src_addr, dst_addr, dst) = match headers.ip {
Some(etherparse::InternetSlice::Ipv4(ipv4_header, _)) => {
let src_addr: IpAddr = ipv4_header.source_addr().into();
let dst_addr: IpAddr = ipv4_header.destination_addr().into();
let dst = dst_port.map(|port| SocketAddr::new(dst_addr, port));
(src_addr, dst_addr, dst)
}
Some(etherparse::InternetSlice::Ipv6(ipv6_header, _)) => {
let src_addr: IpAddr = ipv6_header.source_addr().into();
let dst_addr: IpAddr = ipv6_header.destination_addr().into();
let dst = dst_port.map(|port| SocketAddr::new(dst_addr, port));
(src_addr, dst_addr, dst)
}
None => {
log::warn!("Received packet missing IP header");
return Err(IpPacketRouterError::PacketMissingIpHeader);
}
};
Ok(ParsedPacket {
packet_type,
src_addr,
dst_addr,
dst,
})
}
// Helper function to create the mixnet client.
// This is NOT in the SDK since we don't want to expose any of the client-core config types.
// We could however consider moving it to a crate in common in the future.
@@ -0,0 +1,50 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::net::SocketAddr;
use crate::error::IpPacketRouterError;
use nym_exit_policy::client::get_exit_policy;
use nym_exit_policy::ExitPolicy;
use reqwest::IntoUrl;
use url::Url;
pub struct ExitPolicyRequestFilter {
upstream: Option<Url>,
policy: ExitPolicy,
}
impl ExitPolicyRequestFilter {
pub(crate) async fn new_upstream(url: impl IntoUrl) -> Result<Self, IpPacketRouterError> {
let url = url
.into_url()
.map_err(|source| IpPacketRouterError::MalformedExitPolicyUpstreamUrl { source })?;
Ok(ExitPolicyRequestFilter {
upstream: Some(url.clone()),
policy: get_exit_policy(url).await?,
})
}
#[allow(unused)]
pub(crate) fn new(policy: ExitPolicy) -> Self {
ExitPolicyRequestFilter {
upstream: None,
policy,
}
}
pub fn policy(&self) -> &ExitPolicy {
&self.policy
}
pub fn upstream(&self) -> Option<&Url> {
self.upstream.as_ref()
}
pub(crate) async fn check(&self, addr: &SocketAddr) -> Result<bool, IpPacketRouterError> {
self.policy
.allows_sockaddr(addr)
.ok_or(IpPacketRouterError::AddressNotCoveredByExitPolicy { addr: *addr })
}
}
@@ -0,0 +1,68 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::config::Config;
use crate::error::IpPacketRouterError;
use crate::request_filter::exit_policy::ExitPolicyRequestFilter;
use log::{info, warn};
use std::{net::SocketAddr, sync::Arc};
pub mod exit_policy;
enum RequestFilterInner {
ExitPolicy {
policy_filter: ExitPolicyRequestFilter,
},
}
#[derive(Clone)]
pub struct RequestFilter {
inner: Arc<RequestFilterInner>,
}
impl RequestFilter {
pub(crate) async fn new(config: &Config) -> Result<Self, IpPacketRouterError> {
info!("setting up ExitPolicy based request filter...");
Self::new_exit_policy_filter(config).await
}
pub fn current_exit_policy_filter(&self) -> Option<&ExitPolicyRequestFilter> {
match &*self.inner {
RequestFilterInner::ExitPolicy { policy_filter } => Some(policy_filter),
}
}
pub(crate) async fn start_update_tasks(&self) {
match &*self.inner {
RequestFilterInner::ExitPolicy { .. } => {
// nothing to do for the exit policy (yet; we might add a refresher at some point)
}
}
}
async fn new_exit_policy_filter(config: &Config) -> Result<Self, IpPacketRouterError> {
let upstream_url = config
.ip_packet_router
.upstream_exit_policy_url
.as_ref()
.ok_or(IpPacketRouterError::NoUpstreamExitPolicy)?;
let policy_filter = ExitPolicyRequestFilter::new_upstream(upstream_url.clone()).await?;
Ok(RequestFilter {
inner: Arc::new(RequestFilterInner::ExitPolicy { policy_filter }),
})
}
pub(crate) async fn check_address(&self, address: &SocketAddr) -> bool {
match &*self.inner {
RequestFilterInner::ExitPolicy { policy_filter } => {
match policy_filter.check(address).await {
Err(err) => {
warn!("failed to validate '{address}' against the exit policy: {err}");
false
}
Ok(res) => res,
}
}
}
}
}
+14 -13
View File
@@ -44,7 +44,7 @@ pub(crate) trait ReleasePackage: Sized {
Ok(())
}
fn update_nym_dependencies(&mut self, _: &HashSet<String>) -> anyhow::Result<()> {
fn update_nym_dependencies(&mut self, _: &HashSet<String>, _: bool) -> anyhow::Result<()> {
Ok(())
}
}
@@ -57,28 +57,29 @@ pub(crate) trait VersionBumpExt: Sized {
fn try_remove_prerelease(&self) -> anyhow::Result<Self>;
}
pub(crate) fn try_bump_raw_prerelease(raw: &str) -> anyhow::Result<Prerelease> {
// ugh that's disgusting
let (rc_prefix, pre_version) = raw
.split_once('.')
.context("the prerelease version does not contain a valid rc.X suffix")?;
let parsed_version: u32 = pre_version.parse()?;
let updated_version = parsed_version + 1;
Ok(format!("{rc_prefix}.{updated_version}").parse()?)
}
impl VersionBumpExt for Version {
fn try_bump_prerelease(&self) -> anyhow::Result<Self> {
if self.pre.is_empty() {
bail!("the current version ({self}) does not have pre-release data set - are you sure you followed the release process correctly?")
}
// ugh that's disgusting
let (rc_prefix, pre_version) = self
.pre
.as_str()
.split_once('.')
.context("the prerelease version does not contain a valid rc.X suffix")?;
let parsed_version: u32 = pre_version.parse()?;
let updated_version = parsed_version + 1;
let pre = format!("{rc_prefix}.{updated_version}").parse()?;
Ok(Version {
major: self.major,
minor: self.minor,
patch: self.patch,
pre,
pre: try_bump_raw_prerelease(self.pre.as_str())?,
build: self.build.clone(),
})
}
+48 -11
View File
@@ -1,6 +1,7 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::helpers::try_bump_raw_prerelease;
use crate::json_types::DepsSet;
use crate::{json_types, ReleasePackage};
use anyhow::{bail, Context};
@@ -14,10 +15,18 @@ pub struct PackageJson {
inner: json_types::Package,
}
fn update_dependencies(deps: &mut DepsSet, names: &HashSet<String>) -> anyhow::Result<()> {
fn update_dependencies(
deps: &mut DepsSet,
names: &HashSet<String>,
pre_release: bool,
) -> anyhow::Result<()> {
for (package, version) in deps.iter_mut() {
if names.contains(package) {
let updated = try_bump_minor_version_req(version)?;
let updated = if pre_release {
try_bump_prerelease_version_req(version)?
} else {
try_bump_minor_version_req(version)?
};
println!("\t\t>>> updating '{package}' from {version} to {updated}");
*version = updated
@@ -52,21 +61,25 @@ impl ReleasePackage for PackageJson {
self.inner.version = version.to_string()
}
fn update_nym_dependencies(&mut self, names: &HashSet<String>) -> anyhow::Result<()> {
fn update_nym_dependencies(
&mut self,
names: &HashSet<String>,
pre_release: bool,
) -> anyhow::Result<()> {
println!("\t>>> updating @nymproject dependencies...");
update_dependencies(&mut self.inner.dependencies, names)?;
update_dependencies(&mut self.inner.dependencies, names, pre_release)?;
println!("\t>>> updating @nymproject peerDependencies...");
update_dependencies(&mut self.inner.peer_dependencies, names)?;
update_dependencies(&mut self.inner.peer_dependencies, names, pre_release)?;
println!("\t>>> updating @nymproject devDependencies...");
update_dependencies(&mut self.inner.dev_dependencies, names)?;
update_dependencies(&mut self.inner.dev_dependencies, names, pre_release)?;
println!("\t>>> updating @nymproject optionalDependencies...");
update_dependencies(&mut self.inner.optional_dependencies, names)?;
update_dependencies(&mut self.inner.optional_dependencies, names, pre_release)?;
println!("\t>>> updating @nymproject bundledDependencies...");
update_dependencies(&mut self.inner.bundled_dependencies, names)?;
update_dependencies(&mut self.inner.bundled_dependencies, names, pre_release)?;
Ok(())
}
@@ -101,9 +114,9 @@ pub(crate) fn find_package_path(dir: &Path) -> anyhow::Result<PathBuf> {
// expected structure: `>=X.Y.Z-rc.W || ^X`
fn try_bump_minor_version_req(raw_req: &str) -> anyhow::Result<String> {
let (req, major) = raw_req
.split_once("||")
.context("invalid version requirement")?;
let (req, major) = raw_req.split_once("||").context(format!(
"'{raw_req}' is not a valid semver version requirement - we expect '`>=X.Y.Z-rc.W || ^X`'"
))?;
let parsed_req = VersionReq::parse(req)?;
let parsed_major = VersionReq::parse(major)?;
if parsed_req.comparators.len() != 1 {
@@ -123,6 +136,30 @@ fn try_bump_minor_version_req(raw_req: &str) -> anyhow::Result<String> {
Ok(format!("{updated} || {parsed_major}"))
}
// expected structure: `>=X.Y.Z-rc.W || ^X`
fn try_bump_prerelease_version_req(raw_req: &str) -> anyhow::Result<String> {
let (req, major) = raw_req.split_once("||").context(format!(
"'{raw_req}' is not a valid semver version requirement - we expect '`>=X.Y.Z-rc.W || ^X`'"
))?;
let parsed_req = VersionReq::parse(req)?;
let parsed_major = VersionReq::parse(major)?;
if parsed_req.comparators.len() != 1 {
bail!("wrong number of version requirements present in {parsed_req}")
}
let updated = VersionReq {
comparators: vec![Comparator {
op: parsed_req.comparators[0].op,
major: parsed_req.comparators[0].major,
minor: parsed_req.comparators[0].minor,
patch: parsed_req.comparators[0].patch,
pre: try_bump_raw_prerelease(parsed_req.comparators[0].pre.as_str())?,
}],
};
Ok(format!("{updated} || {parsed_major}"))
}
#[cfg(test)]
mod tests {
use super::*;
+74 -15
View File
@@ -5,7 +5,7 @@ use crate::cargo::CargoPackage;
use crate::helpers::ReleasePackage;
use crate::json::PackageJson;
use clap::{Parser, Subcommand};
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};
use std::env;
use std::path::{Path, PathBuf};
@@ -18,6 +18,48 @@ fn default_root() -> PathBuf {
env::current_dir().unwrap()
}
struct Summary {
cargo_results: HashMap<String, anyhow::Result<()>>,
json_results: HashMap<String, anyhow::Result<()>>,
}
impl Summary {
fn new(
cargo_results: HashMap<String, anyhow::Result<()>>,
json_results: HashMap<String, anyhow::Result<()>>,
) -> Self {
Summary {
cargo_results,
json_results,
}
}
fn print(&self) {
let cargo_ok = self.cargo_results.values().filter(|p| p.is_ok()).count();
let json_ok = self.json_results.values().filter(|p| p.is_ok()).count();
println!("SUMMARY");
println!("inspected {} cargo packages", self.cargo_results.len());
println!("updated {cargo_ok} cargo packages");
for (package, res) in &self.cargo_results {
if let Err(err) = res {
println!(
"\t>>> ❌ FAILURE: cargo package '{package}' failed to get updated: {err}"
);
}
}
println!("inspected {} json packages", self.json_results.len());
println!("updated {json_ok} json packages");
for (package, res) in &self.json_results {
if let Err(err) = res {
println!("\t>>> ❌ FAILURE: json package '{package}' failed to get updated: {err}");
}
}
}
}
#[derive(Parser)]
struct Args {
#[arg(default_value=default_root().into_os_string())]
@@ -36,12 +78,13 @@ enum Commands {
/// It will also update the `@nymproject/...` dependencies from `">=X.Y.Z-rc.0 || ^X"` to `">=X.Y.(Z+1)-rc.0 || ^X"`
BumpVersion {
#[arg(long)]
/// If enabled, the packages will only have their rc version bumped and the dependencies won't get updated at all
/// If enabled, the packages will only have their rc version bumped and the dependencies
/// will get updated from `">=X.Y.Z-rc.W || ^X"` to `">=X.Y.Z-rc.(W+1) || ^X"`
pre_release: bool,
},
}
fn remove_suffix<Pkg: ReleasePackage>(root: &Path, path: impl AsRef<Path>) {
fn remove_suffix<Pkg: ReleasePackage>(root: &Path, path: impl AsRef<Path>) -> anyhow::Result<()> {
let path = root.join(path);
println!(
">>> [{}] UPDATING PACKAGE {}: ",
@@ -51,8 +94,10 @@ fn remove_suffix<Pkg: ReleasePackage>(root: &Path, path: impl AsRef<Path>) {
if let Err(err) = { remove_suffix_inner::<Pkg>(path) } {
println!("\t>>> ❌ FAILURE: {err}");
Err(err)
} else {
println!("\t>>> ✅ SUCCESS");
Ok(())
}
}
@@ -70,7 +115,7 @@ fn bump_version<Pkg: ReleasePackage>(
path: impl AsRef<Path>,
dependencies_to_update: &HashSet<String>,
pre_release: bool,
) {
) -> anyhow::Result<()> {
let path = root.join(path);
println!(
">>> [{}] UPDATING PACKAGE {}: ",
@@ -79,8 +124,10 @@ fn bump_version<Pkg: ReleasePackage>(
);
if let Err(err) = { bump_version_inner::<Pkg>(path, dependencies_to_update, pre_release) } {
println!("\t>>> ❌ FAILURE: {err}");
Err(err)
} else {
println!("\t>>> ✅ SUCCESS");
Ok(())
}
}
@@ -93,9 +140,7 @@ fn bump_version_inner<Pkg: ReleasePackage>(
let mut package = Pkg::open(path)?;
package.bump_version(pre_release)?;
if !pre_release {
package.update_nym_dependencies(dependencies_to_update)?;
}
package.update_nym_dependencies(dependencies_to_update, pre_release)?;
println!("\t>>> saving the package file...");
package.save_changes()
@@ -132,34 +177,46 @@ impl InternalPackages {
self.internal_js_dependencies.insert(name.into());
}
pub fn remove_suffix(&self) {
pub fn remove_suffix(&self) -> Summary {
let mut cargo_results = HashMap::new();
for cargo_package in &self.cargo {
remove_suffix::<CargoPackage>(&self.root, cargo_package);
let res = remove_suffix::<CargoPackage>(&self.root, cargo_package);
cargo_results.insert(cargo_package.clone(), res);
}
let mut json_results = HashMap::new();
for package_json in &self.json {
remove_suffix::<PackageJson>(&self.root, package_json);
let res = remove_suffix::<PackageJson>(&self.root, package_json);
json_results.insert(package_json.clone(), res);
}
Summary::new(cargo_results, json_results)
}
pub fn bump_version(&self, pre_release: bool) {
pub fn bump_version(&self, pre_release: bool) -> Summary {
let mut cargo_results = HashMap::new();
for cargo_package in &self.cargo {
bump_version::<CargoPackage>(
let res = bump_version::<CargoPackage>(
&self.root,
cargo_package,
&Default::default(),
pre_release,
);
cargo_results.insert(cargo_package.clone(), res);
}
let mut json_results = HashMap::new();
for package_json in &self.json {
bump_version::<PackageJson>(
let res = bump_version::<PackageJson>(
&self.root,
package_json,
&self.internal_js_dependencies,
pre_release,
);
json_results.insert(package_json.clone(), res);
}
Summary::new(cargo_results, json_results)
}
}
@@ -226,10 +283,12 @@ fn main() -> anyhow::Result<()> {
let args = Args::parse();
let packages = initialise_internal_packages(args.root);
match args.command {
let summary = match args.command {
Commands::RemoveSuffix => packages.remove_suffix(),
Commands::BumpVersion { pre_release } => packages.bump_version(pre_release),
}
};
summary.print();
Ok(())
}
@@ -13,6 +13,9 @@ pub(crate) async fn execute(
nym_cli_commands::validator::mixnet::operators::mixnode::settings::MixnetOperatorsMixnodeSettingsCommands::UpdateConfig(args) => {
nym_cli_commands::validator::mixnet::operators::mixnode::settings::update_config::update_config(args, create_signing_client(global_args, network_details)?).await
}
nym_cli_commands::validator::mixnet::operators::mixnode::settings::MixnetOperatorsMixnodeSettingsCommands::UpdateCostParameters(args) => {
nym_cli_commands::validator::mixnet::operators::mixnode::settings::update_cost_params::update_cost_params(args, create_signing_client(global_args, network_details)?).await
}
_ => unreachable!(),
}
Ok(())