Skip to content

Commit

Permalink
Automatically add local indexes to CyclesDispenser's allow list
Browse files Browse the repository at this point in the history
  • Loading branch information
hpeebles committed Dec 16, 2024
1 parent 2fb2b43 commit c0a6428
Show file tree
Hide file tree
Showing 16 changed files with 60 additions and 11 deletions.
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions backend/canisters/cycles_dispenser/impl/src/guards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@ pub fn caller_is_governance_principal() -> Result<(), String> {
Err("Caller is not a governance principal".to_string())
}
}

pub fn caller_is_authorized_to_add_canister() -> Result<(), String> {
if read_state(|state| state.is_caller_authorized_to_add_canister()) {
Ok(())
} else {
Err("Caller is not authorized to add a canister".to_string())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ async fn run_async(canister_id: CanisterId) {
// Add SNS canisters to the whitelist
mutate_state(|state| {
let now = state.env.now();
for canister_id in canisters.iter().flat_map(|c| c.canister_id) {
for canister_id in canisters.iter().filter_map(|s| s.canister_id) {
state.data.canisters_directly_controlled_by_sns_root.insert(canister_id);
state.data.canisters.add(canister_id, now);
}
});
Expand Down
11 changes: 10 additions & 1 deletion backend/canisters/cycles_dispenser/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ic_ledger_types::{BlockIndex, Tokens};
use ledger_utils::default_ledger_account;
use serde::{Deserialize, Serialize};
use std::cell::RefCell;
use std::collections::{BTreeMap, HashSet};
use std::collections::{BTreeMap, BTreeSet, HashSet};
use types::{BuildVersion, CanisterId, Cycles, Milliseconds, TimestampMillis, Timestamped};
use utils::env::Environment;

Expand Down Expand Up @@ -37,6 +37,12 @@ impl State {
self.data.governance_principals.contains(&self.env.caller())
}

pub fn is_caller_authorized_to_add_canister(&self) -> bool {
let caller = self.env.caller();
self.data.governance_principals.contains(&caller)
|| self.data.canisters_directly_controlled_by_sns_root.contains(&caller)
}

pub fn metrics(&self) -> Metrics {
Metrics {
heap_memory_used: utils::memory::heap(),
Expand Down Expand Up @@ -64,6 +70,8 @@ impl State {
struct Data {
pub governance_principals: HashSet<Principal>,
pub canisters: Canisters,
#[serde(default)]
pub canisters_directly_controlled_by_sns_root: BTreeSet<CanisterId>,
pub sns_root_canister: Option<CanisterId>,
pub max_top_up_amount: Cycles,
pub min_interval: Milliseconds,
Expand Down Expand Up @@ -93,6 +101,7 @@ impl Data {
Data {
governance_principals: governance_principals.into_iter().collect(),
canisters: Canisters::new(canisters, now),
canisters_directly_controlled_by_sns_root: BTreeSet::default(),
sns_root_canister: None,
max_top_up_amount,
min_interval,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::guards::caller_is_governance_principal;
use crate::guards::caller_is_authorized_to_add_canister;
use crate::{mutate_state, State};
use canister_api_macros::proposal;
use canister_tracing_macros::trace;
use cycles_dispenser_canister::add_canister::{Response::*, *};

#[proposal(guard = "caller_is_governance_principal")]
#[proposal(guard = "caller_is_authorized_to_add_canister")]
#[trace]
fn add_canister(args: Args) -> Response {
mutate_state(|state| add_canister_impl(args, state))
Expand Down
1 change: 1 addition & 0 deletions backend/canisters/group_index/impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ canister_tracing_macros = { path = "../../../libraries/canister_tracing_macros"
community_canister = { path = "../../community/api" }
community_canister_c2c_client = { path = "../../community/c2c_client" }
constants = { path = "../../../libraries/constants" }
cycles_dispenser_canister = { path = "../../cycles_dispenser/api" }
fire_and_forget_handler = { path = "../../../libraries/fire_and_forget_handler" }
futures = { workspace = true }
group_canister = { path = "../../group/api" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ fn prepare(args: &Args, state: &RuntimeState) -> Result<PrepareResult, Response>

fn commit(canister_id: CanisterId, wasm_version: BuildVersion, state: &mut RuntimeState) -> Response {
if state.data.local_index_map.add_index(canister_id, wasm_version) {
state.data.fire_and_forget_handler.send_candid(
state.data.cycles_dispenser_canister_id,
"add_canister",
cycles_dispenser_canister::add_canister::Args { canister_id },
);

Success
} else {
AlreadyAdded
Expand Down
2 changes: 2 additions & 0 deletions backend/canisters/notifications_index/impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ canister_logger = { path = "../../../libraries/canister_logger" }
canister_state_macros = { path = "../../../libraries/canister_state_macros" }
canister_tracing_macros = { path = "../../../libraries/canister_tracing_macros" }
constants = { path = "../../../libraries/constants" }
cycles_dispenser_canister = { path = "../../cycles_dispenser/api" }
fire_and_forget_handler = { path = "../../../libraries/fire_and_forget_handler" }
futures = { workspace = true }
http_request = { path = "../../../libraries/http_request" }
human_readable = { path = "../../../libraries/human_readable" }
Expand Down
4 changes: 4 additions & 0 deletions backend/canisters/notifications_index/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::model::notifications_canister::NotificationsCanister;
use crate::model::subscriptions::Subscriptions;
use candid::Principal;
use canister_state_macros::canister_state;
use fire_and_forget_handler::FireAndForgetHandler;
use notifications_index_canister::{NotificationsIndexEvent, SubscriptionAdded, SubscriptionRemoved};
use principal_to_user_id_map::PrincipalToUserIdMap;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -125,6 +126,8 @@ struct Data {
pub notifications_canister_wasm_for_upgrades: CanisterWasm,
pub canisters_requiring_upgrade: CanistersRequiringUpgrade,
pub notifications_index_event_sync_queue: CanisterEventSyncQueue<NotificationsIndexEvent>,
#[serde(default)]
pub fire_and_forget_handler: FireAndForgetHandler,
pub rng_seed: [u8; 32],
pub test_mode: bool,
}
Expand All @@ -150,6 +153,7 @@ impl Data {
notifications_canister_wasm_for_upgrades: notifications_canister_wasm,
canisters_requiring_upgrade: CanistersRequiringUpgrade::default(),
notifications_index_event_sync_queue: CanisterEventSyncQueue::default(),
fire_and_forget_handler: FireAndForgetHandler::default(),
rng_seed: [0; 32],
test_mode,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ fn commit(canister_id: CanisterId, wasm_version: BuildVersion, state: &mut Runti
);
}

state.data.fire_and_forget_handler.send_candid(
state.data.cycles_dispenser_canister_id,
"add_canister",
cycles_dispenser_canister::add_canister::Args { canister_id },
);

Success
} else {
AlreadyAdded
Expand Down
3 changes: 2 additions & 1 deletion backend/canisters/user_index/impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ chat_events = { path = "../../../libraries/chat_events" }
community_canister = { path = "../../community/api" }
community_canister_c2c_client = { path = "../../community/c2c_client" }
constants = { path = "../../../libraries/constants" }
cycles_dispenser_canister = { path = "../../cycles_dispenser/api" }
dataurl = { workspace = true }
event_store_producer = { workspace = true, features = ["json"] }
event_store_producer_cdk_runtime = { workspace = true }
fire_and_forget_handler = { path = "../../../libraries/fire_and_forget_handler" }
futures = { workspace = true }
group_canister = { path = "../../group/api" }
group_canister_c2c_client = { path = "../../group/c2c_client" }
fire_and_forget_handler = { path = "../../../libraries/fire_and_forget_handler" }
hex = { workspace = true }
http_request = { path = "../../../libraries/http_request" }
human_readable = { path = "../../../libraries/human_readable" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ fn commit(canister_id: CanisterId, wasm_version: BuildVersion, state: &mut Runti
}
crate::jobs::sync_events_to_local_user_index_canisters::try_run_now(state);

state.data.fire_and_forget_handler.send_candid(
state.data.cycles_dispenser_canister_id,
"add_canister",
cycles_dispenser_canister::add_canister::Args { canister_id },
);

Success
} else {
AlreadyAdded
Expand Down
3 changes: 0 additions & 3 deletions backend/integration_tests/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,6 @@ fn install_canisters(env: &mut PocketIc, controller: Principal) -> CanisterIds {
user_index_canister_id,
group_index_canister_id,
notifications_index_canister_id,
local_user_index_canister_id,
local_group_index_canister_id,
notifications_canister_id,
online_users_canister_id,
proposals_bot_canister_id,
storage_index_canister_id,
Expand Down
1 change: 1 addition & 0 deletions backend/libraries/fire_and_forget_handler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
candid = { workspace = true }
canister_client = { path = "../canister_client" }
canister_time = { path = "../canister_time" }
constants = { path = "../constants" }
Expand Down
5 changes: 5 additions & 0 deletions backend/libraries/fire_and_forget_handler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use candid::CandidType;
use canister_client::make_c2c_call_raw;
use constants::SECOND_IN_MS;
use ic_cdk_timers::TimerId;
Expand Down Expand Up @@ -34,6 +35,10 @@ impl FireAndForgetHandler {
ic_cdk::spawn(self.clone().process_single(call));
}

pub fn send_candid<A: CandidType>(&self, canister_id: CanisterId, method_name: impl Into<String>, args: A) {
self.send(canister_id, method_name, candid::encode_one(args).unwrap());
}

fn init(inner: FireAndForgetHandlerInner) -> Self {
let wrapped = Rc::new(Mutex::new(inner));
let handler = FireAndForgetHandler { inner: wrapped };
Expand Down
3 changes: 0 additions & 3 deletions backend/tools/canister_installer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,6 @@ async fn install_service_canisters_impl(
canister_ids.user_index,
canister_ids.group_index,
canister_ids.notifications_index,
canister_ids.local_user_index,
canister_ids.local_group_index,
canister_ids.notifications,
canister_ids.online_users,
canister_ids.proposals_bot,
canister_ids.storage_index,
Expand Down

0 comments on commit c0a6428

Please sign in to comment.