Move locations to their own cache
This commit is contained in:
@@ -34,27 +34,7 @@ pub(crate) struct PrettyMixNodeBondWithLocation {
|
||||
pub(crate) async fn list(
|
||||
state: &State<ExplorerApiStateContext>,
|
||||
) -> Json<Vec<PrettyMixNodeBondWithLocation>> {
|
||||
Json(
|
||||
state
|
||||
.inner
|
||||
.mix_nodes
|
||||
.get()
|
||||
.await
|
||||
.value
|
||||
.values()
|
||||
.map(|i| {
|
||||
let mix_node = i.bond.clone();
|
||||
PrettyMixNodeBondWithLocation {
|
||||
location: i.location.clone(),
|
||||
bond_amount: mix_node.bond_amount,
|
||||
total_delegation: mix_node.total_delegation,
|
||||
owner: mix_node.owner,
|
||||
layer: mix_node.layer,
|
||||
mix_node: mix_node.mix_node,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<PrettyMixNodeBondWithLocation>>(),
|
||||
)
|
||||
Json(state.inner.mix_nodes.get_mixnodes_with_location().await)
|
||||
}
|
||||
|
||||
#[openapi(tag = "mix_node")]
|
||||
|
||||
@@ -7,6 +7,7 @@ use std::time::{Duration, SystemTime};
|
||||
use rocket::tokio::sync::RwLock;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::mix_node::http::PrettyMixNodeBondWithLocation;
|
||||
use crate::mix_nodes::utils::map_2_letter_to_3_letter_country_code;
|
||||
use mixnet_contract::{Delegation, MixNodeBond, RawDelegationData, UnpackedDelegation};
|
||||
use network_defaults::{
|
||||
@@ -53,10 +54,6 @@ impl Location {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct MixNodeBondWithLocation {
|
||||
pub(crate) location: Option<Location>,
|
||||
pub(crate) bond: MixNodeBond,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -92,23 +89,28 @@ impl ThreadsafeMixNodesResult {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn is_location_valid(&self, identity_key: &str) -> bool {
|
||||
self.inner
|
||||
.read()
|
||||
.await
|
||||
.location_cache
|
||||
.get(identity_key)
|
||||
.map(|cache_item| cache_item.valid_until > SystemTime::now())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_location_cache(&self) -> LocationCache {
|
||||
self.inner.read().await.location_cache.clone()
|
||||
}
|
||||
|
||||
pub(crate) async fn set_location(&self, identity_key: &str, location: Location) {
|
||||
pub(crate) async fn set_location(&self, identity_key: &str, location: Option<Location>) {
|
||||
let mut guard = self.inner.write().await;
|
||||
|
||||
// cache the location for this mix node so that it can be used when the mix node list is refreshed
|
||||
guard
|
||||
.location_cache
|
||||
.insert(identity_key.to_string(), location.clone());
|
||||
|
||||
// add the location to the mix node
|
||||
guard
|
||||
.value
|
||||
.entry(identity_key.to_string())
|
||||
.and_modify(|item| item.location = Some(location));
|
||||
guard.location_cache.insert(
|
||||
identity_key.to_string(),
|
||||
LocationCacheItem::new_from_location(location),
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) async fn get(&self) -> MixNodesResult {
|
||||
@@ -124,25 +126,34 @@ impl ThreadsafeMixNodesResult {
|
||||
self.inner.read().await.clone()
|
||||
}
|
||||
|
||||
pub(crate) async fn refresh_and_get(&self) -> MixNodesResult {
|
||||
self.refresh().await;
|
||||
self.inner.read().await.clone()
|
||||
pub(crate) async fn get_mixnodes_with_location(&self) -> Vec<PrettyMixNodeBondWithLocation> {
|
||||
let guard = self.inner.read().await;
|
||||
guard
|
||||
.value
|
||||
.values()
|
||||
.map(|bond| {
|
||||
let location = guard.location_cache.get(&bond.mix_node.identity_key);
|
||||
let copy = bond.clone();
|
||||
PrettyMixNodeBondWithLocation {
|
||||
location: location.and_then(|l| l.location.clone()),
|
||||
bond_amount: copy.bond_amount,
|
||||
total_delegation: copy.total_delegation,
|
||||
owner: copy.owner,
|
||||
layer: copy.layer,
|
||||
mix_node: copy.mix_node,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
async fn refresh(&self) {
|
||||
pub(crate) async fn refresh(&self) {
|
||||
// get mixnodes and cache the new value
|
||||
let value = retrieve_mixnodes().await;
|
||||
let location_cache = self.inner.read().await.location_cache.clone();
|
||||
*self.inner.write().await = MixNodesResult {
|
||||
value: value
|
||||
.into_iter()
|
||||
.map(|bond| {
|
||||
let location = location_cache.get(&bond.mix_node.identity_key).cloned(); // add the location, if we've located this mix node before
|
||||
(
|
||||
bond.mix_node.identity_key.to_string(),
|
||||
MixNodeBondWithLocation { location, bond },
|
||||
)
|
||||
})
|
||||
.map(|bond| (bond.mix_node.identity_key.to_string(), bond))
|
||||
.collect(),
|
||||
valid_until: SystemTime::now() + Duration::from_secs(60 * 10), // valid for 10 minutes
|
||||
location_cache,
|
||||
|
||||
@@ -27,12 +27,7 @@ pub struct ExplorerApiState {
|
||||
|
||||
impl ExplorerApiState {
|
||||
pub(crate) async fn get_mix_node(&self, pubkey: &str) -> Option<MixNodeBond> {
|
||||
self.mix_nodes
|
||||
.get()
|
||||
.await
|
||||
.value
|
||||
.get(pubkey)
|
||||
.map(|cache_item| cache_item.bond.clone())
|
||||
self.mix_nodes.get().await.value.get(pubkey).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user