From d1703e7a041971232614dc1364d98e3838c20784 Mon Sep 17 00:00:00 2001 From: pietrodimarco-dfinity <124565147+pietrodimarco-dfinity@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:58:33 +0200 Subject: [PATCH] Fix cargo build for x86 (#724) --- Cargo.Bazel.lock | 97 ++++++++--- Cargo.lock | 16 +- Cargo.toml | 2 + bazel/external_crates.bzl | 1 + rs/cli/BUILD.bazel | 2 +- .../BUILD.bazel | 16 ++ .../trustworthy-node-metrics-types/Cargo.toml | 24 +++ .../trustworthy-node-metrics-types/src/lib.rs | 1 + .../src/types.rs | 150 ++++++++++++++++++ .../trustworthy-node-metrics.did | 48 ++++++ .../src/trustworthy-node-metrics/BUILD.bazel | 6 +- .../src/trustworthy-node-metrics/Cargo.toml | 7 +- .../src/trustworthy-node-metrics/src/lib.rs | 10 +- .../src/metrics_manager.rs | 10 +- .../src/rewards_manager.rs | 62 +------- .../src/stable_memory.rs | 23 +-- .../src/trustworthy-node-metrics/src/types.rs | 73 --------- rs/ic-canisters/BUILD.bazel | 2 +- rs/ic-canisters/Cargo.toml | 2 +- rs/ic-canisters/src/management.rs | 4 +- rs/ic-canisters/src/node_metrics.rs | 2 +- 21 files changed, 355 insertions(+), 203 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/BUILD.bazel create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/Cargo.toml create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/lib.rs create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/trustworthy-node-metrics.did delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index b83e395be..f3e421c78 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "bb01d0dcdf9c1fe555b6578fa02db9e22077f281f0c0585134761d5ad726a128", + "checksum": "56a1654ffcad2aab45a1a97a7e1bd2e8faf5986e1d11b824bfcd4039e0db3c31", "crates": { "actix-codec 0.5.2": { "name": "actix-codec", @@ -27897,29 +27897,35 @@ ], "crate_features": { "common": [ - "elf", - "errno", "general", "ioctl", "no_std" ], "selects": { "aarch64-unknown-linux-gnu": [ + "elf", + "errno", "prctl", "std", "system" ], "arm-unknown-linux-gnueabi": [ + "elf", + "errno", "prctl", "std", "system" ], "armv7-unknown-linux-gnueabi": [ + "elf", + "errno", "prctl", "std", "system" ], "i686-unknown-linux-gnu": [ + "elf", + "errno", "prctl", "std", "system" @@ -27935,6 +27941,8 @@ "system" ], "x86_64-unknown-linux-gnu": [ + "elf", + "errno", "prctl", "std", "system" @@ -44256,18 +44264,8 @@ "name": "trustworthy-node-metrics", "version": "0.5.0", "repository": null, - "targets": [ - { - "Library": { - "crate_name": "trustworthy_node_metrics", - "crate_root": "src/lib.rs", - "srcs": [ - "**/*.rs" - ] - } - } - ], - "library_target_name": "trustworthy_node_metrics", + "targets": [], + "library_target_name": null, "common_attrs": { "compile_data_glob": [ "**" @@ -44282,10 +44280,6 @@ "id": "candid 0.10.10", "target": "candid" }, - { - "id": "ciborium 0.2.2", - "target": "ciborium" - }, { "id": "dfn_core 0.9.0", "target": "dfn_core" @@ -44321,10 +44315,6 @@ { "id": "itertools 0.13.0", "target": "itertools" - }, - { - "id": "serde 1.0.206", - "target": "serde" } ], "selects": {} @@ -44343,6 +44333,64 @@ }, "license": null }, + "trustworthy-node-metrics-types 0.5.0": { + "name": "trustworthy-node-metrics-types", + "version": "0.5.0", + "repository": null, + "targets": [ + { + "Library": { + "crate_name": "trustworthy_node_metrics_types", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "trustworthy_node_metrics_types", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "candid 0.10.10", + "target": "candid" + }, + { + "id": "ciborium 0.2.2", + "target": "ciborium" + }, + { + "id": "dfn_core 0.9.0", + "target": "dfn_core" + }, + { + "id": "ic-management-canister-types 0.9.0", + "target": "ic_management_canister_types" + }, + { + "id": "ic-stable-structures 0.6.5", + "target": "ic_stable_structures" + }, + { + "id": "serde 1.0.206", + "target": "serde" + }, + { + "id": "serde_json 1.0.124", + "target": "serde_json" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.5.0" + }, + "license": null + }, "try-lock 0.2.5": { "name": "try-lock", "version": "0.2.5", @@ -48905,7 +48953,8 @@ "service-discovery 0.5.0": "rs/ic-observability/service-discovery", "slack-notifications 0.5.0": "rs/slack-notifications", "sns-downloader 0.5.0": "rs/ic-observability/sns-downloader", - "trustworthy-node-metrics 0.5.0": "rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics" + "trustworthy-node-metrics 0.5.0": "rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics", + "trustworthy-node-metrics-types 0.5.0": "rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types" }, "conditions": { "aarch64-apple-darwin": [ diff --git a/Cargo.lock b/Cargo.lock index c1f3f5c37..5482a8a9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3376,7 +3376,7 @@ dependencies = [ "sha2 0.10.8", "simple_asn1", "thiserror", - "trustworthy-node-metrics", + "trustworthy-node-metrics-types", "url", ] @@ -8817,7 +8817,6 @@ version = "0.5.0" dependencies = [ "anyhow", "candid", - "ciborium", "dfn_core", "futures", "ic-cdk 0.15.0", @@ -8828,7 +8827,20 @@ dependencies = [ "ic-protobuf", "ic-stable-structures", "itertools 0.13.0", + "trustworthy-node-metrics-types", +] + +[[package]] +name = "trustworthy-node-metrics-types" +version = "0.5.0" +dependencies = [ + "candid", + "ciborium", + "dfn_core", + "ic-management-canister-types", + "ic-stable-structures", "serde", + "serde_json", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3e5d83893..66a00502b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ members = [ "rs/rollout-controller", "rs/slack-notifications", "rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics", + "rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types", "rs/qualifier", ] @@ -76,6 +77,7 @@ csv = "1.3.0" custom_error = "1.9.2" decentralization = { path = "rs/decentralization" } trustworthy-node-metrics = { path = "rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics" } +trustworthy-node-metrics-types = { path = "rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types" } derive_builder = "0.20.0" derive_more = "1" dialoguer = "0.11.0" diff --git a/bazel/external_crates.bzl b/bazel/external_crates.bzl index f75da47e1..6a1a1bbfc 100644 --- a/bazel/external_crates.bzl +++ b/bazel/external_crates.bzl @@ -74,6 +74,7 @@ def external_crates_repository(): "//rs/slack-notifications:Cargo.toml", "//rs/rollout-controller:Cargo.toml", "//rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics:Cargo.toml", + "//rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types:Cargo.toml", "//rs/qualifier:Cargo.toml", ], splicing_config = splicing_config( diff --git a/rs/cli/BUILD.bazel b/rs/cli/BUILD.bazel index 859482719..2b8cf6040 100644 --- a/rs/cli/BUILD.bazel +++ b/rs/cli/BUILD.bazel @@ -7,7 +7,7 @@ DEPS = [ "//rs/decentralization", "//rs/ic-management-types", "//rs/ic-management-backend:ic-management-backend-lib", - "//rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics:trustworthy_node_metrics" + "//rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types:trustworthy_node_metrics_types" ] package(default_visibility = ["//visibility:public"]) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/BUILD.bazel b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/BUILD.bazel new file mode 100644 index 000000000..2ebabfd08 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/BUILD.bazel @@ -0,0 +1,16 @@ +load("@crate_index_dre//:defs.bzl", "aliases", "all_crate_deps") +load("@rules_rust//rust:defs.bzl", "rust_library") + +package(default_visibility = ["//visibility:public"]) + +rust_library( + name = "trustworthy_node_metrics_types", + srcs = glob(["src/**/*.rs"]), + aliases = aliases(), + proc_macro_deps = all_crate_deps( + proc_macro = True, + ), + deps = all_crate_deps( + normal = True, + ), +) \ No newline at end of file diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/Cargo.toml b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/Cargo.toml new file mode 100644 index 000000000..3e67b0003 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/Cargo.toml @@ -0,0 +1,24 @@ + +[package] +name = "trustworthy-node-metrics-types" +version.workspace = true +authors.workspace = true +edition.workspace = true +description.workspace = true +documentation.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["lib"] +name = "trustworthy_node_metrics_types" +path = "src/lib.rs" + +[dependencies] +candid = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +dfn_core = { workspace = true } +ic-management-canister-types = { workspace = true } +ciborium = { workspace = true } +ic-stable-structures = { workspace = true } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/lib.rs new file mode 100644 index 000000000..cd408564e --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/lib.rs @@ -0,0 +1 @@ +pub mod types; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs new file mode 100644 index 000000000..beb767589 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs @@ -0,0 +1,150 @@ +use std::borrow::Cow; + +use candid::{CandidType, Decode, Deserialize, Encode, Principal}; +use dfn_core::api::PrincipalId; +use ic_management_canister_types::NodeMetricsHistoryResponse; +use ic_stable_structures::{storable::Bound, Storable}; +use serde::Serialize; + +pub type SubnetNodeMetricsHistory = (PrincipalId, Vec); +pub type NodeMetricsGrouped = (u64, PrincipalId, ic_management_canister_types::NodeMetrics); + +// Stored in stable structure +pub type TimestampNanos = u64; +pub type NodeMetricsStoredKey = (TimestampNanos, Principal); +#[derive(Debug, Deserialize, Serialize, CandidType, Clone)] +pub struct NodeMetricsStored { + pub subnet_assigned: Principal, + pub num_blocks_proposed_total: u64, + pub num_blocks_failures_total: u64, + pub num_blocks_proposed: u64, + pub num_blocks_failed: u64, +} + +const MAX_VALUE_SIZE_BYTES: u32 = 102; + +impl Storable for NodeMetricsStored { + fn to_bytes(&self) -> std::borrow::Cow<[u8]> { + Cow::Owned(Encode!(self).unwrap()) + } + + fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Self { + Decode!(bytes.as_ref(), Self).unwrap() + } + + const BOUND: Bound = Bound::Bounded { + max_size: MAX_VALUE_SIZE_BYTES, + is_fixed_size: false, + }; +} + +// subnet_node_metrics query call +#[derive(Deserialize, CandidType)] +pub struct SubnetNodeMetricsArgs { + pub ts: Option, + pub subnet_id: Option, +} + +#[derive(Debug, Deserialize, Serialize, CandidType, Clone)] +pub struct NodeMetrics { + pub node_id: Principal, + pub num_blocks_proposed_total: u64, + pub num_blocks_failures_total: u64, +} + +#[derive(Debug, Deserialize, CandidType)] +pub struct SubnetNodeMetricsResponse { + pub ts: u64, + pub subnet_id: Principal, + pub node_metrics: Vec, +} + +// node_rewards query call +#[derive(Deserialize, CandidType)] +pub struct NodeRewardsArgs { + pub from_ts: u64, + pub to_ts: u64, +} + +#[derive(Debug, Clone, Deserialize, Serialize, CandidType)] +pub struct DailyNodeMetrics { + pub ts: u64, + pub subnet_assigned: Principal, + pub num_blocks_proposed: u64, + pub num_blocks_failed: u64, + + /// The failure rate of the node for the day, calculated as a ratio of + /// `num_blocks_failed` to `num_blocks_total` = `num_blocks_failed` + `num_blocks_proposed`. + /// This value ranges from 0.0 (no failures) to 1.0 (all blocks failed). + pub failure_rate: f64, + + /// The reduction in rewards for the node, determined by the failure rate. + /// This value is between 0.0 and 1.0, where 0.0 indicates no reduction + /// (full rewards) and 1.0 indicates a complete reduction (no rewards). + pub rewards_reduction: f64, +} + +const MIN_FAILURE_RATE: f64 = 0.1; +const MAX_FAILURE_RATE: f64 = 0.7; + +/// Calculates the daily rewards reduction based on the failure rate. +/// +/// # Arguments +/// +/// * `failure_rate` - A reference to a `f64` value representing the failure rate for the day. +/// +/// # Returns +/// +/// * A `f64` value representing the rewards reduction for the day, where: +/// - `0.0` indicates no reduction (failure rate below the minimum threshold), +/// - `1.0` indicates maximum reduction (failure rate above the maximum threshold), +/// - A value between `0.0` and `1.0` represents a proportional reduction based on the failure rate. +/// +/// # Explanation +/// +/// 1. The function checks if the provided `failure_rate` is below the `MIN_FAILURE_RATE` -> no reduction in rewards. +/// +/// 2. It then checks if the `failure_rate` is above the `MAX_FAILURE_RATE` -> maximum reduction in rewards. +/// +/// 3. If the `failure_rate` is within the defined range (`MIN_FAILURE_RATE` to `MAX_FAILURE_RATE`), +/// the function calculates the reduction proportionally: +/// - The reduction is calculated by normalizing the `failure_rate` within the range, resulting in a value between `0.0` and `1.0`. +fn daily_rewards_reduction(failure_rate: &f64) -> f64 { + if failure_rate < &MIN_FAILURE_RATE { + 0.0 + } else if failure_rate > &MAX_FAILURE_RATE { + 1.0 + } else { + (failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE) + } +} + +impl DailyNodeMetrics { + pub fn new(ts: TimestampNanos, subnet_assignment: Principal, proposed_blocks: u64, failed_blocks: u64) -> Self { + let total_blocks = failed_blocks + proposed_blocks; + let failure_rate = if total_blocks == 0 { + 0.0 + } else { + failed_blocks as f64 / total_blocks as f64 + }; + + let rewards_reduction = daily_rewards_reduction(&failure_rate); + + DailyNodeMetrics { + ts, + subnet_assigned: subnet_assignment, + num_blocks_proposed: proposed_blocks, + num_blocks_failed: failed_blocks, + failure_rate, + rewards_reduction, + } + } +} + +#[derive(Debug, Deserialize, CandidType)] +pub struct NodeRewardsResponse { + pub node_id: Principal, + pub rewards_no_penalty: f64, + pub rewards_with_penalty: f64, + pub daily_node_metrics: Vec, +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/trustworthy-node-metrics.did new file mode 100644 index 000000000..22c06ae39 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/trustworthy-node-metrics.did @@ -0,0 +1,48 @@ + +type NodeMetrics = record { + node_id: principal; + num_blocks_proposed_total: nat64; + num_blocks_failures_total: nat64; +}; + +type SubnetNodeMetricsResponse = record { + ts: nat64; + subnet_id: principal; + node_metrics: vec NodeMetrics; +}; + +type SubnetNodeMetricsResult = variant { + Ok : vec SubnetNodeMetricsResponse; + Err : text; +}; + +type SubnetNodeMetricsArgs = record { + subnet_id: opt principal; + ts: opt nat64; +}; + +type DailyNodeMetrics = record { + ts: nat64; + subnet_assigned: principal; + num_blocks_proposed: nat64; + num_blocks_failed: nat64; + failure_rate: float64; + rewards_reduction: float64; +}; + +type NodeRewardsResponse = record { + node_id: principal; + rewards_no_penalty: float64; + rewards_with_penalty: float64; + daily_node_metrics: vec DailyNodeMetrics; +}; + +type NodeRewardsArgs = record { + from_ts: nat64; + to_ts: nat64; +}; + +service : { + "subnet_node_metrics" : (SubnetNodeMetricsArgs) -> (SubnetNodeMetricsResult) query; + "node_rewards" : (NodeRewardsArgs) -> (vec NodeRewardsResponse) query; +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/BUILD.bazel b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/BUILD.bazel index 54894d6df..661b70902 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/BUILD.bazel +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/BUILD.bazel @@ -3,6 +3,10 @@ load("@rules_rust//rust:defs.bzl", "rust_library") package(default_visibility = ["//visibility:public"]) +DEPS = [ + "//rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types:trustworthy_node_metrics_types" +] + rust_library( name = "trustworthy_node_metrics", srcs = glob(["src/**/*.rs"]), @@ -12,5 +16,5 @@ rust_library( ), deps = all_crate_deps( normal = True, - ), + ) + DEPS, ) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml index 6ae42c669..612aae911 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml @@ -9,9 +9,7 @@ documentation.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] -crate-type = ["cdylib", "lib"] -name = "trustworthy_node_metrics" -path = "src/lib.rs" +crate-type = ["cdylib"] [dependencies] candid = { workspace = true } @@ -19,12 +17,11 @@ ic-cdk = { workspace = true } ic-cdk-timers = { workspace = true } ic-cdk-macros = { workspace = true } ic-stable-structures = { workspace = true } -serde = { workspace = true } itertools = { workspace = true } futures = { workspace = true } anyhow = { workspace = true } -ciborium = { workspace = true } ic-management-canister-types = { workspace = true } ic-protobuf = { workspace = true } ic-nns-common = { workspace = true } dfn_core = { workspace = true } +trustworthy-node-metrics-types = { workspace = true } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index 3ffc1bc49..f8437ea9a 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -2,13 +2,13 @@ use candid::Principal; use ic_cdk_macros::*; use itertools::Itertools; use std::collections::{self, btree_map::Entry, BTreeMap}; -use types::{ - DailyNodeMetrics, NodeMetrics, NodeMetricsStoredKey, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, SubnetNodeMetricsResponse, +use trustworthy_node_metrics_types::types::{ + DailyNodeMetrics, NodeMetrics, NodeMetricsStored, NodeMetricsStoredKey, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, + SubnetNodeMetricsResponse, }; mod metrics_manager; mod rewards_manager; mod stable_memory; -pub mod types; // Management canisters updates node metrics every day const TIMER_INTERVAL_SEC: u64 = 60 * 60 * 24; @@ -47,7 +47,7 @@ fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result> = BTreeMap::new(); - let node_metrics: Vec<(NodeMetricsStoredKey, types::NodeMetricsStored)> = stable_memory::get_metrics_range(from_ts, None); + let node_metrics: Vec<(NodeMetricsStoredKey, NodeMetricsStored)> = stable_memory::get_metrics_range(from_ts, None); for ((ts, node_id), node_metrics_value) in node_metrics { if let Some(subnet_id) = args.subnet_id { @@ -86,7 +86,7 @@ fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result Vec { let period_start = args.from_ts; let period_end = args.to_ts; - let node_metrics: Vec<(NodeMetricsStoredKey, types::NodeMetricsStored)> = stable_memory::get_metrics_range(period_start, Some(period_end)); + let node_metrics: Vec<(NodeMetricsStoredKey, NodeMetricsStored)> = stable_memory::get_metrics_range(period_start, Some(period_end)); let mut daily_metrics = collections::BTreeMap::new(); for ((ts, node_id), node_metrics_value) in node_metrics { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs index 1496e1442..d3bce3c94 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs @@ -5,13 +5,11 @@ use dfn_core::api::PrincipalId; use futures::FutureExt; use ic_management_canister_types::{NodeMetricsHistoryArgs, NodeMetricsHistoryResponse}; use ic_protobuf::registry::subnet::v1::SubnetListRecord; -use itertools::Itertools; -use crate::types::{NodeMetricsGrouped, NodeMetricsStored, NodeMetricsStoredKey}; -use crate::{ - stable_memory, - types::{SubnetNodeMetricsHistory, TimestampNanos}, -}; +use crate::stable_memory; +use itertools::Itertools; +use trustworthy_node_metrics_types::types::{NodeMetricsGrouped, NodeMetricsStored, NodeMetricsStoredKey}; +use trustworthy_node_metrics_types::types::{SubnetNodeMetricsHistory, TimestampNanos}; /// Node metrics storable /// diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs index 0688ebbb0..df8729ca7 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs @@ -1,63 +1,4 @@ -use candid::Principal; - -use crate::types::{DailyNodeMetrics, TimestampNanos}; - -const MIN_FAILURE_RATE: f64 = 0.1; -const MAX_FAILURE_RATE: f64 = 0.7; - -/// Calculates the daily rewards reduction based on the failure rate. -/// -/// # Arguments -/// -/// * `failure_rate` - A reference to a `f64` value representing the failure rate for the day. -/// -/// # Returns -/// -/// * A `f64` value representing the rewards reduction for the day, where: -/// - `0.0` indicates no reduction (failure rate below the minimum threshold), -/// - `1.0` indicates maximum reduction (failure rate above the maximum threshold), -/// - A value between `0.0` and `1.0` represents a proportional reduction based on the failure rate. -/// -/// # Explanation -/// -/// 1. The function checks if the provided `failure_rate` is below the `MIN_FAILURE_RATE` -> no reduction in rewards. -/// -/// 2. It then checks if the `failure_rate` is above the `MAX_FAILURE_RATE` -> maximum reduction in rewards. -/// -/// 3. If the `failure_rate` is within the defined range (`MIN_FAILURE_RATE` to `MAX_FAILURE_RATE`), -/// the function calculates the reduction proportionally: -/// - The reduction is calculated by normalizing the `failure_rate` within the range, resulting in a value between `0.0` and `1.0`. -fn daily_rewards_reduction(failure_rate: &f64) -> f64 { - if failure_rate < &MIN_FAILURE_RATE { - 0.0 - } else if failure_rate > &MAX_FAILURE_RATE { - 1.0 - } else { - (failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE) - } -} - -impl DailyNodeMetrics { - pub fn new(ts: TimestampNanos, subnet_assignment: Principal, proposed_blocks: u64, failed_blocks: u64) -> Self { - let total_blocks = failed_blocks + proposed_blocks; - let failure_rate = if total_blocks == 0 { - 0.0 - } else { - failed_blocks as f64 / total_blocks as f64 - }; - - let rewards_reduction = daily_rewards_reduction(&failure_rate); - - DailyNodeMetrics { - ts, - subnet_assigned: subnet_assignment, - num_blocks_proposed: proposed_blocks, - num_blocks_failed: failed_blocks, - failure_rate, - rewards_reduction, - } - } -} +use trustworthy_node_metrics_types::types::DailyNodeMetrics; /// Computes the rewards percentage based on the daily reward reductions WITH consecutive days penalty. /// @@ -144,6 +85,7 @@ pub fn rewards_no_penalty(daily_metrics: &[DailyNodeMetrics]) -> f64 { #[cfg(test)] mod tests { + use candid::Principal; use itertools::Itertools; use super::*; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index 377b47b51..98de71c69 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -1,33 +1,14 @@ -use candid::{Decode, Encode, Principal}; +use candid::Principal; use ic_stable_structures::memory_manager::{MemoryId, MemoryManager, VirtualMemory}; -use ic_stable_structures::{storable::Bound, Storable}; use ic_stable_structures::{DefaultMemoryImpl, StableBTreeMap}; use itertools::Itertools; -use std::borrow::Cow; use std::cell::RefCell; use std::collections::BTreeMap; -use crate::types::{NodeMetricsStored, NodeMetricsStoredKey, TimestampNanos}; +use trustworthy_node_metrics_types::types::{NodeMetricsStored, NodeMetricsStoredKey, TimestampNanos}; type Memory = VirtualMemory; -const MAX_VALUE_SIZE_BYTE: u32 = 102; - -impl Storable for NodeMetricsStored { - fn to_bytes(&self) -> std::borrow::Cow<[u8]> { - Cow::Owned(Encode!(self).unwrap()) - } - - fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Self { - Decode!(bytes.as_ref(), Self).unwrap() - } - - const BOUND: Bound = Bound::Bounded { - max_size: MAX_VALUE_SIZE_BYTE, - is_fixed_size: false, - }; -} - thread_local! { static MEMORY_MANAGER: RefCell> = diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs deleted file mode 100644 index fefcd9d04..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs +++ /dev/null @@ -1,73 +0,0 @@ -use candid::{CandidType, Deserialize, Principal}; -use dfn_core::api::PrincipalId; -use ic_management_canister_types::NodeMetricsHistoryResponse; -use serde::Serialize; - -pub type SubnetNodeMetricsHistory = (PrincipalId, Vec); -pub type NodeMetricsGrouped = (u64, PrincipalId, ic_management_canister_types::NodeMetrics); - -// Stored in stable structure -pub type TimestampNanos = u64; -pub type NodeMetricsStoredKey = (TimestampNanos, Principal); -#[derive(Debug, Deserialize, Serialize, CandidType, Clone)] -pub struct NodeMetricsStored { - pub subnet_assigned: Principal, - pub num_blocks_proposed_total: u64, - pub num_blocks_failures_total: u64, - pub num_blocks_proposed: u64, - pub num_blocks_failed: u64, -} - -// subnet_node_metrics query call -#[derive(Deserialize, CandidType)] -pub struct SubnetNodeMetricsArgs { - pub ts: Option, - pub subnet_id: Option, -} - -#[derive(Debug, Deserialize, Serialize, CandidType, Clone)] -pub struct NodeMetrics { - pub node_id: Principal, - pub num_blocks_proposed_total: u64, - pub num_blocks_failures_total: u64, -} - -#[derive(Debug, Deserialize, CandidType)] -pub struct SubnetNodeMetricsResponse { - pub ts: u64, - pub subnet_id: Principal, - pub node_metrics: Vec, -} - -// node_rewards query call -#[derive(Deserialize, CandidType)] -pub struct NodeRewardsArgs { - pub from_ts: u64, - pub to_ts: u64, -} - -#[derive(Debug, Clone, Deserialize, Serialize, CandidType)] -pub struct DailyNodeMetrics { - pub ts: u64, - pub subnet_assigned: Principal, - pub num_blocks_proposed: u64, - pub num_blocks_failed: u64, - - /// The failure rate of the node for the day, calculated as a ratio of - /// `num_blocks_failed` to `num_blocks_total` = `num_blocks_failed` + `num_blocks_proposed`. - /// This value ranges from 0.0 (no failures) to 1.0 (all blocks failed). - pub failure_rate: f64, - - /// The reduction in rewards for the node, determined by the failure rate. - /// This value is between 0.0 and 1.0, where 0.0 indicates no reduction - /// (full rewards) and 1.0 indicates a complete reduction (no rewards). - pub rewards_reduction: f64, -} - -#[derive(Debug, Deserialize, CandidType)] -pub struct NodeRewardsResponse { - pub node_id: Principal, - pub rewards_no_penalty: f64, - pub rewards_with_penalty: f64, - pub daily_node_metrics: Vec, -} diff --git a/rs/ic-canisters/BUILD.bazel b/rs/ic-canisters/BUILD.bazel index 28ec9d55b..92cf88520 100644 --- a/rs/ic-canisters/BUILD.bazel +++ b/rs/ic-canisters/BUILD.bazel @@ -4,7 +4,7 @@ load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") package(default_visibility = ["//visibility:public"]) DEPS = [ - "//rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics:trustworthy_node_metrics" + "//rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types:trustworthy_node_metrics_types" ] rust_library( diff --git a/rs/ic-canisters/Cargo.toml b/rs/ic-canisters/Cargo.toml index 3fa7e85a4..4f2856e06 100644 --- a/rs/ic-canisters/Cargo.toml +++ b/rs/ic-canisters/Cargo.toml @@ -33,5 +33,5 @@ simple_asn1 = { workspace = true } thiserror = { workspace = true } url = { workspace = true } ic-sns-wasm = { workspace = true } -trustworthy-node-metrics = { workspace = true } +trustworthy-node-metrics-types = { workspace = true } ic-transport-types = { workspace = true } diff --git a/rs/ic-canisters/src/management.rs b/rs/ic-canisters/src/management.rs index ab0d2f3c6..8c974c476 100644 --- a/rs/ic-canisters/src/management.rs +++ b/rs/ic-canisters/src/management.rs @@ -86,8 +86,8 @@ pub struct NodeMetrics { pub num_block_failures_total: u64, } -impl From for NodeMetrics { - fn from(value: trustworthy_node_metrics::types::NodeMetrics) -> Self { +impl From for NodeMetrics { + fn from(value: trustworthy_node_metrics_types::types::NodeMetrics) -> Self { Self { node_id: PrincipalId::from(value.node_id), num_block_failures_total: value.num_blocks_failures_total, diff --git a/rs/ic-canisters/src/node_metrics.rs b/rs/ic-canisters/src/node_metrics.rs index 69b415a1b..59fdf054f 100644 --- a/rs/ic-canisters/src/node_metrics.rs +++ b/rs/ic-canisters/src/node_metrics.rs @@ -4,7 +4,7 @@ use candid::{Decode, Encode}; use ic_agent::Agent; use ic_base_types::{CanisterId, PrincipalId}; use log::error; -use trustworthy_node_metrics::types::{SubnetNodeMetricsArgs, SubnetNodeMetricsResponse}; +use trustworthy_node_metrics_types::types::{SubnetNodeMetricsArgs, SubnetNodeMetricsResponse}; use crate::IcAgentCanisterClient;