1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
//! This module provides functions to manage the state of the indexer canister.
use candid::Principal;
use ic_stable_structures::{
DefaultMemoryImpl, StableBTreeMap, StableVec, StableCell
};
use ic_cdk::{query, update};
use ic_stable_structures::memory_manager::{MemoryId, MemoryManager};
use std::cell::RefCell;
use crate::storable::{
StorablePrincipal,
Issuer,
Memory
};
use crate::access::is_controller;
thread_local! {
static MEMORY_MANAGER: RefCell<MemoryManager<DefaultMemoryImpl>> =
RefCell::new(MemoryManager::init(DefaultMemoryImpl::default()));
static PRINCIPAL_TO_ISSUER: RefCell<StableBTreeMap<StorablePrincipal, Issuer, Memory>> = RefCell::new(
StableBTreeMap::init(
MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(0))),
)
);
}
/// Retrieves the issuer associated with the given principal.
///
/// # Arguments
///
/// * `principal` - The principal for which to retrieve the issuer.
///
/// # Returns
///
/// * `Ok(Issuer)` if the issuer is found.
/// * `Err(String)` if the issuer is not found.
#[query(name = "getIssuer")]
pub fn get_issuer(principal: Principal) -> Result<Issuer, String> {
if let Some(issuer) = PRINCIPAL_TO_ISSUER.with(|p| p.borrow().get(&StorablePrincipal(principal))) {
Ok(issuer)
} else {
Err(String::from("Issuer not found"))
}
}
/// Retrieves a batch of issuers starting from the given principal.
///
/// # Arguments
///
/// * `start_principal` - The principal from which to start the batch retrieval.
/// * `limit` - The maximum number of issuers to retrieve.
///
/// # Returns
///
/// * A vector of tuples containing the principal and issuer.
#[query(name = "getIssuersBatch")]
pub fn get_issuers_batch(start_principal: Option<Principal>, limit: usize) -> Vec<(Principal, Issuer)> {
PRINCIPAL_TO_ISSUER.with(|p| {
let map = p.borrow();
let mut result = Vec::new();
let mut count = 0;
let mut started = start_principal.is_none();
for (key, value) in map.iter() {
if !started {
if key.0 == start_principal.unwrap() {
started = true;
} else {
continue;
}
}
if count >= limit {
break;
}
result.push((key.0, value.clone()));
count += 1;
}
result
})
}
/// Sets the issuer for the given principal.
///
/// # Arguments
///
/// * `principal` - The principal for which to set the issuer.
/// * `issuer` - The issuer to associate with the principal.
///
/// # Returns
///
/// * `Ok(())` if the issuer is set successfully.
/// * `Err(String)` if there is an error.
pub fn _set_issuer(principal: Principal, issuer: Issuer) -> Result<(), String> {
PRINCIPAL_TO_ISSUER.with(|p| p.borrow_mut().insert(StorablePrincipal(principal), issuer));
Ok(())
}
/// Removes the issuer associated with the given principal.
///
/// # Arguments
///
/// * `principal` - The principal for which to remove the issuer.
///
/// # Returns
///
/// * `Ok(())` if the issuer is removed successfully.
/// * `Err(String)` if there is an error or access is denied.
#[update(name = "removeIssuer")]
pub fn remove_issuer(principal: Principal) -> Result<(), String> {
if(!is_controller()) {
return Err(String::from("Access denied"));
}
PRINCIPAL_TO_ISSUER.with(|p| p.borrow_mut().remove(&StorablePrincipal(principal)));
Ok(())
}