Merge pull request #5936 from nymtech/release/2025.14-feta
Merge release/2025.14-feta to develop
This commit is contained in:
@@ -38,15 +38,14 @@ jobs:
|
||||
rm -rf ci-builds || true
|
||||
mkdir -p $OUTPUT_DIR
|
||||
echo $OUTPUT_DIR
|
||||
|
||||
- name: Install Dependencies (Linux)
|
||||
run: sudo apt-get update && sudo apt-get -y install libudev-dev
|
||||
|
||||
- name: Sets env vars for tokio if set in manual dispatch inputs
|
||||
run: |
|
||||
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
|
||||
if: github.event_name == 'workflow_dispatch' && inputs.add_tokio_unstable == true
|
||||
|
||||
run: |
|
||||
echo "RUSTFLAGS=--cfg tokio_unstable" >> $GITHUB_ENV
|
||||
echo "CARGO_FEATURES=--features tokio-console" >> $GITHUB_ENV
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
@@ -103,7 +102,6 @@ jobs:
|
||||
if [ ${{ github.event_name == 'workflow_dispatch' && inputs.enable_deb == true }} = true ]; then
|
||||
cp target/debian/*.deb $OUTPUT_DIR
|
||||
fi
|
||||
|
||||
- name: Deploy branch to CI www
|
||||
continue-on-error: true
|
||||
uses: easingthemes/ssh-deploy@main
|
||||
|
||||
Generated
+48
-116
@@ -556,34 +556,6 @@ dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core 0.3.4",
|
||||
"bitflags 1.3.2",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.32",
|
||||
"itoa",
|
||||
"matchit 0.7.3",
|
||||
"memchr",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"sync_wrapper 0.1.2",
|
||||
"tower 0.4.13",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.7.9"
|
||||
@@ -664,23 +636,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"mime",
|
||||
"rustversion",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.4.5"
|
||||
@@ -1441,11 +1396,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "console-api"
|
||||
version = "0.5.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e"
|
||||
checksum = "8030735ecb0d128428b64cd379809817e620a40e5001c54465b99ec5feec2857"
|
||||
dependencies = [
|
||||
"prost 0.11.9",
|
||||
"futures-core",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"tonic",
|
||||
"tracing-core",
|
||||
@@ -1453,16 +1409,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "console-subscriber"
|
||||
version = "0.1.10"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb"
|
||||
checksum = "6539aa9c6a4cd31f4b1c040f860a1eac9aa80e7df6b05d506a6e7179936d6a01"
|
||||
dependencies = [
|
||||
"console-api",
|
||||
"crossbeam-channel",
|
||||
"crossbeam-utils",
|
||||
"futures",
|
||||
"futures-task",
|
||||
"hdrhistogram",
|
||||
"humantime",
|
||||
"hyper-util",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -1555,7 +1513,7 @@ version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "462e1f6a8e005acc8835d32d60cbd7973ed65ea2a8d8473830e675f050956427"
|
||||
dependencies = [
|
||||
"prost 0.13.5",
|
||||
"prost",
|
||||
"tendermint-proto",
|
||||
]
|
||||
|
||||
@@ -2028,7 +1986,7 @@ dependencies = [
|
||||
"cw-storage-plus",
|
||||
"cw-utils",
|
||||
"itertools 0.14.0",
|
||||
"prost 0.13.5",
|
||||
"prost",
|
||||
"schemars 0.8.22",
|
||||
"serde",
|
||||
"sha2 0.10.9",
|
||||
@@ -3580,6 +3538,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"h2 0.4.11",
|
||||
"http 1.3.1",
|
||||
"http-body 1.0.1",
|
||||
"httparse",
|
||||
@@ -3624,14 +3583,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper-timeout"
|
||||
version = "0.4.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
|
||||
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
|
||||
dependencies = [
|
||||
"hyper 0.14.32",
|
||||
"hyper 1.6.0",
|
||||
"hyper-util",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tokio-io-timeout",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4895,7 +4855,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||
|
||||
[[package]]
|
||||
name = "nym-api"
|
||||
version = "1.1.62"
|
||||
version = "1.1.63"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -5178,7 +5138,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli"
|
||||
version = "1.1.59"
|
||||
version = "1.1.60"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.22.1",
|
||||
@@ -5260,7 +5220,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client"
|
||||
version = "1.1.59"
|
||||
version = "1.1.60"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"clap",
|
||||
@@ -5302,6 +5262,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
"bs58",
|
||||
"cfg-if",
|
||||
"clap",
|
||||
"comfy-table",
|
||||
"futures",
|
||||
@@ -6579,7 +6540,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.60"
|
||||
version = "1.1.61"
|
||||
dependencies = [
|
||||
"addr",
|
||||
"anyhow",
|
||||
@@ -6629,7 +6590,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node"
|
||||
version = "1.15.0"
|
||||
version = "1.16.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
@@ -6642,9 +6603,11 @@ dependencies = [
|
||||
"bs58",
|
||||
"cargo_metadata 0.19.2",
|
||||
"celes",
|
||||
"cfg-if",
|
||||
"chacha",
|
||||
"clap",
|
||||
"colored",
|
||||
"console-subscriber",
|
||||
"criterion",
|
||||
"csv",
|
||||
"cupid",
|
||||
@@ -7153,7 +7116,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.59"
|
||||
version = "1.1.60"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"clap",
|
||||
@@ -7853,7 +7816,7 @@ dependencies = [
|
||||
"nym-performance-contract-common",
|
||||
"nym-serde-helpers 0.1.0",
|
||||
"nym-vesting-contract-common 0.7.0",
|
||||
"prost 0.13.5",
|
||||
"prost",
|
||||
"reqwest 0.12.22",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -7903,7 +7866,7 @@ dependencies = [
|
||||
"nym-network-defaults 0.1.0 (git+https://github.com/nymtech/nym.git?branch=release/2025.11-cheddar)",
|
||||
"nym-serde-helpers 0.1.0 (git+https://github.com/nymtech/nym.git?branch=release/2025.11-cheddar)",
|
||||
"nym-vesting-contract-common 0.7.0 (git+https://github.com/nymtech/nym.git?branch=release/2025.11-cheddar)",
|
||||
"prost 0.13.5",
|
||||
"prost",
|
||||
"reqwest 0.12.22",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -8111,7 +8074,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nymvisor"
|
||||
version = "0.1.24"
|
||||
version = "0.1.25"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -8872,16 +8835,6 @@ dependencies = [
|
||||
"thiserror 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.11.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.13.5"
|
||||
@@ -8889,20 +8842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.13.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.10.5",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8920,11 +8860,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.11.9"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13"
|
||||
checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16"
|
||||
dependencies = [
|
||||
"prost 0.11.9",
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -10839,7 +10779,7 @@ dependencies = [
|
||||
"k256",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"prost 0.13.5",
|
||||
"prost",
|
||||
"ripemd",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
@@ -10876,7 +10816,7 @@ checksum = "d2c40e13d39ca19082d8a7ed22de7595979350319833698f8b1080f29620a094"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"flex-error",
|
||||
"prost 0.13.5",
|
||||
"prost",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"subtle-encoding",
|
||||
@@ -11148,16 +11088,6 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-io-timeout"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bd86198d9ee903fedd2f9a2e72014287c0d9167e4ae43b5853007205dda1b76"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.5.0"
|
||||
@@ -11346,24 +11276,26 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.9.2"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a"
|
||||
checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"axum 0.6.20",
|
||||
"base64 0.21.7",
|
||||
"axum 0.7.9",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.3.27",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.32",
|
||||
"h2 0.4.11",
|
||||
"http 1.3.1",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"hyper 1.6.0",
|
||||
"hyper-timeout",
|
||||
"hyper-util",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost 0.11.9",
|
||||
"prost",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tower 0.4.13",
|
||||
|
||||
+5
-1
@@ -221,7 +221,7 @@ clap_complete_fig = "4.5"
|
||||
colored = "2.2"
|
||||
comfy-table = "7.1.4"
|
||||
console = "0.15.11"
|
||||
console-subscriber = "0.1.1"
|
||||
console-subscriber = "0.4.1"
|
||||
console_error_panic_hook = "0.1"
|
||||
const-str = "0.5.6"
|
||||
const_format = "0.2.34"
|
||||
@@ -438,6 +438,9 @@ opt-level = 'z'
|
||||
# lto = true
|
||||
opt-level = 'z'
|
||||
|
||||
[workspace.lints.rust]
|
||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }
|
||||
|
||||
[workspace.lints.clippy]
|
||||
unwrap_used = "deny"
|
||||
expect_used = "deny"
|
||||
@@ -447,3 +450,4 @@ exit = "deny"
|
||||
panic = "deny"
|
||||
unimplemented = "deny"
|
||||
unreachable = "deny"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.59"
|
||||
version = "1.1.60"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
|
||||
@@ -111,7 +111,7 @@ impl SocketClient {
|
||||
let dkg_query_client = if self.config.base.client.disabled_credentials_mode {
|
||||
None
|
||||
} else {
|
||||
Some(default_query_dkg_client_from_config(&self.config.base))
|
||||
Some(default_query_dkg_client_from_config(&self.config.base)?)
|
||||
};
|
||||
|
||||
let storage = self.initialise_storage().await?;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.59"
|
||||
version = "1.1.60"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||
edition = "2021"
|
||||
|
||||
@@ -13,6 +13,7 @@ async-trait = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
bs58 = { workspace = true }
|
||||
clap = { workspace = true, optional = true }
|
||||
cfg-if = { workspace = true }
|
||||
comfy-table = { workspace = true, optional = true }
|
||||
futures = { workspace = true }
|
||||
humantime = { workspace = true }
|
||||
@@ -123,3 +124,6 @@ fs-surb-storage = ["nym-client-core-surb-storage/fs-surb-storage"]
|
||||
fs-gateways-storage = ["nym-client-core-gateways-storage/fs-gateways-storage"]
|
||||
wasm = ["nym-gateway-client/wasm"]
|
||||
metrics-server = []
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -58,6 +58,7 @@ where
|
||||
Some(data) => data,
|
||||
None => {
|
||||
// SAFETY: one of those arguments must have been set
|
||||
#[allow(clippy::unwrap_used)]
|
||||
fs::read(common_args.signatures_path.unwrap())?
|
||||
}
|
||||
};
|
||||
|
||||
@@ -64,6 +64,7 @@ where
|
||||
Some(data) => data,
|
||||
None => {
|
||||
// SAFETY: one of those arguments must have been set
|
||||
#[allow(clippy::unwrap_used)]
|
||||
fs::read(common_args.credential_path.unwrap())?
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,6 +58,7 @@ where
|
||||
Some(data) => data,
|
||||
None => {
|
||||
// SAFETY: one of those arguments must have been set
|
||||
#[allow(clippy::unwrap_used)]
|
||||
fs::read(common_args.signatures_path.unwrap())?
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,6 +58,7 @@ where
|
||||
Some(data) => data,
|
||||
None => {
|
||||
// SAFETY: one of those arguments must have been set
|
||||
#[allow(clippy::unwrap_used)]
|
||||
fs::read(common_args.key_path.unwrap())?
|
||||
}
|
||||
};
|
||||
|
||||
@@ -135,9 +135,11 @@ pub enum ClientInputStatus {
|
||||
}
|
||||
|
||||
impl ClientInputStatus {
|
||||
#[allow(clippy::panic)]
|
||||
pub fn register_producer(&mut self) -> ClientInput {
|
||||
match std::mem::replace(self, ClientInputStatus::Connected) {
|
||||
ClientInputStatus::AwaitingProducer { client_input } => client_input,
|
||||
// critical failure implying misuse of software
|
||||
ClientInputStatus::Connected => panic!("producer was already registered before"),
|
||||
}
|
||||
}
|
||||
@@ -149,9 +151,11 @@ pub enum ClientOutputStatus {
|
||||
}
|
||||
|
||||
impl ClientOutputStatus {
|
||||
#[allow(clippy::panic)]
|
||||
pub fn register_consumer(&mut self) -> ClientOutput {
|
||||
match std::mem::replace(self, ClientOutputStatus::Connected) {
|
||||
ClientOutputStatus::AwaitingConsumer { client_output } => client_output,
|
||||
// critical failure implying misuse of software
|
||||
ClientOutputStatus::Connected => panic!("consumer was already registered before"),
|
||||
}
|
||||
}
|
||||
@@ -707,11 +711,14 @@ where
|
||||
})?;
|
||||
|
||||
let store_clone = mem_store.clone();
|
||||
spawn_future(async move {
|
||||
persistent_storage
|
||||
.flush_on_shutdown(store_clone, shutdown)
|
||||
.await
|
||||
});
|
||||
spawn_future!(
|
||||
async move {
|
||||
persistent_storage
|
||||
.flush_on_shutdown(store_clone, shutdown)
|
||||
.await
|
||||
},
|
||||
"PersistentReplyStorage::flush_on_shutdown"
|
||||
);
|
||||
|
||||
Ok(mem_store)
|
||||
}
|
||||
@@ -732,7 +739,7 @@ where
|
||||
let mut rng = OsRng;
|
||||
let keys = if let Some(derivation_material) = derivation_material {
|
||||
ClientKeys::from_master_key(&mut rng, &derivation_material)
|
||||
.map_err(|_| ClientCoreError::HkdfDerivationError {})?
|
||||
.map_err(|_| ClientCoreError::HkdfDerivationError)?
|
||||
} else {
|
||||
ClientKeys::generate_new(&mut rng)
|
||||
};
|
||||
|
||||
@@ -114,41 +114,32 @@ pub async fn setup_fs_gateways_storage<P: AsRef<Path>>(
|
||||
})
|
||||
}
|
||||
|
||||
pub fn create_bandwidth_controller<St: CredentialStorage>(
|
||||
config: &Config,
|
||||
storage: St,
|
||||
) -> BandwidthController<QueryHttpRpcNyxdClient, St> {
|
||||
let nyxd_url = config
|
||||
.get_validator_endpoints()
|
||||
.pop()
|
||||
.expect("No nyxd validator endpoint provided");
|
||||
|
||||
create_bandwidth_controller_with_urls(nyxd_url, storage)
|
||||
}
|
||||
|
||||
pub fn create_bandwidth_controller_with_urls<St: CredentialStorage>(
|
||||
nyxd_url: Url,
|
||||
storage: St,
|
||||
) -> BandwidthController<QueryHttpRpcNyxdClient, St> {
|
||||
let client = default_query_dkg_client(nyxd_url);
|
||||
) -> Result<BandwidthController<QueryHttpRpcNyxdClient, St>, ClientCoreError> {
|
||||
let client = default_query_dkg_client(nyxd_url)?;
|
||||
|
||||
BandwidthController::new(storage, client)
|
||||
Ok(BandwidthController::new(storage, client))
|
||||
}
|
||||
|
||||
pub fn default_query_dkg_client_from_config(config: &Config) -> QueryHttpRpcNyxdClient {
|
||||
pub fn default_query_dkg_client_from_config(
|
||||
config: &Config,
|
||||
) -> Result<QueryHttpRpcNyxdClient, ClientCoreError> {
|
||||
let nyxd_url = config
|
||||
.get_validator_endpoints()
|
||||
.pop()
|
||||
.expect("No nyxd validator endpoint provided");
|
||||
.ok_or(ClientCoreError::RpcClientMissingUrl)?;
|
||||
|
||||
default_query_dkg_client(nyxd_url)
|
||||
}
|
||||
|
||||
pub fn default_query_dkg_client(nyxd_url: Url) -> QueryHttpRpcNyxdClient {
|
||||
pub fn default_query_dkg_client(nyxd_url: Url) -> Result<QueryHttpRpcNyxdClient, ClientCoreError> {
|
||||
let details = nym_network_defaults::NymNetworkDetails::new_from_env();
|
||||
let client_config = nyxd::Config::try_from_nym_network_details(&details)
|
||||
.expect("failed to construct validator client config");
|
||||
.map_err(|source| ClientCoreError::InvalidNetworkDetails { source })?;
|
||||
// overwrite env configuration with config URLs
|
||||
|
||||
QueryHttpRpcNyxdClient::connect(client_config, nyxd_url.as_str())
|
||||
.expect("Could not construct query client")
|
||||
.map_err(|source| ClientCoreError::RpcClientCreationFailure { source })
|
||||
}
|
||||
|
||||
@@ -235,6 +235,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
||||
tokio::task::yield_now().await;
|
||||
}
|
||||
|
||||
#[allow(clippy::panic)]
|
||||
pub fn start(mut self) {
|
||||
if self.cover_traffic.disable_loop_cover_traffic_stream {
|
||||
// we should have never got here in the first place - the task should have never been created to begin with
|
||||
@@ -251,27 +252,30 @@ impl LoopCoverTrafficStream<OsRng> {
|
||||
|
||||
let mut shutdown = self.task_client.fork("select");
|
||||
|
||||
spawn_future(async move {
|
||||
debug!("Started LoopCoverTrafficStream with graceful shutdown support");
|
||||
spawn_future!(
|
||||
async move {
|
||||
debug!("Started LoopCoverTrafficStream with graceful shutdown support");
|
||||
|
||||
while !shutdown.is_shutdown() {
|
||||
tokio::select! {
|
||||
biased;
|
||||
_ = shutdown.recv() => {
|
||||
tracing::trace!("LoopCoverTrafficStream: Received shutdown");
|
||||
}
|
||||
next = self.next() => {
|
||||
if next.is_some() {
|
||||
self.on_new_message().await;
|
||||
} else {
|
||||
tracing::trace!("LoopCoverTrafficStream: Stopping since channel closed");
|
||||
break;
|
||||
while !shutdown.is_shutdown() {
|
||||
tokio::select! {
|
||||
biased;
|
||||
_ = shutdown.recv() => {
|
||||
tracing::trace!("LoopCoverTrafficStream: Received shutdown");
|
||||
}
|
||||
next = self.next() => {
|
||||
if next.is_some() {
|
||||
self.on_new_message().await;
|
||||
} else {
|
||||
tracing::trace!("LoopCoverTrafficStream: Stopping since channel closed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
shutdown.recv_timeout().await;
|
||||
tracing::debug!("LoopCoverTrafficStream: Exiting");
|
||||
})
|
||||
shutdown.recv_timeout().await;
|
||||
tracing::debug!("LoopCoverTrafficStream: Exiting");
|
||||
},
|
||||
"LoopCoverTrafficStream"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,8 @@ impl MixTrafficController {
|
||||
debug_assert!(!mix_packets.is_empty());
|
||||
|
||||
let result = if mix_packets.len() == 1 {
|
||||
// SAFETY: we just checked we have one packet
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let mix_packet = mix_packets.pop().unwrap();
|
||||
self.gateway_transceiver.send_mix_packet(mix_packet).await
|
||||
} else {
|
||||
@@ -117,51 +119,54 @@ impl MixTrafficController {
|
||||
}
|
||||
|
||||
pub fn start(mut self) {
|
||||
spawn_future(async move {
|
||||
debug!("Started MixTrafficController with graceful shutdown support");
|
||||
spawn_future!(
|
||||
async move {
|
||||
debug!("Started MixTrafficController with graceful shutdown support");
|
||||
|
||||
while !self.task_client.is_shutdown() {
|
||||
tokio::select! {
|
||||
mix_packets = self.mix_rx.recv() => match mix_packets {
|
||||
Some(mix_packets) => {
|
||||
if let Err(err) = self.on_messages(mix_packets).await {
|
||||
error!("Failed to send sphinx packet(s) to the gateway: {err}");
|
||||
if self.consecutive_gateway_failure_count == MAX_FAILURE_COUNT {
|
||||
// Disconnect from the gateway. If we should try to re-connect
|
||||
// is handled at a higher layer.
|
||||
error!("Failed to send sphinx packet to the gateway {MAX_FAILURE_COUNT} times in a row - assuming the gateway is dead");
|
||||
// Do we need to handle the embedded mixnet client case
|
||||
// separately?
|
||||
self.task_client.send_we_stopped(Box::new(ClientCoreError::GatewayFailedToForwardMessages));
|
||||
break;
|
||||
while !self.task_client.is_shutdown() {
|
||||
tokio::select! {
|
||||
mix_packets = self.mix_rx.recv() => match mix_packets {
|
||||
Some(mix_packets) => {
|
||||
if let Err(err) = self.on_messages(mix_packets).await {
|
||||
error!("Failed to send sphinx packet(s) to the gateway: {err}");
|
||||
if self.consecutive_gateway_failure_count == MAX_FAILURE_COUNT {
|
||||
// Disconnect from the gateway. If we should try to re-connect
|
||||
// is handled at a higher layer.
|
||||
error!("Failed to send sphinx packet to the gateway {MAX_FAILURE_COUNT} times in a row - assuming the gateway is dead");
|
||||
// Do we need to handle the embedded mixnet client case
|
||||
// separately?
|
||||
self.task_client.send_we_stopped(Box::new(ClientCoreError::GatewayFailedToForwardMessages));
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
tracing::trace!("MixTrafficController: Stopping since channel closed");
|
||||
break;
|
||||
}
|
||||
},
|
||||
None => {
|
||||
tracing::trace!("MixTrafficController: Stopping since channel closed");
|
||||
client_request = self.client_rx.recv() => match client_request {
|
||||
Some(client_request) => {
|
||||
match self.gateway_transceiver.send_client_request(client_request).await {
|
||||
Ok(_) => (),
|
||||
Err(e) => error!("Failed to send client request: {e}"),
|
||||
};
|
||||
},
|
||||
None => {
|
||||
tracing::trace!("MixTrafficController, client request channel closed");
|
||||
}
|
||||
},
|
||||
_ = self.task_client.recv() => {
|
||||
tracing::trace!("MixTrafficController: Received shutdown");
|
||||
break;
|
||||
}
|
||||
},
|
||||
client_request = self.client_rx.recv() => match client_request {
|
||||
Some(client_request) => {
|
||||
match self.gateway_transceiver.send_client_request(client_request).await {
|
||||
Ok(_) => (),
|
||||
Err(e) => error!("Failed to send client request: {e}"),
|
||||
};
|
||||
},
|
||||
None => {
|
||||
tracing::trace!("MixTrafficController, client request channel closed");
|
||||
}
|
||||
},
|
||||
_ = self.task_client.recv() => {
|
||||
tracing::trace!("MixTrafficController: Received shutdown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.task_client.recv_timeout().await;
|
||||
self.task_client.recv_timeout().await;
|
||||
|
||||
tracing::debug!("MixTrafficController: Exiting");
|
||||
});
|
||||
tracing::debug!("MixTrafficController: Exiting");
|
||||
},
|
||||
"MixTrafficController"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,6 +269,8 @@ pub struct MockGateway {
|
||||
}
|
||||
|
||||
impl Default for MockGateway {
|
||||
// test code
|
||||
#[allow(clippy::unwrap_used)]
|
||||
fn default() -> Self {
|
||||
MockGateway {
|
||||
dummy_identity: "3ebjp1Fb9hdcS1AR6AZihgeJiMHkB5jjJUsvqNnfQwU7"
|
||||
|
||||
+3
-1
@@ -194,10 +194,11 @@ impl ActionController {
|
||||
trace!("{frag_id} is updating its delay");
|
||||
// TODO: is it possible to solve this without either locking or temporarily removing the value?
|
||||
if let Some((pending_ack_data, queue_key)) = self.pending_acks_data.remove(&frag_id) {
|
||||
// this Action is triggered by `RetransmissionRequestListener` (for 'normal' packets)
|
||||
// SAFETY: this Action is triggered by `RetransmissionRequestListener` (for 'normal' packets)
|
||||
// or `ReplyController` (for 'reply' packets) which held the other potential
|
||||
// reference to this Arc. HOWEVER, before the Action was pushed onto the queue, the reference
|
||||
// was dropped hence this unwrap is safe.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let mut inner_data = Arc::try_unwrap(pending_ack_data).unwrap();
|
||||
inner_data.update_retransmitted(delay);
|
||||
|
||||
@@ -209,6 +210,7 @@ impl ActionController {
|
||||
}
|
||||
|
||||
// note: when the entry expires it's automatically removed from pending_acks_timers
|
||||
#[allow(clippy::panic)]
|
||||
fn handle_expired_ack_timer(&mut self, expired_ack: Expired<FragmentIdentifier>) {
|
||||
let frag_id = expired_ack.into_inner();
|
||||
|
||||
|
||||
+4
-1
@@ -120,6 +120,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::panic)]
|
||||
async fn on_input_message(&mut self, msg: InputMessage) {
|
||||
match msg {
|
||||
InputMessage::Regular {
|
||||
@@ -213,7 +214,9 @@ where
|
||||
self.handle_premade_packets(msgs, lane).await
|
||||
}
|
||||
// MessageWrappers can't be nested
|
||||
InputMessage::MessageWrapper { .. } => unimplemented!(),
|
||||
InputMessage::MessageWrapper { .. } => {
|
||||
panic!("attempted to use nested MessageWrapper")
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
+35
-20
@@ -298,29 +298,44 @@ where
|
||||
let mut sent_notification_listener = self.sent_notification_listener;
|
||||
let mut action_controller = self.action_controller;
|
||||
|
||||
spawn_future(async move {
|
||||
acknowledgement_listener.run().await;
|
||||
debug!("The acknowledgement listener has finished execution!");
|
||||
});
|
||||
spawn_future!(
|
||||
async move {
|
||||
acknowledgement_listener.run().await;
|
||||
debug!("The acknowledgement listener has finished execution!");
|
||||
},
|
||||
"AcknowledgementController::AcknowledgementListener"
|
||||
);
|
||||
|
||||
spawn_future(async move {
|
||||
input_message_listener.run().await;
|
||||
debug!("The input listener has finished execution!");
|
||||
});
|
||||
spawn_future!(
|
||||
async move {
|
||||
input_message_listener.run().await;
|
||||
debug!("The input listener has finished execution!");
|
||||
},
|
||||
"AcknowledgementController::InputMessageListener"
|
||||
);
|
||||
|
||||
spawn_future(async move {
|
||||
retransmission_request_listener.run(packet_type).await;
|
||||
debug!("The retransmission request listener has finished execution!");
|
||||
});
|
||||
spawn_future!(
|
||||
async move {
|
||||
retransmission_request_listener.run(packet_type).await;
|
||||
debug!("The retransmission request listener has finished execution!");
|
||||
},
|
||||
"AcknowledgementController::RetransmissionRequestListener"
|
||||
);
|
||||
|
||||
spawn_future(async move {
|
||||
sent_notification_listener.run().await;
|
||||
debug!("The sent notification listener has finished execution!");
|
||||
});
|
||||
spawn_future!(
|
||||
async move {
|
||||
sent_notification_listener.run().await;
|
||||
debug!("The sent notification listener has finished execution!");
|
||||
},
|
||||
"AcknowledgementController::SentNotificationListener"
|
||||
);
|
||||
|
||||
spawn_future(async move {
|
||||
action_controller.run().await;
|
||||
debug!("The controller has finished execution!");
|
||||
});
|
||||
spawn_future!(
|
||||
async move {
|
||||
action_controller.run().await;
|
||||
debug!("The controller has finished execution!");
|
||||
},
|
||||
"AcknowledgementController::ActionController"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ pub enum PreparationError {
|
||||
#[error(transparent)]
|
||||
NymTopologyError(#[from] NymTopologyError),
|
||||
|
||||
#[error("message wasn't split into any fragments!")]
|
||||
EmptyFragments,
|
||||
|
||||
#[error("message too long for a single SURB, splitting into {fragments} fragments.")]
|
||||
MessageTooLongForSingleSurb { fragments: usize },
|
||||
|
||||
@@ -320,6 +323,16 @@ where
|
||||
});
|
||||
}
|
||||
|
||||
if fragment.is_empty() {
|
||||
error!("CRITICAL FAILURE: our split message didn't result in any sendable fragments");
|
||||
return Err(SurbWrappedPreparationError {
|
||||
source: PreparationError::EmptyFragments,
|
||||
returned_surbs: Some(vec![reply_surb]),
|
||||
});
|
||||
}
|
||||
|
||||
// SAFETY: we just checked we have one fragment
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let chunk = fragment.pop().unwrap();
|
||||
let chunk_clone = chunk.clone();
|
||||
let prepared_fragment = self
|
||||
@@ -657,6 +670,7 @@ where
|
||||
.zip(reply_surbs.into_iter())
|
||||
.map(|(fragment, reply_surb)| {
|
||||
// unwrap here is fine as we know we have a valid topology
|
||||
#[allow(clippy::unwrap_used)]
|
||||
self.message_preparer
|
||||
.prepare_reply_chunk_for_sending(
|
||||
fragment,
|
||||
|
||||
@@ -224,14 +224,20 @@ impl RealMessagesController<OsRng> {
|
||||
let ack_control = self.ack_control;
|
||||
let mut reply_control = self.reply_control;
|
||||
|
||||
spawn_future(async move {
|
||||
out_queue_control.run().await;
|
||||
debug!("The out queue controller has finished execution!");
|
||||
});
|
||||
spawn_future(async move {
|
||||
reply_control.run().await;
|
||||
debug!("The reply controller has finished execution!");
|
||||
});
|
||||
spawn_future!(
|
||||
async move {
|
||||
out_queue_control.run().await;
|
||||
debug!("The out queue controller has finished execution!");
|
||||
},
|
||||
"RealMessagesController::OutQueueControl)"
|
||||
);
|
||||
spawn_future!(
|
||||
async move {
|
||||
reply_control.run().await;
|
||||
debug!("The reply controller has finished execution!");
|
||||
},
|
||||
"RealMessagesController::ReplyController"
|
||||
);
|
||||
|
||||
ack_control.start(packet_type);
|
||||
}
|
||||
|
||||
@@ -249,6 +249,8 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
// SAFETY: our topology must be valid at this point
|
||||
#[allow(clippy::expect_used)]
|
||||
(
|
||||
generate_loop_cover_packet(
|
||||
&mut self.rng,
|
||||
@@ -439,6 +441,8 @@ where
|
||||
tracing::trace!("handling real_messages: size: {}", real_messages.len());
|
||||
|
||||
self.transmission_buffer.store(&conn_id, real_messages);
|
||||
// SAFETY: we just stored the message
|
||||
#[allow(clippy::expect_used)]
|
||||
let real_next = self.pop_next_message().expect("Just stored one");
|
||||
|
||||
Poll::Ready(Some(StreamMessage::Real(Box::new(real_next))))
|
||||
@@ -487,6 +491,8 @@ where
|
||||
|
||||
// First store what we got for the given connection id
|
||||
self.transmission_buffer.store(&conn_id, real_messages);
|
||||
// SAFETY: we just stored the message
|
||||
#[allow(clippy::expect_used)]
|
||||
let real_next = self.pop_next_message().expect("we just added one");
|
||||
|
||||
Poll::Ready(Some(StreamMessage::Real(Box::new(real_next))))
|
||||
|
||||
@@ -198,6 +198,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::panic)]
|
||||
async fn disconnect_sender(&mut self) {
|
||||
let mut guard = self.inner.lock().await;
|
||||
if guard.message_sender.is_none() {
|
||||
@@ -208,6 +209,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
|
||||
guard.message_sender = None;
|
||||
}
|
||||
|
||||
#[allow(clippy::panic)]
|
||||
async fn connect_sender(&mut self, sender: ReconstructedMessagesSender) {
|
||||
let mut guard = self.inner.lock().await;
|
||||
if guard.message_sender.is_some() {
|
||||
@@ -599,14 +601,20 @@ impl<R: MessageReceiver + Clone + Send + 'static> ReceivedMessagesBufferControll
|
||||
let mut fragmented_message_receiver = self.fragmented_message_receiver;
|
||||
let mut request_receiver = self.request_receiver;
|
||||
|
||||
spawn_future(async move {
|
||||
match fragmented_message_receiver.run().await {
|
||||
Ok(_) => {}
|
||||
Err(e) => error!("{e}"),
|
||||
}
|
||||
});
|
||||
spawn_future(async move {
|
||||
request_receiver.run().await;
|
||||
});
|
||||
spawn_future!(
|
||||
async move {
|
||||
match fragmented_message_receiver.run().await {
|
||||
Ok(_) => {}
|
||||
Err(e) => error!("{e}"),
|
||||
}
|
||||
},
|
||||
"ReceivedMessagesBufferController::FragmentedMessageReceiver"
|
||||
);
|
||||
spawn_future!(
|
||||
async move {
|
||||
request_receiver.run().await;
|
||||
},
|
||||
"ReceivedMessagesBufferController::RequestReceiver"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,8 +155,9 @@ where
|
||||
data: Vec<Arc<PendingAcknowledgement>>,
|
||||
) {
|
||||
trace!("re-inserting pending retransmissions for {recipient}");
|
||||
// the underlying entry MUST exist as we've just got data from there
|
||||
// SAFETY: the underlying entry MUST exist as we've just got data from there
|
||||
// and we hold a mut reference
|
||||
#[allow(clippy::expect_used)]
|
||||
let map_entry = &mut self
|
||||
.surb_senders
|
||||
.get_mut(recipient)
|
||||
@@ -429,6 +430,7 @@ where
|
||||
.pop_at_most_n_next_messages_at_random(amount)
|
||||
}
|
||||
|
||||
#[allow(clippy::panic)]
|
||||
async fn try_clear_pending_queue(&mut self, target: AnonymousSenderTag) {
|
||||
trace!("trying to clear pending queue");
|
||||
let available_surbs = self.surbs_storage.available_surbs(&target);
|
||||
|
||||
@@ -165,9 +165,12 @@ impl StatisticsControl {
|
||||
}
|
||||
|
||||
pub(crate) fn start(mut self) {
|
||||
spawn_future(async move {
|
||||
self.run().await;
|
||||
})
|
||||
spawn_future!(
|
||||
async move {
|
||||
self.run().await;
|
||||
},
|
||||
"StatisticsControl"
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn create_and_start(
|
||||
|
||||
@@ -145,36 +145,39 @@ impl TopologyRefresher {
|
||||
}
|
||||
|
||||
pub fn start(mut self) {
|
||||
spawn_future(async move {
|
||||
debug!("Started TopologyRefresher with graceful shutdown support");
|
||||
spawn_future!(
|
||||
async move {
|
||||
debug!("Started TopologyRefresher with graceful shutdown support");
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let mut interval = tokio_stream::wrappers::IntervalStream::new(tokio::time::interval(
|
||||
self.refresh_rate,
|
||||
));
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let mut interval = tokio_stream::wrappers::IntervalStream::new(
|
||||
tokio::time::interval(self.refresh_rate),
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let mut interval =
|
||||
gloo_timers::future::IntervalStream::new(self.refresh_rate.as_millis() as u32);
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let mut interval =
|
||||
gloo_timers::future::IntervalStream::new(self.refresh_rate.as_millis() as u32);
|
||||
|
||||
// We already have an initial topology, so no need to refresh it immediately.
|
||||
// My understanding is that js setInterval does not fire immediately, so it's not
|
||||
// needed there.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
interval.next().await;
|
||||
// We already have an initial topology, so no need to refresh it immediately.
|
||||
// My understanding is that js setInterval does not fire immediately, so it's not
|
||||
// needed there.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
interval.next().await;
|
||||
|
||||
while !self.task_client.is_shutdown() {
|
||||
tokio::select! {
|
||||
_ = interval.next() => {
|
||||
self.try_refresh().await;
|
||||
},
|
||||
_ = self.task_client.recv() => {
|
||||
tracing::trace!("TopologyRefresher: Received shutdown");
|
||||
},
|
||||
while !self.task_client.is_shutdown() {
|
||||
tokio::select! {
|
||||
_ = interval.next() => {
|
||||
self.try_refresh().await;
|
||||
},
|
||||
_ = self.task_client.recv() => {
|
||||
tracing::trace!("TopologyRefresher: Received shutdown");
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
self.task_client.recv_timeout().await;
|
||||
tracing::debug!("TopologyRefresher: Exiting");
|
||||
})
|
||||
self.task_client.recv_timeout().await;
|
||||
tracing::debug!("TopologyRefresher: Exiting");
|
||||
},
|
||||
"TopologyRefresher"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ use nym_gateway_client::error::GatewayClientError;
|
||||
use nym_topology::node::RoutingNodeError;
|
||||
use nym_topology::{NodeId, NymTopologyError};
|
||||
use nym_validator_client::nym_api::error::NymAPIError;
|
||||
use nym_validator_client::nyxd::error::NyxdError;
|
||||
use nym_validator_client::ValidatorClientError;
|
||||
use rand::distributions::WeightedError;
|
||||
use std::error::Error;
|
||||
use std::path::PathBuf;
|
||||
|
||||
@@ -230,7 +232,19 @@ pub enum ClientCoreError {
|
||||
UnexpectedKeyUpgrade { gateway_id: String },
|
||||
|
||||
#[error("failed to derive keys from master key")]
|
||||
HkdfDerivationError {},
|
||||
HkdfDerivationError,
|
||||
|
||||
#[error("missing url for constructing RPC client")]
|
||||
RpcClientMissingUrl,
|
||||
|
||||
#[error("provided nym network details were malformed: {source}")]
|
||||
InvalidNetworkDetails { source: NyxdError },
|
||||
|
||||
#[error("failed to construct RPC client: {source}")]
|
||||
RpcClientCreationFailure { source: NyxdError },
|
||||
|
||||
#[error("failed to select valid gateway due to incomputable latency")]
|
||||
GatewaySelectionFailure { source: WeightedError },
|
||||
}
|
||||
|
||||
impl From<tungstenite::Error> for ClientCoreError {
|
||||
|
||||
@@ -245,7 +245,7 @@ pub async fn choose_gateway_by_latency<R: Rng, G: ConnectableGateway + Clone>(
|
||||
let gateways_with_latency = gateways_with_latency.lock().await;
|
||||
let chosen = gateways_with_latency
|
||||
.choose_weighted(rng, |item| 1. / item.latency.as_secs_f32())
|
||||
.expect("invalid selection weight!");
|
||||
.map_err(|source| ClientCoreError::GatewaySelectionFailure { source })?;
|
||||
|
||||
info!(
|
||||
"chose gateway {} with average latency of {:?}",
|
||||
|
||||
@@ -18,18 +18,54 @@ pub use nym_topology::{
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub(crate) fn spawn_future<F>(future: F)
|
||||
pub fn spawn_future<F>(future: F)
|
||||
where
|
||||
F: Future<Output = ()> + 'static,
|
||||
{
|
||||
wasm_bindgen_futures::spawn_local(future);
|
||||
}
|
||||
|
||||
// TODO: expose similar API to the rest of the codebase,
|
||||
// perhaps with some simple trait for a task to define its name
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) fn spawn_future<F>(future: F)
|
||||
#[track_caller]
|
||||
pub fn spawn_future<F>(future: F)
|
||||
where
|
||||
F: Future + Send + 'static,
|
||||
F::Output: Send + 'static,
|
||||
{
|
||||
tokio::spawn(future);
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[track_caller]
|
||||
pub fn spawn_named_future<F>(future: F, name: &str)
|
||||
where
|
||||
F: Future + Send + 'static,
|
||||
F::Output: Send + 'static,
|
||||
{
|
||||
cfg_if::cfg_if! {if #[cfg(tokio_unstable)] {
|
||||
#[allow(clippy::expect_used)]
|
||||
tokio::task::Builder::new().name(name).spawn(future).expect("failed to spawn future");
|
||||
} else {
|
||||
let _ = name;
|
||||
tracing::debug!(r#"the underlying binary hasn't been built with `RUSTFLAGS="--cfg tokio_unstable"` - the future naming won't do anything"#);
|
||||
spawn_future(future);
|
||||
}}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! spawn_future {
|
||||
($future:expr) => {{
|
||||
$crate::spawn_future($future)
|
||||
}};
|
||||
($future:expr, $name:expr) => {{
|
||||
cfg_if::cfg_if! {if #[cfg(not(target_arch = "wasm32"))] {
|
||||
$crate::spawn_named_future($future, $name)
|
||||
} else {
|
||||
let _ = $name;
|
||||
$crate::spawn_future($future)
|
||||
}}
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ where
|
||||
let dkg_query_client = if self.config.base.client.disabled_credentials_mode {
|
||||
None
|
||||
} else {
|
||||
Some(default_query_dkg_client_from_config(&self.config.base))
|
||||
Some(default_query_dkg_client_from_config(&self.config.base)?)
|
||||
};
|
||||
|
||||
let mut base_builder =
|
||||
|
||||
@@ -265,6 +265,7 @@ impl ShutdownManager {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[track_caller]
|
||||
pub fn with_shutdown<F>(mut self, shutdown: F) -> Self
|
||||
where
|
||||
F: Future<Output = ()>,
|
||||
@@ -281,6 +282,7 @@ impl ShutdownManager {
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[track_caller]
|
||||
pub fn with_shutdown_signal(self, signal_kind: SignalKind) -> std::io::Result<Self> {
|
||||
let mut sig = signal(signal_kind)?;
|
||||
Ok(self.with_shutdown(async move {
|
||||
@@ -289,6 +291,7 @@ impl ShutdownManager {
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[track_caller]
|
||||
pub fn with_interrupt_signal(self) -> Self {
|
||||
self.with_shutdown(async move {
|
||||
let _ = tokio::signal::ctrl_c().await;
|
||||
@@ -296,11 +299,13 @@ impl ShutdownManager {
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[track_caller]
|
||||
pub fn with_terminate_signal(self) -> std::io::Result<Self> {
|
||||
self.with_shutdown_signal(SignalKind::terminate())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[track_caller]
|
||||
pub fn with_quit_signal(self) -> std::io::Result<Self> {
|
||||
self.with_shutdown_signal(SignalKind::quit())
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
[package]
|
||||
name = "nym-api"
|
||||
license = "GPL-3.0"
|
||||
version = "1.1.62"
|
||||
version = "1.1.63"
|
||||
authors.workspace = true
|
||||
edition = "2021"
|
||||
rust-version.workspace = true
|
||||
|
||||
+6
-2
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-node"
|
||||
version = "1.15.0"
|
||||
version = "1.16.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
@@ -20,8 +20,10 @@ arc-swap = { workspace = true }
|
||||
bip39 = { workspace = true, features = ["zeroize"] }
|
||||
bs58.workspace = true
|
||||
bloomfilter = { workspace = true }
|
||||
celes = { workspace = true } # country codes
|
||||
celes = { workspace = true }
|
||||
cfg-if = { workspace = true }# country codes
|
||||
colored = { workspace = true }
|
||||
console-subscriber = { workspace = true, optional = true }
|
||||
csv = { workspace = true }
|
||||
clap = { workspace = true, features = ["cargo", "env"] }
|
||||
futures = { workspace = true }
|
||||
@@ -127,6 +129,8 @@ cargo_metadata = { workspace = true }
|
||||
criterion = { workspace = true, features = ["async_tokio"] }
|
||||
rand_chacha = { workspace = true }
|
||||
|
||||
[features]
|
||||
tokio-console = ["console-subscriber"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -56,7 +56,7 @@ impl Cli {
|
||||
pub(crate) fn execute(self) -> anyhow::Result<()> {
|
||||
// NOTE: `test_throughput` sets up its own logger as it has to include additional layers
|
||||
if !matches!(self.command, Commands::TestThroughput(..)) {
|
||||
setup_tracing_logger()?;
|
||||
crate::logging::setup_tracing_logger()?;
|
||||
}
|
||||
|
||||
match self.command {
|
||||
|
||||
+18
-8
@@ -5,8 +5,9 @@ use nym_bin_common::logging::{default_tracing_env_filter, default_tracing_fmt_la
|
||||
use tracing_subscriber::filter::Directive;
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
use tracing_subscriber::util::SubscriberInitExt;
|
||||
use tracing_subscriber::{EnvFilter, Layer};
|
||||
|
||||
pub(crate) fn granual_filtered_env() -> anyhow::Result<tracing_subscriber::filter::EnvFilter> {
|
||||
pub(crate) fn granual_filtered_env() -> anyhow::Result<EnvFilter> {
|
||||
fn directive_checked(directive: impl Into<String>) -> anyhow::Result<Directive> {
|
||||
directive.into().parse().map_err(From::from)
|
||||
}
|
||||
@@ -21,14 +22,23 @@ pub(crate) fn granual_filtered_env() -> anyhow::Result<tracing_subscriber::filte
|
||||
Ok(filter)
|
||||
}
|
||||
|
||||
pub(crate) fn build_tracing_logger() -> anyhow::Result<impl SubscriberExt> {
|
||||
Ok(tracing_subscriber::registry()
|
||||
.with(default_tracing_fmt_layer(std::io::stderr))
|
||||
.with(granual_filtered_env()?))
|
||||
}
|
||||
|
||||
pub(crate) fn setup_tracing_logger() -> anyhow::Result<()> {
|
||||
build_tracing_logger()?.init();
|
||||
let stderr_layer =
|
||||
default_tracing_fmt_layer(std::io::stderr).with_filter(granual_filtered_env()?);
|
||||
|
||||
cfg_if::cfg_if! {if #[cfg(feature = "tokio-console")] {
|
||||
// instrument tokio console subscriber needs RUSTFLAGS="--cfg tokio_unstable" at build time
|
||||
let console_layer = console_subscriber::spawn();
|
||||
|
||||
tracing_subscriber::registry()
|
||||
.with(console_layer)
|
||||
.with(stderr_layer)
|
||||
.init();
|
||||
} else {
|
||||
tracing_subscriber::registry()
|
||||
.with(stderr_layer)
|
||||
.init();
|
||||
}}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[package]
|
||||
name = "nym-network-requester"
|
||||
license = "GPL-3.0"
|
||||
version = "1.1.60"
|
||||
version = "1.1.61"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version = "1.70"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-cli"
|
||||
version = "1.1.59"
|
||||
version = "1.1.60"
|
||||
authors.workspace = true
|
||||
edition = "2021"
|
||||
license.workspace = true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nymvisor"
|
||||
version = "0.1.24"
|
||||
version = "0.1.25"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
Reference in New Issue
Block a user