From d3372bfc85ea4fda6eb4602babeb8f42d2f8d565 Mon Sep 17 00:00:00 2001 From: Drazen Urch Date: Tue, 12 Apr 2022 11:55:32 +0200 Subject: [PATCH] Additional, more informative routes (#1204) * Have reward set updater run its own timer (#1200) * Have reward set updater run its own timer * Filter rocket log spam * Take last day of uptime for rewarding (#1202) * Take last day of uptime for rewarding * Rejigger calculations * Blacklist based on last 24 hr * Cleanup * Clippy * Additional, more informative routes * Improve blacklist updates * Fix rewards estimation --- Cargo.lock | 261 +++++++++--------- .../mixnet-contract/src/mixnode.rs | 18 +- contracts/mixnet/src/rewards/transactions.rs | 14 +- explorer-api/src/mix_node/econ_stats.rs | 2 +- .../types/rust/rewardestimationresponse.ts | 9 - .../20220410222400_add_timestamp_indexes.sql | 13 + validator-api/src/config/mod.rs | 8 - validator-api/src/config/template.rs | 5 - validator-api/src/contract_cache/mod.rs | 85 +++--- validator-api/src/contract_cache/routes.rs | 29 +- validator-api/src/main.rs | 15 +- .../src/network_monitor/monitor/mod.rs | 33 --- .../src/network_monitor/monitor/preparer.rs | 4 - validator-api/src/node_status_api/models.rs | 9 + validator-api/src/node_status_api/routes.rs | 30 +- validator-api/src/nymd_client.rs | 14 - validator-api/src/rewarded_set_updater/mod.rs | 96 ++++++- validator-api/src/storage/manager.rs | 109 ++++++++ validator-api/src/storage/mod.rs | 61 ++-- .../validator-api-requests/Cargo.toml | 1 + .../validator-api-requests/src/models.rs | 13 +- 21 files changed, 486 insertions(+), 343 deletions(-) delete mode 100644 nym-wallet/src/types/rust/rewardestimationresponse.ts create mode 100644 validator-api/migrations/20220410222400_add_timestamp_indexes.sql diff --git a/Cargo.lock b/Cargo.lock index 9f17b2da89..8c3bc17e44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,7 +44,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.6", "once_cell", "version_check", ] @@ -114,9 +114,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.52" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" +checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" dependencies = [ "proc-macro2", "quote", @@ -218,9 +218,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "base64ct" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71acf5509fc522cce1b100ac0121c635129bfd4d91cdf036bcc9b9935f97ccf5" +checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" [[package]] name = "binascii" @@ -419,9 +419,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytemuck" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e851ca7c24871e7336801608a4797d7376545b6928a10d32d75685687141ead" +checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" [[package]] name = "byteorder" @@ -525,9 +525,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.6" +version = "3.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123" +checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" dependencies = [ "atty", "bitflags", @@ -542,9 +542,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.4" +version = "3.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16" +checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -762,7 +762,7 @@ dependencies = [ "cosmos-sdk-proto 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ecdsa 0.13.4", "eyre", - "getrandom 0.2.5", + "getrandom 0.2.6", "k256 0.10.4", "prost", "prost-types", @@ -783,7 +783,7 @@ dependencies = [ "cosmos-sdk-proto 0.9.0 (git+https://github.com/nymtech/cosmos-rust?branch=bugfix/account-id-length-validation)", "ecdsa 0.13.4", "eyre", - "getrandom 0.2.5", + "getrandom 0.2.6", "k256 0.10.4", "prost", "prost-types", @@ -798,9 +798,9 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.0.0-beta7" +version = "1.0.0-beta8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c2565b1e73a816fb659ef4838fc356143fbd35f43c48a51d2d7d4e5d6679d3" +checksum = "37e70111e9701c3ec43bfbff0e523cd4cb115876b4d3433813436dd0934ee962" dependencies = [ "digest 0.9.0", "ed25519-zebra", @@ -811,18 +811,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0-beta7" +version = "1.0.0-beta8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa89fcdf8dbbe0088e663d0a814aa7368e7ebe8fb045a3a150fb5fdc2ffe3b45" +checksum = "58bc2ad5d86be5f6068833f63e20786768db6890019c095dd7775232184fb7b3" dependencies = [ "syn", ] [[package]] name = "cosmwasm-std" -version = "1.0.0-beta7" +version = "1.0.0-beta8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcb8f99a61d0b9069e1afc80a4ffea87dcc3523edd992080923870b13a677da0" +checksum = "915ca82bd944f116f3a9717481f3fa657e4a73f28c4887288761ebb24e6fbe10" dependencies = [ "base64", "cosmwasm-crypto", @@ -837,9 +837,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ "libc", ] @@ -875,7 +875,7 @@ dependencies = [ "async-trait", "bip39", "cfg-if 0.1.10", - "clap 3.1.6", + "clap 3.1.8", "coconut-bandwidth-contract-common", "coconut-interface", "credentials", @@ -944,9 +944,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbfe11fe19ff083c48923cf179540e8cd0535903dc35e178a1fdeeb59aef51f" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -1155,9 +1155,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ "darling_core", "darling_macro", @@ -1165,9 +1165,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", @@ -1179,9 +1179,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", @@ -1302,9 +1302,9 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", @@ -1361,9 +1361,9 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed12bbf7b5312f8da1c2722bc06d8c6b12c2d86a7fb35a194c7f3e6fc2bbe39" +checksum = "3d5c4b5e5959dc2c2b89918d8e2cc40fcdd623cef026ed09d2f0ee05199dc8e4" dependencies = [ "signature", ] @@ -1439,9 +1439,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if 1.0.0", ] @@ -1557,9 +1557,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9289ed2c0440a6536e65119725cf91fc2c6b5e513bfd2e36e1134d7cca6ca12f" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" dependencies = [ "indenter", "once_cell", @@ -1616,9 +1616,9 @@ dependencies = [ [[package]] name = "fixed" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3342b127378d13cfdbd56de8d7e7feec33a9772d5657b9605e59a6e4a337e36" +checksum = "86d3f4dd10ddfcb0bd2b2efe9f18aff37ed48265fda3e20e5d53f046aba9d50a" dependencies = [ "az", "bytemuck", @@ -1883,7 +1883,7 @@ dependencies = [ "fluvio-wasm-timer", "futures", "gateway-requests", - "getrandom 0.2.5", + "getrandom 0.2.6", "json", "log", "network-defaults", @@ -1970,9 +1970,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -2049,9 +2049,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62eeb471aa3e3c9197aa4bfeabfe02982f6dc96f750486c0bb0009ac58b26d2b" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" dependencies = [ "bytes", "fnv", @@ -2062,7 +2062,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.6.9", + "tokio-util 0.7.1", "tracing", ] @@ -2277,9 +2277,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.17" +version = "0.14.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043f0e083e9901b6cc658a77d1eb86f4fc650bbb977a4337dd63192826aa85dd" +checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" dependencies = [ "bytes", "futures-channel", @@ -2423,9 +2423,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg 1.1.0", "hashbrown", @@ -2440,9 +2440,9 @@ checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" [[package]] name = "inout" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1f03d4ab4d5dc9ec2d219f86c15d2a15fc08239d1cd3b2d6a19717c0a2f443" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ "generic-array 0.14.5", ] @@ -2599,9 +2599,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.120" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09" +checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" [[package]] name = "libgit2-sys" @@ -2664,18 +2664,19 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg 1.1.0", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ "cfg-if 1.0.0", ] @@ -2761,9 +2762,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba42135c6a5917b9db9cd7b293e5409e1c6b041e6f9825e92e55a894c63b6f8" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" dependencies = [ "libc", "log", @@ -2807,7 +2808,7 @@ dependencies = [ "serde", "serde_repr", "thiserror", - "time 0.3.7", + "time 0.3.9", "ts-rs", ] @@ -2865,9 +2866,9 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "native-tls" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" dependencies = [ "lazy_static", "libc", @@ -3014,7 +3015,7 @@ dependencies = [ "bandwidth-claim-contract", "bip39", "bs58", - "clap 3.1.6", + "clap 3.1.8", "coconut-interface", "colored", "config", @@ -3057,7 +3058,7 @@ version = "1.0.0-rc.1" dependencies = [ "anyhow", "bs58", - "clap 3.1.6", + "clap 3.1.8", "colored", "config", "crypto", @@ -3182,7 +3183,7 @@ dependencies = [ "serde_json", "sqlx", "thiserror", - "time 0.3.7", + "time 0.3.9", "tokio", "tokio-stream", "topology", @@ -3204,7 +3205,7 @@ dependencies = [ "digest 0.9.0", "doc-comment", "ff 0.10.1", - "getrandom 0.2.5", + "getrandom 0.2.6", "group 0.10.0", "itertools", "rand 0.8.5", @@ -3470,7 +3471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" dependencies = [ "lock_api", - "parking_lot_core 0.9.1", + "parking_lot_core 0.9.2", ] [[package]] @@ -3489,9 +3490,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" +checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" dependencies = [ "cfg-if 1.0.0", "libc", @@ -3502,9 +3503,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" +checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" [[package]] name = "pbkdf2" @@ -3710,9 +3711,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "plotters" @@ -3813,9 +3814,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ "unicode-xid", ] @@ -3928,9 +3929,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quote" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -4055,7 +4056,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.6", ] [[package]] @@ -4175,21 +4176,22 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.6", "redox_syscall", + "thiserror", ] [[package]] @@ -4501,7 +4503,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.6", + "semver 1.0.7", ] [[package]] @@ -4690,9 +4692,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" +checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" [[package]] name = "semver-parser" @@ -4948,9 +4950,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "sled" @@ -5316,9 +5318,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" dependencies = [ "proc-macro2", "quote", @@ -5384,7 +5386,7 @@ dependencies = [ "subtle 2.4.1", "subtle-encoding", "tendermint-proto", - "time 0.3.7", + "time 0.3.9", "zeroize", ] @@ -5417,7 +5419,7 @@ dependencies = [ "serde", "serde_bytes", "subtle-encoding", - "time 0.3.7", + "time 0.3.9", ] [[package]] @@ -5430,7 +5432,7 @@ dependencies = [ "bytes", "flex-error", "futures", - "getrandom 0.2.5", + "getrandom 0.2.6", "http", "hyper", "hyper-proxy", @@ -5445,7 +5447,7 @@ dependencies = [ "tendermint-config", "tendermint-proto", "thiserror", - "time 0.3.7", + "time 0.3.9", "tokio", "tracing", "url", @@ -5534,15 +5536,15 @@ dependencies = [ [[package]] name = "time" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d" +checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" dependencies = [ "itoa 1.0.1", "libc", "num_threads", "serde", - "time-macros 0.2.3", + "time-macros 0.2.4", ] [[package]] @@ -5557,9 +5559,9 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6" +checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" [[package]] name = "time-macros-impl" @@ -5711,16 +5713,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64910e1b9c1901aaf5375561e35b9c057d95ff41a44ede043a03e09279eabaf1" +checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" dependencies = [ "bytes", "futures-core", "futures-sink", - "log", "pin-project-lite", "tokio", + "tracing", ] [[package]] @@ -5803,7 +5805,7 @@ dependencies = [ "rand 0.8.5", "slab", "tokio", - "tokio-util 0.7.0", + "tokio-util 0.7.1", "tower-layer", "tower-service", "tracing", @@ -5823,9 +5825,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" +checksum = "80b9fa4360528139bc96100c160b7ae879f5567f49f1782b0b02035b0358ebf3" dependencies = [ "cfg-if 1.0.0", "log", @@ -5847,9 +5849,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c" +checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee" dependencies = [ "lazy_static", "valuable", @@ -5878,9 +5880,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e0ab7bdc962035a87fba73f3acca9b8a8d0034c2e6f60b84aeaaddddc155dce" +checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" dependencies = [ "ansi_term", "lazy_static", @@ -5966,9 +5968,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "uint" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" dependencies = [ "byteorder", "crunchy", @@ -6079,6 +6081,7 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" name = "validator-api-requests" version = "0.1.0" dependencies = [ + "mixnet-contract-common", "serde", "ts-rs", ] @@ -6333,7 +6336,7 @@ dependencies = [ "ethereum-types", "futures", "futures-timer", - "getrandom 0.2.5", + "getrandom 0.2.6", "headers", "hex", "js-sys", @@ -6400,9 +6403,9 @@ dependencies = [ [[package]] name = "which" -version = "4.2.4" +version = "4.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" dependencies = [ "either", "lazy_static", @@ -6448,9 +6451,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.32.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" +checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" dependencies = [ "windows_aarch64_msvc", "windows_i686_gnu", @@ -6461,33 +6464,33 @@ dependencies = [ [[package]] name = "windows_aarch64_msvc" -version = "0.32.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" [[package]] name = "windows_i686_gnu" -version = "0.32.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" [[package]] name = "windows_i686_msvc" -version = "0.32.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" [[package]] name = "windows_x86_64_gnu" -version = "0.32.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" [[package]] name = "windows_x86_64_msvc" -version = "0.32.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" [[package]] name = "winreg" @@ -6526,9 +6529,9 @@ dependencies = [ [[package]] name = "yansi" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zeroize" diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs index ddcf52e382..a55a5a3392 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs @@ -228,7 +228,7 @@ impl DelegatorRewardParams { let scaled_delegation_amount = delegation_amount / circulating_supply; let delegator_reward = - (ONE - self.profit_margin) * scaled_delegation_amount / self.sigma * self.node_profit; + (ONE - self.profit_margin) * (scaled_delegation_amount / self.sigma) * self.node_profit; let reward = delegator_reward.max(U128::ZERO); if let Some(int_reward) = reward.checked_cast() { @@ -426,17 +426,17 @@ impl MixNodeBond { &self, params: &RewardParams, ) -> Result<(u64, u64, u64), MixnetContractError> { - let total_node_reward = self.reward(params); + let total_node_reward = self + .reward(params) + .reward() + .checked_to_num::() + .unwrap_or_default(); let operator_reward = self.operator_reward(params); - // TODO: This overestimates the reward by a lot, it should take a Uint128 and return estiamte for that - let delegators_reward = self.reward_delegation(self.total_delegation().amount, params); + // Total reward has to be the sum of operator and delegator rewards + let delegators_reward = total_node_reward - operator_reward; Ok(( - total_node_reward - .reward() - .checked_to_num::() - .unwrap_or_default() - .try_into()?, + total_node_reward.try_into()?, operator_reward.try_into()?, delegators_reward.try_into()?, )) diff --git a/contracts/mixnet/src/rewards/transactions.rs b/contracts/mixnet/src/rewards/transactions.rs index 11a9116ec5..b3937d7bd7 100644 --- a/contracts/mixnet/src/rewards/transactions.rs +++ b/contracts/mixnet/src/rewards/transactions.rs @@ -1025,6 +1025,8 @@ pub mod tests { ); assert_eq!(mix_1_reward_result.reward().int(), 259114u128); + assert_eq!(mix_1.node_profit(¶ms).int(), 203558u128); + let mix1_operator_reward = mix_1.operator_reward(¶ms); let mix1_delegator1_reward = mix_1.reward_delegation(Uint128::new(8000_000000), ¶ms); @@ -1035,6 +1037,11 @@ pub mod tests { assert_eq!(mix1_delegator1_reward, 73280); assert_eq!(mix1_delegator2_reward, 18320); + assert_eq!( + mix_1_reward_result.reward().int(), + mix1_operator_reward + mix1_delegator1_reward + mix1_delegator2_reward + 1 + ); + assert_eq!( mix1_operator_reward + mix1_delegator1_reward + mix1_delegator2_reward + 1, mix_1_reward_result.reward().int() @@ -1076,13 +1083,6 @@ pub mod tests { + mix1_delegator2_reward + 1 // There is a rounding error here it seems ); - // assert_eq!( - // mixnodes_storage::TOTAL_DELEGATION - // .load(&deps.storage, &node_identity) - // .unwrap() - // .u128(), - // pre_reward_delegation + mix1_delegator1_reward + mix1_delegator2_reward - // ); assert_eq!( storage::REWARD_POOL.load(&deps.storage).unwrap().u128(), diff --git a/explorer-api/src/mix_node/econ_stats.rs b/explorer-api/src/mix_node/econ_stats.rs index ee703047db..25765cf8c6 100644 --- a/explorer-api/src/mix_node/econ_stats.rs +++ b/explorer-api/src/mix_node/econ_stats.rs @@ -36,6 +36,6 @@ pub(crate) async fn retrieve_mixnode_econ_stats( estimated_total_node_reward: reward_estimation.estimated_total_node_reward, estimated_operator_reward: reward_estimation.estimated_operator_reward, estimated_delegators_reward: reward_estimation.estimated_delegators_reward, - current_interval_uptime: reward_estimation.current_interval_uptime, + current_interval_uptime: reward_estimation.reward_params.node.uptime() as u8, }) } diff --git a/nym-wallet/src/types/rust/rewardestimationresponse.ts b/nym-wallet/src/types/rust/rewardestimationresponse.ts deleted file mode 100644 index 6ca4481acc..0000000000 --- a/nym-wallet/src/types/rust/rewardestimationresponse.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface RewardEstimationResponse { - estimated_total_node_reward: bigint; - estimated_operator_reward: bigint; - estimated_delegators_reward: bigint; - current_interval_start: bigint; - current_interval_end: bigint; - current_interval_uptime: number; - as_at: bigint; -} diff --git a/validator-api/migrations/20220410222400_add_timestamp_indexes.sql b/validator-api/migrations/20220410222400_add_timestamp_indexes.sql new file mode 100644 index 0000000000..76efcb1313 --- /dev/null +++ b/validator-api/migrations/20220410222400_add_timestamp_indexes.sql @@ -0,0 +1,13 @@ +/* + * Copyright 2022 - Nym Technologies SA + * SPDX-License-Identifier: Apache-2.0 + */ + +CREATE INDEX mixnode_status_timestamp ON mixnode_status(`timestamp`); +CREATE INDEX mixnode_status_id ON mixnode_status(`mixnode_details_id`); + +CREATE INDEX gateway_status_timestamp ON gateway_status(`timestamp`); +CREATE INDEX gateway_status_id ON gateway_status(`gateway_details_id`); + +CREATE INDEX gateway_details_id on gateway_details(`id`); +CREATE INDEX mixnode_details_id on mixnode_details(`id`); \ No newline at end of file diff --git a/validator-api/src/config/mod.rs b/validator-api/src/config/mod.rs index 05e22003eb..98a1846671 100644 --- a/validator-api/src/config/mod.rs +++ b/validator-api/src/config/mod.rs @@ -435,14 +435,6 @@ impl Config { self.network_monitor.minimum_test_routes } - pub fn get_min_mixnode_reliability(&self) -> u8 { - self.network_monitor.min_mixnode_reliability - } - - pub fn get_min_gateway_reliability(&self) -> u8 { - self.network_monitor.min_gateway_reliability - } - pub fn get_route_test_packets(&self) -> usize { self.network_monitor.route_test_packets } diff --git a/validator-api/src/config/template.rs b/validator-api/src/config/template.rs index 815bc8e8e7..1347a63eb2 100644 --- a/validator-api/src/config/template.rs +++ b/validator-api/src/config/template.rs @@ -19,11 +19,6 @@ mixnet_contract_address = '{{ base.mixnet_contract_address }}' ##### network monitor config options ##### [network_monitor] - -# Mixnodes and gateways with relialability lower the this get blacklisted by network monitor, get no traffic and cannot be selected into a rewarded set. -min_mixnode_reliability = {{ network_monitor.min_mixnode_reliability }} # deafults to 50 -min_gateway_reliability = {{ network_monitor.min_gateway_reliability }} # defaults to 20 - # Specifies whether network monitoring service is enabled in this process. enabled = {{ network_monitor.enabled }} diff --git a/validator-api/src/contract_cache/mod.rs b/validator-api/src/contract_cache/mod.rs index dd95dd35b1..b81d38acde 100644 --- a/validator-api/src/contract_cache/mod.rs +++ b/validator-api/src/contract_cache/mod.rs @@ -17,7 +17,7 @@ use std::collections::HashSet; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; -use tokio::sync::{Notify, RwLock}; +use tokio::sync::RwLock; use tokio::time; use validator_api_requests::models::MixnodeStatus; use validator_client::nymd::CosmWasmClient; @@ -28,7 +28,6 @@ pub struct ValidatorCacheRefresher { nymd_client: Client, cache: ValidatorCache, caching_interval: Duration, - update_rewarded_set_notify: Option>, } #[derive(Clone)] @@ -89,13 +88,11 @@ impl ValidatorCacheRefresher { nymd_client: Client, caching_interval: Duration, cache: ValidatorCache, - update_rewarded_set_notify: Option>, ) -> Self { ValidatorCacheRefresher { nymd_client, cache, caching_interval, - update_rewarded_set_notify, } } @@ -136,6 +133,7 @@ impl ValidatorCacheRefresher { self.collect_rewarded_and_active_set_details(&mixnodes, rewarded_set_identities); let epoch_rewarding_params = self.nymd_client.get_current_epoch_reward_params().await?; + let current_epoch = self.nymd_client.get_current_epoch().await?; info!( "Updating validator cache. There are {} mixnodes and {} gateways", @@ -150,23 +148,10 @@ impl ValidatorCacheRefresher { rewarded_set, active_set, epoch_rewarding_params, + current_epoch, ) .await; - if let Some(notify) = &self.update_rewarded_set_notify { - let update_details = self - .nymd_client - .get_current_rewarded_set_update_details() - .await?; - - if update_details.last_refreshed_block + (update_details.refresh_rate_blocks as u64) - < update_details.current_height - { - // there's only ever a single waiter -> the set updater - notify.notify_one() - } - } - Ok(()) } @@ -209,6 +194,8 @@ impl ValidatorCache { routes::get_rewarded_set, routes::get_blacklisted_mixnodes, routes::get_blacklisted_gateways, + routes::get_epoch_reward_params, + routes::get_current_epoch ], ) }) @@ -221,6 +208,7 @@ impl ValidatorCache { rewarded_set: Vec, active_set: Vec, epoch_rewarding_params: EpochRewardParams, + current_epoch: Interval, ) { let mut inner = self.inner.write().await; @@ -229,6 +217,7 @@ impl ValidatorCache { inner.rewarded_set.update(rewarded_set); inner.active_set.update(active_set); inner.current_reward_params.update(epoch_rewarding_params); + inner.current_epoch.update(Some(current_epoch)); } pub async fn mixnodes_blacklist(&self) -> Cache> { @@ -239,40 +228,52 @@ impl ValidatorCache { self.inner.read().await.gateways_blacklist.clone() } - pub async fn insert_mixnodes_blacklist(&mut self, mix_identity: IdentityKey) { + pub async fn update_mixnodes_blacklist( + &self, + add: HashSet, + remove: HashSet, + ) { + let blacklist = self.mixnodes_blacklist().await.value; + let mut blacklist = blacklist + .union(&add) + .cloned() + .collect::>(); + let to_remove = blacklist + .intersection(&remove) + .cloned() + .collect::>(); + for key in to_remove { + blacklist.remove(&key); + } self.inner .write() .await .mixnodes_blacklist - .value - .insert(mix_identity); + .update(blacklist); } - pub async fn remove_mixnodes_blacklist(&mut self, mix_identity: &str) { - self.inner - .write() - .await - .mixnodes_blacklist - .value - .remove(mix_identity); - } - - pub async fn insert_gateways_blacklist(&mut self, gateway_identity: IdentityKey) { + pub async fn update_gateways_blacklist( + &self, + add: HashSet, + remove: HashSet, + ) { + let blacklist = self.gateways_blacklist().await.value; + let mut blacklist = blacklist + .union(&add) + .cloned() + .collect::>(); + let to_remove = blacklist + .intersection(&remove) + .cloned() + .collect::>(); + for key in to_remove { + blacklist.remove(&key); + } self.inner .write() .await .gateways_blacklist - .value - .insert(gateway_identity); - } - - pub async fn remove_gateways_blacklist(&mut self, gateway_identity: &str) { - self.inner - .write() - .await - .gateways_blacklist - .value - .remove(gateway_identity); + .update(blacklist); } pub async fn mixnodes(&self) -> Vec { diff --git a/validator-api/src/contract_cache/routes.rs b/validator-api/src/contract_cache/routes.rs index 74890b05fd..5c5eeafee0 100644 --- a/validator-api/src/contract_cache/routes.rs +++ b/validator-api/src/contract_cache/routes.rs @@ -2,41 +2,48 @@ // SPDX-License-Identifier: Apache-2.0 use crate::contract_cache::ValidatorCache; -use mixnet_contract_common::{GatewayBond, MixNodeBond}; +use mixnet_contract_common::reward_params::EpochRewardParams; +use mixnet_contract_common::{GatewayBond, Interval, MixNodeBond}; use rocket::serde::json::Json; use rocket::State; use std::collections::HashSet; #[get("/mixnodes")] -pub(crate) async fn get_mixnodes(cache: &State) -> Json> { +pub async fn get_mixnodes(cache: &State) -> Json> { Json(cache.mixnodes().await) } #[get("/gateways")] -pub(crate) async fn get_gateways(cache: &State) -> Json> { +pub async fn get_gateways(cache: &State) -> Json> { Json(cache.gateways().await) } #[get("/mixnodes/rewarded")] -pub(crate) async fn get_rewarded_set(cache: &State) -> Json> { +pub async fn get_rewarded_set(cache: &State) -> Json> { Json(cache.rewarded_set().await.value) } #[get("/mixnodes/active")] -pub(crate) async fn get_active_set(cache: &State) -> Json> { +pub async fn get_active_set(cache: &State) -> Json> { Json(cache.active_set().await.value) } #[get("/mixnodes/blacklisted")] -pub(crate) async fn get_blacklisted_mixnodes( - cache: &State, -) -> Json> { +pub async fn get_blacklisted_mixnodes(cache: &State) -> Json> { Json(cache.mixnodes_blacklist().await.value) } #[get("/gateways/blacklisted")] -pub(crate) async fn get_blacklisted_gateways( - cache: &State, -) -> Json> { +pub async fn get_blacklisted_gateways(cache: &State) -> Json> { Json(cache.gateways_blacklist().await.value) } + +#[get("/epoch/reward_params")] +pub async fn get_epoch_reward_params(cache: &State) -> Json { + Json(cache.epoch_reward_params().await.value) +} + +#[get("/epoch/current")] +pub async fn get_current_epoch(cache: &State) -> Json> { + Json(cache.current_epoch().await.value) +} diff --git a/validator-api/src/main.rs b/validator-api/src/main.rs index 14001328aa..04a75b5ebe 100644 --- a/validator-api/src/main.rs +++ b/validator-api/src/main.rs @@ -239,6 +239,8 @@ fn setup_logging() { .filter_module("sled", log::LevelFilter::Warn) .filter_module("tungstenite", log::LevelFilter::Warn) .filter_module("tokio_tungstenite", log::LevelFilter::Warn) + .filter_module("_", log::LevelFilter::Warn) + .filter_module("rocket::server", log::LevelFilter::Warn) .init(); } @@ -483,14 +485,11 @@ async fn run_validator_api(matches: ArgMatches<'static>) -> Result<()> { // if network monitor is disabled, we're not going to be sending any rewarding hence // we're not starting signing client if config.get_network_monitor_enabled() { - let rewarded_set_update_notify = Arc::new(Notify::new()); - let nymd_client = Client::new_signing(&config); let validator_cache_refresher = ValidatorCacheRefresher::new( nymd_client.clone(), config.get_caching_interval(), validator_cache.clone(), - Some(Arc::clone(&rewarded_set_update_notify)), ); // spawn our cacher @@ -502,13 +501,8 @@ async fn run_validator_api(matches: ArgMatches<'static>) -> Result<()> { let uptime_updater = HistoricalUptimeUpdater::new(storage.clone()); tokio::spawn(async move { uptime_updater.run().await }); - let mut rewarded_set_updater = RewardedSetUpdater::new( - nymd_client, - rewarded_set_update_notify, - validator_cache.clone(), - storage, - ) - .await?; + let mut rewarded_set_updater = + RewardedSetUpdater::new(nymd_client, validator_cache.clone(), storage).await?; // spawn rewarded set updater tokio::spawn(async move { rewarded_set_updater.run().await.unwrap() }); @@ -518,7 +512,6 @@ async fn run_validator_api(matches: ArgMatches<'static>) -> Result<()> { nymd_client, config.get_caching_interval(), validator_cache, - None, ); // spawn our cacher diff --git a/validator-api/src/network_monitor/monitor/mod.rs b/validator-api/src/network_monitor/monitor/mod.rs index efd034710c..f6fd3fe881 100644 --- a/validator-api/src/network_monitor/monitor/mod.rs +++ b/validator-api/src/network_monitor/monitor/mod.rs @@ -42,8 +42,6 @@ pub(super) struct Monitor { /// The minimum number of test routes that need to be constructed (and working) in order for /// a monitor test run to be valid. minimum_test_routes: usize, - min_mixnode_reliability: u8, - min_gateway_reliability: u8, } impl Monitor { @@ -68,8 +66,6 @@ impl Monitor { route_test_packets: config.get_route_test_packets(), test_routes: config.get_test_routes(), minimum_test_routes: config.get_minimum_test_routes(), - min_mixnode_reliability: config.get_min_mixnode_reliability(), - min_gateway_reliability: config.get_min_gateway_reliability(), } } @@ -78,35 +74,6 @@ impl Monitor { async fn submit_new_node_statuses(&mut self, test_summary: TestSummary) { // indicate our run has completed successfully and should be used in any future // uptime calculations - - for result in test_summary.mixnode_results.iter() { - if result.reliability < self.min_mixnode_reliability { - self.packet_preparer - .validator_cache() - .insert_mixnodes_blacklist(result.identity.clone()) - .await; - } else { - self.packet_preparer - .validator_cache() - .remove_mixnodes_blacklist(&result.identity) - .await; - } - } - - for result in test_summary.gateway_results.iter() { - if result.reliability < self.min_gateway_reliability { - self.packet_preparer - .validator_cache() - .insert_gateways_blacklist(result.identity.clone()) - .await; - } else { - self.packet_preparer - .validator_cache() - .remove_gateways_blacklist(&result.identity) - .await; - } - } - if let Err(err) = self .node_status_storage .insert_monitor_run_results( diff --git a/validator-api/src/network_monitor/monitor/preparer.rs b/validator-api/src/network_monitor/monitor/preparer.rs index 2169fc3cba..d67eb59629 100644 --- a/validator-api/src/network_monitor/monitor/preparer.rs +++ b/validator-api/src/network_monitor/monitor/preparer.rs @@ -151,10 +151,6 @@ impl PacketPreparer { } } - pub fn validator_cache(&mut self) -> &mut ValidatorCache { - &mut self.validator_cache - } - async fn wrap_test_packet( &mut self, packet: &TestPacket, diff --git a/validator-api/src/node_status_api/models.rs b/validator-api/src/node_status_api/models.rs index 27e348b229..2120e3158d 100644 --- a/validator-api/src/node_status_api/models.rs +++ b/validator-api/src/node_status_api/models.rs @@ -25,6 +25,15 @@ impl Uptime { Uptime(0) } + pub fn new(uptime: f32) -> Self { + if uptime > 100f32 { + error!("Got uptime {}, max is 100, returning 0", uptime); + Uptime(0) + } else { + Uptime(uptime as u8) + } + } + pub fn from_ratio(numerator: usize, denominator: usize) -> Result { if denominator == 0 { return Ok(Self::zero()); diff --git a/validator-api/src/node_status_api/routes.rs b/validator-api/src/node_status_api/routes.rs index 582b93ceb8..e43b84eae5 100644 --- a/validator-api/src/node_status_api/routes.rs +++ b/validator-api/src/node_status_api/routes.rs @@ -118,18 +118,16 @@ pub(crate) async fn get_mixnode_reward_estimation( ) -> Result, ErrorResponse> { let (bond, status) = cache.mixnode_details(&identity).await; if let Some(bond) = bond { - let interval_reward_params = cache.epoch_reward_params().await; - let as_at = interval_reward_params.timestamp(); - let interval_reward_params = interval_reward_params.into_inner(); + let reward_params = cache.epoch_reward_params().await; + let as_at = reward_params.timestamp(); + let reward_params = reward_params.into_inner(); let current_epoch = cache.current_epoch().await.into_inner(); + info!("{:?}", current_epoch); + let uptime = if let Some(epoch) = current_epoch { storage - .get_average_mixnode_uptime_in_interval( - &identity, - epoch.start_unix_timestamp(), - epoch.end_unix_timestamp(), - ) + .get_average_mixnode_uptime_in_the_last_24hrs(&identity, epoch.end_unix_timestamp()) .await .map_err(|err| ErrorResponse::new(err.to_string(), Status::NotFound))? } else { @@ -137,18 +135,8 @@ pub(crate) async fn get_mixnode_reward_estimation( }; let node_reward_params = NodeRewardParams::new(0, uptime.u8() as u128, status.is_active()); - let reward_params = RewardParams::new(interval_reward_params, node_reward_params); - let epoch_start = if let Some(epoch) = current_epoch { - epoch.start_unix_timestamp() - } else { - 0 - }; + let reward_params = RewardParams::new(reward_params, node_reward_params); - let epoch_end = if let Some(epoch) = current_epoch { - epoch.end_unix_timestamp() - } else { - 0 - }; match bond.estimate_reward(&reward_params) { Ok(( estimated_total_node_reward, @@ -159,9 +147,7 @@ pub(crate) async fn get_mixnode_reward_estimation( estimated_total_node_reward, estimated_operator_reward, estimated_delegators_reward, - current_interval_start: epoch_start, - current_interval_end: epoch_end, - current_interval_uptime: uptime.u8(), + reward_params, as_at, }; Ok(Json(reponse)) diff --git a/validator-api/src/nymd_client.rs b/validator-api/src/nymd_client.rs index 749ee16d41..4ede1a1f7c 100644 --- a/validator-api/src/nymd_client.rs +++ b/validator-api/src/nymd_client.rs @@ -8,7 +8,6 @@ use mixnet_contract_common::Interval; use mixnet_contract_common::{ reward_params::EpochRewardParams, ContractStateParams, Delegation, ExecuteMsg, GatewayBond, IdentityKey, MixNodeBond, MixnodeRewardingStatusResponse, RewardedSetNodeStatus, - RewardedSetUpdateDetails, }; use serde::Serialize; use std::sync::Arc; @@ -265,19 +264,6 @@ impl Client { .await } - pub(crate) async fn get_current_rewarded_set_update_details( - &self, - ) -> Result - where - C: CosmWasmClient + Sync, - { - self.0 - .read() - .await - .get_current_rewarded_set_update_details() - .await - } - #[allow(dead_code)] pub(crate) async fn advance_current_epoch(&self) -> Result<(), ValidatorClientError> where diff --git a/validator-api/src/rewarded_set_updater/mod.rs b/validator-api/src/rewarded_set_updater/mod.rs index 88a14ffc6a..daedfe5f3e 100644 --- a/validator-api/src/rewarded_set_updater/mod.rs +++ b/validator-api/src/rewarded_set_updater/mod.rs @@ -22,9 +22,9 @@ use mixnet_contract_common::{IdentityKey, Interval, MixNodeBond}; use rand::prelude::SliceRandom; use rand::rngs::OsRng; use std::collections::HashSet; -use std::sync::Arc; use std::time::Duration; -use tokio::sync::Notify; +use time::OffsetDateTime; +use tokio::time::sleep; use validator_client::nymd::{CosmosCoin, SigningNymdClient}; pub(crate) mod error; @@ -62,7 +62,6 @@ type Epoch = Interval; pub struct RewardedSetUpdater { nymd_client: Client, - update_rewarded_set_notify: Arc, validator_cache: ValidatorCache, storage: ValidatorApiStorage, } @@ -74,13 +73,11 @@ impl RewardedSetUpdater { pub(crate) async fn new( nymd_client: Client, - update_rewarded_set_notify: Arc, validator_cache: ValidatorCache, storage: ValidatorApiStorage, ) -> Result { Ok(RewardedSetUpdater { nymd_client, - update_rewarded_set_notify, validator_cache, storage, }) @@ -177,9 +174,8 @@ impl RewardedSetUpdater { for rewarded_node in rewarded_set.into_iter() { let uptime = self .storage - .get_average_mixnode_uptime_in_interval( + .get_average_mixnode_uptime_in_the_last_24hrs( rewarded_node.identity(), - epoch.start_unix_timestamp(), epoch.end_unix_timestamp(), ) .await?; @@ -200,7 +196,7 @@ impl RewardedSetUpdater { } // This is where the epoch gets advanced, and all epoch related transactions originate - async fn update_rewarded_set(&self) -> Result<(), RewardingError> { + async fn update(&self) -> Result<(), RewardingError> { let epoch = self.epoch().await?; log::info!("Starting rewarded set update"); // we know the entries are not stale, as a matter of fact they were JUST updated, since we got notified @@ -242,13 +238,93 @@ impl RewardedSetUpdater { Ok(()) } + async fn update_blacklist(&mut self, epoch: &Interval) -> Result<(), RewardingError> { + info!("Updating blacklist"); + + let mut mix_blacklist_add = HashSet::new(); + let mut mix_blacklist_remove = HashSet::new(); + let mut gate_blacklist_add = HashSet::new(); + let mut gate_blacklist_remove = HashSet::new(); + + let mixnodes = self + .storage + .get_all_avg_mix_reliability_in_last_24hr(epoch.end_unix_timestamp()) + .await?; + let gateways = self + .storage + .get_all_avg_gateway_reliability_in_last_24hr(epoch.end_unix_timestamp()) + .await?; + + // TODO: Make thresholds configurable + for mix in mixnodes { + if mix.value() <= 50.0 { + mix_blacklist_add.insert(mix.identity().to_string()); + } else { + mix_blacklist_remove.insert(mix.identity().to_string()); + } + } + + self.validator_cache + .update_mixnodes_blacklist(mix_blacklist_add, mix_blacklist_remove) + .await; + + for gateway in gateways { + if gateway.value() <= 50.0 { + gate_blacklist_add.insert(gateway.identity().to_string()); + } else { + gate_blacklist_remove.insert(gateway.identity().to_string()); + } + } + + self.validator_cache + .update_gateways_blacklist(gate_blacklist_add, gate_blacklist_remove) + .await; + + info!( + "Blacklisted mixnodes: {}", + self.validator_cache + .mixnodes_blacklist() + .await + .into_inner() + .len() + ); + info!( + "Blacklisted gateways: {}", + self.validator_cache + .gateways_blacklist() + .await + .into_inner() + .len() + ); + Ok(()) + } + pub(crate) async fn run(&mut self) -> Result<(), RewardingError> { self.validator_cache.wait_for_initial_values().await; loop { // wait until the cache refresher determined its time to update the rewarded/active sets - self.update_rewarded_set_notify.notified().await; - self.update_rewarded_set().await?; + let time = OffsetDateTime::now_utc().unix_timestamp(); + let epoch = self.epoch().await?; + let time_to_epoch_change = epoch.end_unix_timestamp() - time; + if time_to_epoch_change <= 0 { + self.update_blacklist(&epoch).await?; + log::info!( + "Time to epoch change is {}, updating rewarded set", + time_to_epoch_change + ); + self.update().await?; + } else { + log::info!( + "Waiting for epoch change, time to epoch change is {}", + time_to_epoch_change + ); + // Sleep at most 300 before checking again, to keep logs busy + let s = time_to_epoch_change.min(300).max(0) as u64; + sleep(Duration::from_secs(s)).await; + } + // allow some blocks to pass + sleep(Duration::from_secs(10)).await; } #[allow(unreachable_code)] Ok(()) diff --git a/validator-api/src/storage/manager.rs b/validator-api/src/storage/manager.rs index 5f08b98ccd..860b60a135 100644 --- a/validator-api/src/storage/manager.rs +++ b/validator-api/src/storage/manager.rs @@ -11,8 +11,97 @@ pub(crate) struct StorageManager { pub(crate) connection_pool: sqlx::SqlitePool, } +pub struct AvgReliability { + identity: String, + value: Option, +} + +impl AvgReliability { + pub fn identity(&self) -> &str { + &self.identity + } + + pub fn value(&self) -> f32 { + self.value.unwrap_or_default() + } +} + // all SQL goes here impl StorageManager { + pub(super) async fn get_all_avg_mix_reliability_in_last_24hr( + &self, + end_ts_secs: i64, + ) -> Result, sqlx::Error> { + let start_ts_secs = end_ts_secs - 86400; + self.get_all_avg_mix_reliability_in_interval(start_ts_secs, end_ts_secs) + .await + } + + pub(super) async fn get_all_avg_gateway_reliability_in_last_24hr( + &self, + end_ts_secs: i64, + ) -> Result, sqlx::Error> { + let start_ts_secs = end_ts_secs - 86400; + self.get_all_avg_gateway_reliability_in_interval(start_ts_secs, end_ts_secs) + .await + } + + pub(super) async fn get_all_avg_mix_reliability_in_interval( + &self, + start_ts_secs: i64, + end_ts_secs: i64, + ) -> Result, sqlx::Error> { + let result = sqlx::query_as!( + AvgReliability, + r#" + SELECT + d.identity as "identity: String", + AVG(s.reliability) as "value: f32" + FROM + mixnode_details d + JOIN + mixnode_status s on d.id = s.mixnode_details_id + WHERE + timestamp >= ? AND + timestamp <= ? + GROUP BY 1 + "#, + start_ts_secs, + end_ts_secs + ) + .fetch_all(&self.connection_pool) + .await?; + Ok(result) + } + + pub(super) async fn get_all_avg_gateway_reliability_in_interval( + &self, + start_ts_secs: i64, + end_ts_secs: i64, + ) -> Result, sqlx::Error> { + let result = sqlx::query_as!( + AvgReliability, + r#" + SELECT + d.identity as "identity: String", + AVG(reliability) as "value: f32" + FROM + gateway_details d + JOIN + gateway_status s on d.id = s.gateway_details_id + WHERE + timestamp >= ? AND + timestamp <= ? + GROUP BY 1 + "#, + start_ts_secs, + end_ts_secs + ) + .fetch_all(&self.connection_pool) + .await?; + Ok(result) + } + /// Tries to obtain row id of given mixnode given its identity. /// /// # Arguments @@ -247,6 +336,26 @@ impl StorageManager { .await } + pub(super) async fn get_average_reliability_in_interval( + &self, + id: i64, + start: i64, + end: i64, + ) -> Result, sqlx::Error> { + let result = sqlx::query!( + r#" + SELECT AVG(reliability) as "reliability: f32" FROM mixnode_status + WHERE mixnode_details_id= ? AND timestamp >= ? AND timestamp <= ? + "#, + id, + start, + end + ) + .fetch_one(&self.connection_pool) + .await?; + Ok(result.reliability) + } + /// Gets all reliability statuses for gateway with particular id that were inserted /// into the database within the specified time interval. /// diff --git a/validator-api/src/storage/mod.rs b/validator-api/src/storage/mod.rs index bda0d617ff..b3e514e33d 100644 --- a/validator-api/src/storage/mod.rs +++ b/validator-api/src/storage/mod.rs @@ -15,6 +15,8 @@ use sqlx::ConnectOptions; use std::path::PathBuf; use time::OffsetDateTime; +use self::manager::AvgReliability; + pub(crate) mod manager; pub(crate) mod models; @@ -68,6 +70,32 @@ impl ValidatorApiStorage { }) } + pub(crate) async fn get_all_avg_gateway_reliability_in_last_24hr( + &self, + end_ts_secs: i64, + ) -> Result, ValidatorApiStorageError> { + let result = self + .manager + .get_all_avg_gateway_reliability_in_last_24hr(end_ts_secs) + .await + .map_err(|e| ValidatorApiStorageError::InternalDatabaseError(format!("{}", e)))?; + + Ok(result) + } + + pub(crate) async fn get_all_avg_mix_reliability_in_last_24hr( + &self, + end_ts_secs: i64, + ) -> Result, ValidatorApiStorageError> { + let result = self + .manager + .get_all_avg_mix_reliability_in_last_24hr(end_ts_secs) + .await + .map_err(|e| ValidatorApiStorageError::InternalDatabaseError(format!("{}", e)))?; + + Ok(result) + } + /// Gets all statuses for particular mixnode that were inserted /// since the provided timestamp. /// @@ -261,6 +289,16 @@ impl ValidatorApiStorage { )) } + pub(crate) async fn get_average_mixnode_uptime_in_the_last_24hrs( + &self, + identity: &str, + end_ts_secs: i64, + ) -> Result { + let start = end_ts_secs - 86400; + self.get_average_mixnode_uptime_in_interval(identity, start, end_ts_secs) + .await + } + /// Based on the data available in the validator API, determines the average uptime of particular /// mixnode during the specified time interval. /// @@ -285,28 +323,17 @@ impl ValidatorApiStorage { None => return Ok(Uptime::zero()), }; - let monitor_runs = self.get_monitor_runs_count(start, end).await?; - let mixnode_statuses = self + let reliability = self .manager - .get_mixnode_statuses_by_id(mixnode_database_id, start, end) + .get_average_reliability_in_interval(mixnode_database_id, start, end) .await .map_err(|e| ValidatorApiStorageError::InternalDatabaseError(format!("{}", e)))?; - let mut total: f32 = 0.0; - for mixnode_status in mixnode_statuses { - total += mixnode_status.reliability() as f32; + if let Some(reliability) = reliability { + Ok(Uptime::new(reliability)) + } else { + Ok(Uptime::zero()) } - - let uptime = match Uptime::from_uptime_sum(total, monitor_runs) { - Ok(uptime) => uptime, - Err(_) => { - // this should really ever happen... - error!("mixnode {} has uptime > 100!", identity); - Uptime::default() - } - }; - - Ok(uptime) } /// Obtain status reports of mixnodes that were active in the specified time interval. diff --git a/validator-api/validator-api-requests/Cargo.toml b/validator-api/validator-api-requests/Cargo.toml index 84972360da..d39e479ca1 100644 --- a/validator-api/validator-api-requests/Cargo.toml +++ b/validator-api/validator-api-requests/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] serde = "1.0" +mixnet-contract-common = { path= ".../../../../common/cosmwasm-smart-contracts/mixnet-contract" } [dev-dependencies] ts-rs = "6.1.2" \ No newline at end of file diff --git a/validator-api/validator-api-requests/src/models.rs b/validator-api/validator-api-requests/src/models.rs index 0c5a650ad1..496fbd3514 100644 --- a/validator-api/validator-api-requests/src/models.rs +++ b/validator-api/validator-api-requests/src/models.rs @@ -1,6 +1,7 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use mixnet_contract_common::reward_params::RewardParams; use serde::{Deserialize, Serialize}; use std::fmt; @@ -52,22 +53,12 @@ pub struct MixnodeStatusResponse { } #[derive(Clone, Copy, Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(ts_rs::TS))] -#[cfg_attr( - test, - ts( - export, - export_to = "../../nym-wallet/src/types/rust/rewardestimationresponse.ts" - ) -)] pub struct RewardEstimationResponse { pub estimated_total_node_reward: u64, pub estimated_operator_reward: u64, pub estimated_delegators_reward: u64, - pub current_interval_start: i64, - pub current_interval_end: i64, - pub current_interval_uptime: u8, + pub reward_params: RewardParams, pub as_at: i64, }