Compare commits

..

39 Commits

Author SHA1 Message Date
Tommy Verrall 6f1321e1b0 testing cosmwasm docker optimiser 2024-05-23 10:44:45 +02:00
Tommy Verrall 76953df4bb Merge pull request #4605 from nymtech/feature/nym-node-api-location
Feature/nym node api location
2024-05-21 17:28:53 +01:00
Tommy Verrall ce2449f86a Merge pull request #4599 from nymtech/feature/expose-all-api-reports
nym-api: make report/avg_uptime endpoints ignore blacklist
2024-05-21 17:28:07 +01:00
Jędrzej Stuczyński 598014bf30 fixed deserialisation of 'AuxiliaryDetails' api response 2024-05-21 17:06:15 +01:00
Jędrzej Stuczyński 73fe7618db removing needless clones 2024-05-21 17:06:15 +01:00
Jędrzej Stuczyński 7a416f8cf5 aggregate new data with nym-api 2024-05-21 17:06:14 +01:00
Jędrzej Stuczyński 3077c2ea8d create '/api/v1/auxiliary-details' that exposes nodes location 2024-05-21 17:06:13 +01:00
Tommy Verrall be6c63723c Merge pull request #4553 from nymtech/jon/autoinherit
Run cargo autoinherit on the main workspace
2024-05-21 16:33:38 +01:00
Jon Häggblad c5a3cb7707 Update to handle changes in develop 2024-05-21 17:15:38 +02:00
Jon Häggblad cce9f0b183 Merge remote-tracking branch 'origin/develop' into jon/autoinherit 2024-05-21 17:10:02 +02:00
Tommy Verrall 84b74703b2 Merge pull request #4604 from nymtech/jon/ipr-request-sign
Add optional signature to IPR request/response
2024-05-21 15:01:43 +01:00
Tommy Verrall 9bf3600e5b Merge pull request #4601 from nymtech/feature/unstable-tested-nodes-endpoint
Feature/unstable tested nodes endpoint
2024-05-21 14:51:46 +01:00
Jędrzej Stuczyński 9f20c8ed1f Merge pull request #4598 from nymtech/feature/remove-coconut-wait-buffer
removed blocking for coconut in the final epoch state
2024-05-21 10:19:38 +01:00
Jędrzej Stuczyński 84e66c34f2 Merge pull request #4584 from nymtech/feature/wasm-coconut
Feature/wasm coconut
2024-05-21 10:08:40 +01:00
Jędrzej Stuczyński e04df37988 Merge pull request #4595 from nymtech/feature/freepass-admin
allow using explicit admin address for issuing freepasses
2024-05-21 10:07:44 +01:00
Jon Häggblad c91412f949 Restore exact same serde import for common contract crates 2024-05-20 13:45:18 +02:00
Jon Häggblad 0a89f31a29 Merge in new deps in the main list 2024-05-20 13:19:47 +02:00
Jon Häggblad 9badeac832 cargo autoinherit in root workspace 2024-05-20 13:16:25 +02:00
Jon Häggblad b59c41d9cd Fix test 2024-05-20 12:24:39 +02:00
Jon Häggblad 8f083ff91e Add signatures to dynamic connect and disconect, and remove from response 2024-05-20 12:18:28 +02:00
Jon Häggblad 0f44836025 Move signature one layer down 2024-05-20 12:04:05 +02:00
Jon Häggblad 68ee2d747d Add timestamps to requests 2024-05-20 11:53:00 +02:00
Jon Häggblad e29c76678d Add optional signature field to requests and responses 2024-05-20 10:58:10 +02:00
Jon Häggblad a4005c7d81 Add v7 request/responses 2024-05-20 10:57:56 +02:00
Jędrzej Stuczyński efe6d916e2 order results by timestamp desc 2024-05-20 09:29:09 +01:00
Jędrzej Stuczyński 910b6a1369 adding explicit 'unstable' path segment 2024-05-19 10:27:33 +01:00
Jędrzej Stuczyński 7818658ee8 flatten the response 2024-05-17 18:36:50 +01:00
Jędrzej Stuczyński 89e34b4fd3 queries for detailed node statuses with broken pagination 2024-05-17 17:02:29 +01:00
Jędrzej Stuczyński 2f5a00dbda removed blocking for coconut in the final epoch state 2024-05-17 11:04:19 +01:00
Jędrzej Stuczyński 7f87d42f9a nym-api: make report/avg_uptime endpoints ignore blacklist 2024-05-17 11:01:16 +01:00
Jędrzej Stuczyński 93b12bccca updated the lock file after the rebasing fixes 2024-05-14 17:47:43 +01:00
Jędrzej Stuczyński 89fb4ef03f fixing more build issues 2024-05-14 17:45:17 +01:00
Jędrzej Stuczyński b8ab187db0 fixed wrong version of gloo-net and removed reduntant imports 2024-05-14 17:45:17 +01:00
Jędrzej Stuczyński a9790c1f66 removed duplicate 'set_panic_hook' symbol in the browser extension code 2024-05-14 17:45:17 +01:00
Jędrzej Stuczyński b46634b8f7 fixed test import paths 2024-05-14 17:45:17 +01:00
Jędrzej Stuczyński 633e7ffb46 no idea what happened here 2024-05-14 17:45:16 +01:00
Jędrzej Stuczyński dd2077bf12 updated the makefile 2024-05-14 17:45:16 +01:00
Jędrzej Stuczyński 0323ba2bb9 ability to obtain bandwidth voucher from wasm via vpn-api 2024-05-14 17:45:14 +01:00
Jędrzej Stuczyński 07cc47a0ff allow using explicit admin address for issuing freepasses 2024-05-14 16:58:11 +01:00
181 changed files with 7225 additions and 1808 deletions
@@ -35,7 +35,7 @@ jobs:
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: 1.77.0
target: wasm32-unknown-unknown
override: true
@@ -47,6 +47,17 @@ jobs:
- name: Build release contracts
run: make contracts
- name: Install CosmWasm optimizer
run: |
sudo apt-get update
sudo apt-get install -y docker.io
- name: Optimize WASM contracts
run: |
docker run --rm -v $(pwd)/contracts/target/wasm32-unknown-unknown/release:/code \
--mount type=volume,source=cosmwasm_cache,target=/code/cache \
cosmwasm/workspace-optimizer:0.12.9
- name: Prepare build output
shell: bash
env:
@@ -58,8 +69,7 @@ jobs:
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/nym_service_provider_directory.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/nym_name_service.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/nym_ecash.wasm $OUTPUT_DIR
- name: Deploy branch to CI www
continue-on-error: true
Generated
+319 -122
View File
File diff suppressed because it is too large Load Diff
+111 -13
View File
@@ -122,6 +122,7 @@ members = [
# "wasm/full-nym-wasm",
"wasm/mix-fetch",
"wasm/node-tester",
"wasm/zknym-lib",
]
default-members = [
@@ -158,46 +159,142 @@ edition = "2021"
license = "Apache-2.0"
[workspace.dependencies]
addr = "0.15.6"
aes = "0.8.1"
aes-gcm = "0.10.1"
anyhow = "1.0.71"
argon2 = "0.5.0"
async-trait = "0.1.68"
axum = "0.7.5"
axum-extra = "0.9.3"
base64 = "0.21.4"
bs58 = "0.5.0"
bincode = "1.3.3"
bip39 = { version = "2.0.0", features = ["zeroize"] }
clap = "4.4.7"
bitvec = "1.0.0"
blake3 = "1.3.1"
bs58 = "0.5.0"
bytecodec = "0.4.15"
bytes = "1.5.0"
cargo_metadata = "0.18.1"
celes = "2.4.0"
cfg-if = "1.0.0"
chacha20 = "0.9.0"
chacha20poly1305 = "0.10.1"
chrono = "0.4.31"
cipher = "0.4.3"
clap = "4.4.7"
clap_complete = "4.0"
clap_complete_fig = "4.0"
colored = "2.0"
comfy-table = "6.0.0"
console-subscriber = "0.1.1"
console_error_panic_hook = "0.1"
const-str = "0.5.6"
const_format = "0.2.32"
criterion = "0.4"
csv = "1.3.0"
ctr = "0.9.1"
cupid = "0.6.1"
curve25519-dalek = "3.2"
dashmap = "5.5.3"
defguard_wireguard_rs = { git = "https://github.com/neacsu/wireguard-rs.git", rev = "c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed" }
doc-comment = "0.3"
dotenvy = "0.15.6"
ecdsa = "0.16"
ed25519-dalek = "1.0"
etherparse = "0.13.0"
eyre = "0.6.9"
flate2 = "1.0.28"
futures = "0.3.28"
generic-array = "0.14.7"
getrandom = "0.2.10"
getset = "0.1.1"
handlebars = "3.5.5"
headers = "0.4.0"
hex = "0.4.3"
hex-literal = "0.3.3"
hkdf = "0.12.3"
hmac = "0.12.1"
httpcodec = "0.2.3"
humantime = "2.1.0"
humantime-serde = "1.1.1"
http = "1"
hyper = "1.3.1"
indexed_db_futures = "0.3.0"
inquire = "0.6.2"
ip_network = "0.4.1"
isocountry = "0.3.2"
k256 = "0.13"
lazy_static = "1.4.0"
ledger-transport = "0.10.0"
ledger-transport-hid = "0.10.0"
log = "0.4"
maxminddb = "0.23.0"
mime = "0.3.17"
nix = "0.27.1"
notify = "5.1.0"
okapi = "0.7.0"
once_cell = "1.7.2"
opentelemetry = "0.19.0"
opentelemetry-jaeger = "0.18.0"
parking_lot = "0.12.1"
pem = "0.8"
pin-project = "1.0"
pretty_env_logger = "0.4.0"
publicsuffix = "2.2.3"
quote = "1"
rand = "0.8.5"
rand-07 = "0.7.3"
rand_chacha_02 = "0.2"
rand_core = "0.6.3"
rand_distr = "0.3"
rand_pcg = "0.3.1"
rand_seeder = "0.2.3"
rayon = "1.5.1"
regex = "1.8.4"
reqwest = { version = "0.12.4", default-features = false }
rocket = "0.5.0"
rocket_cors = "0.6.0"
rocket_okapi = "0.8.0"
safer-ffi = "0.1.4"
schemars = "0.8.1"
serde = "1.0.152"
serde_bytes = "0.11.6"
serde_derive = "1.0"
serde_json = "1.0.91"
serde_repr = "0.1"
serde_with = "3.4.0"
serde_yaml = "0.9.25"
si-scale = "0.2.2"
sphinx-packet = "0.1.0"
sqlx = "0.6.3"
strum = "0.25"
subtle-encoding = "0.5"
syn = "1"
tap = "1.0.1"
time = "0.3.30"
tar = "0.4.40"
tempfile = "3.5.0"
thiserror = "1.0.48"
time = "0.3.30"
tokio = "1.33.0"
tokio-util = "0.7.10"
tokio-stream = "0.1.14"
tokio-test = "0.4.2"
tokio-tungstenite = { version = "0.20.1" }
tokio-util = "0.7.10"
tower = "0.4.13"
tower-http = "0.5.2"
tracing = "0.1.37"
tungstenite = { version = "0.20.1", default-features = false }
tracing-opentelemetry = "0.19.0"
tracing-subscriber = "0.3.16"
tracing-tree = "0.2.2"
ts-rs = "7.0.0"
tungstenite = { version = "0.20.1", default-features = false }
url = "2.4"
utoipa = "4.2.0"
utoipa-swagger-ui = "6.0.0"
url = "2.4"
vergen = { version = "=8.2.6", default-features = false }
walkdir = "2"
wasm-bindgen-test = "0.3.36"
zeroize = "1.6.0"
prometheus = { version = "0.13.0" }
@@ -209,7 +306,6 @@ bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch = "feature/g
group = "0.13.0"
ff = "0.13.0"
# cosmwasm-related
cosmwasm-derive = "=1.4.3"
cosmwasm-schema = "=1.4.3"
@@ -237,14 +333,16 @@ tendermint-rpc = "0.34" # same version as used by cosmrs
prost = "0.12"
# wasm-related dependencies
gloo-utils = "0.1.7"
js-sys = "0.3.63"
serde-wasm-bindgen = "0.5.0"
gloo-utils = "0.2.0"
gloo-net = "0.5.0"
js-sys = "0.3.69"
serde-wasm-bindgen = "0.6.5"
tsify = "0.4.5"
wasm-bindgen = "0.2.86"
wasm-bindgen-futures = "0.4.37"
wasm-bindgen = "0.2.92"
wasm-bindgen-futures = "0.4.39"
wasmtimer = "0.2.0"
web-sys = "0.3.63"
web-sys = "0.3.69"
# Profile settings for individual crates
+2 -1
View File
@@ -105,6 +105,7 @@ sdk-wasm-build:
$(MAKE) -C wasm/client
$(MAKE) -C wasm/node-tester
$(MAKE) -C wasm/mix-fetch
$(MAKE) -C wasm/zknym-lib
#$(MAKE) -C wasm/full-nym-wasm
# run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo
@@ -115,7 +116,7 @@ sdk-typescript-build:
yarn --cwd sdk/typescript/codegen/contract-clients build
# NOTE: These targets are part of the main workspace (but not as wasm32-unknown-unknown)
WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm
WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm zknym-lib
sdk-wasm-test:
#cargo test $(addprefix -p , $(WASM_CRATES)) --target wasm32-unknown-unknown -- -Dwarnings
+2 -2
View File
@@ -25,11 +25,11 @@ bs58 = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
dirs = "4.0"
log = { workspace = true } # self explanatory
rand = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
serde_json = { workspace = true }
thiserror = { workspace = true }
tap = "1.0.1"
tap = { workspace = true }
time = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] } # async runtime
tokio-tungstenite = { workspace = true }
+3 -3
View File
@@ -13,10 +13,10 @@ clap = { workspace = true, features = ["cargo", "derive"] }
log = { workspace = true }
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
serde_json = { workspace = true }
tap = "1.0.1"
tap = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] }
rand = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] }
rand = "0.7.3"
time = { workspace = true }
url = { workspace = true }
zeroize = { workspace = true }
+2 -2
View File
@@ -8,6 +8,6 @@ license.workspace = true
[dependencies]
futures = { workspace = true }
log = "0.4"
notify = "5.1.0"
log = { workspace = true }
notify = { workspace = true }
tokio = { workspace = true, features = ["time"] }
+1 -1
View File
@@ -9,7 +9,7 @@ license.workspace = true
[dependencies]
bip39 = { workspace = true }
log = { workspace = true }
rand = { workspace = true }
rand = "0.7.3"
thiserror = { workspace = true }
url = { workspace = true }
zeroize = { workspace = true }
+10 -22
View File
@@ -8,40 +8,28 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
const-str = "0.5.6"
const-str = { workspace = true }
clap = { workspace = true, features = ["derive"] }
clap_complete = "4.0"
clap_complete_fig = "4.0"
clap_complete = { workspace = true }
clap_complete_fig = { workspace = true }
log = { workspace = true }
pretty_env_logger = "0.4.0"
pretty_env_logger = { workspace = true }
semver = "0.11"
schemars = { workspace = true, features = ["preserve_order"], optional = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, optional = true }
## tracing
tracing-subscriber = { version = "0.3.16", features = [
"env-filter",
], optional = true }
tracing-tree = { version = "0.2.2", optional = true }
opentelemetry-jaeger = { version = "0.18.0", optional = true, features = [
"rt-tokio",
"collector_client",
"isahc_collector_client",
] }
tracing-opentelemetry = { version = "0.19.0", optional = true }
tracing-subscriber = { workspace = true, features = ["env-filter"], optional = true }
tracing-tree = { workspace = true, optional = true }
opentelemetry-jaeger = { workspace = true, features = ["rt-tokio", "collector_client", "isahc_collector_client"], optional = true }
tracing-opentelemetry = { workspace = true, optional = true }
utoipa = { workspace = true, optional = true }
opentelemetry = { version = "0.19.0", optional = true, features = ["rt-tokio"] }
opentelemetry = { workspace = true, features = ["rt-tokio"], optional = true }
[build-dependencies]
vergen = { version = "=8.2.6", default-features = false, features = [
"build",
"git",
"gitcl",
"rustc",
"cargo",
] }
vergen = { workspace = true, features = ["build", "git", "gitcl", "rustc", "cargo"] }
[features]
default = []
+5 -5
View File
@@ -12,17 +12,17 @@ license.workspace = true
async-trait = { workspace = true }
base64 = "0.21.2"
bs58 = { workspace = true }
cfg-if = "1.0.0"
cfg-if = { workspace = true }
clap = { workspace = true, optional = true }
futures = { workspace = true }
humantime-serde = { workspace = true }
log = { workspace = true }
rand = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = "0.10.6"
si-scale = "0.2.2"
tap = "1.0.1"
si-scale = { workspace = true }
tap = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true, features = ["serde"] }
tokio = { workspace = true, features = ["macros"] }
@@ -108,7 +108,7 @@ version = "0.3.17"
features = ["wasm-bindgen"]
[dev-dependencies]
tempfile = "3.1.0"
tempfile = { workspace = true }
[features]
default = []
+3 -3
View File
@@ -14,9 +14,9 @@ futures = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true }
rand = { workspace = true }
tokio = { version = "1.24.1", features = ["macros"] }
si-scale = "0.2.2"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
tokio = { workspace = true, features = ["macros"] }
si-scale = { workspace = true }
time.workspace = true
# internal
@@ -10,7 +10,7 @@ license.workspace = true
[dependencies]
base64 = "0.13"
colored = "2.0"
colored = { workspace = true }
nym-coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" }
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
@@ -48,14 +48,14 @@ tendermint-rpc = { workspace = true }
# of cargo's feature unification we'd get `bip32/std` meaning we'd get `std::error::Error` for the re-exported (via cosmrs) bip32::Error type
bip32 = { workspace = true, default-features = false, features = ["std"] }
eyre = { version = "0.6" }
eyre = { workspace = true }
cw-utils = { workspace = true }
cw2 = { workspace = true }
cw3 = { workspace = true }
cw4 = { workspace = true }
cw-controllers = { workspace = true }
prost = { workspace = true, default-features = false }
flate2 = { version = "1.0.20" }
flate2 = { workspace = true }
sha2 = { version = "0.9.5" }
itertools = { version = "0.10" }
zeroize = { workspace = true, features = ["zeroize_derive"] }
+7 -7
View File
@@ -10,26 +10,26 @@ anyhow = { workspace = true }
base64 = "0.13.0"
bip39 = { workspace = true }
bs58 = { workspace = true }
comfy-table = "6.0.0"
cfg-if = "1.0.0"
comfy-table = { workspace = true }
cfg-if = { workspace = true }
clap = { workspace = true, features = ["derive"] }
csv = "1.3.0"
csv = { workspace = true }
cw-utils = { workspace = true }
futures = { workspace = true }
handlebars = "3.0.1"
handlebars = { workspace = true }
humantime-serde = { workspace = true }
inquire = "0.6.2"
inquire = { workspace = true }
k256 = { workspace = true, features = ["ecdsa", "sha256"] }
log = { workspace = true }
rand = {version = "0.6", features = ["std"] }
serde = { version = "1.0", features = ["derive"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
time = { workspace = true, features = ["parsing", "formatting"] }
tokio = { workspace = true, features = ["sync"]}
toml = "0.5.6"
url = { workspace = true }
tap = "1"
tap = { workspace = true }
zeroize = { workspace = true }
cosmrs = { workspace = true }
+1 -1
View File
@@ -9,7 +9,7 @@ license.workspace = true
[dependencies]
dirs = { version = "5.0.1", optional = true }
handlebars = "3.5.5"
handlebars = { workspace = true }
log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
toml = "0.7.4"
@@ -11,7 +11,7 @@ repository = { workspace = true }
bs58 = { workspace = true }
cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
schemars = "0.8"
schemars = { workspace = true }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
@@ -10,5 +10,5 @@ license.workspace = true
cosmwasm-schema = { workspace = true }
cw4 = { workspace = true }
cw-controllers = { workspace = true }
schemars = "0.8"
schemars = { workspace = true }
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
@@ -14,14 +14,14 @@ cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
cw2 = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"] }
serde_repr = "0.1"
serde_repr = { workspace = true }
# we still have to preserve that import for `JsonSchema` for `Layer` type (since we can't use cw_serde macro due to custom serde impl)
schemars = "0.8"
schemars = { workspace = true }
thiserror = { workspace = true }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
serde-json-wasm = { workspace = true }
humantime-serde = "1.1.1"
humantime-serde = { workspace = true }
# TO CHECK WHETHER STILL NEEDED:
log = { workspace = true }
@@ -13,6 +13,6 @@ cw4 = { workspace = true }
cw-storage-plus = { workspace = true }
cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
schemars = "0.8"
schemars = { workspace = true }
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
thiserror = { workspace = true }
@@ -13,7 +13,7 @@ cosmwasm-schema = { workspace = true }
cw2 = { workspace = true, optional = true }
mixnet-contract-common = { path = "../mixnet-contract", package = "nym-mixnet-contract-common", version = "0.6.0" }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
serde = { version = "1.0", features = ["derive"] }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
ts-rs = { workspace = true, optional = true}
+1 -1
View File
@@ -26,4 +26,4 @@ features = [ "rt-multi-thread", "net", "signal", "fs" ]
[build-dependencies]
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
-10
View File
@@ -11,11 +11,8 @@ use nym_validator_client::nyxd::contract_traits::{
};
use nym_validator_client::nyxd::Coin;
use std::path::PathBuf;
use std::process::exit;
use std::time::{Duration, SystemTime};
const SAFETY_BUFFER_SECS: u64 = 60; // 1 minute
pub async fn issue_credential<C>(
client: &C,
amount: Coin,
@@ -92,13 +89,6 @@ where
.as_secs();
if epoch.state.is_final() {
if let Some(finish_timestamp) = epoch.deadline {
if current_timestamp_secs + SAFETY_BUFFER_SECS >= finish_timestamp.seconds() {
info!("In the next {} minute(s), a transition will take place in the coconut system. Deposits should be halted in this time for safety reasons.", SAFETY_BUFFER_SECS / 60);
exit(0);
}
}
break;
} else if let Some(final_timestamp) = epoch.final_timestamp_secs() {
// Use 1 additional second to not start the next iteration immediately and spam get_current_epoch queries
+2 -2
View File
@@ -8,7 +8,7 @@ license.workspace = true
[dependencies]
bls12_381 = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] }
bincode = "1.3.3"
bincode = { workspace = true }
cosmrs = { workspace = true }
thiserror = { workspace = true }
log = { workspace = true }
@@ -23,5 +23,5 @@ nym-api-requests = { path = "../../nym-api/nym-api-requests" }
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
[dev-dependencies]
rand = "0.8.5"
rand = "0.7.3"
@@ -155,11 +155,6 @@ impl IssuedBandwidthCredential {
})
}
pub fn randomise_signature(&mut self) {
let signature_prime = self.signature.randomise(bandwidth_credential_params());
self.signature = signature_prime.0
}
pub fn default_parameters() -> Parameters {
IssuanceBandwidthCredential::default_parameters()
}
@@ -30,6 +30,10 @@ impl<'a> From<&'a BandwidthVoucherIssuanceData> for BandwidthVoucherIssuedData {
}
impl BandwidthVoucherIssuedData {
pub fn new(value: Coin) -> Self {
BandwidthVoucherIssuedData { value }
}
pub fn value(&self) -> &Coin {
&self.value
}
+12 -12
View File
@@ -8,21 +8,21 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
aes = { version = "0.8.1", optional = true }
aes = { workspace = true, optional = true }
bs58 = { workspace = true }
blake3 = { version = "1.3.1", features = ["traits-preview"], optional = true }
ctr = { version = "0.9.1", optional = true }
blake3 = { workspace = true, features = ["traits-preview"], optional = true }
ctr = { workspace = true, optional = true }
digest = { version = "0.10.3", optional = true }
generic-array = { workspace = true, optional = true }
hkdf = { version = "0.12.3", optional = true }
hmac = { version = "0.12.1", optional = true }
cipher = { version = "0.4.3", optional = true }
x25519-dalek = { version = "2.0.0", optional = true }
ed25519-dalek = { version = "2.1", features = ["rand_core"], optional = true }
rand = { version = "0.8.5", optional = true }
serde_bytes = { version = "0.11.6", optional = true }
hkdf = { workspace = true, optional = true }
hmac = { workspace = true, optional = true }
cipher = { workspace = true, optional = true }
x25519-dalek = { version = "1.1", optional = true }
ed25519-dalek = { workspace = true, optional = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"], optional = true }
serde_bytes = { workspace = true, optional = true }
serde_crate = { version = "1.0", optional = true, default_features = false, features = ["derive"], package = "serde" }
subtle-encoding = { version = "0.5", features = ["bech32-preview"]}
subtle-encoding = { workspace = true, features = ["bech32-preview"] }
thiserror = { workspace = true }
zeroize = { workspace = true, optional = true, features = ["zeroize_derive"] }
@@ -31,7 +31,7 @@ nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0", default-fea
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
[dev-dependencies]
rand_chacha = "0.3"
rand_chacha = "0.2"
[features]
default = ["sphinx"]
+14 -4
View File
@@ -56,7 +56,7 @@ pub struct KeyPair {
impl KeyPair {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let private_key = x25519_dalek::StaticSecret::random_from_rng(rng);
let private_key = x25519_dalek::StaticSecret::new(rng);
let public_key = (&private_key).into();
KeyPair {
@@ -200,10 +200,18 @@ impl<'a> From<&'a PrivateKey> for PublicKey {
}
}
impl FromStr for PrivateKey {
type Err = KeyRecoveryError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
PrivateKey::from_base58_string(s)
}
}
impl PrivateKey {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let x25519_secret = x25519_dalek::StaticSecret::random_from_rng(rng);
let x25519_secret = x25519_dalek::StaticSecret::new(rng);
PrivateKey(x25519_secret)
}
@@ -322,7 +330,9 @@ impl<'a> From<&'a PrivateKey> for nym_sphinx_types::PrivateKey {
#[cfg(feature = "sphinx")]
impl From<nym_sphinx_types::PrivateKey> for PrivateKey {
fn from(private_key: nym_sphinx_types::PrivateKey) -> Self {
Self(private_key)
let private_key_bytes = private_key.to_bytes();
assert_eq!(private_key_bytes.len(), PRIVATE_KEY_SIZE);
Self::from_bytes(&private_key_bytes).unwrap()
}
}
@@ -364,7 +374,7 @@ mod sphinx_key_conversion {
#[test]
fn works_for_backward_conversion() {
for _ in 0..NUM_ITERATIONS {
let (sphinx_private, sphinx_public) = nym_sphinx_types::test_utils::fixtures::keygen();
let (sphinx_private, sphinx_public) = nym_sphinx_types::crypto::keygen();
let private_bytes = sphinx_private.to_bytes();
let public_bytes = sphinx_public.as_bytes();
+23 -21
View File
@@ -1,8 +1,8 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub use ed25519_dalek::ed25519::signature::Signature as SignatureTrait;
pub use ed25519_dalek::SignatureError;
use ed25519_dalek::{Signer, SigningKey};
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
use std::fmt::{self, Display, Formatter};
@@ -30,9 +30,6 @@ pub enum Ed25519RecoveryError {
#[error(transparent)]
MalformedBytes(#[from] SignatureError),
#[error(transparent)]
BytesLengthError(#[from] std::array::TryFromSliceError),
#[error("the base58 representation of the public key was malformed - {source}")]
MalformedPublicKeyString {
#[source]
@@ -67,11 +64,11 @@ pub struct KeyPair {
impl KeyPair {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let ed25519_signing_key = ed25519_dalek::SigningKey::generate(rng);
let ed25519_keypair = ed25519_dalek::Keypair::generate(rng);
KeyPair {
private_key: PrivateKey(ed25519_signing_key.to_bytes()),
public_key: PublicKey(ed25519_signing_key.verifying_key()),
private_key: PrivateKey(ed25519_keypair.secret),
public_key: PublicKey(ed25519_keypair.public),
}
}
@@ -112,7 +109,7 @@ impl PemStorableKeyPair for KeyPair {
/// ed25519 EdDSA Public Key
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct PublicKey(ed25519_dalek::VerifyingKey);
pub struct PublicKey(ed25519_dalek::PublicKey);
impl Display for PublicKey {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -138,9 +135,7 @@ impl PublicKey {
}
pub fn from_bytes(b: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Ok(PublicKey(ed25519_dalek::VerifyingKey::from_bytes(
b.try_into()?,
)?))
Ok(PublicKey(ed25519_dalek::PublicKey::from_bytes(b)?))
}
pub fn to_base58_string(self) -> String {
@@ -194,7 +189,7 @@ impl<'d> Deserialize<'d> for PublicKey {
where
D: Deserializer<'d>,
{
Ok(PublicKey(ed25519_dalek::VerifyingKey::deserialize(
Ok(PublicKey(ed25519_dalek::PublicKey::deserialize(
deserializer,
)?))
}
@@ -228,14 +223,22 @@ impl Display for PrivateKey {
impl<'a> From<&'a PrivateKey> for PublicKey {
fn from(pk: &'a PrivateKey) -> Self {
PublicKey(SigningKey::from_bytes(&pk.0).verifying_key())
PublicKey((&pk.0).into())
}
}
impl FromStr for PrivateKey {
type Err = Ed25519RecoveryError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
PrivateKey::from_base58_string(s)
}
}
impl PrivateKey {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let ed25519_secret = ed25519_dalek::SigningKey::generate(rng).to_bytes();
let ed25519_secret = ed25519_dalek::SecretKey::generate(rng);
PrivateKey(ed25519_secret)
}
@@ -245,11 +248,11 @@ impl PrivateKey {
}
pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
self.0
self.0.to_bytes()
}
pub fn from_bytes(b: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Ok(PrivateKey(b.try_into()?))
Ok(PrivateKey(ed25519_dalek::SecretKey::from_bytes(b)?))
}
pub fn to_base58_string(&self) -> String {
@@ -264,8 +267,9 @@ impl PrivateKey {
}
pub fn sign<M: AsRef<[u8]>>(&self, message: M) -> Signature {
let signing_key: SigningKey = self.0.into();
let sig = signing_key.sign(message.as_ref());
let expanded_secret_key = ed25519_dalek::ExpandedSecretKey::from(&self.0);
let public_key: PublicKey = self.into();
let sig = expanded_secret_key.sign(message.as_ref(), &public_key.0);
Signature(sig)
}
@@ -334,9 +338,7 @@ impl Signature {
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Ok(Signature(ed25519_dalek::Signature::from_bytes(
bytes.try_into()?,
)))
Ok(Signature(ed25519_dalek::Signature::from_bytes(bytes)?))
}
}
+2 -2
View File
@@ -3,11 +3,11 @@
use crate::asymmetric::encryption;
use crate::hkdf;
#[cfg(feature = "rand")]
use cipher::crypto_common::rand_core::{CryptoRng, RngCore};
use cipher::{Key, KeyIvInit, StreamCipher};
use digest::crypto_common::BlockSizeUser;
use digest::Digest;
#[cfg(feature = "rand")]
use rand::{CryptoRng, RngCore};
/// Generate an ephemeral encryption keypair and perform diffie-hellman to establish
/// shared key with the remote.
+5 -5
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bitvec = "1.0.0"
bitvec = { workspace = true }
# 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
@@ -17,13 +17,13 @@ nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common",
bs58 = { workspace = true }
lazy_static = "1.4.0"
lazy_static = { workspace = true }
rand = { version = "0.8.5", default-features = false}
rand_chacha = "0.3"
rand_core = "0.6.3"
rand_core = { workspace = true }
sha2 = "0.9"
serde = { workspace = true }
serde_derive = "1.0"
serde_derive = { workspace = true }
thiserror = { workspace = true }
zeroize = { workspace = true, features = ["zeroize_derive"] }
@@ -38,7 +38,7 @@ workspace = true
default-features = false
[dev-dependencies]
criterion = "0.4"
criterion = { workspace = true }
[[bench]]
name = "benchmarks"
+2 -2
View File
@@ -8,5 +8,5 @@ license.workspace = true
proc-macro = true
[dependencies]
syn = { version = "1", features = ["full"] }
quote = "1"
syn = { workspace = true, features = ["full"] }
quote = { workspace = true }
+1
View File
@@ -13,6 +13,7 @@ license.workspace = true
[dependencies]
async-trait = { workspace = true }
reqwest = { workspace = true, features = ["json"] }
http.workspace = true
url = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
+130 -31
View File
@@ -2,7 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
use async_trait::async_trait;
use reqwest::{IntoUrl, Response, StatusCode};
use reqwest::header::HeaderValue;
use reqwest::{RequestBuilder, Response, StatusCode};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
@@ -11,6 +12,8 @@ use thiserror::Error;
use tracing::warn;
use url::Url;
pub use reqwest::IntoUrl;
pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
pub type PathSegments<'a> = &'a [&'a str];
@@ -52,6 +55,88 @@ pub enum HttpClientError<E: Display = String> {
RequestTimeout,
}
pub struct ClientBuilder {
url: Url,
timeout: Option<Duration>,
custom_user_agent: bool,
reqwest_client_builder: reqwest::ClientBuilder,
}
impl ClientBuilder {
pub fn new<U, E>(url: U) -> Result<Self, HttpClientError<E>>
where
U: IntoUrl,
E: Display,
{
// a naive check: if the provided URL does not start with http(s), add that scheme
let str_url = url.as_str();
if !str_url.starts_with("http") {
let alt = format!("http://{str_url}");
warn!("the provided url ('{str_url}') does not contain scheme information. Changing it to '{alt}' ...");
// TODO: or should we maybe default to https?
Self::new(alt)
} else {
Ok(ClientBuilder {
url: url.into_url()?,
timeout: None,
custom_user_agent: false,
reqwest_client_builder: reqwest::ClientBuilder::new(),
})
}
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub fn with_reqwest_builder(mut self, reqwest_builder: reqwest::ClientBuilder) -> Self {
self.reqwest_client_builder = reqwest_builder;
self
}
pub fn with_user_agent<V>(mut self, value: V) -> Self
where
V: TryInto<HeaderValue>,
V::Error: Into<http::Error>,
{
self.custom_user_agent = true;
self.reqwest_client_builder = self.reqwest_client_builder.user_agent(value);
self
}
pub fn build<E>(self) -> Result<Client, HttpClientError<E>>
where
E: Display,
{
#[cfg(target_arch = "wasm32")]
let reqwest_client = self.reqwest_client_builder.build()?;
// TODO: we should probably be propagating the error rather than panicking,
// but that'd break bunch of things due to type changes
#[cfg(not(target_arch = "wasm32"))]
let reqwest_client = {
let mut builder = self
.reqwest_client_builder
.timeout(self.timeout.unwrap_or(DEFAULT_TIMEOUT));
if !self.custom_user_agent {
builder =
builder.user_agent(format!("nym-http-api-client/{}", env!("CARGO_PKG_VERSION")))
}
builder.build()?
};
Ok(Client {
base_url: self.url,
reqwest_client,
#[cfg(target_arch = "wasm32")]
request_timeout: self.timeout.unwrap_or(DEFAULT_TIMEOUT),
})
}
}
/// A simple extendable client wrapper for http request with extra url sanitization.
#[derive(Debug, Clone)]
pub struct Client {
@@ -65,25 +150,9 @@ pub struct Client {
impl Client {
// no timeout until https://github.com/seanmonstar/reqwest/issues/1135 is fixed
pub fn new(base_url: Url, timeout: Option<Duration>) -> Self {
#[cfg(target_arch = "wasm32")]
let reqwest_client = reqwest::Client::new();
// TODO: we should probably be propagating the error rather than panicking,
// but that'd break bunch of things due to type changes
#[cfg(not(target_arch = "wasm32"))]
let reqwest_client = reqwest::ClientBuilder::new()
.timeout(timeout.unwrap_or(DEFAULT_TIMEOUT))
.user_agent(format!("nym-http-api-client/{}", env!("CARGO_PKG_VERSION")))
.build()
.expect("Client::new()");
Client {
base_url,
reqwest_client,
#[cfg(target_arch = "wasm32")]
request_timeout: timeout.unwrap_or(DEFAULT_TIMEOUT),
}
Self::new_url::<_, String>(base_url, timeout).expect(
"we provided valid url and we were unwrapping previous construction errors anyway",
)
}
pub fn new_url<U, E>(url: U, timeout: Option<Duration>) -> Result<Self, HttpClientError<E>>
@@ -91,19 +160,21 @@ impl Client {
U: IntoUrl,
E: Display,
{
// a naive check: if the provided URL does not start with http(s), add that scheme
let str_url = url.as_str();
if !str_url.starts_with("http") {
let alt = format!("http://{str_url}");
warn!("the provided url ('{str_url}') does not contain scheme information. Changing it to '{alt}' ...");
// TODO: or should we maybe default to https?
Self::new_url(alt, timeout)
} else {
Ok(Self::new(url.into_url()?, timeout))
let builder = Self::builder(url)?;
match timeout {
Some(timeout) => builder.with_timeout(timeout).build(),
None => builder.build(),
}
}
pub fn builder<U, E>(url: U) -> Result<ClientBuilder, HttpClientError<E>>
where
U: IntoUrl,
E: Display,
{
ClientBuilder::new(url)
}
pub fn change_base_url(&mut self, new_url: Url) {
self.base_url = new_url
}
@@ -112,6 +183,19 @@ impl Client {
&self.base_url
}
pub fn create_get_request<K, V>(
&self,
path: PathSegments<'_>,
params: Params<'_, K, V>,
) -> RequestBuilder
where
K: AsRef<str>,
V: AsRef<str>,
{
let url = sanitize_url(&self.base_url, path, params);
self.reqwest_client.get(url)
}
async fn send_get_request<K, V, E>(
&self,
path: PathSegments<'_>,
@@ -142,6 +226,21 @@ impl Client {
}
}
pub fn create_post_request<B, K, V>(
&self,
path: PathSegments<'_>,
params: Params<'_, K, V>,
json_body: &B,
) -> RequestBuilder
where
B: Serialize + ?Sized,
K: AsRef<str>,
V: AsRef<str>,
{
let url = sanitize_url(&self.base_url, path, params);
self.reqwest_client.post(url).json(json_body)
}
async fn send_post_request<B, K, V, E>(
&self,
path: PathSegments<'_>,
@@ -407,7 +506,7 @@ pub fn sanitize_url<K: AsRef<str>, V: AsRef<str>>(
url
}
async fn parse_response<T, E>(res: Response, allow_empty: bool) -> Result<T, HttpClientError<E>>
pub async fn parse_response<T, E>(res: Response, allow_empty: bool) -> Result<T, HttpClientError<E>>
where
T: DeserializeOwned,
E: DeserializeOwned + Display,
+3 -3
View File
@@ -12,9 +12,9 @@ license.workspace = true
[dependencies]
axum.workspace = true
bytes = "1.5.0"
mime = "0.3.17"
bytes = { workspace = true }
mime = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
serde_yaml = "0.9.25"
serde_yaml = { workspace = true }
utoipa = { workspace = true }
+3 -2
View File
@@ -9,12 +9,13 @@ edition.workspace = true
license.workspace = true
[dependencies]
bincode = "1.3.3"
bytes = "1.5.0"
bincode = { workspace = true }
bytes = { workspace = true }
nym-bin-common = { path = "../bin-common" }
nym-sphinx = { path = "../nymsphinx" }
rand = "0.8.5"
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
time = { workspace = true }
tokio = { workspace = true, features = ["time"] }
tokio-util = { workspace = true, features = ["codec"] }
+2
View File
@@ -12,11 +12,13 @@ pub use v6::response;
pub mod codec;
pub mod v6;
pub mod v7;
// version 3: initial version
// version 4: IPv6 support
// version 5: Add severity level to info response
// version 6: Increase the available IPs
// version 7: Add signature support (for the future)
pub const CURRENT_VERSION: u8 = 6;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+2
View File
@@ -0,0 +1,2 @@
pub mod request;
pub mod response;
+395
View File
@@ -0,0 +1,395 @@
use nym_sphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION};
fn generate_random() -> u64 {
use rand::RngCore;
let mut rng = rand::rngs::OsRng;
rng.next_u64()
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IpPacketRequest {
pub version: u8,
pub data: IpPacketRequestData,
}
impl IpPacketRequest {
pub fn new_static_connect_request(
ips: IpPair,
reply_to: Recipient,
reply_to_hops: Option<u8>,
reply_to_avg_mix_delays: Option<f64>,
buffer_timeout: Option<u64>,
) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::StaticConnect(SignedStaticConnectRequest {
request: StaticConnectRequest {
request_id,
ips,
reply_to,
reply_to_hops,
reply_to_avg_mix_delays,
buffer_timeout,
timestamp: OffsetDateTime::now_utc(),
},
signature: None,
}),
},
request_id,
)
}
pub fn new_dynamic_connect_request(
reply_to: Recipient,
reply_to_hops: Option<u8>,
reply_to_avg_mix_delays: Option<f64>,
buffer_timeout: Option<u64>,
) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::DynamicConnect(SignedDynamicConnectRequest {
request: DynamicConnectRequest {
request_id,
reply_to,
reply_to_hops,
reply_to_avg_mix_delays,
buffer_timeout,
timestamp: OffsetDateTime::now_utc(),
},
signature: None,
}),
},
request_id,
)
}
pub fn new_disconnect_request(reply_to: Recipient) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::Disconnect(SignedDisconnectRequest {
request: DisconnectRequest {
request_id,
reply_to,
timestamp: OffsetDateTime::now_utc(),
},
signature: None,
}),
},
request_id,
)
}
pub fn new_data_request(ip_packets: bytes::Bytes) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::Data(DataRequest { ip_packets }),
}
}
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,
timestamp: OffsetDateTime::now_utc(),
}),
},
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,
timestamp: OffsetDateTime::now_utc(),
}),
},
request_id,
)
}
pub fn id(&self) -> Option<u64> {
match &self.data {
IpPacketRequestData::StaticConnect(request) => Some(request.request.request_id),
IpPacketRequestData::DynamicConnect(request) => Some(request.request.request_id),
IpPacketRequestData::Disconnect(request) => Some(request.request.request_id),
IpPacketRequestData::Data(_) => None,
IpPacketRequestData::Ping(request) => Some(request.request_id),
IpPacketRequestData::Health(request) => Some(request.request_id),
}
}
pub fn recipient(&self) -> Option<&Recipient> {
match &self.data {
IpPacketRequestData::StaticConnect(request) => Some(&request.request.reply_to),
IpPacketRequestData::DynamicConnect(request) => Some(&request.request.reply_to),
IpPacketRequestData::Disconnect(request) => Some(&request.request.reply_to),
IpPacketRequestData::Data(_) => None,
IpPacketRequestData::Ping(request) => Some(&request.reply_to),
IpPacketRequestData::Health(request) => Some(&request.reply_to),
}
}
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
pub fn from_reconstructed_message(
message: &nym_sphinx::receiver::ReconstructedMessage,
) -> Result<Self, bincode::Error> {
use bincode::Options;
make_bincode_serializer().deserialize(&message.message)
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum IpPacketRequestData {
StaticConnect(SignedStaticConnectRequest),
DynamicConnect(SignedDynamicConnectRequest),
Disconnect(SignedDisconnectRequest),
Data(DataRequest),
Ping(PingRequest),
Health(HealthRequest),
}
impl IpPacketRequestData {
pub fn add_signature(&mut self, signature: Vec<u8>) -> Option<Vec<u8>> {
match self {
IpPacketRequestData::StaticConnect(request) => {
request.signature = Some(signature);
request.signature.clone()
}
IpPacketRequestData::DynamicConnect(request) => {
request.signature = Some(signature);
request.signature.clone()
}
IpPacketRequestData::Disconnect(request) => {
request.signature = Some(signature);
request.signature.clone()
}
IpPacketRequestData::Data(_)
| IpPacketRequestData::Ping(_)
| IpPacketRequestData::Health(_) => None,
}
}
}
// A static connect request is when the client provides the internal IP address it will use on the
// ip packet router.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct StaticConnectRequest {
pub request_id: u64,
pub ips: IpPair,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// The number of mix node hops that responses should take, in addition to the entry and exit
// node. Zero means only client -> entry -> exit -> client.
pub reply_to_hops: Option<u8>,
// The average delay at each mix node, in milliseconds. Currently this is not supported by the
// ip packet router.
pub reply_to_avg_mix_delays: Option<f64>,
// The maximum time in milliseconds the IPR should wait when filling up a mix packet
// with ip packets.
pub buffer_timeout: Option<u64>,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
impl StaticConnectRequest {
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedStaticConnectRequest {
pub request: StaticConnectRequest,
pub signature: Option<Vec<u8>>,
}
// A dynamic connect request is when the client does not provide the internal IP address it will use
// on the ip packet router, and instead requests one to be assigned to it.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct DynamicConnectRequest {
pub request_id: u64,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// The number of mix node hops that responses should take, in addition to the entry and exit
// node. Zero means only client -> entry -> exit -> client.
pub reply_to_hops: Option<u8>,
// The average delay at each mix node, in milliseconds. Currently this is not supported by the
// ip packet router.
pub reply_to_avg_mix_delays: Option<f64>,
// The maximum time in milliseconds the IPR should wait when filling up a mix packet
// with ip packets.
pub buffer_timeout: Option<u64>,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
impl DynamicConnectRequest {
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedDynamicConnectRequest {
pub request: DynamicConnectRequest,
pub signature: Option<Vec<u8>>,
}
// A disconnect request is when the client wants to disconnect from the ip packet router and free
// up the allocated IP address.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct DisconnectRequest {
pub request_id: u64,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
impl DisconnectRequest {
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedDisconnectRequest {
pub request: DisconnectRequest,
pub signature: Option<Vec<u8>>,
}
// A data request is when the client wants to send an IP packet to a destination.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct DataRequest {
pub ip_packets: bytes::Bytes,
}
// A ping request is when the client wants to check if the ip packet router is still alive.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct PingRequest {
pub request_id: u64,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct HealthRequest {
pub request_id: u64,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
#[cfg(test)]
mod tests {
use super::*;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
#[test]
fn check_size_of_request() {
let connect = IpPacketRequest {
version: 4,
data: IpPacketRequestData::StaticConnect(
SignedStaticConnectRequest {
request: StaticConnectRequest {
request_id: 123,
ips: IpPair::new(Ipv4Addr::from_str("10.0.0.1").unwrap(), Ipv6Addr::from_str("2001:db8:a160::1").unwrap()),
reply_to: Recipient::try_from_base58_string("D1rrpsysCGCYXy9saP8y3kmNpGtJZUXN9SvFoUcqAsM9.9Ssso1ea5NfkbMASdiseDSjTN1fSWda5SgEVjdSN4CvV@GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN").unwrap(),
reply_to_hops: None,
reply_to_avg_mix_delays: None,
buffer_timeout: None,
timestamp: OffsetDateTime::now_utc(),
},
signature: None,
}
),
};
assert_eq!(connect.to_bytes().unwrap().len(), 139);
}
#[test]
fn check_size_of_data() {
let data = IpPacketRequest {
version: 4,
data: IpPacketRequestData::Data(DataRequest {
ip_packets: bytes::Bytes::from(vec![1u8; 32]),
}),
};
assert_eq!(data.to_bytes().unwrap().len(), 35);
}
#[test]
fn serialize_and_deserialize_data_request() {
let data = IpPacketRequest {
version: 4,
data: IpPacketRequestData::Data(DataRequest {
ip_packets: bytes::Bytes::from(vec![1, 2, 4, 2, 5]),
}),
};
let serialized = data.to_bytes().unwrap();
let deserialized = IpPacketRequest::from_reconstructed_message(
&nym_sphinx::receiver::ReconstructedMessage {
message: serialized,
sender_tag: None,
},
)
.unwrap();
assert_eq!(deserialized.version, 4);
assert_eq!(
deserialized.data,
IpPacketRequestData::Data(DataRequest {
ip_packets: bytes::Bytes::from(vec![1, 2, 4, 2, 5]),
})
);
}
}
@@ -0,0 +1,410 @@
use nym_sphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize};
use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IpPacketResponse {
pub version: u8,
pub data: IpPacketResponseData,
}
impl IpPacketResponse {
pub fn new_static_connect_success(request_id: u64, reply_to: Recipient) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
request_id,
reply_to,
reply: StaticConnectResponseReply::Success,
}),
}
}
pub fn new_static_connect_failure(
request_id: u64,
reply_to: Recipient,
reason: StaticConnectFailureReason,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
request_id,
reply_to,
reply: StaticConnectResponseReply::Failure(reason),
}),
}
}
pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IpPair) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
request_id,
reply_to,
reply: DynamicConnectResponseReply::Success(DynamicConnectSuccess { ips }),
}),
}
}
pub fn new_dynamic_connect_failure(
request_id: u64,
reply_to: Recipient,
reason: DynamicConnectFailureReason,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
request_id,
reply_to,
reply: DynamicConnectResponseReply::Failure(reason),
}),
}
}
pub fn new_disconnect_success(request_id: u64, reply_to: Recipient) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Disconnect(DisconnectResponse {
request_id,
reply_to,
reply: DisconnectResponseReply::Success,
}),
}
}
pub fn new_disconnect_failure(
request_id: u64,
reply_to: Recipient,
reason: DisconnectFailureReason,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Disconnect(DisconnectResponse {
request_id,
reply_to,
reply: DisconnectResponseReply::Failure(reason),
}),
}
}
pub fn new_unrequested_disconnect(
reply_to: Recipient,
reason: UnrequestedDisconnectReason,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::UnrequestedDisconnect(UnrequestedDisconnect {
reply_to,
reason,
}),
}
}
pub fn new_ip_packet(ip_packet: bytes::Bytes) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Data(DataResponse { ip_packet }),
}
}
pub fn new_version_mismatch(
request_id: u64,
reply_to: Recipient,
request_version: u8,
our_version: u8,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Info(InfoResponse {
request_id,
reply_to,
reply: InfoResponseReply::VersionMismatch {
request_version,
response_version: our_version,
},
level: InfoLevel::Error,
}),
}
}
pub fn new_data_info_response(
reply_to: Recipient,
reply: InfoResponseReply,
level: InfoLevel,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Info(InfoResponse {
request_id: 0,
reply_to,
reply,
level,
}),
}
}
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),
IpPacketResponseData::DynamicConnect(response) => Some(response.request_id),
IpPacketResponseData::Disconnect(response) => Some(response.request_id),
IpPacketResponseData::UnrequestedDisconnect(_) => None,
IpPacketResponseData::Data(_) => None,
IpPacketResponseData::Pong(response) => Some(response.request_id),
IpPacketResponseData::Health(response) => Some(response.request_id),
IpPacketResponseData::Info(response) => Some(response.request_id),
}
}
pub fn recipient(&self) -> Option<&Recipient> {
match &self.data {
IpPacketResponseData::StaticConnect(response) => Some(&response.reply_to),
IpPacketResponseData::DynamicConnect(response) => Some(&response.reply_to),
IpPacketResponseData::Disconnect(response) => Some(&response.reply_to),
IpPacketResponseData::UnrequestedDisconnect(response) => Some(&response.reply_to),
IpPacketResponseData::Data(_) => None,
IpPacketResponseData::Pong(response) => Some(&response.reply_to),
IpPacketResponseData::Health(response) => Some(&response.reply_to),
IpPacketResponseData::Info(response) => Some(&response.reply_to),
}
}
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
pub fn from_reconstructed_message(
message: &nym_sphinx::receiver::ReconstructedMessage,
) -> Result<Self, bincode::Error> {
use bincode::Options;
make_bincode_serializer().deserialize(&message.message)
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum IpPacketResponseData {
// Response for a static connect request
StaticConnect(StaticConnectResponse),
// Response for a dynamic connect request
DynamicConnect(DynamicConnectResponse),
// Response for a disconnect initiqated by the client
Disconnect(DisconnectResponse),
// Message from the server that the client got disconnected without the client initiating it
UnrequestedDisconnect(UnrequestedDisconnect),
// Response to a data request
Data(DataResponse),
// Response to ping request
Pong(PongResponse),
// Response for a health request
Health(HealthResponse),
// Info response. This can be anything from informative messages to errors
Info(InfoResponse),
}
impl IpPacketResponseData {
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StaticConnectResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: StaticConnectResponseReply,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum StaticConnectResponseReply {
Success,
Failure(StaticConnectFailureReason),
}
impl StaticConnectResponseReply {
pub fn is_success(&self) -> bool {
match self {
StaticConnectResponseReply::Success => true,
StaticConnectResponseReply::Failure(_) => false,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum StaticConnectFailureReason {
#[error("requested ip address is already in use")]
RequestedIpAlreadyInUse,
#[error("requested nym-address is already in use")]
RequestedNymAddressAlreadyInUse,
#[error("{0}")]
Other(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DynamicConnectResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: DynamicConnectResponseReply,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum DynamicConnectResponseReply {
Success(DynamicConnectSuccess),
Failure(DynamicConnectFailureReason),
}
impl DynamicConnectResponseReply {
pub fn is_success(&self) -> bool {
match self {
DynamicConnectResponseReply::Success(_) => true,
DynamicConnectResponseReply::Failure(_) => false,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DynamicConnectSuccess {
pub ips: IpPair,
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum DynamicConnectFailureReason {
#[error("requested nym-address is already in use")]
RequestedNymAddressAlreadyInUse,
#[error("no available ip address")]
NoAvailableIp,
#[error("{0}")]
Other(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DisconnectResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: DisconnectResponseReply,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum DisconnectResponseReply {
Success,
Failure(DisconnectFailureReason),
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum DisconnectFailureReason {
#[error("requested nym-address is not currently connected")]
RequestedNymAddressNotConnected,
#[error("{0}")]
Other(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct UnrequestedDisconnect {
pub reply_to: Recipient,
pub reason: UnrequestedDisconnectReason,
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum UnrequestedDisconnectReason {
#[error("client mixnet traffic timeout")]
ClientMixnetTrafficTimeout,
#[error("client tun traffic timeout")]
ClientTunTrafficTimeout,
#[error("{0}")]
Other(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DataResponse {
pub ip_packet: bytes::Bytes,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PongResponse {
pub request_id: u64,
pub reply_to: Recipient,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct HealthResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: HealthResponseReply,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct HealthResponseReply {
// Return the binary build information of the IPR
pub build_info: nym_bin_common::build_information::BinaryBuildInformationOwned,
// Return if the IPR has performed a successful routing test.
pub routable: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct InfoResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: InfoResponseReply,
pub level: InfoLevel,
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum InfoResponseReply {
#[error("{msg}")]
Generic { msg: String },
#[error(
"version mismatch: response is v{request_version} and response is v{response_version}"
)]
VersionMismatch {
request_version: u8,
response_version: u8,
},
#[error("destination failed exit policy filter check: {dst}")]
ExitPolicyFilterCheckFailed { dst: String },
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum InfoLevel {
Info,
Warn,
Error,
}
+3 -3
View File
@@ -7,8 +7,8 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bip32 = "0.5.1"
bip32 = { workspace = true }
k256 = { workspace = true }
ledger-transport = "0.10.0"
ledger-transport-hid = "0.10.0"
ledger-transport = { workspace = true }
ledger-transport-hid = { workspace = true }
thiserror = { workspace = true }
+2 -2
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bytes = "1.0"
bytes = { workspace = true }
futures = { workspace = true }
humantime-serde = { workspace = true }
log = { workspace = true }
@@ -38,4 +38,4 @@ nym-task = { path = "../task" }
nym-validator-client = { path = "../client-libs/validator-client" }
nym-bin-common = { path = "../bin-common" }
nym-metrics = { path = "../nym-metrics" }
nym-node-http-api = { path = "../../nym-node/nym-node-http-api" }
nym-node-http-api = { path = "../../nym-node/nym-node-http-api" }
@@ -242,7 +242,7 @@ impl SphinxPacketProcessor {
#[cfg(test)]
mod tests {
use super::*;
use nym_sphinx_types::test_utils::fixtures::keygen;
use nym_sphinx_types::crypto::keygen;
fn fixture() -> SphinxPacketProcessor {
let local_keys = keygen();
+1 -1
View File
@@ -10,7 +10,7 @@ repository.workspace = true
[dependencies]
cfg-if = { workspace = true }
dotenvy = { workspace = true }
hex-literal = "0.3.3"
hex-literal = { workspace = true }
log = { workspace = true }
once_cell = { workspace = true }
schemars = { workspace = true, features = ["preserve_order"] }
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
[dependencies]
futures = { workspace = true }
rand = { workspace = true }
rand = "0.7.3"
serde = { workspace = true }
serde_json = { workspace = true }
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio-stream = "0.1.11" # this one seems to be a thing until `Stream` trait is stabilised in stdlib
tokio-stream = { workspace = true } # this one seems to be a thing until `Stream` trait is stabilised in stdlib
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
workspace = true
+1 -1
View File
@@ -14,4 +14,4 @@ license.workspace = true
prometheus = { workspace = true }
log = { workspace = true }
dashmap = { workspace = true }
lazy_static = "1.4"
lazy_static = { workspace = true }
+3 -3
View File
@@ -14,7 +14,7 @@ digest = "0.9"
rand = "0.8"
thiserror = { workspace = true }
serde = { workspace = true }
serde_derive = "1.0"
serde_derive = { workspace = true }
bs58 = { workspace = true }
sha2 = "0.9"
zeroize = { workspace = true, optional = true }
@@ -31,8 +31,8 @@ workspace = true
default-features = false
[dev-dependencies]
criterion = { version="0.4", features=["html_reports"] }
doc-comment = "0.3"
criterion = { workspace = true, features = ["html_reports"] }
doc-comment = { workspace = true }
rand_chacha = "0.3"
[[bench]]
+2 -2
View File
@@ -9,8 +9,8 @@ repository = { workspace = true }
[dependencies]
log = { workspace = true }
rand = { workspace = true }
rand_distr = "0.4"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand_distr = { workspace = true }
thiserror = { workspace = true }
nym-sphinx-acknowledgements = { path = "acknowledgements" }
+1 -1
View File
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
rand = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde_crate = { version = "1.0", optional = true, default_features = false, features = ["derive"], package = "serde" }
generic-array = { workspace = true, optional = true, features = ["serde"] }
thiserror = { workspace = true }
+3 -3
View File
@@ -10,9 +10,9 @@ repository = { workspace = true }
[dependencies]
nym-crypto = { path = "../../crypto", features = ["asymmetric"] } # all addresses are expressed in terms on their crypto keys
nym-sphinx-types = { path = "../types", features = ["sphinx"] } # we need to be able to refer to some types defined inside sphinx crate
serde = "1.0" # implementing serialization/deserialization for some types, like `Recipient`
serde = { workspace = true } # implementing serialization/deserialization for some types, like `Recipient`
thiserror = { workspace = true }
[dev-dependencies]
rand = "0.8.5"
nym-crypto = { path = "../../crypto", features = ["rand"] }
rand = "0.7"
nym-crypto = { path = "../../crypto", features = ["rand"] }
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
rand = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
bs58 = { workspace = true }
serde = { workspace = true }
thiserror = { workspace = true }
@@ -24,4 +24,4 @@ nym-topology = { path = "../../topology" }
version = "0.2.83"
[dev-dependencies]
rand_chacha = "0.3"
rand_chacha = "0.2"
@@ -570,7 +570,7 @@ mod tests {
let mut address_bytes = [0; NODE_ADDRESS_LENGTH];
rng.fill_bytes(&mut address_bytes);
let dummy_private = PrivateKey::random_from_rng(rng);
let dummy_private = PrivateKey::new_with_rng(rng);
let pub_key = (&dummy_private).into();
Node {
address: NodeAddressBytes::from_bytes(address_bytes),
+1 -1
View File
@@ -11,7 +11,7 @@ repository = { workspace = true }
[dependencies]
log = { workspace = true }
rand = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
thiserror = { workspace = true }
nym-sphinx-addressing = { path = "../addressing" }
+1 -1
View File
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
rand = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
thiserror = { workspace = true }
nym-crypto = { path = "../../crypto" }
+1 -1
View File
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
bytes = "1.0"
bytes = { workspace = true }
tokio-util = { workspace = true, features = ["codec"] }
thiserror = { workspace = true }
+9 -9
View File
@@ -130,28 +130,28 @@ impl Decoder for NymCodec {
mod packet_encoding {
use super::*;
use nym_sphinx_types::{
test_utils, Delay as SphinxDelay, Destination, DestinationAddressBytes, Node,
NodeAddressBytes, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, NODE_ADDRESS_LENGTH,
crypto, Delay as SphinxDelay, Destination, DestinationAddressBytes, Node, NodeAddressBytes,
DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, NODE_ADDRESS_LENGTH,
};
fn make_valid_outfox_packet(size: PacketSize) -> NymPacket {
let (_, node1_pk) = test_utils::fixtures::keygen();
let (_, node1_pk) = crypto::keygen();
let node1 = Node::new(
NodeAddressBytes::from_bytes([5u8; NODE_ADDRESS_LENGTH]),
node1_pk,
);
let (_, node2_pk) = test_utils::fixtures::keygen();
let (_, node2_pk) = crypto::keygen();
let node2 = Node::new(
NodeAddressBytes::from_bytes([4u8; NODE_ADDRESS_LENGTH]),
node2_pk,
);
let (_, node3_pk) = test_utils::fixtures::keygen();
let (_, node3_pk) = crypto::keygen();
let node3 = Node::new(
NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]),
node3_pk,
);
let (_, node4_pk) = test_utils::fixtures::keygen();
let (_, node4_pk) = crypto::keygen();
let node4 = Node::new(
NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]),
node4_pk,
@@ -170,17 +170,17 @@ mod packet_encoding {
}
fn make_valid_sphinx_packet(size: PacketSize) -> NymPacket {
let (_, node1_pk) = test_utils::fixtures::keygen();
let (_, node1_pk) = crypto::keygen();
let node1 = Node::new(
NodeAddressBytes::from_bytes([5u8; NODE_ADDRESS_LENGTH]),
node1_pk,
);
let (_, node2_pk) = test_utils::fixtures::keygen();
let (_, node2_pk) = crypto::keygen();
let node2 = Node::new(
NodeAddressBytes::from_bytes([4u8; NODE_ADDRESS_LENGTH]),
node2_pk,
);
let (_, node3_pk) = test_utils::fixtures::keygen();
let (_, node3_pk) = crypto::keygen();
let node3 = Node::new(
NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]),
node3_pk,
+1 -1
View File
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
sphinx-packet = { version = "0.2.0", optional = true }
sphinx-packet = { workspace = true, optional = true }
nym-outfox = { path = "../../../nym-outfox", optional = true }
thiserror = { workspace = true }
+2 -2
View File
@@ -15,13 +15,13 @@ pub use sphinx_packet::{
self, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, MAX_PATH_LENGTH, NODE_ADDRESS_LENGTH,
PAYLOAD_KEY_SIZE,
},
crypto::{self, PrivateKey, PublicKey},
crypto::{self, EphemeralSecret, PrivateKey, PublicKey, SharedSecret},
header::{self, delays, delays::Delay, ProcessedHeader, SphinxHeader, HEADER_SIZE},
packet::builder::DEFAULT_PAYLOAD_SIZE,
payload::{Payload, PAYLOAD_OVERHEAD_SIZE},
route::{Destination, DestinationAddressBytes, Node, NodeAddressBytes, SURBIdentifier},
surb::{SURBMaterial, SURB},
test_utils, Error as SphinxError, ProcessedPacket,
Error as SphinxError, ProcessedPacket,
};
#[cfg(feature = "sphinx")]
use sphinx_packet::{SphinxPacket, SphinxPacketBuilder};
+5 -5
View File
@@ -12,11 +12,11 @@ license.workspace = true
[dependencies]
async-trait.workspace = true
const_format = "0.2.32"
const_format = { workspace = true }
cosmrs.workspace = true
eyre = "0.6.9"
eyre = { workspace = true }
futures.workspace = true
humantime = "2.1.0"
humantime = { workspace = true }
sha2 = "0.10.8"
serde = { workspace = true, features = ["derive"] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate", "time"] }
@@ -25,8 +25,8 @@ tendermint-rpc = { workspace = true, features = ["websocket-client", "http-clien
thiserror.workspace = true
time = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tokio-stream = "0.1.14"
tokio-util = { version = "0.7.10", features = ["rt"] }
tokio-stream = { workspace = true }
tokio-util = { workspace = true, features = ["rt"] }
tracing.workspace = true
url.workspace = true
+1 -1
View File
@@ -8,4 +8,4 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
pem = "0.8"
pem = { workspace = true }
+4 -4
View File
@@ -11,14 +11,14 @@ anyhow = { workspace = true }
dirs = "4.0"
futures = { workspace = true }
log = { workspace = true }
pin-project = "1.0"
rand = { workspace = true }
pin-project = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
reqwest = { workspace = true }
schemars = { workspace = true, features = ["preserve_order"] }
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
tap = "1.0.1"
tap = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] }
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] }
url = { workspace = true }
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
+2 -2
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bytes = "1.0"
bytes = { workspace = true }
tokio = { workspace = true, features = [ "net", "io-util", "sync", "macros", "time", "rt-multi-thread" ] }
tokio-util = { workspace = true, features = [ "io" ] } # reason for getting this guy is to to able to port to tokio 1.X more quickly by being able to use
# their `read_buf` [from the util crate] replacement rather than having to rethink/reimplement `AvailableReader` with the new AsyncRead trait definition.
@@ -22,4 +22,4 @@ nym-socks5-requests = { path = "../requests" }
nym-task = { path = "../../task" }
[dev-dependencies]
tokio-test = "0.4.2"
tokio-test = { workspace = true }
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bincode = "1.3.3"
bincode = { workspace = true }
log = { workspace = true }
nym-exit-policy = { path = "../../../common/exit-policy"}
nym-service-providers-common = { path = "../../../service-providers/common" }
+3 -3
View File
@@ -13,8 +13,8 @@ license.workspace = true
async-trait = { workspace = true }
log = { workspace = true }
reqwest = { workspace = true, features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "chrono"]}
thiserror = { workspace = true }
tokio = { version = "1.24.1", features = [ "time" ] }
tokio = { workspace = true, features = ["time"] }
+3 -3
View File
@@ -7,14 +7,14 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aes-gcm = { version = "0.10.1" }
argon2 = { version = "0.5.0" }
aes-gcm = { workspace = true }
argon2 = { workspace = true }
generic-array = { workspace = true, features = ["zeroize"] }
rand = "0.8.5"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, optional = true }
thiserror = { workspace = true }
zeroize = { version = "1.6.0", features = ["zeroize_derive"] }
zeroize = { workspace = true, features = ["zeroize_derive"] }
[target.'cfg(target_env = "wasm32-unknown-unknown")'.dependencies]
getrandom = { version = "0.2", features = ["js"] }
+1 -1
View File
@@ -14,7 +14,7 @@ documentation = { workspace = true }
[dependencies]
bs58 = { workspace = true }
log = { workspace = true }
rand = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
thiserror = { workspace = true }
async-trait = { workspace = true, optional = true }
semver = "0.11"
+1 -1
View File
@@ -13,7 +13,7 @@ license.workspace = true
[dependencies]
thiserror.workspace = true
tokio = { workspace = true, features = ["rt-multi-thread", "net", "io-util", "time", "sync", "macros"] }
etherparse = "0.13.0"
etherparse = { workspace = true }
log.workspace = true
nym-wireguard-types = { path = "../wireguard-types", optional = true }
+6 -6
View File
@@ -9,16 +9,16 @@ license.workspace = true
[dependencies]
base64 = "0.21.4"
eyre = "0.6.5"
hmac = "0.12.1"
eyre = { workspace = true }
hmac = { workspace = true }
itertools = "0.11"
log = { workspace = true }
reqwest = { workspace = true }
schemars = "0.8"
serde = { version = "1.0", features = ["derive"] }
schemars = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = "0.10.8"
strum = { version = "0.25", features = ["derive"] }
strum = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
ts-rs = { workspace = true }
url = { workspace = true }
@@ -34,7 +34,7 @@ nym-config = { path = "../../common/config" }
nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] }
[dev-dependencies]
tempfile = "3.3.0"
tempfile = { workspace = true }
[features]
default = []
+3 -3
View File
@@ -11,7 +11,7 @@ repository = "https://github.com/nymtech/nym"
[dependencies]
async-trait = { workspace = true }
js-sys = { workspace = true }
rand = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde = { workspace = true, features = ["derive"] }
serde-wasm-bindgen = { workspace = true }
thiserror = { workspace = true }
@@ -41,7 +41,7 @@ wasm-storage = { path = "../storage" }
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1", optional = true }
console_error_panic_hook = { workspace = true, optional = true }
[features]
default = ["console_error_panic_hook"]
default = ["console_error_panic_hook"]
-1
View File
@@ -3,7 +3,6 @@
use crate::storage::wasm_client_traits::WasmClientStorageError;
use crate::topology::WasmTopologyError;
use js_sys::Promise;
use nym_client_core::client::base_client::storage::gateways_storage::BadGateway;
use nym_client_core::error::ClientCoreError;
use nym_crypto::asymmetric::identity::Ed25519RecoveryError;
+1 -14
View File
@@ -32,17 +32,4 @@ pub use nym_validator_client::{DirectSigningReqwestRpcNyxdClient, QueryReqwestRp
pub use nym_validator_client::client::IdentityKey;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[cfg(target_arch = "wasm32")]
pub fn set_panic_hook() {
// When the `console_error_panic_hook` feature is enabled, we can call the
// `set_panic_hook` function at least once during initialization, and then
// we will get better error messages if our code ever panics.
//
// For more details see
// https://github.com/rustwasm/console_error_panic_hook#readme
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}
pub use wasm_utils::set_panic_hook;
+1 -1
View File
@@ -14,7 +14,7 @@ js-sys = { workspace = true }
wasm-bindgen = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde-wasm-bindgen = { workspace = true }
indexed_db_futures = { version = " 0.3.0"}
indexed_db_futures = { workspace = true }
thiserror = { workspace = true }
nym-store-cipher = { path = "../../store-cipher", features = ["json"] }
+2 -2
View File
@@ -12,9 +12,9 @@ futures = { workspace = true }
js-sys = { workspace = true }
wasm-bindgen = { workspace = true }
wasm-bindgen-futures = { workspace = true }
getrandom = { workspace = true, features=["js"], optional = true }
getrandom = { workspace = true, features = ["js"], optional = true }
gloo-utils = { workspace = true }
gloo-net = { version = "0.3.1", features = ["websocket"], optional = true }
gloo-net = { workspace = true, features = ["websocket"], optional = true }
#gloo-net = { path = "../../../../gloo/crates/net", features = ["websocket"], optional = true }
# we don't want entire tokio-tungstenite, tungstenite itself is just fine - we just want message and error enums
+1 -1
View File
@@ -21,7 +21,7 @@ macro_rules! wasm_error {
impl From<$struct> for js_sys::Promise {
fn from(value: $struct) -> Self {
Promise::reject(&value.into())
js_sys::Promise::reject(&value.into())
}
}
};
+12
View File
@@ -41,6 +41,18 @@ macro_rules! console_error {
($($t:tt)*) => ($crate::error(&format_args!($($t)*).to_string()))
}
#[wasm_bindgen]
pub fn set_panic_hook() {
// When the `console_error_panic_hook` feature is enabled, we can call the
// `set_panic_hook` function at least once during initialization, and then
// we will get better error messages if our code ever panics.
//
// For more details see
// https://github.com/rustwasm/console_error_panic_hook#readme
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
+2 -2
View File
@@ -22,7 +22,7 @@ nym-crypto = { path = "../crypto", features = ["asymmetric"] }
# feature-specific dependencies:
## verify:
hmac = { version = "0.12.1", optional = true }
hmac = { workspace = true, optional = true }
sha2 = { version = "0.10.8", optional = true }
## openapi:
@@ -32,7 +32,7 @@ serde_json = { workspace = true, optional = true }
x25519-dalek = { version = "2.0.0", features = ["static_secrets"] }
[dev-dependencies]
rand = "0.8.5"
rand = "0.7.3"
nym-crypto = { path = "../crypto", features = ["rand"]}
+1 -1
View File
@@ -16,7 +16,7 @@ base64 = "0.21.3"
# version mismatch with x25519-dalek/curve25519-dalek that is resolved in the
# latest commit. So pick that for now.
x25519-dalek = "2.0.0"
ip_network = "0.4.1"
ip_network = { workspace = true }
log.workspace = true
nym-network-defaults = { path = "../network-defaults" }
nym-task = { path = "../task" }
+348 -284
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -32,7 +32,7 @@ cw-multi-test = { workspace = true }
cw3-flex-multisig = { path = "../multisig/cw3-flex-multisig" }
cw4-group = { path = "../multisig/cw4-group" }
rand_chacha = "0.3"
rand_chacha = "0.2"
[[test]]
name = "coconut-test"
@@ -25,7 +25,7 @@ nym-vesting-contract = { path = "../vesting" }
nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] }
# external dependencies
rand_chacha = "0.3"
rand_chacha = "0.2"
[[test]]
name = "mixnet-vesting-test"
+1 -1
View File
@@ -44,7 +44,7 @@ time = { version = "0.3", features = ["macros"] }
semver = { workspace = true, default-features = false }
[dev-dependencies]
rand_chacha = "0.3"
rand_chacha = "0.2"
nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] }
[build-dependencies]
+1 -1
View File
@@ -33,7 +33,7 @@ cw-multi-test = { workspace = true }
nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] }
nym-sphinx-addressing = { path = "../../common/nymsphinx/addressing" }
rand = "0.8.5"
rand_chacha = "0.3"
rand_chacha = "0.2"
rstest = "0.17.0"
[features]
@@ -31,7 +31,7 @@ vergen = { version = "=7.4.3", default-features = false, features = ["build", "g
anyhow = "1.0.40"
cw-multi-test = { workspace = true }
nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] }
rand_chacha = "0.3"
rand_chacha = "0.2"
rstest = "0.17.0"
[features]
+11 -11
View File
@@ -7,28 +7,28 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = { version = "0.4.31", features = ["serde"] }
chrono = { workspace = true, features = ["serde"] }
clap = { workspace = true, features = ["cargo", "derive"] }
dotenvy = { workspace = true }
humantime-serde = { workspace = true }
isocountry = "0.3.2"
isocountry = { workspace = true }
itertools = "0.10.3"
log = { workspace = true }
maxminddb = "0.23.0"
okapi = { version = "0.7.0", features = ["impl_json_schema"] }
pretty_env_logger = "0.4.0"
maxminddb = { workspace = true }
okapi = { workspace = true, features = ["impl_json_schema"] }
pretty_env_logger = { workspace = true }
rand = "0.8.5"
rand_pcg = "0.3.1"
rand_seeder = "0.2.3"
rand_pcg = { workspace = true }
rand_seeder = { workspace = true }
reqwest = { workspace = true }
rocket = { version = "0.5.0", features = ["json"] }
rocket_cors = { version = "0.6.0" }
rocket_okapi = { version = "0.8.0", features = ["swagger"] }
rocket = { workspace = true, features = ["json"] }
rocket_cors = { workspace = true }
rocket_okapi = { workspace = true, features = ["swagger"] }
schemars = { workspace = true, features = ["preserve_order"] }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tokio = {version = "1.21.2", features = ["full"] }
tokio = { workspace = true, features = ["full"] }
nym-bin-common = { path = "../common/bin-common"}
nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" }
@@ -9,5 +9,5 @@ nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts
nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" }
nym-api-requests = { path = "../../nym-api/nym-api-requests" }
schemars = { workspace = true, features = ["preserve_order"] }
serde = { version = "1.0", features = ["derive"] }
serde = { workspace = true, features = ["derive"] }
ts-rs = { workspace = true, optional = true }
+6 -6
View File
@@ -21,7 +21,7 @@ async-trait = { workspace = true }
bip39 = { workspace = true }
bs58 = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
colored = "2.0"
colored = { workspace = true }
dashmap = { workspace = true }
dirs = "4.0"
dotenvy = { workspace = true }
@@ -29,8 +29,8 @@ futures = { workspace = true }
humantime-serde = { workspace = true }
ipnetwork = "0.16"
log = { workspace = true }
once_cell = "1.7.2"
rand = { workspace = true }
once_cell = { workspace = true }
rand = "0.7"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sqlx = { workspace = true, features = [
@@ -40,7 +40,7 @@ sqlx = { workspace = true, features = [
"migrate",
"time"
] }
subtle-encoding = { version = "0.5", features = ["bech32-preview"] }
subtle-encoding = { workspace = true, features = ["bech32-preview"] }
thiserror = { workspace = true }
tokio = { workspace = true, features = [
"rt-multi-thread",
@@ -49,7 +49,7 @@ tokio = { workspace = true, features = [
"fs",
"time",
] }
tokio-stream = { version = "0.1.11", features = ["fs"] }
tokio-stream = { workspace = true, features = ["fs"] }
tokio-tungstenite = { workspace = true }
tokio-util = { workspace = true, features = ["codec"] }
url = { workspace = true, features = ["serde"] }
@@ -81,7 +81,7 @@ nym-ip-packet-router = { path = "../service-providers/ip-packet-router" }
nym-wireguard = { path = "../common/wireguard", optional = true }
nym-wireguard-types = { path = "../common/wireguard-types", default-features = false }
defguard_wireguard_rs = { git = "https://github.com/neacsu/wireguard-rs.git", rev = "c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed", optional = true }
defguard_wireguard_rs = { workspace = true, optional = true }
[build-dependencies]
+1 -1
View File
@@ -15,7 +15,7 @@ bs58 = { workspace = true }
futures = { workspace = true }
generic-array = { workspace = true, features = ["serde"] }
log = { workspace = true }
rand = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
@@ -82,10 +82,8 @@ impl SharedKeys {
)
}
};
let mac = compute_keyed_hmac::<GatewayIntegrityHmacAlgorithm>(
self.mac_key().as_slice(),
&encrypted_data,
);
let mac =
compute_keyed_hmac::<GatewayIntegrityHmacAlgorithm>(self.mac_key(), &encrypted_data);
mac.into_bytes().into_iter().chain(encrypted_data).collect()
}
@@ -104,7 +102,7 @@ impl SharedKeys {
let message_bytes = &enc_data[mac_size..];
if !recompute_keyed_hmac_and_verify_tag::<GatewayIntegrityHmacAlgorithm>(
self.mac_key().as_slice(),
self.mac_key(),
message_bytes,
mac_tag,
) {
+1 -1
View File
@@ -421,7 +421,7 @@ impl BinaryResponse {
let message_bytes = &raw_req[mac_size..];
if !recompute_keyed_hmac_and_verify_tag::<GatewayIntegrityHmacAlgorithm>(
shared_keys.mac_key().as_slice(),
shared_keys.mac_key(),
message_bytes,
mac_tag,
) {
+4 -4
View File
@@ -6,11 +6,11 @@ rust-version = "1.56"
license.workspace = true
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
k256 = { workspace = true, features = ["ecdsa", "sha256"] }
eyre = "0.6.5"
eyre = { workspace = true }
cosmrs = { workspace = true }
@@ -18,4 +18,4 @@ nym-cli-commands = { path = "../../common/commands" }
nym-validator-client = { path = "../../common/client-libs/validator-client" }
[dev-dependencies]
anyhow = "1"
anyhow = { workspace = true }
+4 -4
View File
@@ -21,14 +21,14 @@ axum = { workspace = true }
anyhow = { workspace = true }
bs58 = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
colored = "2.0"
cupid = "0.6.1"
colored = { workspace = true }
cupid = { workspace = true }
dirs = "4.0"
futures = { workspace = true }
humantime-serde = { workspace = true }
lazy_static = "1.4"
lazy_static = { workspace = true }
log = { workspace = true }
rand = { workspace = true }
rand = "0.7.3"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sysinfo = "0.27.7"
+9 -9
View File
@@ -141,8 +141,8 @@ mod tests {
use nym_sphinx_params::packet_sizes::PacketSize;
use nym_sphinx_params::PacketType;
use nym_sphinx_types::{
test_utils, Delay as SphinxDelay, Destination, DestinationAddressBytes, Node,
NodeAddressBytes, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, NODE_ADDRESS_LENGTH,
crypto, Delay as SphinxDelay, Destination, DestinationAddressBytes, Node, NodeAddressBytes,
DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, NODE_ADDRESS_LENGTH,
};
#[derive(Default)]
@@ -166,17 +166,17 @@ mod tests {
}
fn make_valid_sphinx_packet(size: PacketSize) -> NymPacket {
let (_, node1_pk) = test_utils::fixtures::keygen();
let (_, node1_pk) = crypto::keygen();
let node1 = Node::new(
NodeAddressBytes::from_bytes([5u8; NODE_ADDRESS_LENGTH]),
node1_pk,
);
let (_, node2_pk) = test_utils::fixtures::keygen();
let (_, node2_pk) = crypto::keygen();
let node2 = Node::new(
NodeAddressBytes::from_bytes([4u8; NODE_ADDRESS_LENGTH]),
node2_pk,
);
let (_, node3_pk) = test_utils::fixtures::keygen();
let (_, node3_pk) = crypto::keygen();
let node3 = Node::new(
NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]),
node3_pk,
@@ -197,23 +197,23 @@ mod tests {
}
fn make_valid_outfox_packet(size: PacketSize) -> NymPacket {
let (_, node1_pk) = test_utils::fixtures::keygen();
let (_, node1_pk) = crypto::keygen();
let node1 = Node::new(
NodeAddressBytes::from_bytes([5u8; NODE_ADDRESS_LENGTH]),
node1_pk,
);
let (_, node2_pk) = test_utils::fixtures::keygen();
let (_, node2_pk) = crypto::keygen();
let node2 = Node::new(
NodeAddressBytes::from_bytes([4u8; NODE_ADDRESS_LENGTH]),
node2_pk,
);
let (_, node3_pk) = test_utils::fixtures::keygen();
let (_, node3_pk) = crypto::keygen();
let node3 = Node::new(
NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]),
node3_pk,
);
let (_, node4_pk) = test_utils::fixtures::keygen();
let (_, node4_pk) = crypto::keygen();
let node4 = Node::new(
NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]),
node4_pk,
+18 -21
View File
@@ -11,7 +11,7 @@ authors = [
"Drazen Urch <durch@users.noreply.github.com>",
]
edition = "2021"
rust-version = "1.70.0"
rust-version = "1.76.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -19,38 +19,34 @@ rust-version = "1.70.0"
async-trait = { workspace = true }
bs58 = { workspace = true }
bip39 = { workspace = true }
cfg-if = "1.0"
cfg-if = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
console-subscriber = { version = "0.1.1", optional = true } # validator-api needs to be built with RUSTFLAGS="--cfg tokio_unstable"
console-subscriber = { workspace = true, optional = true } # validator-api needs to be built with RUSTFLAGS="--cfg tokio_unstable"
dirs = "4.0"
futures = { workspace = true }
itertools = "0.12.0"
humantime-serde = { workspace = true }
k256 = { version = "*", features = ["ecdsa-core"] } # needed for the Verifier trait; pull whatever version is used by other dependencies
k256 = { workspace = true, features = ["ecdsa-core"] } # needed for the Verifier trait; pull whatever version is used by other dependencies
log = { workspace = true }
pin-project = "1.0"
rand = { workspace = true }
pin-project = { workspace = true }
rand = "0.8.5"
rand-07 = { package = "rand", version = "0.7.3" } # required for compatibility
reqwest = { workspace = true, features = ["json"] }
rocket = { version = "0.5.0", features = ["json"] }
rocket_cors = { version = "0.6.0" }
rocket = { workspace = true, features = ["json"] }
rocket_cors = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tap = "1.0"
tap = { workspace = true }
thiserror = { workspace = true }
time = { workspace = true, features = ["serde-human-readable", "parsing"] }
tokio = { version = "1.24.1", features = [
"rt-multi-thread",
"macros",
"signal",
"time",
] }
tokio-stream = "0.1.11"
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal", "time"] }
tokio-stream = { workspace = true }
url = { workspace = true }
ts-rs = { workspace = true, optional = true}
ts-rs = { workspace = true, optional = true }
anyhow = { workspace = true }
getset = "0.1.1"
getset = { workspace = true }
sqlx = { workspace = true, features = [
"runtime-tokio-rustls",
@@ -59,8 +55,8 @@ sqlx = { workspace = true, features = [
"migrate",
] }
okapi = { version = "0.7.0", features = ["impl_json_schema"] }
rocket_okapi = { version = "0.8.0", features = ["swagger"] }
okapi = { workspace = true, features = ["impl_json_schema"] }
rocket_okapi = { workspace = true, features = ["swagger"] }
schemars = { workspace = true, features = ["preserve_order"] }
zeroize = { workspace = true }
@@ -120,9 +116,10 @@ sqlx = { workspace = true, features = [
] }
[dev-dependencies]
tempfile = "3.3.0"
tempfile = { workspace = true }
cw3 = { workspace = true }
cw-utils = { workspace = true }
rand_chacha = "0.3"
rand_chacha_02 = { package = "rand_chacha", version = "0.2" }
sha2 = "0.9"
+2 -2
View File
@@ -10,7 +10,7 @@ license.workspace = true
bs58 = { workspace = true }
cosmrs = { workspace = true }
cosmwasm-std = { workspace = true }
getset = "0.1.1"
getset = { workspace = true }
schemars = { workspace = true, features = ["preserve_order"] }
serde = { workspace = true, features = ["derive"] }
ts-rs = { workspace = true, optional = true }
@@ -19,7 +19,7 @@ time = { workspace = true, features = ["serde", "parsing", "formatting"] }
# for serde on secp256k1 signatures
ecdsa = { version = "0.16", features = ["serde"] }
ecdsa = { workspace = true, features = ["serde"] }
nym-credentials-interface = { path = "../../common/credentials-interface" }
nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"] }
+1
View File
@@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
pub mod coconut;
pub mod models;
pub mod pagination;
pub trait Deprecatable {
fn deprecate(self) -> Deprecated<Self>
+31 -1
View File
@@ -1,6 +1,7 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::pagination::PaginatedResponse;
use cosmwasm_std::{Addr, Coin, Decimal};
use nym_mixnet_contract_common::families::FamilyHead;
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
@@ -9,7 +10,7 @@ use nym_mixnet_contract_common::rewarding::RewardEstimate;
use nym_mixnet_contract_common::{
GatewayBond, IdentityKey, Interval, MixId, MixNode, Percent, RewardedSetNodeStatus,
};
use nym_node_requests::api::v1::node::models::BinaryBuildInformationOwned;
use nym_node_requests::api::v1::node::models::{AuxiliaryDetails, BinaryBuildInformationOwned};
use schemars::gen::SchemaGenerator;
use schemars::schema::{InstanceType, Schema, SchemaObject};
use schemars::JsonSchema;
@@ -482,6 +483,7 @@ impl JsonSchema for OffsetDateTimeJsonSchemaWrapper {
}
}
// this struct is getting quite bloated...
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)]
pub struct NymNodeDescription {
#[serde(default)]
@@ -489,6 +491,9 @@ pub struct NymNodeDescription {
pub host_information: HostInformation,
#[serde(default)]
pub auxiliary_details: AuxiliaryDetails,
// TODO: do we really care about ALL build info or just the version?
pub build_information: BinaryBuildInformationOwned,
@@ -569,3 +574,28 @@ pub struct SignerInformationResponse {
pub verification_key: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, Default)]
pub struct TestNode {
pub node_id: Option<u32>,
pub identity_key: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)]
pub struct TestRoute {
pub gateway: TestNode,
pub layer1: TestNode,
pub layer2: TestNode,
pub layer3: TestNode,
}
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)]
pub struct PartialTestResult {
pub monitor_run_id: i64,
pub timestamp: i64,
pub overall_reliability_for_all_routes_in_monitor_run: Option<u8>,
pub test_routes: TestRoute,
}
pub type MixnodeTestResultResponse = PaginatedResponse<PartialTestResult>;
pub type GatewayTestResultResponse = PaginatedResponse<PartialTestResult>;
@@ -0,0 +1,18 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, JsonSchema)]
pub struct Pagination {
pub total: usize,
pub page: u32,
pub size: usize,
}
#[derive(Serialize, Deserialize, JsonSchema)]
pub struct PaginatedResponse<T> {
pub pagination: Pagination,
pub data: Vec<T>,
}
+42 -22
View File
@@ -1,12 +1,15 @@
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::coconut::api_routes::helpers::build_credentials_response;
use crate::coconut::error::{CoconutError, Result};
use crate::coconut::helpers::{accepted_vote_err, blind_sign};
use crate::coconut::state::State;
use crate::coconut::storage::CoconutStorageExt;
use std::ops::Deref;
use k256::ecdsa::signature::Verifier;
use rand::rngs::OsRng;
use rand::RngCore;
use rocket::serde::json::Json;
use rocket::State as RocketState;
use time::OffsetDateTime;
use nym_api_requests::coconut::models::{
CredentialsRequestBody, EpochCredentialsResponse, FreePassNonceResponse, FreePassRequest,
IssuedCredentialResponse, IssuedCredentialsResponse,
@@ -23,12 +26,12 @@ use nym_credentials::coconut::bandwidth::{
bandwidth_credential_params, CredentialType, IssuanceBandwidthCredential,
};
use nym_validator_client::nyxd::Coin;
use rand::rngs::OsRng;
use rand::RngCore;
use rocket::serde::json::Json;
use rocket::State as RocketState;
use std::ops::Deref;
use time::OffsetDateTime;
use crate::coconut::api_routes::helpers::build_credentials_response;
use crate::coconut::error::{CoconutError, Result};
use crate::coconut::helpers::{accepted_vote_err, blind_sign};
use crate::coconut::state::State;
use crate::coconut::storage::CoconutStorageExt;
mod helpers;
@@ -98,17 +101,30 @@ pub async fn post_free_pass(
validate_freepass_public_attributes(&freepass_request_body)?;
// grab the admin of the bandwidth contract
let Some(authorised_admin) = state.get_bandwidth_contract_admin().await? else {
error!("our bandwidth contract does not have an admin set! We won't be able to migrate the contract! We should redeploy it ASAP");
return Err(CoconutError::MissingBandwidthContractAdmin);
// check for explicit admin
let explicit_admin = state.get_authorised_freepass_requester().await;
// otherwise fallback to bandwidth contract admin
let bandwidth_contract_admin = state
.get_bandwidth_contract_admin()
.await
.cloned()
.inspect_err(|_| error!("our bandwidth contract does not have an admin set! We won't be able to migrate the contract! We should redeploy it ASAP"))
.ok()
.flatten();
// extract account prefix
let prefix = match (&explicit_admin, &bandwidth_contract_admin) {
(None, None) => {
error!("neither explicit admin nor bandwidth contract admin has been set!");
return Err(CoconutError::MissingBandwidthContractAddress);
}
(Some(addr), _) => addr.prefix(),
(None, Some(addr)) => addr.prefix(),
};
// derive the address out of the provided pubkey
let requester = match freepass_request_body
.cosmos_pubkey
.account_id(authorised_admin.prefix())
{
let requester = match freepass_request_body.cosmos_pubkey.account_id(prefix) {
Ok(address) => address,
Err(err) => {
return Err(CoconutError::AdminAccountDerivationFailure {
@@ -116,12 +132,16 @@ pub async fn post_free_pass(
})
}
};
debug!("derived the following address out of the provided public key: {requester}. Going to check it against the authorised admin ({authorised_admin})");
debug!("derived the following address out of the provided public key: {requester}. Going to check it against the authorised admin ({explicit_admin:?}) and fallback to bandwidth contract admin: {bandwidth_contract_admin:?}");
if &requester != authorised_admin {
// check if request matches any address
if Some(&requester) != explicit_admin.as_ref()
&& Some(&requester) != bandwidth_contract_admin.as_ref()
{
return Err(CoconutError::UnauthorisedFreePassAccount {
requester,
authorised_admin: authorised_admin.clone(),
explicit_admin,
bandwidth_contract_admin,
});
}
+12 -2
View File
@@ -37,10 +37,20 @@ pub enum CoconutError {
#[error("failed to derive the admin account from the provided public key: {formatted_source}")]
AdminAccountDerivationFailure { formatted_source: String },
#[error("the requester of the free pass ({requester}) is not authorised. the only allowed account is {authorised_admin}.")]
#[error("failed to query for the authorised freepass requester address: {source}")]
FreepassAuthorisedFreepassRequesterQueryFailure {
#[from]
source: reqwest::Error,
},
#[error("the provided authorised freepass requester address ({address}) is not a valid cosmos address")]
MalformedAuthorisedFreepassRequesterAddress { address: String },
#[error("the requester of the free pass ({requester}) is not authorised. the only allowed account is {explicit_admin:?} or {bandwidth_contract_admin:?}.")]
UnauthorisedFreePassAccount {
requester: AccountId,
authorised_admin: AccountId,
explicit_admin: Option<AccountId>,
bandwidth_contract_admin: Option<AccountId>,
},
#[error("failed to verify signature on the provided free pass request")]
+74 -1
View File
@@ -4,7 +4,7 @@
use crate::coconut::client::Client as LocalClient;
use crate::coconut::comm::APICommunicationChannel;
use crate::coconut::deposit::validate_deposit_tx;
use crate::coconut::error::Result;
use crate::coconut::error::{CoconutError, Result};
use crate::coconut::keys::KeyPair;
use crate::coconut::storage::CoconutStorageExt;
use crate::support::storage::NymApiStorage;
@@ -17,6 +17,7 @@ use nym_validator_client::nyxd::{AccountId, Hash, TxResponse};
use rand::rngs::OsRng;
use rand::RngCore;
use std::sync::Arc;
use time::{Duration, OffsetDateTime};
use tokio::sync::{OnceCell, RwLock};
pub use nym_credentials::coconut::bandwidth::bandwidth_credential_params;
@@ -30,6 +31,25 @@ pub struct State {
pub(crate) comm_channel: Arc<dyn APICommunicationChannel + Send + Sync>,
pub(crate) storage: NymApiStorage,
pub(crate) freepass_nonce: Arc<RwLock<[u8; 16]>>,
pub(crate) authorised_freepass_requester: Arc<RwLock<AuthorisedFreepassRequester>>,
}
const FREEPASS_REQUESTER_TTL: Duration = Duration::hours(1);
const AUTHORISED_FREEPASS_REQUESTER_ENDPOINT: &str =
"https://nymtech.net/.wellknown/authorised-freepass-requester.txt";
pub struct AuthorisedFreepassRequester {
address: Option<AccountId>,
refreshed_at: OffsetDateTime,
}
impl Default for AuthorisedFreepassRequester {
fn default() -> Self {
AuthorisedFreepassRequester {
address: None,
refreshed_at: OffsetDateTime::UNIX_EPOCH,
}
}
}
impl State {
@@ -60,6 +80,7 @@ impl State {
comm_channel,
storage,
freepass_nonce: Arc::new(RwLock::new(nonce)),
authorised_freepass_requester: Arc::new(Default::default()),
}
}
@@ -83,6 +104,58 @@ impl State {
.await
}
async fn try_get_authorised_freepass_requester(&self) -> Result<AccountId> {
let address = reqwest::Client::builder()
.user_agent(format!(
"nym-api / {} identity: {}",
env!("CARGO_PKG_VERSION"),
self.identity_keypair.public_key().to_base58_string()
))
.build()?
.get(AUTHORISED_FREEPASS_REQUESTER_ENDPOINT)
.send()
.await?
.text()
.await?;
let trimmed = address.trim();
address.parse().map_err(
|_| CoconutError::MalformedAuthorisedFreepassRequesterAddress {
address: trimmed.to_string(),
},
)
}
pub async fn get_authorised_freepass_requester(&self) -> Option<AccountId> {
{
let cached = self.authorised_freepass_requester.read().await;
// the entry hasn't expired
if cached.refreshed_at + FREEPASS_REQUESTER_TTL >= OffsetDateTime::now_utc() {
if let Some(cached_address) = cached.address.as_ref() {
return Some(cached_address.clone());
}
}
}
// refresh cache
let mut cache = self.authorised_freepass_requester.write().await;
// whatever happens, update refresh time
cache.refreshed_at = OffsetDateTime::now_utc();
let refreshed = match self.try_get_authorised_freepass_requester().await {
Ok(upstream) => upstream,
Err(err) => {
warn!("failed to obtain authorised freepass requester address: {err}");
return None;
}
};
cache.address = Some(refreshed.clone());
Some(refreshed)
}
pub async fn validate_request(
&self,
request: &BlindSignRequestBody,
+12 -2
View File
@@ -27,6 +27,11 @@ pub fn test_rng(seed: [u8; 32]) -> ChaCha20Rng {
ChaCha20Rng::from_seed(seed)
}
pub fn test_rng_07(seed: [u8; 32]) -> rand_chacha_02::ChaCha20Rng {
use rand_chacha_02::rand_core::SeedableRng;
rand_chacha_02::ChaCha20Rng::from_seed(seed)
}
pub fn pseudorandom_account(rng: &mut ChaCha20Rng) -> AccountId {
let mut dummy_account_key_hash = [0u8; 32];
rng.fill_bytes(&mut dummy_account_key_hash);
@@ -37,8 +42,13 @@ pub fn dealer_fixture(mut rng: &mut ChaCha20Rng, id: NodeIndex) -> DealerDetails
// we might possibly need that private key later on
let keypair = DkgKeyPair::new(dkg::params(), &mut rng);
// lol, instantiate rng with an rng due to incompatibility, but even though it looks dodgy AF,
// it's 100% deterministic
let mut secondary_seed = [0u8; 32];
rng.fill_bytes(&mut secondary_seed);
let addr = pseudorandom_account(rng);
let identity_keypair = identity::KeyPair::new(&mut rng);
let identity_keypair = identity::KeyPair::new(&mut test_rng_07(secondary_seed));
let bte_public_key_with_proof = bs58::encode(&keypair.public_key().to_bytes()).into_string();
let port = 8080 + id;
@@ -146,7 +156,7 @@ impl TestingDkgControllerBuilder {
let mut secondary_seed = [0u8; 32];
rng.fill_bytes(&mut secondary_seed);
let identity_keypair = identity::KeyPair::new(&mut test_rng(secondary_seed));
let identity_keypair = identity::KeyPair::new(&mut test_rng_07(secondary_seed));
DealerDetails {
address: Addr::unchecked(address.as_ref()),

Some files were not shown because too many files have changed in this diff Show More