use crate::sns::report::MainnetSnsCanisters;
use crate::sns::report::lookup::model::SnsLookup;
use crate::sns::report::{
SnsHostError, SnsLookupRequest, enforce_mainnet_network,
source::{
SnsDiscoverySource, model::list::join_selected_mainnet_sns, validate_mainnet_sns_inventory,
},
};
pub(in crate::sns::report) async fn resolve_sns_lookup(
request: &SnsLookupRequest,
source: &dyn SnsDiscoverySource,
) -> Result<SnsLookup, SnsHostError> {
enforce_mainnet_network(&request.network)?;
let fetch_request = crate::report::CollectionSourceRequest::from_unix_secs(
&request.network,
&request.source_endpoint,
request.now_unix_secs,
"ic-query",
);
let mut inventory = source.fetch_sns_inventory(&fetch_request).await?;
validate_mainnet_sns_inventory(&fetch_request, &inventory)?;
let index = resolve_sns(&inventory.sns_instances, request)?;
let metadata = source
.fetch_sns_metadata(&fetch_request, &inventory.sns_instances[index..=index])
.await?;
let target = inventory.sns_instances.swap_remove(index);
let mut sns = join_selected_mainnet_sns(target, metadata)?;
sns.id = index + 1;
Ok(SnsLookup { fetch_request, sns })
}
fn resolve_sns(
instances: &[MainnetSnsCanisters],
request: &SnsLookupRequest,
) -> Result<usize, SnsHostError> {
if let Some(id) = request.id() {
return id
.checked_sub(1)
.filter(|index| *index < instances.len())
.ok_or(SnsHostError::UnknownSnsId {
id,
sns_count: instances.len(),
});
}
let root_canister_id = request
.root_canister_id()
.expect("lookup constructors admit id or principal")
.to_text();
instances
.iter()
.position(|sns| sns.root_canister_id == root_canister_id)
.ok_or(SnsHostError::UnknownSnsRoot { root_canister_id })
}