Merge branch 'develop' into update/bond-form-state-management

Merge develop branch
This commit is contained in:
fmtabbara
2021-08-05 09:14:40 +01:00
21 changed files with 1373 additions and 1567 deletions
+18 -24
View File
@@ -21,52 +21,46 @@ jobs:
override: true
components: rustfmt, clippy
# main repo
# Exclude validator API on Windows
- uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: build
args: --all --exclude nym-validator-api
- uses: actions-rs/cargo@v1
if: ${{ matrix.os != 'windows-latest' }}
with:
command: build
args: --all
# validator API
# Exclude validator API on Windows
- uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: build
args: --manifest-path validator-api/Cargo.toml
command: test
args: --all --exclude nym-validator-api
# main repo
- uses: actions-rs/cargo@v1
if: ${{ matrix.os != 'windows-latest' }}
with:
command: test
args: --all
# validator API
- uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path validator-api/Cargo.toml
# main repo
- uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
# validator API
# Exclude validator API on Windows
- uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' && matrix.os == 'windows-latest' }}
with:
command: fmt
args: --manifest-path validator-api/Cargo.toml -- --check
command: clippy
args: --all --exclude nym-validator-api -- -D warnings
# main repo
- uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
if: ${{ matrix.rust != 'nightly' && matrix.os != 'windows-latest' }}
with:
command: clippy
args: -- -D warnings
# validator API
- uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --manifest-path validator-api/Cargo.toml -- -D warnings
Generated
+630 -15
View File
@@ -70,6 +70,17 @@ dependencies = [
"opaque-debug 0.3.0",
]
[[package]]
name = "ahash"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
dependencies = [
"getrandom 0.2.3",
"once_cell",
"version_check",
]
[[package]]
name = "aho-corasick"
version = "0.7.18"
@@ -88,6 +99,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
[[package]]
name = "arrayref"
version = "0.3.6"
@@ -132,6 +149,15 @@ dependencies = [
"syn",
]
[[package]]
name = "atoi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5"
dependencies = [
"num-traits",
]
[[package]]
name = "atomic"
version = "0.5.0"
@@ -189,7 +215,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98fcd36dda4e17b7d7abc64cb549bf0201f4ab71e00700c798ca7e62ed3761fa"
dependencies = [
"funty",
"radium",
"radium 0.3.0",
"wyz",
]
[[package]]
name = "bitvec"
version = "0.19.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321"
dependencies = [
"funty",
"radium 0.5.3",
"tap",
"wyz",
]
@@ -271,6 +309,12 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
[[package]]
name = "build_const"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7"
[[package]]
name = "bumpalo"
version = "3.7.0"
@@ -323,6 +367,20 @@ dependencies = [
"keystream",
]
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"serde",
"time 0.1.44",
"winapi",
]
[[package]]
name = "cipher"
version = "0.2.5"
@@ -341,7 +399,7 @@ dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"strsim 0.8.0",
"textwrap",
"unicode-width",
"vec_map",
@@ -433,7 +491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffdf8865bac3d9a3bde5bde9088ca431b11f5d37c7a578b8086af77248b76627"
dependencies = [
"percent-encoding",
"time",
"time 0.2.27",
"version_check",
]
@@ -500,6 +558,15 @@ dependencies = [
"libc",
]
[[package]]
name = "crc"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
dependencies = [
"build_const",
]
[[package]]
name = "crc32fast"
version = "1.2.1"
@@ -509,6 +576,16 @@ dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.5"
@@ -522,6 +599,16 @@ dependencies = [
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
@@ -620,6 +707,41 @@ dependencies = [
"zeroize",
]
[[package]]
name = "darling"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "757c0ded2af11d8e739c4daea1ac623dd1624b06c844cf3f5a39f1bdbd99bb12"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c34d8efb62d0c2d7f60ece80f75e5c63c1588ba68032740494b0b9a996466e3"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim 0.10.0",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade7bff147130fe5e6d39f089c6bd49ec0250f35d70b2eebf72afdfc919f15cc"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "dashmap"
version = "4.0.2"
@@ -806,7 +928,7 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2db227e61a43a34915680bdda462ec0e212095518020a88a1f91acd16092c39"
dependencies = [
"bitvec",
"bitvec 0.18.5",
"digest 0.9.0",
"ff",
"funty",
@@ -840,6 +962,26 @@ dependencies = [
"termcolor",
]
[[package]]
name = "explorer-api"
version = "0.1.0"
dependencies = [
"chrono",
"isocountry",
"log",
"mixnet-contract",
"okapi",
"pretty_env_logger",
"reqwest",
"rocket",
"rocket_okapi",
"schemars",
"serde",
"serde_json",
"tokio",
"validator-client",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
@@ -852,7 +994,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef"
dependencies = [
"bitvec",
"bitvec 0.18.5",
"rand_core 0.5.1",
"subtle 2.4.0",
]
@@ -1111,7 +1253,7 @@ dependencies = [
"cfg-if 1.0.0",
"js-sys",
"libc",
"wasi 0.10.2+wasi-snapshot-preview1",
"wasi 0.10.0+wasi-snapshot-preview1",
"wasm-bindgen",
]
@@ -1170,6 +1312,27 @@ name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
"ahash",
]
[[package]]
name = "hashlink"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf"
dependencies = [
"hashbrown",
]
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
@@ -1332,6 +1495,12 @@ dependencies = [
"tokio-native-tls",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.2.3"
@@ -1393,6 +1562,16 @@ dependencies = [
"serde",
]
[[package]]
name = "isocountry"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ea1dc4bf0fb4904ba83ffdb98af3d9c325274e92e6e295e4151e86c96363e04"
dependencies = [
"serde",
"thiserror",
]
[[package]]
name = "itoa"
version = "0.4.7"
@@ -1432,6 +1611,19 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lexical-core"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if 1.0.0",
"ryu",
"static_assertions",
]
[[package]]
name = "libc"
version = "0.2.97"
@@ -1444,6 +1636,17 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]]
name = "libsqlite3-sys"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290b64917f8b0cb885d9de0f9959fe1f775d7fa12f1da2db9001c1c8ab60f89d"
dependencies = [
"cc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "lioness"
version = "0.1.2"
@@ -1608,7 +1811,7 @@ dependencies = [
"httparse",
"log",
"mime",
"spin",
"spin 0.9.1",
"tokio",
"tokio-util",
"twoway",
@@ -1633,6 +1836,19 @@ dependencies = [
"tempfile",
]
[[package]]
name = "nom"
version = "6.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
dependencies = [
"bitvec 0.19.5",
"funty",
"lexical-core",
"memchr",
"version_check",
]
[[package]]
name = "nonexhaustive-delayqueue"
version = "0.1.0"
@@ -1651,6 +1867,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
@@ -1835,6 +2061,39 @@ dependencies = [
"version-checker",
]
[[package]]
name = "nym-validator-api"
version = "0.11.0"
dependencies = [
"anyhow",
"clap",
"config",
"crypto",
"dirs",
"dotenv",
"futures",
"gateway-client",
"gateway-requests",
"humantime-serde",
"log",
"mixnet-contract",
"nymsphinx",
"pin-project",
"pretty_env_logger",
"rand 0.7.3",
"reqwest",
"rocket",
"rocket_cors",
"rocket_sync_db_pools",
"serde",
"serde_json",
"sqlx",
"tokio",
"topology",
"validator-client",
"version-checker",
]
[[package]]
name = "nymsphinx"
version = "0.1.0"
@@ -1953,6 +2212,17 @@ dependencies = [
"sphinx",
]
[[package]]
name = "okapi"
version = "0.6.0-alpha-1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb085e00daf8d75b9dbf0ffdb4738e69503e28898d9641fa8bdc6ad536c7bcf4"
dependencies = [
"schemars",
"serde",
"serde_json",
]
[[package]]
name = "once_cell"
version = "1.8.0"
@@ -2269,12 +2539,29 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r2d2"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f"
dependencies = [
"log",
"parking_lot",
"scheduled-thread-pool",
]
[[package]]
name = "radium"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac"
[[package]]
name = "radium"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
[[package]]
name = "rand"
version = "0.7.3"
@@ -2475,6 +2762,21 @@ dependencies = [
"winreg",
]
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin 0.5.2",
"untrusted",
"web-sys",
"winapi",
]
[[package]]
name = "rocket"
version = "0.5.0-rc.1"
@@ -2505,7 +2807,7 @@ dependencies = [
"serde_json",
"state",
"tempfile",
"time",
"time 0.2.27",
"tokio",
"tokio-stream",
"tokio-util",
@@ -2530,6 +2832,21 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "rocket_cors"
version = "0.5.2"
source = "git+https://github.com/lawliet89/rocket_cors?rev=dfd3662c49e2f6fc37df35091cb94d82f7fb5915#dfd3662c49e2f6fc37df35091cb94d82f7fb5915"
dependencies = [
"log",
"regex",
"rocket",
"serde",
"serde_derive",
"unicase",
"unicase_serde",
"url",
]
[[package]]
name = "rocket_http"
version = "0.5.0-rc.1"
@@ -2553,11 +2870,61 @@ dependencies = [
"smallvec",
"stable-pattern",
"state",
"time",
"time 0.2.27",
"tokio",
"uncased",
]
[[package]]
name = "rocket_okapi"
version = "0.7.0-alpha-1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b2f4f48fb070f9f6c56d5663df5fa8a514406207744f4abd84661bfb24efd7d"
dependencies = [
"okapi",
"rocket",
"rocket_okapi_codegen",
"schemars",
"serde",
"serde_json",
]
[[package]]
name = "rocket_okapi_codegen"
version = "0.7.0-alpha-1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ccf1550e1c806461a6b08e2ab64eb10701d41bf50bde59ab9aa3a57ab14d41"
dependencies = [
"darling",
"proc-macro2",
"quote",
"rocket_http",
"syn",
]
[[package]]
name = "rocket_sync_db_pools"
version = "0.1.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38cfdfebd552d075c368e641c88a5cd6ce1c58c5c710548aeb777abb48830f4b"
dependencies = [
"r2d2",
"rocket",
"rocket_sync_db_pools_codegen",
"serde",
"tokio",
]
[[package]]
name = "rocket_sync_db_pools_codegen"
version = "0.1.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267808c094db5366e1d8925aaf9f2ce05ff9b3bd92cb18c7040a1fe219c2e25"
dependencies = [
"devise",
"quote",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
@@ -2567,6 +2934,19 @@ dependencies = [
"semver 0.9.0",
]
[[package]]
name = "rustls"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
dependencies = [
"base64",
"log",
"ring",
"sct",
"webpki",
]
[[package]]
name = "rustversion"
version = "1.0.5"
@@ -2589,6 +2969,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "scheduled-thread-pool"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7"
dependencies = [
"parking_lot",
]
[[package]]
name = "schemars"
version = "0.8.3"
@@ -2596,6 +2985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc6ab463ae35acccb5cba66c0084c985257b797d288b6050cc2f6ac1b266cb78"
dependencies = [
"dyn-clone",
"indexmap",
"schemars_derive",
"serde",
"serde_json",
@@ -2625,6 +3015,16 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sct"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "security-framework"
version = "2.3.1"
@@ -2723,9 +3123,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.64"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
dependencies = [
"itoa",
"ryu",
@@ -2940,12 +3340,116 @@ dependencies = [
"sha2 0.8.2",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5fdd7196b4ae35a111c6dc97f9cc152ca3ea8ad744f7cb46a9f27b3ef8f2f54"
[[package]]
name = "sqlformat"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d86e3c77ff882a828346ba401a7ef4b8e440df804491c6064fe8295765de71c"
dependencies = [
"lazy_static",
"maplit",
"nom",
"regex",
"unicode_categories",
]
[[package]]
name = "sqlx"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba82f79b31f30acebf19905bcd8b978f46891b9d0723f578447361a8910b6584"
dependencies = [
"sqlx-core",
"sqlx-macros",
]
[[package]]
name = "sqlx-core"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f23af36748ec8ea8d49ef8499839907be41b0b1178a4e82b8cb45d29f531dc9"
dependencies = [
"ahash",
"atoi",
"bitflags",
"byteorder",
"bytes",
"crc",
"crossbeam-channel",
"crossbeam-queue",
"crossbeam-utils",
"either",
"futures-channel",
"futures-core",
"futures-util",
"hashlink",
"hex",
"itoa",
"libc",
"libsqlite3-sys",
"log",
"memchr",
"once_cell",
"parking_lot",
"percent-encoding",
"rustls",
"sha2 0.9.5",
"smallvec",
"sqlformat",
"sqlx-rt",
"stringprep",
"thiserror",
"time 0.2.27",
"tokio-stream",
"url",
"webpki",
"webpki-roots",
"whoami",
]
[[package]]
name = "sqlx-macros"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e4a2349d1ffd60a03ca0de3f116ba55d7f406e55a0d84c64a5590866d94c06"
dependencies = [
"dotenv",
"either",
"futures",
"heck",
"once_cell",
"proc-macro2",
"quote",
"sha2 0.9.5",
"sqlx-core",
"sqlx-rt",
"syn",
"url",
]
[[package]]
name = "sqlx-rt"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8199b421ecf3493ee9ef3e7bc90c904844cfb2ea7ea2f57347a93f52bfd3e057"
dependencies = [
"once_cell",
"tokio",
"tokio-rustls",
]
[[package]]
name = "stable-pattern"
version = "0.1.0"
@@ -3037,12 +3541,28 @@ dependencies = [
"generic-array 0.12.4",
]
[[package]]
name = "stringprep"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "subtle"
version = "1.0.0"
@@ -3078,6 +3598,12 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tempfile"
version = "3.2.0"
@@ -3130,6 +3656,17 @@ dependencies = [
"syn",
]
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]]
name = "time"
version = "0.2.27"
@@ -3185,9 +3722,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.8.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4"
checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c"
dependencies = [
"autocfg",
"bytes",
@@ -3196,6 +3733,7 @@ dependencies = [
"mio",
"num_cpus",
"once_cell",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"tokio-macros",
@@ -3223,6 +3761,17 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
dependencies = [
"rustls",
"tokio",
"webpki",
]
[[package]]
name = "tokio-stream"
version = "0.1.6"
@@ -3409,6 +3958,25 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]]
name = "unicase_serde"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ef53697679d874d69f3160af80bc28de12730a985d57bdf2b47456ccb8b11f1"
dependencies = [
"serde",
"unicase",
]
[[package]]
name = "unicode-bidi"
version = "0.3.5"
@@ -3427,6 +3995,12 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-width"
version = "0.1.8"
@@ -3439,6 +4013,18 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "unicode_categories"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "url"
version = "2.2.2"
@@ -3517,9 +4103,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasm-bindgen"
@@ -3650,6 +4236,25 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki"
version = "0.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "webpki-roots"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
dependencies = [
"webpki",
]
[[package]]
name = "websocket-requests"
version = "0.1.0"
@@ -3671,6 +4276,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "whoami"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4abacf325c958dfeaf1046931d37f2a901b6dfe0968ee965a29e94c6766b2af6"
dependencies = [
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "winapi"
version = "0.3.9"
+4 -3
View File
@@ -39,10 +39,11 @@ members = [
"common/socks5/proxy-helpers",
"common/topology",
"common/wasm-utils",
"explorer-api",
"gateway",
"gateway/gateway-requests",
"mixnode",
# "validator-api",
"validator-api",
"service-providers/network-requester",
]
@@ -53,7 +54,7 @@ default-members = [
"gateway",
"service-providers/network-requester",
"mixnode",
# "validator-api",
"validator-api",
]
exclude = ["explorer", "contracts", "validator-api"]
exclude = ["explorer", "contracts"]
+2
View File
@@ -0,0 +1,2 @@
target
explorer-api-state.json
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
[package]
name = "explorer-api"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
isocountry = "0.3.2"
reqwest = "0.11.4"
rocket = {version = "0.5.0-rc.1", features=["json"] }
serde = "1.0.126"
serde_json = "1.0.66"
tokio = {version = "1.9.0", features = ["full"] }
chrono = { version = "0.4.19", features = ["serde"] }
schemars = { version = "0.8", features = ["preserve_order"] }
okapi = { version = "0.6.0-alpha-1", features = ["derive_json_schema"] }
rocket_okapi = "0.7.0-alpha-1"
log = "0.4.0"
pretty_env_logger = "0.4.0"
mixnet-contract = { path = "../common/mixnet-contract" }
validator-client = { path = "../common/client-libs/validator-client" }
+17
View File
@@ -0,0 +1,17 @@
Network Explorer API
====================
An API that can:
* calculate how many nodes are in which country, by checking the IPs of all nodes against an external service
* serve "hello world" via HTTP
TODO:
* record the number of mixnodes on a given date and write to a file for later retrieval
* store the nodes per country state in a variable
* grab mixnode description info via reqwest and serve it (avoid mixed-content errors)
* serve it all over http
* dependency injection
* tests
@@ -0,0 +1,35 @@
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
pub type CountryNodesDistribution = HashMap<String, u32>;
#[derive(Clone)]
pub struct ConcurrentCountryNodesDistribution {
inner: Arc<RwLock<CountryNodesDistribution>>,
}
impl ConcurrentCountryNodesDistribution {
pub(crate) fn new() -> Self {
ConcurrentCountryNodesDistribution {
inner: Arc::new(RwLock::new(CountryNodesDistribution::new())),
}
}
pub(crate) fn attach(country_node_distribution: CountryNodesDistribution) -> Self {
ConcurrentCountryNodesDistribution {
inner: Arc::new(RwLock::new(country_node_distribution)),
}
}
pub(crate) async fn set_all(&mut self, country_node_distribution: CountryNodesDistribution) {
self.inner
.write()
.await
.clone_from(&country_node_distribution)
}
pub(crate) async fn get_all(&self) -> HashMap<String, u32> {
self.inner.read().await.clone()
}
}
@@ -0,0 +1,19 @@
use crate::country_statistics::country_nodes_distribution::CountryNodesDistribution;
use crate::state::ExplorerApiStateContext;
use rocket::serde::json::Json;
use rocket::{Route, State};
pub fn make_default_routes() -> Vec<Route> {
routes_with_openapi![index]
}
// We could either separate stuff by structure (like this, http is separate), or we could just
// stick the http route directly into each sub-application (e.g. put this file into the
// "country_statistics" module directly
#[openapi(tag = "country_statistics")]
#[get("/")]
pub(crate) async fn index(
state: &State<ExplorerApiStateContext>,
) -> Json<CountryNodesDistribution> {
Json(state.inner.country_node_distribution.get_all().await)
}
+124
View File
@@ -0,0 +1,124 @@
use isocountry::CountryCode;
use log::{info, trace, warn};
use mixnet_contract::MixNodeBond;
use reqwest::Error as ReqwestError;
use validator_client::Config;
use models::GeoLocation;
use crate::country_statistics::country_nodes_distribution::CountryNodesDistribution;
use crate::state::ExplorerApiStateContext;
pub mod country_nodes_distribution;
pub mod http;
mod models;
pub(crate) struct CountryStatistics {
state: ExplorerApiStateContext,
}
impl CountryStatistics {
pub(crate) fn new(state: ExplorerApiStateContext) -> Self {
CountryStatistics { state }
}
pub(crate) fn start(mut self) {
info!("Spawning task runner...");
tokio::spawn(async move {
let mut interval_timer = tokio::time::interval(std::time::Duration::from_secs(60 * 60));
loop {
// wait for the next interval tick
interval_timer.tick().await;
info!("Running task...");
self.calculate_nodes_per_country().await;
info!("Done");
}
});
}
/// Retrieves the current list of mixnodes from the validators and calculates how many nodes are in each country
async fn calculate_nodes_per_country(&mut self) {
let mixnode_bonds = retrieve_mixnodes().await;
let mut distribution = CountryNodesDistribution::new();
info!("Locating mixnodes...");
for (i, bond) in mixnode_bonds.iter().enumerate() {
match locate(&bond.mix_node.host).await {
Ok(location) => {
let country_code = map_2_letter_to_3_letter_country_code(&location);
*(distribution.entry(country_code)).or_insert(0) += 1;
trace!(
"Ip {} is located in {:#?}",
bond.mix_node.host,
map_2_letter_to_3_letter_country_code(&location)
);
if (i % 100) == 0 {
info!(
"Located {} mixnodes in {} countries",
i + 1,
distribution.len()
);
}
}
Err(e) => warn!("❌ Oh no! Location failed {}", e),
}
}
// replace the shared distribution to be the new distribution
self.state
.inner
.country_node_distribution
.set_all(distribution)
.await;
info!(
"Locating mixnodes done: {:?}",
self.state.inner.country_node_distribution.get_all().await
);
// keep state on disk, so that when this process dies it can start up again and users get some data
self.state.write_to_file().await;
}
}
fn map_2_letter_to_3_letter_country_code(geo: &GeoLocation) -> String {
match CountryCode::for_alpha2(&geo.country_code) {
Ok(three_letter_country_code) => three_letter_country_code.alpha3().to_string(),
Err(_e) => {
warn!(
"❌ Oh no! map_2_letter_to_3_letter_country_code failed for '{:#?}'",
geo
);
"???".to_string()
}
}
}
async fn locate(ip: &str) -> Result<GeoLocation, ReqwestError> {
let response = reqwest::get(format!("{}{}", crate::GEO_IP_SERVICE, ip)).await?;
let location = response.json::<GeoLocation>().await?;
Ok(location)
}
async fn retrieve_mixnodes() -> Vec<MixNodeBond> {
let client = new_validator_client();
info!("About to retrieve mixnode bonds...");
let bonds: Vec<MixNodeBond> = match client.get_cached_mix_nodes().await {
Ok(result) => result,
Err(e) => panic!("Unable to retrieve mixnode bonds: {:?}", e),
};
info!("Fetched {} mixnode bonds", bonds.len());
bonds
}
// TODO: inject constants
fn new_validator_client() -> validator_client::Client {
let config = Config::new(vec![crate::VALIDATOR_API.to_string()], crate::CONTRACT);
validator_client::Client::new(config)
}
@@ -0,0 +1,16 @@
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub(crate) struct GeoLocation {
pub(crate) ip: String,
pub(crate) country_code: String,
pub(crate) country_name: String,
pub(crate) region_code: String,
pub(crate) region_name: String,
pub(crate) city: String,
pub(crate) zip_code: String,
pub(crate) time_zone: String,
pub(crate) latitude: f32,
pub(crate) longitude: f32,
pub(crate) metro_code: u32,
}
+28
View File
@@ -0,0 +1,28 @@
mod swagger;
use crate::country_statistics::http::make_default_routes;
use crate::http::swagger::get_docs;
use crate::ping::http::ping_make_default_routes;
use crate::state::ExplorerApiStateContext;
use log::info;
use rocket_okapi::swagger_ui::make_swagger_ui;
pub(crate) fn start(state: ExplorerApiStateContext) {
tokio::spawn(async move {
info!("Starting up...");
let config = rocket::config::Config::release_default();
rocket::build()
.configure(config)
.mount("/countries", make_default_routes())
.mount("/ping", ping_make_default_routes())
.mount("/swagger", make_swagger_ui(&get_docs()))
// .register("/", catchers![not_found])
.manage(state)
// .manage(descriptor)
// .manage(node_stats_pointer)
.launch()
.await
});
}
+11
View File
@@ -0,0 +1,11 @@
use rocket_okapi::swagger_ui::{SwaggerUIConfig, UrlObject};
pub(crate) fn get_docs() -> SwaggerUIConfig {
SwaggerUIConfig {
urls: vec![
UrlObject::new("Country statistics", "/countries/openapi.json"),
UrlObject::new("Node ping", "/ping/openapi.json"),
],
..Default::default()
}
}
+72
View File
@@ -0,0 +1,72 @@
#[macro_use]
extern crate rocket;
#[macro_use]
extern crate rocket_okapi;
use log::info;
mod country_statistics;
mod http;
mod ping;
mod state;
const VALIDATOR_API: &str = "http://testnet-milhon-validator1.nymtech.net:8080";
const CONTRACT: &str = "punk10pyejy66429refv3g35g2t7am0was7yalwrzen";
const GEO_IP_SERVICE: &str = "https://freegeoip.app/json/";
#[tokio::main]
async fn main() {
setup_logging();
let mut explorer_api = ExplorerApi::new();
explorer_api.run().await;
}
pub struct ExplorerApi {
state: state::ExplorerApiStateContext,
}
impl ExplorerApi {
fn new() -> ExplorerApi {
ExplorerApi {
state: state::ExplorerApiStateContext::new(),
}
}
async fn run(&mut self) {
info!("Explorer API starting up...");
// spawn concurrent tasks
country_statistics::CountryStatistics::new(self.state.clone()).start();
http::start(self.state.clone());
// wait for user to press ctrl+C
self.wait_for_interrupt().await
}
async fn wait_for_interrupt(&self) {
if let Err(e) = tokio::signal::ctrl_c().await {
error!(
"There was an error while capturing SIGINT - {:?}. We will terminate regardless",
e
);
}
info!(
"Received SIGINT - the mixnode will terminate now (threads are not yet nicely stopped, if you see stack traces that's alright)."
);
}
}
fn setup_logging() {
let mut log_builder = pretty_env_logger::formatted_timed_builder();
if let Ok(s) = ::std::env::var("RUST_LOG") {
log_builder.parse_filters(&s);
} else {
// default to 'Info'
log_builder.filter(None, log::LevelFilter::Info);
}
log_builder
.filter_module("tokio_reactor", log::LevelFilter::Warn)
.filter_module("reqwest", log::LevelFilter::Warn)
.init();
}
+19
View File
@@ -0,0 +1,19 @@
use rocket::serde::json::Json;
use rocket::Route;
use serde::Deserialize;
use serde::Serialize;
pub fn ping_make_default_routes() -> Vec<Route> {
routes_with_openapi![index]
}
#[derive(Deserialize, Serialize, JsonSchema)]
pub(crate) struct PingResponse {
response_time: u32,
}
#[openapi(tag = "ping")]
#[get("/")]
pub(crate) async fn index() -> Json<PingResponse> {
Json(PingResponse { response_time: 42 })
}
+1
View File
@@ -0,0 +1 @@
pub mod http;
+82
View File
@@ -0,0 +1,82 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::path::Path;
use log::info;
use crate::country_statistics::country_nodes_distribution::{
ConcurrentCountryNodesDistribution, CountryNodesDistribution,
};
// TODO: change to an environment variable with a default value
const STATE_FILE: &str = "explorer-api-state.json";
#[derive(Clone)]
pub struct ExplorerApiState {
pub(crate) country_node_distribution: ConcurrentCountryNodesDistribution,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ExplorerApiStateOnDisk {
pub(crate) country_node_distribution: CountryNodesDistribution,
pub(crate) as_at: DateTime<Utc>,
}
#[derive(Clone)]
pub(crate) struct ExplorerApiStateContext {
pub(crate) inner: ExplorerApiState,
state_file: String,
}
impl ExplorerApiStateContext {
pub(crate) fn new() -> Self {
ExplorerApiStateContext {
inner: ExplorerApiStateContext::read_from_file(),
state_file: std::env::var("API_STATE_FILE").unwrap_or_else(|_| STATE_FILE.to_string()),
}
}
pub(crate) fn read_from_file() -> ExplorerApiState {
let json_file = get_state_file_path();
let json_file_path = Path::new(&json_file);
info!("Loading state from file {:?}...", json_file);
match File::open(json_file_path) {
Ok(file) => {
let state: ExplorerApiStateOnDisk =
serde_json::from_reader(file).expect("error while reading json");
info!("Loaded state from file {:?}: {:?}", json_file, state);
ExplorerApiState {
country_node_distribution: ConcurrentCountryNodesDistribution::attach(
state.country_node_distribution,
),
}
}
Err(_e) => {
warn!(
"Failed to load state from file {:?}, starting with empty state!",
json_file
);
ExplorerApiState {
country_node_distribution: ConcurrentCountryNodesDistribution::new(),
}
}
}
}
pub(crate) async fn write_to_file(&self) {
let json_file = get_state_file_path().to_string();
let json_file_path = Path::new(&json_file);
let file = File::create(json_file_path).expect("unable to create state json file");
let state = ExplorerApiStateOnDisk {
country_node_distribution: self.inner.country_node_distribution.get_all().await,
as_at: Utc::now(),
};
serde_json::to_writer(file, &state).expect("error writing state to disk");
info!("Saved file to '{:?}'", json_file_path.canonicalize());
}
}
fn get_state_file_path() -> String {
std::env::var("API_STATE_FILE").unwrap_or_else(|_| STATE_FILE.to_string())
}
+5 -5
View File
@@ -11,10 +11,6 @@ authors = [
]
edition = "2018"
# if there's ANY panic in ANY thread, abort the whole thing
[profile.release]
panic = "abort"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
@@ -36,7 +32,7 @@ rocket_cors = { git="https://github.com/lawliet89/rocket_cors", rev="dfd3662c49e
anyhow = "1"
rocket_sync_db_pools = {version = "0.1.0-rc.1", default-features = false}
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite", "macros", "offline", "migrate", "time"]}
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate", "time"]}
## internal
config = { path = "../common/config" }
@@ -50,3 +46,7 @@ validator-client = { path="../common/client-libs/validator-client" }
version-checker = { path="../common/version-checker" }
[dev-dependencies]
[build-dependencies]
tokio = { version="1.4", features=["rt-multi-thread", "macros"] }
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]}
+19
View File
@@ -0,0 +1,19 @@
use sqlx::{Connection, SqliteConnection};
use std::env;
#[tokio::main]
async fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let database_path = format!("sqlite://{}/validator-api-example.sqlite", out_dir);
let mut conn = SqliteConnection::connect(&*format!("{}?mode=rwc", database_path))
.await
.expect("Failed to create SQLx database connection");
sqlx::migrate!("./migrations")
.run(&mut conn)
.await
.expect("Failed to perform SQLx migrations");
println!("cargo:rustc-env=DATABASE_URL={}", &database_path);
}