Skip to content

Commit

Permalink
added method to allot empty canisters to individual user canisters
Browse files Browse the repository at this point in the history
  • Loading branch information
ravi-sawlani-yral committed Oct 11, 2024
1 parent b234455 commit 306a00a
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 8 deletions.
21 changes: 13 additions & 8 deletions src/canister/user_index/can.did
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ type RejectionCode = variant {
SysFatal;
CanisterReject;
};
type Result = variant { Ok : text; Err : text };
type Result_1 = variant { Ok : principal; Err : text };
type Result = variant { Ok : principal; Err : text };
type Result_1 = variant { Ok : text; Err : text };
type Result_2 = variant {
Ok : record { CanisterStatusResponse };
Err : record { RejectionCode; text };
Expand Down Expand Up @@ -117,8 +117,11 @@ type UserIndexInitArgs = record {
access_control_map : opt vec record { principal; vec UserAccessRole };
};
service : (UserIndexInitArgs) -> {
allot_empty_canister : () -> (Result);
are_signups_enabled : () -> (bool) query;
create_pool_of_individual_user_available_canisters : (text, blob) -> (Result);
create_pool_of_individual_user_available_canisters : (text, blob) -> (
Result_1,
);
get_current_list_of_all_well_known_principal_values : () -> (
vec record { KnownPrincipalType; principal },
) query;
Expand All @@ -127,7 +130,7 @@ service : (UserIndexInitArgs) -> {
get_last_broadcast_call_status : () -> (BroadcastCallStatus) query;
get_list_of_available_canisters : () -> (vec principal) query;
get_recycle_status : () -> (RecycleStatus) query;
get_requester_principals_canister_id_create_if_not_exists : () -> (Result_1);
get_requester_principals_canister_id_create_if_not_exists : () -> (Result);
get_requester_principals_canister_id_create_if_not_exists_and_optionally_allow_referrer : () -> (
principal,
);
Expand All @@ -149,15 +152,15 @@ service : (UserIndexInitArgs) -> {
opt principal,
) query;
http_request : (HttpRequest) -> (HttpResponse) query;
issue_rewards_for_referral : (principal, principal, principal) -> (Result);
issue_rewards_for_referral : (principal, principal, principal) -> (Result_1);
make_individual_canister_logs_private : (principal) -> (Result_3);
make_individual_canister_logs_public : (principal) -> (Result_3);
provision_empty_canisters : (nat64) -> ();
recharge_individual_user_canister : () -> (Result_3);
reclaim_cycles_from_individual_canisters : () -> ();
request_cycles : (nat) -> (Result_3);
reset_user_individual_canisters : (vec principal) -> (Result);
return_cycles_to_platform_orchestrator_canister : () -> (Result);
reset_user_individual_canisters : (vec principal) -> (Result_1);
return_cycles_to_platform_orchestrator_canister : () -> (Result_1);
set_permission_to_upgrade_individual_canisters : (bool) -> (text);
start_upgrades_for_individual_canisters : (text, blob) -> (text);
toggle_signups_enabled : () -> (Result_3);
Expand All @@ -174,5 +177,7 @@ service : (UserIndexInitArgs) -> {
opt principal,
opt CanisterInstallMode,
) -> (text);
validate_reset_user_individual_canisters : (vec principal) -> (Result) query;
validate_reset_user_individual_canisters : (vec principal) -> (
Result_1,
) query;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use candid::Principal;
use ic_cdk::caller;
use ic_cdk_macros::update;
use shared_utils::constant::{
get_backup_individual_user_canister_batch_size, get_backup_individual_user_canister_threshold,
};

use crate::{
util::{
canister_management::provision_number_of_empty_canisters,
types::individual_user_canister::IndividualUserCanister,
},
CANISTER_DATA,
};

#[update]
fn allot_empty_canister() -> Result<Principal, String> {
let registered_individual_canister = IndividualUserCanister::new(caller())?;
let result = registered_individual_canister.allot_empty_canister();

let backup_canister_count =
CANISTER_DATA.with_borrow(|canister_data| canister_data.backup_canister_pool.len() as u64);

if backup_canister_count < get_backup_individual_user_canister_threshold() {
let number_of_canisters = get_backup_individual_user_canister_batch_size();
let breaking_condition = || {
CANISTER_DATA.with_borrow_mut(|canister_data| {
canister_data.backup_canister_pool.len() as u64
> get_backup_individual_user_canister_batch_size()
})
};
ic_cdk::spawn(provision_number_of_empty_canisters(
number_of_canisters,
breaking_condition,
));
}

result
}
1 change: 1 addition & 0 deletions src/canister/user_index/src/api/canister_management/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use crate::{
CANISTER_DATA,
};

pub mod allot_empty_canister;
pub mod create_pool_of_available_canisters;
pub mod get_last_broadcast_call_status;
pub mod get_subnet_available_capacity;
Expand Down
13 changes: 13 additions & 0 deletions src/canister/user_index/src/util/types/individual_user_canister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,17 @@ impl IndividualUserCanister {
.await
.map_err(|e| e.1)
}

pub fn allot_empty_canister(&self) -> Result<Principal, String> {
CANISTER_DATA.with_borrow_mut(|canister_data| {
let Some(new_canister_id) = canister_data.backup_canister_pool.iter().next().copied()
else {
return Err("No Backup Canisters Available".into());
};

canister_data.backup_canister_pool.remove(&new_canister_id);

Ok(new_canister_id)
})
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod provision_new_available_and_backup_canister_on_signups_if_required;
pub mod recharge_individual_canister_when_requested;
pub mod test_allot_empty_canisters_to_individual_canister;
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use candid::Principal;
use pocket_ic::WasmResult;
use shared_utils::common::types::known_principal::KnownPrincipalType;
use test_utils::setup::{
env::pocket_ic_env::get_new_pocket_ic_env,
test_constants::{get_mock_user_alice_principal_id, get_mock_user_charlie_principal_id},
};

#[test]
fn test_allot_empty_canisters_to_individual_canister() {
let (pocket_ic, known_principal) = get_new_pocket_ic_env();
let platform_canister_id = known_principal
.get(&KnownPrincipalType::CanisterIdPlatformOrchestrator)
.cloned()
.unwrap();

let super_admin = known_principal
.get(&KnownPrincipalType::UserIdGlobalSuperAdmin)
.cloned()
.unwrap();

let application_subnets = pocket_ic.topology().get_app_subnets();

let charlie_global_admin = get_mock_user_charlie_principal_id();

pocket_ic
.update_call(
platform_canister_id,
super_admin,
"add_principal_as_global_admin",
candid::encode_one(charlie_global_admin).unwrap(),
)
.unwrap();

let subnet_orchestrator_canister_id: Principal = pocket_ic
.update_call(
platform_canister_id,
charlie_global_admin,
"provision_subnet_orchestrator_canister",
candid::encode_one(application_subnets[1]).unwrap(),
)
.map(|res| {
let canister_id_result: Result<Principal, String> = match res {
WasmResult::Reply(payload) => candid::decode_one(&payload).unwrap(),
_ => panic!("Canister call failed"),
};
canister_id_result.unwrap()
})
.unwrap();

for i in 0..120 {
pocket_ic.tick();
}

let alice_yral_principal_id = get_mock_user_alice_principal_id();
let alice_yral_canister_id = pocket_ic
.update_call(
subnet_orchestrator_canister_id,
alice_yral_principal_id,
"get_requester_principals_canister_id_create_if_not_exists",
candid::encode_one(()).unwrap(),
)
.map(|res| {
let canister_id: Result<Principal, String> = match res {
WasmResult::Reply(payload) => candid::decode_one(&payload).unwrap(),
_ => panic!("Canister call failed"),
};
canister_id
})
.unwrap()
.unwrap();

let mut intial_subnet_backup_capacity = pocket_ic
.query_call(
subnet_orchestrator_canister_id,
super_admin,
"get_subnet_backup_capacity",
candid::encode_one(()).unwrap(),
)
.map(|reply_payload| {
let subnet_capacity: u64 = match reply_payload {
WasmResult::Reply(payload) => candid::decode_one(&payload).unwrap(),
_ => panic!("\n🛑 get_subnet_backup_capacity failed\n"),
};
subnet_capacity
})
.unwrap();

for _ in 0..10 {
pocket_ic
.update_call(
subnet_orchestrator_canister_id,
alice_yral_canister_id,
"allot_empty_canister",
candid::encode_one(()).unwrap(),
)
.map(|res| {
let canister_id: Result<Principal, String> = match res {
WasmResult::Reply(payload) => candid::decode_one(&payload).unwrap(),
_ => panic!("Canister call failed"),
};
canister_id
})
.unwrap()
.unwrap();

intial_subnet_backup_capacity -= 1;
}

let final_backup_capacity = pocket_ic
.query_call(
subnet_orchestrator_canister_id,
super_admin,
"get_subnet_backup_capacity",
candid::encode_one(()).unwrap(),
)
.map(|reply_payload| {
let subnet_capacity: u64 = match reply_payload {
WasmResult::Reply(payload) => candid::decode_one(&payload).unwrap(),
_ => panic!("\n🛑 get_subnet_backup_capacity failed\n"),
};
subnet_capacity
})
.unwrap();

assert!(final_backup_capacity > intial_subnet_backup_capacity);
}

0 comments on commit 306a00a

Please sign in to comment.