Skip to content

Commit

Permalink
Keep existing data in SNS aggregator when new data can't be loaded
Browse files Browse the repository at this point in the history
  • Loading branch information
dskloetd committed Nov 26, 2024
1 parent 95b7d3e commit ba12111
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
13 changes: 13 additions & 0 deletions rs/sns_aggregator/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,19 @@ impl State {
Ok(())
}

pub fn get_cached_sns(root_canister_id: CanisterId) -> Option<UpstreamData> {
STATE.with(|state| {
state
.stable
.borrow()
.sns_cache
.borrow_mut()
.upstream_data
.get(&root_canister_id)
.cloned()
})
}

/// Creates a page of "slow data".
///
/// This shall be used for the the "latest" and paginated responses, so that the response is consistent.
Expand Down
38 changes: 25 additions & 13 deletions rs/sns_aggregator/src/upstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,32 +98,38 @@ async fn get_sns_data(index: u64, sns_canister_ids: DeployedSns) -> anyhow::Resu
let ledger_canister_id = convert_canister_id!(&sns_canister_ids.ledger_canister_id);

crate::state::log(format!("Getting SNS index {index}... list_sns_canisters"));

// Default to existing data when some new data for an SNS can't be loaded.
let existing_data = State::get_cached_sns(root_canister_id).unwrap_or_default();

let list_sns_canisters: types::ListSnsCanistersResponse =
ic_cdk::api::call::call(root_canister_id, "list_sns_canisters", (types::EmptyRecord {},))
.await
.map(|response: (_,)| response.0)
.map_err(|err| anyhow!("Failed to list SNS canisters: {:?}", err))?;
.map_err(|err| crate::state::log(format!("Failed to list SNS canisters: {err:?}")))
.unwrap_or(existing_data.list_sns_canisters);

crate::state::log(format!("Getting SNS index {index}... get_metadata"));
let meta: types::GetMetadataResponse =
ic_cdk::api::call::call(governance_canister_id, "get_metadata", (types::EmptyRecord {},))
.await
.map(|response: (_,)| response.0)
.map_err(|err| anyhow!("Failed to get SNS metadata: {err:?}"))?;
.map_err(|err| crate::state::log(format!("Failed to get SNS metadata: {err:?}")))
.unwrap_or(existing_data.meta);

crate::state::log(format!("Getting SNS index {index}... list_nervous_system_functions"));
let parameters: types::ListNervousSystemFunctionsResponse =
ic_cdk::api::call::call(governance_canister_id, "list_nervous_system_functions", ((),))
.await
.map(|response: (_,)| response.0)
.map_err(|err| crate::state::log(format!("Failed to get SNS parameters: {err:?}")))
.unwrap_or_default();
.unwrap_or(existing_data.parameters);

crate::state::log(format!("Getting SNS index {index}... get_state"));
let swap_state: GetStateResponse = get_swap_state(swap_canister_id)
.await
.map_err(|err| crate::state::log(format!("Failed to get swap state: {err:?}")))
.unwrap_or_default();
.unwrap_or(existing_data.swap_state);

crate::state::log(format!("Getting SNS index {index}... icrc1_metadata"));
//let icrc1_metadata = Vec::new();
Expand All @@ -132,20 +138,21 @@ async fn get_sns_data(index: u64, sns_canister_ids: DeployedSns) -> anyhow::Resu
.await
.map(|response: (_,)| response.0)
.map_err(|err| crate::state::log(format!("Failed to get ledger metadata: {err:?}")))
.unwrap_or_default();
.unwrap_or(existing_data.icrc1_metadata);

crate::state::log(format!("Getting SNS index {index}... icrc1_fee"));
//let icrc1_fee = SnsTokens::default();
let icrc1_fee: SnsTokens = ic_cdk::api::call::call(ledger_canister_id, "icrc1_fee", ((),))
.await
.map(|response: (_,)| response.0)
.map_err(|err| anyhow!("Failed to get ledger fee: {err:?}"))?;
.map_err(|err| crate::state::log(format!("Failed to get ledger fee: {err:?}")))
.unwrap_or(existing_data.icrc1_fee);

let icrc1_total_supply: SnsTokens = ic_cdk::api::call::call(ledger_canister_id, "icrc1_total_supply", ((),))
.await
.map(|response: (_,)| response.0)
.map_err(|err| anyhow!("Failed to get ledger total tokens supply: {err:?}"))
.unwrap_or_default();
.map_err(|err| crate::state::log(format!("Failed to get ledger total tokens supply: {err:?}")))
.unwrap_or(existing_data.icrc1_total_supply);

let swap_params_response: Option<GetSaleParametersResponse> =
match ic_cdk::api::call::call(swap_canister_id, "get_sale_parameters", (EmptyRecord {},))
Expand All @@ -157,7 +164,8 @@ async fn get_sns_data(index: u64, sns_canister_ids: DeployedSns) -> anyhow::Resu
None
}
Ok(response) => Some(response),
};
}
.or(existing_data.swap_params);

let init_response: Option<GetInitResponse> =
match ic_cdk::api::call::call(swap_canister_id, "get_init", (EmptyRecord {},))
Expand All @@ -169,23 +177,27 @@ async fn get_sns_data(index: u64, sns_canister_ids: DeployedSns) -> anyhow::Resu
None
}
Ok(response) => Some(response),
};
}
.or(existing_data.init);

let derived_state_response: Option<GetDerivedStateResponse> = get_derived_state(swap_canister_id)
.await
.map_err(|err| crate::state::log(format!("Failed to get derived state: {err:?}")))
.ok();
.ok()
.or(existing_data.derived_state);

let lifecycle_response: Option<GetLifecycleResponse> = get_lifecycle(swap_canister_id)
.await
.map_err(|err| crate::state::log(format!("Failed to get lifecycle: {err:?}")))
.ok();
.ok()
.or(existing_data.lifecycle);

let nervous_system_parameters: Option<NervousSystemParameters> =
get_nervous_system_parameters(governance_canister_id)
.await
.map_err(|err| crate::state::log(format!("Failed to get nervous system parameters: {err:?}")))
.ok();
.ok()
.or(existing_data.nervous_system_parameters);

crate::state::log("Yay, got an SNS status".to_string());
// If the SNS sale will open, collect data when it does.
Expand Down

0 comments on commit ba12111

Please sign in to comment.