Merge remote-tracking branch 'origin/develop' into jon/update-some-nym-prefixes

This commit is contained in:
Jon Häggblad
2024-03-26 11:39:29 +01:00
40 changed files with 754 additions and 250 deletions
+19 -10
View File
@@ -23973,10 +23973,14 @@ function getBinInfo(path) {
let mode = external_fs_.statSync(path).mode
external_fs_.chmodSync(path, mode | 0o111)
const raw = (0,external_child_process_namespaceObject.execSync)(`${path} build-info --output=json`, { stdio: 'pipe', encoding: "utf8" });
const cmd = `${path} build-info --output=json`;
console.log(`🚚 Running ${cmd}... (for max of 3 seconds, then SIGTERM)`);
const raw = (0,external_child_process_namespaceObject.execSync)(cmd, { stdio: 'pipe', encoding: "utf8", timeout: 3000 });
const parsed = JSON.parse(raw)
console.log(` ✅ ok`);
return parsed
} catch (_) {
console.log(` ❌ failed`);
return undefined
}
}
@@ -23986,8 +23990,11 @@ async function run(assets, algorithm, filename, cache) {
console.warn("cache is set to 'false', but we we no longer support it")
}
const directory = external_path_.join(process.env.RUNNER_TEMP || '.tmp', process.env.GITHUB_RUN_ID || '');
console.log('Temporary directory: ', directory);
try {
external_fs_.mkdirSync('.tmp');
external_fs_.mkdirSync(directory, { recursive: true });
} catch(e) {
// ignore
}
@@ -24002,13 +24009,13 @@ async function run(assets, algorithm, filename, cache) {
let sig = null;
// cache in `${WORKING_DIR}/.tmp/`
const cacheFilename = external_path_.resolve(`.tmp/${asset.name}`);
const cacheFilename = external_path_.join(directory, `${asset.name}`);
if(!external_fs_.existsSync(cacheFilename)) {
console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`);
console.log(`⬇️ Downloading ${asset.browser_download_url}... to ${cacheFilename} [${numAwaiting} of ${assets.length}]`);
buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer()));
external_fs_.writeFileSync(cacheFilename, buffer);
} else {
console.log(`Loading from ${cacheFilename}`);
console.log(`💾 Loading from ${cacheFilename}`);
buffer = Buffer.from(external_fs_.readFileSync(cacheFilename));
// console.log('Reading signature from content');
@@ -24093,6 +24100,7 @@ async function run(assets, algorithm, filename, cache) {
}
}
}
console.log(`Completed hashing ${assets.length} files`);
return hashes;
}
@@ -24122,8 +24130,8 @@ async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algo
let releases;
if(cache) {
const cacheFilename = external_path_.resolve(`.tmp/releases.json`);
if(!external_fs_.existsSync(cacheFilename)) {
const cacheFilename = __nccwpck_require__.ab + "releases.json";
if(!external_fs_.existsSync(__nccwpck_require__.ab + "releases.json")) {
releases = await octokit.paginate(
octokit.rest.repos.listReleases,
{
@@ -24133,10 +24141,10 @@ async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algo
},
(response) => response.data
);
external_fs_.writeFileSync(cacheFilename, JSON.stringify(releases, null, 2));
external_fs_.writeFileSync(__nccwpck_require__.ab + "releases.json", JSON.stringify(releases, null, 2));
} else {
console.log('Loading releases from cache...');
releases = JSON.parse(external_fs_.readFileSync(cacheFilename));
releases = JSON.parse(external_fs_.readFileSync(__nccwpck_require__.ab + "releases.json"));
}
} else {
releases = await octokit.paginate(
@@ -24172,9 +24180,10 @@ async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algo
releasesToProcess.forEach(release => {
const {tag_name, name} = release;
const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+\.\S+)/);
const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+(\.\S+)?)/);
if(!matches || matches.length < 2) {
console.warn('Could not match version structure in tag name = ', tag_name);
return;
}
@@ -11,10 +11,14 @@ function getBinInfo(path) {
let mode = fs.statSync(path).mode
fs.chmodSync(path, mode | 0o111)
const raw = execSync(`${path} build-info --output=json`, { stdio: 'pipe', encoding: "utf8" });
const cmd = `${path} build-info --output=json`;
console.log(`🚚 Running ${cmd}... (for max of 3 seconds, then SIGTERM)`);
const raw = execSync(cmd, { stdio: 'pipe', encoding: "utf8", timeout: 3000 });
const parsed = JSON.parse(raw)
console.log(` ✅ ok`);
return parsed
} catch (_) {
console.log(` ❌ failed`);
return undefined
}
}
@@ -24,8 +28,11 @@ async function run(assets, algorithm, filename, cache) {
console.warn("cache is set to 'false', but we we no longer support it")
}
const directory = path.join(process.env.RUNNER_TEMP || '.tmp', process.env.GITHUB_RUN_ID || '');
console.log('Temporary directory: ', directory);
try {
fs.mkdirSync('.tmp');
fs.mkdirSync(directory, { recursive: true });
} catch(e) {
// ignore
}
@@ -40,13 +47,13 @@ async function run(assets, algorithm, filename, cache) {
let sig = null;
// cache in `${WORKING_DIR}/.tmp/`
const cacheFilename = path.resolve(`.tmp/${asset.name}`);
const cacheFilename = path.join(directory, `${asset.name}`);
if(!fs.existsSync(cacheFilename)) {
console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`);
console.log(`⬇️ Downloading ${asset.browser_download_url}... to ${cacheFilename} [${numAwaiting} of ${assets.length}]`);
buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer()));
fs.writeFileSync(cacheFilename, buffer);
} else {
console.log(`Loading from ${cacheFilename}`);
console.log(`💾 Loading from ${cacheFilename}`);
buffer = Buffer.from(fs.readFileSync(cacheFilename));
// console.log('Reading signature from content');
@@ -131,6 +138,7 @@ async function run(assets, algorithm, filename, cache) {
}
}
}
console.log(`Completed hashing ${assets.length} files`);
return hashes;
}
@@ -210,9 +218,10 @@ export async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrI
releasesToProcess.forEach(release => {
const {tag_name, name} = release;
const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+\.\S+)/);
const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+(\.\S+)?)/);
if(!matches || matches.length < 2) {
console.warn('Could not match version structure in tag name = ', tag_name);
return;
}
@@ -1,6 +1,11 @@
import {createHashesFromReleaseTagOrNameOrId} from './create-hashes.mjs';
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 119065724, cache: true, upload: false});
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: '119065724', cache: true, upload: false});
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-connect-v1.1.19-snickers', cache: true, upload: false});
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'Nym Connect v1.1.19-snickers', cache: true, upload: false});
const cache = true;
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-binaries-v2024.1-marabou', cache, upload: false});
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-vpn-desktop-v0.0.8', cache, upload: false, repo: 'nym-vpn-client'});
// await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 119065724, cache: true, upload: false});
// await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: '119065724', cache: true, upload: false});
// await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-connect-v1.1.19-snickers', cache: true, upload: false});
// await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'Nym Connect v1.1.19-snickers', cache: true, upload: false});
+3 -6
View File
@@ -8,8 +8,8 @@ on:
required: true
type: string
workflow_dispatch:
release_tag:
tag:
inputs:
release_tag:
description: 'Release tag'
required: true
type: string
@@ -24,10 +24,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install packages
run: cd ./.github/actions/nym-hash-releases && npm i
- uses: ./.github/actions/nym-hash-releases
- uses: nymtech/nym/.github/actions/nym-hash-releases@develop
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Generated
+150 -75
View File
@@ -389,6 +389,16 @@ dependencies = [
"futures-core",
]
[[package]]
name = "async-file-watcher"
version = "0.1.0"
dependencies = [
"futures",
"log",
"notify",
"tokio",
]
[[package]]
name = "async-io"
version = "1.13.0"
@@ -547,9 +557,9 @@ dependencies = [
"bitflags 1.3.2",
"bytes",
"futures-util",
"http",
"http-body",
"hyper",
"http 0.2.9",
"http-body 0.4.5",
"hyper 0.14.27",
"itoa",
"matchit",
"memchr",
@@ -577,8 +587,8 @@ dependencies = [
"async-trait",
"bytes",
"futures-util",
"http",
"http-body",
"http 0.2.9",
"http-body 0.4.5",
"mime",
"rustversion",
"tower-layer",
@@ -3001,7 +3011,7 @@ dependencies = [
"futures-core",
"futures-sink",
"gloo-utils",
"http",
"http 0.2.9",
"js-sys",
"pin-project",
"serde",
@@ -3070,7 +3080,7 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-util",
"http",
"http 0.2.9",
"indexmap 1.9.3",
"slab",
"tokio",
@@ -3280,6 +3290,31 @@ dependencies = [
"itoa",
]
[[package]]
name = "http"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-api-client"
version = "0.1.0"
dependencies = [
"async-trait",
"reqwest",
"serde",
"serde_json",
"thiserror",
"tracing",
"url",
"wasmtimer",
]
[[package]]
name = "http-body"
version = "0.4.5"
@@ -3287,7 +3322,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes",
"http",
"http 0.2.9",
"pin-project-lite 0.2.13",
]
[[package]]
name = "http-body"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes",
"http 1.1.0",
]
[[package]]
name = "http-body-util"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d"
dependencies = [
"bytes",
"futures-core",
"http 1.1.0",
"http-body 1.0.0",
"pin-project-lite 0.2.13",
]
@@ -3355,8 +3413,8 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"http 0.2.9",
"http-body 0.4.5",
"httparse",
"httpdate",
"itoa",
@@ -3368,6 +3426,25 @@ dependencies = [
"want",
]
[[package]]
name = "hyper"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"httparse",
"httpdate",
"itoa",
"pin-project-lite 0.2.13",
"smallvec",
"tokio",
]
[[package]]
name = "hyper-rustls"
version = "0.24.1"
@@ -3375,8 +3452,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
dependencies = [
"futures-util",
"http",
"hyper",
"http 0.2.9",
"hyper 0.14.27",
"rustls 0.21.10",
"tokio",
"tokio-rustls 0.24.1",
@@ -3388,12 +3465,28 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
"hyper",
"hyper 0.14.27",
"pin-project-lite 0.2.13",
"tokio",
"tokio-io-timeout",
]
[[package]]
name = "hyper-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
dependencies = [
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"hyper 1.2.0",
"pin-project-lite 0.2.13",
"socket2 0.5.4",
"tokio",
]
[[package]]
name = "iana-time-zone"
version = "0.1.58"
@@ -3718,7 +3811,7 @@ dependencies = [
"curl-sys",
"event-listener",
"futures-lite",
"http",
"http 0.2.9",
"log",
"once_cell",
"polling",
@@ -3850,6 +3943,17 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "ledger"
version = "0.1.0"
dependencies = [
"bip32",
"k256",
"ledger-transport",
"ledger-transport-hid",
"thiserror",
]
[[package]]
name = "ledger-apdu"
version = "0.10.0"
@@ -4492,9 +4596,9 @@ version = "1.2.4-rc.2"
dependencies = [
"async-trait",
"futures",
"http-api-client",
"js-sys",
"nym-bin-common",
"nym-http-api-client",
"nym-ordered-buffer",
"nym-service-providers-common",
"nym-socks5-requests",
@@ -4520,7 +4624,7 @@ dependencies = [
"bytes",
"encoding_rs",
"futures-util",
"http",
"http 0.2.9",
"httparse",
"log",
"memchr",
@@ -4969,16 +5073,6 @@ dependencies = [
"ts-rs",
]
[[package]]
name = "nym-async-file-watcher"
version = "0.1.0"
dependencies = [
"futures",
"log",
"notify",
"tokio",
]
[[package]]
name = "nym-bandwidth-controller"
version = "0.1.0"
@@ -5167,7 +5261,10 @@ dependencies = [
"dirs 4.0.0",
"futures",
"gloo-timers",
"http-body-util",
"humantime-serde",
"hyper 1.2.0",
"hyper-util",
"log",
"nym-bandwidth-controller",
"nym-config",
@@ -5176,6 +5273,7 @@ dependencies = [
"nym-explorer-client",
"nym-gateway-client",
"nym-gateway-requests",
"nym-metrics",
"nym-network-defaults",
"nym-nonexhaustive-delayqueue",
"nym-pemstore",
@@ -5489,7 +5587,7 @@ dependencies = [
"dotenvy",
"futures",
"humantime-serde",
"hyper",
"hyper 0.14.27",
"ipnetwork 0.16.0",
"log",
"nym-api-requests",
@@ -5597,20 +5695,6 @@ dependencies = [
"serde",
]
[[package]]
name = "nym-http-api-client"
version = "0.1.0"
dependencies = [
"async-trait",
"reqwest",
"serde",
"serde_json",
"thiserror",
"tracing",
"url",
"wasmtimer",
]
[[package]]
name = "nym-id"
version = "0.1.0"
@@ -5700,17 +5784,6 @@ dependencies = [
"url",
]
[[package]]
name = "nym-ledger"
version = "0.1.0"
dependencies = [
"bip32",
"k256",
"ledger-transport",
"ledger-transport-hid",
"thiserror",
]
[[package]]
name = "nym-metrics"
version = "0.1.0"
@@ -5719,7 +5792,6 @@ dependencies = [
"lazy_static",
"log",
"prometheus",
"regex",
]
[[package]]
@@ -5876,6 +5948,7 @@ version = "1.1.33"
dependencies = [
"addr",
"anyhow",
"async-file-watcher",
"async-trait",
"bs58 0.5.0",
"clap 4.4.7",
@@ -5884,7 +5957,6 @@ dependencies = [
"humantime-serde",
"ipnetwork 0.20.0",
"log",
"nym-async-file-watcher",
"nym-bin-common",
"nym-client-core",
"nym-client-websocket-requests",
@@ -5950,7 +6022,7 @@ dependencies = [
"dashmap",
"fastrand 2.0.1",
"hmac 0.12.1",
"hyper",
"hyper 0.14.27",
"ipnetwork 0.16.0",
"mime",
"nym-config",
@@ -5979,10 +6051,10 @@ version = "0.1.0"
dependencies = [
"async-trait",
"base64 0.21.4",
"http-api-client",
"nym-bin-common",
"nym-crypto",
"nym-exit-policy",
"nym-http-api-client",
"nym-wireguard-types",
"schemars",
"serde",
@@ -6103,7 +6175,7 @@ dependencies = [
"dotenvy",
"futures",
"hex",
"http",
"http 0.2.9",
"httpcodec",
"libp2p",
"log",
@@ -6560,6 +6632,7 @@ dependencies = [
"eyre",
"flate2",
"futures",
"http-api-client",
"itertools 0.10.5",
"log",
"nym-api-requests",
@@ -6570,7 +6643,6 @@ dependencies = [
"nym-contracts-common",
"nym-ephemera-common",
"nym-group-contract-common",
"nym-http-api-client",
"nym-mixnet-contract-common",
"nym-multisig-contract-common",
"nym-name-service-common",
@@ -6696,6 +6768,7 @@ name = "nymvisor"
version = "0.1.0"
dependencies = [
"anyhow",
"async-file-watcher",
"bytes",
"clap 4.4.7",
"dotenvy",
@@ -6705,7 +6778,6 @@ dependencies = [
"humantime 2.1.0",
"humantime-serde",
"nix 0.27.1",
"nym-async-file-watcher",
"nym-bin-common",
"nym-config",
"nym-task",
@@ -6843,7 +6915,7 @@ checksum = "a819b71d6530c4297b49b3cae2939ab3a8cc1b9f382826a1bc29dd0ca3864906"
dependencies = [
"async-trait",
"bytes",
"http",
"http 0.2.9",
"isahc",
"opentelemetry_api",
]
@@ -6857,7 +6929,7 @@ dependencies = [
"async-trait",
"futures",
"futures-executor",
"http",
"http 0.2.9",
"isahc",
"once_cell",
"opentelemetry",
@@ -8038,9 +8110,9 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"http 0.2.9",
"http-body 0.4.5",
"hyper 0.14.27",
"hyper-rustls",
"ipnet",
"js-sys",
@@ -8199,7 +8271,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69"
dependencies = [
"http",
"http 0.2.9",
"log",
"regex",
"rocket",
@@ -8219,8 +8291,8 @@ dependencies = [
"cookie",
"either",
"futures",
"http",
"hyper",
"http 0.2.9",
"hyper 0.14.27",
"indexmap 2.0.2",
"log",
"memchr",
@@ -9024,9 +9096,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.1"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "snafu"
@@ -9875,7 +9947,10 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
dependencies = [
"futures-util",
"log",
"rustls 0.21.10",
"rustls-native-certs",
"tokio",
"tokio-rustls 0.24.1",
"tungstenite",
]
@@ -9978,9 +10053,9 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"http 0.2.9",
"http-body 0.4.5",
"hyper 0.14.27",
"hyper-timeout",
"percent-encoding",
"pin-project",
@@ -10023,8 +10098,8 @@ dependencies = [
"bytes",
"futures-core",
"futures-util",
"http",
"http-body",
"http 0.2.9",
"http-body 0.4.5",
"http-range-header",
"httpdate",
"mime",
@@ -10302,7 +10377,7 @@ dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http",
"http 0.2.9",
"httparse",
"log",
"rand 0.8.5",
+1 -1
View File
@@ -172,7 +172,7 @@ log = "0.4"
once_cell = "1.7.2"
parking_lot = "0.12.1"
rand = "0.8.5"
reqwest = { version = "0.11.22", default_features = false }
reqwest = { version = "0.11.22", default-features = false }
schemars = "0.8.1"
serde = "1.0.152"
serde_json = "1.0.91"
+22 -3
View File
@@ -27,7 +27,7 @@ tap = "1.0.1"
thiserror = { workspace = true }
url = { workspace = true, features = ["serde"] }
tungstenite = { workspace = true, default-features = false }
tokio = { workspace = true, features = ["macros"]}
tokio = { workspace = true, features = ["macros"] }
time = "0.3.17"
zeroize = { workspace = true }
@@ -38,6 +38,7 @@ nym-crypto = { path = "../crypto" }
nym-explorer-client = { path = "../../explorer-api/explorer-client" }
nym-gateway-client = { path = "../client-libs/gateway-client" }
nym-gateway-requests = { path = "../../gateway/gateway-requests" }
nym-metrics = { path = "../nym-metrics" }
nym-nonexhaustive-delayqueue = { path = "../nonexhaustive-delayqueue" }
nym-sphinx = { path = "../nymsphinx" }
nym-pemstore = { path = "../pemstore" }
@@ -48,6 +49,19 @@ nym-credential-storage = { path = "../credential-storage" }
nym-network-defaults = { path = "../network-defaults" }
si-scale = "0.2.2"
### For serving prometheus metrics
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper]
version = "1"
features = ["server", "http1"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.http-body-util]
version = "0.1"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper-util]
version = "0.1"
features = ["tokio"]
###
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream]
version = "0.1.11"
features = ["time"]
@@ -58,6 +72,7 @@ features = ["time"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-tungstenite]
version = "0.20.1"
features = ["rustls-tls-native-roots"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
workspace = true
@@ -91,11 +106,15 @@ tempfile = "3.1.0"
[build-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
sqlx = { workspace = true, features = [
"runtime-tokio-rustls",
"sqlite",
"macros",
"migrate",
] }
[features]
default = []
cli = ["clap"]
fs-surb-storage = ["sqlx"]
wasm = ["nym-gateway-client/wasm"]
@@ -300,7 +300,7 @@ impl KeyManager {
/// Gets an atomically reference counted pointer to [`SharedKey`].
pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> {
self.gateway_shared_key.as_ref().map(Arc::clone)
self.gateway_shared_key.clone()
}
pub fn remove_gateway_key(self) -> KeyManagerBuilder {
@@ -3,8 +3,30 @@ use std::{
time::{Duration, Instant},
};
use log::{info, warn};
use nym_metrics::{inc, inc_by, metrics};
use si_scale::helpers::bibytes2;
// Metrics server
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use http_body_util::Full;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper::body::Bytes;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper::server::conn::http1;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper::service::service_fn;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper::{Request, Response};
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper_util::rt::TokioIo;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use std::convert::Infallible;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use std::net::SocketAddr;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use tokio::net::TcpListener;
use crate::spawn_future;
// Time interval between reporting packet statistics
@@ -53,42 +75,60 @@ impl PacketStatistics {
PacketStatisticsEvent::RealPacketSent(packet_size) => {
self.real_packets_sent += 1;
self.real_packets_sent_size += packet_size;
inc!("real_packets_sent");
inc_by!("real_packets_sent_size", packet_size);
}
PacketStatisticsEvent::CoverPacketSent(packet_size) => {
self.cover_packets_sent += 1;
self.cover_packets_sent_size += packet_size;
inc!("cover_packets_sent");
inc_by!("cover_packets_sent_size", packet_size);
}
PacketStatisticsEvent::RealPacketReceived(packet_size) => {
self.real_packets_received += 1;
self.real_packets_received_size += packet_size;
inc!("real_packets_received");
inc_by!("real_packets_received_size", packet_size);
}
PacketStatisticsEvent::CoverPacketReceived(packet_size) => {
self.cover_packets_received += 1;
self.cover_packets_received_size += packet_size;
inc!("cover_packets_received");
inc_by!("cover_packets_received_size", packet_size);
}
PacketStatisticsEvent::AckReceived(packet_size) => {
self.total_acks_received += 1;
self.total_acks_received_size += packet_size;
inc!("total_acks_received");
inc_by!("total_acks_received_size", packet_size);
}
PacketStatisticsEvent::RealAckReceived(packet_size) => {
self.real_acks_received += 1;
self.real_acks_received_size += packet_size;
inc!("real_acks_received");
inc_by!("real_acks_received_size", packet_size);
}
PacketStatisticsEvent::CoverAckReceived(packet_size) => {
self.cover_acks_received += 1;
self.cover_acks_received_size += packet_size;
inc!("cover_acks_received");
inc_by!("cover_acks_received_size", packet_size);
}
PacketStatisticsEvent::RealPacketQueued => {
self.real_packets_queued += 1;
inc!("real_packets_queued");
}
PacketStatisticsEvent::RetransmissionQueued => {
self.retransmissions_queued += 1;
inc!("retransmissions_queued");
}
PacketStatisticsEvent::ReplySurbRequestQueued => {
self.reply_surbs_queued += 1;
inc!("reply_surbs_queued");
}
PacketStatisticsEvent::AdditionalReplySurbRequestQueued => {
self.additional_reply_surbs_queued += 1;
inc!("additional_reply_surbs_queued");
}
}
}
@@ -465,6 +505,33 @@ impl PacketStatisticsControl {
let snapshot_interval = Duration::from_millis(SNAPSHOT_INTERVAL_MS);
let mut snapshot_interval = tokio::time::interval(snapshot_interval);
cfg_if::cfg_if! {
if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] {
log::warn!("Metrics server is not supported on wasm32-unknown-unknown");
let listener = None;
} else {
let mut metrics_port = 18000;
let listener: Option<TcpListener>;
loop {
let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port));
match TcpListener::bind(addr).await {
Ok(l) => {
info!("###############################");
info!("Metrics endpoint is at: {:?}", l.local_addr());
info!("###############################");
listener = Some(l);
break;
},
Err(err) => {
log::warn!("Failed to bind metrics server: {:?}", err);
metrics_port += 1;
}
};
}
}
}
loop {
tokio::select! {
stats_event = self.stats_rx.recv() => match stats_event {
@@ -477,6 +544,27 @@ impl PacketStatisticsControl {
break;
}
},
// conditional will disable the branch if we're in wasm32-unknown-unknown
result = listener.as_ref().unwrap().accept(), if listener.is_some() => {
cfg_if::cfg_if! {
if #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] {
if let Ok((stream, _)) = result {
let io = TokioIo::new(stream);
tokio::task::spawn(async move {
if let Err(err) = http1::Builder::new()
.serve_connection(io, service_fn(serve_metrics))
.await
{
warn!("Error serving connection: {:?}", err);
}
});
} else {
warn!("Error accepting connection");
}
}
}
}
_ = snapshot_interval.tick() => {
self.update_history();
self.update_rates();
@@ -501,3 +589,9 @@ impl PacketStatisticsControl {
})
}
}
async fn serve_metrics(
_: Request<hyper::body::Incoming>,
) -> Result<Response<Full<Bytes>>, Infallible> {
Ok(Response::new(Full::new(Bytes::from(metrics!()))))
}
@@ -49,6 +49,7 @@ workspace = true
# the choice of this particular tls feature was arbitrary;
# if you reckon a different one would be more appropriate, feel free to change it
# features = ["native-tls"]
features = ["rustls-tls-native-roots"]
# wasm-only dependencies
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen]
@@ -69,6 +69,10 @@ impl PacketRouter {
}
Ok(())
}
pub fn mark_as_success(&mut self) {
self.shutdown.mark_as_success();
}
}
impl GatewayPacketRouter for PacketRouter {
@@ -44,9 +44,7 @@ pub(crate) fn ws_fd(_conn: &WsConn) -> Option<RawFd> {
#[cfg(unix)]
match _conn.get_ref() {
MaybeTlsStream::Plain(stream) => Some(stream.as_raw_fd()),
&_ => unreachable!(
"If tls features are enabled, the inner stream needs to be unpacked into raw fd"
),
&_ => None,
}
#[cfg(not(unix))]
None
@@ -99,7 +97,7 @@ impl PartiallyDelegated {
pub(crate) fn split_and_listen_for_mixnet_messages(
conn: WsConn,
packet_router: PacketRouter,
mut packet_router: PacketRouter,
shared_key: Arc<SharedKeys>,
mut shutdown: TaskClient,
) -> Self {
@@ -142,6 +140,7 @@ impl PartiallyDelegated {
if match ret_err {
Err(err) => stream_sender.send(Err(err)),
Ok(_) => {
packet_router.mark_as_success();
shutdown.mark_as_success();
stream_sender.send(Ok(stream))
}
+1 -1
View File
@@ -837,7 +837,7 @@ mod tests {
let share3 = chunks3.clone().try_into().unwrap();
let shares = vec![share1, share2, share3];
let chunks = vec![chunks1, chunks2, chunks3];
let chunks = &[chunks1, chunks2, chunks3];
for (i, pk_i) in pks.iter().enumerate() {
let mut ciphertext_chunk_i = Vec::with_capacity(NUM_CHUNKS);
+8 -1
View File
@@ -34,6 +34,13 @@ impl MultiIpPacketCodec {
}
}
pub fn bundle_one_packet(packet: Bytes) -> Bytes {
let mut bundled_packets = BytesMut::new();
bundled_packets.extend_from_slice(&(packet.len() as u16).to_be_bytes());
bundled_packets.extend_from_slice(&packet);
bundled_packets.freeze()
}
// Append a packet to the buffer and return the buffer if it's full
pub fn append_packet(&mut self, packet: Bytes) -> Option<Bytes> {
let mut bundled_packets = BytesMut::new();
@@ -47,7 +54,7 @@ impl MultiIpPacketCodec {
}
// Flush the current buffer and return it.
fn flush_current_buffer(&mut self) -> Bytes {
pub fn flush_current_buffer(&mut self) -> Bytes {
let mut output_buffer = BytesMut::new();
std::mem::swap(&mut output_buffer, &mut self.buffer);
output_buffer.freeze()
+2 -1
View File
@@ -9,7 +9,8 @@ pub mod response;
// version 3: initial version
// version 4: IPv6 support
// version 5: Add severity level to info response
pub const CURRENT_VERSION: u8 = 5;
// version 6: Increase the available IPs
pub const CURRENT_VERSION: u8 = 6;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct IpPair {
+15 -22
View File
@@ -79,7 +79,13 @@ impl NymNetworkDetails {
pub fn new_from_env() -> Self {
fn get_optional_env<K: AsRef<OsStr>>(env: K) -> Option<String> {
match var(env) {
Ok(var) => Some(var),
Ok(var) => {
if var.is_empty() {
None
} else {
Some(var)
}
}
Err(VarError::NotPresent) => None,
err => panic!("Unable to set: {:?}", err),
}
@@ -113,28 +119,15 @@ impl NymNetworkDetails {
Some(var(var_names::NYM_API).expect("nym api not set")),
get_optional_env(var_names::NYXD_WEBSOCKET),
))
.with_mixnet_contract(Some(
var(var_names::MIXNET_CONTRACT_ADDRESS).expect("mixnet contract not set"),
))
.with_vesting_contract(Some(
var(var_names::VESTING_CONTRACT_ADDRESS).expect("vesting contract not set"),
))
.with_coconut_bandwidth_contract(Some(
var(var_names::COCONUT_BANDWIDTH_CONTRACT_ADDRESS)
.expect("coconut bandwidth contract not set"),
))
.with_group_contract(Some(
var(var_names::GROUP_CONTRACT_ADDRESS).expect("group contract not set"),
))
.with_multisig_contract(Some(
var(var_names::MULTISIG_CONTRACT_ADDRESS).expect("multisig contract not set"),
))
.with_coconut_dkg_contract(Some(
var(var_names::COCONUT_DKG_CONTRACT_ADDRESS).expect("coconut dkg contract not set"),
))
.with_ephemera_contract(Some(
var(var_names::EPHEMERA_CONTRACT_ADDRESS).expect("ephemera contract not set"),
.with_mixnet_contract(get_optional_env(var_names::MIXNET_CONTRACT_ADDRESS))
.with_vesting_contract(get_optional_env(var_names::VESTING_CONTRACT_ADDRESS))
.with_coconut_bandwidth_contract(get_optional_env(
var_names::COCONUT_BANDWIDTH_CONTRACT_ADDRESS,
))
.with_group_contract(get_optional_env(var_names::GROUP_CONTRACT_ADDRESS))
.with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS))
.with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS))
.with_ephemera_contract(get_optional_env(var_names::EPHEMERA_CONTRACT_ADDRESS))
.with_service_provider_directory_contract(get_optional_env(
var_names::SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS,
))
+7 -5
View File
@@ -16,11 +16,13 @@ pub const MIXNET_CONTRACT_ADDRESS: &str =
"n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr";
pub const VESTING_CONTRACT_ADDRESS: &str =
"n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw";
pub const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
pub const GROUP_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
pub const MULTISIG_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
pub const EPHEMERA_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
pub const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = "";
pub const GROUP_CONTRACT_ADDRESS: &str = "";
pub const MULTISIG_CONTRACT_ADDRESS: &str = "";
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "";
pub const EPHEMERA_CONTRACT_ADDRESS: &str = "";
pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy";
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/";
-1
View File
@@ -14,5 +14,4 @@ license.workspace = true
prometheus = { workspace = true }
log = { workspace = true }
dashmap = { workspace = true }
regex = "1.1"
lazy_static = "1.4"
+111 -13
View File
@@ -1,12 +1,47 @@
use dashmap::DashMap;
pub use log::error;
use log::{debug, warn};
use regex::Regex;
use std::fmt;
pub use std::time::Instant;
use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder};
#[macro_export]
macro_rules! prepend_package_name {
($name: literal) => {
&format!(
"{}_{}",
std::module_path!()
.split("::")
.next()
.unwrap_or("x")
.to_string(),
$name
)
};
}
#[macro_export]
macro_rules! inc_by {
($name:literal, $x:expr) => {
$crate::REGISTRY.inc_by($crate::prepend_package_name!($name), $x as f64);
};
}
#[macro_export]
macro_rules! inc {
($name:literal) => {
$crate::REGISTRY.inc($crate::prepend_package_name!($name));
};
}
#[macro_export]
macro_rules! metrics {
() => {
$crate::REGISTRY.to_string();
};
}
#[macro_export]
macro_rules! nanos {
( $name:literal, $x:expr ) => {{
@@ -14,13 +49,13 @@ macro_rules! nanos {
// if the block needs to return something, we can return it
let r = $x;
let duration = start.elapsed().as_nanos() as f64;
let name = $crate::prepend_package_name!($name);
$crate::REGISTRY.inc_by(&format!("{}_nanos", $name), duration);
r
}};
}
lazy_static::lazy_static! {
pub static ref RE: Regex = Regex::new(r"[^a-zA-Z0-9_]").unwrap();
pub static ref REGISTRY: MetricsController = MetricsController::default();
}
@@ -43,6 +78,7 @@ fn fq_name(c: &dyn Collector) -> String {
}
impl Metric {
#[inline(always)]
fn fq_name(&self) -> String {
match self {
Metric::C(c) => fq_name(c.as_ref()),
@@ -50,6 +86,15 @@ impl Metric {
}
}
#[inline(always)]
fn inc(&self) {
match self {
Metric::C(c) => c.inc(),
Metric::G(g) => g.inc(),
}
}
#[inline(always)]
fn inc_by(&self, value: f64) {
match self {
Metric::C(c) => c.inc_by(value),
@@ -57,6 +102,7 @@ impl Metric {
}
}
#[inline(always)]
fn set(&self, value: f64) {
match self {
Metric::C(_c) => {
@@ -69,14 +115,8 @@ impl Metric {
impl fmt::Display for MetricsController {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut buffer = vec![];
let encoder = TextEncoder::new();
let metrics = self.registry.gather();
match encoder.encode(&metrics, &mut buffer) {
Ok(_) => {}
Err(e) => return write!(f, "Error encoding metrics to buffer: {}", e),
}
let output = match String::from_utf8(buffer) {
let metrics = self.gather();
let output = match String::from_utf8(metrics) {
Ok(output) => output,
Err(e) => return write!(f, "Error decoding metrics to String: {}", e),
};
@@ -85,6 +125,26 @@ impl fmt::Display for MetricsController {
}
impl MetricsController {
#[inline(always)]
pub fn gather(&self) -> Vec<u8> {
let mut buffer = vec![];
let encoder = TextEncoder::new();
let metrics = self.registry.gather();
match encoder.encode(&metrics, &mut buffer) {
Ok(_) => {}
Err(e) => error!("Error encoding metrics to buffer: {}", e),
}
buffer
}
pub fn to_writer(&self, writer: &mut dyn std::io::Write) {
let metrics = self.gather();
match writer.write_all(&metrics) {
Ok(_) => {}
Err(e) => error!("Error writing metrics to writer: {}", e),
}
}
pub fn set(&self, name: &str, value: f64) {
if let Some(metric) = self.registry_index.get(name) {
metric.set(value);
@@ -101,6 +161,22 @@ impl MetricsController {
}
}
pub fn inc(&self, name: &str) {
if let Some(metric) = self.registry_index.get(name) {
metric.inc();
} else {
let counter = match Counter::new(sanitize_metric_name(name), name) {
Ok(c) => c,
Err(e) => {
debug!("Failed to create counter {:?}:\n{}", name, e);
return;
}
};
self.register_counter(Box::new(counter));
self.inc(name)
}
}
pub fn inc_by(&self, name: &str, value: f64) {
if let Some(metric) = self.registry_index.get(name) {
metric.inc_by(value);
@@ -161,9 +237,31 @@ impl MetricsController {
}
}
#[inline(always)]
fn sanitize_metric_name(name: &str) -> String {
RE.replace_all(name, "_").to_string()
// The first character must be [a-zA-Z_:], and all subsequent characters must be [a-zA-Z0-9_:].
let mut out = String::with_capacity(name.len());
let mut is_invalid: fn(char) -> bool = invalid_metric_name_start_character;
for c in name.chars() {
if is_invalid(c) {
out.push('_');
} else {
out.push(c);
}
is_invalid = invalid_metric_name_character;
}
out
}
#[inline]
fn invalid_metric_name_start_character(c: char) -> bool {
// Essentially, needs to match the regex pattern of [a-zA-Z_:].
!(c.is_ascii_alphabetic() || c == '_' || c == ':')
}
#[inline]
fn invalid_metric_name_character(c: char) -> bool {
// Essentially, needs to match the regex pattern of [a-zA-Z0-9_:].
!(c.is_ascii_alphanumeric() || c == '_' || c == ':')
}
#[cfg(test)]
@@ -174,7 +272,7 @@ mod tests {
fn test_sanitization() {
assert_eq!(
sanitize_metric_name("packets_sent_34.242.65.133:1789"),
"packets_sent_34_242_65_133_1789"
"packets_sent_34_242_65_133:1789"
)
}
}
+16 -13
View File
@@ -18,7 +18,7 @@
},
"devDependencies": {
"@tsconfig/recommended": "^1.0.1",
"prettier": "^2.2.1",
"prettier": "^2.8.7",
"typescript": "^4.1.3"
}
},
@@ -570,9 +570,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
@@ -875,15 +875,18 @@
}
},
"node_modules/prettier": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
"integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/protobufjs": {
@@ -1664,9 +1667,9 @@
}
},
"follow-redirects": {
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
},
"fsevents": {
"version": "2.3.2",
@@ -1885,9 +1888,9 @@
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw=="
},
"prettier": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
"integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true
},
"protobufjs": {
@@ -682,6 +682,8 @@ Which should return:
Proxying various full node services through port 80 can then be done by creating a file with the following at `/etc/nginx/sites-enabled/nyxd-webrequests.conf`:
Setting up a reverse proxy using a webserver such as Nginx allows you to easily configure SSL certificates for the endpoints. When running on mainnet, it is recommended to encrypt all web traffic to your node.
```sh
### To expose RPC server
server {
@@ -695,6 +697,14 @@ server {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /websocket {
proxy_pass http://127.0.0.1:26657;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
}
### To expose Cosmos API server
@@ -2,10 +2,6 @@
[//]: # (> The nym-api binary was built in the [building nym]&#40;../binaries/building-nym.md&#41; section. If you haven't yet built Nym and want to run the code, go there first. You can build just the API with `cargo build --release --bin nym-api`.)
> The `nym-api` binary will be released in the immediate future - we're releasing this document beforehand so that validators have information as soon as possible and get an idea of what to expect. This doc will be expanded over time as we release the API binary itself as well as start enabling functionality.
>
> You can build the API with `cargo build --release --bin nym-api`.
> Any syntax in `<>` brackets is a user's unique variable. Exchange with a corresponding name without the `<>` brackets.
## What is the Nym API?
-2
View File
@@ -22,5 +22,3 @@ REWARDING_VALIDATOR_ADDRESS=n1tfzd4qz3a45u8p4mr5zmzv66457uwjgcl05jdq
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
NYXD="http://127.0.0.1:26657"
NYM_API="http://127.0.0.1:8000"
DKG_TIME_CONFIGURATION="600,300,300,60,60,1209600"
+2 -7
View File
@@ -11,18 +11,13 @@ MIX_DENOM_DISPLAY=nym
STAKE_DENOM=unyx
STAKE_DENOM_DISPLAY=nyx
DENOMS_EXPONENT=6
MIXNET_CONTRACT_ADDRESS=n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr
VESTING_CONTRACT_ADDRESS=n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw
COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
GROUP_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m
MULTISIG_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
COCONUT_DKG_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
EPHEMERA_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
REWARDING_VALIDATOR_ADDRESS=n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy
STATISTICS_SERVICE_DOMAIN_ADDRESS="https://mainnet-stats.nymte.ch:8090"
NYXD="https://rpc.nymtech.net"
NYM_API="https://validator.nymtech.net/api/"
NYXD_WS="wss://rpc.nymtech.net/websocket"
EXPLORER_API="https://explorer.nymtech.net/api/"
DKG_TIME_CONFIGURATION="259200,300,300,60,60,1209600"
-1
View File
@@ -25,5 +25,4 @@ EXPLORER_API=https://qa-network-explorer.qa.nymte.ch/api
NYXD="https://qa-validator.qa.nymte.ch"
NYM_API="https://qa-nym-api.qa.nymte.ch/api"
DKG_TIME_CONFIGURATION="600,300,300,60,60,1209600"
EXIT_POLICY="https://nymtech.net/.wellknown/network-requester/exit-policy.txt"
@@ -92,6 +92,9 @@ pub(crate) enum RequestHandlingError {
#[error("the provided credential did not have a bandwidth attribute")]
MissingBandwidthAttribute,
#[error("the DKG contract is unavailable")]
UnavailableDkgContract,
}
impl RequestHandlingError {
@@ -600,7 +603,7 @@ where
None => break,
Some(Ok(socket_msg)) => socket_msg,
Some(Err(err)) => {
error!("failed to obtain message from websocket stream! stopping connection handler: {err}");
debug!("failed to obtain message from websocket stream! stopping connection handler: {err}");
break;
}
};
@@ -611,7 +614,7 @@ where
if let Some(response) = self.handle_request(socket_msg).await {
if let Err(err) = self.inner.send_websocket_message(response).await {
warn!(
debug!(
"Failed to send message over websocket: {err}. Assuming the connection is dead.",
);
break;
@@ -621,13 +624,13 @@ where
mix_messages = self.mix_receiver.next() => {
let mix_messages = match mix_messages {
None => {
warn!("mix receiver was closed! Assuming the connection is dead.");
debug!("mix receiver was closed! Assuming the connection is dead.");
break;
}
Some(mix_messages) => mix_messages,
};
if let Err(err) = self.inner.push_packets_to_client(&self.client.shared_keys, mix_messages).await {
warn!("failed to send the unwrapped sphinx packets back to the client - {err}, assuming the connection is dead");
debug!("failed to send the unwrapped sphinx packets back to the client - {err}, assuming the connection is dead");
break;
}
}
@@ -36,6 +36,7 @@ pub(crate) struct CoconutVerifier {
impl CoconutVerifier {
pub async fn new(
nyxd_client: DirectSigningHttpRpcNyxdClient,
only_coconut_credentials: bool,
) -> Result<Self, RequestHandlingError> {
let mix_denom_base = nyxd_client.current_chain_details().mix_denom.base.clone();
let address = nyxd_client.address();
@@ -45,9 +46,17 @@ impl CoconutVerifier {
// don't make it a hard failure in case we're running on mainnet (where DKG hasn't been deployed yet)
if nyxd_client.dkg_contract_address().is_none() {
error!(
"DKG contract address is not available - no coconut credentials will be redeemable"
);
if !only_coconut_credentials {
warn!(
"the DKG contract address is not available - \
no coconut credentials will be redeemable \
(if the DKG ceremony hasn't been run yet this warning is expected)"
);
} else {
// if we require coconut credentials, we MUST have DKG contract available
return Err(RequestHandlingError::UnavailableDkgContract);
}
return Ok(CoconutVerifier {
address,
nyxd_client: RwLock::new(nyxd_client),
@@ -60,6 +69,10 @@ impl CoconutVerifier {
let Ok(current_epoch) = nyxd_client.get_current_epoch().await else {
// another case of somebody putting a placeholder address that doesn't exist
error!("the specified DKG contract address is invalid - no coconut credentials will be redeemable");
if only_coconut_credentials {
// if we require coconut credentials, we MUST have DKG contract available
return Err(RequestHandlingError::UnavailableDkgContract);
}
return Ok(CoconutVerifier {
address,
nyxd_client: RwLock::new(nyxd_client),
@@ -667,7 +667,7 @@ where
let msg = match msg {
Ok(msg) => msg,
Err(err) => {
error!("failed to obtain message from websocket stream! stopping connection handler: {err}");
debug!("failed to obtain message from websocket stream! stopping connection handler: {err}");
break;
}
};
@@ -723,7 +723,7 @@ where
Message::Binary(_) => {
// perhaps logging level should be reduced here, let's leave it for now and see what happens
// if client is working correctly, this should have never happened
warn!("possibly received a sphinx packet without prior authentication. Request is going to be ignored");
debug!("possibly received a sphinx packet without prior authentication. Request is going to be ignored");
if let Err(err) = self
.send_websocket_message(
ServerResponse::new_error(
+1 -1
View File
@@ -447,7 +447,7 @@ impl<St> Gateway<St> {
let coconut_verifier = {
let nyxd_client = self.random_nyxd_client()?;
CoconutVerifier::new(nyxd_client).await
CoconutVerifier::new(nyxd_client, self.config.gateway.only_coconut_credentials).await
}?;
let mix_forwarding_channel =
+3 -3
View File
@@ -7,7 +7,7 @@ use axum::{
extract::{Query, State},
http::HeaderMap,
};
use nym_metrics::REGISTRY;
use nym_metrics::metrics;
use nym_node::http::api::{FormattedResponse, Output};
use serde::{Deserialize, Serialize};
@@ -24,7 +24,7 @@ pub(crate) async fn metrics(State(state): State<MixnodeAppState>, headers: Heade
if let Some(metrics_key) = state.metrics_key {
if let Some(auth) = headers.get("Authorization") {
if auth.to_str().unwrap_or_default() == format!("Bearer {}", metrics_key) {
REGISTRY.to_string()
metrics!()
} else {
"Unauthorized".to_string()
}
@@ -50,7 +50,7 @@ pub(crate) async fn stats(
async fn generate_stats(full: bool, stats: SharedNodeStats) -> NodeStatsResponse {
let snapshot_data = stats.clone_data().await;
if full {
NodeStatsResponse::Full(REGISTRY.to_string())
NodeStatsResponse::Full(metrics!())
} else {
NodeStatsResponse::Simple(snapshot_data.simplify())
}
+10 -6
View File
@@ -1,7 +1,7 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use nym_metrics::REGISTRY;
use nym_metrics::inc_by;
use super::TaskClient;
use futures::channel::mpsc;
@@ -65,11 +65,14 @@ impl SharedNodeStats {
guard.packets_dropped_since_startup_all += count;
}
REGISTRY.inc_by("packets_received_since_startup", new_received);
REGISTRY.inc_by("packets_sent_since_startup_all", new_sent.values().sum());
REGISTRY.inc_by(
inc_by!("packets_received_since_startup", new_received);
inc_by!(
"packets_sent_since_startup_all",
new_sent.values().sum::<f64>()
);
inc_by!(
"packets_dropped_since_startup_all",
new_dropped.values().sum(),
new_dropped.values().sum::<f64>()
);
guard.packets_received_since_last_update = new_received;
@@ -509,6 +512,7 @@ impl Controller {
#[cfg(test)]
mod tests {
use super::*;
use nym_metrics::metrics;
use nym_task::TaskManager;
#[tokio::test]
@@ -538,6 +542,6 @@ mod tests {
assert_eq!(&stats.packets_sent_since_last_update.len(), &1);
assert_eq!(&stats.packets_received_since_startup, &0.);
assert_eq!(&stats.packets_dropped_since_startup_all, &0.);
assert_eq!(REGISTRY.to_string(), "# HELP packets_dropped_since_startup_all packets_dropped_since_startup_all\n# TYPE packets_dropped_since_startup_all counter\npackets_dropped_since_startup_all 0\n# HELP packets_received_since_startup packets_received_since_startup\n# TYPE packets_received_since_startup counter\npackets_received_since_startup 0\n# HELP packets_sent_since_startup_all packets_sent_since_startup_all\n# TYPE packets_sent_since_startup_all counter\npackets_sent_since_startup_all 2\n")
assert_eq!(metrics!(), "# HELP nym_mixnode_packets_dropped_since_startup_all nym_mixnode_packets_dropped_since_startup_all\n# TYPE nym_mixnode_packets_dropped_since_startup_all counter\nnym_mixnode_packets_dropped_since_startup_all 0\n# HELP nym_mixnode_packets_received_since_startup nym_mixnode_packets_received_since_startup\n# TYPE nym_mixnode_packets_received_since_startup counter\nnym_mixnode_packets_received_since_startup 0\n# HELP nym_mixnode_packets_sent_since_startup_all nym_mixnode_packets_sent_since_startup_all\n# TYPE nym_mixnode_packets_sent_since_startup_all counter\nnym_mixnode_packets_sent_since_startup_all 2\n")
}
}
+6 -6
View File
@@ -2555,9 +2555,9 @@
"integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ=="
},
"node_modules/follow-redirects": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
@@ -6845,9 +6845,9 @@
"integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ=="
},
"follow-redirects": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
},
"form-data": {
"version": "4.0.0",
+3 -3
View File
@@ -1568,9 +1568,9 @@ flatted@^3.1.0:
integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==
follow-redirects@^1.15.0:
version "1.15.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
form-data@4.0.0, form-data@^4.0.0:
version "4.0.0"
+132 -27
View File
@@ -2529,7 +2529,7 @@ dependencies = [
"futures-core",
"futures-sink",
"gloo-utils",
"http",
"http 0.2.9",
"js-sys",
"pin-project",
"serde",
@@ -2664,7 +2664,7 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-util",
"http",
"http 0.2.9",
"indexmap 1.9.3",
"slab",
"tokio",
@@ -2833,6 +2833,31 @@ dependencies = [
"itoa 1.0.9",
]
[[package]]
name = "http"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
dependencies = [
"bytes",
"fnv",
"itoa 1.0.9",
]
[[package]]
name = "http-api-client"
version = "0.1.0"
dependencies = [
"async-trait",
"reqwest",
"serde",
"serde_json",
"thiserror",
"tracing",
"url",
"wasmtimer",
]
[[package]]
name = "http-body"
version = "0.4.5"
@@ -2840,7 +2865,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes",
"http",
"http 0.2.9",
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes",
"http 1.1.0",
]
[[package]]
name = "http-body-util"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d"
dependencies = [
"bytes",
"futures-core",
"http 1.1.0",
"http-body 1.0.0",
"pin-project-lite",
]
@@ -2898,8 +2946,8 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"http 0.2.9",
"http-body 0.4.5",
"httparse",
"httpdate",
"itoa 1.0.9",
@@ -2911,6 +2959,25 @@ dependencies = [
"want",
]
[[package]]
name = "hyper"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"httparse",
"httpdate",
"itoa 1.0.9",
"pin-project-lite",
"smallvec",
"tokio",
]
[[package]]
name = "hyper-rustls"
version = "0.24.1"
@@ -2918,8 +2985,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
dependencies = [
"futures-util",
"http",
"hyper",
"http 0.2.9",
"hyper 0.14.27",
"rustls 0.21.7",
"tokio",
"tokio-rustls 0.24.1",
@@ -2932,12 +2999,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper",
"hyper 0.14.27",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "hyper-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
dependencies = [
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"hyper 1.2.0",
"pin-project-lite",
"socket2 0.5.5",
"tokio",
]
[[package]]
name = "iana-time-zone"
version = "0.1.57"
@@ -3740,7 +3823,10 @@ dependencies = [
"dirs 4.0.0",
"futures",
"gloo-timers",
"http-body-util",
"humantime-serde",
"hyper 1.2.0",
"hyper-util",
"log",
"nym-bandwidth-controller",
"nym-config",
@@ -3749,6 +3835,7 @@ dependencies = [
"nym-explorer-client",
"nym-gateway-client",
"nym-gateway-requests",
"nym-metrics",
"nym-network-defaults",
"nym-nonexhaustive-delayqueue",
"nym-pemstore",
@@ -4091,17 +4178,13 @@ dependencies = [
]
[[package]]
name = "nym-http-api-client"
name = "nym-metrics"
version = "0.1.0"
dependencies = [
"async-trait",
"reqwest",
"serde",
"serde_json",
"thiserror",
"tracing",
"url",
"wasmtimer",
"dashmap",
"lazy_static",
"log",
"prometheus",
]
[[package]]
@@ -4507,6 +4590,7 @@ dependencies = [
"eyre",
"flate2",
"futures",
"http-api-client",
"itertools",
"log",
"nym-api-requests",
@@ -4517,7 +4601,6 @@ dependencies = [
"nym-contracts-common",
"nym-ephemera-common",
"nym-group-contract-common",
"nym-http-api-client",
"nym-mixnet-contract-common",
"nym-multisig-contract-common",
"nym-name-service-common",
@@ -5206,6 +5289,21 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "prometheus"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c"
dependencies = [
"cfg-if",
"fnv",
"lazy_static",
"memchr",
"parking_lot 0.12.1",
"protobuf",
"thiserror",
]
[[package]]
name = "prost"
version = "0.12.1"
@@ -5238,6 +5336,12 @@ dependencies = [
"prost",
]
[[package]]
name = "protobuf"
version = "2.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
[[package]]
name = "quick-error"
version = "1.2.3"
@@ -5487,9 +5591,9 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"http 0.2.9",
"http-body 0.4.5",
"hyper 0.14.27",
"hyper-rustls",
"hyper-tls",
"ipnet",
@@ -6309,9 +6413,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.0"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
@@ -6787,7 +6891,7 @@ dependencies = [
"glob",
"gtk",
"heck 0.4.1",
"http",
"http 0.2.9",
"ignore",
"minisign-verify",
"notify-rust",
@@ -6887,7 +6991,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "108683199cb18f96d2d4134187bb789964143c845d2d154848dda209191fd769"
dependencies = [
"gtk",
"http",
"http 0.2.9",
"http-range",
"rand 0.8.5",
"raw-window-handle",
@@ -7273,6 +7377,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
dependencies = [
"futures-util",
"log",
"rustls 0.21.7",
"tokio",
"tungstenite",
]
@@ -7450,7 +7555,7 @@ dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http",
"http 0.2.9",
"httparse",
"log",
"rand 0.8.5",
@@ -8263,7 +8368,7 @@ dependencies = [
"glib",
"gtk",
"html5ever",
"http",
"http 0.2.9",
"kuchiki",
"libc",
"log",
+3 -1
View File
@@ -72,7 +72,9 @@ def config_to_targets(config, mixnodes, labels=None):
def make_prom_target(env, mixnode, port=None, labels=None):
bond_info = mixnode.get("bond_information", {})
mix_node = bond_info.get("mix_node", {})
mix_node = bond_info.get("mix_node")
if mix_node is None:
mix_node = mixnode.get("gateway")
host = mix_node.get("host", None)
port = port if port else mix_node.get("http_api_port", None)
if host is None or port is None:
+43
View File
@@ -0,0 +1,43 @@
import json
import os
ips = [
"2.221.182.179",
"54.232.20.104",
"15.237.112.155",
"54.93.108.209",
"13.38.74.100",
"15.237.93.154",
"18.156.175.57",
"3.76.123.170",
]
port_range = range(18000, 18999)
def make_prom_target(ip, port, env):
return {
"targets": [f"{ip}:{port}"],
"labels": {
"mixnet_env": env,
},
}
if __name__ == "__main__":
outfile = "/tmp/tmp_static_prom_tragets.json"
outlink = "/tmp/static_prom_tragets.json"
targets = []
for ip in ips:
for port in port_range:
targets.append(make_prom_target(ip, port, "performance"))
with open(outfile, "w") as f:
json.dump(targets, f)
os.chmod(outfile, 0o777)
os.rename(outfile, outlink)
os.chmod(outlink, 0o777)
print(f"Prometheus -> {len(targets)} targets written to {outlink}")
@@ -76,9 +76,7 @@ impl MessageQueue {
}
pub(crate) fn pop(&mut self) -> Option<TransportMessage> {
let Some(head) = self.queue.first() else {
return None;
};
let head = self.queue.first()?;
if head.nonce == self.next_expected_nonce {
self.next_expected_nonce = self.next_expected_nonce.wrapping_add(1);
@@ -174,6 +174,7 @@ impl MixnetClient {
}
}
#[derive(Clone)]
pub struct MixnetClientSender {
client_input: ClientInput,
packet_type: Option<PacketType>,
@@ -4,10 +4,10 @@ use std::time::Duration;
// The interface used to route traffic
pub const TUN_BASE_NAME: &str = "nymtun";
pub const TUN_DEVICE_ADDRESS_V4: Ipv4Addr = Ipv4Addr::new(10, 0, 0, 1);
pub const TUN_DEVICE_NETMASK_V4: Ipv4Addr = Ipv4Addr::new(255, 255, 255, 0);
pub const TUN_DEVICE_NETMASK_V4: Ipv4Addr = Ipv4Addr::new(255, 255, 0, 0);
pub const TUN_DEVICE_ADDRESS_V6: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0xa160, 0, 0, 0, 0, 0x1); // 2001:db8:a160::1
pub const TUN_DEVICE_NETMASK_V6: &str = "120";
pub const TUN_DEVICE_NETMASK_V6: &str = "112";
// We routinely check if any clients needs to be disconnected at this interval
pub(crate) const DISCONNECT_TIMER_INTERVAL: Duration = Duration::from_secs(10);
@@ -6,12 +6,13 @@ use crate::constants::{TUN_DEVICE_ADDRESS_V4, TUN_DEVICE_ADDRESS_V6};
// Find an available IP address in self.connected_clients
// TODO: make this nicer
fn generate_random_ips_within_subnet() -> IpPair {
let mut rng = rand::thread_rng();
// Generate a random number in the range 1-254
let last_octet = rand::Rng::gen_range(&mut rng, 1..=254);
let ipv4 = Ipv4Addr::new(10, 0, 0, last_octet);
let ipv6 = Ipv6Addr::new(0x2001, 0x0db8, 0xa160, 0, 0, 0, 0, last_octet as u16);
fn generate_random_ips_within_subnet<R: rand::Rng>(rng: &mut R) -> IpPair {
// Generate a random number in the range 2-65535
let last_bytes: u16 = rand::Rng::gen_range(rng, 2..=65534);
let before_last_byte = (last_bytes >> 8) as u8;
let last_byte = (last_bytes & 255) as u8;
let ipv4 = Ipv4Addr::new(10, 0, before_last_byte, last_byte);
let ipv6 = Ipv6Addr::new(0x2001, 0x0db8, 0xa160, 0, 0, 0, 0, last_bytes);
IpPair::new(ipv4, ipv6)
}
@@ -32,7 +33,8 @@ pub(crate) fn find_new_ips<T>(
connected_clients_ipv4: &HashMap<Ipv4Addr, T>,
connected_clients_ipv6: &HashMap<Ipv6Addr, T>,
) -> Option<IpPair> {
let mut new_ips = generate_random_ips_within_subnet();
let mut rng = rand::thread_rng();
let mut new_ips = generate_random_ips_within_subnet(&mut rng);
let mut tries = 0;
let tun_ips = IpPair::new(TUN_DEVICE_ADDRESS_V4, TUN_DEVICE_ADDRESS_V6);
@@ -42,7 +44,7 @@ pub(crate) fn find_new_ips<T>(
tun_ips,
new_ips,
) {
new_ips = generate_random_ips_within_subnet();
new_ips = generate_random_ips_within_subnet(&mut rng);
tries += 1;
if tries > 100 {
return None;
@@ -50,3 +52,23 @@ pub(crate) fn find_new_ips<T>(
}
Some(new_ips)
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashSet;
#[test]
fn verify_ip_generation() {
let mut map = HashSet::with_capacity(65533);
let mut rng = rand::rngs::mock::StepRng::new(0, 65540);
for _ in 2..65535 {
let pair = generate_random_ips_within_subnet(&mut rng);
println!("{:?}", pair);
assert!(!map.contains(&pair));
map.insert(pair);
}
let pair = generate_random_ips_within_subnet(&mut rng);
assert!(map.contains(&pair));
}
}