From 89df67d4609ae9508b2f73530f278fc8ecc27fb5 Mon Sep 17 00:00:00 2001 From: Manuel Amador Date: Thu, 8 May 2025 14:50:28 +0200 Subject: [PATCH 1/3] Instant synchronization feature. This is an optional feature!. --- Cargo.Bazel.lock | 2 +- .../canister/BUILD.bazel | 17 ++++++++++++++ .../node-provider-rewards/canister/Cargo.toml | 3 +++ .../node-provider-rewards/canister/src/lib.rs | 22 +++++++++++++++++-- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index fc6dccc3a..c13ad5118 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "93eb173474b738829386a93aa1c4fe928fa11cc79c0e225995cf6a3c621f2f5c", + "checksum": "5a594c10fdeada9c26d1d74018cd82f7bf918f006aa356d441cb390d5e5192f2", "crates": { "actix-codec 0.5.2": { "name": "actix-codec", diff --git a/rs/dre-canisters/node-provider-rewards/canister/BUILD.bazel b/rs/dre-canisters/node-provider-rewards/canister/BUILD.bazel index 2acad63b9..f066e405b 100644 --- a/rs/dre-canisters/node-provider-rewards/canister/BUILD.bazel +++ b/rs/dre-canisters/node-provider-rewards/canister/BUILD.bazel @@ -43,6 +43,23 @@ rust_library( ) + [":build_script"], ) +rust_library( + name = "node_provider_rewards_canister_instant_sync", + srcs = glob(["src/**/*.rs"]), + aliases = ALIASES, + crate_name = "node_provider_rewards_canister", + crate_features = [ + "instant-sync" + ], + proc_macro_deps = all_crate_deps( + proc_macro = True, + ), + version = "0.9.0", + deps = DEPS + all_crate_deps( + normal = True, + ) + [":build_script"], +) + rust_test( name = "npr_test", crate = ":node_provider_rewards_canister", diff --git a/rs/dre-canisters/node-provider-rewards/canister/Cargo.toml b/rs/dre-canisters/node-provider-rewards/canister/Cargo.toml index c6e8269a4..e85278c2e 100644 --- a/rs/dre-canisters/node-provider-rewards/canister/Cargo.toml +++ b/rs/dre-canisters/node-provider-rewards/canister/Cargo.toml @@ -7,6 +7,9 @@ description.workspace = true documentation.workspace = true license.workspace = true +[features] +instant-sync = [] + [lib] crate-type = ["cdylib"] diff --git a/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs b/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs index 7ac1d742d..bb60b5edc 100644 --- a/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs +++ b/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs @@ -1,7 +1,9 @@ use crate::storage::{METRICS_MANAGER, REGISTRY_STORE}; use candid::candid_method; use chrono::Months; -use chrono::{DateTime, Days, Duration, Timelike, Utc}; +use chrono::{DateTime, Timelike, Utc}; +#[cfg(not(feature = "instant-sync"))] +use chrono::{Days, Duration}; use ic_canisters_http_types::{HttpRequest, HttpResponse, HttpResponseBuilder}; use ic_cdk_macros::*; use ic_nervous_system_common::serve_metrics; @@ -11,6 +13,7 @@ use rewards_calculation::rewards_calculator::builder::RewardsCalculatorBuilder; use rewards_calculation::rewards_calculator::RewardsCalculator; use rewards_calculation::types::RewardPeriod; use std::collections::BTreeMap; +#[cfg(not(feature = "instant-sync"))] use std::ops::Add; use std::str::FromStr; @@ -108,6 +111,7 @@ fn get_n_months_rewards_period(now: Option>, months: u32) -> Rewar } } +#[cfg(not(feature = "instant-sync"))] /// Compute the duration left until either today or tomorrow at 1AM (whichever is earliest). fn time_left_for_next_1am(now: Option>) -> std::time::Duration { let really_now = now.unwrap_or(DateTime::from_timestamp_nanos(ic_cdk::api::time().try_into().unwrap())); @@ -157,7 +161,12 @@ fn setup_timers() { // I had to rewrite this to compute the correct remaining time until next 1AM. // It is simply not true that one can get a midnight from the modulo of seconds since // the UNIX epoch (as it was being done before). Leap seconds are a thing. - ic_cdk_timers::set_timer(time_left_for_next_1am(None), || { + #[cfg(not(feature = "instant-sync"))] + let next_1am = time_left_for_next_1am(None); + #[cfg(feature = "instant-sync")] + let next_1am = std::time::Duration::from_secs(2); + + ic_cdk_timers::set_timer(next_1am, || { // It's 1AM since the canister was installed or upgraded. // Schedule a repeat timer to run sync_all() every 24 hours. // Sadly we ignore leap seconds here. @@ -166,6 +175,15 @@ fn setup_timers() { // Spawn a sync_all() right now. ic_cdk::futures::spawn(sync_all()); + #[cfg(feature = "instant-sync")] + { + let in_15_seconds = std::time::Duration::from_secs(15); + ic_cdk_timers::set_timer(in_15_seconds, || measure_get_node_providers_rewards_query()); + for np in NODE_PROVIDERS_USED_DURING_CALCULATION_MEASUREMENT { + ic_cdk_timers::set_timer(in_15_seconds, || measure_get_node_provider_rewards_calculation_query(np)); + } + } + // Hourly timers after first sync. One for rewards query, and N for rewards calculation query. ic_cdk_timers::set_timer_interval(std::time::Duration::from_secs(HOUR_IN_SECONDS), measure_get_node_providers_rewards_query); for np in NODE_PROVIDERS_USED_DURING_CALCULATION_MEASUREMENT { From 100fbbea0db3eb8f8d37ec1214180f422cc79d19 Mon Sep 17 00:00:00 2001 From: Manuel Amador Date: Thu, 8 May 2025 14:58:00 +0200 Subject: [PATCH 2/3] Run measurments after sync. --- .../node-provider-rewards/canister/src/lib.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs b/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs index bb60b5edc..f0aed3b28 100644 --- a/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs +++ b/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs @@ -173,16 +173,17 @@ fn setup_timers() { ic_cdk_timers::set_timer_interval(std::time::Duration::from_secs(DAY_IN_SECONDS), || ic_cdk::futures::spawn(sync_all())); // Spawn a sync_all() right now. - ic_cdk::futures::spawn(sync_all()); - - #[cfg(feature = "instant-sync")] - { - let in_15_seconds = std::time::Duration::from_secs(15); - ic_cdk_timers::set_timer(in_15_seconds, || measure_get_node_providers_rewards_query()); - for np in NODE_PROVIDERS_USED_DURING_CALCULATION_MEASUREMENT { - ic_cdk_timers::set_timer(in_15_seconds, || measure_get_node_provider_rewards_calculation_query(np)); + ic_cdk::futures::spawn(async { + sync_all().await; + #[cfg(feature = "instant-sync")] + { + let in_1_second = std::time::Duration::from_secs(1); + ic_cdk_timers::set_timer(in_1_second, || measure_get_node_providers_rewards_query()); + for np in NODE_PROVIDERS_USED_DURING_CALCULATION_MEASUREMENT { + ic_cdk_timers::set_timer(in_1_second, || measure_get_node_provider_rewards_calculation_query(np)); + } } - } + }); // Hourly timers after first sync. One for rewards query, and N for rewards calculation query. ic_cdk_timers::set_timer_interval(std::time::Duration::from_secs(HOUR_IN_SECONDS), measure_get_node_providers_rewards_query); From ad8a6df6c42d69847892b9613cbdd4a61706c66a Mon Sep 17 00:00:00 2001 From: Manuel Amador Date: Thu, 8 May 2025 15:02:14 +0200 Subject: [PATCH 3/3] Clippy. --- rs/dre-canisters/node-provider-rewards/canister/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs b/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs index f0aed3b28..89f4a7134 100644 --- a/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs +++ b/rs/dre-canisters/node-provider-rewards/canister/src/lib.rs @@ -178,7 +178,7 @@ fn setup_timers() { #[cfg(feature = "instant-sync")] { let in_1_second = std::time::Duration::from_secs(1); - ic_cdk_timers::set_timer(in_1_second, || measure_get_node_providers_rewards_query()); + ic_cdk_timers::set_timer(in_1_second, measure_get_node_providers_rewards_query); for np in NODE_PROVIDERS_USED_DURING_CALCULATION_MEASUREMENT { ic_cdk_timers::set_timer(in_1_second, || measure_get_node_provider_rewards_calculation_query(np)); }