Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 47fd5697ed |
@@ -23973,14 +23973,10 @@ function getBinInfo(path) {
|
||||
let mode = external_fs_.statSync(path).mode
|
||||
external_fs_.chmodSync(path, mode | 0o111)
|
||||
|
||||
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 raw = (0,external_child_process_namespaceObject.execSync)(`${path} build-info --output=json`, { stdio: 'pipe', encoding: "utf8" });
|
||||
const parsed = JSON.parse(raw)
|
||||
console.log(` ✅ ok`);
|
||||
return parsed
|
||||
} catch (_) {
|
||||
console.log(` ❌ failed`);
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
@@ -23990,11 +23986,8 @@ 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(directory, { recursive: true });
|
||||
external_fs_.mkdirSync('.tmp');
|
||||
} catch(e) {
|
||||
// ignore
|
||||
}
|
||||
@@ -24009,13 +24002,13 @@ async function run(assets, algorithm, filename, cache) {
|
||||
let sig = null;
|
||||
|
||||
// cache in `${WORKING_DIR}/.tmp/`
|
||||
const cacheFilename = external_path_.join(directory, `${asset.name}`);
|
||||
const cacheFilename = external_path_.resolve(`.tmp/${asset.name}`);
|
||||
if(!external_fs_.existsSync(cacheFilename)) {
|
||||
console.log(`⬇️ Downloading ${asset.browser_download_url}... to ${cacheFilename} [${numAwaiting} of ${assets.length}]`);
|
||||
console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`);
|
||||
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');
|
||||
@@ -24100,7 +24093,6 @@ async function run(assets, algorithm, filename, cache) {
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(`Completed hashing ${assets.length} files`);
|
||||
return hashes;
|
||||
}
|
||||
|
||||
@@ -24130,8 +24122,8 @@ async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algo
|
||||
|
||||
let releases;
|
||||
if(cache) {
|
||||
const cacheFilename = __nccwpck_require__.ab + "releases.json";
|
||||
if(!external_fs_.existsSync(__nccwpck_require__.ab + "releases.json")) {
|
||||
const cacheFilename = external_path_.resolve(`.tmp/releases.json`);
|
||||
if(!external_fs_.existsSync(cacheFilename)) {
|
||||
releases = await octokit.paginate(
|
||||
octokit.rest.repos.listReleases,
|
||||
{
|
||||
@@ -24141,10 +24133,10 @@ async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algo
|
||||
},
|
||||
(response) => response.data
|
||||
);
|
||||
external_fs_.writeFileSync(__nccwpck_require__.ab + "releases.json", JSON.stringify(releases, null, 2));
|
||||
external_fs_.writeFileSync(cacheFilename, JSON.stringify(releases, null, 2));
|
||||
} else {
|
||||
console.log('Loading releases from cache...');
|
||||
releases = JSON.parse(external_fs_.readFileSync(__nccwpck_require__.ab + "releases.json"));
|
||||
releases = JSON.parse(external_fs_.readFileSync(cacheFilename));
|
||||
}
|
||||
} else {
|
||||
releases = await octokit.paginate(
|
||||
@@ -24180,10 +24172,9 @@ 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,14 +11,10 @@ function getBinInfo(path) {
|
||||
let mode = fs.statSync(path).mode
|
||||
fs.chmodSync(path, mode | 0o111)
|
||||
|
||||
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 raw = execSync(`${path} build-info --output=json`, { stdio: 'pipe', encoding: "utf8" });
|
||||
const parsed = JSON.parse(raw)
|
||||
console.log(` ✅ ok`);
|
||||
return parsed
|
||||
} catch (_) {
|
||||
console.log(` ❌ failed`);
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
@@ -28,11 +24,8 @@ 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(directory, { recursive: true });
|
||||
fs.mkdirSync('.tmp');
|
||||
} catch(e) {
|
||||
// ignore
|
||||
}
|
||||
@@ -47,13 +40,13 @@ async function run(assets, algorithm, filename, cache) {
|
||||
let sig = null;
|
||||
|
||||
// cache in `${WORKING_DIR}/.tmp/`
|
||||
const cacheFilename = path.join(directory, `${asset.name}`);
|
||||
const cacheFilename = path.resolve(`.tmp/${asset.name}`);
|
||||
if(!fs.existsSync(cacheFilename)) {
|
||||
console.log(`⬇️ Downloading ${asset.browser_download_url}... to ${cacheFilename} [${numAwaiting} of ${assets.length}]`);
|
||||
console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`);
|
||||
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');
|
||||
@@ -138,7 +131,6 @@ async function run(assets, algorithm, filename, cache) {
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(`Completed hashing ${assets.length} files`);
|
||||
return hashes;
|
||||
}
|
||||
|
||||
@@ -218,10 +210,9 @@ 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,11 +1,6 @@
|
||||
import {createHashesFromReleaseTagOrNameOrId} from './create-hashes.mjs';
|
||||
|
||||
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});
|
||||
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});
|
||||
|
||||
@@ -8,8 +8,8 @@ on:
|
||||
required: true
|
||||
type: string
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release_tag:
|
||||
release_tag:
|
||||
tag:
|
||||
description: 'Release tag'
|
||||
required: true
|
||||
type: string
|
||||
@@ -24,7 +24,10 @@ jobs:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- uses: nymtech/nym/.github/actions/nym-hash-releases@develop
|
||||
- name: Install packages
|
||||
run: cd ./.github/actions/nym-hash-releases && npm i
|
||||
|
||||
- uses: ./.github/actions/nym-hash-releases
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
|
||||
Generated
+70
-167
@@ -557,9 +557,9 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 0.2.9",
|
||||
"http-body 0.4.5",
|
||||
"hyper 0.14.27",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"itoa",
|
||||
"matchit",
|
||||
"memchr",
|
||||
@@ -587,8 +587,8 @@ dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 0.2.9",
|
||||
"http-body 0.4.5",
|
||||
"http",
|
||||
"http-body",
|
||||
"mime",
|
||||
"rustversion",
|
||||
"tower-layer",
|
||||
@@ -1429,6 +1429,14 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpu-cycles"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.9"
|
||||
@@ -1908,12 +1916,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.5"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc5d6b04b3fd0ba9926f945895de7d806260a2d7431ba82e7edaecb043c4c6b8"
|
||||
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
|
||||
dependencies = [
|
||||
"darling_core 0.20.5",
|
||||
"darling_macro 0.20.5",
|
||||
"darling_core 0.20.3",
|
||||
"darling_macro 0.20.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1946,9 +1954,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.20.5"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04e48a959bcd5c761246f5d090ebc2fbf7b9cd527a492b07a67510c108f1e7e3"
|
||||
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
@@ -1982,11 +1990,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.5"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d1545d67a2149e1d93b7e5c7752dce5a7426eb5d1357ddcfd89336b94444f77"
|
||||
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
|
||||
dependencies = [
|
||||
"darling_core 0.20.5",
|
||||
"darling_core 0.20.3",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
@@ -3011,7 +3019,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"gloo-utils",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"js-sys",
|
||||
"pin-project",
|
||||
"serde",
|
||||
@@ -3080,7 +3088,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"indexmap 1.9.3",
|
||||
"slab",
|
||||
"tokio",
|
||||
@@ -3290,17 +3298,6 @@ 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"
|
||||
@@ -3322,30 +3319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"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",
|
||||
"http",
|
||||
"pin-project-lite 0.2.13",
|
||||
]
|
||||
|
||||
@@ -3413,8 +3387,8 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http 0.2.9",
|
||||
"http-body 0.4.5",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
@@ -3426,25 +3400,6 @@ 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"
|
||||
@@ -3452,8 +3407,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http 0.2.9",
|
||||
"hyper 0.14.27",
|
||||
"http",
|
||||
"hyper",
|
||||
"rustls 0.21.10",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
@@ -3465,28 +3420,12 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
|
||||
dependencies = [
|
||||
"hyper 0.14.27",
|
||||
"hyper",
|
||||
"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"
|
||||
@@ -3811,7 +3750,7 @@ dependencies = [
|
||||
"curl-sys",
|
||||
"event-listener",
|
||||
"futures-lite",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"log",
|
||||
"once_cell",
|
||||
"polling",
|
||||
@@ -4624,7 +4563,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-util",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"memchr",
|
||||
@@ -5261,10 +5200,7 @@ 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",
|
||||
@@ -5273,7 +5209,6 @@ dependencies = [
|
||||
"nym-explorer-client",
|
||||
"nym-gateway-client",
|
||||
"nym-gateway-requests",
|
||||
"nym-metrics",
|
||||
"nym-network-defaults",
|
||||
"nym-nonexhaustive-delayqueue",
|
||||
"nym-pemstore",
|
||||
@@ -5587,7 +5522,7 @@ dependencies = [
|
||||
"dotenvy",
|
||||
"futures",
|
||||
"humantime-serde",
|
||||
"hyper 0.14.27",
|
||||
"hyper",
|
||||
"ipnetwork 0.16.0",
|
||||
"log",
|
||||
"nym-api-requests",
|
||||
@@ -5678,9 +5613,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tungstenite",
|
||||
"wasmtimer",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@@ -5784,16 +5717,6 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-metrics"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dashmap",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"prometheus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-mixnet-client"
|
||||
version = "0.1.0"
|
||||
@@ -5834,19 +5757,19 @@ dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
"bs58 0.5.0",
|
||||
"cfg-if",
|
||||
"clap 4.4.7",
|
||||
"colored",
|
||||
"cpu-cycles",
|
||||
"cupid",
|
||||
"dirs 4.0.0",
|
||||
"futures",
|
||||
"humantime-serde",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"nym-bin-common",
|
||||
"nym-config",
|
||||
"nym-contracts-common",
|
||||
"nym-crypto",
|
||||
"nym-metrics",
|
||||
"nym-mixnet-client",
|
||||
"nym-mixnode-common",
|
||||
"nym-node",
|
||||
@@ -5859,6 +5782,7 @@ dependencies = [
|
||||
"nym-topology",
|
||||
"nym-types",
|
||||
"nym-validator-client",
|
||||
"opentelemetry",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -5867,6 +5791,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"toml 0.5.11",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
@@ -5875,12 +5800,13 @@ name = "nym-mixnode-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"cpu-cycles",
|
||||
"futures",
|
||||
"humantime-serde",
|
||||
"log",
|
||||
"nym-bin-common",
|
||||
"nym-crypto",
|
||||
"nym-metrics",
|
||||
"nym-network-defaults",
|
||||
"nym-sphinx-acknowledgements",
|
||||
"nym-sphinx-addressing",
|
||||
@@ -5895,6 +5821,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
@@ -6022,7 +5949,7 @@ dependencies = [
|
||||
"dashmap",
|
||||
"fastrand 2.0.1",
|
||||
"hmac 0.12.1",
|
||||
"hyper 0.14.27",
|
||||
"hyper",
|
||||
"ipnetwork 0.16.0",
|
||||
"mime",
|
||||
"nym-config",
|
||||
@@ -6175,7 +6102,7 @@ dependencies = [
|
||||
"dotenvy",
|
||||
"futures",
|
||||
"hex",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"httpcodec",
|
||||
"libp2p",
|
||||
"log",
|
||||
@@ -6915,7 +6842,7 @@ checksum = "a819b71d6530c4297b49b3cae2939ab3a8cc1b9f382826a1bc29dd0ca3864906"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"isahc",
|
||||
"opentelemetry_api",
|
||||
]
|
||||
@@ -6929,7 +6856,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
"futures-executor",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"isahc",
|
||||
"once_cell",
|
||||
"opentelemetry",
|
||||
@@ -7514,21 +7441,6 @@ dependencies = [
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[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 = "prometheus-client"
|
||||
version = "0.19.0"
|
||||
@@ -7650,17 +7562,11 @@ dependencies = [
|
||||
"prost 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "2.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
|
||||
|
||||
[[package]]
|
||||
name = "psl"
|
||||
version = "2.1.22"
|
||||
version = "2.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc74a6e6a56708be1cf5c4c4d1a0dc21d33b2dcaa24e731b7fa9c287ce4f916f"
|
||||
checksum = "383703acfc34f7a00724846c14dc5ea4407c59e5aedcbbb18a1c0c1a23fe5013"
|
||||
dependencies = [
|
||||
"psl-types",
|
||||
]
|
||||
@@ -8056,13 +7962,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.3"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.4.6",
|
||||
"regex-automata 0.4.3",
|
||||
"regex-syntax 0.8.2",
|
||||
]
|
||||
|
||||
@@ -8077,9 +7983,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -8110,9 +8016,9 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http 0.2.9",
|
||||
"http-body 0.4.5",
|
||||
"hyper 0.14.27",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
@@ -8271,7 +8177,7 @@ version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69"
|
||||
dependencies = [
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"log",
|
||||
"regex",
|
||||
"rocket",
|
||||
@@ -8291,8 +8197,8 @@ dependencies = [
|
||||
"cookie",
|
||||
"either",
|
||||
"futures",
|
||||
"http 0.2.9",
|
||||
"hyper 0.14.27",
|
||||
"http",
|
||||
"hyper",
|
||||
"indexmap 2.0.2",
|
||||
"log",
|
||||
"memchr",
|
||||
@@ -8902,9 +8808,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "3.6.0"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b0ed1662c5a68664f45b76d18deb0e234aff37207086803165c961eb695e981"
|
||||
checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23"
|
||||
dependencies = [
|
||||
"base64 0.21.4",
|
||||
"chrono",
|
||||
@@ -8919,11 +8825,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "3.6.0"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "568577ff0ef47b879f736cd66740e022f3672788cdf002a05a4e609ea5a6fb15"
|
||||
checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788"
|
||||
dependencies = [
|
||||
"darling 0.20.5",
|
||||
"darling 0.20.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
@@ -9096,9 +9002,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.1"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
|
||||
|
||||
[[package]]
|
||||
name = "snafu"
|
||||
@@ -9947,10 +9853,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"rustls 0.21.10",
|
||||
"rustls-native-certs",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
"tungstenite",
|
||||
]
|
||||
|
||||
@@ -10053,9 +9956,9 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http 0.2.9",
|
||||
"http-body 0.4.5",
|
||||
"hyper 0.14.27",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-timeout",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
@@ -10098,8 +10001,8 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http 0.2.9",
|
||||
"http-body 0.4.5",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-range-header",
|
||||
"httpdate",
|
||||
"mime",
|
||||
@@ -10377,7 +10280,7 @@ dependencies = [
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"data-encoding",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
|
||||
+7
-20
@@ -32,7 +32,7 @@ members = [
|
||||
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
|
||||
"common/cosmwasm-smart-contracts/coconut-dkg",
|
||||
"common/cosmwasm-smart-contracts/contracts-common",
|
||||
# "common/cosmwasm-smart-contracts/ephemera",
|
||||
# "common/cosmwasm-smart-contracts/ephemera",
|
||||
"common/cosmwasm-smart-contracts/group-contract",
|
||||
"common/cosmwasm-smart-contracts/mixnet-contract",
|
||||
"common/cosmwasm-smart-contracts/multisig-contract",
|
||||
@@ -57,7 +57,6 @@ members = [
|
||||
"common/nonexhaustive-delayqueue",
|
||||
"common/nymcoconut",
|
||||
"common/nym-id",
|
||||
"common/nym-metrics",
|
||||
"common/nymsphinx",
|
||||
"common/nymsphinx/acknowledgements",
|
||||
"common/nymsphinx/addressing",
|
||||
@@ -113,10 +112,9 @@ members = [
|
||||
"tools/nymvisor",
|
||||
"tools/ts-rs-cli",
|
||||
"wasm/client",
|
||||
# "wasm/full-nym-wasm",
|
||||
# "wasm/full-nym-wasm",
|
||||
"wasm/mix-fetch",
|
||||
"wasm/node-tester",
|
||||
"common/nym-metrics",
|
||||
]
|
||||
|
||||
default-members = [
|
||||
@@ -132,16 +130,7 @@ default-members = [
|
||||
"nym-validator-rewarder",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
"explorer",
|
||||
"contracts",
|
||||
"nym-wallet",
|
||||
"nym-connect/mobile/src-tauri",
|
||||
"nym-connect/desktop",
|
||||
"nym-vpn/ui/src-tauri",
|
||||
"cpu-cycles",
|
||||
"sdk/ffi/cpp",
|
||||
]
|
||||
exclude = ["explorer", "contracts", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "nym-vpn/ui/src-tauri", "cpu-cycles", "sdk/ffi/cpp"]
|
||||
|
||||
[workspace.package]
|
||||
authors = ["Nym Technologies SA"]
|
||||
@@ -172,7 +161,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"
|
||||
@@ -191,12 +180,10 @@ utoipa-swagger-ui = "3.1.5"
|
||||
url = "2.4"
|
||||
zeroize = "1.6.0"
|
||||
|
||||
prometheus = { version = "0.13.0" }
|
||||
|
||||
# coconut/DKG related
|
||||
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
|
||||
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
|
||||
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch = "feature/gt-serialization-0.8.0" }
|
||||
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch ="feature/gt-serialization-0.8.0" }
|
||||
group = "0.13.0"
|
||||
ff = "0.13.0"
|
||||
|
||||
@@ -221,9 +208,9 @@ cw-controllers = { version = "=1.1.0" }
|
||||
bip32 = "0.5.1"
|
||||
|
||||
# temporarily using a fork again (yay.) because we need staking and slashing support
|
||||
cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" }
|
||||
cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch ="nym-temp/all-validator-features" }
|
||||
#cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" } # unfortuntely we need a fork by yours truly to get the staking support
|
||||
tendermint = "0.34" # same version as used by cosmrs
|
||||
tendermint = "0.34" # same version as used by cosmrs
|
||||
tendermint-rpc = "0.34" # same version as used by cosmrs
|
||||
prost = "0.12"
|
||||
|
||||
|
||||
+28
-28
@@ -1667,9 +1667,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"version": "1.15.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -1705,9 +1705,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fs-monkey": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz",
|
||||
"integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
|
||||
"integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
@@ -2430,12 +2430,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/memfs": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
|
||||
"integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz",
|
||||
"integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs-monkey": "^1.0.4"
|
||||
"fs-monkey": "1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
@@ -4047,13 +4047,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-dev-middleware": {
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
|
||||
"integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz",
|
||||
"integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"colorette": "^2.0.10",
|
||||
"memfs": "^3.4.3",
|
||||
"memfs": "^3.4.1",
|
||||
"mime-types": "^2.1.31",
|
||||
"range-parser": "^1.2.1",
|
||||
"schema-utils": "^4.0.0"
|
||||
@@ -5800,9 +5800,9 @@
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"version": "1.15.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||
"dev": true
|
||||
},
|
||||
"forwarded": {
|
||||
@@ -5818,9 +5818,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"fs-monkey": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz",
|
||||
"integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
|
||||
"integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
@@ -6346,12 +6346,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"memfs": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
|
||||
"integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz",
|
||||
"integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs-monkey": "^1.0.4"
|
||||
"fs-monkey": "1.0.3"
|
||||
}
|
||||
},
|
||||
"merge-descriptors": {
|
||||
@@ -7547,13 +7547,13 @@
|
||||
}
|
||||
},
|
||||
"webpack-dev-middleware": {
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
|
||||
"integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz",
|
||||
"integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"colorette": "^2.0.10",
|
||||
"memfs": "^3.4.3",
|
||||
"memfs": "^3.4.1",
|
||||
"mime-types": "^2.1.31",
|
||||
"range-parser": "^1.2.1",
|
||||
"schema-utils": "^4.0.0"
|
||||
|
||||
@@ -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,7 +38,6 @@ 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" }
|
||||
@@ -49,19 +48,6 @@ 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"]
|
||||
@@ -72,7 +58,6 @@ 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
|
||||
@@ -106,15 +91,11 @@ 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.clone()
|
||||
self.gateway_shared_key.as_ref().map(Arc::clone)
|
||||
}
|
||||
|
||||
pub fn remove_gateway_key(self) -> KeyManagerBuilder {
|
||||
|
||||
@@ -3,30 +3,8 @@ 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
|
||||
@@ -75,60 +53,42 @@ 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -505,33 +465,6 @@ 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 {
|
||||
@@ -544,27 +477,6 @@ 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();
|
||||
@@ -589,9 +501,3 @@ impl PacketStatisticsControl {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn serve_metrics(
|
||||
_: Request<hyper::body::Incoming>,
|
||||
) -> Result<Response<Full<Bytes>>, Infallible> {
|
||||
Ok(Response::new(Full::new(Bytes::from(metrics!()))))
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ 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]
|
||||
|
||||
@@ -20,7 +20,7 @@ use nym_gateway_requests::authentication::encrypted_address::EncryptedAddressByt
|
||||
use nym_gateway_requests::iv::IV;
|
||||
use nym_gateway_requests::registration::handshake::{client_handshake, SharedKeys};
|
||||
use nym_gateway_requests::{
|
||||
BinaryRequest, ClientControlRequest, ServerResponse, CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION,
|
||||
BinaryRequest, ClientControlRequest, ServerResponse, CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION,
|
||||
CURRENT_PROTOCOL_VERSION,
|
||||
};
|
||||
use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN};
|
||||
@@ -438,7 +438,6 @@ impl<C, St> GatewayClient<C, St> {
|
||||
ws_stream,
|
||||
self.local_identity.as_ref(),
|
||||
self.gateway_identity,
|
||||
!self.disabled_credentials_mode,
|
||||
)
|
||||
.await
|
||||
.map_err(GatewayClientError::RegistrationFailure),
|
||||
@@ -495,13 +494,8 @@ impl<C, St> GatewayClient<C, St> {
|
||||
.derive_destination_address();
|
||||
let encrypted_address = EncryptedAddressBytes::new(&self_address, shared_key, &iv);
|
||||
|
||||
let msg = ClientControlRequest::new_authenticate(
|
||||
self_address,
|
||||
encrypted_address,
|
||||
iv,
|
||||
!self.disabled_credentials_mode,
|
||||
)
|
||||
.into();
|
||||
let msg =
|
||||
ClientControlRequest::new_authenticate(self_address, encrypted_address, iv).into();
|
||||
|
||||
match self.send_websocket_message(msg).await? {
|
||||
ServerResponse::Authenticate {
|
||||
@@ -605,7 +599,7 @@ impl<C, St> GatewayClient<C, St> {
|
||||
});
|
||||
};
|
||||
|
||||
if gateway_protocol < CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION {
|
||||
if gateway_protocol < CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION {
|
||||
return Err(GatewayClientError::OutdatedGatewayCredentialVersion {
|
||||
negotiated_protocol: Some(gateway_protocol),
|
||||
});
|
||||
|
||||
@@ -69,10 +69,6 @@ impl PacketRouter {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn mark_as_success(&mut self) {
|
||||
self.shutdown.mark_as_success();
|
||||
}
|
||||
}
|
||||
|
||||
impl GatewayPacketRouter for PacketRouter {
|
||||
|
||||
@@ -44,7 +44,9 @@ pub(crate) fn ws_fd(_conn: &WsConn) -> Option<RawFd> {
|
||||
#[cfg(unix)]
|
||||
match _conn.get_ref() {
|
||||
MaybeTlsStream::Plain(stream) => Some(stream.as_raw_fd()),
|
||||
&_ => None,
|
||||
&_ => unreachable!(
|
||||
"If tls features are enabled, the inner stream needs to be unpacked into raw fd"
|
||||
),
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
None
|
||||
@@ -97,7 +99,7 @@ impl PartiallyDelegated {
|
||||
|
||||
pub(crate) fn split_and_listen_for_mixnet_messages(
|
||||
conn: WsConn,
|
||||
mut packet_router: PacketRouter,
|
||||
packet_router: PacketRouter,
|
||||
shared_key: Arc<SharedKeys>,
|
||||
mut shutdown: TaskClient,
|
||||
) -> Self {
|
||||
@@ -140,7 +142,6 @@ 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))
|
||||
}
|
||||
|
||||
@@ -695,6 +695,46 @@ pub trait MixnetSigningClient {
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn admin_add_mixnode(
|
||||
&self,
|
||||
mix_node: MixNode,
|
||||
cost_params: MixNodeCostParams,
|
||||
owner: String,
|
||||
pledge: Coin,
|
||||
fee: Option<Fee>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
self.execute_mixnet_contract(
|
||||
fee,
|
||||
MixnetExecuteMsg::UncheckedImportMixnode {
|
||||
mix_node,
|
||||
cost_params,
|
||||
owner,
|
||||
pledge: pledge.into(),
|
||||
},
|
||||
vec![],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn admin_add_gateway(
|
||||
&self,
|
||||
gateway: Gateway,
|
||||
owner: String,
|
||||
pledge: Coin,
|
||||
fee: Option<Fee>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
self.execute_mixnet_contract(
|
||||
fee,
|
||||
MixnetExecuteMsg::UncheckedImportGateway {
|
||||
gateway,
|
||||
owner,
|
||||
pledge: pledge.into(),
|
||||
},
|
||||
vec![],
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
||||
@@ -734,6 +774,7 @@ where
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue};
|
||||
use nym_mixnet_contract_common::ExecuteMsg;
|
||||
|
||||
// it's enough that this compiles and clippy is happy about it
|
||||
#[allow(dead_code)]
|
||||
@@ -933,6 +974,21 @@ mod tests {
|
||||
MixnetExecuteMsg::TestingResolveAllPendingEvents { .. } => {
|
||||
client.testing_resolve_all_pending_events(None).ignore()
|
||||
}
|
||||
ExecuteMsg::UncheckedImportMixnode {
|
||||
mix_node,
|
||||
cost_params,
|
||||
owner,
|
||||
pledge,
|
||||
} => client
|
||||
.admin_add_mixnode(mix_node, cost_params, owner, pledge.into(), None)
|
||||
.ignore(),
|
||||
ExecuteMsg::UncheckedImportGateway {
|
||||
gateway,
|
||||
owner,
|
||||
pledge,
|
||||
} => client
|
||||
.admin_add_gateway(gateway, owner, pledge.into(), None)
|
||||
.ignore(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,6 +274,19 @@ pub enum ExecuteMsg {
|
||||
TestingResolveAllPendingEvents {
|
||||
limit: Option<u32>,
|
||||
},
|
||||
|
||||
// speedtest:
|
||||
UncheckedImportMixnode {
|
||||
mix_node: MixNode,
|
||||
cost_params: MixNodeCostParams,
|
||||
owner: String,
|
||||
pledge: Coin,
|
||||
},
|
||||
UncheckedImportGateway {
|
||||
gateway: Gateway,
|
||||
owner: String,
|
||||
pledge: Coin,
|
||||
},
|
||||
}
|
||||
|
||||
impl ExecuteMsg {
|
||||
@@ -385,6 +398,9 @@ impl ExecuteMsg {
|
||||
ExecuteMsg::TestingResolveAllPendingEvents { .. } => {
|
||||
"resolving all pending events".into()
|
||||
}
|
||||
|
||||
ExecuteMsg::UncheckedImportMixnode { .. } => "unchecked import mixnode".into(),
|
||||
ExecuteMsg::UncheckedImportGateway { .. } => "unchecked import gateway".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,7 +837,7 @@ mod tests {
|
||||
let share3 = chunks3.clone().try_into().unwrap();
|
||||
|
||||
let shares = vec![share1, share2, share3];
|
||||
let chunks = &[chunks1, chunks2, chunks3];
|
||||
let chunks = vec![chunks1, chunks2, chunks3];
|
||||
|
||||
for (i, pk_i) in pks.iter().enumerate() {
|
||||
let mut ciphertext_chunk_i = Vec::with_capacity(NUM_CHUNKS);
|
||||
|
||||
@@ -34,13 +34,6 @@ 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();
|
||||
@@ -54,7 +47,7 @@ impl MultiIpPacketCodec {
|
||||
}
|
||||
|
||||
// Flush the current buffer and return it.
|
||||
pub fn flush_current_buffer(&mut self) -> Bytes {
|
||||
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,22 +2,14 @@ use serde::{Deserialize, Serialize};
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
|
||||
// The current version of the protocol.
|
||||
// The idea here is that we add new request response types at least one version before we start
|
||||
// using them.
|
||||
// Also, depending on the version in the client connect message the IPR could respond with a
|
||||
// matching older version.
|
||||
pub use v6::request;
|
||||
pub use v6::response;
|
||||
|
||||
pub mod codec;
|
||||
pub mod v6;
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
|
||||
// version 3: initial version
|
||||
// version 4: IPv6 support
|
||||
// version 5: Add severity level to info response
|
||||
// version 6: Increase the available IPs
|
||||
pub const CURRENT_VERSION: u8 = 6;
|
||||
pub const CURRENT_VERSION: u8 = 5;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct IpPair {
|
||||
|
||||
-28
@@ -83,34 +83,6 @@ impl IpPacketRequest {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_ping(reply_to: Recipient) -> (Self, u64) {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
data: IpPacketRequestData::Ping(PingRequest {
|
||||
request_id,
|
||||
reply_to,
|
||||
}),
|
||||
},
|
||||
request_id,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_health_request(reply_to: Recipient) -> (Self, u64) {
|
||||
let request_id = generate_random();
|
||||
(
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
data: IpPacketRequestData::Health(HealthRequest {
|
||||
request_id,
|
||||
reply_to,
|
||||
}),
|
||||
},
|
||||
request_id,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn id(&self) -> Option<u64> {
|
||||
match &self.data {
|
||||
IpPacketRequestData::StaticConnect(request) => Some(request.request_id),
|
||||
-29
@@ -144,35 +144,6 @@ impl IpPacketResponse {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_pong(request_id: u64, reply_to: Recipient) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
data: IpPacketResponseData::Pong(PongResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_health_response(
|
||||
request_id: u64,
|
||||
reply_to: Recipient,
|
||||
build_info: nym_bin_common::build_information::BinaryBuildInformationOwned,
|
||||
routable: Option<bool>,
|
||||
) -> Self {
|
||||
Self {
|
||||
version: CURRENT_VERSION,
|
||||
data: IpPacketResponseData::Health(HealthResponse {
|
||||
request_id,
|
||||
reply_to,
|
||||
reply: HealthResponseReply {
|
||||
build_info,
|
||||
routable,
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> Option<u64> {
|
||||
match &self.data {
|
||||
IpPacketResponseData::StaticConnect(response) => Some(response.request_id),
|
||||
@@ -1,2 +0,0 @@
|
||||
pub mod request;
|
||||
pub mod response;
|
||||
@@ -25,6 +25,9 @@ tokio-util = { workspace = true, features = ["codec"] }
|
||||
url = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
## tracing
|
||||
tracing = { version = "0.1.37", optional = true }
|
||||
|
||||
nym-crypto = { path = "../crypto" }
|
||||
nym-network-defaults = { path = "../network-defaults" }
|
||||
nym-sphinx-acknowledgements = { path = "../nymsphinx/acknowledgements" }
|
||||
@@ -36,4 +39,9 @@ nym-sphinx-types = { path = "../nymsphinx/types" }
|
||||
nym-task = { path = "../task" }
|
||||
nym-validator-client = { path = "../client-libs/validator-client" }
|
||||
nym-bin-common = { path = "../bin-common" }
|
||||
nym-metrics = { path = "../nym-metrics" }
|
||||
|
||||
cfg-if = "1.0.0"
|
||||
cpu-cycles = { path = "../../cpu-cycles", optional = true }
|
||||
|
||||
[features]
|
||||
cpucycles = ["cpu-cycles", "tracing"]
|
||||
|
||||
@@ -2,3 +2,40 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
pub mod packet_processor;
|
||||
pub mod verloc;
|
||||
|
||||
pub fn cpu_cycles() -> Result<i64, Box<dyn std::error::Error>> {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "cpucycles")] {
|
||||
Ok(cpu_cycles::cpucycles()?)
|
||||
} else {
|
||||
Err("`cpucycles` feature is not turned on!".into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! measure {
|
||||
( $x:expr ) => {{
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "cpucycles")] {
|
||||
let start_cycles = $crate::cpu_cycles();
|
||||
// if the block needs to return something, we can return it
|
||||
let r = $x;
|
||||
let end_cycles = $crate::cpu_cycles();
|
||||
let name = if let Some(meta) = tracing::Span::current().metadata() {
|
||||
meta.name()
|
||||
} else {
|
||||
"measure"
|
||||
};
|
||||
match (start_cycles, end_cycles) {
|
||||
(Ok(start), Ok(end)) => log::trace!("{} cpucycles: {}", name, end - start),
|
||||
(Err(e), _) => error!("{e}"),
|
||||
(_, Err(e)) => error!("{e}"),
|
||||
}
|
||||
r
|
||||
} else {
|
||||
$x
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::measure;
|
||||
use crate::packet_processor::error::MixProcessingError;
|
||||
use log::*;
|
||||
use nym_metrics::nanos;
|
||||
use nym_sphinx_acknowledgements::surb_ack::SurbAck;
|
||||
use nym_sphinx_addressing::nodes::NymNodeRoutingAddress;
|
||||
use nym_sphinx_forwarding::packet::MixPacket;
|
||||
@@ -15,6 +15,8 @@ use nym_sphinx_types::{
|
||||
};
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
#[cfg(feature = "cpucycles")]
|
||||
use tracing::instrument;
|
||||
|
||||
type ForwardAck = MixPacket;
|
||||
|
||||
@@ -49,11 +51,15 @@ impl SphinxPacketProcessor {
|
||||
}
|
||||
|
||||
/// Performs a fresh sphinx unwrapping using no cache.
|
||||
#[cfg_attr(
|
||||
feature = "cpucycles",
|
||||
instrument(skip(self, packet), fields(cpucycles))
|
||||
)]
|
||||
fn perform_initial_packet_processing(
|
||||
&self,
|
||||
packet: NymPacket,
|
||||
) -> Result<NymProcessedPacket, MixProcessingError> {
|
||||
nanos!("perform_initial_packet_processing", {
|
||||
measure!({
|
||||
packet.process(&self.sphinx_key).map_err(|err| {
|
||||
debug!("Failed to unwrap NymPacket packet: {err}");
|
||||
MixProcessingError::NymPacketProcessingError(err)
|
||||
@@ -62,12 +68,17 @@ impl SphinxPacketProcessor {
|
||||
}
|
||||
|
||||
/// Takes the received framed packet and tries to unwrap it from the sphinx encryption.
|
||||
#[cfg_attr(
|
||||
feature = "cpucycles",
|
||||
instrument(skip(self, received), fields(cpucycles))
|
||||
)]
|
||||
fn perform_initial_unwrapping(
|
||||
&self,
|
||||
received: FramedNymPacket,
|
||||
) -> Result<NymProcessedPacket, MixProcessingError> {
|
||||
nanos!("perform_initial_unwrapping", {
|
||||
measure!({
|
||||
let packet = received.into_inner();
|
||||
|
||||
self.perform_initial_packet_processing(packet)
|
||||
})
|
||||
}
|
||||
@@ -212,12 +223,16 @@ impl SphinxPacketProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "cpucycles",
|
||||
instrument(skip(self, received), fields(cpucycles))
|
||||
)]
|
||||
pub fn process_received(
|
||||
&self,
|
||||
received: FramedNymPacket,
|
||||
) -> Result<MixProcessingResult, MixProcessingError> {
|
||||
// explicit packet size will help to correctly parse final hop
|
||||
nanos!("process_received", {
|
||||
measure!({
|
||||
let packet_size = received.packet_size();
|
||||
let packet_type = received.packet_type();
|
||||
|
||||
|
||||
@@ -79,13 +79,7 @@ impl NymNetworkDetails {
|
||||
pub fn new_from_env() -> Self {
|
||||
fn get_optional_env<K: AsRef<OsStr>>(env: K) -> Option<String> {
|
||||
match var(env) {
|
||||
Ok(var) => {
|
||||
if var.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(var)
|
||||
}
|
||||
}
|
||||
Ok(var) => Some(var),
|
||||
Err(VarError::NotPresent) => None,
|
||||
err => panic!("Unable to set: {:?}", err),
|
||||
}
|
||||
@@ -119,15 +113,28 @@ impl NymNetworkDetails {
|
||||
Some(var(var_names::NYM_API).expect("nym api not set")),
|
||||
get_optional_env(var_names::NYXD_WEBSOCKET),
|
||||
))
|
||||
.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_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_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,
|
||||
))
|
||||
|
||||
@@ -16,13 +16,11 @@ pub const MIXNET_CONTRACT_ADDRESS: &str =
|
||||
"n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr";
|
||||
pub const VESTING_CONTRACT_ADDRESS: &str =
|
||||
"n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw";
|
||||
|
||||
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 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 REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy";
|
||||
|
||||
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/";
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
[package]
|
||||
name = "nym-metrics"
|
||||
version = "0.1.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
documentation.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
prometheus = { workspace = true }
|
||||
log = { workspace = true }
|
||||
dashmap = { workspace = true }
|
||||
lazy_static = "1.4"
|
||||
@@ -1,278 +0,0 @@
|
||||
use dashmap::DashMap;
|
||||
pub use log::error;
|
||||
use log::{debug, warn};
|
||||
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 ) => {{
|
||||
let start = $crate::Instant::now();
|
||||
// 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 REGISTRY: MetricsController = MetricsController::default();
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MetricsController {
|
||||
registry: Registry,
|
||||
registry_index: DashMap<String, Metric>,
|
||||
}
|
||||
|
||||
enum Metric {
|
||||
C(Box<Counter>),
|
||||
G(Box<Gauge>),
|
||||
}
|
||||
|
||||
fn fq_name(c: &dyn Collector) -> String {
|
||||
c.desc()
|
||||
.first()
|
||||
.map(|d| d.fq_name.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
impl Metric {
|
||||
#[inline(always)]
|
||||
fn fq_name(&self) -> String {
|
||||
match self {
|
||||
Metric::C(c) => fq_name(c.as_ref()),
|
||||
Metric::G(g) => fq_name(g.as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
#[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),
|
||||
Metric::G(g) => g.add(value),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set(&self, value: f64) {
|
||||
match self {
|
||||
Metric::C(_c) => {
|
||||
warn!("Cannot set value for counter {:?}", self.fq_name());
|
||||
}
|
||||
Metric::G(g) => g.set(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MetricsController {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
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),
|
||||
};
|
||||
write!(f, "{}", output)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
let gauge = match Gauge::new(sanitize_metric_name(name), name) {
|
||||
Ok(g) => g,
|
||||
Err(e) => {
|
||||
debug!("Failed to create gauge {:?}:\n{}", name, e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
self.register_gauge(Box::new(gauge));
|
||||
self.set(name, value)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
} 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_by(name, value)
|
||||
}
|
||||
}
|
||||
|
||||
fn register_gauge(&self, metric: Box<Gauge>) {
|
||||
let fq_name = metric
|
||||
.desc()
|
||||
.first()
|
||||
.map(|d| d.fq_name.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
if self.registry_index.contains_key(&fq_name) {
|
||||
return;
|
||||
}
|
||||
|
||||
match self.registry.register(metric.clone()) {
|
||||
Ok(_) => {
|
||||
self.registry_index
|
||||
.insert(fq_name, Metric::G(metric.clone()));
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("Failed to register {:?}:\n{}", fq_name, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn register_counter(&self, metric: Box<Counter>) {
|
||||
let fq_name = metric
|
||||
.desc()
|
||||
.first()
|
||||
.map(|d| d.fq_name.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
if self.registry_index.contains_key(&fq_name) {
|
||||
return;
|
||||
}
|
||||
match self.registry.register(metric.clone()) {
|
||||
Ok(_) => {
|
||||
self.registry_index
|
||||
.insert(fq_name, Metric::C(metric.clone()));
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("Failed to register {:?}:\n{}", fq_name, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sanitize_metric_name(name: &str) -> 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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_sanitization() {
|
||||
assert_eq!(
|
||||
sanitize_metric_name("packets_sent_34.242.65.133:1789"),
|
||||
"packets_sent_34_242_65_133:1789"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ use crate::interval::storage as interval_storage;
|
||||
use crate::mixnet_contract_settings::storage as mixnet_params_storage;
|
||||
use crate::mixnodes::storage as mixnode_storage;
|
||||
use crate::rewards::storage as rewards_storage;
|
||||
use crate::speedtest_tmp::{admin_add_gateway, admin_add_mixnode};
|
||||
use cosmwasm_std::{
|
||||
entry_point, to_binary, Addr, Coin, Deps, DepsMut, Env, MessageInfo, QueryResponse, Response,
|
||||
};
|
||||
@@ -372,6 +373,18 @@ pub fn execute(
|
||||
ExecuteMsg::TestingResolveAllPendingEvents { limit } => {
|
||||
crate::testing::transactions::try_resolve_all_pending_events(deps, env, limit)
|
||||
}
|
||||
|
||||
ExecuteMsg::UncheckedImportMixnode {
|
||||
mix_node,
|
||||
cost_params,
|
||||
owner,
|
||||
pledge,
|
||||
} => admin_add_mixnode(deps, env, info, mix_node, cost_params, pledge, owner),
|
||||
ExecuteMsg::UncheckedImportGateway {
|
||||
gateway,
|
||||
owner,
|
||||
pledge,
|
||||
} => admin_add_gateway(deps, env, info, gateway, pledge, owner),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,3 +19,5 @@ mod support;
|
||||
|
||||
#[cfg(feature = "contract-testing")]
|
||||
mod testing;
|
||||
|
||||
mod speedtest_tmp;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::gateways::storage::gateways;
|
||||
use crate::mixnet_contract_settings::storage as mixnet_params_storage;
|
||||
use crate::mixnodes::helpers::save_new_mixnode;
|
||||
use crate::support::helpers::ensure_no_existing_bond;
|
||||
use cosmwasm_std::{Coin, DepsMut, Env, MessageInfo, Response};
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
use mixnet_contract_common::{Gateway, GatewayBond, MixNode, MixNodeCostParams};
|
||||
|
||||
pub fn admin_add_mixnode(
|
||||
deps: DepsMut<'_>,
|
||||
env: Env,
|
||||
info: MessageInfo,
|
||||
mixnode: MixNode,
|
||||
cost_params: MixNodeCostParams,
|
||||
pledge: Coin,
|
||||
owner: String,
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
let state = mixnet_params_storage::CONTRACT_STATE.load(deps.storage)?;
|
||||
|
||||
// check if this is executed by the owner, if not reject the transaction
|
||||
if info.sender != state.owner {
|
||||
return Err(MixnetContractError::Unauthorized);
|
||||
}
|
||||
|
||||
let owner = deps.api.addr_validate(&owner)?;
|
||||
|
||||
ensure_no_existing_bond(&owner, deps.storage)?;
|
||||
|
||||
save_new_mixnode(deps.storage, env, mixnode, cost_params, owner, None, pledge)?;
|
||||
|
||||
Ok(Response::new())
|
||||
}
|
||||
|
||||
pub fn admin_add_gateway(
|
||||
deps: DepsMut<'_>,
|
||||
env: Env,
|
||||
info: MessageInfo,
|
||||
gateway: Gateway,
|
||||
pledge: Coin,
|
||||
owner: String,
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
let state = mixnet_params_storage::CONTRACT_STATE.load(deps.storage)?;
|
||||
|
||||
// check if this is executed by the owner, if not reject the transaction
|
||||
if info.sender != state.owner {
|
||||
return Err(MixnetContractError::Unauthorized);
|
||||
}
|
||||
|
||||
let owner = deps.api.addr_validate(&owner)?;
|
||||
|
||||
ensure_no_existing_bond(&owner, deps.storage)?;
|
||||
|
||||
let bond = GatewayBond::new(pledge, owner, env.block.height, gateway, None);
|
||||
gateways().save(deps.storage, bond.identity(), &bond)?;
|
||||
|
||||
Ok(Response::new())
|
||||
}
|
||||
+13
-16
@@ -18,7 +18,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/recommended": "^1.0.1",
|
||||
"prettier": "^2.8.7",
|
||||
"prettier": "^2.2.1",
|
||||
"typescript": "^4.1.3"
|
||||
}
|
||||
},
|
||||
@@ -570,9 +570,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"version": "1.14.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
|
||||
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -875,18 +875,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
|
||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
|
||||
"integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
@@ -1667,9 +1664,9 @@
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
|
||||
"version": "1.14.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
|
||||
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.2",
|
||||
@@ -1888,9 +1885,9 @@
|
||||
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw=="
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
|
||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
|
||||
"integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
|
||||
"dev": true
|
||||
},
|
||||
"protobufjs": {
|
||||
|
||||
@@ -682,8 +682,6 @@ 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 {
|
||||
@@ -697,14 +695,6 @@ 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,6 +2,10 @@
|
||||
|
||||
[//]: # (> The nym-api binary was built in the [building nym](../binaries/building-nym.md) 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?
|
||||
|
||||
@@ -22,3 +22,5 @@ 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"
|
||||
|
||||
+7
-2
@@ -11,13 +11,18 @@ 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"
|
||||
|
||||
@@ -25,4 +25,5 @@ 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"
|
||||
@@ -112,12 +112,12 @@ pub(crate) struct NodeStats {
|
||||
)]
|
||||
previous_update_time: SystemTime,
|
||||
|
||||
packets_received_since_startup: f64,
|
||||
packets_sent_since_startup: f64,
|
||||
packets_explicitly_dropped_since_startup: f64,
|
||||
packets_received_since_last_update: f64,
|
||||
packets_sent_since_last_update: f64,
|
||||
packets_explicitly_dropped_since_last_update: f64,
|
||||
packets_received_since_startup: u64,
|
||||
packets_sent_since_startup: u64,
|
||||
packets_explicitly_dropped_since_startup: u64,
|
||||
packets_received_since_last_update: u64,
|
||||
packets_sent_since_last_update: u64,
|
||||
packets_explicitly_dropped_since_last_update: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, JsonSchema)]
|
||||
|
||||
@@ -28,14 +28,6 @@ nym-sphinx = { path = "../../common/nymsphinx" }
|
||||
nym-credentials = { path = "../../common/credentials" }
|
||||
nym-credentials-interface = { path = "../../common/credentials-interface" }
|
||||
|
||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
|
||||
workspace = true
|
||||
features = ["time"]
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer]
|
||||
workspace = true
|
||||
features = ["tokio"]
|
||||
|
||||
[dependencies.tungstenite]
|
||||
workspace = true
|
||||
default-features = false
|
||||
|
||||
@@ -13,7 +13,7 @@ pub mod models;
|
||||
pub mod registration;
|
||||
pub mod types;
|
||||
|
||||
pub const CURRENT_PROTOCOL_VERSION: u8 = CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION;
|
||||
pub const CURRENT_PROTOCOL_VERSION: u8 = CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION;
|
||||
|
||||
/// Defines the current version of the communication protocol between gateway and clients.
|
||||
/// It has to be incremented for any breaking change.
|
||||
@@ -21,7 +21,7 @@ pub const CURRENT_PROTOCOL_VERSION: u8 = CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION;
|
||||
// 1 - initial release
|
||||
// 2 - changes to client credentials structure
|
||||
pub const INITIAL_PROTOCOL_VERSION: u8 = 1;
|
||||
pub const CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION: u8 = 2;
|
||||
pub const CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION: u8 = 2;
|
||||
|
||||
pub type GatewayMac = HmacOutput<GatewayIntegrityHmacAlgorithm>;
|
||||
|
||||
|
||||
@@ -24,18 +24,11 @@ impl<'a> ClientHandshake<'a> {
|
||||
ws_stream: &'a mut S,
|
||||
identity: &'a nym_crypto::asymmetric::identity::KeyPair,
|
||||
gateway_pubkey: identity::PublicKey,
|
||||
expects_credential_usage: bool,
|
||||
) -> Self
|
||||
where
|
||||
S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a,
|
||||
{
|
||||
let mut state = State::new(
|
||||
rng,
|
||||
ws_stream,
|
||||
identity,
|
||||
Some(gateway_pubkey),
|
||||
expects_credential_usage,
|
||||
);
|
||||
let mut state = State::new(rng, ws_stream, identity, Some(gateway_pubkey));
|
||||
|
||||
ClientHandshake {
|
||||
handshake_future: Box::pin(async move {
|
||||
|
||||
@@ -25,7 +25,4 @@ pub enum HandshakeError {
|
||||
MalformedRequest,
|
||||
#[error("sent request was malformed")]
|
||||
HandshakeFailure,
|
||||
|
||||
#[error("timed out waiting for a handshake message")]
|
||||
Timeout,
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ impl<'a> GatewayHandshake<'a> {
|
||||
where
|
||||
S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a,
|
||||
{
|
||||
let mut state = State::new(rng, ws_stream, identity, None, true);
|
||||
let mut state = State::new(rng, ws_stream, identity, None);
|
||||
GatewayHandshake {
|
||||
handshake_future: Box::pin(async move {
|
||||
// If any step along the way failed (that are non-network related),
|
||||
|
||||
@@ -30,19 +30,11 @@ pub async fn client_handshake<'a, S>(
|
||||
ws_stream: &'a mut S,
|
||||
identity: &'a identity::KeyPair,
|
||||
gateway_pubkey: identity::PublicKey,
|
||||
expects_credential_usage: bool,
|
||||
) -> Result<SharedKeys, HandshakeError>
|
||||
where
|
||||
S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a,
|
||||
{
|
||||
ClientHandshake::new(
|
||||
rng,
|
||||
ws_stream,
|
||||
identity,
|
||||
gateway_pubkey,
|
||||
expects_credential_usage,
|
||||
)
|
||||
.await
|
||||
ClientHandshake::new(rng, ws_stream, identity, gateway_pubkey).await
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::registration::handshake::error::HandshakeError;
|
||||
@@ -15,17 +15,9 @@ use nym_crypto::{
|
||||
};
|
||||
use nym_sphinx::params::{GatewayEncryptionAlgorithm, GatewaySharedKeyHkdfAlgorithm};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use std::convert::TryInto;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use tungstenite::Message as WsMessage;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use tokio::time::timeout;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasmtimer::tokio::timeout;
|
||||
|
||||
/// Handshake state.
|
||||
pub(crate) struct State<'a, S> {
|
||||
/// The underlying WebSocket stream.
|
||||
@@ -44,10 +36,6 @@ pub(crate) struct State<'a, S> {
|
||||
/// The known or received public identity key of the remote.
|
||||
/// Ideally it would always be known before the handshake was initiated.
|
||||
remote_pubkey: Option<identity::PublicKey>,
|
||||
|
||||
// this field is really out of place here, however, we need to propagate this information somehow
|
||||
// in order to establish correct protocol for backwards compatibility reasons
|
||||
expects_credential_usage: bool,
|
||||
}
|
||||
|
||||
impl<'a, S> State<'a, S> {
|
||||
@@ -56,7 +44,6 @@ impl<'a, S> State<'a, S> {
|
||||
ws_stream: &'a mut S,
|
||||
identity: &'a identity::KeyPair,
|
||||
remote_pubkey: Option<identity::PublicKey>,
|
||||
expects_credential_usage: bool,
|
||||
) -> Self {
|
||||
let ephemeral_keypair = encryption::KeyPair::new(rng);
|
||||
State {
|
||||
@@ -65,7 +52,6 @@ impl<'a, S> State<'a, S> {
|
||||
identity,
|
||||
remote_pubkey,
|
||||
derived_shared_keys: None,
|
||||
expects_credential_usage,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +67,15 @@ impl<'a, S> State<'a, S> {
|
||||
self.identity
|
||||
.public_key()
|
||||
.to_bytes()
|
||||
.into_iter()
|
||||
.chain(self.ephemeral_keypair.public_key().to_bytes())
|
||||
.iter()
|
||||
.cloned()
|
||||
.chain(
|
||||
self.ephemeral_keypair
|
||||
.public_key()
|
||||
.to_bytes()
|
||||
.iter()
|
||||
.cloned(),
|
||||
)
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -139,8 +132,9 @@ impl<'a, S> State<'a, S> {
|
||||
.ephemeral_keypair
|
||||
.public_key()
|
||||
.to_bytes()
|
||||
.into_iter()
|
||||
.chain(remote_ephemeral_key.to_bytes())
|
||||
.iter()
|
||||
.cloned()
|
||||
.chain(remote_ephemeral_key.to_bytes().iter().cloned())
|
||||
.collect();
|
||||
|
||||
let signature = self.identity.private_key().sign(message);
|
||||
@@ -183,8 +177,15 @@ impl<'a, S> State<'a, S> {
|
||||
// g^y || g^x, if y is remote and x is local
|
||||
let signed_payload: Vec<_> = remote_ephemeral_key
|
||||
.to_bytes()
|
||||
.into_iter()
|
||||
.chain(self.ephemeral_keypair.public_key().to_bytes())
|
||||
.iter()
|
||||
.cloned()
|
||||
.chain(
|
||||
self.ephemeral_keypair
|
||||
.public_key()
|
||||
.to_bytes()
|
||||
.iter()
|
||||
.cloned(),
|
||||
)
|
||||
.collect();
|
||||
|
||||
self.remote_pubkey
|
||||
@@ -199,54 +200,33 @@ impl<'a, S> State<'a, S> {
|
||||
self.remote_pubkey = Some(remote_pubkey)
|
||||
}
|
||||
|
||||
async fn _receive_handshake_message(&mut self) -> Result<Vec<u8>, HandshakeError>
|
||||
where
|
||||
S: Stream<Item = WsItem> + Unpin,
|
||||
{
|
||||
loop {
|
||||
let Some(msg) = self.ws_stream.next().await else {
|
||||
return Err(HandshakeError::ClosedStream);
|
||||
};
|
||||
|
||||
let Ok(msg) = msg else {
|
||||
return Err(HandshakeError::NetworkError);
|
||||
};
|
||||
|
||||
match msg {
|
||||
WsMessage::Text(ref ws_msg) => {
|
||||
match types::RegistrationHandshake::from_str(ws_msg) {
|
||||
Ok(reg_handshake_msg) => {
|
||||
return match reg_handshake_msg {
|
||||
// hehe, that's a bit disgusting that the type system requires we explicitly ignore the
|
||||
// protocol_version field that we actually never attach at this point
|
||||
// yet another reason for the overdue refactor
|
||||
types::RegistrationHandshake::HandshakePayload { data, .. } => {
|
||||
Ok(data)
|
||||
}
|
||||
types::RegistrationHandshake::HandshakeError { message } => {
|
||||
Err(HandshakeError::RemoteError(message))
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(_) => {
|
||||
error!("Received a non-handshake message during the registration handshake! It's getting dropped. The received content was: '{msg}'");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => error!("Received non-text message during registration handshake"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_handshake_message(&mut self) -> Result<Vec<u8>, HandshakeError>
|
||||
where
|
||||
S: Stream<Item = WsItem> + Unpin,
|
||||
{
|
||||
// TODO: make timeout duration configurable
|
||||
timeout(Duration::from_secs(5), self._receive_handshake_message())
|
||||
.await
|
||||
.map_err(|_| HandshakeError::Timeout)?
|
||||
loop {
|
||||
if let Some(msg) = self.ws_stream.next().await {
|
||||
if let Ok(msg) = msg {
|
||||
match msg {
|
||||
WsMessage::Text(ws_msg) => match types::RegistrationHandshake::try_from(ws_msg) {
|
||||
Ok(reg_handshake_msg) => return match reg_handshake_msg {
|
||||
// hehe, that's a bit disgusting that the type system requires we explicitly ignore the
|
||||
// protocol_version field that we actually never attach at this point
|
||||
// yet another reason for the overdue refactor
|
||||
types::RegistrationHandshake::HandshakePayload { data, .. } => Ok(data),
|
||||
types::RegistrationHandshake::HandshakeError { message } => Err(HandshakeError::RemoteError(message)),
|
||||
},
|
||||
Err(_) => error!("Received a non-handshake message during the registration handshake! It's getting dropped."),
|
||||
},
|
||||
_ => error!("Received non-text message during registration handshake"),
|
||||
}
|
||||
} else {
|
||||
return Err(HandshakeError::NetworkError);
|
||||
}
|
||||
} else {
|
||||
return Err(HandshakeError::ClosedStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// upon receiving this, the receiver should terminate the handshake
|
||||
@@ -271,8 +251,7 @@ impl<'a, S> State<'a, S> {
|
||||
where
|
||||
S: Sink<WsMessage> + Unpin,
|
||||
{
|
||||
let handshake_message =
|
||||
types::RegistrationHandshake::new_payload(payload, self.expects_credential_usage);
|
||||
let handshake_message = types::RegistrationHandshake::new_payload(payload);
|
||||
self.ws_stream
|
||||
.send(WsMessage::Text(handshake_message.try_into().unwrap()))
|
||||
.await
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::authentication::encrypted_address::EncryptedAddressBytes;
|
||||
use crate::iv::IV;
|
||||
use crate::models::{CredentialSpendingRequest, OldV1Credential};
|
||||
use crate::registration::handshake::SharedKeys;
|
||||
use crate::{GatewayMacSize, CURRENT_PROTOCOL_VERSION, INITIAL_PROTOCOL_VERSION};
|
||||
use crate::{GatewayMacSize, CURRENT_PROTOCOL_VERSION};
|
||||
use log::error;
|
||||
use nym_credentials::coconut::bandwidth::CredentialSpendingData;
|
||||
use nym_credentials_interface::{CoconutError, UnknownCredentialType};
|
||||
@@ -19,7 +19,6 @@ use nym_sphinx::params::{GatewayEncryptionAlgorithm, GatewayIntegrityHmacAlgorit
|
||||
use nym_sphinx::DestinationAddressBytes;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::str::FromStr;
|
||||
use std::string::FromUtf8Error;
|
||||
use thiserror::Error;
|
||||
use tungstenite::protocol::Message;
|
||||
@@ -38,17 +37,9 @@ pub enum RegistrationHandshake {
|
||||
}
|
||||
|
||||
impl RegistrationHandshake {
|
||||
pub fn new_payload(data: Vec<u8>, will_use_credentials: bool) -> Self {
|
||||
// if we're not going to be using credentials, advertise lower protocol version to allow connection
|
||||
// to wider range of gateways
|
||||
let protocol_version = if will_use_credentials {
|
||||
Some(CURRENT_PROTOCOL_VERSION)
|
||||
} else {
|
||||
Some(INITIAL_PROTOCOL_VERSION)
|
||||
};
|
||||
|
||||
pub fn new_payload(data: Vec<u8>) -> Self {
|
||||
RegistrationHandshake::HandshakePayload {
|
||||
protocol_version,
|
||||
protocol_version: Some(CURRENT_PROTOCOL_VERSION),
|
||||
data,
|
||||
}
|
||||
}
|
||||
@@ -60,19 +51,11 @@ impl RegistrationHandshake {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for RegistrationHandshake {
|
||||
type Err = serde_json::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
serde_json::from_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for RegistrationHandshake {
|
||||
type Error = serde_json::Error;
|
||||
|
||||
fn try_from(msg: String) -> Result<Self, serde_json::Error> {
|
||||
msg.parse()
|
||||
serde_json::from_str(&msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,18 +155,9 @@ impl ClientControlRequest {
|
||||
address: DestinationAddressBytes,
|
||||
enc_address: EncryptedAddressBytes,
|
||||
iv: IV,
|
||||
uses_credentials: bool,
|
||||
) -> Self {
|
||||
// if we're not going to be using credentials, advertise lower protocol version to allow connection
|
||||
// to wider range of gateways
|
||||
let protocol_version = if uses_credentials {
|
||||
Some(CURRENT_PROTOCOL_VERSION)
|
||||
} else {
|
||||
Some(INITIAL_PROTOCOL_VERSION)
|
||||
};
|
||||
|
||||
ClientControlRequest::Authenticate {
|
||||
protocol_version,
|
||||
protocol_version: Some(CURRENT_PROTOCOL_VERSION),
|
||||
address: address.as_base58_string(),
|
||||
enc_address: enc_address.to_base58_string(),
|
||||
iv: iv.to_base58_string(),
|
||||
|
||||
@@ -88,19 +88,18 @@ impl OverrideConfig {
|
||||
if config.network_requester.enabled
|
||||
&& config.storage_paths.network_requester_config.is_none()
|
||||
{
|
||||
config = config.with_default_network_requester_config_path();
|
||||
}
|
||||
|
||||
if config.ip_packet_router.enabled && config.storage_paths.ip_packet_router_config.is_none()
|
||||
Ok(config.with_default_network_requester_config_path())
|
||||
} else if config.ip_packet_router.enabled
|
||||
&& config.storage_paths.ip_packet_router_config.is_none()
|
||||
{
|
||||
config = config.with_default_ip_packet_router_config_path();
|
||||
Ok(config.with_default_ip_packet_router_config_path())
|
||||
} else {
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
#[derive(Default)]
|
||||
pub(crate) struct OverrideNetworkRequesterConfig {
|
||||
pub(crate) fastmode: bool,
|
||||
pub(crate) no_cover: bool,
|
||||
@@ -113,7 +112,7 @@ pub(crate) struct OverrideNetworkRequesterConfig {
|
||||
pub(crate) statistics_recipient: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
#[derive(Default)]
|
||||
pub(crate) struct OverrideIpPacketRouterConfig {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ use std::{fs, io};
|
||||
|
||||
use super::helpers::OverrideIpPacketRouterConfig;
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
#[derive(Args, Clone)]
|
||||
pub struct Init {
|
||||
/// Id of the gateway we want to create config for
|
||||
#[clap(long)]
|
||||
@@ -82,11 +82,11 @@ pub struct Init {
|
||||
statistics_service_url: Option<url::Url>,
|
||||
|
||||
/// Allows this gateway to run an embedded network requester for minimal network overhead
|
||||
#[clap(long)]
|
||||
#[clap(long, conflicts_with = "with_ip_packet_router")]
|
||||
with_network_requester: bool,
|
||||
|
||||
/// Allows this gateway to run an embedded network requester for minimal network overhead
|
||||
#[clap(long, hide = true)]
|
||||
#[clap(long, hide = true, conflicts_with = "with_network_requester")]
|
||||
with_ip_packet_router: bool,
|
||||
|
||||
// ##### NETWORK REQUESTER FLAGS #####
|
||||
@@ -243,9 +243,7 @@ pub async fn execute(args: Init) -> anyhow::Result<()> {
|
||||
if config.network_requester.enabled {
|
||||
initialise_local_network_requester(&config, nr_opts, *identity_keys.public_key())
|
||||
.await?;
|
||||
}
|
||||
|
||||
if config.ip_packet_router.enabled {
|
||||
} else if config.ip_packet_router.enabled {
|
||||
initialise_local_ip_packet_router(&config, ip_opts, *identity_keys.public_key())
|
||||
.await?;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::Cli;
|
||||
use clap::CommandFactory;
|
||||
use clap::Subcommand;
|
||||
use nym_bin_common::completions::{fig_generate, ArgShell};
|
||||
use std::error::Error;
|
||||
|
||||
pub(crate) mod build_info;
|
||||
pub(crate) mod helpers;
|
||||
@@ -49,7 +50,7 @@ pub(crate) enum Commands {
|
||||
GenerateFigSpec,
|
||||
}
|
||||
|
||||
pub(crate) async fn execute(args: Cli) -> anyhow::Result<()> {
|
||||
pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
let bin_name = "nym-gateway";
|
||||
|
||||
match args.command {
|
||||
|
||||
@@ -87,11 +87,11 @@ pub struct Run {
|
||||
statistics_service_url: Option<url::Url>,
|
||||
|
||||
/// Allows this gateway to run an embedded network requester for minimal network overhead
|
||||
#[arg(long)]
|
||||
#[arg(long, conflicts_with = "with_ip_packet_router")]
|
||||
with_network_requester: Option<bool>,
|
||||
|
||||
/// Allows this gateway to run an embedded network requester for minimal network overhead
|
||||
#[arg(long, hide = true)]
|
||||
#[arg(long, hide = true, conflicts_with = "with_network_requester")]
|
||||
with_ip_packet_router: Option<bool>,
|
||||
|
||||
// ##### NETWORK REQUESTER FLAGS #####
|
||||
|
||||
+2
-1
@@ -11,6 +11,7 @@ use nym_bin_common::bin_info;
|
||||
use nym_bin_common::logging::{maybe_print_banner, setup_logging};
|
||||
use nym_bin_common::output_format::OutputFormat;
|
||||
use nym_network_defaults::setup_env;
|
||||
use std::error::Error;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
mod commands;
|
||||
@@ -41,7 +42,7 @@ struct Cli {
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
setup_logging();
|
||||
|
||||
let args = Cli::parse();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use super::websocket::message_receiver::{IsActiveRequestSender, MixMessageSender};
|
||||
use crate::node::client_handling::embedded_clients::LocalEmbeddedClientHandle;
|
||||
use crate::node::client_handling::embedded_network_requester::LocalNetworkRequesterHandle;
|
||||
use dashmap::DashMap;
|
||||
use log::warn;
|
||||
use nym_sphinx::DestinationAddressBytes;
|
||||
@@ -12,8 +12,8 @@ enum ActiveClient {
|
||||
/// Handle to a remote client connected via a network socket.
|
||||
Remote(ClientIncomingChannels),
|
||||
|
||||
/// Handle to a locally (inside the same process) running client.
|
||||
Embedded(LocalEmbeddedClientHandle),
|
||||
/// Handle to a locally (inside the same process) running network requester client.
|
||||
Embedded(LocalNetworkRequesterHandle),
|
||||
}
|
||||
|
||||
impl ActiveClient {
|
||||
@@ -149,14 +149,13 @@ impl ActiveClientsStore {
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts a handle to the embedded client
|
||||
pub(crate) fn insert_embedded(&self, local_client_handle: LocalEmbeddedClientHandle) {
|
||||
let key = local_client_handle.client_destination();
|
||||
let entry = ActiveClient::Embedded(local_client_handle);
|
||||
/// Inserts a handle to the embedded network requester
|
||||
pub(crate) fn insert_embedded(&self, local_nr_handle: LocalNetworkRequesterHandle) {
|
||||
let key = local_nr_handle.client_destination();
|
||||
let entry = ActiveClient::Embedded(local_nr_handle);
|
||||
if self.inner.insert(key, entry).is_some() {
|
||||
// this is literally impossible since we're starting the local embedded client before
|
||||
// even spawning the websocket listener task
|
||||
panic!("somehow we already had a client with the same address as our local embedded client!")
|
||||
// this is literally impossible since we're starting local NR before even spawning the websocket listener task
|
||||
panic!("somehow we already had a client with the same address as our local NR!")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-11
@@ -12,15 +12,15 @@ use nym_sphinx::DestinationAddressBytes;
|
||||
use nym_task::TaskClient;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct LocalEmbeddedClientHandle {
|
||||
/// Nym address of the embedded client.
|
||||
pub(crate) struct LocalNetworkRequesterHandle {
|
||||
/// Nym address of the embedded network requester.
|
||||
pub(crate) address: Recipient,
|
||||
|
||||
/// Message channel used internally to forward any received mix packets to the client.
|
||||
/// Message channel used internally to forward any received mix packets to the network requester.
|
||||
pub(crate) mix_message_sender: MixMessageSender,
|
||||
}
|
||||
|
||||
impl LocalEmbeddedClientHandle {
|
||||
impl LocalNetworkRequesterHandle {
|
||||
pub(crate) fn new(address: Recipient, mix_message_sender: MixMessageSender) -> Self {
|
||||
Self {
|
||||
address,
|
||||
@@ -28,6 +28,17 @@ impl LocalEmbeddedClientHandle {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: generalize this whole thing to be general. And change the name(s).
|
||||
pub(crate) fn new_ip(
|
||||
start_data: nym_ip_packet_router::OnStartData,
|
||||
mix_message_sender: MixMessageSender,
|
||||
) -> Self {
|
||||
Self {
|
||||
address: start_data.address,
|
||||
mix_message_sender,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn client_destination(&self) -> DestinationAddressBytes {
|
||||
self.address.identity().derive_destination_address()
|
||||
}
|
||||
@@ -37,8 +48,8 @@ impl LocalEmbeddedClientHandle {
|
||||
// calling the method. however, this would have caused slightly more complexity and more overhead
|
||||
// (due to more data being copied to every [mix] connection)
|
||||
//
|
||||
/// task responsible for receiving messages for locally embedded clients from multiple mix
|
||||
/// connections and forwarding them via the router. kinda equivalent of a client socket handler
|
||||
/// task responsible for receiving messages for locally NR requester from multiple mix connections
|
||||
/// and forwarding them via the router. kinda equivalent of a client socket handler
|
||||
pub(crate) struct MessageRouter {
|
||||
mix_receiver: MixMessageReceiver,
|
||||
packet_router: PacketRouter,
|
||||
@@ -60,29 +71,29 @@ impl MessageRouter {
|
||||
if let Err(err) = self.packet_router.route_received(messages) {
|
||||
// TODO: what should we do here? I don't think this could/should ever fail.
|
||||
// is panicking the appropriate thing to do then?
|
||||
error!("failed to route packets to local embedded client: {err}")
|
||||
error!("failed to route packets to local NR: {err}")
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn run_with_shutdown(mut self, mut shutdown: TaskClient) {
|
||||
debug!("Started embedded client message router with graceful shutdown support");
|
||||
debug!("Started embedded network requester message router with graceful shutdown support");
|
||||
while !shutdown.is_shutdown() {
|
||||
tokio::select! {
|
||||
messages = self.mix_receiver.next() => match messages {
|
||||
Some(messages) => self.handle_received_messages(messages),
|
||||
None => {
|
||||
log::trace!("embedded_clients::MessageRouter: Stopping since channel closed");
|
||||
log::trace!("embedded_network_requester::MessageRouter: Stopping since channel closed");
|
||||
break;
|
||||
}
|
||||
},
|
||||
_ = shutdown.recv_with_delay() => {
|
||||
log::trace!("embedded_clients::MessageRouter: Received shutdown");
|
||||
log::trace!("embedded_network_requester::MessageRouter: Received shutdown");
|
||||
debug_assert!(shutdown.is_shutdown());
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!("embedded_network_clients::MessageRouter: Exiting")
|
||||
debug!("embedded_network_requester::MessageRouter: Exiting")
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ use crate::node::client_handling::bandwidth::Bandwidth;
|
||||
|
||||
pub(crate) mod active_clients;
|
||||
mod bandwidth;
|
||||
pub(crate) mod embedded_clients;
|
||||
pub(crate) mod embedded_network_requester;
|
||||
pub(crate) mod websocket;
|
||||
|
||||
pub(crate) const FREE_TESTNET_BANDWIDTH_VALUE: Bandwidth = Bandwidth::new(64 * 1024 * 1024 * 1024); // 64GB
|
||||
|
||||
@@ -92,9 +92,6 @@ pub(crate) enum RequestHandlingError {
|
||||
|
||||
#[error("the provided credential did not have a bandwidth attribute")]
|
||||
MissingBandwidthAttribute,
|
||||
|
||||
#[error("the DKG contract is unavailable")]
|
||||
UnavailableDkgContract,
|
||||
}
|
||||
|
||||
impl RequestHandlingError {
|
||||
@@ -603,7 +600,7 @@ where
|
||||
None => break,
|
||||
Some(Ok(socket_msg)) => socket_msg,
|
||||
Some(Err(err)) => {
|
||||
debug!("failed to obtain message from websocket stream! stopping connection handler: {err}");
|
||||
error!("failed to obtain message from websocket stream! stopping connection handler: {err}");
|
||||
break;
|
||||
}
|
||||
};
|
||||
@@ -614,7 +611,7 @@ where
|
||||
|
||||
if let Some(response) = self.handle_request(socket_msg).await {
|
||||
if let Err(err) = self.inner.send_websocket_message(response).await {
|
||||
debug!(
|
||||
warn!(
|
||||
"Failed to send message over websocket: {err}. Assuming the connection is dead.",
|
||||
);
|
||||
break;
|
||||
@@ -624,13 +621,13 @@ where
|
||||
mix_messages = self.mix_receiver.next() => {
|
||||
let mix_messages = match mix_messages {
|
||||
None => {
|
||||
debug!("mix receiver was closed! Assuming the connection is dead.");
|
||||
warn!("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 {
|
||||
debug!("failed to send the unwrapped sphinx packets back to the client - {err}, assuming the connection is dead");
|
||||
warn!("failed to send the unwrapped sphinx packets back to the client - {err}, assuming the connection is dead");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ 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();
|
||||
@@ -46,17 +45,9 @@ 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() {
|
||||
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);
|
||||
}
|
||||
|
||||
error!(
|
||||
"DKG contract address is not available - no coconut credentials will be redeemable"
|
||||
);
|
||||
return Ok(CoconutVerifier {
|
||||
address,
|
||||
nyxd_client: RwLock::new(nyxd_client),
|
||||
@@ -69,10 +60,6 @@ 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) => {
|
||||
debug!("failed to obtain message from websocket stream! stopping connection handler: {err}");
|
||||
error!("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
|
||||
debug!("possibly received a sphinx packet without prior authentication. Request is going to be ignored");
|
||||
warn!("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(
|
||||
|
||||
+22
-11
@@ -11,7 +11,9 @@ use crate::config::Config;
|
||||
use crate::error::GatewayError;
|
||||
use crate::http::HttpApiBuilder;
|
||||
use crate::node::client_handling::active_clients::ActiveClientsStore;
|
||||
use crate::node::client_handling::embedded_clients::{LocalEmbeddedClientHandle, MessageRouter};
|
||||
use crate::node::client_handling::embedded_network_requester::{
|
||||
LocalNetworkRequesterHandle, MessageRouter,
|
||||
};
|
||||
use crate::node::client_handling::websocket;
|
||||
use crate::node::client_handling::websocket::connection_handler::coconut::CoconutVerifier;
|
||||
use crate::node::helpers::{initialise_main_storage, load_network_requester_config};
|
||||
@@ -49,7 +51,7 @@ struct StartedNetworkRequester {
|
||||
used_request_filter: RequestFilter,
|
||||
|
||||
/// Handle to interact with the local network requester
|
||||
handle: LocalEmbeddedClientHandle,
|
||||
handle: LocalNetworkRequesterHandle,
|
||||
}
|
||||
|
||||
/// Wire up and create Gateway instance
|
||||
@@ -78,7 +80,7 @@ pub(crate) async fn create_gateway(
|
||||
let cfg = load_ip_packet_router_config(&config.gateway.id, path)?;
|
||||
Some(override_ip_packet_router_config(cfg, ip_config_override))
|
||||
} else {
|
||||
// if IPR is enabled, the config path must be specified
|
||||
// if NR is enabled, the config path must be specified
|
||||
return Err(GatewayError::UnspecifiedIpPacketRouterConfig);
|
||||
}
|
||||
} else {
|
||||
@@ -317,7 +319,7 @@ impl<St> Gateway<St> {
|
||||
info!("the local network requester is running on {address}",);
|
||||
Ok(StartedNetworkRequester {
|
||||
used_request_filter: start_data.request_filter,
|
||||
handle: LocalEmbeddedClientHandle::new(address, nr_mix_sender),
|
||||
handle: LocalNetworkRequesterHandle::new(address, nr_mix_sender),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -325,16 +327,17 @@ impl<St> Gateway<St> {
|
||||
&self,
|
||||
forwarding_channel: MixForwardingSender,
|
||||
shutdown: TaskClient,
|
||||
) -> Result<LocalEmbeddedClientHandle, GatewayError> {
|
||||
) -> Result<LocalNetworkRequesterHandle, GatewayError> {
|
||||
info!("Starting IP packet provider...");
|
||||
|
||||
// if network requester is enabled, configuration file must be provided!
|
||||
let Some(ip_opts) = &self.ip_packet_router_opts else {
|
||||
log::error!("IP packet router is enabled but no configuration file was provided!");
|
||||
return Err(GatewayError::UnspecifiedIpPacketRouterConfig);
|
||||
};
|
||||
|
||||
// this gateway, whenever it has anything to send to its local NR will use fake_client_tx
|
||||
let (ipr_mix_sender, ipr_mix_receiver) = mpsc::unbounded();
|
||||
let (nr_mix_sender, nr_mix_receiver) = mpsc::unbounded();
|
||||
let router_shutdown = shutdown.fork("message_router");
|
||||
|
||||
let (router_tx, mut router_rx) = oneshot::channel();
|
||||
@@ -345,6 +348,7 @@ impl<St> Gateway<St> {
|
||||
router_tx,
|
||||
);
|
||||
|
||||
// TODO: well, wire it up internally to gateway traffic, shutdowns, etc.
|
||||
let (on_start_tx, on_start_rx) = oneshot::channel();
|
||||
let mut ip_packet_router =
|
||||
nym_ip_packet_router::IpPacketRouter::new(ip_opts.config.clone())
|
||||
@@ -375,11 +379,16 @@ impl<St> Gateway<St> {
|
||||
return Err(GatewayError::IpPacketRouterStartupFailure);
|
||||
};
|
||||
|
||||
MessageRouter::new(ipr_mix_receiver, packet_router).start_with_shutdown(router_shutdown);
|
||||
let address = start_data.address;
|
||||
MessageRouter::new(nr_mix_receiver, packet_router).start_with_shutdown(router_shutdown);
|
||||
info!(
|
||||
"the local ip packet router is running on {}",
|
||||
start_data.address
|
||||
);
|
||||
|
||||
info!("the local ip packet router is running on {address}");
|
||||
Ok(LocalEmbeddedClientHandle::new(address, ipr_mix_sender))
|
||||
Ok(LocalNetworkRequesterHandle::new_ip(
|
||||
start_data,
|
||||
nr_mix_sender,
|
||||
))
|
||||
}
|
||||
|
||||
async fn wait_for_interrupt(
|
||||
@@ -447,7 +456,7 @@ impl<St> Gateway<St> {
|
||||
|
||||
let coconut_verifier = {
|
||||
let nyxd_client = self.random_nyxd_client()?;
|
||||
CoconutVerifier::new(nyxd_client, self.config.gateway.only_coconut_credentials).await
|
||||
CoconutVerifier::new(nyxd_client).await
|
||||
}?;
|
||||
|
||||
let mix_forwarding_channel =
|
||||
@@ -495,6 +504,8 @@ impl<St> Gateway<St> {
|
||||
None
|
||||
};
|
||||
|
||||
// NOTE: this is mutually exclusive with the network requester (for now). This is reflected
|
||||
// in the command line arguments as well.
|
||||
if self.config.ip_packet_router.enabled {
|
||||
let embedded_ip_sp = self
|
||||
.start_ip_packet_router(
|
||||
|
||||
+15
-2
@@ -26,7 +26,6 @@ cupid = "0.6.1"
|
||||
dirs = "4.0"
|
||||
futures = { workspace = true }
|
||||
humantime-serde = "1.0"
|
||||
lazy_static = "1.4"
|
||||
log = { workspace = true }
|
||||
rand = "0.7.3"
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
@@ -36,8 +35,14 @@ tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] }
|
||||
tokio-util = { workspace = true, features = ["codec"] }
|
||||
toml = "0.5.8"
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
cfg-if = "1.0.0"
|
||||
thiserror = { workspace = true }
|
||||
|
||||
## tracing
|
||||
tracing = { workspace = true, optional = true }
|
||||
opentelemetry = { version = "0.19.0", optional = true }
|
||||
|
||||
|
||||
# internal
|
||||
nym-node = { path = "../nym-node" }
|
||||
|
||||
@@ -46,7 +51,6 @@ nym-crypto = { path = "../common/crypto" }
|
||||
nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" }
|
||||
nym-mixnet-client = { path = "../common/client-libs/mixnet-client" }
|
||||
nym-mixnode-common = { path = "../common/mixnode-common" }
|
||||
nym-metrics = { path = "../common/nym-metrics" }
|
||||
nym-nonexhaustive-delayqueue = { path = "../common/nonexhaustive-delayqueue" }
|
||||
nym-sphinx = { path = "../common/nymsphinx" }
|
||||
nym-sphinx-params = { path = "../common/nymsphinx/params" }
|
||||
@@ -56,6 +60,7 @@ nym-types = { path = "../common/types" }
|
||||
nym-topology = { path = "../common/topology" }
|
||||
nym-validator-client = { path = "../common/client-libs/validator-client" }
|
||||
nym-bin-common = { path = "../common/bin-common", features = ["output_format"] }
|
||||
cpu-cycles = { path = "../cpu-cycles", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { workspace = true, features = [
|
||||
@@ -68,6 +73,14 @@ tokio = { workspace = true, features = [
|
||||
nym-sphinx-types = { path = "../common/nymsphinx/types" }
|
||||
nym-sphinx-params = { path = "../common/nymsphinx/params" }
|
||||
|
||||
[features]
|
||||
cpucycles = [
|
||||
"nym-mixnode-common/cpucycles",
|
||||
"tracing",
|
||||
"opentelemetry",
|
||||
"nym-bin-common/tracing",
|
||||
]
|
||||
|
||||
[package.metadata.deb]
|
||||
name = "nym-mixnode"
|
||||
maintainer-scripts = "debian"
|
||||
|
||||
@@ -42,9 +42,6 @@ pub(crate) struct Init {
|
||||
|
||||
#[clap(short, long, default_value_t = OutputFormat::default())]
|
||||
output: OutputFormat,
|
||||
|
||||
#[clap(long)]
|
||||
metrics_key: Option<String>,
|
||||
}
|
||||
|
||||
impl From<Init> for OverrideConfig {
|
||||
@@ -56,7 +53,6 @@ impl From<Init> for OverrideConfig {
|
||||
verloc_port: init_config.verloc_port,
|
||||
http_api_port: init_config.http_api_port,
|
||||
nym_apis: init_config.nym_apis,
|
||||
metrics_key: init_config.metrics_key,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ struct OverrideConfig {
|
||||
verloc_port: Option<u16>,
|
||||
http_api_port: Option<u16>,
|
||||
nym_apis: Option<Vec<url::Url>>,
|
||||
metrics_key: Option<String>,
|
||||
}
|
||||
|
||||
pub(crate) async fn execute(args: Cli) -> anyhow::Result<()> {
|
||||
@@ -84,7 +83,6 @@ fn override_config(config: Config, args: OverrideConfig) -> Config {
|
||||
.with_optional(Config::with_mix_port, args.mix_port)
|
||||
.with_optional(Config::with_verloc_port, args.verloc_port)
|
||||
.with_optional(Config::with_http_api_port, args.http_api_port)
|
||||
.with_optional(Config::with_metrics_key, args.metrics_key)
|
||||
.with_optional_custom_env(
|
||||
Config::with_custom_nym_apis,
|
||||
args.nym_apis,
|
||||
|
||||
@@ -44,9 +44,6 @@ pub(crate) struct Run {
|
||||
|
||||
#[clap(short, long, default_value_t = OutputFormat::default())]
|
||||
output: OutputFormat,
|
||||
|
||||
#[clap(long)]
|
||||
metrics_key: Option<String>,
|
||||
}
|
||||
|
||||
impl From<Run> for OverrideConfig {
|
||||
@@ -58,7 +55,6 @@ impl From<Run> for OverrideConfig {
|
||||
verloc_port: run_config.verloc_port,
|
||||
http_api_port: run_config.http_api_port,
|
||||
nym_apis: run_config.nym_apis,
|
||||
metrics_key: run_config.metrics_key,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,6 @@ fn default_mixnode_http_config() -> config::Http {
|
||||
DEFAULT_HTTP_API_LISTENING_PORT,
|
||||
),
|
||||
landing_page_assets_path: None,
|
||||
metrics_key: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,15 +208,6 @@ impl Config {
|
||||
pub fn get_nym_api_endpoints(&self) -> Vec<Url> {
|
||||
self.mixnode.nym_api_urls.clone()
|
||||
}
|
||||
|
||||
pub fn with_metrics_key(mut self, metrics_key: String) -> Self {
|
||||
self.http.metrics_key = Some(metrics_key);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn metrics_key(&self) -> Option<&String> {
|
||||
self.http.metrics_key.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
|
||||
@@ -95,7 +95,6 @@ impl From<ConfigV1_1_32> for Config {
|
||||
value.mixnode.http_api_port,
|
||||
),
|
||||
landing_page_assets_path: None,
|
||||
metrics_key: None,
|
||||
},
|
||||
// /\ ADDED
|
||||
mixnode: MixNode {
|
||||
|
||||
@@ -57,8 +57,6 @@ bind_address = '{{ http.bind_address }}'
|
||||
# Path to assets directory of custom landing page of this node
|
||||
landing_page_assets_path = '{{ http.landing_page_assets_path }}'
|
||||
|
||||
metrics_key = '{{ http.metrics_key }}'
|
||||
|
||||
[storage_paths]
|
||||
|
||||
# Path to file containing private identity key.
|
||||
|
||||
+27
-1
@@ -3,11 +3,18 @@
|
||||
|
||||
use ::nym_config::defaults::setup_env;
|
||||
use clap::{crate_name, crate_version, Parser};
|
||||
use log::info;
|
||||
use nym_bin_common::bin_info;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use nym_bin_common::logging::{maybe_print_banner, setup_logging};
|
||||
#[cfg(feature = "cpucycles")]
|
||||
use nym_bin_common::setup_tracing;
|
||||
#[cfg(feature = "cpucycles")]
|
||||
use nym_mixnode_common::measure;
|
||||
#[cfg(feature = "cpucycles")]
|
||||
use tracing::instrument;
|
||||
|
||||
mod commands;
|
||||
mod config;
|
||||
@@ -34,6 +41,12 @@ struct Cli {
|
||||
command: commands::Commands,
|
||||
}
|
||||
|
||||
#[cfg(feature = "cpucycles")]
|
||||
#[instrument(fields(cpucycles))]
|
||||
fn test_function() {
|
||||
measure!({})
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let args = Cli::parse();
|
||||
@@ -43,10 +56,23 @@ async fn main() -> anyhow::Result<()> {
|
||||
maybe_print_banner(crate_name!(), crate_version!());
|
||||
}
|
||||
|
||||
setup_logging();
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "cpucycles")] {
|
||||
setup_tracing!("mixnode");
|
||||
info!("CPU cycles measurement is ON")
|
||||
} else {
|
||||
setup_logging();
|
||||
info!("CPU cycles measurement is OFF")
|
||||
}
|
||||
}
|
||||
|
||||
commands::execute(args).await?;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "cpucycles")] {
|
||||
opentelemetry::global::shutdown_tracer_provider();
|
||||
}}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
use crate::node::http::legacy::description::description;
|
||||
use crate::node::http::legacy::hardware::hardware;
|
||||
use crate::node::http::legacy::state::MixnodeAppState;
|
||||
use crate::node::http::legacy::stats::metrics;
|
||||
use crate::node::http::legacy::stats::stats;
|
||||
use crate::node::http::legacy::verloc::verloc;
|
||||
use crate::node::node_description::NodeDescription;
|
||||
@@ -30,7 +29,6 @@ pub(crate) mod api_routes {
|
||||
pub(crate) const VERLOC: &str = "/verloc";
|
||||
pub(crate) const DESCRIPTION: &str = "/description";
|
||||
pub(crate) const STATS: &str = "/stats";
|
||||
pub(crate) const METRICS: &str = "/metrics";
|
||||
pub(crate) const HARDWARE: &str = "/hardware";
|
||||
}
|
||||
|
||||
@@ -46,7 +44,6 @@ pub(crate) fn routes<S: Send + Sync + 'static + Clone>(
|
||||
)
|
||||
.route(api_routes::STATS, get(stats))
|
||||
.route(api_routes::HARDWARE, get(hardware))
|
||||
.route(api_routes::METRICS, get(metrics))
|
||||
.fallback(not_found)
|
||||
.with_state(state)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ use axum::extract::FromRef;
|
||||
pub(crate) struct MixnodeAppState {
|
||||
pub(crate) verloc: VerlocState,
|
||||
pub(crate) stats: SharedNodeStats,
|
||||
pub(crate) metrics_key: Option<String>,
|
||||
}
|
||||
|
||||
impl FromRef<MixnodeAppState> for VerlocState {
|
||||
|
||||
@@ -1,59 +1,33 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::node::node_statistics::{NodeStatsSimple, SharedNodeStats};
|
||||
|
||||
use axum::{
|
||||
extract::{Query, State},
|
||||
http::HeaderMap,
|
||||
};
|
||||
use nym_metrics::metrics;
|
||||
use crate::node::node_statistics::{NodeStats, NodeStatsSimple, SharedNodeStats};
|
||||
use axum::extract::{Query, State};
|
||||
use nym_node::http::api::{FormattedResponse, Output};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::state::MixnodeAppState;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum NodeStatsResponse {
|
||||
Full(String),
|
||||
Full(NodeStats),
|
||||
Simple(NodeStatsSimple),
|
||||
}
|
||||
|
||||
pub(crate) async fn metrics(State(state): State<MixnodeAppState>, headers: HeaderMap) -> String {
|
||||
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) {
|
||||
metrics!()
|
||||
} else {
|
||||
"Unauthorized".to_string()
|
||||
}
|
||||
} else {
|
||||
"Unauthorized".to_string()
|
||||
}
|
||||
} else {
|
||||
"Set metrics_key in config to enable Prometheus metrics".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn stats(
|
||||
Query(params): Query<StatsQueryParams>,
|
||||
State(stats): State<SharedNodeStats>,
|
||||
) -> MixnodeStatsResponse {
|
||||
let output = params.output.unwrap_or_default();
|
||||
|
||||
// there's no point in returning the entire hashmap of sending destinations in regular mode
|
||||
let response = generate_stats(params.debug, stats).await;
|
||||
output.to_response(response)
|
||||
}
|
||||
|
||||
async fn generate_stats(full: bool, stats: SharedNodeStats) -> NodeStatsResponse {
|
||||
let snapshot_data = stats.clone_data().await;
|
||||
if full {
|
||||
NodeStatsResponse::Full(metrics!())
|
||||
|
||||
// there's no point in returning the entire hashmap of sending destinations in regular mode
|
||||
let response = if params.debug {
|
||||
NodeStatsResponse::Full(snapshot_data)
|
||||
} else {
|
||||
NodeStatsResponse::Simple(snapshot_data.simplify())
|
||||
}
|
||||
};
|
||||
output.to_response(response)
|
||||
}
|
||||
|
||||
pub type MixnodeStatsResponse = FormattedResponse<NodeStatsResponse>;
|
||||
|
||||
@@ -64,12 +64,6 @@ impl<'a> HttpApiBuilder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn with_metrics_key(mut self, metrics_key: Option<&String>) -> Self {
|
||||
self.legacy_mixnode.metrics_key = metrics_key.map(|k| k.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn with_verloc(mut self, verloc: VerlocState) -> Self {
|
||||
self.legacy_mixnode.verloc = verloc;
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::node::TaskClient;
|
||||
use futures::StreamExt;
|
||||
use log::debug;
|
||||
use log::{error, info, warn};
|
||||
use nym_metrics::nanos;
|
||||
use nym_mixnode_common::measure;
|
||||
use nym_sphinx::forwarding::packet::MixPacket;
|
||||
use nym_sphinx::framing::codec::NymCodec;
|
||||
use nym_sphinx::framing::packet::FramedNymPacket;
|
||||
@@ -19,6 +19,9 @@ use tokio::net::TcpStream;
|
||||
use tokio::time::Instant;
|
||||
use tokio_util::codec::Framed;
|
||||
|
||||
#[cfg(feature = "cpucycles")]
|
||||
use tracing::instrument;
|
||||
|
||||
pub(crate) mod packet_processing;
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -50,6 +53,10 @@ impl ConnectionHandler {
|
||||
.expect("the delay-forwarder has died!");
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "cpucycles",
|
||||
instrument(skip(self, framed_sphinx_packet), fields(cpucycles))
|
||||
)]
|
||||
fn handle_received_packet(&self, framed_sphinx_packet: FramedNymPacket) {
|
||||
//
|
||||
// TODO: here be replay attack detection - it will require similar key cache to the one in
|
||||
@@ -59,7 +66,7 @@ impl ConnectionHandler {
|
||||
|
||||
// all processing such, key caching, etc. was done.
|
||||
// however, if it was a forward hop, we still need to delay it
|
||||
nanos!("handle_received_packet", {
|
||||
measure!({
|
||||
match self.packet_processor.process_received(framed_sphinx_packet) {
|
||||
Err(err) => debug!("We failed to process received sphinx packet - {err}"),
|
||||
Ok(res) => match res {
|
||||
|
||||
@@ -72,13 +72,11 @@ impl MixNode {
|
||||
&self,
|
||||
atomic_verloc_result: AtomicVerlocResult,
|
||||
node_stats_pointer: SharedNodeStats,
|
||||
metrics_key: Option<&String>,
|
||||
task_client: TaskClient,
|
||||
) -> Result<(), MixnodeError> {
|
||||
HttpApiBuilder::new(&self.config, &self.identity_keypair, &self.sphinx_keypair)
|
||||
.with_verloc(VerlocState::new(atomic_verloc_result))
|
||||
.with_mixing_stats(node_stats_pointer)
|
||||
.with_metrics_key(metrics_key)
|
||||
.with_descriptor(self.descriptor.clone())
|
||||
.start(task_client)
|
||||
}
|
||||
@@ -251,7 +249,6 @@ impl MixNode {
|
||||
self.start_http_api(
|
||||
atomic_verloc_results,
|
||||
node_stats_pointer,
|
||||
self.config.metrics_key(),
|
||||
shutdown.subscribe().named("http-api"),
|
||||
)?;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use nym_metrics::inc_by;
|
||||
|
||||
use super::TaskClient;
|
||||
use futures::channel::mpsc;
|
||||
use futures::lock::Mutex;
|
||||
@@ -17,7 +15,7 @@ use std::time::{Duration, SystemTime};
|
||||
use tokio::sync::{RwLock, RwLockReadGuard};
|
||||
|
||||
// convenience aliases
|
||||
type PacketsMap = HashMap<String, f64>;
|
||||
type PacketsMap = HashMap<String, u64>;
|
||||
type PacketDataReceiver = mpsc::UnboundedReceiver<PacketEvent>;
|
||||
type PacketDataSender = mpsc::UnboundedSender<PacketEvent>;
|
||||
|
||||
@@ -29,15 +27,14 @@ pub(crate) struct SharedNodeStats {
|
||||
impl SharedNodeStats {
|
||||
pub(crate) fn new() -> Self {
|
||||
let now = SystemTime::now();
|
||||
|
||||
SharedNodeStats {
|
||||
inner: Arc::new(RwLock::new(NodeStats {
|
||||
update_time: now,
|
||||
previous_update_time: now,
|
||||
packets_received_since_startup: 0.,
|
||||
packets_sent_since_startup_all: 0.,
|
||||
packets_dropped_since_startup_all: 0.,
|
||||
packets_received_since_last_update: 0.,
|
||||
packets_received_since_startup: 0,
|
||||
packets_sent_since_startup: HashMap::new(),
|
||||
packets_explicitly_dropped_since_startup: HashMap::new(),
|
||||
packets_received_since_last_update: 0,
|
||||
packets_sent_since_last_update: HashMap::new(),
|
||||
packets_explicitly_dropped_since_last_update: HashMap::new(),
|
||||
})),
|
||||
@@ -46,7 +43,7 @@ impl SharedNodeStats {
|
||||
|
||||
pub(crate) async fn update(
|
||||
&self,
|
||||
new_received: f64,
|
||||
new_received: u64,
|
||||
new_sent: PacketsMap,
|
||||
new_dropped: PacketsMap,
|
||||
) {
|
||||
@@ -57,24 +54,20 @@ impl SharedNodeStats {
|
||||
guard.update_time = snapshot_time;
|
||||
|
||||
guard.packets_received_since_startup += new_received;
|
||||
for count in new_sent.values() {
|
||||
guard.packets_sent_since_startup_all += count;
|
||||
for (mix, count) in &new_sent {
|
||||
*guard
|
||||
.packets_sent_since_startup
|
||||
.entry(mix.clone())
|
||||
.or_insert(0) += *count;
|
||||
}
|
||||
|
||||
for count in new_dropped.values() {
|
||||
guard.packets_dropped_since_startup_all += count;
|
||||
for (mix, count) in &new_dropped {
|
||||
*guard
|
||||
.packets_explicitly_dropped_since_last_update
|
||||
.entry(mix.clone())
|
||||
.or_insert(0) += *count;
|
||||
}
|
||||
|
||||
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::<f64>()
|
||||
);
|
||||
|
||||
guard.packets_received_since_last_update = new_received;
|
||||
guard.packets_sent_since_last_update = new_sent;
|
||||
guard.packets_explicitly_dropped_since_last_update = new_dropped;
|
||||
@@ -89,18 +82,27 @@ impl SharedNodeStats {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct NodeStats {
|
||||
#[serde(serialize_with = "humantime_serde::serialize")]
|
||||
update_time: SystemTime,
|
||||
|
||||
#[serde(serialize_with = "humantime_serde::serialize")]
|
||||
previous_update_time: SystemTime,
|
||||
|
||||
packets_received_since_startup: f64,
|
||||
packets_sent_since_startup_all: f64,
|
||||
packets_dropped_since_startup_all: f64,
|
||||
packets_received_since_last_update: f64,
|
||||
packets_received_since_startup: u64,
|
||||
|
||||
// note: sent does not imply forwarded. We don't know if it was delivered successfully
|
||||
packets_sent_since_startup: PacketsMap,
|
||||
|
||||
// we know for sure we dropped packets to those destinations
|
||||
packets_explicitly_dropped_since_startup: PacketsMap,
|
||||
|
||||
packets_received_since_last_update: u64,
|
||||
|
||||
// note: sent does not imply forwarded. We don't know if it was delivered successfully
|
||||
packets_sent_since_last_update: PacketsMap,
|
||||
|
||||
// we know for sure we dropped packets to those destinations
|
||||
packets_explicitly_dropped_since_last_update: PacketsMap,
|
||||
}
|
||||
@@ -110,10 +112,10 @@ impl Default for NodeStats {
|
||||
NodeStats {
|
||||
update_time: SystemTime::UNIX_EPOCH,
|
||||
previous_update_time: SystemTime::UNIX_EPOCH,
|
||||
packets_received_since_startup: 0.,
|
||||
packets_sent_since_startup_all: 0.,
|
||||
packets_dropped_since_startup_all: 0.,
|
||||
packets_received_since_last_update: 0.,
|
||||
packets_received_since_startup: 0,
|
||||
packets_sent_since_startup: Default::default(),
|
||||
packets_explicitly_dropped_since_startup: Default::default(),
|
||||
packets_received_since_last_update: 0,
|
||||
packets_sent_since_last_update: Default::default(),
|
||||
packets_explicitly_dropped_since_last_update: Default::default(),
|
||||
}
|
||||
@@ -126,8 +128,11 @@ impl NodeStats {
|
||||
update_time: self.update_time,
|
||||
previous_update_time: self.previous_update_time,
|
||||
packets_received_since_startup: self.packets_received_since_startup,
|
||||
packets_sent_since_startup: self.packets_sent_since_startup_all,
|
||||
packets_explicitly_dropped_since_startup: self.packets_dropped_since_startup_all,
|
||||
packets_sent_since_startup: self.packets_sent_since_startup.values().sum(),
|
||||
packets_explicitly_dropped_since_startup: self
|
||||
.packets_explicitly_dropped_since_startup
|
||||
.values()
|
||||
.sum(),
|
||||
packets_received_since_last_update: self.packets_received_since_last_update,
|
||||
packets_sent_since_last_update: self.packets_sent_since_last_update.values().sum(),
|
||||
packets_explicitly_dropped_since_last_update: self
|
||||
@@ -146,21 +151,21 @@ pub struct NodeStatsSimple {
|
||||
#[serde(serialize_with = "humantime_serde::serialize")]
|
||||
previous_update_time: SystemTime,
|
||||
|
||||
packets_received_since_startup: f64,
|
||||
packets_received_since_startup: u64,
|
||||
|
||||
// note: sent does not imply forwarded. We don't know if it was delivered successfully
|
||||
packets_sent_since_startup: f64,
|
||||
packets_sent_since_startup: u64,
|
||||
|
||||
// we know for sure we dropped those packets
|
||||
packets_explicitly_dropped_since_startup: f64,
|
||||
packets_explicitly_dropped_since_startup: u64,
|
||||
|
||||
packets_received_since_last_update: f64,
|
||||
packets_received_since_last_update: u64,
|
||||
|
||||
// note: sent does not imply forwarded. We don't know if it was delivered successfully
|
||||
packets_sent_since_last_update: f64,
|
||||
packets_sent_since_last_update: u64,
|
||||
|
||||
// we know for sure we dropped those packets
|
||||
packets_explicitly_dropped_since_last_update: f64,
|
||||
packets_explicitly_dropped_since_last_update: u64,
|
||||
}
|
||||
|
||||
pub(crate) enum PacketEvent {
|
||||
@@ -198,14 +203,14 @@ impl CurrentPacketData {
|
||||
|
||||
async fn increment_sent(&self, destination: String) {
|
||||
let mut unlocked = self.inner.sent.lock().await;
|
||||
let receiver_count = unlocked.entry(destination).or_insert(0.);
|
||||
*receiver_count += 1.;
|
||||
let receiver_count = unlocked.entry(destination).or_insert(0);
|
||||
*receiver_count += 1;
|
||||
}
|
||||
|
||||
async fn increment_dropped(&self, destination: String) {
|
||||
let mut unlocked = self.inner.dropped.lock().await;
|
||||
let dropped_count = unlocked.entry(destination).or_insert(0.);
|
||||
*dropped_count += 1.;
|
||||
let dropped_count = unlocked.entry(destination).or_insert(0);
|
||||
*dropped_count += 1;
|
||||
}
|
||||
|
||||
async fn acquire_and_reset(&self) -> (u64, PacketsMap, PacketsMap) {
|
||||
@@ -327,9 +332,7 @@ impl StatsUpdater {
|
||||
async fn update_stats(&self) {
|
||||
// grab new data since last update
|
||||
let (received, sent, dropped) = self.current_packet_data.acquire_and_reset().await;
|
||||
self.current_stats
|
||||
.update(received as f64, sent, dropped)
|
||||
.await;
|
||||
self.current_stats.update(received, sent, dropped).await;
|
||||
}
|
||||
|
||||
async fn run(&mut self) {
|
||||
@@ -373,18 +376,21 @@ impl PacketStatsConsoleLogger {
|
||||
|
||||
info!(
|
||||
"Since startup mixed {} packets! ({} in last {} seconds)",
|
||||
stats.packets_sent_since_startup_all,
|
||||
stats.packets_sent_since_last_update.values().sum::<f64>(),
|
||||
stats.packets_sent_since_startup.values().sum::<u64>(),
|
||||
stats.packets_sent_since_last_update.values().sum::<u64>(),
|
||||
difference_secs,
|
||||
);
|
||||
if stats.packets_dropped_since_startup_all > 0. {
|
||||
if !stats.packets_explicitly_dropped_since_startup.is_empty() {
|
||||
info!(
|
||||
"Since startup dropped {} packets! ({} in last {} seconds)",
|
||||
stats.packets_dropped_since_startup_all,
|
||||
stats
|
||||
.packets_explicitly_dropped_since_startup
|
||||
.values()
|
||||
.sum::<u64>(),
|
||||
stats
|
||||
.packets_explicitly_dropped_since_last_update
|
||||
.values()
|
||||
.sum::<f64>(),
|
||||
.sum::<u64>(),
|
||||
difference_secs,
|
||||
);
|
||||
}
|
||||
@@ -397,19 +403,22 @@ impl PacketStatsConsoleLogger {
|
||||
);
|
||||
trace!(
|
||||
"Since startup sent packets to the following: \n{:#?} \n And in last {} seconds: {:#?})",
|
||||
stats.packets_sent_since_startup_all,
|
||||
stats.packets_sent_since_startup,
|
||||
difference_secs,
|
||||
stats.packets_sent_since_last_update
|
||||
);
|
||||
} else {
|
||||
info!(
|
||||
"Since startup mixed {} packets!",
|
||||
stats.packets_sent_since_startup_all,
|
||||
stats.packets_sent_since_startup.values().sum::<u64>(),
|
||||
);
|
||||
if stats.packets_dropped_since_startup_all > 0. {
|
||||
if !stats.packets_explicitly_dropped_since_startup.is_empty() {
|
||||
info!(
|
||||
"Since startup dropped {} packets!",
|
||||
stats.packets_dropped_since_startup_all,
|
||||
stats
|
||||
.packets_explicitly_dropped_since_startup
|
||||
.values()
|
||||
.sum::<u64>(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -418,8 +427,8 @@ impl PacketStatsConsoleLogger {
|
||||
stats.packets_received_since_startup
|
||||
);
|
||||
trace!(
|
||||
"Since startup sent packets {}",
|
||||
stats.packets_sent_since_startup_all
|
||||
"Since startup sent packets to the following: \n{:#?}",
|
||||
stats.packets_sent_since_startup
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -512,7 +521,6 @@ impl Controller {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use nym_metrics::metrics;
|
||||
use nym_task::TaskManager;
|
||||
|
||||
#[tokio::test]
|
||||
@@ -537,11 +545,14 @@ mod tests {
|
||||
|
||||
// Get output (stats)
|
||||
let stats = node_stats_pointer.read().await;
|
||||
assert_eq!(&stats.packets_sent_since_startup_all, &2.);
|
||||
assert_eq!(&stats.packets_sent_since_last_update.get("foo"), &Some(&2.));
|
||||
assert_eq!(&stats.packets_sent_since_startup.get("foo"), &Some(&2u64));
|
||||
assert_eq!(&stats.packets_sent_since_startup.len(), &1);
|
||||
assert_eq!(
|
||||
&stats.packets_sent_since_last_update.get("foo"),
|
||||
&Some(&2u64)
|
||||
);
|
||||
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!(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")
|
||||
assert_eq!(&stats.packets_received_since_startup, &0u64);
|
||||
assert!(&stats.packets_explicitly_dropped_since_startup.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+6
-6
@@ -2555,9 +2555,9 @@
|
||||
"integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ=="
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"version": "1.15.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -6845,9 +6845,9 @@
|
||||
"integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
|
||||
"version": "1.15.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "4.0.0",
|
||||
|
||||
@@ -1568,9 +1568,9 @@ flatted@^3.1.0:
|
||||
integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==
|
||||
|
||||
follow-redirects@^1.15.0:
|
||||
version "1.15.6"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
|
||||
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
|
||||
version "1.15.4"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
|
||||
integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
|
||||
|
||||
form-data@4.0.0, form-data@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
||||
Generated
+17
-124
@@ -2529,7 +2529,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"gloo-utils",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"js-sys",
|
||||
"pin-project",
|
||||
"serde",
|
||||
@@ -2664,7 +2664,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"indexmap 1.9.3",
|
||||
"slab",
|
||||
"tokio",
|
||||
@@ -2833,17 +2833,6 @@ 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"
|
||||
@@ -2865,30 +2854,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"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",
|
||||
"http",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
@@ -2946,8 +2912,8 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http 0.2.9",
|
||||
"http-body 0.4.5",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa 1.0.9",
|
||||
@@ -2959,25 +2925,6 @@ 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"
|
||||
@@ -2985,8 +2932,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http 0.2.9",
|
||||
"hyper 0.14.27",
|
||||
"http",
|
||||
"hyper",
|
||||
"rustls 0.21.7",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
@@ -2999,28 +2946,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hyper 0.14.27",
|
||||
"hyper",
|
||||
"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"
|
||||
@@ -3823,10 +3754,7 @@ 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",
|
||||
@@ -3835,7 +3763,6 @@ dependencies = [
|
||||
"nym-explorer-client",
|
||||
"nym-gateway-client",
|
||||
"nym-gateway-requests",
|
||||
"nym-metrics",
|
||||
"nym-network-defaults",
|
||||
"nym-nonexhaustive-delayqueue",
|
||||
"nym-pemstore",
|
||||
@@ -4160,9 +4087,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tungstenite",
|
||||
"wasmtimer",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@@ -4177,16 +4102,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-metrics"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dashmap",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"prometheus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-mixnet-contract-common"
|
||||
version = "0.6.0"
|
||||
@@ -5289,21 +5204,6 @@ 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"
|
||||
@@ -5336,12 +5236,6 @@ 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"
|
||||
@@ -5591,9 +5485,9 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http 0.2.9",
|
||||
"http-body 0.4.5",
|
||||
"hyper 0.14.27",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"ipnet",
|
||||
@@ -6413,9 +6307,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
@@ -6891,7 +6785,7 @@ dependencies = [
|
||||
"glob",
|
||||
"gtk",
|
||||
"heck 0.4.1",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"ignore",
|
||||
"minisign-verify",
|
||||
"notify-rust",
|
||||
@@ -6991,7 +6885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "108683199cb18f96d2d4134187bb789964143c845d2d154848dda209191fd769"
|
||||
dependencies = [
|
||||
"gtk",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"http-range",
|
||||
"rand 0.8.5",
|
||||
"raw-window-handle",
|
||||
@@ -7377,7 +7271,6 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"rustls 0.21.7",
|
||||
"tokio",
|
||||
"tungstenite",
|
||||
]
|
||||
@@ -7555,7 +7448,7 @@ dependencies = [
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"data-encoding",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
@@ -8368,7 +8261,7 @@ dependencies = [
|
||||
"glib",
|
||||
"gtk",
|
||||
"html5ever",
|
||||
"http 0.2.9",
|
||||
"http",
|
||||
"kuchiki",
|
||||
"libc",
|
||||
"log",
|
||||
|
||||
@@ -49,9 +49,6 @@ pub struct Http {
|
||||
/// Path to assets directory of custom landing page of this node.
|
||||
#[serde(deserialize_with = "de_maybe_path")]
|
||||
pub landing_page_assets_path: Option<PathBuf>,
|
||||
|
||||
#[serde(default)]
|
||||
pub metrics_key: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for Http {
|
||||
@@ -59,7 +56,6 @@ impl Default for Http {
|
||||
Http {
|
||||
bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), DEFAULT_HTTP_PORT),
|
||||
landing_page_assets_path: None,
|
||||
metrics_key: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# Wallet CLI Recovery Tool Guide
|
||||
|
||||
This guide provides instructions on how to use the Wallet CLI recovery tool to recover your mnemonic phrase using your password, especially useful if you're unable to access your wallet in the usual way.
|
||||
|
||||
## Step 1: Install the CLI Tool
|
||||
|
||||
1. Change directory `cd /nym-wallet/nym-wallet-recovery-cli` from root Nym repository
|
||||
2. Have rust installed `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
|
||||
3. Once the installation is complete run `cargo build --release`
|
||||
4. The binary should live here: `nym/nym-wallet/nym-wallet-recovery-cli)`
|
||||
|
||||
## Step 2: Prepare Your Command
|
||||
|
||||
The tool requires specific command-line arguments to specify the password(s) and the file path to your wallet file. The basic structure of the command is as follows:
|
||||
|
||||
```
|
||||
nym-recovery-cli --password <YOUR_PASSWORD> --file <PATH_TO_YOUR_WALLET_FILE> [OPTIONS]
|
||||
```
|
||||
|
||||
- Replace `<YOUR_PASSWORD>` with your wallet password.
|
||||
- Replace `<PATH_TO_YOUR_WALLET_FILE>` with the path to your wallet file, where your encrypted mnemonic is stored.
|
||||
|
||||
## Step 3: Running the Tool
|
||||
|
||||
1. Open your terminal or command prompt.
|
||||
2. Navigate to the directory where the `nym-recovery-cli` tool is located.
|
||||
3. Execute the command prepared in Step 2.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
./nym-recovery-cli --password "mySecurePassword123" --file "/path/to/mywallet.json"
|
||||
```
|
||||
|
||||
To try multiple passwords:
|
||||
|
||||
```
|
||||
./nym-recovery-cli --password "myFirstPassword" --password "mySecondPassword" --file "/path/to/mywallet.json"
|
||||
```
|
||||
|
||||
## Step 4: Understanding the Output
|
||||
|
||||
The tool will attempt to decrypt the wallet file. If successful, it will print the decrypted content, including your mnemonic phrase.
|
||||
|
||||
## Step 5: If You Encounter Issues
|
||||
|
||||
- Verify the accuracy of the passwords and file path.
|
||||
- Ensure there are no typos in the command.
|
||||
- Make sure the wallet file's path is correctly specified.
|
||||
|
||||
## Additional Options
|
||||
|
||||
- `--raw`: Skips trying to parse the decrypted content, showing raw output instead.
|
||||
|
||||
This guide should help you safely recover your mnemonic phrase. Remember to keep it secure once retrieved.
|
||||
@@ -20,13 +20,13 @@ echo "Using $localnetdir for the localnet"
|
||||
|
||||
# initialise mixnet
|
||||
echo "initialising mixnode1..."
|
||||
cargo run --release --bin nym-mixnode -- init --id "mix1-$suffix" --host 127.0.0.1 --mix-port 10001 --verloc-port 20001 --http-api-port 30001 --metrics-key=lala --output=json >>"$localnetdir/mix1.json"
|
||||
cargo run --release --bin nym-mixnode -- init --id "mix1-$suffix" --host 127.0.0.1 --mix-port 10001 --verloc-port 20001 --http-api-port 30001 --output=json >>"$localnetdir/mix1.json"
|
||||
|
||||
echo "initialising mixnode2..."
|
||||
cargo run --release --bin nym-mixnode -- init --id "mix2-$suffix" --host 127.0.0.1 --mix-port 10002 --verloc-port 20002 --http-api-port 30002 --metrics-key=lala --output=json >>"$localnetdir/mix2.json"
|
||||
cargo run --release --bin nym-mixnode -- init --id "mix2-$suffix" --host 127.0.0.1 --mix-port 10002 --verloc-port 20002 --http-api-port 30002 --output=json >>"$localnetdir/mix2.json"
|
||||
|
||||
echo "initialising mixnode3..."
|
||||
cargo run --release --bin nym-mixnode -- init --id "mix3-$suffix" --host 127.0.0.1 --mix-port 10003 --verloc-port 20003 --http-api-port 30003 --metrics-key=lala --output=json >>"$localnetdir/mix3.json"
|
||||
cargo run --release --bin nym-mixnode -- init --id "mix3-$suffix" --host 127.0.0.1 --mix-port 10003 --verloc-port 20003 --http-api-port 30003 --output=json >>"$localnetdir/mix3.json"
|
||||
|
||||
echo "initialising gateway..."
|
||||
cargo run --release --bin nym-gateway -- init --id "gateway-$suffix" --host 127.0.0.1 --mix-port 10004 --clients-port 9000 --output=json >>"$localnetdir/gateway.json"
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if the script is run as root
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script must be run as root. Please use sudo or log in as the root user."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Hardcoded node_exporter version
|
||||
node_exporter_version="1.7.0"
|
||||
|
||||
# Create a user for node_exporter without a home directory
|
||||
useradd --no-create-home --shell /bin/false node_exporter
|
||||
|
||||
# Download node_exporter
|
||||
echo "Downloading node_exporter version $node_exporter_version..."
|
||||
wget "https://github.com/prometheus/node_exporter/releases/download/v$node_exporter_version/node_exporter-$node_exporter_version.linux-amd64.tar.gz" -O /tmp/node_exporter-$node_exporter_version.linux-amd64.tar.gz
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to download node_exporter."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Unarchive node_exporter
|
||||
echo "Unarchiving node_exporter..."
|
||||
tar xvfz /tmp/node_exporter-$node_exporter_version.linux-amd64.tar.gz -C /tmp
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to unarchive node_exporter."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Move node_exporter to /usr/local/bin
|
||||
echo "Moving node_exporter to /usr/local/bin..."
|
||||
mv /tmp/node_exporter-$node_exporter_version.linux-amd64/node_exporter /usr/local/bin/node_exporter
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to move node_exporter."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set ownership and permissions
|
||||
chown node_exporter:node_exporter /usr/local/bin/node_exporter
|
||||
chmod 0755 /usr/local/bin/node_exporter
|
||||
|
||||
# Create node_exporter service file
|
||||
echo "Creating node_exporter service file..."
|
||||
cat <<EOF > /etc/systemd/system/node_exporter.service
|
||||
[Unit]
|
||||
Description=Node Exporter
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
User=node_exporter
|
||||
Group=node_exporter
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/node_exporter --web.config.file /etc/prometheus_node_exporter/configuration.yml
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
|
||||
mkdir -p /etc/prometheus_node_exporter/
|
||||
|
||||
sudo cat << EOF > /etc/prometheus_node_exporter/configuration.yml
|
||||
basic_auth_users:
|
||||
prometheus: "\$2y\$10\$aB1RMr6ZGg2psbMOezmfluVzGcH/VHIqP4Lksx0DWuw/QSr9Iccwu"
|
||||
|
||||
EOF
|
||||
|
||||
ufw allow 9100
|
||||
|
||||
# Reload systemd, enable and start node_exporter service
|
||||
echo "Configuring systemd for node_exporter..."
|
||||
systemctl daemon-reload
|
||||
systemctl enable node_exporter.service
|
||||
systemctl start node_exporter.service
|
||||
|
||||
# Cleanup
|
||||
echo "Cleaning up..."
|
||||
rm -rf /tmp/node_exporter-${node_exporter_version}.linux-amd64.tar.gz
|
||||
rm -rf /tmp/node_exporter-${node_exporter_version}.linux-amd64
|
||||
|
||||
echo "node_exporter installation and configuration complete."
|
||||
@@ -1,119 +0,0 @@
|
||||
import argparse
|
||||
import os
|
||||
import requests
|
||||
import json
|
||||
from collections import namedtuple
|
||||
|
||||
Config = namedtuple("Config", ["port", "outfile", "outlink", "env"])
|
||||
|
||||
|
||||
def gateway_targets(entry):
|
||||
targets = [
|
||||
# Config(
|
||||
# None,
|
||||
# "/tmp/temp_targets_gateway.json",
|
||||
# f"/tmp/prom_targets_gateway_{entry['env']}.json",
|
||||
# entry["env"],
|
||||
# ),
|
||||
Config(
|
||||
9100,
|
||||
"/tmp/temp_targets_gateway_node.json",
|
||||
f"/tmp/prom_targets_gateway_node_{entry['env']}.json",
|
||||
entry["env"],
|
||||
),
|
||||
]
|
||||
|
||||
gateways = requests.get(f"{entry['nym_api']}/api/v1/gateways").json()
|
||||
|
||||
for config in targets:
|
||||
config_to_targets(config, gateways, {"kind": "gateway"})
|
||||
|
||||
|
||||
def mixnode_targets(entry):
|
||||
targets = [
|
||||
Config(
|
||||
None,
|
||||
"/tmp/temp_targets_mix.json",
|
||||
f"/tmp/prom_targets_mix_{entry['env']}.json",
|
||||
entry["env"],
|
||||
),
|
||||
Config(
|
||||
9100,
|
||||
"/tmp/temp_targets_node.json",
|
||||
f"/tmp/prom_targets_node_{entry['env']}.json",
|
||||
entry["env"],
|
||||
),
|
||||
]
|
||||
|
||||
mixnodes = requests.get(f"{entry['nym_api']}/api/v1/mixnodes").json()
|
||||
|
||||
for config in targets:
|
||||
config_to_targets(config, mixnodes, {"kind": "mixnode"})
|
||||
|
||||
|
||||
def validate_config_entry(entry):
|
||||
return entry.get("nym_api") and entry.get("env")
|
||||
|
||||
|
||||
def config_to_targets(config, mixnodes, labels=None):
|
||||
prom_targets = [
|
||||
make_prom_target(config.env, mixnode, config.port, labels)
|
||||
for mixnode in mixnodes
|
||||
]
|
||||
with open(config.outfile, "w") as f:
|
||||
json.dump(prom_targets, f)
|
||||
|
||||
os.chmod(config.outfile, 0o777)
|
||||
os.rename(config.outfile, config.outlink)
|
||||
os.chmod(config.outlink, 0o777)
|
||||
|
||||
print(f"Prometheus -> {len(prom_targets)} targets written to {config.outlink}")
|
||||
|
||||
|
||||
def make_prom_target(env, mixnode, port=None, labels=None):
|
||||
bond_info = mixnode.get("bond_information", {})
|
||||
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:
|
||||
return None
|
||||
|
||||
target = {
|
||||
"targets": [f"{host}:{port}"],
|
||||
"labels": {
|
||||
"mix_node_host": host,
|
||||
"identity_key": mix_node.get("identity_key", None),
|
||||
"sphinx_key": mix_node.get("sphinx_key", None),
|
||||
"mix_node_version": mix_node.get("version", None),
|
||||
"mixnet_env": env,
|
||||
},
|
||||
}
|
||||
|
||||
for k, v in labels.items():
|
||||
target["labels"][k] = v
|
||||
|
||||
return target
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Create prometheus targets for rewarded set mixnodes."
|
||||
)
|
||||
parser.add_argument(
|
||||
"config",
|
||||
type=str,
|
||||
help="Config file, see scripts/prom_targets_config.json",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
config_file = args.config
|
||||
|
||||
with open(config_file, "r") as f:
|
||||
config = json.load(f)
|
||||
|
||||
for entry in config:
|
||||
mixnode_targets(entry)
|
||||
|
||||
gateway_targets(entry)
|
||||
@@ -1,4 +0,0 @@
|
||||
[
|
||||
{ "nym_api": "https://sandbox-nym-api1.nymtech.net", "env": "sandbox" },
|
||||
{ "nym_api": "https://api.performance.nymte.ch", "env": "performance" }
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
requests
|
||||
@@ -1,43 +0,0 @@
|
||||
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}")
|
||||
@@ -1,7 +0,0 @@
|
||||
# FFI
|
||||
This repo contains bindings for C/C++ and Go in the respectively named directories.
|
||||
|
||||
`shared/` contains shared 'internal' functions which are imported by bindings. Primarily these functions rely on managing:
|
||||
* that the client is not mutated by multiple threads simultaneously
|
||||
* that client actions happen in blocking threads
|
||||
|
||||
Generated
+13
-344
@@ -155,47 +155,6 @@ version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "askama"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28"
|
||||
dependencies = [
|
||||
"askama_derive",
|
||||
"askama_escape",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_derive"
|
||||
version = "0.12.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83"
|
||||
dependencies = [
|
||||
"askama_parser",
|
||||
"basic-toml",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "askama_escape"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||
|
||||
[[package]]
|
||||
name = "askama_parser"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.77"
|
||||
@@ -281,15 +240,6 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "basic-toml"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
@@ -524,38 +474,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.15.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
@@ -1548,15 +1466,6 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e"
|
||||
|
||||
[[package]]
|
||||
name = "fs-err"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
@@ -1741,12 +1650,6 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "gloo-net"
|
||||
version = "0.3.1"
|
||||
@@ -1793,17 +1696,6 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d6b4de4a8eb6c46a8c77e1d3be942cb9a8bf073c22374578e5ba4b08ed0ff68"
|
||||
dependencies = [
|
||||
"log",
|
||||
"plain",
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "group"
|
||||
version = "0.10.0"
|
||||
@@ -2391,16 +2283,6 @@ version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
@@ -2679,20 +2561,6 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-cpp-ffi"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bs58 0.5.0",
|
||||
"lazy_static",
|
||||
"nym-bin-common",
|
||||
"nym-ffi-shared",
|
||||
"nym-sdk",
|
||||
"nym-sphinx-anonymous-replies",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-credential-storage"
|
||||
version = "0.1.0"
|
||||
@@ -2828,21 +2696,6 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-ffi-shared"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bs58 0.5.0",
|
||||
"lazy_static",
|
||||
"nym-bin-common",
|
||||
"nym-sdk",
|
||||
"nym-sphinx-anonymous-replies",
|
||||
"tokio",
|
||||
"uniffi",
|
||||
"uniffi_build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-gateway-client"
|
||||
version = "0.1.0"
|
||||
@@ -3439,6 +3292,19 @@ dependencies = [
|
||||
"x25519-dalek 2.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym_cpp_ffi"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bs58 0.5.0",
|
||||
"lazy_static",
|
||||
"nym-bin-common",
|
||||
"nym-sdk",
|
||||
"nym-sphinx-anonymous-replies",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.2"
|
||||
@@ -3454,12 +3320,6 @@ version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "oneshot-uniffi"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c548d5c78976f6955d72d0ced18c48ca07030f7a1d4024529fedd7c1c01b29c"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
@@ -3751,12 +3611,6 @@ version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb"
|
||||
|
||||
[[package]]
|
||||
name = "plain"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "platforms"
|
||||
version = "3.3.0"
|
||||
@@ -4295,26 +4149,6 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "scroll"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da"
|
||||
dependencies = [
|
||||
"scroll_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll_derive"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.6.1"
|
||||
@@ -4386,9 +4220,6 @@ name = "semver"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
@@ -4551,12 +4382,6 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
@@ -4824,12 +4649,6 @@ dependencies = [
|
||||
"tokio-rustls 0.23.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.4"
|
||||
@@ -5365,15 +5184,6 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.15"
|
||||
@@ -5407,138 +5217,6 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||
|
||||
[[package]]
|
||||
name = "uniffi"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21345172d31092fd48c47fd56c53d4ae9e41c4b1f559fb8c38c1ab1685fd919f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"clap",
|
||||
"uniffi_bindgen",
|
||||
"uniffi_build",
|
||||
"uniffi_core",
|
||||
"uniffi_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_bindgen"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd992f2929a053829d5875af1eff2ee3d7a7001cb3b9a46cc7895f2caede6940"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"clap",
|
||||
"fs-err",
|
||||
"glob",
|
||||
"goblin",
|
||||
"heck",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"serde",
|
||||
"toml 0.5.11",
|
||||
"uniffi_meta",
|
||||
"uniffi_testing",
|
||||
"uniffi_udl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_build"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "001964dd3682d600084b3aaf75acf9c3426699bc27b65e96bb32d175a31c74e9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"uniffi_bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_checksum_derive"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_core"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6121a127a3af1665cd90d12dd2b3683c2643c5103281d0fed5838324ca1fad5b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"camino",
|
||||
"log",
|
||||
"once_cell",
|
||||
"oneshot-uniffi",
|
||||
"paste",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11cf7a58f101fcedafa5b77ea037999b88748607f0ef3a33eaa0efc5392e92e4"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"camino",
|
||||
"fs-err",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.48",
|
||||
"toml 0.5.11",
|
||||
"uniffi_build",
|
||||
"uniffi_meta",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_meta"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71dc8573a7b1ac4b71643d6da34888273ebfc03440c525121f1b3634ad3417a2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"siphasher",
|
||||
"uniffi_checksum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_testing"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "118448debffcb676ddbe8c5305fb933ab7e0123753e659a71dc4a693f8d9f23c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"cargo_metadata",
|
||||
"fs-err",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_udl"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "889edb7109c6078abe0e53e9b4070cf74a6b3468d141bdf5ef1bd4d1dc24a1c3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"uniffi_meta",
|
||||
"uniffi_testing",
|
||||
"weedle2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.5.1"
|
||||
@@ -5795,15 +5473,6 @@ dependencies = [
|
||||
"webpki 0.22.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weedle2"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-cpp-ffi"
|
||||
version = "0.1.1"
|
||||
name = "nym_cpp_ffi"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
@@ -10,11 +10,11 @@ crate-type = ["cdylib"]
|
||||
[dependencies]
|
||||
# Async runtime
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
# Nym clients, addressing, packet format, common tools (logging), ffi shared
|
||||
# Nym clients, addressing, packet format, common tools (logging)
|
||||
nym-sdk = { git = "https://github.com/nymtech/nym", branch = "master" }
|
||||
nym-bin-common = { git = "https://github.com/nymtech/nym", branch = "master" }
|
||||
nym-sphinx-anonymous-replies = { git = "https://github.com/nymtech/nym", branch = "master" }
|
||||
nym-ffi-shared = { path = "../shared" }
|
||||
# static var macro
|
||||
lazy_static = "1.4.0"
|
||||
# error handling
|
||||
anyhow = "1.0.75"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# C++ FFI
|
||||
> ⚠️ This is an initial version of this library in order to give developers something to experiment with. If you use this code to begin testing out Mixnet integration and run into issues, errors, or have feedback, please feel free to open an issue; feedback from developers trying to use it will help us improve it. If you have questions feel free to reach out via our [Matrix channel](https://matrix.to/#/#dev:nymtech.chat).
|
||||
> ⚠️ This is an initial version of this library in order to give developers something to experiment with. If you use this code to begin testing out Mixnet integration and run into issues, errors, or have feedback, please feel free to open an issue; feedback from developers trying to use it will help us improve it. If you have questions feel free to reach out via our [Matrix channel]().
|
||||
|
||||
This repo contains:
|
||||
* `lib.rs`: an initial version of bindings for interacting with the Mixnet via the Rust SDK from C++. These are essentially match statements wrapping imported functions from the `nym-ffi-shared` lib allowing for nicer [error handling](#error-handling-).
|
||||
* `lib.rs`: an initial version of bindings for interacting with the Mixnet via the Rust SDK from C++.
|
||||
* `main.cpp`: an example of using this library, relying on `Boost` for threads.
|
||||
|
||||
The example `.cpp` file is a simple example flow of:
|
||||
|
||||
@@ -44,7 +44,7 @@ else
|
||||
build_artifacts_and_link;
|
||||
./main;
|
||||
else
|
||||
printf "unknown optional argument - the only available optional argument is 'clean'"
|
||||
echo "unknown optional argument - the only available optional argument is 'clean'"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
+171
-45
@@ -1,13 +1,49 @@
|
||||
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use nym_ffi_shared;
|
||||
use std::ffi::{c_char, c_int, CStr, CString};
|
||||
|
||||
use anyhow::{anyhow, bail};
|
||||
use lazy_static::lazy_static;
|
||||
use nym_sdk::mixnet::{MixnetClient, MixnetMessageSender, ReconstructedMessage};
|
||||
use nym_sphinx_anonymous_replies::requests::AnonymousSenderTag;
|
||||
use std::ffi::{c_char, c_int, CStr, CString};
|
||||
use std::mem::forget;
|
||||
mod types;
|
||||
use crate::types::types::{CMessageCallback, CStringCallback, ReceivedMessage, StatusCode};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
/*
|
||||
NYM_CLIENT: Static reference (only init-ed once) to:
|
||||
- Arc: share ownership
|
||||
- Mutex: thread-safe way to share data between threads
|
||||
- Option: init-ed or not
|
||||
RUNTIME: Tokio runtime: no need to pass back to C and deal with raw pointers as it was previously
|
||||
*/
|
||||
lazy_static! {
|
||||
static ref NYM_CLIENT: Arc<Mutex<Option<MixnetClient>>> = Arc::new(Mutex::new(None));
|
||||
static ref RUNTIME: Runtime = Runtime::new().unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum StatusCode {
|
||||
NoError = 0,
|
||||
ClientInitError = -1,
|
||||
ClientUninitialisedError = -2,
|
||||
SelfAddrError = -3,
|
||||
SendMsgError = -4,
|
||||
ReplyError = -5,
|
||||
ListenError = -6,
|
||||
}
|
||||
|
||||
// pub type CIntCallback = extern "C" fn(i32);
|
||||
pub type CStringCallback = extern "C" fn(*const c_char);
|
||||
pub type CMessageCallback = extern "C" fn(ReceivedMessage);
|
||||
|
||||
// FFI-sanitised way of sending back a ReconstructedMessage to C
|
||||
#[repr(C)]
|
||||
pub struct ReceivedMessage {
|
||||
message: *const u8,
|
||||
size: usize,
|
||||
sender_tag: *const c_char,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn init_logging() {
|
||||
@@ -16,31 +52,76 @@ pub extern "C" fn init_logging() {
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn init_ephemeral() -> c_int {
|
||||
match nym_ffi_shared::init_ephemeral_internal() {
|
||||
match init_ephemeral_internal() {
|
||||
Ok(_) => StatusCode::NoError as c_int,
|
||||
Err(_) => StatusCode::ClientInitError as c_int,
|
||||
}
|
||||
}
|
||||
|
||||
fn init_ephemeral_internal() -> anyhow::Result<(), anyhow::Error> {
|
||||
if NYM_CLIENT.lock().unwrap().as_ref().is_some() {
|
||||
bail!("client already exists");
|
||||
} else {
|
||||
RUNTIME.block_on(async move {
|
||||
let init_client = MixnetClient::connect_new().await?;
|
||||
let mut client = NYM_CLIENT.try_lock();
|
||||
if let Ok(ref mut client) = client {
|
||||
**client = Some(init_client);
|
||||
} else {
|
||||
anyhow!("couldnt lock NYM_CLIENT");
|
||||
}
|
||||
Ok::<(), anyhow::Error>(())
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn get_self_address(callback: CStringCallback) -> c_int {
|
||||
match nym_ffi_shared::get_self_address_internal(/*callback*/) {
|
||||
Ok(addr) => {
|
||||
let c_ptr = CString::new(addr).expect("could not convert Nym address to CString");
|
||||
let call = CStringCallback::new(callback.callback);
|
||||
// as_ptr() keeps ownership in rust unlike into_raw() so no need to free it
|
||||
call.trigger(c_ptr.as_ptr());
|
||||
StatusCode::NoError as c_int
|
||||
}
|
||||
match get_self_address_internal(callback) {
|
||||
Ok(_) => StatusCode::NoError as c_int,
|
||||
Err(_) => StatusCode::SelfAddrError as c_int,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_self_address_internal(callback: CStringCallback) -> anyhow::Result<(), anyhow::Error> {
|
||||
let client = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT");
|
||||
if client.is_none() {
|
||||
bail!("Client is not yet initialised");
|
||||
}
|
||||
let nym_client = client
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("could not get client as_ref()"))?;
|
||||
// get address as cstring
|
||||
let c_string = CString::new(nym_client.nym_address().to_string())?;
|
||||
// as_ptr() keeps ownership in rust unlike into_raw() so no need to free it
|
||||
callback(c_string.as_ptr());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn send_message(recipient: *const c_char, message: *const c_char) -> c_int {
|
||||
match send_message_internal(recipient, message) {
|
||||
Ok(_) => StatusCode::NoError as c_int,
|
||||
Err(_) => StatusCode::SendMsgError as c_int,
|
||||
}
|
||||
}
|
||||
|
||||
fn send_message_internal(
|
||||
recipient: *const c_char,
|
||||
message: *const c_char,
|
||||
) -> anyhow::Result<(), anyhow::Error> {
|
||||
let client = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT");
|
||||
if client.is_none() {
|
||||
bail!("Client is not yet initialised");
|
||||
}
|
||||
let nym_client = client
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("could not get client as_ref()"))?;
|
||||
|
||||
let c_str = unsafe {
|
||||
if recipient.is_null() {
|
||||
return StatusCode::RecipientNullError as c_int;
|
||||
bail!("recipient is null");
|
||||
}
|
||||
let c_str = CStr::from_ptr(recipient);
|
||||
c_str
|
||||
@@ -49,24 +130,44 @@ pub extern "C" fn send_message(recipient: *const c_char, message: *const c_char)
|
||||
let recipient = r_str.parse().unwrap();
|
||||
let c_str = unsafe {
|
||||
if message.is_null() {
|
||||
return StatusCode::MessageNullError as c_int;
|
||||
bail!("message is null");
|
||||
}
|
||||
let c_str = CStr::from_ptr(message);
|
||||
c_str
|
||||
};
|
||||
let message = c_str.to_str().unwrap();
|
||||
|
||||
match nym_ffi_shared::send_message_internal(recipient, message) {
|
||||
Ok(_) => StatusCode::NoError as c_int,
|
||||
Err(_) => StatusCode::SendMsgError as c_int,
|
||||
}
|
||||
// send message
|
||||
RUNTIME.block_on(async move {
|
||||
nym_client.send_plain_message(recipient, message).await?;
|
||||
Ok::<(), anyhow::Error>(())
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn reply(recipient: *const c_char, message: *const c_char) -> c_int {
|
||||
match reply_internal(recipient, message) {
|
||||
Ok(_) => StatusCode::NoError as c_int,
|
||||
Err(_) => StatusCode::ReplyError as c_int,
|
||||
}
|
||||
}
|
||||
|
||||
fn reply_internal(
|
||||
recipient: *const c_char,
|
||||
message: *const c_char,
|
||||
) -> anyhow::Result<(), anyhow::Error> {
|
||||
let client = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT");
|
||||
if client.is_none() {
|
||||
bail!("Client is not yet initialised");
|
||||
}
|
||||
let nym_client = client
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("could not get client as_ref()"))?;
|
||||
|
||||
let recipient = unsafe {
|
||||
if recipient.is_null() {
|
||||
return StatusCode::RecipientNullError as c_int;
|
||||
bail!("recipient is null");
|
||||
}
|
||||
let r_str = CStr::from_ptr(recipient).to_string_lossy().into_owned();
|
||||
AnonymousSenderTag::try_from_base58_string(r_str)
|
||||
@@ -74,39 +175,64 @@ pub extern "C" fn reply(recipient: *const c_char, message: *const c_char) -> c_i
|
||||
};
|
||||
let message = unsafe {
|
||||
if message.is_null() {
|
||||
return StatusCode::MessageNullError as c_int;
|
||||
bail!("message is null");
|
||||
}
|
||||
let c_str = CStr::from_ptr(message);
|
||||
let r_str = c_str.to_str().unwrap();
|
||||
r_str
|
||||
};
|
||||
|
||||
match nym_ffi_shared::reply_internal(recipient, message) {
|
||||
Ok(_) => StatusCode::NoError as c_int,
|
||||
Err(_) => StatusCode::ReplyError as c_int,
|
||||
}
|
||||
RUNTIME.block_on(async move {
|
||||
nym_client.send_reply(recipient, message).await?;
|
||||
Ok::<(), anyhow::Error>(())
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn listen_for_incoming(callback: CMessageCallback) -> c_int {
|
||||
match nym_ffi_shared::listen_for_incoming_internal() {
|
||||
Ok(received) => {
|
||||
let message_ptr = received.message.as_ptr();
|
||||
let message_length = received.message.len();
|
||||
let c_string = CString::new(received.sender_tag.unwrap().to_string()).unwrap();
|
||||
let sender_ptr = c_string.as_ptr();
|
||||
// stop deallocation when out of scope as passing raw ptr to it elsewhere
|
||||
forget(received);
|
||||
let rec_for_c = ReceivedMessage {
|
||||
message: message_ptr,
|
||||
size: message_length,
|
||||
sender_tag: sender_ptr,
|
||||
};
|
||||
let call = CMessageCallback::new(callback.callback);
|
||||
call.trigger(rec_for_c);
|
||||
|
||||
StatusCode::NoError as c_int
|
||||
}
|
||||
match listen_for_incoming_internal(callback) {
|
||||
Ok(_) => StatusCode::NoError as c_int,
|
||||
Err(_) => StatusCode::ListenError as c_int,
|
||||
}
|
||||
}
|
||||
|
||||
fn listen_for_incoming_internal(callback: CMessageCallback) -> anyhow::Result<(), anyhow::Error> {
|
||||
let mut binding = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT");
|
||||
if binding.is_none() {
|
||||
bail!("recipient is null");
|
||||
}
|
||||
let client = binding
|
||||
.as_mut()
|
||||
.ok_or_else(|| anyhow!("could not get client as_ref()"))?;
|
||||
|
||||
RUNTIME.block_on(async move {
|
||||
let received = wait_for_non_empty_message(client).await?;
|
||||
let message_ptr = received.message.as_ptr();
|
||||
let message_length = received.message.len();
|
||||
let c_string = CString::new(received.sender_tag.unwrap().to_string())?;
|
||||
let sender_ptr = c_string.as_ptr();
|
||||
// stop deallocation when out of scope as passing raw ptr to it elsewhere
|
||||
forget(received);
|
||||
let rec_for_c = ReceivedMessage {
|
||||
message: message_ptr,
|
||||
size: message_length,
|
||||
sender_tag: sender_ptr,
|
||||
};
|
||||
callback(rec_for_c);
|
||||
Ok::<(), anyhow::Error>(())
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn wait_for_non_empty_message(
|
||||
client: &mut MixnetClient,
|
||||
) -> anyhow::Result<ReconstructedMessage> {
|
||||
while let Some(mut new_message) = client.wait_for_messages().await {
|
||||
if !new_message.is_empty() {
|
||||
return new_message
|
||||
.pop()
|
||||
.ok_or_else(|| anyhow!("could not get client as_ref()"));
|
||||
}
|
||||
}
|
||||
bail!("(Rust) did not receive any non-empty message")
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ int main() {
|
||||
// - execute
|
||||
// - get() returned val
|
||||
// - handle val
|
||||
// initialise an ephemeral client - aka one without specified keystore
|
||||
boost::packaged_task<char> init(boost::bind(init_ephemeral));
|
||||
boost::unique_future<char> init_future = init.get_future();
|
||||
init();
|
||||
@@ -78,7 +77,7 @@ int main() {
|
||||
return_code = get_self_address(string_callback_function);
|
||||
handle(return_code);
|
||||
|
||||
// send a message through the mixnet - in this case to ourselves using the value from get_self_address
|
||||
// send a message through the mixnet - in this case to ourselves
|
||||
std::cout << "(c++) message to send through mixnet: " << message << std::endl;
|
||||
boost::packaged_task<char> send(boost::bind(send_message, addr, message));
|
||||
boost::unique_future<char> send_future = send.get_future();
|
||||
@@ -95,17 +94,16 @@ int main() {
|
||||
return_code = listen_future.get();
|
||||
handle(return_code);
|
||||
|
||||
// replying to incoming message (from ourselves) with SURBs - note that sending a message to a recipient and
|
||||
// replying to an incoming are different functions: replying relies on parsing the incoming sender_tag on the Rust
|
||||
// side and creating an AnonymousSenderTag type, instead of the Recipient type which relies on a nym address
|
||||
// replying to incoming message (from ourselves) with SURBs- note that sending a message to a recipient and
|
||||
// replying to an incoming are different functions
|
||||
boost::packaged_task<char> reply_fn(boost::bind(reply, sender_tag, reply_message));
|
||||
boost::unique_future<char> reply_future = reply_fn.get_future();
|
||||
reply_fn();
|
||||
return_code = reply_future.get();
|
||||
handle(return_code);
|
||||
|
||||
// sleep so that the client processes can catch up - in reality you'd have another process running to keep logging
|
||||
// going, so this is only necessary for this reference
|
||||
// sleep so that the nym side logging can catch up - in reality you'd have another process running to keep logging
|
||||
// going, so this is only necessary for this reference implementation
|
||||
std::this_thread::sleep_for(std::chrono::seconds(40));
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
pub mod types {
|
||||
|
||||
use std::ffi::c_char;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum StatusCode {
|
||||
NoError = 0,
|
||||
ClientInitError = -1,
|
||||
ClientUninitialisedError = -2,
|
||||
SelfAddrError = -3,
|
||||
SendMsgError = -4,
|
||||
ReplyError = -5,
|
||||
ListenError = -6,
|
||||
RecipientNullError = -7,
|
||||
MessageNullError = -8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CStringCallback {
|
||||
pub callback: extern "C" fn(*const c_char),
|
||||
}
|
||||
|
||||
impl CStringCallback {
|
||||
pub fn new(callback: extern "C" fn(*const c_char)) -> Self {
|
||||
CStringCallback { callback }
|
||||
}
|
||||
pub fn trigger(&self, char: *const c_char) {
|
||||
(self.callback)(char);
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CMessageCallback {
|
||||
pub callback: extern "C" fn(ReceivedMessage),
|
||||
}
|
||||
|
||||
impl CMessageCallback {
|
||||
pub fn new(callback: extern "C" fn(ReceivedMessage)) -> Self {
|
||||
CMessageCallback { callback }
|
||||
}
|
||||
pub fn trigger(&self, message: ReceivedMessage) {
|
||||
(self.callback)(message)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ReceivedMessage {
|
||||
pub message: *const u8,
|
||||
pub size: usize,
|
||||
pub sender_tag: *const c_char,
|
||||
}
|
||||
}
|
||||
Generated
-6061
File diff suppressed because it is too large
Load Diff
@@ -1,31 +0,0 @@
|
||||
[package]
|
||||
name = "nym-go-ffi" #"goffitest"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
name = "nym_go_ffi" #"go_ffi"
|
||||
|
||||
[dependencies]
|
||||
# Bindgen
|
||||
uniffi = { version = "0.25.2", features = ["cli"] }
|
||||
# Nym clients, addressing, packet format, common tools (logging), ffi shared
|
||||
nym-bin-common = { git = "https://github.com/nymtech/nym", branch = "master" }
|
||||
nym-sdk = { git = "https://github.com/nymtech/nym", branch = "master" }
|
||||
nym-sphinx-anonymous-replies = { git = "https://github.com/nymtech/nym", branch = "master" }
|
||||
nym-ffi-shared = { path = "../shared" }
|
||||
# Async runtime
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
lazy_static = "1.4.0"
|
||||
# error handling
|
||||
anyhow = "1.0.79"
|
||||
thiserror = "1.0.56"
|
||||
|
||||
[build-dependencies]
|
||||
uniffi = { version = "0.25.2", features = ["build" ] }
|
||||
uniffi_build = { version = "0.25.2", features=["builtin-bindgen"] }
|
||||
|
||||
[[bin]]
|
||||
name = "uniffi-bindgen"
|
||||
path = "uniffi-bindgen.rs"
|
||||
@@ -1,47 +0,0 @@
|
||||
# Go FFI
|
||||
> ⚠️ This is an initial version of this library in order to give developers something to experiment with. If you use this code to begin testing out Mixnet integration and run into issues, errors, or have feedback, please feel free to open an issue; feedback from developers trying to use it will help us improve it. If you have questions feel free to reach out via our [Matrix channel](https://matrix.to/#/#dev:nymtech.chat).
|
||||
|
||||
This repo contains:
|
||||
* `lib.rs`: an initial version of bindings for interacting with the Mixnet via the Rust SDK from Go. These are essentially match statemtns wrapping imported functions from the `nym-ffi-shared` lib.
|
||||
* `ffi/`: a directory containing:
|
||||
* the `bindings/` files generated using [`uniffi-bindgen-go`](https://github.com/NordSecurity/uniffi-bindgen-go)
|
||||
* [`example.go`](./example.go): an example of using this library.
|
||||
|
||||
The `example.go` file is an example flow of:
|
||||
* setting up Nym client logging
|
||||
* creating an ephemeral Nym client (no key storage / persistent address - this will come in a future iteration)
|
||||
* getting its [Nym address](https://nymtech.net/docs/clients/addressing-system.html)
|
||||
* using that address to send a message to yourself via the Mixnet
|
||||
* listen for and parse the incoming message for the `sender_tag` used for [anonymous replies with SURBs](https://nymtech.net/docs/architecture/traffic-flow.html#private-replies-using-surbs)
|
||||
* send a reply to yourself using SURBs
|
||||
|
||||
## Useage - Consuming the Library
|
||||
You can import the bindings as normal and interact with them as shown in the [example file](./example.go). This example imports the bindings from the this repository (hence the `go.mod` and `go.sum` in the crate root) but you can import them remotely as usual.
|
||||
|
||||
## Useage - Developing on the Library
|
||||
If you want to fork and add new features/functions to this library use the following instructions to rebuild the Go bindings.
|
||||
|
||||
Rust functions exposed to the Go binding library are in `./src/lib.rs`.
|
||||
|
||||
The `build.sh` script in the root of the repository speeds up the task of building and linking the Rust and Go code.
|
||||
* if want to quickly recompile your code run it as-is with `./build.sh`
|
||||
* if you want to clean build both the Rust and Go code after removing existing compiled binaries run it with the optional `clean` argument: `./build.sh clean`.
|
||||
|
||||
> Make sure to run the script from the root of the project directory, and that your LD PATH is set first!
|
||||
> ```
|
||||
> RUST_BINARIES=target/release
|
||||
> echo 'export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:'${RUST_BINARIES} >> ~/.zshrc
|
||||
> source ~/.zshrc
|
||||
> ```
|
||||
|
||||
This script will:
|
||||
* (optionally if called with `clean` argument) remove existing Rust and Go artifacts
|
||||
* build `lib.rs` with the `--release` flag
|
||||
* compile the Go bindings
|
||||
|
||||
**WIP** you need to manually add the following `cgo` flags to the generated bindings immediately underneath LN3 (`// #include <bindings.h`). In the future this will be automated in `build.sh`:
|
||||
|
||||
```
|
||||
// #cgo LDFLAGS: -L../../target/release -lnym_go_ffi
|
||||
```
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
fn main() {
|
||||
uniffi::generate_scaffolding("src/bindings.udl").unwrap();
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
PROJECT_NAME="go"
|
||||
|
||||
set -eu
|
||||
MODE="--release"
|
||||
|
||||
GO_DIR="./go-nym"
|
||||
UDL_PATH="./src/bindings.udl"
|
||||
|
||||
build_artifacts() {
|
||||
# build rust
|
||||
cargo build $MODE
|
||||
# build go bindings
|
||||
printf "building go bindings \n"
|
||||
uniffi-bindgen-go $UDL_PATH --out-dir $GO_DIR
|
||||
printf "bindings built \n\n"
|
||||
|
||||
# something not right with these - having to add it manually to bindings.go for the moment
|
||||
# pushd $GO_DIR/bindings
|
||||
# echo $(pwd)
|
||||
# LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}:../../target/release" \
|
||||
# CGO_LDFLAGS="-L../target/release -lnym_go_ffi -lm -ldl" \
|
||||
# CGO_ENABLED=1 \
|
||||
# go run ../main.go
|
||||
}
|
||||
|
||||
clean_artifacts() {
|
||||
# clean up existing things
|
||||
rm -rf $GO_DIR
|
||||
cargo clean
|
||||
}
|
||||
|
||||
|
||||
if [ $(pwd | awk -F/ '{print $NF}') != ${PROJECT_NAME} ]
|
||||
then
|
||||
printf "please run from root dir of project"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $# -eq 0 ];
|
||||
then
|
||||
build_artifacts;
|
||||
else
|
||||
arg=$1
|
||||
if [ "$arg" == "clean" ]; then
|
||||
clean_artifacts;
|
||||
build_artifacts;
|
||||
else
|
||||
printf "unknown optional argument - the only available optional argument is 'clean'"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@@ -1,74 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"nymffi/go-nym/bindings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
// initialise Nym client logging - this is quite verbose but very informative
|
||||
bindings.InitLogging()
|
||||
|
||||
// initialise an ephemeral client - aka one without specified keystore
|
||||
err := bindings.InitEphemeral()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// get our client's address
|
||||
str, err2 := bindings.GetSelfAddress()
|
||||
if err2 != nil {
|
||||
fmt.Println("(Go) Error:", err2)
|
||||
return
|
||||
}
|
||||
fmt.Println("(Go) response:")
|
||||
fmt.Println(str)
|
||||
|
||||
// send a message through the mixnet - in this case to ourselves using the value from GetSelfAddress
|
||||
err3 := bindings.SendMessage(str, "helloworld")
|
||||
if err3 != nil {
|
||||
fmt.Println("(Go) Error:", err3)
|
||||
return
|
||||
}
|
||||
|
||||
// listen out for incoming messages: in the future the client can be split into a listening and a sending client,
|
||||
// allowing for this to run as a persistent process in its own thread and not have to block but instead be running
|
||||
// concurrently
|
||||
//
|
||||
// assuming a data type like so:
|
||||
// type IncomingMessage struct {
|
||||
// Message string
|
||||
// SenderTag vec<u8>
|
||||
// }
|
||||
incomingMessage, err4 := bindings.ListenForIncoming()
|
||||
if err4 != nil {
|
||||
fmt.Println("(Go) Error:", err4)
|
||||
return
|
||||
}
|
||||
fmt.Println("(Go) incoming message: ", incomingMessage.Message, " from: ", incomingMessage.Sender)
|
||||
|
||||
// we can just use the byte array we parsed from the incoming message to reply with: this is a
|
||||
// byte representation of the sender_tag used for Single Use Reply Blocks (SURBs)
|
||||
//
|
||||
// replying to incoming message (from ourselves) with SURBs - note that sending a message to a recipient and
|
||||
// replying to an incoming are different functions: replying relies on parsing the incoming sender_tag on the Rust
|
||||
// side and creating an AnonymousSenderTag type, instead of the Recipient type which relies on a nym address
|
||||
//
|
||||
// you will see in the client logs that there are requests for more SURBs that we send to ourselves to
|
||||
// be able to fit the full reply message in there. In a future iteration of this code we can also expose
|
||||
// a send() which allows for developers to dictate the number of SURBs to send along with their outgoing message
|
||||
fmt.Println("(Go) replying to received message")
|
||||
err5 := bindings.Reply(incomingMessage.Sender, "replyworld")
|
||||
if err5 != nil {
|
||||
fmt.Println("(Go) Error:", err5)
|
||||
return
|
||||
}
|
||||
|
||||
// sleep so that the nym client processes can catch up - in reality you'd have another process
|
||||
// running to keep logging going, so this is only necessary for this reference
|
||||
time.Sleep(30 * time.Second)
|
||||
fmt.Println("(Go) end go example")
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#include <bindings.h>
|
||||
|
||||
// This file exists beacause of
|
||||
// https://github.com/golang/go/issues/11263
|
||||
|
||||
void cgo_rust_task_callback_bridge_bindings(RustTaskCallback cb, const void * taskData, int8_t status) {
|
||||
cb(taskData, status);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user