diff --git a/src/canister/individual_user_template/src/api/cdao/upgrade_creator_dao_governance_canisters.rs b/src/canister/individual_user_template/src/api/cdao/upgrade_creator_dao_governance_canisters.rs index 76f249bd..382a5c36 100644 --- a/src/canister/individual_user_template/src/api/cdao/upgrade_creator_dao_governance_canisters.rs +++ b/src/canister/individual_user_template/src/api/cdao/upgrade_creator_dao_governance_canisters.rs @@ -22,6 +22,7 @@ use shared_utils::{ SNS_TOKEN_INDEX_MODULE_HASH, SNS_TOKEN_LEDGER_MODULE_HASH, SNS_TOKEN_ROOT_MODULE_HASH, SNS_TOKEN_SWAP_MODULE_HASH, }, + types::sns_canisters::sns_governance::{self, GetRunningSnsVersionArg}, }; #[update(guard = "is_caller_controller_or_global_admin")] @@ -29,14 +30,13 @@ pub async fn upgrade_creator_dao_governance_canisters(wasm_module: Vec) -> R notify_to_recharge_canister(); let mut res: Result<(), String>; - let governance_canisters: Vec = - CANISTER_DATA.with_borrow_mut(|canister_data| { - canister_data - .cdao_canisters - .iter() - .map(|canisters| canisters.governance) - .collect() - }); + let governance_canisters: Vec = CANISTER_DATA.with_borrow(|canister_data| { + canister_data + .cdao_canisters + .iter() + .map(|canisters| canisters.governance) + .collect() + }); let recharge_amount = 100_000_000_000; //100B @@ -89,6 +89,17 @@ async fn recharge_and_upgrade_canister( .await .map_err(|e| e.1)?; + let sns_governance = sns_governance::Service(canister_id); + + let (sns_running_version,) = sns_governance + .get_running_sns_version(GetRunningSnsVersionArg {}) + .await + .map_err(|e| e.1)?; + + if sns_running_version.deployed_version.is_some() { + return Ok(()); + } + let gov_hash = hex::decode(SNS_TOKEN_GOVERNANCE_MODULE_HASH).unwrap(); let ledger_hash = hex::decode(SNS_TOKEN_LEDGER_MODULE_HASH).unwrap(); let root_hash = hex::decode(SNS_TOKEN_ROOT_MODULE_HASH).unwrap(); diff --git a/src/canister/platform_orchestrator/can.did b/src/canister/platform_orchestrator/can.did index e1dc8016..70e37978 100644 --- a/src/canister/platform_orchestrator/can.did +++ b/src/canister/platform_orchestrator/can.did @@ -105,9 +105,6 @@ service : (PlatformOrchestratorInitArgs) -> { make_individual_canister_logs_public : (principal) -> (Result); make_subnet_orchestrator_logs_private : (principal) -> (Result); make_subnet_orchestrator_logs_public : (principal) -> (Result); - notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters : ( - blob, - ) -> (Result); notify_specific_individual_canister_to_upgrade_creator_dao_governance_canisters : ( principal, blob, @@ -146,6 +143,7 @@ service : (PlatformOrchestratorInitArgs) -> { KnownPrincipalType, principal, ) -> (Result_1); + upgrade_all_creator_dao_governance_canisters_in_the_network : (blob) -> (); upgrade_canisters_in_network : (UpgradeCanisterArg) -> (Result_1); upgrade_individual_canisters_in_a_subnet_with_latest_wasm : (principal) -> ( Result, diff --git a/src/canister/platform_orchestrator/src/api/canister_management/mod.rs b/src/canister/platform_orchestrator/src/api/canister_management/mod.rs index 79cb22f8..5da1adbd 100644 --- a/src/canister/platform_orchestrator/src/api/canister_management/mod.rs +++ b/src/canister/platform_orchestrator/src/api/canister_management/mod.rs @@ -12,7 +12,6 @@ mod get_subnets_upgrade_status_report; mod global_admin; mod known_principal; pub mod logging; -pub mod notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters; pub mod notify_specific_individual_canister_to_upgrade_creator_dao_governance_canisters; mod populate_known_principal_for_all_subnet; pub mod provision_empty_canisters_in_a_subnet; @@ -30,6 +29,7 @@ mod subnet_orchestrator_maxed_out; mod update_canisters_last_access_time; mod update_profile_owner_for_individual_users; pub mod update_timers_for_hon_game; +pub mod upgrade_all_creator_dao_governance_canisters_in_the_network; pub mod upgrade_canisters_in_network; mod upgrade_individual_canisters_in_a_subnet_with_latest_wasm; mod upgrade_specific_individual_canister; diff --git a/src/canister/platform_orchestrator/src/api/canister_management/notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters.rs b/src/canister/platform_orchestrator/src/api/canister_management/notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters.rs deleted file mode 100644 index 4849934c..00000000 --- a/src/canister/platform_orchestrator/src/api/canister_management/notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters.rs +++ /dev/null @@ -1,23 +0,0 @@ -use ic_cdk_macros::update; - -use crate::{guard::is_caller::is_caller_global_admin_or_controller, CANISTER_DATA}; - -#[update(guard = "is_caller_global_admin_or_controller")] -pub fn notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters( - wasm_module: Vec, -) -> Result<(), String> { - CANISTER_DATA.with_borrow(|canister_data| { - let subnet_orchestrators = canister_data.all_subnet_orchestrator_canisters_list.iter(); - - for canister_id in subnet_orchestrators { - ic_cdk::notify::<_>( - *canister_id, - "notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters", - (wasm_module.clone(),), - ) - .map_err(|e| format!("Error: {:?}", e))?; - } - - Ok(()) - }) -} diff --git a/src/canister/platform_orchestrator/src/api/canister_management/upgrade_all_creator_dao_governance_canisters_in_the_network.rs b/src/canister/platform_orchestrator/src/api/canister_management/upgrade_all_creator_dao_governance_canisters_in_the_network.rs new file mode 100644 index 00000000..438e69ce --- /dev/null +++ b/src/canister/platform_orchestrator/src/api/canister_management/upgrade_all_creator_dao_governance_canisters_in_the_network.rs @@ -0,0 +1,37 @@ +use ic_cdk_macros::update; +use shared_utils::common::{types::wasm, utils::task::run_task_concurrently}; + +use crate::{guard::is_caller::is_caller_global_admin_or_controller, CANISTER_DATA}; + +#[update(guard = "is_caller_global_admin_or_controller")] +pub fn upgrade_all_creator_dao_governance_canisters_in_the_network(wasm_module: Vec) { + let subnet_orchestrators = CANISTER_DATA + .with_borrow(|canister_data| canister_data.all_subnet_orchestrator_canisters_list.clone()); + + let upgrade_governance_canister_tasks = + subnet_orchestrators + .into_iter() + .map(move |subnet_orchestrator| { + let wasm = wasm_module.clone(); + async move { + ic_cdk::call::<_, ()>( + subnet_orchestrator, + "upgrade_all_creator_dao_governance_canisters_in_the_network", + (wasm,), + ) + .await + .map_err(|e| e.1) + } + }); + + ic_cdk::spawn(run_task_concurrently( + upgrade_governance_canister_tasks, + 10, + |result| { + if let Err(e) = result { + ic_cdk::println!("Error upgrading governance canister in the subnet. {}", e); + } + }, + || false, + )); +} diff --git a/src/canister/user_index/can.did b/src/canister/user_index/can.did index ae332206..994a29f8 100644 --- a/src/canister/user_index/can.did +++ b/src/canister/user_index/can.did @@ -168,9 +168,6 @@ service : (UserIndexInitArgs) -> { issue_rewards_for_referral : (principal, principal, principal) -> (Result_2); make_individual_canister_logs_private : (principal) -> (Result_3); make_individual_canister_logs_public : (principal) -> (Result_3); - notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters : ( - blob, - ) -> (Result_3); notify_specific_individual_canister_to_upgrade_creator_dao_governance_canisters : ( principal, blob, @@ -199,6 +196,7 @@ service : (UserIndexInitArgs) -> { update_profile_owner_for_individual_canisters : () -> (); update_restart_timers_hon_game : () -> (text); update_well_known_principal : (KnownPrincipalType, principal) -> (); + upgrade_all_creator_dao_governance_canisters_in_the_network : (blob) -> (); upgrade_specific_individual_user_canister_with_latest_wasm : ( principal, opt principal, diff --git a/src/canister/user_index/src/api/canister_management/mod.rs b/src/canister/user_index/src/api/canister_management/mod.rs index ee56b333..7e706e99 100644 --- a/src/canister/user_index/src/api/canister_management/mod.rs +++ b/src/canister/user_index/src/api/canister_management/mod.rs @@ -39,7 +39,6 @@ pub mod get_subnet_available_capacity; pub mod get_subnet_backup_capacity; pub mod make_individual_canister_logs_private; pub mod make_individual_canister_logs_public; -pub mod notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters; pub mod notify_specific_individual_canister_to_upgrade_creator_dao_governance_canisters; pub mod provision_empty_canisters; pub mod receive_empty_canister_from_individual_canister; @@ -50,6 +49,7 @@ pub mod reset_user_canister_ml_feed_cache; pub mod start_upgrades_for_individual_canisters; pub mod update_canisters_access_time; pub mod update_user_canister_restart_timers; +pub mod upgrade_all_creator_dao_governance_canisters_in_the_network; #[update] pub async fn get_user_canister_status( diff --git a/src/canister/user_index/src/api/canister_management/notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters.rs b/src/canister/user_index/src/api/canister_management/notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters.rs deleted file mode 100644 index e17a1060..00000000 --- a/src/canister/user_index/src/api/canister_management/notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters.rs +++ /dev/null @@ -1,25 +0,0 @@ -use candid::Principal; -use ic_cdk_macros::update; -use shared_utils::common::utils::permissions::is_caller_controller_or_global_admin; - -use crate::CANISTER_DATA; - -#[update(guard = "is_caller_controller_or_global_admin")] -pub fn notify_all_individual_canisters_to_upgrade_creator_dao_governance_canisters( - wasm_module: Vec, -) -> Result<(), String> { - CANISTER_DATA.with_borrow(|canister_data| { - let individual_canisters = canister_data.user_principal_id_to_canister_id_map.iter(); - - for (_, canister_id) in individual_canisters { - ic_cdk::notify::<_>( - *canister_id, - "upgrade_creator_dao_governance_canisters", - (wasm_module.clone(),), - ) - .map_err(|e| format!("Error: {:?}", e))?; - } - - Ok(()) - }) -} diff --git a/src/canister/user_index/src/api/canister_management/upgrade_all_creator_dao_governance_canisters_in_the_network.rs b/src/canister/user_index/src/api/canister_management/upgrade_all_creator_dao_governance_canisters_in_the_network.rs new file mode 100644 index 00000000..bb3cef2c --- /dev/null +++ b/src/canister/user_index/src/api/canister_management/upgrade_all_creator_dao_governance_canisters_in_the_network.rs @@ -0,0 +1,44 @@ +use candid::Principal; +use ic_cdk_macros::update; +use shared_utils::common::utils::{ + permissions::is_caller_controller_or_global_admin, task::run_task_concurrently, +}; + +use crate::CANISTER_DATA; + +#[update(guard = "is_caller_controller_or_global_admin")] +pub fn upgrade_all_creator_dao_governance_canisters_in_the_network(wasm_module: Vec) { + let individual_canisters: Vec = CANISTER_DATA.with_borrow(|canister_data| { + canister_data + .user_principal_id_to_canister_id_map + .values() + .cloned() + .collect() + }); + + let upgrade_governance_canister_tasks = + individual_canisters.into_iter().map(move |canister_id| { + let wasm = wasm_module.clone(); + async move { + ic_cdk::call::<_, (Result<(), String>,)>( + canister_id, + "upgrade_creator_dao_governance_canisters", + (wasm,), + ) + .await + .map_err(|e| format!("Error: {:?}", e))? + .0 + } + }); + + ic_cdk::spawn(run_task_concurrently( + upgrade_governance_canister_tasks, + 10, + |result| { + if let Err(e) = result { + ic_cdk::println!("Error upgrading governance canister. Error: {}", e); + } + }, + || false, + )); +} diff --git a/src/canister/user_index/src/api/user_record/get_requester_principals_canister_id_create_if_not_exists_and_optionally_allow_referrer.rs b/src/canister/user_index/src/api/user_record/get_requester_principals_canister_id_create_if_not_exists_and_optionally_allow_referrer.rs index 81710b81..43f26e20 100644 --- a/src/canister/user_index/src/api/user_record/get_requester_principals_canister_id_create_if_not_exists_and_optionally_allow_referrer.rs +++ b/src/canister/user_index/src/api/user_record/get_requester_principals_canister_id_create_if_not_exists_and_optionally_allow_referrer.rs @@ -197,37 +197,37 @@ async fn provision_new_available_canisters(individual_user_template_canister_was CANISTER_DATA.with_borrow(|canister_data| canister_data.available_canisters.len() as u64); let max_canister_count = available_canister_count + canister_count; - let install_canister_wasm_futures = CANISTER_DATA.with_borrow(|canister_data| { - let mut backup_pool_canister = canister_data.backup_canister_pool.clone().into_iter(); - (0..canister_count).map(move |_| { - let individual_user_template_canister_wasm_version = - individual_user_template_canister_wasm.version.clone(); + let mut backup_pool_canister = CANISTER_DATA + .with_borrow(|canister_data| canister_data.backup_canister_pool.clone()) + .into_iter(); - let individual_user_template_canister_wasm = - individual_user_template_canister_wasm.wasm_blob.clone(); + let install_canister_wasm_futures = (0..canister_count).map(move |_| { + let individual_user_template_canister_wasm_version = + individual_user_template_canister_wasm.version.clone(); - let canister_id = backup_pool_canister.next().unwrap(); + let individual_user_template_canister_wasm = + individual_user_template_canister_wasm.wasm_blob.clone(); - // Remove the canister id from backup pool so no one else access it - CANISTER_DATA.with_borrow_mut(|canister_data| { - canister_data.backup_canister_pool.remove(&canister_id) - }); + let canister_id = backup_pool_canister.next().unwrap(); - async move { - let _ = check_and_request_cycles_from_platform_orchestrator().await; - //recharge backup canister if required - recharge_canister_for_installing_wasm(canister_id) - .await - .map_err(|e| (canister_id, e))?; - install_canister_wasm( - canister_id, - None, - individual_user_template_canister_wasm_version, - individual_user_template_canister_wasm, - ) + CANISTER_DATA.with_borrow_mut(|canister_data| { + canister_data.backup_canister_pool.remove(&canister_id) + }); + + async move { + let _ = check_and_request_cycles_from_platform_orchestrator().await; + //recharge backup canister if required + recharge_canister_for_installing_wasm(canister_id) .await - } - }) + .map_err(|e| (canister_id, e))?; + install_canister_wasm( + canister_id, + None, + individual_user_template_canister_wasm_version, + individual_user_template_canister_wasm, + ) + .await + } }); let result_callback = |install_canister_wasm_result: Result| { diff --git a/src/lib/integration_tests/tests/creator_dao/main.rs b/src/lib/integration_tests/tests/creator_dao/main.rs index 1b5ee702..96a51517 100644 --- a/src/lib/integration_tests/tests/creator_dao/main.rs +++ b/src/lib/integration_tests/tests/creator_dao/main.rs @@ -1,3 +1,4 @@ +pub mod test_custom_governance_upgrade; pub mod test_deletion_of_creator_tokens; pub mod test_number_of_creator_tokens; pub mod types; diff --git a/src/lib/integration_tests/tests/creator_dao/test_custom_governance_upgrade.rs b/src/lib/integration_tests/tests/creator_dao/test_custom_governance_upgrade.rs new file mode 100644 index 00000000..5b6c9a25 --- /dev/null +++ b/src/lib/integration_tests/tests/creator_dao/test_custom_governance_upgrade.rs @@ -0,0 +1,138 @@ +use candid::Principal; +use hex::ToHex; +use ic_cdk::println; +use pocket_ic::WasmResult; +use shared_utils::{ + common::types::known_principal::KnownPrincipalType, + constant::{SNS_TOKEN_GOVERNANCE_MODULE_HASH, SNS_WASM_W_PRINCIPAL_ID}, +}; +use test_utils::setup::{ + env::pocket_ic_env::get_new_pocket_ic_env, + test_constants::{ + get_global_super_admin_principal_id, get_mock_user_alice_principal_id, + get_mock_user_charlie_principal_id, + }, +}; + +use crate::{ + utils::{setup_default_sns_creator_token, setup_sns_w_canister_for_creator_dao}, + Wasm, +}; + +#[test] +pub fn test_skip_upgrading_creator_sns_governance_canister_if_version_is_present() { + let (pocket_ic, known_principal) = get_new_pocket_ic_env(); + let platform_canister_id = known_principal + .get(&KnownPrincipalType::CanisterIdPlatformOrchestrator) + .cloned() + .unwrap(); + + let super_admin = get_global_super_admin_principal_id(); + + 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(); + + pocket_ic + .update_call( + platform_canister_id, + super_admin, + "update_global_known_principal", + candid::encode_args(( + KnownPrincipalType::CanisterIdSnsWasm, + Principal::from_text(SNS_WASM_W_PRINCIPAL_ID).unwrap(), + )) + .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 = match res { + WasmResult::Reply(payload) => candid::decode_one(&payload).unwrap(), + _ => panic!("Canister call failed"), + }; + canister_id_result.unwrap() + }) + .unwrap(); + + for i in 0..50 { + pocket_ic.tick(); + } + + let alice_principal = get_mock_user_alice_principal_id(); + let alice_canister_id: Principal = pocket_ic + .update_call( + subnet_orchestrator_canister_id, + alice_principal, + "get_requester_principals_canister_id_create_if_not_exists", + candid::encode_one(()).unwrap(), + ) + .map(|reply_payload| { + let response: Result = match reply_payload { + WasmResult::Reply(payload) => candid::decode_one(&payload).unwrap(), + _ => panic!("\nšŸ›‘ get requester principals canister id failed\n"), + }; + response + }) + .unwrap() + .unwrap(); + + let alice_initial_cycle_balance = pocket_ic.cycle_balance(alice_canister_id); + let sns_wasm_w_canister_id = Principal::from_text(SNS_WASM_W_PRINCIPAL_ID).unwrap(); + + setup_sns_w_canister_for_creator_dao(&pocket_ic, super_admin); + + let deployed_canister = setup_default_sns_creator_token( + &pocket_ic, + super_admin, + alice_principal, + alice_canister_id, + ); + let custom_governance_wasm = + include_bytes!("../../../../../wasms/custom-governance-canister.wasm.gz"); + + pocket_ic + .update_call( + platform_canister_id, + super_admin, + "upgrade_all_creator_dao_governance_canisters_in_the_network", + candid::encode_one(custom_governance_wasm).unwrap(), + ) + .unwrap(); + + for _ in 0..110 { + pocket_ic.tick(); + } + + let governance_canister_status = pocket_ic + .canister_status(deployed_canister.governance, Some(alice_canister_id)) + .unwrap(); + + let governance_canister_module_hash = governance_canister_status + .module_hash + .unwrap() + .encode_hex::(); + + println!( + "Custom governance canister module hash {}", + &governance_canister_module_hash + ); + + assert!(governance_canister_module_hash.eq(&SNS_TOKEN_GOVERNANCE_MODULE_HASH.to_owned())); +} diff --git a/src/lib/integration_tests/tests/subnet_orchestrator/provision_new_available_and_backup_canister_on_signups_if_required.rs b/src/lib/integration_tests/tests/subnet_orchestrator/provision_new_available_and_backup_canister_on_signups_if_required.rs index 8b7f4481..73f64e6a 100644 --- a/src/lib/integration_tests/tests/subnet_orchestrator/provision_new_available_and_backup_canister_on_signups_if_required.rs +++ b/src/lib/integration_tests/tests/subnet_orchestrator/provision_new_available_and_backup_canister_on_signups_if_required.rs @@ -11,7 +11,6 @@ use test_utils::setup::{ env::pocket_ic_env::get_new_pocket_ic_env, test_constants::get_mock_user_charlie_principal_id, }; -#[ignore = "we are not provisioning new backup canisters anymore"] #[test] pub fn provision_new_available_and_backup_canisters_on_signup_if_required() { let (pocket_ic, known_principal) = get_new_pocket_ic_env(); @@ -165,22 +164,4 @@ pub fn provision_new_available_and_backup_canisters_on_signup_if_required() { .unwrap(); assert!(subnet_available_canister_cnt > 0); - - let subnet_backup_canister_cnt = pocket_ic - .query_call( - subnet_orchestrator_canister_id, - Principal::anonymous(), - "get_subnet_backup_capacity", - candid::encode_one(()).unwrap(), - ) - .map(|res| { - let available_capacity: u64 = match res { - WasmResult::Reply(payload) => candid::decode_one(&payload).unwrap(), - _ => panic!("get subnet available capacity call failed"), - }; - available_capacity - }) - .unwrap(); - - assert!(subnet_backup_canister_cnt > 0); } diff --git a/src/lib/shared_utils/src/types/sns_canisters/mod.rs b/src/lib/shared_utils/src/types/sns_canisters/mod.rs index 2e82136b..37437878 100644 --- a/src/lib/shared_utils/src/types/sns_canisters/mod.rs +++ b/src/lib/shared_utils/src/types/sns_canisters/mod.rs @@ -1 +1,2 @@ +pub mod sns_governance; pub mod swap; diff --git a/src/lib/shared_utils/src/types/sns_canisters/sns_governance.rs b/src/lib/shared_utils/src/types/sns_canisters/sns_governance.rs new file mode 100644 index 00000000..0dce89cc --- /dev/null +++ b/src/lib/shared_utils/src/types/sns_canisters/sns_governance.rs @@ -0,0 +1,654 @@ +// This is an experimental feature to generate Rust binding from Candid. +// You may want to manually adjust some of the types. +#![allow(dead_code, unused_imports)] +use candid::{self, CandidType, Deserialize, Principal}; +use ic_cdk::api::call::CallResult as Result; + +#[derive(CandidType, Deserialize)] +pub struct GenericNervousSystemFunction { + pub validator_canister_id: Option, + pub target_canister_id: Option, + pub validator_method_name: Option, + pub target_method_name: Option, +} +#[derive(CandidType, Deserialize)] +pub enum FunctionType { + NativeNervousSystemFunction{}, + GenericNervousSystemFunction(GenericNervousSystemFunction), +} +#[derive(CandidType, Deserialize)] +pub struct NervousSystemFunction { + pub id: u64, + pub name: String, + pub description: Option, + pub function_type: Option, +} +#[derive(CandidType, Deserialize)] +pub struct GovernanceCachedMetrics { + pub not_dissolving_neurons_e8s_buckets: Vec<(u64,f64,)>, + pub garbage_collectable_neurons_count: u64, + pub neurons_with_invalid_stake_count: u64, + pub not_dissolving_neurons_count_buckets: Vec<(u64,u64,)>, + pub neurons_with_less_than_6_months_dissolve_delay_count: u64, + pub dissolved_neurons_count: u64, + pub total_staked_e8s: u64, + pub total_supply_governance_tokens: u64, + pub not_dissolving_neurons_count: u64, + pub dissolved_neurons_e8s: u64, + pub neurons_with_less_than_6_months_dissolve_delay_e8s: u64, + pub dissolving_neurons_count_buckets: Vec<(u64,u64,)>, + pub dissolving_neurons_count: u64, + pub dissolving_neurons_e8s_buckets: Vec<(u64,f64,)>, + pub timestamp_seconds: u64, +} +#[derive(CandidType, Deserialize)] +pub struct MaturityModulation { + pub current_basis_points: Option, + pub updated_at_timestamp_seconds: Option, +} +#[derive(CandidType, Deserialize)] +pub struct NeuronId { pub id: serde_bytes::ByteBuf } +#[derive(CandidType, Deserialize)] +pub struct Followees { pub followees: Vec } +#[derive(CandidType, Deserialize)] +pub struct DefaultFollowees { pub followees: Vec<(u64,Followees,)> } +#[derive(CandidType, Deserialize)] +pub struct NeuronPermissionList { pub permissions: Vec } +#[derive(CandidType, Deserialize)] +pub struct VotingRewardsParameters { + pub final_reward_rate_basis_points: Option, + pub initial_reward_rate_basis_points: Option, + pub reward_rate_transition_duration_seconds: Option, + pub round_duration_seconds: Option, +} +#[derive(CandidType, Deserialize)] +pub struct NervousSystemParameters { + pub default_followees: Option, + pub max_dissolve_delay_seconds: Option, + pub max_dissolve_delay_bonus_percentage: Option, + pub max_followees_per_function: Option, + pub neuron_claimer_permissions: Option, + pub neuron_minimum_stake_e8s: Option, + pub max_neuron_age_for_age_bonus: Option, + pub initial_voting_period_seconds: Option, + pub neuron_minimum_dissolve_delay_to_vote_seconds: Option, + pub reject_cost_e8s: Option, + pub max_proposals_to_keep_per_action: Option, + pub wait_for_quiet_deadline_increase_seconds: Option, + pub max_number_of_neurons: Option, + pub transaction_fee_e8s: Option, + pub max_number_of_proposals_with_ballots: Option, + pub max_age_bonus_percentage: Option, + pub neuron_grantable_permissions: Option, + pub voting_rewards_parameters: Option, + pub maturity_modulation_disabled: Option, + pub max_number_of_principals_per_neuron: Option, +} +#[derive(CandidType, Deserialize)] +pub struct Version { + pub archive_wasm_hash: serde_bytes::ByteBuf, + pub root_wasm_hash: serde_bytes::ByteBuf, + pub swap_wasm_hash: serde_bytes::ByteBuf, + pub ledger_wasm_hash: serde_bytes::ByteBuf, + pub governance_wasm_hash: serde_bytes::ByteBuf, + pub index_wasm_hash: serde_bytes::ByteBuf, +} +#[derive(CandidType, Deserialize)] +pub struct ProposalId { pub id: u64 } +#[derive(CandidType, Deserialize)] +pub struct RewardEvent { + pub rounds_since_last_distribution: Option, + pub actual_timestamp_seconds: u64, + pub end_timestamp_seconds: Option, + pub total_available_e8s_equivalent: Option, + pub distributed_e8s_equivalent: u64, + pub round: u64, + pub settled_proposals: Vec, +} +#[derive(CandidType, Deserialize)] +pub struct UpgradeInProgress { + pub mark_failed_at_seconds: u64, + pub checking_upgrade_lock: u64, + pub proposal_id: u64, + pub target_version: Option, +} +#[derive(CandidType, Deserialize)] +pub struct GovernanceError { pub error_message: String, pub error_type: i32 } +#[derive(CandidType, Deserialize)] +pub struct Subaccount { pub subaccount: serde_bytes::ByteBuf } +#[derive(CandidType, Deserialize)] +pub struct Account { + pub owner: Option, + pub subaccount: Option, +} +#[derive(CandidType, Deserialize)] +pub struct Decimal { pub human_readable: Option } +#[derive(CandidType, Deserialize)] +pub struct Tokens { pub e8s: Option } +#[derive(CandidType, Deserialize)] +pub struct ValuationFactors { + pub xdrs_per_icp: Option, + pub icps_per_token: Option, + pub tokens: Option, +} +#[derive(CandidType, Deserialize)] +pub struct Valuation { + pub token: Option, + pub account: Option, + pub valuation_factors: Option, + pub timestamp_seconds: Option, +} +#[derive(CandidType, Deserialize)] +pub struct MintSnsTokensActionAuxiliary { pub valuation: Option } +#[derive(CandidType, Deserialize)] +pub enum ActionAuxiliary { + TransferSnsTreasuryFunds(MintSnsTokensActionAuxiliary), + MintSnsTokens(MintSnsTokensActionAuxiliary), +} +#[derive(CandidType, Deserialize)] +pub struct Ballot { + pub vote: i32, + pub cast_timestamp_seconds: u64, + pub voting_power: u64, +} +#[derive(CandidType, Deserialize)] +pub struct Percentage { pub basis_points: Option } +#[derive(CandidType, Deserialize)] +pub struct Tally { + pub no: u64, + pub yes: u64, + pub total: u64, + pub timestamp_seconds: u64, +} +#[derive(CandidType, Deserialize)] +pub struct ManageDappCanisterSettings { + pub freezing_threshold: Option, + pub canister_ids: Vec, + pub reserved_cycles_limit: Option, + pub log_visibility: Option, + pub memory_allocation: Option, + pub compute_allocation: Option, +} +#[derive(CandidType, Deserialize)] +pub struct RegisterDappCanisters { pub canister_ids: Vec } +#[derive(CandidType, Deserialize)] +pub struct TransferSnsTreasuryFunds { + pub from_treasury: i32, + pub to_principal: Option, + pub to_subaccount: Option, + pub memo: Option, + pub amount_e8s: u64, +} +#[derive(CandidType, Deserialize)] +pub struct UpgradeSnsControlledCanister { + pub new_canister_wasm: serde_bytes::ByteBuf, + pub mode: Option, + pub canister_id: Option, + pub canister_upgrade_arg: Option, +} +#[derive(CandidType, Deserialize)] +pub struct DeregisterDappCanisters { + pub canister_ids: Vec, + pub new_controllers: Vec, +} +#[derive(CandidType, Deserialize)] +pub struct MintSnsTokens { + pub to_principal: Option, + pub to_subaccount: Option, + pub memo: Option, + pub amount_e8s: Option, +} +#[derive(CandidType, Deserialize)] +pub struct ManageSnsMetadata { + pub url: Option, + pub logo: Option, + pub name: Option, + pub description: Option, +} +#[derive(CandidType, Deserialize)] +pub struct ExecuteGenericNervousSystemFunction { + pub function_id: u64, + pub payload: serde_bytes::ByteBuf, +} +#[derive(CandidType, Deserialize)] +pub struct ManageLedgerParameters { pub transfer_fee: Option } +#[derive(CandidType, Deserialize)] +pub struct Motion { pub motion_text: String } +#[derive(CandidType, Deserialize)] +pub enum Action { + ManageNervousSystemParameters(NervousSystemParameters), + AddGenericNervousSystemFunction(NervousSystemFunction), + ManageDappCanisterSettings(ManageDappCanisterSettings), + RemoveGenericNervousSystemFunction(u64), + UpgradeSnsToNextVersion{}, + RegisterDappCanisters(RegisterDappCanisters), + TransferSnsTreasuryFunds(TransferSnsTreasuryFunds), + UpgradeSnsControlledCanister(UpgradeSnsControlledCanister), + DeregisterDappCanisters(DeregisterDappCanisters), + MintSnsTokens(MintSnsTokens), + Unspecified{}, + ManageSnsMetadata(ManageSnsMetadata), + ExecuteGenericNervousSystemFunction(ExecuteGenericNervousSystemFunction), + ManageLedgerParameters(ManageLedgerParameters), + Motion(Motion), +} +#[derive(CandidType, Deserialize)] +pub struct Proposal { + pub url: String, + pub title: String, + pub action: Option, + pub summary: String, +} +#[derive(CandidType, Deserialize)] +pub struct WaitForQuietState { pub current_deadline_timestamp_seconds: u64 } +#[derive(CandidType, Deserialize)] +pub struct ProposalData { + pub id: Option, + pub payload_text_rendering: Option, + pub action: u64, + pub failure_reason: Option, + pub action_auxiliary: Option, + pub ballots: Vec<(String,Ballot,)>, + pub minimum_yes_proportion_of_total: Option, + pub reward_event_round: u64, + pub failed_timestamp_seconds: u64, + pub reward_event_end_timestamp_seconds: Option, + pub proposal_creation_timestamp_seconds: u64, + pub initial_voting_period_seconds: u64, + pub reject_cost_e8s: u64, + pub latest_tally: Option, + pub wait_for_quiet_deadline_increase_seconds: u64, + pub decided_timestamp_seconds: u64, + pub proposal: Option, + pub proposer: Option, + pub wait_for_quiet_state: Option, + pub minimum_yes_proportion_of_exercised: Option, + pub is_eligible_for_rewards: bool, + pub executed_timestamp_seconds: u64, +} +#[derive(CandidType, Deserialize)] +pub struct Split { pub memo: u64, pub amount_e8s: u64 } +#[derive(CandidType, Deserialize)] +pub struct Follow { pub function_id: u64, pub followees: Vec } +#[derive(CandidType, Deserialize)] +pub struct DisburseMaturity { + pub to_account: Option, + pub percentage_to_disburse: u32, +} +#[derive(CandidType, Deserialize)] +pub struct ChangeAutoStakeMaturity { + pub requested_setting_for_auto_stake_maturity: bool, +} +#[derive(CandidType, Deserialize)] +pub struct IncreaseDissolveDelay { pub additional_dissolve_delay_seconds: u32 } +#[derive(CandidType, Deserialize)] +pub struct SetDissolveTimestamp { pub dissolve_timestamp_seconds: u64 } +#[derive(CandidType, Deserialize)] +pub enum Operation { + ChangeAutoStakeMaturity(ChangeAutoStakeMaturity), + StopDissolving{}, + StartDissolving{}, + IncreaseDissolveDelay(IncreaseDissolveDelay), + SetDissolveTimestamp(SetDissolveTimestamp), +} +#[derive(CandidType, Deserialize)] +pub struct Configure { pub operation: Option } +#[derive(CandidType, Deserialize)] +pub struct RegisterVote { pub vote: i32, pub proposal: Option } +#[derive(CandidType, Deserialize)] +pub struct FinalizeDisburseMaturity { + pub amount_to_be_disbursed_e8s: u64, + pub to_account: Option, +} +#[derive(CandidType, Deserialize)] +pub struct MemoAndController { + pub controller: Option, + pub memo: u64, +} +#[derive(CandidType, Deserialize)] +pub enum By { MemoAndController(MemoAndController), NeuronId{} } +#[derive(CandidType, Deserialize)] +pub struct ClaimOrRefresh { pub by: Option } +#[derive(CandidType, Deserialize)] +pub struct RemoveNeuronPermissions { + pub permissions_to_remove: Option, + pub principal_id: Option, +} +#[derive(CandidType, Deserialize)] +pub struct AddNeuronPermissions { + pub permissions_to_add: Option, + pub principal_id: Option, +} +#[derive(CandidType, Deserialize)] +pub struct MergeMaturity { pub percentage_to_merge: u32 } +#[derive(CandidType, Deserialize)] +pub struct Amount { pub e8s: u64 } +#[derive(CandidType, Deserialize)] +pub struct Disburse { + pub to_account: Option, + pub amount: Option, +} +#[derive(CandidType, Deserialize)] +pub enum Command2 { + Split(Split), + Follow(Follow), + DisburseMaturity(DisburseMaturity), + Configure(Configure), + RegisterVote(RegisterVote), + SyncCommand{}, + MakeProposal(Proposal), + FinalizeDisburseMaturity(FinalizeDisburseMaturity), + ClaimOrRefreshNeuron(ClaimOrRefresh), + RemoveNeuronPermissions(RemoveNeuronPermissions), + AddNeuronPermissions(AddNeuronPermissions), + MergeMaturity(MergeMaturity), + Disburse(Disburse), +} +#[derive(CandidType, Deserialize)] +pub struct NeuronInFlightCommand { + pub command: Option, + pub timestamp: u64, +} +#[derive(CandidType, Deserialize)] +pub struct NeuronPermission { + pub principal: Option, + pub permission_type: Vec, +} +#[derive(CandidType, Deserialize)] +pub enum DissolveState { + DissolveDelaySeconds(u64), + WhenDissolvedTimestampSeconds(u64), +} +#[derive(CandidType, Deserialize)] +pub struct DisburseMaturityInProgress { + pub timestamp_of_disbursement_seconds: u64, + pub amount_e8s: u64, + pub account_to_disburse_to: Option, + pub finalize_disbursement_timestamp_seconds: Option, +} +#[derive(CandidType, Deserialize)] +pub struct Neuron { + pub id: Option, + pub staked_maturity_e8s_equivalent: Option, + pub permissions: Vec, + pub maturity_e8s_equivalent: u64, + pub cached_neuron_stake_e8s: u64, + pub created_timestamp_seconds: u64, + pub source_nns_neuron_id: Option, + pub auto_stake_maturity: Option, + pub aging_since_timestamp_seconds: u64, + pub dissolve_state: Option, + pub voting_power_percentage_multiplier: u64, + pub vesting_period_seconds: Option, + pub disburse_maturity_in_progress: Vec, + pub followees: Vec<(u64,Followees,)>, + pub neuron_fees_e8s: u64, +} +#[derive(CandidType, Deserialize)] +pub struct Governance { + pub root_canister_id: Option, + pub id_to_nervous_system_functions: Vec<(u64,NervousSystemFunction,)>, + pub metrics: Option, + pub maturity_modulation: Option, + pub mode: i32, + pub parameters: Option, + pub is_finalizing_disburse_maturity: Option, + pub deployed_version: Option, + pub sns_initialization_parameters: String, + pub latest_reward_event: Option, + pub pending_version: Option, + pub swap_canister_id: Option, + pub ledger_canister_id: Option, + pub proposals: Vec<(u64,ProposalData,)>, + pub in_flight_commands: Vec<(String,NeuronInFlightCommand,)>, + pub sns_metadata: Option, + pub neurons: Vec<(String,Neuron,)>, + pub genesis_timestamp_seconds: u64, +} +#[derive(CandidType, Deserialize)] +pub struct NeuronParameters { + pub controller: Option, + pub dissolve_delay_seconds: Option, + pub source_nns_neuron_id: Option, + pub stake_e8s: Option, + pub followees: Vec, + pub hotkey: Option, + pub neuron_id: Option, +} +#[derive(CandidType, Deserialize)] +pub struct ClaimSwapNeuronsRequest { + pub neuron_parameters: Vec, +} +#[derive(CandidType, Deserialize)] +pub struct SwapNeuron { pub id: Option, pub status: i32 } +#[derive(CandidType, Deserialize)] +pub struct ClaimedSwapNeurons { pub swap_neurons: Vec } +#[derive(CandidType, Deserialize)] +pub enum ClaimSwapNeuronsResult { Ok(ClaimedSwapNeurons), Err(i32) } +#[derive(CandidType, Deserialize)] +pub struct ClaimSwapNeuronsResponse { + pub claim_swap_neurons_result: Option, +} +#[derive(CandidType, Deserialize)] +pub struct FailStuckUpgradeInProgressArg {} +#[derive(CandidType, Deserialize)] +pub struct FailStuckUpgradeInProgressRet {} +#[derive(CandidType, Deserialize)] +pub struct GetMaturityModulationArg {} +#[derive(CandidType, Deserialize)] +pub struct GetMaturityModulationResponse { + pub maturity_modulation: Option, +} +#[derive(CandidType, Deserialize)] +pub struct GetMetadataArg {} +#[derive(CandidType, Deserialize)] +pub struct GetMetadataResponse { + pub url: Option, + pub logo: Option, + pub name: Option, + pub description: Option, +} +#[derive(CandidType, Deserialize)] +pub struct GetModeArg {} +#[derive(CandidType, Deserialize)] +pub struct GetModeResponse { pub mode: Option } +#[derive(CandidType, Deserialize)] +pub struct GetNeuron { pub neuron_id: Option } +#[derive(CandidType, Deserialize)] +pub enum Result_ { Error(GovernanceError), Neuron(Neuron) } +#[derive(CandidType, Deserialize)] +pub struct GetNeuronResponse { pub result: Option } +#[derive(CandidType, Deserialize)] +pub struct GetProposal { pub proposal_id: Option } +#[derive(CandidType, Deserialize)] +pub enum Result1 { Error(GovernanceError), Proposal(ProposalData) } +#[derive(CandidType, Deserialize)] +pub struct GetProposalResponse { pub result: Option } +#[derive(CandidType, Deserialize)] +pub enum CanisterStatusType { + #[serde(rename="stopped")] + Stopped, + #[serde(rename="stopping")] + Stopping, + #[serde(rename="running")] + Running, +} +#[derive(CandidType, Deserialize)] +pub struct DefiniteCanisterSettingsArgs { + pub freezing_threshold: candid::Nat, + pub controllers: Vec, + pub memory_allocation: candid::Nat, + pub compute_allocation: candid::Nat, +} +#[derive(CandidType, Deserialize)] +pub struct CanisterStatusResultV2 { + pub status: CanisterStatusType, + pub memory_size: candid::Nat, + pub cycles: candid::Nat, + pub settings: DefiniteCanisterSettingsArgs, + pub idle_cycles_burned_per_day: candid::Nat, + pub module_hash: Option, +} +#[derive(CandidType, Deserialize)] +pub struct GetRunningSnsVersionArg {} +#[derive(CandidType, Deserialize)] +pub struct GetRunningSnsVersionResponse { + pub deployed_version: Option, + pub pending_version: Option, +} +#[derive(CandidType, Deserialize)] +pub struct GetSnsInitializationParametersArg {} +#[derive(CandidType, Deserialize)] +pub struct GetSnsInitializationParametersResponse { + pub sns_initialization_parameters: String, +} +#[derive(CandidType, Deserialize)] +pub struct ListNervousSystemFunctionsResponse { + pub reserved_ids: Vec, + pub functions: Vec, +} +#[derive(CandidType, Deserialize)] +pub struct ListNeurons { + pub of_principal: Option, + pub limit: u32, + pub start_page_at: Option, +} +#[derive(CandidType, Deserialize)] +pub struct ListNeuronsResponse { pub neurons: Vec } +#[derive(CandidType, Deserialize)] +pub struct ListProposals { + pub include_reward_status: Vec, + pub before_proposal: Option, + pub limit: u32, + pub exclude_type: Vec, + pub include_status: Vec, +} +#[derive(CandidType, Deserialize)] +pub struct ListProposalsResponse { + pub include_ballots_by_caller: Option, + pub proposals: Vec, +} +#[derive(CandidType, Deserialize)] +pub struct StakeMaturity { pub percentage_to_stake: Option } +#[derive(CandidType, Deserialize)] +pub enum Command { + Split(Split), + Follow(Follow), + DisburseMaturity(DisburseMaturity), + ClaimOrRefresh(ClaimOrRefresh), + Configure(Configure), + RegisterVote(RegisterVote), + MakeProposal(Proposal), + StakeMaturity(StakeMaturity), + RemoveNeuronPermissions(RemoveNeuronPermissions), + AddNeuronPermissions(AddNeuronPermissions), + MergeMaturity(MergeMaturity), + Disburse(Disburse), +} +#[derive(CandidType, Deserialize)] +pub struct ManageNeuron { + pub subaccount: serde_bytes::ByteBuf, + pub command: Option, +} +#[derive(CandidType, Deserialize)] +pub struct SplitResponse { pub created_neuron_id: Option } +#[derive(CandidType, Deserialize)] +pub struct DisburseMaturityResponse { + pub amount_disbursed_e8s: u64, + pub amount_deducted_e8s: Option, +} +#[derive(CandidType, Deserialize)] +pub struct ClaimOrRefreshResponse { pub refreshed_neuron_id: Option } +#[derive(CandidType, Deserialize)] +pub struct StakeMaturityResponse { + pub maturity_e8s: u64, + pub staked_maturity_e8s: u64, +} +#[derive(CandidType, Deserialize)] +pub struct MergeMaturityResponse { + pub merged_maturity_e8s: u64, + pub new_stake_e8s: u64, +} +#[derive(CandidType, Deserialize)] +pub struct DisburseResponse { pub transfer_block_height: u64 } +#[derive(CandidType, Deserialize)] +pub enum Command1 { + Error(GovernanceError), + Split(SplitResponse), + Follow{}, + DisburseMaturity(DisburseMaturityResponse), + ClaimOrRefresh(ClaimOrRefreshResponse), + Configure{}, + RegisterVote{}, + MakeProposal(GetProposal), + RemoveNeuronPermission{}, + StakeMaturity(StakeMaturityResponse), + MergeMaturity(MergeMaturityResponse), + Disburse(DisburseResponse), + AddNeuronPermission{}, +} +#[derive(CandidType, Deserialize)] +pub struct ManageNeuronResponse { pub command: Option } +#[derive(CandidType, Deserialize)] +pub struct SetMode { pub mode: i32 } +#[derive(CandidType, Deserialize)] +pub struct SetModeRet {} + +pub struct Service(pub Principal); +impl Service { + pub async fn claim_swap_neurons(&self, arg0: ClaimSwapNeuronsRequest) -> Result<(ClaimSwapNeuronsResponse,)> { + ic_cdk::call(self.0, "claim_swap_neurons", (arg0,)).await + } + pub async fn fail_stuck_upgrade_in_progress(&self, arg0: FailStuckUpgradeInProgressArg) -> Result<(FailStuckUpgradeInProgressRet,)> { + ic_cdk::call(self.0, "fail_stuck_upgrade_in_progress", (arg0,)).await + } + pub async fn get_build_metadata(&self) -> Result<(String,)> { + ic_cdk::call(self.0, "get_build_metadata", ()).await + } + pub async fn get_latest_reward_event(&self) -> Result<(RewardEvent,)> { + ic_cdk::call(self.0, "get_latest_reward_event", ()).await + } + pub async fn get_maturity_modulation(&self, arg0: GetMaturityModulationArg) -> Result<(GetMaturityModulationResponse,)> { + ic_cdk::call(self.0, "get_maturity_modulation", (arg0,)).await + } + pub async fn get_metadata(&self, arg0: GetMetadataArg) -> Result<(GetMetadataResponse,)> { + ic_cdk::call(self.0, "get_metadata", (arg0,)).await + } + pub async fn get_mode(&self, arg0: GetModeArg) -> Result<(GetModeResponse,)> { + ic_cdk::call(self.0, "get_mode", (arg0,)).await + } + pub async fn get_nervous_system_parameters(&self, arg0: ()) -> Result<(NervousSystemParameters,)> { + ic_cdk::call(self.0, "get_nervous_system_parameters", (arg0,)).await + } + pub async fn get_neuron(&self, arg0: GetNeuron) -> Result<(GetNeuronResponse,)> { + ic_cdk::call(self.0, "get_neuron", (arg0,)).await + } + pub async fn get_proposal(&self, arg0: GetProposal) -> Result<(GetProposalResponse,)> { + ic_cdk::call(self.0, "get_proposal", (arg0,)).await + } + pub async fn get_root_canister_status(&self, arg0: ()) -> Result<(CanisterStatusResultV2,)> { + ic_cdk::call(self.0, "get_root_canister_status", (arg0,)).await + } + pub async fn get_running_sns_version(&self, arg0: GetRunningSnsVersionArg) -> Result<(GetRunningSnsVersionResponse,)> { + ic_cdk::call(self.0, "get_running_sns_version", (arg0,)).await + } + pub async fn get_sns_initialization_parameters(&self, arg0: GetSnsInitializationParametersArg) -> Result<(GetSnsInitializationParametersResponse,)> { + ic_cdk::call(self.0, "get_sns_initialization_parameters", (arg0,)).await + } + pub async fn list_nervous_system_functions(&self) -> Result<(ListNervousSystemFunctionsResponse,)> { + ic_cdk::call(self.0, "list_nervous_system_functions", ()).await + } + pub async fn list_neurons(&self, arg0: ListNeurons) -> Result<(ListNeuronsResponse,)> { + ic_cdk::call(self.0, "list_neurons", (arg0,)).await + } + pub async fn list_proposals(&self, arg0: ListProposals) -> Result<(ListProposalsResponse,)> { + ic_cdk::call(self.0, "list_proposals", (arg0,)).await + } + pub async fn manage_neuron(&self, arg0: ManageNeuron) -> Result<(ManageNeuronResponse,)> { + ic_cdk::call(self.0, "manage_neuron", (arg0,)).await + } + pub async fn set_mode(&self, arg0: SetMode) -> Result<(SetModeRet,)> { + ic_cdk::call(self.0, "set_mode", (arg0,)).await + } +} +