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..89f4a7134 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,14 +161,29 @@ 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. 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()); + 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);