use crate::{
cdk::{
env::nns::NNS_REGISTRY_CANISTER,
spec::governance::nns::{GetSubnetForCanisterRequest, GetSubnetForCanisterResponse},
types::Principal,
},
infra::{InfraError, ic::call::Call, ic::nns::NnsInfraError},
log,
log::Topic,
};
use thiserror::Error as ThisError;
#[derive(Debug, ThisError)]
pub enum NnsRegistryInfraError {
#[error("NNS registry rejected the request: {reason}")]
Rejected { reason: String },
}
impl From<NnsRegistryInfraError> for InfraError {
fn from(err: NnsRegistryInfraError) -> Self {
NnsInfraError::from(err).into()
}
}
pub struct NnsRegistryInfra;
impl NnsRegistryInfra {
pub async fn get_subnet_for_canister(pid: Principal) -> Result<Option<Principal>, InfraError> {
let request = GetSubnetForCanisterRequest { principal: pid };
let result = Call::unbounded_wait(*NNS_REGISTRY_CANISTER, "get_subnet_for_canister")
.with_arg(request)?
.execute()
.await?
.candid::<GetSubnetForCanisterResponse>()?;
match result {
Ok(payload) => Ok(payload.subnet_id),
Err(msg) => {
log!(
Topic::Topology,
Warn,
"NNS registry rejected get_subnet_for_canister: {msg}"
);
Err(NnsRegistryInfraError::Rejected { reason: msg }.into())
}
}
}
}